• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_STACK) {
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_STACK) {
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_STACK;
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_STACK;
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_STACK;
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_STACK && 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_STACK;
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_STACK) && (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_STACK && 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_STACK;
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_STACK) {
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_STACK) {
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_STACK) {
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 = 1,
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             } else {
1597                 connection->remoteFeatures.bredr.extendedFeatureStatus = eventParam->status;
1598                 status = eventParam->status;
1599             }
1600         } else {
1601             connection->remoteFeatures.bredr.extendedFeatureStatus = eventParam->status;
1602             status = eventParam->status;
1603         }
1604 
1605         if (status != REQUEST_NOT_COMPLETED) {
1606             BtmGetRemoteDeviceSupportRequests(eventParam->connectionHandle, REMOTE_EXTENDED_FEATURE_COMPLETE, requests);
1607 
1608             addr = connection->addr;
1609             extendedFeatures = connection->remoteFeatures.bredr.extendedLmpFeatures;
1610         }
1611     }
1612     MutexUnlock(g_aclListLock);
1613 
1614     if (nextPageNumber > 0) {
1615         HciReadRemoteExtendedFeaturesParam cmdParam = {
1616             .connectionHandle = eventParam->connectionHandle,
1617             .pageNumber = nextPageNumber,
1618         };
1619         HCI_ReadRemoteExtendedFeatures(&cmdParam);
1620     }
1621 
1622     if (ListGetSize(requests)) {
1623         BtmOnRemoteExtendedFeatureComplete(&addr, requests, &extendedFeatures);
1624     }
1625 
1626     ListDelete(requests);
1627 }
1628 
BtmOnReadRssiComplete(const HciReadRssiReturnParam * returnParam)1629 static void BtmOnReadRssiComplete(const HciReadRssiReturnParam *returnParam)
1630 {
1631     BtAddr addr;
1632     MutexLock(g_aclListLock);
1633     BtmAclConnection *connection = BtmAclFindConnectionByHandle(returnParam->handle);
1634     if (connection != NULL) {
1635         addr = connection->addr;
1636     }
1637     MutexUnlock(g_aclListLock);
1638 
1639     MutexLock(g_aclCallbackListLock);
1640     BtmAclCallbacksBlock *block = NULL;
1641     ListNode *node = ListGetFirstNode(g_aclCallbackList);
1642     while (node != NULL) {
1643         block = ListGetNodeData(node);
1644         if (block->callbacks->readRssiComplete != NULL) {
1645             block->callbacks->readRssiComplete(returnParam->status, &addr, returnParam->rssi, block->context);
1646         }
1647         node = ListGetNextNode(node);
1648     }
1649     MutexUnlock(g_aclCallbackListLock);
1650 }
1651 
BtmAclOnCommandStatus(uint8_t status,uint16_t commandOpcode)1652 static void BtmAclOnCommandStatus(uint8_t status, uint16_t commandOpcode)
1653 {
1654     if (commandOpcode == HCI_DISCONNECT) {
1655         MutexLock(g_cleanupMutex);
1656         if (g_cleanupHandle != 0xffff) {
1657             AlarmCancel(g_cleanupTimer);
1658             SemaphorePost(g_cleanupEvent);
1659         }
1660         MutexUnlock(g_cleanupMutex);
1661     }
1662 }
1663 
BTM_RegisterAclCallbacks(const BtmAclCallbacks * callbacks,void * context)1664 int BTM_RegisterAclCallbacks(const BtmAclCallbacks *callbacks, void *context)
1665 {
1666     if (callbacks == NULL) {
1667         return BT_BAD_PARAM;
1668     }
1669 
1670     if (!IS_INITIALIZED()) {
1671         return BT_BAD_STATUS;
1672     }
1673 
1674     BtmAclCallbacksBlock *block = BtmAllocAclCallbacksBlock(callbacks, context);
1675     if (block == NULL) {
1676         return BT_NO_MEMORY;
1677     }
1678 
1679     MutexLock(g_aclCallbackListLock);
1680     ListAddLast(g_aclCallbackList, block);
1681     MutexUnlock(g_aclCallbackListLock);
1682     return BT_SUCCESS;
1683 }
1684 
BTM_DeregisterAclCallbacks(const BtmAclCallbacks * callbacks)1685 int BTM_DeregisterAclCallbacks(const BtmAclCallbacks *callbacks)
1686 {
1687     if (callbacks == NULL) {
1688         return BT_BAD_PARAM;
1689     }
1690 
1691     if (!IS_INITIALIZED()) {
1692         return BT_BAD_STATUS;
1693     }
1694 
1695     MutexLock(g_aclCallbackListLock);
1696     BtmAclCallbacksBlock *block = NULL;
1697     ListNode *node = ListGetFirstNode(g_aclCallbackList);
1698     while (node != NULL) {
1699         block = ListGetNodeData(node);
1700         if (block->callbacks == callbacks) {
1701             ListRemoveNode(g_aclCallbackList, block);
1702             break;
1703         }
1704         node = ListGetNextNode(node);
1705     }
1706     MutexUnlock(g_aclCallbackListLock);
1707     return BT_SUCCESS;
1708 }
1709 
BtmGetAclHandleByAddress(const BtAddr * addr,uint16_t * handle)1710 int BtmGetAclHandleByAddress(const BtAddr *addr, uint16_t *handle)
1711 {
1712     int result = BT_SUCCESS;
1713     MutexLock(g_aclListLock);
1714     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
1715     if (connection != NULL) {
1716         *handle = connection->connectionHandle;
1717     } else {
1718         result = BT_BAD_STATUS;
1719     }
1720     MutexUnlock(g_aclListLock);
1721     return result;
1722 }
1723 
BtmGetLeAclHandleByAddress(const BtAddr * addr,uint16_t * handle)1724 int BtmGetLeAclHandleByAddress(const BtAddr *addr, uint16_t *handle)
1725 {
1726     int result = BT_SUCCESS;
1727     MutexLock(g_aclListLock);
1728     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1729     if (connection != NULL) {
1730         *handle = connection->connectionHandle;
1731     } else {
1732         result = BT_BAD_STATUS;
1733     }
1734     MutexUnlock(g_aclListLock);
1735     return result;
1736 }
1737 
BtmGetAclAddressByHandle(const uint16_t handle,BtAddr * addr)1738 int BtmGetAclAddressByHandle(const uint16_t handle, BtAddr *addr)
1739 {
1740     int result = BT_SUCCESS;
1741     MutexLock(g_aclListLock);
1742     BtmAclConnection *connection = BtmAclFindConnectionByHandle(handle);
1743     if (connection != NULL) {
1744         *addr = connection->addr;
1745     } else {
1746         result = BT_BAD_STATUS;
1747     }
1748     MutexUnlock(g_aclListLock);
1749     return result;
1750 }
1751 
BTM_AclAddRef(uint16_t connectionHandle)1752 int BTM_AclAddRef(uint16_t connectionHandle)
1753 {
1754     if (!IS_INITIALIZED()) {
1755         return BT_OPERATION_FAILED;
1756     }
1757 
1758     int result = BT_SUCCESS;
1759 
1760     MutexLock(g_aclListLock);
1761     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1762     if (connection != NULL) {
1763         if (connection->state == DISCONNECTING) {
1764             result = BT_BAD_STATUS;
1765         } else {
1766             connection->refCount++;
1767             AlarmCancel(connection->timeoutTimer);
1768         }
1769     } else {
1770         result = BT_BAD_PARAM;
1771     }
1772     MutexUnlock(g_aclListLock);
1773 
1774     return result;
1775 }
1776 
BtmReleaseConnection(BtmAclConnection * connection)1777 void BtmReleaseConnection(BtmAclConnection *connection)
1778 {
1779     if (connection->isInitiator) {
1780         connection->state = DISCONNECTING;
1781 
1782         HciDisconnectParam param = {
1783             .connectionHandle = connection->connectionHandle,
1784             .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
1785         };
1786         HCI_Disconnect(&param);
1787     } else {
1788         if (connection->transport == TRANSPORT_BREDR_STACK) {
1789             AlarmSet(connection->timeoutTimer, ACL_PASSIVE_TIMEOUT, BtmAclTimeout, connection);
1790         } else if (connection->transport == TRANSPORT_LE_STACK) {
1791             connection->state = DISCONNECTING;
1792 
1793             HciDisconnectParam param = {
1794                 .connectionHandle = connection->connectionHandle,
1795                 .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
1796             };
1797             HCI_Disconnect(&param);
1798         }
1799     }
1800 }
1801 
BTM_AclRelease(uint16_t connectionHandle)1802 void BTM_AclRelease(uint16_t connectionHandle)
1803 {
1804     if (!IS_INITIALIZED()) {
1805         return;
1806     }
1807 
1808     MutexLock(g_aclListLock);
1809     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1810     if (connection != NULL) {
1811         connection->refCount--;
1812         if (connection->refCount == 0) {
1813             BtmReleaseConnection(connection);
1814         }
1815     }
1816     MutexUnlock(g_aclListLock);
1817 }
1818 
BTM_ReadRssi(const BtAddr * addr)1819 int BTM_ReadRssi(const BtAddr *addr)
1820 {
1821     if (addr == NULL) {
1822         return BT_BAD_PARAM;
1823     }
1824 
1825     if (!IS_INITIALIZED()) {
1826         return BT_BAD_STATUS;
1827     }
1828 
1829     uint16_t handle = 0xffff;
1830 
1831     MutexLock(g_aclListLock);
1832     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1833     if (connection != NULL && connection->state == CONNECTED) {
1834         handle = connection->connectionHandle;
1835     } else {
1836         MutexUnlock(g_aclListLock);
1837         return BT_BAD_STATUS;
1838     }
1839     MutexUnlock(g_aclListLock);
1840 
1841     HciReadRssiParam param = {
1842         .handle = handle,
1843     };
1844     return HCI_ReadRssi(&param);
1845 }
1846 
BTM_GetLeConnectionAddress(uint16_t connectionHandle,BtAddr * localAddr,BtAddr * peerAddr)1847 int BTM_GetLeConnectionAddress(uint16_t connectionHandle, BtAddr *localAddr, BtAddr *peerAddr)
1848 {
1849     if (!IS_INITIALIZED()) {
1850         return BT_BAD_STATUS;
1851     }
1852 
1853     int result = BT_SUCCESS;
1854     MutexLock(g_aclListLock);
1855     BtmAclConnection *connection = BtmAclFindConnectionByHandle(connectionHandle);
1856     if (connection != NULL) {
1857         *localAddr = connection->leLocalAddr;
1858         *peerAddr = connection->lePeerAddr;
1859     } else {
1860         result = BT_BAD_STATUS;
1861     }
1862     MutexUnlock(g_aclListLock);
1863     return result;
1864 }
1865 
BtmOnEncryptionChange(const HciEncryptionChangeEventParam * eventParam)1866 static void BtmOnEncryptionChange(const HciEncryptionChangeEventParam *eventParam)
1867 {
1868     if (eventParam->status != HCI_SUCCESS) {
1869         return;
1870     }
1871 
1872     MutexLock(g_aclListLock);
1873     BtmAclConnection *connection = BtmAclFindConnectionByHandle(eventParam->connectionHandle);
1874     if (connection != NULL) {
1875         connection->encryption = eventParam->encryptionEnabled;
1876     }
1877     MutexUnlock(g_aclListLock);
1878 }
1879 
BTM_IsSecureConnection(const BtAddr * addr)1880 bool BTM_IsSecureConnection(const BtAddr *addr)
1881 {
1882     if (!IS_INITIALIZED()) {
1883         return false;
1884     }
1885 
1886     bool isSecureConnection = false;
1887     MutexLock(g_aclListLock);
1888     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
1889     if (connection != NULL) {
1890         if (connection->encryption == LINK_LEVEL_ENCRYPTION_ON_AES_CCM) {
1891             isSecureConnection = true;
1892         }
1893     }
1894     MutexUnlock(g_aclListLock);
1895     return isSecureConnection;
1896 }
1897 
BtmAclOnCleanUpTimeout(void * parameter)1898 static void BtmAclOnCleanUpTimeout(void *parameter)
1899 {
1900     SemaphorePost(g_cleanupEvent);
1901 }
1902 
BtmCloseAclConnectionByTransport(uint8_t transport)1903 void BtmCloseAclConnectionByTransport(uint8_t transport)
1904 {
1905     bool noActiveConnection = false;
1906 
1907     BtmAclConnection *connection = NULL;
1908     HciDisconnectParam param = {
1909         .reason = HCI_REMOTE_USER_TERMINATED_CONNECTION,
1910     };
1911 
1912     while (!noActiveConnection) {
1913         uint16_t connectionHandle = 0xffff;
1914         MutexLock(g_aclListLock);
1915         ListNode *node = ListGetFirstNode(g_aclList);
1916         while (node != NULL) {
1917             connection = ListGetNodeData(node);
1918             if (connection->transport == transport && connection->state == CONNECTED) {
1919                 connectionHandle = connection->connectionHandle;
1920                 connection->state = DISCONNECTING;
1921                 break;
1922             }
1923             node = ListGetNextNode(node);
1924         }
1925         MutexUnlock(g_aclListLock);
1926 
1927         if (connectionHandle != 0xffff) {
1928             MutexLock(g_cleanupMutex);
1929             g_cleanupHandle = connectionHandle;
1930             MutexUnlock(g_cleanupMutex);
1931 
1932             param.connectionHandle = connectionHandle;
1933             HCI_Disconnect(&param);
1934 
1935             AlarmSet(g_cleanupTimer, CLEANUP_TIMEOUT, BtmAclOnCleanUpTimeout, NULL);
1936             SemaphoreWait(g_cleanupEvent);
1937 
1938             MutexLock(g_cleanupMutex);
1939             g_cleanupHandle = 0xffff;
1940             MutexUnlock(g_cleanupMutex);
1941         } else {
1942             noActiveConnection = true;
1943         }
1944     }
1945 }
1946 
BTM_AclCancelConnect(const BtAddr * addr)1947 int BTM_AclCancelConnect(const BtAddr *addr)
1948 {
1949     if (addr == NULL) {
1950         return BT_BAD_PARAM;
1951     }
1952 
1953     if (!IS_INITIALIZED()) {
1954         return BT_BAD_STATUS;
1955     }
1956 
1957     int result;
1958     MutexLock(g_aclListLock);
1959     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
1960     if (connection != NULL) {
1961         ListRemoveNode(g_aclList, connection);
1962         HciCreateConnectionCancelParam param = {
1963             .bdAddr =
1964                 {
1965                     .raw = {0},
1966                 },
1967         };
1968         (void)memcpy_s(param.bdAddr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
1969         result = HCI_CreateConnectionCancel(&param);
1970     } else {
1971         result = BT_BAD_STATUS;
1972     }
1973     MutexUnlock(g_aclListLock);
1974     return result;
1975 }
1976 
BTM_LeCancelConnect(const BtAddr * addr)1977 int BTM_LeCancelConnect(const BtAddr *addr)
1978 {
1979     if (addr == NULL) {
1980         return BT_BAD_PARAM;
1981     }
1982 
1983     if (!IS_INITIALIZED()) {
1984         return BT_BAD_STATUS;
1985     }
1986 
1987     int reuslt = BT_SUCCESS;
1988 
1989     MutexLock(g_aclListLock);
1990 
1991     BtmAclConnection *connection = BtmAclFindLeConnectionByAddr(addr);
1992     if (connection != NULL) {
1993         if (connection->state == CONNECTING) {
1994             MutexLock(g_leConnectionCancelLock);
1995             BtAddr *cancelAddr = MEM_MALLOC.alloc(sizeof(BtAddr));
1996             if (cancelAddr != NULL) {
1997                 *cancelAddr = *addr;
1998                 ListAddLast(g_leConnectionCancelList, cancelAddr);
1999             }
2000             MutexUnlock(g_leConnectionCancelLock);
2001 
2002             BtmWhiteListPendingAction *action = MEM_MALLOC.alloc(sizeof(BtmWhiteListPendingAction));
2003             if (action != NULL) {
2004                 action->action = ACTION_REMOVE_FORM_WHITE_LIST;
2005                 action->addr = *addr;
2006                 BtmConvertAddressForConnection(&action->addr);
2007                 QueueEnqueue(g_leWhiteListPendingActionQueue, action);
2008             }
2009 
2010             BtmStopAutoConnection();
2011 
2012             ListRemoveNode(g_aclList, connection);
2013         } else {
2014             reuslt = BT_BAD_STATUS;
2015         }
2016     } else {
2017         reuslt = BT_BAD_STATUS;
2018     }
2019 
2020     MutexUnlock(g_aclListLock);
2021 
2022     return reuslt;
2023 }
2024 
BTM_IsRemoteDeviceSupportHostSecureSimplePairing(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2025 void BTM_IsRemoteDeviceSupportHostSecureSimplePairing(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2026 {
2027     BtmAclConnection *connection = NULL;
2028     BTMRemoteDeviceSupportCallback callback_ = NULL;
2029     bool isSupported = false;
2030 
2031     MutexLock(g_aclListLock);
2032 
2033     connection = BtmAclFindConnectionByAddr(addr);
2034     if (connection != NULL) {
2035         if (connection->remoteFeatures.bredr.extendedFeatureStatus != REQUEST_NOT_COMPLETED) {
2036             callback_ = callback;
2037             isSupported =
2038                 HCI_SUPPORT_SECURE_SIMPLE_PAIRING_HOST(connection->remoteFeatures.bredr.extendedLmpFeatures.page[1]);
2039         } else {
2040             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2041             if (request != NULL) {
2042                 request->addr = *addr;
2043                 request->callback = callback;
2044                 request->connectionHandle = connection->connectionHandle;
2045                 request->event = REMOTE_EXTENDED_FEATURE_COMPLETE;
2046                 request->feature.extendedFeature = SECURE_SIMPLE_PAIRING_HOST_SUPPORT;
2047 
2048                 ListAddLast(g_remoteSupportRequestList, request);
2049             }
2050         }
2051     } else {
2052         callback_ = callback;
2053     }
2054 
2055     MutexUnlock(g_aclListLock);
2056 
2057     if (callback_ != NULL) {
2058         callback_(addr, isSupported);
2059     }
2060 }
2061 
BTM_IsRemoteDeviceSupportConnectionParametersRequest(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2062 void BTM_IsRemoteDeviceSupportConnectionParametersRequest(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2063 {
2064     BtmAclConnection *connection = NULL;
2065     BTMRemoteDeviceSupportCallback callback_ = NULL;
2066     bool isSupported = false;
2067 
2068     MutexLock(g_aclListLock);
2069 
2070     connection = BtmAclFindConnectionByAddr(addr);
2071     if (connection != NULL) {
2072         if (connection->remoteFeatures.bredr.extendedFeatureStatus != REQUEST_NOT_COMPLETED) {
2073             callback_ = callback;
2074             isSupported =
2075                 HCI_SUPPORT_CONNECTION_PARAMETERS_REQUEST_PROCEDURE(connection->remoteFeatures.le.leFeatures.raw);
2076         } else {
2077             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2078             if (request != NULL) {
2079                 request->addr = *addr;
2080                 request->callback = callback;
2081                 request->connectionHandle = connection->connectionHandle;
2082                 request->event = REMOTE_LE_FEATURE_COMPLETE;
2083                 request->feature.leFreature = CONNECTION_PARAMETER_REQUEST;
2084 
2085                 ListAddLast(g_remoteSupportRequestList, request);
2086             }
2087         }
2088     } else {
2089         callback_ = callback;
2090     }
2091 
2092     MutexUnlock(g_aclListLock);
2093 
2094     if (callback_ != NULL) {
2095         callback_(addr, isSupported);
2096     }
2097 }
2098 
BTM_IsRemoteDeviceSupportEdrAcl2MbMode(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2099 void BTM_IsRemoteDeviceSupportEdrAcl2MbMode(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2100 {
2101     BtmAclConnection *connection = NULL;
2102     BTMRemoteDeviceSupportCallback callback_ = NULL;
2103     bool isSupported = false;
2104 
2105     MutexLock(g_aclListLock);
2106 
2107     connection = BtmAclFindConnectionByAddr(addr);
2108     if (connection != NULL) {
2109         if (connection->remoteFeatures.bredr.featureStatus != REQUEST_NOT_COMPLETED) {
2110             callback_ = callback;
2111             isSupported = HCI_SUPPORT_EDR_ACL_2MBS_MODE(connection->remoteFeatures.bredr.lmpFeatures.raw);
2112         } else {
2113             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2114             if (request != NULL) {
2115                 request->addr = *addr;
2116                 request->callback = callback;
2117                 request->connectionHandle = connection->connectionHandle;
2118                 request->event = REMOTE_FEATURE_COMPLETE;
2119                 request->feature.feature = EDR_ACL_2MB_MODE;
2120 
2121                 ListAddLast(g_remoteSupportRequestList, request);
2122             }
2123         }
2124     } else {
2125         callback_ = callback;
2126     }
2127 
2128     MutexUnlock(g_aclListLock);
2129 
2130     if (callback_ != NULL) {
2131         callback_(addr, isSupported);
2132     }
2133 }
2134 
BTM_IsRemoteDeviceSupportEdrAcl3MbMode(const BtAddr * addr,BTMRemoteDeviceSupportCallback callback)2135 void BTM_IsRemoteDeviceSupportEdrAcl3MbMode(const BtAddr *addr, BTMRemoteDeviceSupportCallback callback)
2136 {
2137     BtmAclConnection *connection = NULL;
2138     BTMRemoteDeviceSupportCallback callback_ = NULL;
2139     bool isSupported = false;
2140 
2141     MutexLock(g_aclListLock);
2142 
2143     connection = BtmAclFindConnectionByAddr(addr);
2144     if (connection != NULL) {
2145         if (connection->remoteFeatures.bredr.featureStatus != REQUEST_NOT_COMPLETED) {
2146             callback_ = callback;
2147             isSupported = HCI_SUPPORT_EDR_ACL_3MBS_MODE(connection->remoteFeatures.bredr.lmpFeatures.raw);
2148         } else {
2149             BtmRemoteDeviceSupportRequest *request = MEM_MALLOC.alloc(sizeof(BtmRemoteDeviceSupportRequest));
2150             if (request != NULL) {
2151                 request->addr = *addr;
2152                 request->callback = callback;
2153                 request->connectionHandle = connection->connectionHandle;
2154                 request->event = REMOTE_FEATURE_COMPLETE;
2155                 request->feature.feature = EDR_ACL_3MB_MODE;
2156 
2157                 ListAddLast(g_remoteSupportRequestList, request);
2158             }
2159         }
2160     } else {
2161         callback_ = callback;
2162     }
2163 
2164     MutexUnlock(g_aclListLock);
2165 
2166     if (callback_ != NULL) {
2167         callback_(addr, isSupported);
2168     }
2169 }
2170 
BTM_SetDefaultLinkPolicySettings(uint16_t linkPolicySettings)2171 int BTM_SetDefaultLinkPolicySettings(uint16_t linkPolicySettings)
2172 {
2173     HciWriteDefaultLinkPolicySettingsParam param = {
2174         .defaultLinkPolicySettings = HCI_LINK_POLICY_DISABLE_ALL,
2175     };
2176 
2177     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_ROLE_SWITCH) && BTM_IsControllerSupportRoleSwitch()) {
2178         param.defaultLinkPolicySettings |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH;
2179     }
2180     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_HOLD_MODE) && BTM_IsControllerSupportHoldMode()) {
2181         param.defaultLinkPolicySettings |= HCI_LINK_POLICY_ENABLE_HOLD_MODE;
2182     }
2183     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_SNIFF_MODE) && BTM_IsControllerSupportSniffMode()) {
2184         param.defaultLinkPolicySettings |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE;
2185     }
2186 
2187     return HCI_WriteDefaultLinkPolicySettings(&param);
2188 }
2189 
BTM_SetLinkPolicySettings(const BtAddr * addr,uint16_t linkPolicySettings)2190 int BTM_SetLinkPolicySettings(const BtAddr *addr, uint16_t linkPolicySettings)
2191 {
2192     uint16_t connectionHandle = 0xffff;
2193     int result = BtmGetAclHandleByAddress(addr, &connectionHandle);
2194     if (result != BT_SUCCESS) {
2195         return result;
2196     }
2197 
2198     HciWriteLinkPolicySettingsParam param = {
2199         .connectionHandle = connectionHandle,
2200         .linkPolicySettings = HCI_LINK_POLICY_DISABLE_ALL,
2201     };
2202 
2203     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_ROLE_SWITCH) && BTM_IsControllerSupportRoleSwitch()) {
2204         param.linkPolicySettings |= HCI_LINK_POLICY_ENABLE_ROLE_SWITCH;
2205     }
2206     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_HOLD_MODE) && BTM_IsControllerSupportHoldMode()) {
2207         param.linkPolicySettings |= HCI_LINK_POLICY_ENABLE_HOLD_MODE;
2208     }
2209     if ((linkPolicySettings & BTM_LINK_POLICY_ENABLE_SNIFF_MODE) && BTM_IsControllerSupportSniffMode()) {
2210         param.linkPolicySettings |= HCI_LINK_POLICY_ENABLE_SNIFF_MODE;
2211     }
2212 
2213     return HCI_WriteLinkPolicySettings(&param);
2214 }
2215 
BtmOnRoleChange(const HciRoleChangeEventParam * eventParam)2216 void BtmOnRoleChange(const HciRoleChangeEventParam *eventParam)
2217 {
2218     BtAddr addr = {
2219         .addr = {0},
2220         .type = BT_PUBLIC_DEVICE_ADDRESS,
2221     };
2222     (void)memcpy_s(addr.addr, BT_ADDRESS_SIZE, eventParam->bdAddr.raw, BT_ADDRESS_SIZE);
2223 
2224     MutexLock(g_aclCallbackListLock);
2225     ListNode *node = ListGetFirstNode(g_aclCallbackList);
2226     BtmAclCallbacksBlock *block = NULL;
2227     while (node != NULL) {
2228         block = (BtmAclCallbacksBlock *)ListGetNodeData(node);
2229         if (block->callbacks->roleChange != NULL) {
2230             block->callbacks->roleChange(eventParam->status, &addr, eventParam->newRole, block->context);
2231         }
2232         node = ListGetNextNode(node);
2233     }
2234     MutexUnlock(g_aclCallbackListLock);
2235 }
2236 
BTM_SwitchRole(const BtAddr * addr,uint8_t role)2237 int BTM_SwitchRole(const BtAddr *addr, uint8_t role)
2238 {
2239     if (!IS_INITIALIZED()) {
2240         return BT_BAD_STATUS;
2241     }
2242 
2243     if (addr == NULL || (role != BTM_ROLE_MASTER && role != BTM_ROLE_SLAVE)) {
2244         return BT_BAD_PARAM;
2245     }
2246 
2247     uint16_t connectionHandle = 0xffff;
2248     int result = BtmGetAclHandleByAddress(addr, &connectionHandle);
2249     if (result != BT_SUCCESS) {
2250         return result;
2251     }
2252 
2253     BTM_ExitSniffMode(addr);
2254 
2255     HciSwitchRoleParam param = {
2256         .bdAddr =
2257             {
2258                 .raw = {0},
2259             },
2260         .role = role,
2261     };
2262     (void)memcpy_s(param.bdAddr.raw, BT_ADDRESS_SIZE, addr->addr, BT_ADDRESS_SIZE);
2263 
2264     result = HCI_SwitchRole(&param);
2265 
2266     return result;
2267 }
2268 
BTM_SetLeConnectionModeToFast()2269 int BTM_SetLeConnectionModeToFast()
2270 {
2271     if (!IS_INITIALIZED()) {
2272         return BT_BAD_STATUS;
2273     }
2274 
2275     MutexLock(g_autoConnectLock);
2276 
2277     if (g_leScanInterval != LE_SCAN_INTERVAL_FAST || g_leScanWindow != LE_SCAN_WINDOW_FAST) {
2278         if (BtmGetDeviceCountInWhiteList() > 0) {
2279             BtmStopAutoConnectionInternal();
2280         }
2281 
2282         g_leScanInterval = LE_SCAN_INTERVAL_FAST;
2283         g_leScanWindow = LE_SCAN_WINDOW_FAST;
2284     }
2285 
2286     MutexUnlock(g_autoConnectLock);
2287 
2288     return BT_SUCCESS;
2289 }
2290 
BTM_SetLeConnectionModeToSlow()2291 int BTM_SetLeConnectionModeToSlow()
2292 {
2293     if (!IS_INITIALIZED()) {
2294         return BT_BAD_STATUS;
2295     }
2296 
2297     MutexLock(g_autoConnectLock);
2298 
2299     if (g_leScanInterval != LE_SCAN_INTERVAL_SLOW || g_leScanWindow != LE_SCAN_WINDOW_SLOW) {
2300         if (BtmGetDeviceCountInWhiteList() > 0) {
2301             BtmStopAutoConnectionInternal();
2302         }
2303 
2304         g_leScanInterval = LE_SCAN_INTERVAL_SLOW;
2305         g_leScanWindow = LE_SCAN_WINDOW_SLOW;
2306     }
2307 
2308     MutexUnlock(g_autoConnectLock);
2309 
2310     return BT_SUCCESS;
2311 }
2312 
BtmGenerateSupportedPacketTypes(const HciLmpFeatures * lmpFeature)2313 static uint16_t BtmGenerateSupportedPacketTypes(const HciLmpFeatures *lmpFeature)
2314 {
2315     uint16_t packetType = BTM_ACL_PACKET_TYPE_DH1 | BTM_ACL_PACKET_TYPE_DM1;
2316 
2317     if (HCI_SUPPORT_3_SLOT_PACKETS(lmpFeature->raw)) {
2318         packetType |= BTM_ACL_PACKET_TYPE_DH3;
2319         packetType |= BTM_ACL_PACKET_TYPE_DM3;
2320     }
2321 
2322     if (HCI_SUPPORT_5_SLOT_PACKETS(lmpFeature->raw)) {
2323         packetType |= BTM_ACL_PACKET_TYPE_DH5;
2324         packetType |= BTM_ACL_PACKET_TYPE_DM5;
2325     }
2326 
2327     if (!HCI_SUPPORT_EDR_ACL_2MBS_MODE(lmpFeature->raw)) {
2328         packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH1;
2329         packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH3;
2330         packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH5;
2331     } else {
2332         if (!HCI_SUPPORT_3_SLOT_EDR_PACKET(lmpFeature->raw)) {
2333             packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH3;
2334         }
2335         if (!HCI_SUPPORT_5_SLOT_EDR_PACKET(lmpFeature->raw)) {
2336             packetType |= BTM_ACL_PACKET_TYPE_NO_2_DH5;
2337         }
2338     }
2339 
2340     if (!HCI_SUPPORT_EDR_ACL_3MBS_MODE(lmpFeature->raw)) {
2341         packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH1;
2342         packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH3;
2343         packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH5;
2344     } else {
2345         if (!HCI_SUPPORT_3_SLOT_EDR_PACKET(lmpFeature->raw)) {
2346             packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH3;
2347         }
2348         if (!HCI_SUPPORT_5_SLOT_EDR_PACKET(lmpFeature->raw)) {
2349             packetType |= BTM_ACL_PACKET_TYPE_NO_3_DH5;
2350         }
2351     }
2352 
2353     return packetType;
2354 }
2355 
BTM_ChangeConnectionPacketType(const BtAddr * addr,uint16_t packetType)2356 int BTM_ChangeConnectionPacketType(const BtAddr *addr, uint16_t packetType)
2357 {
2358     if (!IS_INITIALIZED()) {
2359         return BT_BAD_STATUS;
2360     }
2361 
2362     if (addr == NULL) {
2363         return BT_BAD_PARAM;
2364     }
2365 
2366     uint16_t connectionHandle = 0xffff;
2367     uint16_t peerPacketType = 0;
2368 
2369     MutexLock(g_aclListLock);
2370     BtmAclConnection *connection = BtmAclFindConnectionByAddr(addr);
2371     if (connection != NULL) {
2372         connectionHandle = connection->connectionHandle;
2373         peerPacketType = BtmGenerateSupportedPacketTypes(&connection->remoteFeatures.bredr.lmpFeatures);
2374     }
2375     MutexUnlock(g_aclListLock);
2376 
2377     if (connectionHandle == 0xffff) {
2378         return BT_BAD_STATUS;
2379     }
2380 
2381     HciLmpFeatures lmpFeatures = {0};
2382     BtmGetLocalSupportedFeature(&lmpFeatures);
2383     uint16_t localPacketType = BtmGenerateSupportedPacketTypes(&lmpFeatures);
2384 
2385     const uint16_t usedTypes = BTM_ACL_PACKET_TYPE_DM1 | BTM_ACL_PACKET_TYPE_DH1 | BTM_ACL_PACKET_TYPE_DM3 |
2386                                BTM_ACL_PACKET_TYPE_DH3 | BTM_ACL_PACKET_TYPE_DM5 | BTM_ACL_PACKET_TYPE_DH5;
2387     const uint16_t unusedTypes = BTM_ACL_PACKET_TYPE_NO_2_DH1 | BTM_ACL_PACKET_TYPE_NO_3_DH1 |
2388                                  BTM_ACL_PACKET_TYPE_NO_2_DH3 | BTM_ACL_PACKET_TYPE_NO_3_DH3 |
2389                                  BTM_ACL_PACKET_TYPE_NO_2_DH5 | BTM_ACL_PACKET_TYPE_NO_3_DH5;
2390 
2391     uint16_t hciPacketType = (packetType & usedTypes) & (localPacketType & usedTypes) & (peerPacketType & usedTypes);
2392     hciPacketType |= ((packetType & unusedTypes) | (localPacketType & unusedTypes) | (peerPacketType & unusedTypes));
2393 
2394     HciChangeConnectionPacketTypeParam param = {
2395         .connectionHandle = connectionHandle,
2396         .packetType = hciPacketType,
2397     };
2398     return HCI_ChangeConnectionPacketType(&param);
2399 }
2400 
2401 static HciEventCallbacks g_hciEventCallbacks = {
2402     .connectionComplete = BtmOnConnectionComplete,
2403     .connectionRequest = BtmOnConnectionrequest,
2404     .disconnectComplete = BtmOnDisconnectComplete,
2405     .encryptionChange = BtmOnEncryptionChange,
2406     .readRemoteSupportedFeaturesComplete = BtmOnReadRemoteSupportedFeaturesComplete,
2407     .readRemoteVersionInformationComplete = BtmOnReadRemoteVersionInformationComplete,
2408     .commandStatus = BtmAclOnCommandStatus,
2409     .roleChange = BtmOnRoleChange,
2410     .readRemoteExtendedFeaturesComplete = BtmOnReadRemoteExtendedFeaturesComplete,
2411 
2412     .readRssiComplete = BtmOnReadRssiComplete,
2413 
2414     .leConnectionComplete = BtmOnLeConnectionComplete,
2415     .leReadRemoteFeaturesComplete = BtmOnLeReadRemoteFeaturesComplete,
2416     .leEnhancedConnectionComplete = BtmOnLeEnhancedConnectionComplete,
2417 };
2418