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(¶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_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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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