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