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