1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "btm_acl.h"
17 
18 #include <securec.h>
19 
20 #include "hci/hci.h"
21 #include "hci/hci_error.h"
22 #include "log.h"
23 #include "platform/include/alarm.h"
24 #include "platform/include/allocator.h"
25 #include "platform/include/list.h"
26 #include "platform/include/mutex.h"
27 #include "platform/include/queue.h"
28 #include "platform/include/semaphore.h"
29 #include "platform/include/thread.h"
30 
31 #include "btm.h"
32 #include "btm_acl_def.h"
33 #include "btm_controller.h"
34 #include "btm_inq_db.h"
35 #include "btm_le_sec.h"
36 #include "btm_thread.h"
37 #include "btm_wl.h"
38 
39 #define STATUS_NONE 0
40 #define STATUS_INITIALIZED 1
41 
42 #define IS_INITIALIZED() (g_status == STATUS_INITIALIZED)
43 
44 #define COD_SIZE 3
45 
46 #define CLEANUP_TIMEOUT 5000
47 
48 #define REQUEST_NOT_COMPLETED 0xff
49 
50 typedef enum {
51     CONNECTING,
52     CONNECTED,
53     DISCONNECTING,
54     DISCONNECTED,
55 } BtmAclConnectionState;
56 
57 typedef struct {
58     uint16_t connectionHandle;
59     uint8_t transport;
60     BtAddr addr;
61     bool isInitiator;
62     BtmAclConnectionState state;
63     uint8_t refCount;
64     uint8_t encryption;
65     Alarm *timeoutTimer;
66     union {
67         struct {
68             uint8_t featureStatus;
69             HciLmpFeatures lmpFeatures;
70             uint8_t extendedFeatureStatus;
71             uint8_t maxPageNumber;
72             HciExtendedLmpFeatures extendedLmpFeatures;
73         } bredr;
74         struct {
75             uint8_t featureStatus;
76             HciLeFeatures leFeatures;
77         } le;
78     } remoteFeatures;
79     struct {
80         uint8_t version;
81         uint16_t manufactureName;
82         uint16_t subVersion;
83     } remoteVersion;
84     uint8_t remoteCod[COD_SIZE];
85     BtAddr leLocalAddr;
86     BtAddr lePeerAddr;
87 } BtmAclConnection;
88 
89 typedef struct {
90     const BtmAclCallbacks *callbacks;
91     void *context;
92 } BtmAclCallbacksBlock;
93 
94 typedef enum {
95     REMOTE_FEATURE_COMPLETE,
96     REMOTE_EXTENDED_FEATURE_COMPLETE,
97     REMOTE_LE_FEATURE_COMPLETE,
98 } BtmRemoteDeviceSupportEvent;
99 
100 typedef enum {
101     EDR_ACL_2MB_MODE,
102     EDR_ACL_3MB_MODE,
103 } BtmRemoteDeviceFeature;
104 
105 typedef enum {
106     SECURE_SIMPLE_PAIRING_HOST_SUPPORT,
107 } BtmRemoteDeviceExtendedFeature;
108 
109 typedef enum {
110     CONNECTION_PARAMETER_REQUEST,
111 } BtmRemoteDeviceLeFeature;
112 
113 typedef struct {
114     BtAddr addr;
115     uint16_t connectionHandle;
116     BTMRemoteDeviceSupportCallback callback;
117     BtmRemoteDeviceSupportEvent event;
118     union {
119         BtmRemoteDeviceFeature feature;
120         BtmRemoteDeviceExtendedFeature extendedFeature;
121         BtmRemoteDeviceLeFeature leFreature;
122     } feature;
123 } BtmRemoteDeviceSupportRequest;
124 
125 #define ACTION_ADD_TO_WHITE_LIST 1
126 #define ACTION_REMOVE_FORM_WHITE_LIST 2
127 
128 typedef struct {
129     uint8_t action;
130     BtAddr addr;
131 } BtmWhiteListPendingAction;
132 
133 static List *g_aclList = NULL;
134 static Mutex *g_aclListLock = NULL;
135 static List *g_aclCallbackList = NULL;
136 static Mutex *g_aclCallbackListLock = NULL;
137 static List *g_remoteSupportRequestList = NULL;
138 
139 static HciEventCallbacks g_hciEventCallbacks;
140 
141 static Mutex *g_cleanupMutex = NULL;
142 static uint16_t g_cleanupHandle = 0xffff;
143 static Semaphore *g_cleanupEvent = NULL;
144 static Alarm *g_cleanupTimer = NULL;
145 
146 static uint8_t g_status = STATUS_NONE;
147 
148 static uint16_t g_leScanInterval = LE_SCAN_INTERVAL_DEFAULT;
149 static uint16_t g_leScanWindow = LE_SCAN_WINDOW_DEFAULT;
150 
151 static Mutex *g_leConnectionCancelLock = NULL;
152 static List *g_leConnectionCancelList = NULL;
153 
154 static Queue *g_leWhiteListPendingActionQueue;
155 
156 static Mutex *g_autoConnectLock = NULL;
157 
AllocAclConnection()158 static BtmAclConnection *AllocAclConnection()
159 {
160     BtmAclConnection *connection = MEM_CALLOC.alloc(sizeof(BtmAclConnection));
161     if (connection != NULL) {
162         connection->refCount = 0;
163         connection->isInitiator = false;
164         connection->timeoutTimer = AlarmCreate(NULL, false);
165 
166         connection->remoteFeatures.bredr.featureStatus = REQUEST_NOT_COMPLETED;
167         connection->remoteFeatures.bredr.extendedFeatureStatus = REQUEST_NOT_COMPLETED;
168         connection->remoteFeatures.le.featureStatus = REQUEST_NOT_COMPLETED;
169     }
170     return connection;
171 }
172 
FreeAclConnection(void * connection)173 static void FreeAclConnection(void *connection)
174 {
175     BtmAclConnection *aclConnection = (BtmAclConnection *)connection;
176     if (aclConnection != NULL) {
177         if (aclConnection->timeoutTimer != NULL) {
178             AlarmCancel(aclConnection->timeoutTimer);
179             AlarmDelete(aclConnection->timeoutTimer);
180             aclConnection->timeoutTimer = NULL;
181         }
182     }
183     MEM_CALLOC.free(connection);
184 }
185 
BtmAllocAclCallbacksBlock(const BtmAclCallbacks * callbacks,void * context)186 static BtmAclCallbacksBlock *BtmAllocAclCallbacksBlock(const BtmAclCallbacks *callbacks, void *context)
187 {
188     BtmAclCallbacksBlock *block = MEM_CALLOC.alloc(sizeof(BtmAclCallbacksBlock));
189     if (block != NULL) {
190         block->callbacks = callbacks;
191         block->context = context;
192     }
193     return block;
194 }
195 
BtmFreeAclCallbacksBlock(void * block)196 static void BtmFreeAclCallbacksBlock(void *block)
197 {
198     MEM_CALLOC.free(block);
199 }
200 
BtmAclAllocRes()201 static void BtmAclAllocRes()
202 {
203     g_aclListLock = MutexCreate();
204     g_aclList = ListCreate(FreeAclConnection);
205 
206     g_remoteSupportRequestList = ListCreate(MEM_MALLOC.free);
207 
208     g_aclCallbackListLock = MutexCreate();
209     g_aclCallbackList = ListCreate(BtmFreeAclCallbacksBlock);
210 
211     g_cleanupMutex = MutexCreate();
212     g_cleanupEvent = SemaphoreCreate(0);
213     g_cleanupTimer = AlarmCreate("AclCleanup", false);
214 
215     g_leScanInterval = LE_SCAN_INTERVAL_DEFAULT;
216     g_leScanWindow = LE_SCAN_WINDOW_DEFAULT;
217 
218     g_leConnectionCancelLock = MutexCreate();
219     g_leConnectionCancelList = ListCreate(MEM_MALLOC.free);
220 
221     g_leWhiteListPendingActionQueue = QueueCreate(UINT16_MAX);
222     g_autoConnectLock = MutexCreate();
223 }
224 
BtmInitAcl()225 void BtmInitAcl()
226 {
227     LOG_DEBUG("%{public}s start", __FUNCTION__);
228 
229     BtmAclAllocRes();
230 
231     g_status = STATUS_INITIALIZED;
232 
233     LOG_DEBUG("%{public}s end", __FUNCTION__);
234 }
235 
BtmAclFreeRes()236 static void BtmAclFreeRes()
237 {
238     if (g_cleanupMutex != NULL) {
239         MutexDelete(g_cleanupMutex);
240         g_cleanupMutex = NULL;
241     }
242     if (g_cleanupEvent != NULL) {
243         SemaphoreDelete(g_cleanupEvent);
244         g_cleanupEvent = NULL;
245     }
246     if (g_cleanupTimer != NULL) {
247         AlarmDelete(g_cleanupTimer);
248         g_cleanupTimer = NULL;
249     }
250     if (g_aclList != NULL) {
251         ListDelete(g_aclList);
252         g_aclList = NULL;
253     }
254     if (g_remoteSupportRequestList != NULL) {
255         ListDelete(g_remoteSupportRequestList);
256         g_remoteSupportRequestList = NULL;
257     }
258     if (g_aclListLock != NULL) {
259         MutexDelete(g_aclListLock);
260         g_aclListLock = NULL;
261     }
262     if (g_aclCallbackListLock != NULL) {
263         MutexDelete(g_aclCallbackListLock);
264         g_aclCallbackListLock = NULL;
265     }
266     if (g_aclCallbackList != NULL) {
267         ListDelete(g_aclCallbackList);
268         g_aclCallbackList = NULL;
269     }
270     if (g_leConnectionCancelList != NULL) {
271         ListDelete(g_leConnectionCancelList);
272         g_leConnectionCancelList = NULL;
273     }
274     if (g_leConnectionCancelLock != NULL) {
275         MutexDelete(g_leConnectionCancelLock);
276         g_leConnectionCancelLock = NULL;
277     }
278     if (g_autoConnectLock != NULL) {
279         MutexDelete(g_autoConnectLock);
280         g_autoConnectLock = NULL;
281     }
282     if (g_leWhiteListPendingActionQueue != NULL) {
283         QueueDelete(g_leWhiteListPendingActionQueue, MEM_MALLOC.free);
284         g_leWhiteListPendingActionQueue = NULL;
285     }
286 }
287 
BtmCloseAcl()288 void BtmCloseAcl()
289 {
290     LOG_DEBUG("%{public}s start", __FUNCTION__);
291 
292     g_status = STATUS_NONE;
293 
294     BtmAclFreeRes();
295 
296     LOG_DEBUG("%{public}s end", __FUNCTION__);
297 }
298 
BtmStartAcl()299 void BtmStartAcl()
300 {
301     g_leScanInterval = LE_SCAN_INTERVAL_DEFAULT;
302     g_leScanWindow = LE_SCAN_WINDOW_DEFAULT;
303 
304     HCI_RegisterEventCallbacks(&g_hciEventCallbacks);
305 }
306 
BtmStopAcl()307 void BtmStopAcl()
308 {
309     HCI_DeregisterEventCallbacks(&g_hciEventCallbacks);
310 
311     MutexLock(g_aclListLock);
312     ListClear(g_aclList);
313     ListClear(g_remoteSupportRequestList);
314     MutexUnlock(g_aclListLock);
315 
316     MutexLock(g_aclCallbackListLock);
317     ListClear(g_aclCallbackList);
318     MutexUnlock(g_aclCallbackListLock);
319 
320     MutexLock(g_leConnectionCancelLock);
321     ListClear(g_leConnectionCancelList);
322     MutexUnlock(g_leConnectionCancelLock);
323 }
324 
IsEqualAddr(const uint8_t addr1[BT_ADDRESS_SIZE],const uint8_t addr2[BT_ADDRESS_SIZE])325 static bool IsEqualAddr(const uint8_t addr1[BT_ADDRESS_SIZE], const uint8_t addr2[BT_ADDRESS_SIZE])
326 {
327     bool isEqual = true;
328     for (uint8_t i = 0; i < BT_ADDRESS_SIZE; i++) {
329         if (addr1[i] != addr2[i]) {
330             isEqual = false;
331             break;
332         }
333     }
334     return isEqual;
335 }
336 
BtmAclFindConnectionByAddr(const BtAddr * addr)337 static BtmAclConnection *BtmAclFindConnectionByAddr(const BtAddr *addr)
338 {
339     BtmAclConnection *connection = NULL;
340 
341     ListNode *node = ListGetFirstNode(g_aclList);
342     while (node != NULL) {
343         connection = ListGetNodeData(node);
344         if (connection->transport == TRANSPORT_BREDR) {
345             if (IsEqualAddr(connection->addr.addr, addr->addr)) {
346                 break;
347             }
348         }
349         connection = NULL;
350         node = ListGetNextNode(node);
351     }
352 
353     return connection;
354 }
355 
BtmAclFindLeConnectionByAddr(const BtAddr * addr)356 static BtmAclConnection *BtmAclFindLeConnectionByAddr(const BtAddr *addr)
357 {
358     BtmAclConnection *connection = NULL;
359 
360     ListNode *node = ListGetFirstNode(g_aclList);
361     while (node != NULL) {
362         connection = ListGetNodeData(node);
363         if (connection->transport == TRANSPORT_LE) {
364             if (IsEqualAddr(connection->addr.addr, addr->addr)) {
365                 break;
366             }
367         }
368         connection = NULL;
369         node = ListGetNextNode(node);
370     }
371 
372     return connection;
373 }
374 
BtmAclFindConnectionByHandle(uint16_t handle)375 static BtmAclConnection *BtmAclFindConnectionByHandle(uint16_t handle)
376 {
377     BtmAclConnection *connection = NULL;
378 
379     ListNode *node = ListGetFirstNode(g_aclList);
380     while (node != NULL) {
381         connection = ListGetNodeData(node);
382         if (connection != NULL) {
383             if (connection->connectionHandle == handle) {
384                 break;
385             }
386             connection = NULL;
387         }
388 
389         node = ListGetNextNode(node);
390     }
391 
392     return connection;
393 }
394 
BtmAclCreateConnection(const BtAddr * addr)395 static int BtmAclCreateConnection(const BtAddr *addr)
396 {
397     uint8_t pageScanRepetitionMode = HCI_PAGE_SCAN_REPETITION_MODE_R1;
398     uint16_t clockOffset = 0;
399 
400     BtmInquiryInfo inquiryInfo = {0};
401     int queryResult = BtmQueryInquiryInfoByAddr(addr, &inquiryInfo);
402     if (queryResult == BT_SUCCESS) {
403         pageScanRepetitionMode = inquiryInfo.pageScanRepetitionMode;
404         clockOffset = inquiryInfo.clockOffset;
405     }
406 
407     HciCreateConnectionParam param = {
408         .bdAddr =
409             {
410                 .raw = {0},
411             },
412         .packetType = (HCI_PACKET_TYPE_DM1 | HCI_PACKET_TYPE_DH1 | HCI_PACKET_TYPE_DM3 | HCI_PACKET_TYPE_DH3 |
413                        HCI_PACKET_TYPE_DM5 | HCI_PACKET_TYPE_DH5),
414         .pageScanRepetitionMode = pageScanRepetitionMode,
415         .reserved = 0,
416         .clockOffset = clockOffset,
417         .allowRoleSwitch = BTM_IsControllerSupportRoleSwitch() ? HCI_ALLOW_ROLE_SWITCH : HCI_NOT_ALLOW_ROLE_SWITCH,
418     };
419     (void)memcpy_s(param.bdAddr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
420 
421     return HCI_CreateConnection(&param);
422 }
423 
BTM_AclConnect(const BtAddr * addr)424 int BTM_AclConnect(const BtAddr *addr)
425 {
426     if (addr == NULL) {
427         return BT_BAD_PARAM;
428     }
429 
430     if (!IS_INITIALIZED()) {
431         return BT_BAD_STATUS;
432     }
433 
434     int result = BT_SUCCESS;
435     MutexLock(g_aclListLock);
436     if (ListGetSize(g_aclList) >= BTM_MAX_ACL) {
437         MutexUnlock(g_aclListLock);
438         result = BT_CONNECT_NUM_MAX;
439     } else {
440         BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
441         if (connection != NULL) {
442             if (connection->state != CONNECTING) {
443                 result = BT_BAD_STATUS;
444             }
445             MutexUnlock(g_aclListLock);
446         } else {
447             connection = AllocAclConnection();
448             if (connection != NULL) {
449                 connection->addr = *addr;
450                 connection->transport = TRANSPORT_BREDR;
451                 connection->isInitiator = true;
452                 connection->state = CONNECTING;
453 
454                 ListAddLast(g_aclList, connection);
455             } else {
456                 MutexUnlock(g_aclListLock);
457                 return BT_NO_MEMORY;
458             }
459             result = BtmAclCreateConnection(addr);
460             if (result != BT_SUCCESS) {
461                 ListRemoveNode(g_aclList, connection);
462             }
463 
464             MutexUnlock(g_aclListLock);
465         }
466     }
467 
468     return result;
469 }
470 
BtmAclTimeoutTask(void * context)471 static void BtmAclTimeoutTask(void *context)
472 {
473     BtmAclConnection *connection = (BtmAclConnection *)context;
474     MutexLock(g_aclListLock);
475     ListNode *node = ListGetFirstNode(g_aclList);
476     while (node != NULL) {
477         if (connection == ListGetNodeData(node)) {
478             if (connection->refCount == 0) {
479                 connection->state = DISCONNECTING;
480 
481                 HciDisconnectParam disconnectParam = {
482                     .connectionHandle = connection->connectionHandle,
483                     .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
484                 };
485                 HCI_Disconnect(&disconnectParam);
486             }
487             break;
488         }
489         node = ListGetNextNode(node);
490     }
491     MutexUnlock(g_aclListLock);
492 }
493 
BtmAclTimeout(void * context)494 static void BtmAclTimeout(void *context)
495 {
496     Thread *thread = BTM_GetProcessingThread();
497     if (thread != NULL) {
498         ThreadPostTask(thread, BtmAclTimeoutTask, context);
499     }
500 }
501 
BtmOnConnectionComplete(const HciConnectionCompleteEventParam * eventParam)502 NO_SANITIZE("cfi") static void BtmOnConnectionComplete(const HciConnectionCompleteEventParam *eventParam)
503 {
504     if (eventParam->linkType != HCI_LINK_TYPE_ACL ||
505         (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS)) {
506         return;
507     }
508 
509     BtAddr addr = {0};
510     addr.type = BT_PUBLIC_DEVICE_ADDRESS;
511     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->bdAddr.raw, BT_ADDRESS_SIZE);
512 
513     uint8_t cod[COD_SIZE] = {0, 0, 0};
514 
515     MutexLock(g_aclListLock);
516     BtmAclConnection *connection = BtmAclFindConnectionByAddr(&addr);
517     if (connection != NULL) {
518         if (eventParam->status == HCI_SUCCESS) {
519             connection->connectionHandle = eventParam->connectionHandle;
520             connection->state = CONNECTED;
521 
522             (void)memcpy_s(cod, COD_SIZE, connection->remoteCod, COD_SIZE);
523 
524             AlarmSet(connection->timeoutTimer,
525                 connection->isInitiator ? ACL_TIMEOUT : ACL_PASSIVE_TIMEOUT,
526                 BtmAclTimeout,
527                 connection);
528         } else {
529             ListRemoveNode(g_aclList, connection);
530         }
531     }
532     MutexUnlock(g_aclListLock);
533 
534     if (eventParam->status == HCI_SUCCESS) {
535         HciReadRemoteVersionInformationParam cmdParam = {0};
536         cmdParam.connectionHandle = eventParam->connectionHandle;
537         HCI_ReadRemoteVersionInformation(&cmdParam);
538     }
539 
540     BtmAclConnectCompleteParam connectCompleteParam = {0};
541     connectCompleteParam.status = eventParam->status;
542     connectCompleteParam.connectionHandle = eventParam->connectionHandle;
543     connectCompleteParam.addr = &addr;
544     (void)memcpy_s(connectCompleteParam.classOfDevice, COD_SIZE, cod, COD_SIZE);
545     connectCompleteParam.encyptionEnabled = eventParam->encryptionEnabled;
546 
547     MutexLock(g_aclCallbackListLock);
548 
549     ListNode *node = ListGetFirstNode(g_aclCallbackList);
550     BtmAclCallbacksBlock *block = NULL;
551     while (node != NULL) {
552         block = (BtmAclCallbacksBlock *)ListGetNodeData(node);
553         if (block->callbacks->connectionComplete != NULL) {
554             block->callbacks->connectionComplete(&connectCompleteParam, block->context);
555         }
556         node = ListGetNextNode(node);
557     }
558 
559     MutexUnlock(g_aclCallbackListLock);
560 }
561 
BtmOnConnectionrequest(const HciConnectionRequestEventParam * eventParam)562 static void BtmOnConnectionrequest(const HciConnectionRequestEventParam *eventParam)
563 {
564     if (eventParam->linkType != HCI_LINK_TYPE_ACL) {
565         return;
566     }
567 
568     BtAddr addr = {
569         .addr = {0},
570         .type = BT_PUBLIC_DEVICE_ADDRESS,
571     };
572     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->bdAddr.raw, BT_ADDRESS_SIZE);
573 
574     MutexLock(g_aclListLock);
575     if (ListGetSize(g_aclList) >= BTM_MAX_ACL) {
576         MutexUnlock(g_aclListLock);
577         HciRejectConnectionRequestParam param = {
578             .bdAddr = eventParam->bdAddr,
579             .reason = HCI_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES,
580         };
581         HCI_RejectConnectionRequest(&param);
582         return;
583     }
584 
585     BtmAclConnection *connection = AllocAclConnection();
586     if (connection == NULL) {
587         MutexUnlock(g_aclListLock);
588         return;
589     }
590 
591     connection->addr = addr;
592     connection->transport = TRANSPORT_BREDR;
593     connection->state = CONNECTING;
594     connection->isInitiator = false;
595 
596     (void)memcpy_s(connection->remoteCod, COD_SIZE, eventParam->classOfDevice, COD_SIZE);
597 
598     uint8_t role = HCI_ROLE_SLAVE;
599     if (ListGetSize(g_aclList) > 0) {
600         if (BTM_IsControllerSupportRoleSwitch()) {
601             role = HCI_ROLE_MASTER;
602         }
603     }
604 
605     ListAddLast(g_aclList, connection);
606 
607     HciAcceptConnectionReqestParam acceptParam = {
608         .bdAddr = eventParam->bdAddr,
609         .role = role,
610     };
611     int result = HCI_AcceptConnectionRequest(&acceptParam);
612     if (result != BT_SUCCESS) {
613         ListRemoveNode(g_aclList, connection);
614     }
615 
616     MutexUnlock(g_aclListLock);
617 }
618 
BtmConvertAddressForConnection(BtAddr * addr)619 static void BtmConvertAddressForConnection(BtAddr *addr)
620 {
621     bool localResolve = false;
622     BtAddr address;
623     if (BTM_IsControllerSupportLlPrivacy()) {
624         if (BTM_IsDeviceInResolvingList(addr)) {
625             int result = BTM_GetRemoteIdentityAddress(addr, &address);
626             if (result == BT_SUCCESS) {
627                 *addr = address;
628             }
629         } else {
630             localResolve = true;
631         }
632     } else {
633         localResolve = true;
634     }
635 
636     if (localResolve) {
637         int result = BTM_GetCurrentRemoteAddress(addr, &address);
638         if (result == BT_SUCCESS) {
639             *addr = address;
640         }
641     }
642 }
643 
BtmLeExtendedCreateConnection()644 static int BtmLeExtendedCreateConnection()
645 {
646     uint8_t ownAddressType = LOCAL_ADDR_TYPE_PUBLIC;
647     if (BTM_GetOwnAddressType() == OWN_ADDRESS_TYPE_RANDOM) {
648         ownAddressType = BTM_IsControllerSupportLlPrivacy() ? LOCAL_ADDR_TYPE_RPA_OR_RANDOM : LOCAL_ADDR_TYPE_RANDOM;
649     }
650 
651     uint8_t countOfSets = 1;
652     uint8_t initiatingPhys = LE_1M_PHY;
653     if (BTM_IsControllerSupportLe2MPhy()) {
654         initiatingPhys |= LE_2M_PHY;
655         countOfSets++;
656     }
657     if (BTM_IsControllerSupportLeCodedPhy()) {
658         initiatingPhys |= LE_CODED_PHY;
659         countOfSets++;
660     }
661 
662     uint16_t leScanInterval = g_leScanInterval;
663     uint16_t leScanWindow = g_leScanWindow;
664 
665     HciLeConnectionParamSet *sets = MEM_MALLOC.alloc(sizeof(HciLeConnectionParamSet) * countOfSets);
666     if (sets == NULL) {
667         LOG_ERROR("sets is NULL");
668         return BT_NO_MEMORY;
669     }
670     for (uint8_t i = 0; i < countOfSets; i++) {
671         sets[i].scanInterval = leScanInterval;
672         sets[i].scanWindow = leScanWindow;
673         sets[i].connIntervalMin = LE_CONN_INTERVAL_MIN_DEFAULT;
674         sets[i].connIntervalMax = LE_CONN_INTERVAL_MAX_DEFAULT;
675         sets[i].connLatency = LE_CONN_LATENCY_DEFAULT;
676         sets[i].supervisionTimeout = LE_SUPERVISION_TIMEOUT_DEFAULT;
677         sets[i].minimumCELength = LE_MINIMUM_CE_LENGTH_DEFAULT;
678         sets[i].maximumCELength = LE_MAXIMUM_CE_LENGTH_DEFAULT;
679     }
680 
681     HciLeExtendedCreateConnectionParam param = {
682         .initiatingFilterPolicy = INITIATOR_FILTER_USE_WHITE_LIST,
683         .peerAddressType = 0,
684         .peerAddress = {.raw = {0}},
685         .ownAddressType = ownAddressType,
686         .initiatingPhys = initiatingPhys,
687         .sets = sets,
688     };
689 
690     int result = HCI_LeExtenedCreateConnection(&param);
691 
692     MEM_MALLOC.free(sets);
693 
694     return result;
695 }
696 
BtmStartAutoConnectionInternal()697 static int BtmStartAutoConnectionInternal()
698 {
699     if (BTM_IsControllerSupportLeExtendedAdvertising()) {
700         return BtmLeExtendedCreateConnection();
701     } else {
702         uint8_t ownAddressType = LOCAL_ADDR_TYPE_PUBLIC;
703         if (BTM_GetOwnAddressType() == OWN_ADDRESS_TYPE_RANDOM) {
704             ownAddressType =
705                 BTM_IsControllerSupportLlPrivacy() ? LOCAL_ADDR_TYPE_RPA_OR_RANDOM : LOCAL_ADDR_TYPE_RANDOM;
706         }
707 
708         uint16_t leScanInterval = g_leScanInterval;
709         uint16_t leScanWindow = g_leScanWindow;
710 
711         HciLeCreateConnectionParam param = {
712             .leScanInterval = leScanInterval,
713             .leScanWindow = leScanWindow,
714             .initiatorFilterPolicy = INITIATOR_FILTER_USE_WHITE_LIST,
715             .peerAddressType = 0,
716             .peerAddress =
717                 {
718                     .raw = {0},
719                 },
720             .ownAddressType = ownAddressType,
721             .connIntervalMin = LE_CONN_INTERVAL_MIN_DEFAULT,
722             .connIntervalMax = LE_CONN_INTERVAL_MAX_DEFAULT,
723             .connLatency = LE_CONN_LATENCY_DEFAULT,
724             .supervisionTimeout = LE_SUPERVISION_TIMEOUT_DEFAULT,
725             .minimumCELength = LE_MINIMUM_CE_LENGTH_DEFAULT,
726             .maximumCELength = LE_MAXIMUM_CE_LENGTH_DEFAULT,
727         };
728         return HCI_LeCreateConnection(&param);
729     }
730 }
731 
BtmStartAutoConnection()732 int BtmStartAutoConnection()
733 {
734     int result;
735     MutexLock(g_autoConnectLock);
736     if (BtmGetDeviceCountInWhiteList() > 0) {
737         result = BtmStartAutoConnectionInternal();
738     } else {
739         result = BT_SUCCESS;
740     }
741     MutexUnlock(g_autoConnectLock);
742     return result;
743 }
744 
BtmStopAutoConnectionInternal(void)745 static int BtmStopAutoConnectionInternal(void)
746 {
747     return HCI_LeCreateConnectionCancel();
748 }
749 
BtmStopAutoConnection()750 int BtmStopAutoConnection()
751 {
752     int result;
753     MutexLock(g_autoConnectLock);
754     if (BtmGetDeviceCountInWhiteList() > 0) {
755         result = BtmStopAutoConnectionInternal();
756     } else {
757         result = BT_SUCCESS;
758     }
759     MutexUnlock(g_autoConnectLock);
760     return result;
761 }
762 
BtmUpdateWhiteList()763 static void BtmUpdateWhiteList()
764 {
765     BtmWhiteListPendingAction *action = QueueTryDequeue(g_leWhiteListPendingActionQueue);
766     while (action != NULL) {
767         uint8_t whiteListAddressType = (action->addr.type == BT_PUBLIC_DEVICE_ADDRESS) ? WHITE_LIST_ADDRESS_TYPE_PUBLIC
768                                                                                        : WHITE_LIST_ADDRESS_TYPE_RANDOM;
769         if (action->action == ACTION_ADD_TO_WHITE_LIST) {
770             BtmAddDeviceToWhiteList(whiteListAddressType, &action->addr);
771         } else if (action->action == ACTION_REMOVE_FORM_WHITE_LIST) {
772             BtmRemoveDeviceFromWhiteList(whiteListAddressType, &action->addr);
773         }
774         MEM_MALLOC.free(action);
775 
776         action = QueueTryDequeue(g_leWhiteListPendingActionQueue);
777     }
778 }
779 
BtmLeCreateConnection(const BtAddr * addr)780 static int BtmLeCreateConnection(const BtAddr *addr)
781 {
782     MutexLock(g_autoConnectLock);
783     if (BtmGetDeviceCountInWhiteList() > 0) {
784         BtmWhiteListPendingAction *action = MEM_MALLOC.alloc(sizeof(BtmWhiteListPendingAction));
785         if (action != NULL) {
786             action->action = ACTION_ADD_TO_WHITE_LIST;
787             action->addr = *addr;
788             QueueEnqueue(g_leWhiteListPendingActionQueue, action);
789         }
790         MutexUnlock(g_autoConnectLock);
791         return BtmStopAutoConnectionInternal();
792     } else {
793         uint8_t whiteListAddressType =
794             (addr->type == BT_PUBLIC_DEVICE_ADDRESS) ? WHITE_LIST_ADDRESS_TYPE_PUBLIC : WHITE_LIST_ADDRESS_TYPE_RANDOM;
795         BtmAddDeviceToWhiteList(whiteListAddressType, addr);
796         MutexUnlock(g_autoConnectLock);
797         return BtmStartAutoConnectionInternal();
798     }
799 }
800 
BTM_LeConnect(const BtAddr * addr)801 int BTM_LeConnect(const BtAddr *addr)
802 {
803     if (addr == NULL) {
804         return BT_BAD_PARAM;
805     }
806 
807     if (!IS_INITIALIZED()) {
808         return BT_BAD_STATUS;
809     }
810 
811     int result = BT_SUCCESS;
812 
813     BtAddr leAddr = *addr;
814     BtmConvertAddressForConnection(&leAddr);
815 
816     MutexLock(g_aclListLock);
817 
818     if (ListGetSize(g_aclList) >= BTM_MAX_ACL) {
819         MutexUnlock(g_aclListLock);
820         return BT_CONNECT_NUM_MAX;
821     }
822 
823     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
824     if (connection != NULL) {
825         if (connection->state != CONNECTING) {
826             result = BT_BAD_STATUS;
827         }
828     } else {
829         connection = AllocAclConnection();
830         if (connection != NULL) {
831             connection->addr = *addr;
832             connection->transport = TRANSPORT_LE;
833             connection->isInitiator = true;
834             connection->state = CONNECTING;
835 
836             if (BTM_GetOwnAddressType() == OWN_ADDRESS_TYPE_RANDOM) {
837                 // Random Address
838                 BTM_GetLeRandomAddress(&connection->leLocalAddr);
839             } else {
840                 // Public Address
841                 BTM_GetLocalAddr(&connection->leLocalAddr);
842             }
843 
844             connection->lePeerAddr = leAddr;
845 
846             ListAddLast(g_aclList, connection);
847         }
848 
849         result = BtmLeCreateConnection(&leAddr);
850     }
851 
852     MutexUnlock(g_aclListLock);
853 
854     return result;
855 }
856 
BtmConvertAddressForConnectionComplete(BtAddr * addr)857 static void BtmConvertAddressForConnectionComplete(BtAddr *addr)
858 {
859     BtAddr pairedAddress;
860     int result = BTM_ConvertToPairedAddress(addr, &pairedAddress);
861     if (result == BT_SUCCESS) {
862         *addr = pairedAddress;
863     }
864 }
865 
BtmRemoveAllConnectingLeConnection()866 static void BtmRemoveAllConnectingLeConnection()
867 {
868     BtmAclConnection *connection = NULL;
869     ListNode *node = ListGetFirstNode(g_aclList);
870     while (node != NULL) {
871         connection = ListGetNodeData(node);
872         node = ListGetNextNode(node);
873         if (connection->transport == TRANSPORT_LE && connection->state == CONNECTING) {
874             ListRemoveNode(g_aclList, connection);
875         }
876     }
877 }
878 
BtmUpdateLeConnectionOnConnectComplete(const BtAddr * addr,uint8_t peerAddrType,const HciLeConnectionCompleteEventParam * eventParam)879 static void BtmUpdateLeConnectionOnConnectComplete(
880     const BtAddr *addr, uint8_t peerAddrType, const HciLeConnectionCompleteEventParam *eventParam)
881 {
882     MutexLock(g_aclListLock);
883 
884     if (eventParam->status == HCI_SUCCESS) {
885         BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
886         if (connection != NULL) {
887             connection->connectionHandle = eventParam->connectionHandle;
888             connection->state = CONNECTED;
889 
890             (void)memcpy_s(connection->lePeerAddr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
891             connection->lePeerAddr.type = peerAddrType;
892         } else {
893             connection = AllocAclConnection();
894             if (connection == NULL) {
895                 MutexUnlock(g_aclListLock);
896                 return;
897             }
898 
899             connection->addr = *addr;
900             connection->connectionHandle = eventParam->connectionHandle;
901             connection->transport = TRANSPORT_LE;
902             connection->state = CONNECTED;
903             connection->isInitiator = false;
904 
905             if (BTM_GetOwnAddressType() == OWN_ADDRESS_TYPE_RANDOM) {
906                 // Random Address
907                 BTM_GetLeRandomAddress(&connection->leLocalAddr);
908             } else {
909                 // Public Address
910                 BTM_GetLocalAddr(&connection->leLocalAddr);
911             }
912 
913             (void)memcpy_s(connection->lePeerAddr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
914             connection->lePeerAddr.type = peerAddrType;
915 
916             ListAddLast(g_aclList, connection);
917         }
918     } else if (eventParam->status == HCI_UNKNOWN_CONNECTION_IDENTIFIER) {
919         // Cancel. Do nothing.
920     } else if (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS) {
921         // Already exists. Do nothing.
922     } else {
923         BtmRemoveAllConnectingLeConnection();
924     }
925 
926     MutexUnlock(g_aclListLock);
927 }
928 
BtmLeCancelConnectCallback(uint8_t status)929 NO_SANITIZE("cfi") static void BtmLeCancelConnectCallback(uint8_t status)
930 {
931     MutexLock(g_leConnectionCancelLock);
932 
933     ListNode *node1 = ListGetFirstNode(g_leConnectionCancelList);
934     BtAddr *addr = NULL;
935 
936     ListNode *node2 = NULL;
937     BtmAclCallbacksBlock *block = NULL;
938 
939     while (node1 != NULL) {
940         addr = ListGetNodeData(node1);
941 
942         MutexLock(g_aclCallbackListLock);
943         node2 = ListGetFirstNode(g_aclCallbackList);
944 
945         while (node2 != NULL) {
946             block = (BtmAclCallbacksBlock *)ListGetNodeData(node2);
947             if (block->callbacks->leConnectionComplete != NULL) {
948                 block->callbacks->leConnectionComplete(status, 0, addr, 0, block->context);
949             }
950             node2 = ListGetNextNode(node2);
951         }
952         MutexUnlock(g_aclCallbackListLock);
953 
954         node1 = ListGetNextNode(node1);
955     }
956 
957     ListClear(g_leConnectionCancelList);
958 
959     MutexUnlock(g_leConnectionCancelLock);
960 }
961 
BtmLeReadRemoteFeatures(uint16_t connectionHandle)962 static void BtmLeReadRemoteFeatures(uint16_t connectionHandle)
963 {
964     HciLeReadRemoteFeaturesParam cmdParam = {
965         .connectionHandle = connectionHandle,
966     };
967     HCI_LeReadRemoteFeatures(&cmdParam);
968 }
969 
BtmOnLeConnectCallback(const BtAddr * addrList,uint8_t addrCount,uint8_t status,uint16_t connectionHandle,uint16_t role)970 NO_SANITIZE("cfi") static void BtmOnLeConnectCallback(
971     const BtAddr *addrList, uint8_t addrCount, uint8_t status, uint16_t connectionHandle, uint16_t role)
972 {
973     MutexLock(g_aclCallbackListLock);
974 
975     ListNode *node = NULL;
976     BtmAclCallbacksBlock *block = NULL;
977 
978     for (uint8_t i = 0; i < addrCount; i++) {
979         node = ListGetFirstNode(g_aclCallbackList);
980         while (node != NULL) {
981             block = (BtmAclCallbacksBlock *)ListGetNodeData(node);
982             if (block->callbacks->leConnectionComplete != NULL) {
983                 block->callbacks->leConnectionComplete(status, connectionHandle, addrList + i, role, block->context);
984             }
985             node = ListGetNextNode(node);
986         }
987     }
988 
989     MutexUnlock(g_aclCallbackListLock);
990 }
991 
BtmGetLeConnectingAddr(BtAddr ** addrList,uint8_t * addrCount)992 static void BtmGetLeConnectingAddr(BtAddr **addrList, uint8_t *addrCount)
993 {
994     MutexLock(g_aclListLock);
995 
996     uint8_t count = 0;
997     BtmAclConnection *connection = NULL;
998 
999     ListNode *node = ListGetFirstNode(g_aclList);
1000     while (node != NULL) {
1001         connection = ListGetNodeData(node);
1002         if ((connection->transport == TRANSPORT_LE) && (connection->state == CONNECTING)) {
1003             count++;
1004         }
1005         connection = NULL;
1006         node = ListGetNextNode(node);
1007     }
1008 
1009     if (count > 0) {
1010         *addrList = MEM_CALLOC.alloc(sizeof(BtAddr) * count);
1011         *addrCount = count;
1012     }
1013 
1014     if (*addrList != NULL) {
1015         uint8_t index = 0;
1016         node = ListGetFirstNode(g_aclList);
1017         while (node != NULL) {
1018             connection = ListGetNodeData(node);
1019             if (connection->transport == TRANSPORT_LE && connection->state == CONNECTING) {
1020                 (*addrList)[index] = connection->addr;
1021                 index++;
1022             }
1023             connection = NULL;
1024             node = ListGetNextNode(node);
1025         }
1026     }
1027 
1028     MutexUnlock(g_aclListLock);
1029 }
1030 
IsZeroAddress(const uint8_t addr[BT_ADDRESS_SIZE])1031 static bool IsZeroAddress(const uint8_t addr[BT_ADDRESS_SIZE])
1032 {
1033     bool isZeroAddress = true;
1034     for (uint8_t i = 0; i < BT_ADDRESS_SIZE; i++) {
1035         if (addr[i] != 0) {
1036             isZeroAddress = false;
1037             break;
1038         }
1039     }
1040     return isZeroAddress;
1041 }
1042 
BtmUpdateUpdateWhiteListOnLeConnectionComplete(const BtAddr * addrList,const uint8_t addrCount,const HciLeConnectionCompleteEventParam * eventParam)1043 static void BtmUpdateUpdateWhiteListOnLeConnectionComplete(
1044     const BtAddr *addrList, const uint8_t addrCount, const HciLeConnectionCompleteEventParam *eventParam)
1045 {
1046     MutexLock(g_autoConnectLock);
1047     BtAddr addr = {
1048         .addr = {0},
1049         .type = (eventParam->peerAddressType == HCI_PEER_ADDR_TYPE_PUBLIC) ? BT_PUBLIC_DEVICE_ADDRESS
1050                                                                            : BT_RANDOM_DEVICE_ADDRESS,
1051     };
1052     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
1053 
1054     bool restartAutoConnection = false;
1055     if (eventParam->status == HCI_SUCCESS) {
1056         uint8_t whiteListAddrType = (eventParam->peerAddressType == HCI_PEER_ADDR_TYPE_PUBLIC)
1057                                         ? WHITE_LIST_ADDRESS_TYPE_PUBLIC
1058                                         : WHITE_LIST_ADDRESS_TYPE_RANDOM;
1059         restartAutoConnection = BtmIsDeviceInWhiteList(whiteListAddrType, &addr);
1060     } else if (eventParam->status == HCI_UNKNOWN_CONNECTION_IDENTIFIER) {
1061         restartAutoConnection = true;
1062     } else if (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS) {
1063         restartAutoConnection = true;
1064     }
1065 
1066     BtmUpdateWhiteList();
1067 
1068     if ((eventParam->status == HCI_SUCCESS) || (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS)) {
1069         uint8_t addrType =
1070             (addr.type == BT_PUBLIC_DEVICE_ADDRESS) ? WHITE_LIST_ADDRESS_TYPE_PUBLIC : WHITE_LIST_ADDRESS_TYPE_RANDOM;
1071         BtmRemoveDeviceFromWhiteList(addrType, &addr);
1072     } else if (eventParam->status == HCI_UNKNOWN_CONNECTION_IDENTIFIER) {
1073         // Cancel. Do nothing.
1074     } else {
1075         for (uint8_t i = 0; i < addrCount; i++) {
1076             uint8_t addrType = ((addrList + i)->type == BT_PUBLIC_DEVICE_ADDRESS) ? WHITE_LIST_ADDRESS_TYPE_PUBLIC
1077                                                                                   : WHITE_LIST_ADDRESS_TYPE_RANDOM;
1078             BtmRemoveDeviceFromWhiteList(addrType, addrList + i);
1079         }
1080     }
1081 
1082     if (BtmGetDeviceCountInWhiteList() > 0 && restartAutoConnection) {
1083         BtmStartAutoConnection();
1084     }
1085     MutexUnlock(g_autoConnectLock);
1086 }
1087 
BtmOnLeConnectionComplete(const HciLeConnectionCompleteEventParam * eventParam)1088 static void BtmOnLeConnectionComplete(const HciLeConnectionCompleteEventParam *eventParam)
1089 {
1090     uint8_t peerAddrType = (eventParam->peerAddressType == HCI_PEER_ADDR_TYPE_PUBLIC) ? BT_PUBLIC_DEVICE_ADDRESS
1091                                                                                       : BT_RANDOM_DEVICE_ADDRESS;
1092 
1093     BtAddr addr = {
1094         .addr = {0},
1095         .type = peerAddrType,
1096     };
1097     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
1098 
1099     if (!IsZeroAddress(addr.addr)) {
1100         BtmConvertAddressForConnectionComplete(&addr);
1101     }
1102 
1103     BtAddr *addrList = NULL;
1104     uint8_t addrCount = 0;
1105     BtmGetLeConnectingAddr(&addrList, &addrCount);
1106 
1107     BtmUpdateLeConnectionOnConnectComplete(&addr, peerAddrType, eventParam);
1108 
1109     if (eventParam->status == HCI_SUCCESS) {
1110         BtmLeReadRemoteFeatures(eventParam->connectionHandle);
1111     }
1112 
1113     BtmUpdateUpdateWhiteListOnLeConnectionComplete(addrList, addrCount, eventParam);
1114 
1115     switch (eventParam->status) {
1116         case HCI_SUCCESS:
1117             BtmOnLeConnectCallback(&addr, 1, eventParam->status, eventParam->connectionHandle, eventParam->role);
1118             break;
1119         case HCI_UNKNOWN_CONNECTION_IDENTIFIER:
1120             BtmLeCancelConnectCallback(eventParam->status);
1121             break;
1122         case HCI_CONNECTION_ALREADY_EXISTS:
1123             break;
1124         default:
1125             BtmOnLeConnectCallback(
1126                 addrList, addrCount, eventParam->status, eventParam->connectionHandle, eventParam->role);
1127             break;
1128     }
1129 
1130     if (addrList != NULL) {
1131         MEM_CALLOC.free(addrList);
1132     }
1133 }
1134 
BtmUpdateLeConnectionOnEnhancedConnectComplete(BtmAclConnection * connection,uint8_t peerAddrType,const HciLeEnhancedConnectionCompleteEventParam * eventParam)1135 static void BtmUpdateLeConnectionOnEnhancedConnectComplete(
1136     BtmAclConnection *connection, uint8_t peerAddrType, const HciLeEnhancedConnectionCompleteEventParam *eventParam)
1137 {
1138     connection->connectionHandle = eventParam->connectionHandle;
1139     connection->state = CONNECTED;
1140 
1141     if (!IsZeroAddress(eventParam->localResolvablePrivateAddress.raw)) {
1142         (void)memcpy_s(connection->leLocalAddr.addr,
1143             BT_ADDRESS_SIZE,
1144             eventParam->localResolvablePrivateAddress.raw,
1145             BT_ADDRESS_SIZE);
1146         connection->leLocalAddr.type = BT_RANDOM_DEVICE_ADDRESS;
1147     }
1148     if (!IsZeroAddress(eventParam->peerResolvablePrivateAddress.raw)) {
1149         (void)memcpy_s(connection->lePeerAddr.addr,
1150             BT_ADDRESS_SIZE,
1151             eventParam->peerResolvablePrivateAddress.raw,
1152             BT_ADDRESS_SIZE);
1153         connection->lePeerAddr.type = BT_RANDOM_DEVICE_ADDRESS;
1154     }
1155 }
1156 
BtmAllocLeConnectionOnEnhancedConnectComplete(const BtAddr * addr,uint8_t peerAddrType,const HciLeEnhancedConnectionCompleteEventParam * eventParam)1157 static void BtmAllocLeConnectionOnEnhancedConnectComplete(
1158     const BtAddr *addr, uint8_t peerAddrType, const HciLeEnhancedConnectionCompleteEventParam *eventParam)
1159 {
1160     BtmAclConnection *connection = AllocAclConnection();
1161     if (connection == NULL) {
1162         return;
1163     }
1164 
1165     connection->addr = *addr;
1166     connection->connectionHandle = eventParam->connectionHandle;
1167     connection->transport = TRANSPORT_LE;
1168     connection->state = CONNECTED;
1169     connection->isInitiator = false;
1170 
1171     if (!IsZeroAddress(eventParam->localResolvablePrivateAddress.raw)) {
1172         (void)memcpy_s(connection->leLocalAddr.addr,
1173             BT_ADDRESS_SIZE,
1174             eventParam->localResolvablePrivateAddress.raw,
1175             BT_ADDRESS_SIZE);
1176         connection->leLocalAddr.type = BT_RANDOM_DEVICE_ADDRESS;
1177     } else {
1178         if (BTM_GetOwnAddressType() == OWN_ADDRESS_TYPE_RANDOM) {
1179             // Random Address
1180             BTM_GetLeRandomAddress(&connection->leLocalAddr);
1181         } else {
1182             // Public Address
1183             BTM_GetLocalAddr(&connection->leLocalAddr);
1184         }
1185     }
1186 
1187     if (!IsZeroAddress(eventParam->peerResolvablePrivateAddress.raw)) {
1188         (void)memcpy_s(connection->lePeerAddr.addr,
1189             BT_ADDRESS_SIZE,
1190             eventParam->peerResolvablePrivateAddress.raw,
1191             BT_ADDRESS_SIZE);
1192         connection->lePeerAddr.type = BT_RANDOM_DEVICE_ADDRESS;
1193     } else {
1194         (void)memcpy_s(connection->lePeerAddr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
1195         connection->lePeerAddr.type = peerAddrType;
1196     }
1197 
1198     ListAddLast(g_aclList, connection);
1199 }
1200 
BtmUpdateConnectionInfoOnLeEnhancedConnectionComplete(const BtAddr * addr,uint8_t peerAddrType,const HciLeEnhancedConnectionCompleteEventParam * eventParam)1201 static void BtmUpdateConnectionInfoOnLeEnhancedConnectionComplete(
1202     const BtAddr *addr, uint8_t peerAddrType, const HciLeEnhancedConnectionCompleteEventParam *eventParam)
1203 {
1204     MutexLock(g_aclListLock);
1205 
1206     if (eventParam->status == HCI_SUCCESS) {
1207         BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1208         if (connection != NULL) {
1209             BtmUpdateLeConnectionOnEnhancedConnectComplete(connection, peerAddrType, eventParam);
1210         } else {
1211             BtmAllocLeConnectionOnEnhancedConnectComplete(addr, peerAddrType, eventParam);
1212         }
1213     } else if (eventParam->status == HCI_UNKNOWN_CONNECTION_IDENTIFIER) {
1214         // Cancel. Do nothing.
1215     } else if (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS) {
1216         // Already exists. Do nothing.
1217     } else {
1218         BtmRemoveAllConnectingLeConnection();
1219     }
1220 
1221     MutexUnlock(g_aclListLock);
1222 }
1223 
BtmUpdateWhiteListOnLeEnhancedConnectionComplete(const BtAddr * addrList,const uint8_t addrCount,const HciLeEnhancedConnectionCompleteEventParam * eventParam)1224 static void BtmUpdateWhiteListOnLeEnhancedConnectionComplete(
1225     const BtAddr *addrList, const uint8_t addrCount, const HciLeEnhancedConnectionCompleteEventParam *eventParam)
1226 {
1227     MutexLock(g_autoConnectLock);
1228     BtAddr addr = {
1229         .addr = {0},
1230         .type = (eventParam->peerAddressType == HCI_PEER_ADDR_TYPE_PUBLIC) ? BT_PUBLIC_DEVICE_ADDRESS
1231                                                                            : BT_RANDOM_DEVICE_ADDRESS,
1232     };
1233     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
1234 
1235     bool restartAutoConnection = false;
1236     if (eventParam->status == HCI_SUCCESS) {
1237         uint8_t whiteListAddrType = (eventParam->peerAddressType == HCI_PEER_ADDR_TYPE_PUBLIC)
1238                                         ? WHITE_LIST_ADDRESS_TYPE_PUBLIC
1239                                         : WHITE_LIST_ADDRESS_TYPE_RANDOM;
1240         restartAutoConnection = BtmIsDeviceInWhiteList(whiteListAddrType, &addr);
1241     } else if (eventParam->status == HCI_UNKNOWN_CONNECTION_IDENTIFIER) {
1242         restartAutoConnection = true;
1243     } else if (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS) {
1244         restartAutoConnection = true;
1245     }
1246 
1247     BtmUpdateWhiteList();
1248 
1249     if ((eventParam->status == HCI_SUCCESS) || (eventParam->status == HCI_CONNECTION_ALREADY_EXISTS)) {
1250         uint8_t addrType =
1251             (addr.type == BT_PUBLIC_DEVICE_ADDRESS) ? WHITE_LIST_ADDRESS_TYPE_PUBLIC : WHITE_LIST_ADDRESS_TYPE_RANDOM;
1252         BtmRemoveDeviceFromWhiteList(addrType, &addr);
1253     } else if (eventParam->status == HCI_UNKNOWN_CONNECTION_IDENTIFIER) {
1254         // Cancel. Do nothing.
1255     } else {
1256         for (uint8_t i = 0; i < addrCount; i++) {
1257             uint8_t addrType = ((addrList + i)->type == BT_PUBLIC_DEVICE_ADDRESS) ? WHITE_LIST_ADDRESS_TYPE_PUBLIC
1258                                                                                   : WHITE_LIST_ADDRESS_TYPE_RANDOM;
1259             BtmRemoveDeviceFromWhiteList(addrType, addrList + i);
1260         }
1261     }
1262 
1263     if (BtmGetDeviceCountInWhiteList() > 0 && restartAutoConnection) {
1264         BtmStartAutoConnectionInternal();
1265     }
1266     MutexUnlock(g_autoConnectLock);
1267 }
1268 
BtmOnLeEnhancedConnectionComplete(const HciLeEnhancedConnectionCompleteEventParam * eventParam)1269 static void BtmOnLeEnhancedConnectionComplete(const HciLeEnhancedConnectionCompleteEventParam *eventParam)
1270 {
1271     uint8_t peerAddrType = (eventParam->peerAddressType == HCI_PEER_ADDR_TYPE_PUBLIC) ? BT_PUBLIC_DEVICE_ADDRESS
1272                                                                                       : BT_RANDOM_DEVICE_ADDRESS;
1273 
1274     BtAddr addr = {
1275         .addr = {0},
1276         .type = peerAddrType,
1277     };
1278     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->peerAddress.raw, BT_ADDRESS_SIZE);
1279 
1280     if (!IsZeroAddress(addr.addr)) {
1281         BtmConvertAddressForConnectionComplete(&addr);
1282     }
1283 
1284     BtAddr *addrList = NULL;
1285     uint8_t addrCount = 0;
1286     BtmGetLeConnectingAddr(&addrList, &addrCount);
1287 
1288     BtmUpdateConnectionInfoOnLeEnhancedConnectionComplete(&addr, peerAddrType, eventParam);
1289 
1290     if (eventParam->status == HCI_SUCCESS) {
1291         BtmLeReadRemoteFeatures(eventParam->connectionHandle);
1292     }
1293 
1294     BtmUpdateWhiteListOnLeEnhancedConnectionComplete(addrList, addrCount, eventParam);
1295 
1296     switch (eventParam->status) {
1297         case HCI_SUCCESS:
1298             BtmOnLeConnectCallback(&addr, 1, eventParam->status, eventParam->connectionHandle, eventParam->role);
1299             break;
1300         case HCI_UNKNOWN_CONNECTION_IDENTIFIER:
1301             BtmLeCancelConnectCallback(eventParam->status);
1302             break;
1303         case HCI_CONNECTION_ALREADY_EXISTS:
1304             break;
1305         default:
1306             BtmOnLeConnectCallback(
1307                 addrList, addrCount, eventParam->status, eventParam->connectionHandle, eventParam->role);
1308             break;
1309     }
1310 
1311     if (addrList != NULL) {
1312         MEM_CALLOC.free(addrList);
1313     }
1314 }
1315 
BTM_GetAclTranspot(uint16_t connectionHandle)1316 uint8_t BTM_GetAclTranspot(uint16_t connectionHandle)
1317 {
1318     if (!IS_INITIALIZED()) {
1319         return -1;
1320     }
1321 
1322     uint8_t transport = -1;
1323     MutexLock(g_aclListLock);
1324     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1325     if (connection != NULL) {
1326         transport = connection->transport;
1327     }
1328     MutexUnlock(g_aclListLock);
1329     return transport;
1330 }
1331 
BTM_AclDisconnect(uint16_t connectionHandle,uint8_t reason)1332 int BTM_AclDisconnect(uint16_t connectionHandle, uint8_t reason)
1333 {
1334     if (!IS_INITIALIZED()) {
1335         return BT_BAD_STATUS;
1336     }
1337 
1338     int result = BT_SUCCESS;
1339     MutexLock(g_aclListLock);
1340     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1341     if (connection != NULL) {
1342         if (connection->state != DISCONNECTING) {
1343             connection->state = DISCONNECTING;
1344 
1345             HciDisconnectParam param = {
1346                 .connectionHandle = connectionHandle,
1347                 .reason = reason,
1348             };
1349             result = HCI_Disconnect(&param);
1350         }
1351     } else {
1352         result = BT_BAD_STATUS;
1353     }
1354     MutexUnlock(g_aclListLock);
1355     return result;
1356 }
1357 
BtmOnDisconnectComplete(const HciDisconnectCompleteEventParam * eventParam)1358 NO_SANITIZE("cfi") static void BtmOnDisconnectComplete(const HciDisconnectCompleteEventParam *eventParam)
1359 {
1360     uint8_t transport = 0;
1361 
1362     MutexLock(g_aclListLock);
1363     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1364     if (connection != NULL) {
1365         transport = connection->transport;
1366 
1367         if (eventParam->status == HCI_SUCCESS) {
1368             connection->state = DISCONNECTED;
1369             ListRemoveNode(g_aclList, connection);
1370             connection = NULL;
1371         }
1372     }
1373     MutexUnlock(g_aclListLock);
1374 
1375     MutexLock(g_aclCallbackListLock);
1376     ListNode *node = ListGetFirstNode(g_aclCallbackList);
1377     BtmAclCallbacksBlock *block = NULL;
1378     while (node != NULL) {
1379         block = (BtmAclCallbacksBlock *)ListGetNodeData(node);
1380         if (transport == TRANSPORT_BREDR) {
1381             if (block->callbacks->disconnectionComplete != NULL) {
1382                 block->callbacks->disconnectionComplete(
1383                     eventParam->status, eventParam->connectionHandle, eventParam->reason, block->context);
1384             }
1385         } else if (transport == TRANSPORT_LE) {
1386             if (block->callbacks->leDisconnectionComplete != NULL) {
1387                 block->callbacks->leDisconnectionComplete(
1388                     eventParam->status, eventParam->connectionHandle, eventParam->reason, block->context);
1389             }
1390         }
1391         node = ListGetNextNode(node);
1392     }
1393     MutexUnlock(g_aclCallbackListLock);
1394 }
1395 
BtmGetRemoteDeviceSupportRequests(uint16_t connectionHandle,BtmRemoteDeviceSupportEvent event,List * requests)1396 static void BtmGetRemoteDeviceSupportRequests(
1397     uint16_t connectionHandle, BtmRemoteDeviceSupportEvent event, List *requests)
1398 {
1399     BtmRemoteDeviceSupportRequest *request = NULL;
1400     BtmRemoteDeviceSupportRequest *duplicated = NULL;
1401 
1402     ListNode *node = ListGetFirstNode(g_remoteSupportRequestList);
1403     while (node != NULL) {
1404         request = ListGetNodeData(node);
1405         node = ListGetNextNode(node);
1406 
1407         if (request->event == event && request->connectionHandle == connectionHandle) {
1408             duplicated = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
1409             if (duplicated != NULL) {
1410                 *duplicated = *request;
1411                 ListAddLast(requests, duplicated);
1412             }
1413 
1414             ListRemoveNode(g_remoteSupportRequestList, request);
1415         }
1416     }
1417 }
1418 
BtmOnLeRemoteFeatureComplete(const BtAddr * addr,const List * requests,const HciLeFeatures * leFeatures)1419 static void BtmOnLeRemoteFeatureComplete(const BtAddr *addr, const List *requests, const HciLeFeatures *leFeatures)
1420 {
1421     BtmRemoteDeviceSupportRequest *request = NULL;
1422     ListNode *node = ListGetFirstNode(requests);
1423     while (node != NULL) {
1424         request = ListGetNodeData(node);
1425 
1426         switch (request->feature.leFreature) {
1427             case CONNECTION_PARAMETER_REQUEST:
1428                 request->callback(addr, HCI_SUPPORT_CONNECTION_PARAMETERS_REQUEST_PROCEDURE(leFeatures->raw));
1429                 break;
1430             default:
1431                 break;
1432         }
1433 
1434         node = ListGetNextNode(node);
1435     }
1436 }
1437 
BtmOnLeReadRemoteFeaturesComplete(const HciLeReadRemoteFeaturesCompleteEventParam * eventParam)1438 static void BtmOnLeReadRemoteFeaturesComplete(const HciLeReadRemoteFeaturesCompleteEventParam *eventParam)
1439 {
1440     BtAddr addr = {0};
1441     HciLeFeatures leFeatures = {0};
1442     List *requests = ListCreate(MEM_MALLOC.free);
1443 
1444     MutexLock(g_aclListLock);
1445     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1446     if (connection != NULL) {
1447         connection->remoteFeatures.le.featureStatus = eventParam->status;
1448         if (eventParam->status == HCI_SUCCESS) {
1449             connection->remoteFeatures.le.leFeatures = eventParam->leFeatures;
1450         }
1451 
1452         addr = connection->addr;
1453         leFeatures = connection->remoteFeatures.le.leFeatures;
1454         BtmGetRemoteDeviceSupportRequests(eventParam->connectionHandle, REMOTE_LE_FEATURE_COMPLETE, requests);
1455     }
1456     MutexUnlock(g_aclListLock);
1457 
1458     if (eventParam->status == HCI_SUCCESS) {
1459         HciReadRemoteVersionInformationParam cmdParam = {
1460             .connectionHandle = eventParam->connectionHandle,
1461         };
1462         HCI_ReadRemoteVersionInformation(&cmdParam);
1463     }
1464 
1465     if (ListGetSize(requests)) {
1466         BtmOnLeRemoteFeatureComplete(&addr, requests, &leFeatures);
1467     }
1468 
1469     ListDelete(requests);
1470 }
1471 
BtmOnReadRemoteVersionInformationComplete(const HciReadRemoteVersionInformationCompleteEventParam * eventParam)1472 static void BtmOnReadRemoteVersionInformationComplete(
1473     const HciReadRemoteVersionInformationCompleteEventParam *eventParam)
1474 {
1475     uint8_t transport = 0;
1476 
1477     MutexLock(g_aclListLock);
1478     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1479     if (connection != NULL) {
1480         if (eventParam->status == HCI_SUCCESS) {
1481             connection->remoteVersion.version = eventParam->version;
1482             connection->remoteVersion.manufactureName = eventParam->manufacturerName;
1483             connection->remoteVersion.subVersion = eventParam->subVersion;
1484         }
1485 
1486         transport = connection->transport;
1487     }
1488     MutexUnlock(g_aclListLock);
1489 
1490     if (transport == TRANSPORT_BREDR) {
1491         HciReadRemoteSupportedFeaturesParam cmdParam = {
1492             .connectionHandle = eventParam->connectionHandle,
1493         };
1494         HCI_ReadRemoteSupportedFeatures(&cmdParam);
1495     }
1496 }
1497 
BtmOnRemoteFeatureComplete(const BtAddr * addr,const List * requests,const HciLmpFeatures * lmpFeatures)1498 static void BtmOnRemoteFeatureComplete(const BtAddr *addr, const List *requests, const HciLmpFeatures *lmpFeatures)
1499 {
1500     BtmRemoteDeviceSupportRequest *request = NULL;
1501     ListNode *node = ListGetFirstNode(requests);
1502     while (node != NULL) {
1503         request = ListGetNodeData(node);
1504 
1505         switch (request->feature.feature) {
1506             case EDR_ACL_2MB_MODE:
1507                 request->callback(addr, HCI_SUPPORT_EDR_ACL_2MBS_MODE(lmpFeatures->raw));
1508                 break;
1509             case EDR_ACL_3MB_MODE:
1510                 request->callback(addr, HCI_SUPPORT_EDR_ACL_3MBS_MODE(lmpFeatures->raw));
1511                 break;
1512             default:
1513                 break;
1514         }
1515 
1516         node = ListGetNextNode(node);
1517     }
1518 }
1519 
BtmOnReadRemoteSupportedFeaturesComplete(const HciReadRemoteSupportedFeaturesCompleteEventParam * eventParam)1520 static void BtmOnReadRemoteSupportedFeaturesComplete(const HciReadRemoteSupportedFeaturesCompleteEventParam *eventParam)
1521 {
1522     BtAddr addr = {0};
1523     HciLmpFeatures lmpFeatures = {0};
1524     List *requests = ListCreate(MEM_MALLOC.free);
1525 
1526     MutexLock(g_aclListLock);
1527     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1528     if (connection != NULL) {
1529         connection->remoteFeatures.bredr.featureStatus = eventParam->status;
1530         if (eventParam->status == HCI_SUCCESS) {
1531             connection->remoteFeatures.bredr.lmpFeatures = eventParam->lmpFeatures;
1532         }
1533 
1534         addr = connection->addr;
1535         lmpFeatures = connection->remoteFeatures.bredr.lmpFeatures;
1536         BtmGetRemoteDeviceSupportRequests(eventParam->connectionHandle, REMOTE_FEATURE_COMPLETE, requests);
1537     }
1538     MutexUnlock(g_aclListLock);
1539 
1540     HciReadRemoteExtendedFeaturesParam cmdParam = {
1541         .connectionHandle = eventParam->connectionHandle,
1542         .pageNumber = 0,
1543     };
1544     HCI_ReadRemoteExtendedFeatures(&cmdParam);
1545 
1546     if (ListGetSize(requests)) {
1547         BtmOnRemoteFeatureComplete(&addr, requests, &lmpFeatures);
1548     }
1549 
1550     ListDelete(requests);
1551 }
1552 
BtmOnRemoteExtendedFeatureComplete(const BtAddr * addr,const List * requests,const HciExtendedLmpFeatures * extendedFeatures)1553 static void BtmOnRemoteExtendedFeatureComplete(
1554     const BtAddr *addr, const List *requests, const HciExtendedLmpFeatures *extendedFeatures)
1555 {
1556     BtmRemoteDeviceSupportRequest *request = NULL;
1557 
1558     ListNode *node = ListGetFirstNode(requests);
1559     while (node != NULL) {
1560         request = ListGetNodeData(node);
1561 
1562         switch (request->feature.extendedFeature) {
1563             case SECURE_SIMPLE_PAIRING_HOST_SUPPORT:
1564                 request->callback(addr, HCI_SUPPORT_SECURE_SIMPLE_PAIRING_HOST(extendedFeatures->page[1]));
1565                 break;
1566             default:
1567                 break;
1568         }
1569 
1570         node = ListGetNextNode(node);
1571     }
1572 }
1573 
BtmOnReadRemoteExtendedFeaturesComplete(const HciReadRemoteExtendedFeaturesCompleteEventParam * eventParam)1574 static void BtmOnReadRemoteExtendedFeaturesComplete(const HciReadRemoteExtendedFeaturesCompleteEventParam *eventParam)
1575 {
1576     uint8_t nextPageNumber = 0;
1577     BtAddr addr = {0};
1578     HciExtendedLmpFeatures extendedFeatures = {0};
1579     List *requests = ListCreate(MEM_MALLOC.free);
1580 
1581     MutexLock(g_aclListLock);
1582     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1583     if (connection != NULL) {
1584         uint8_t status = REQUEST_NOT_COMPLETED;
1585         if (eventParam->status == HCI_SUCCESS) {
1586             connection->remoteFeatures.bredr.maxPageNumber = eventParam->maximumPageNumber;
1587             if (eventParam->pageNumber <= MAX_EXTENED_FEATURES_PAGE_NUMBER) {
1588                 (void)memcpy_s(connection->remoteFeatures.bredr.extendedLmpFeatures.page[eventParam->pageNumber],
1589                     LMP_FEATURES_SIZE,
1590                     eventParam->extendedLMPFeatures,
1591                     LMP_FEATURES_SIZE);
1592             }
1593 
1594             if (eventParam->pageNumber < eventParam->maximumPageNumber) {
1595                 nextPageNumber = eventParam->pageNumber + 1;
1596             }
1597 
1598             if (eventParam->pageNumber == eventParam->maximumPageNumber) {
1599                 connection->remoteFeatures.bredr.extendedFeatureStatus = eventParam->status;
1600                 status = eventParam->status;
1601             }
1602         } else {
1603             connection->remoteFeatures.bredr.extendedFeatureStatus = eventParam->status;
1604             status = eventParam->status;
1605         }
1606 
1607         if (status != REQUEST_NOT_COMPLETED) {
1608             BtmGetRemoteDeviceSupportRequests(eventParam->connectionHandle, REMOTE_EXTENDED_FEATURE_COMPLETE, requests);
1609 
1610             addr = connection->addr;
1611             extendedFeatures = connection->remoteFeatures.bredr.extendedLmpFeatures;
1612         }
1613     }
1614     MutexUnlock(g_aclListLock);
1615 
1616     if (nextPageNumber > 0) {
1617         HciReadRemoteExtendedFeaturesParam cmdParam = {
1618             .connectionHandle = eventParam->connectionHandle,
1619             .pageNumber = nextPageNumber,
1620         };
1621         HCI_ReadRemoteExtendedFeatures(&cmdParam);
1622     }
1623 
1624     if (ListGetSize(requests)) {
1625         BtmOnRemoteExtendedFeatureComplete(&addr, requests, &extendedFeatures);
1626     }
1627 
1628     ListDelete(requests);
1629 }
1630 
BtmOnReadRssiComplete(const HciReadRssiReturnParam * returnParam)1631 static void BtmOnReadRssiComplete(const HciReadRssiReturnParam *returnParam)
1632 {
1633     BtAddr addr;
1634     MutexLock(g_aclListLock);
1635     BtmAclConnection *connection = BtmAclFindConnectionByHandle(returnParam->handle);
1636     if (connection != NULL) {
1637         addr = connection->addr;
1638     }
1639     MutexUnlock(g_aclListLock);
1640 
1641     MutexLock(g_aclCallbackListLock);
1642     BtmAclCallbacksBlock *block = NULL;
1643     ListNode *node = ListGetFirstNode(g_aclCallbackList);
1644     while (node != NULL) {
1645         block = ListGetNodeData(node);
1646         if (block->callbacks->readRssiComplete != NULL) {
1647             block->callbacks->readRssiComplete(returnParam->status, &addr, returnParam->rssi, block->context);
1648         }
1649         node = ListGetNextNode(node);
1650     }
1651     MutexUnlock(g_aclCallbackListLock);
1652 }
1653 
BtmAclOnCommandStatus(uint8_t status,uint16_t commandOpcode)1654 static void BtmAclOnCommandStatus(uint8_t status, uint16_t commandOpcode)
1655 {
1656     if (commandOpcode == HCI_DISCONNECT) {
1657         MutexLock(g_cleanupMutex);
1658         if (g_cleanupHandle != 0xffff) {
1659             AlarmCancel(g_cleanupTimer);
1660             SemaphorePost(g_cleanupEvent);
1661         }
1662         MutexUnlock(g_cleanupMutex);
1663     }
1664 }
1665 
BTM_RegisterAclCallbacks(const BtmAclCallbacks * callbacks,void * context)1666 int BTM_RegisterAclCallbacks(const BtmAclCallbacks *callbacks, void *context)
1667 {
1668     if (callbacks == NULL) {
1669         return BT_BAD_PARAM;
1670     }
1671 
1672     if (!IS_INITIALIZED()) {
1673         return BT_BAD_STATUS;
1674     }
1675 
1676     BtmAclCallbacksBlock *block = BtmAllocAclCallbacksBlock(callbacks, context);
1677     if (block == NULL) {
1678         return BT_NO_MEMORY;
1679     }
1680 
1681     MutexLock(g_aclCallbackListLock);
1682     ListAddLast(g_aclCallbackList, block);
1683     MutexUnlock(g_aclCallbackListLock);
1684     return BT_SUCCESS;
1685 }
1686 
BTM_DeregisterAclCallbacks(const BtmAclCallbacks * callbacks)1687 int BTM_DeregisterAclCallbacks(const BtmAclCallbacks *callbacks)
1688 {
1689     if (callbacks == NULL) {
1690         return BT_BAD_PARAM;
1691     }
1692 
1693     if (!IS_INITIALIZED()) {
1694         return BT_BAD_STATUS;
1695     }
1696 
1697     MutexLock(g_aclCallbackListLock);
1698     BtmAclCallbacksBlock *block = NULL;
1699     ListNode *node = ListGetFirstNode(g_aclCallbackList);
1700     while (node != NULL) {
1701         block = ListGetNodeData(node);
1702         if (block->callbacks == callbacks) {
1703             ListRemoveNode(g_aclCallbackList, block);
1704             break;
1705         }
1706         node = ListGetNextNode(node);
1707     }
1708     MutexUnlock(g_aclCallbackListLock);
1709     return BT_SUCCESS;
1710 }
1711 
BtmGetAclHandleByAddress(const BtAddr * addr,uint16_t * handle)1712 int BtmGetAclHandleByAddress(const BtAddr *addr, uint16_t *handle)
1713 {
1714     int result = BT_SUCCESS;
1715     MutexLock(g_aclListLock);
1716     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
1717     if (connection != NULL) {
1718         *handle = connection->connectionHandle;
1719     } else {
1720         result = BT_BAD_STATUS;
1721     }
1722     MutexUnlock(g_aclListLock);
1723     return result;
1724 }
1725 
BtmGetLeAclHandleByAddress(const BtAddr * addr,uint16_t * handle)1726 int BtmGetLeAclHandleByAddress(const BtAddr *addr, uint16_t *handle)
1727 {
1728     int result = BT_SUCCESS;
1729     MutexLock(g_aclListLock);
1730     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1731     if (connection != NULL) {
1732         *handle = connection->connectionHandle;
1733     } else {
1734         result = BT_BAD_STATUS;
1735     }
1736     MutexUnlock(g_aclListLock);
1737     return result;
1738 }
1739 
BtmGetAclAddressByHandle(const uint16_t handle,BtAddr * addr)1740 int BtmGetAclAddressByHandle(const uint16_t handle, BtAddr *addr)
1741 {
1742     int result = BT_SUCCESS;
1743     MutexLock(g_aclListLock);
1744     BtmAclConnection *connection = BtmAclFindConnectionByHandle(handle);
1745     if (connection != NULL) {
1746         *addr = connection->addr;
1747     } else {
1748         result = BT_BAD_STATUS;
1749     }
1750     MutexUnlock(g_aclListLock);
1751     return result;
1752 }
1753 
BTM_AclAddRef(uint16_t connectionHandle)1754 int BTM_AclAddRef(uint16_t connectionHandle)
1755 {
1756     if (!IS_INITIALIZED()) {
1757         return BT_OPERATION_FAILED;
1758     }
1759 
1760     int result = BT_SUCCESS;
1761 
1762     MutexLock(g_aclListLock);
1763     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1764     if (connection != NULL) {
1765         if (connection->state == DISCONNECTING) {
1766             result = BT_BAD_STATUS;
1767         } else {
1768             connection->refCount++;
1769             AlarmCancel(connection->timeoutTimer);
1770         }
1771     } else {
1772         result = BT_BAD_PARAM;
1773     }
1774     MutexUnlock(g_aclListLock);
1775 
1776     return result;
1777 }
1778 
BtmReleaseConnection(BtmAclConnection * connection)1779 void BtmReleaseConnection(BtmAclConnection *connection)
1780 {
1781     if (connection->isInitiator) {
1782         connection->state = DISCONNECTING;
1783 
1784         HciDisconnectParam param = {
1785             .connectionHandle = connection->connectionHandle,
1786             .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
1787         };
1788         HCI_Disconnect(&param);
1789     } else {
1790         if (connection->transport == TRANSPORT_BREDR) {
1791             AlarmSet(connection->timeoutTimer, ACL_PASSIVE_TIMEOUT, BtmAclTimeout, connection);
1792         } else if (connection->transport == TRANSPORT_LE) {
1793             connection->state = DISCONNECTING;
1794 
1795             HciDisconnectParam param = {
1796                 .connectionHandle = connection->connectionHandle,
1797                 .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
1798             };
1799             HCI_Disconnect(&param);
1800         }
1801     }
1802 }
1803 
BTM_AclRelease(uint16_t connectionHandle)1804 void BTM_AclRelease(uint16_t connectionHandle)
1805 {
1806     if (!IS_INITIALIZED()) {
1807         return;
1808     }
1809 
1810     MutexLock(g_aclListLock);
1811     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1812     if (connection != NULL) {
1813         connection->refCount--;
1814         if (connection->refCount == 0) {
1815             BtmReleaseConnection(connection);
1816         }
1817     }
1818     MutexUnlock(g_aclListLock);
1819 }
1820 
BTM_ReadRssi(const BtAddr * addr)1821 int BTM_ReadRssi(const BtAddr *addr)
1822 {
1823     if (addr == NULL) {
1824         return BT_BAD_PARAM;
1825     }
1826 
1827     if (!IS_INITIALIZED()) {
1828         return BT_BAD_STATUS;
1829     }
1830 
1831     uint16_t handle = 0xffff;
1832 
1833     MutexLock(g_aclListLock);
1834     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1835     if (connection != NULL && connection->state == CONNECTED) {
1836         handle = connection->connectionHandle;
1837     } else {
1838         MutexUnlock(g_aclListLock);
1839         return BT_BAD_STATUS;
1840     }
1841     MutexUnlock(g_aclListLock);
1842 
1843     HciReadRssiParam param = {
1844         .handle = handle,
1845     };
1846     return HCI_ReadRssi(&param);
1847 }
1848 
BTM_GetLeConnectionAddress(uint16_t connectionHandle,BtAddr * localAddr,BtAddr * peerAddr)1849 int BTM_GetLeConnectionAddress(uint16_t connectionHandle, BtAddr *localAddr, BtAddr *peerAddr)
1850 {
1851     if (!IS_INITIALIZED()) {
1852         return BT_BAD_STATUS;
1853     }
1854 
1855     int result = BT_SUCCESS;
1856     MutexLock(g_aclListLock);
1857     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1858     if (connection != NULL) {
1859         *localAddr = connection->leLocalAddr;
1860         *peerAddr = connection->lePeerAddr;
1861     } else {
1862         result = BT_BAD_STATUS;
1863     }
1864     MutexUnlock(g_aclListLock);
1865     return result;
1866 }
1867 
BtmOnEncryptionChange(const HciEncryptionChangeEventParam * eventParam)1868 static void BtmOnEncryptionChange(const HciEncryptionChangeEventParam *eventParam)
1869 {
1870     if (eventParam->status != HCI_SUCCESS) {
1871         return;
1872     }
1873 
1874     MutexLock(g_aclListLock);
1875     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1876     if (connection != NULL) {
1877         connection->encryption = eventParam->encryptionEnabled;
1878     }
1879     MutexUnlock(g_aclListLock);
1880 }
1881 
BTM_IsSecureConnection(const BtAddr * addr)1882 bool BTM_IsSecureConnection(const BtAddr *addr)
1883 {
1884     if (!IS_INITIALIZED()) {
1885         return false;
1886     }
1887 
1888     bool isSecureConnection = false;
1889     MutexLock(g_aclListLock);
1890     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
1891     if (connection != NULL) {
1892         if (connection->encryption == LINK_LEVEL_ENCRYPTION_ON_AES_CCM) {
1893             isSecureConnection = true;
1894         }
1895     }
1896     MutexUnlock(g_aclListLock);
1897     return isSecureConnection;
1898 }
1899 
BtmAclOnCleanUpTimeout(void * parameter)1900 static void BtmAclOnCleanUpTimeout(void *parameter)
1901 {
1902     SemaphorePost(g_cleanupEvent);
1903 }
1904 
BtmCloseAclConnectionByTransport(uint8_t transport)1905 void BtmCloseAclConnectionByTransport(uint8_t transport)
1906 {
1907     bool noActiveConnection = false;
1908 
1909     BtmAclConnection *connection = NULL;
1910     HciDisconnectParam param = {
1911         .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
1912     };
1913 
1914     while (!noActiveConnection) {
1915         uint16_t connectionHandle = 0xffff;
1916         MutexLock(g_aclListLock);
1917         ListNode *node = ListGetFirstNode(g_aclList);
1918         while (node != NULL) {
1919             connection = ListGetNodeData(node);
1920             if (connection->transport == transport && connection->state == CONNECTED) {
1921                 connectionHandle = connection->connectionHandle;
1922                 connection->state = DISCONNECTING;
1923                 break;
1924             }
1925             node = ListGetNextNode(node);
1926         }
1927         MutexUnlock(g_aclListLock);
1928 
1929         if (connectionHandle != 0xffff) {
1930             MutexLock(g_cleanupMutex);
1931             g_cleanupHandle = connectionHandle;
1932             MutexUnlock(g_cleanupMutex);
1933 
1934             param.connectionHandle = connectionHandle;
1935             HCI_Disconnect(&param);
1936 
1937             AlarmSet(g_cleanupTimer, CLEANUP_TIMEOUT, BtmAclOnCleanUpTimeout, NULL);
1938             SemaphoreWait(g_cleanupEvent);
1939 
1940             MutexLock(g_cleanupMutex);
1941             g_cleanupHandle = 0xffff;
1942             MutexUnlock(g_cleanupMutex);
1943         } else {
1944             noActiveConnection = true;
1945         }
1946     }
1947 }
1948 
BTM_AclCancelConnect(const BtAddr * addr)1949 int BTM_AclCancelConnect(const BtAddr *addr)
1950 {
1951     if (addr == NULL) {
1952         return BT_BAD_PARAM;
1953     }
1954 
1955     if (!IS_INITIALIZED()) {
1956         return BT_BAD_STATUS;
1957     }
1958 
1959     int result;
1960     MutexLock(g_aclListLock);
1961     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
1962     if (connection != NULL) {
1963         ListRemoveNode(g_aclList, connection);
1964         HciCreateConnectionCancelParam param = {
1965             .bdAddr =
1966                 {
1967                     .raw = {0},
1968                 },
1969         };
1970         (void)memcpy_s(param.bdAddr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
1971         result = HCI_CreateConnectionCancel(&param);
1972     } else {
1973         result = BT_BAD_STATUS;
1974     }
1975     MutexUnlock(g_aclListLock);
1976     return result;
1977 }
1978 
BTM_LeCancelConnect(const BtAddr * addr)1979 int BTM_LeCancelConnect(const BtAddr *addr)
1980 {
1981     if (addr == NULL) {
1982         return BT_BAD_PARAM;
1983     }
1984 
1985     if (!IS_INITIALIZED()) {
1986         return BT_BAD_STATUS;
1987     }
1988 
1989     int reuslt = BT_SUCCESS;
1990 
1991     MutexLock(g_aclListLock);
1992 
1993     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1994     if (connection != NULL) {
1995         if (connection->state == CONNECTING) {
1996             MutexLock(g_leConnectionCancelLock);
1997             BtAddr *cancelAddr = MEM_MALLOC.alloc(sizeof(BtAddr));
1998             if (cancelAddr != NULL) {
1999                 *cancelAddr = *addr;
2000                 ListAddLast(g_leConnectionCancelList, cancelAddr);
2001             }
2002             MutexUnlock(g_leConnectionCancelLock);
2003 
2004             BtmWhiteListPendingAction *action = MEM_MALLOC.alloc(sizeof(BtmWhiteListPendingAction));
2005             if (action != NULL) {
2006                 action->action = ACTION_REMOVE_FORM_WHITE_LIST;
2007                 action->addr = *addr;
2008                 BtmConvertAddressForConnection(&action->addr);
2009                 QueueEnqueue(g_leWhiteListPendingActionQueue, action);
2010             }
2011 
2012             BtmStopAutoConnection();
2013 
2014             ListRemoveNode(g_aclList, connection);
2015         } else {
2016             reuslt = BT_BAD_STATUS;
2017         }
2018     } else {
2019         reuslt = BT_BAD_STATUS;
2020     }
2021 
2022     MutexUnlock(g_aclListLock);
2023 
2024     return reuslt;
2025 }
2026 
BTM_IsRemoteDeviceSupportHostSecureSimplePairing(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2027 void BTM_IsRemoteDeviceSupportHostSecureSimplePairing(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2028 {
2029     BtmAclConnection *connection = NULL;
2030     BTMRemoteDeviceSupportCallback callback_ = NULL;
2031     bool isSupported = false;
2032 
2033     MutexLock(g_aclListLock);
2034 
2035     connection = BtmAclFindConnectionByAddr(addr);
2036     if (connection != NULL) {
2037         if (connection->remoteFeatures.bredr.extendedFeatureStatus != REQUEST_NOT_COMPLETED) {
2038             callback_ = callback;
2039             isSupported =
2040                 HCI_SUPPORT_SECURE_SIMPLE_PAIRING_HOST(connection->remoteFeatures.bredr.extendedLmpFeatures.page[1]);
2041         } else {
2042             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2043             if (request != NULL) {
2044                 request->addr = *addr;
2045                 request->callback = callback;
2046                 request->connectionHandle = connection->connectionHandle;
2047                 request->event = REMOTE_EXTENDED_FEATURE_COMPLETE;
2048                 request->feature.extendedFeature = SECURE_SIMPLE_PAIRING_HOST_SUPPORT;
2049 
2050                 ListAddLast(g_remoteSupportRequestList, request);
2051             }
2052         }
2053     } else {
2054         callback_ = callback;
2055     }
2056 
2057     MutexUnlock(g_aclListLock);
2058 
2059     if (callback_ != NULL) {
2060         callback_(addr, isSupported);
2061     }
2062 }
2063 
BTM_IsRemoteDeviceSupportConnectionParametersRequest(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2064 void BTM_IsRemoteDeviceSupportConnectionParametersRequest(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2065 {
2066     BtmAclConnection *connection = NULL;
2067     BTMRemoteDeviceSupportCallback callback_ = NULL;
2068     bool isSupported = false;
2069 
2070     MutexLock(g_aclListLock);
2071 
2072     connection = BtmAclFindConnectionByAddr(addr);
2073     if (connection != NULL) {
2074         if (connection->remoteFeatures.bredr.extendedFeatureStatus != REQUEST_NOT_COMPLETED) {
2075             callback_ = callback;
2076             isSupported =
2077                 HCI_SUPPORT_CONNECTION_PARAMETERS_REQUEST_PROCEDURE(connection->remoteFeatures.le.leFeatures.raw);
2078         } else {
2079             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2080             if (request != NULL) {
2081                 request->addr = *addr;
2082                 request->callback = callback;
2083                 request->connectionHandle = connection->connectionHandle;
2084                 request->event = REMOTE_LE_FEATURE_COMPLETE;
2085                 request->feature.leFreature = CONNECTION_PARAMETER_REQUEST;
2086 
2087                 ListAddLast(g_remoteSupportRequestList, request);
2088             }
2089         }
2090     } else {
2091         callback_ = callback;
2092     }
2093 
2094     MutexUnlock(g_aclListLock);
2095 
2096     if (callback_ != NULL) {
2097         callback_(addr, isSupported);
2098     }
2099 }
2100 
BTM_IsRemoteDeviceSupportEdrAcl2MbMode(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2101 void BTM_IsRemoteDeviceSupportEdrAcl2MbMode(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2102 {
2103     BtmAclConnection *connection = NULL;
2104     BTMRemoteDeviceSupportCallback callback_ = NULL;
2105     bool isSupported = false;
2106 
2107     MutexLock(g_aclListLock);
2108 
2109     connection = BtmAclFindConnectionByAddr(addr);
2110     if (connection != NULL) {
2111         if (connection->remoteFeatures.bredr.featureStatus != REQUEST_NOT_COMPLETED) {
2112             callback_ = callback;
2113             isSupported = HCI_SUPPORT_EDR_ACL_2MBS_MODE(connection->remoteFeatures.bredr.lmpFeatures.raw);
2114         } else {
2115             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2116             if (request != NULL) {
2117                 request->addr = *addr;
2118                 request->callback = callback;
2119                 request->connectionHandle = connection->connectionHandle;
2120                 request->event = REMOTE_FEATURE_COMPLETE;
2121                 request->feature.feature = EDR_ACL_2MB_MODE;
2122 
2123                 ListAddLast(g_remoteSupportRequestList, request);
2124             }
2125         }
2126     } else {
2127         callback_ = callback;
2128     }
2129 
2130     MutexUnlock(g_aclListLock);
2131 
2132     if (callback_ != NULL) {
2133         callback_(addr, isSupported);
2134     }
2135 }
2136 
BTM_IsRemoteDeviceSupportEdrAcl3MbMode(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2137 void BTM_IsRemoteDeviceSupportEdrAcl3MbMode(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2138 {
2139     BtmAclConnection *connection = NULL;
2140     BTMRemoteDeviceSupportCallback callback_ = NULL;
2141     bool isSupported = false;
2142 
2143     MutexLock(g_aclListLock);
2144 
2145     connection = BtmAclFindConnectionByAddr(addr);
2146     if (connection != NULL) {
2147         if (connection->remoteFeatures.bredr.featureStatus != REQUEST_NOT_COMPLETED) {
2148             callback_ = callback;
2149             isSupported = HCI_SUPPORT_EDR_ACL_3MBS_MODE(connection->remoteFeatures.bredr.lmpFeatures.raw);
2150         } else {
2151             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2152             if (request != NULL) {
2153                 request->addr = *addr;
2154                 request->callback = callback;
2155                 request->connectionHandle = connection->connectionHandle;
2156                 request->event = REMOTE_FEATURE_COMPLETE;
2157                 request->feature.feature = EDR_ACL_3MB_MODE;
2158 
2159                 ListAddLast(g_remoteSupportRequestList, request);
2160             }
2161         }
2162     } else {
2163         callback_ = callback;
2164     }
2165 
2166     MutexUnlock(g_aclListLock);
2167 
2168     if (callback_ != NULL) {
2169         callback_(addr, isSupported);
2170     }
2171 }
2172 
BTM_SetDefaultLinkPolicySettings(uint16_t linkPolicySettings)2173 int BTM_SetDefaultLinkPolicySettings(uint16_t linkPolicySettings)
2174 {
2175     HciWriteDefaultLinkPolicySettingsParam param = {
2176         .defaultLinkPolicySettings = HCI_LINK_POLICY_DISABLE_ALL,
2177     };
2178 
2179     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_ROLE_SWITCH) && BTM_IsControllerSupportRoleSwitch()) {
2180         param.defaultLinkPolicySettings |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH;
2181     }
2182     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_HOLD_MODE) && BTM_IsControllerSupportHoldMode()) {
2183         param.defaultLinkPolicySettings |= HCI_LINK_POLICY_ENABLE_HOLD_MODE;
2184     }
2185     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_SNIFF_MODE) && BTM_IsControllerSupportSniffMode()) {
2186         param.defaultLinkPolicySettings |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE;
2187     }
2188 
2189     return HCI_WriteDefaultLinkPolicySettings(&param);
2190 }
2191 
BTM_SetLinkPolicySettings(const BtAddr * addr,uint16_t linkPolicySettings)2192 int BTM_SetLinkPolicySettings(const BtAddr *addr, uint16_t linkPolicySettings)
2193 {
2194     uint16_t connectionHandle = 0xffff;
2195     int result = BtmGetAclHandleByAddress(addr, &connectionHandle);
2196     if (result != BT_SUCCESS) {
2197         return result;
2198     }
2199 
2200     HciWriteLinkPolicySettingsParam param = {
2201         .connectionHandle = connectionHandle,
2202         .linkPolicySettings = HCI_LINK_POLICY_DISABLE_ALL,
2203     };
2204 
2205     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_ROLE_SWITCH) && BTM_IsControllerSupportRoleSwitch()) {
2206         param.linkPolicySettings |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH;
2207     }
2208     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_HOLD_MODE) && BTM_IsControllerSupportHoldMode()) {
2209         param.linkPolicySettings |= HCI_LINK_POLICY_ENABLE_HOLD_MODE;
2210     }
2211     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_SNIFF_MODE) && BTM_IsControllerSupportSniffMode()) {
2212         param.linkPolicySettings |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE;
2213     }
2214 
2215     return HCI_WriteLinkPolicySettings(&param);
2216 }
2217 
BtmOnRoleChange(const HciRoleChangeEventParam * eventParam)2218 void BtmOnRoleChange(const HciRoleChangeEventParam *eventParam)
2219 {
2220     BtAddr addr = {
2221         .addr = {0},
2222         .type = BT_PUBLIC_DEVICE_ADDRESS,
2223     };
2224     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->bdAddr.raw, BT_ADDRESS_SIZE);
2225 
2226     MutexLock(g_aclCallbackListLock);
2227     ListNode *node = ListGetFirstNode(g_aclCallbackList);
2228     BtmAclCallbacksBlock *block = NULL;
2229     while (node != NULL) {
2230         block = (BtmAclCallbacksBlock *)ListGetNodeData(node);
2231         if (block->callbacks->roleChange != NULL) {
2232             block->callbacks->roleChange(eventParam->status, &addr, eventParam->newRole, block->context);
2233         }
2234         node = ListGetNextNode(node);
2235     }
2236     MutexUnlock(g_aclCallbackListLock);
2237 }
2238 
BTM_SwitchRole(const BtAddr * addr,uint8_t role)2239 int BTM_SwitchRole(const BtAddr *addr, uint8_t role)
2240 {
2241     if (!IS_INITIALIZED()) {
2242         return BT_BAD_STATUS;
2243     }
2244 
2245     if (addr == NULL || (role != BTM_ROLE_MASTER && role != BTM_ROLE_SLAVE)) {
2246         return BT_BAD_PARAM;
2247     }
2248 
2249     uint16_t connectionHandle = 0xffff;
2250     int result = BtmGetAclHandleByAddress(addr, &connectionHandle);
2251     if (result != BT_SUCCESS) {
2252         return result;
2253     }
2254 
2255     BTM_ExitSniffMode(addr);
2256 
2257     HciSwitchRoleParam param = {
2258         .bdAddr =
2259             {
2260                 .raw = {0},
2261             },
2262         .role = role,
2263     };
2264     (void)memcpy_s(param.bdAddr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
2265 
2266     result = HCI_SwitchRole(&param);
2267 
2268     return result;
2269 }
2270 
BTM_SetLeConnectionModeToFast()2271 int BTM_SetLeConnectionModeToFast()
2272 {
2273     if (!IS_INITIALIZED()) {
2274         return BT_BAD_STATUS;
2275     }
2276 
2277     MutexLock(g_autoConnectLock);
2278 
2279     if (g_leScanInterval != LE_SCAN_INTERVAL_FAST || g_leScanWindow != LE_SCAN_WINDOW_FAST) {
2280         if (BtmGetDeviceCountInWhiteList() > 0) {
2281             BtmStopAutoConnectionInternal();
2282         }
2283 
2284         g_leScanInterval = LE_SCAN_INTERVAL_FAST;
2285         g_leScanWindow = LE_SCAN_WINDOW_FAST;
2286     }
2287 
2288     MutexUnlock(g_autoConnectLock);
2289 
2290     return BT_SUCCESS;
2291 }
2292 
BTM_SetLeConnectionModeToSlow()2293 int BTM_SetLeConnectionModeToSlow()
2294 {
2295     if (!IS_INITIALIZED()) {
2296         return BT_BAD_STATUS;
2297     }
2298 
2299     MutexLock(g_autoConnectLock);
2300 
2301     if (g_leScanInterval != LE_SCAN_INTERVAL_SLOW || g_leScanWindow != LE_SCAN_WINDOW_SLOW) {
2302         if (BtmGetDeviceCountInWhiteList() > 0) {
2303             BtmStopAutoConnectionInternal();
2304         }
2305 
2306         g_leScanInterval = LE_SCAN_INTERVAL_SLOW;
2307         g_leScanWindow = LE_SCAN_WINDOW_SLOW;
2308     }
2309 
2310     MutexUnlock(g_autoConnectLock);
2311 
2312     return BT_SUCCESS;
2313 }
2314 
BtmGenerateSupportedPacketTypes(const HciLmpFeatures * lmpFeature)2315 static uint16_t BtmGenerateSupportedPacketTypes(const HciLmpFeatures *lmpFeature)
2316 {
2317     uint16_t packetType = BTM_ACL_PACKET_TYPE_DH1 | BTM_ACL_PACKET_TYPE_DM1;
2318 
2319     if (HCI_SUPPORT_3_SLOT_PACKETS(lmpFeature->raw)) {
2320         packetType |= BTM_ACL_PACKET_TYPE_DH3;
2321         packetType |= BTM_ACL_PACKET_TYPE_DM3;
2322     }
2323 
2324     if (HCI_SUPPORT_5_SLOT_PACKETS(lmpFeature->raw)) {
2325         packetType |= BTM_ACL_PACKET_TYPE_DH5;
2326         packetType |= BTM_ACL_PACKET_TYPE_DM5;
2327     }
2328 
2329     if (!HCI_SUPPORT_EDR_ACL_2MBS_MODE(lmpFeature->raw)) {
2330         packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH1;
2331         packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH3;
2332         packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH5;
2333     } else {
2334         if (!HCI_SUPPORT_3_SLOT_EDR_PACKET(lmpFeature->raw)) {
2335             packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH3;
2336         }
2337         if (!HCI_SUPPORT_5_SLOT_EDR_PACKET(lmpFeature->raw)) {
2338             packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH5;
2339         }
2340     }
2341 
2342     if (!HCI_SUPPORT_EDR_ACL_3MBS_MODE(lmpFeature->raw)) {
2343         packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH1;
2344         packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH3;
2345         packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH5;
2346     } else {
2347         if (!HCI_SUPPORT_3_SLOT_EDR_PACKET(lmpFeature->raw)) {
2348             packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH3;
2349         }
2350         if (!HCI_SUPPORT_5_SLOT_EDR_PACKET(lmpFeature->raw)) {
2351             packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH5;
2352         }
2353     }
2354 
2355     return packetType;
2356 }
2357 
BTM_ChangeConnectionPacketType(const BtAddr * addr,uint16_t packetType)2358 int BTM_ChangeConnectionPacketType(const BtAddr *addr, uint16_t packetType)
2359 {
2360     if (!IS_INITIALIZED()) {
2361         return BT_BAD_STATUS;
2362     }
2363 
2364     if (addr == NULL) {
2365         return BT_BAD_PARAM;
2366     }
2367 
2368     uint16_t connectionHandle = 0xffff;
2369     uint16_t peerPacketType = 0;
2370 
2371     MutexLock(g_aclListLock);
2372     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
2373     if (connection != NULL) {
2374         connectionHandle = connection->connectionHandle;
2375         peerPacketType = BtmGenerateSupportedPacketTypes(&connection->remoteFeatures.bredr.lmpFeatures);
2376     }
2377     MutexUnlock(g_aclListLock);
2378 
2379     if (connectionHandle == 0xffff) {
2380         return BT_BAD_STATUS;
2381     }
2382 
2383     HciLmpFeatures lmpFeatures = {0};
2384     BtmGetLocalSupportedFeature(&lmpFeatures);
2385     uint16_t localPacketType = BtmGenerateSupportedPacketTypes(&lmpFeatures);
2386 
2387     const uint16_t usedTypes = BTM_ACL_PACKET_TYPE_DM1 | BTM_ACL_PACKET_TYPE_DH1 | BTM_ACL_PACKET_TYPE_DM3 |
2388                                BTM_ACL_PACKET_TYPE_DH3 | BTM_ACL_PACKET_TYPE_DM5 | BTM_ACL_PACKET_TYPE_DH5;
2389     const uint16_t unusedTypes = BTM_ACL_PACKET_TYPE_NO_2_DH1 | BTM_ACL_PACKET_TYPE_NO_3_DH1 |
2390                                  BTM_ACL_PACKET_TYPE_NO_2_DH3 | BTM_ACL_PACKET_TYPE_NO_3_DH3 |
2391                                  BTM_ACL_PACKET_TYPE_NO_2_DH5 | BTM_ACL_PACKET_TYPE_NO_3_DH5;
2392 
2393     uint16_t hciPacketType = (packetType & usedTypes) & (localPacketType & usedTypes) & (peerPacketType & usedTypes);
2394     hciPacketType |= ((packetType & unusedTypes) | (localPacketType & unusedTypes) | (peerPacketType & unusedTypes));
2395 
2396     HciChangeConnectionPacketTypeParam param = {
2397         .connectionHandle = connectionHandle,
2398         .packetType = hciPacketType,
2399     };
2400     return HCI_ChangeConnectionPacketType(&param);
2401 }
2402 
2403 static HciEventCallbacks g_hciEventCallbacks = {
2404     .connectionComplete = BtmOnConnectionComplete,
2405     .connectionRequest = BtmOnConnectionrequest,
2406     .disconnectComplete = BtmOnDisconnectComplete,
2407     .encryptionChange = BtmOnEncryptionChange,
2408     .readRemoteSupportedFeaturesComplete = BtmOnReadRemoteSupportedFeaturesComplete,
2409     .readRemoteVersionInformationComplete = BtmOnReadRemoteVersionInformationComplete,
2410     .commandStatus = BtmAclOnCommandStatus,
2411     .roleChange = BtmOnRoleChange,
2412     .readRemoteExtendedFeaturesComplete = BtmOnReadRemoteExtendedFeaturesComplete,
2413 
2414     .readRssiComplete = BtmOnReadRssiComplete,
2415 
2416     .leConnectionComplete = BtmOnLeConnectionComplete,
2417     .leReadRemoteFeaturesComplete = BtmOnLeReadRemoteFeaturesComplete,
2418     .leEnhancedConnectionComplete = BtmOnLeEnhancedConnectionComplete,
2419 };
2420