1 /*
2 * Copyright (C) 2021 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.h"
17
18 #include <stdint.h>
19
20 #include "btstack.h"
21 #include "hci/hci.h"
22 #include "log.h"
23 #include "module.h"
24 #include "platform/include/alarm.h"
25 #include "platform/include/allocator.h"
26 #include "platform/include/list.h"
27 #include "platform/include/mutex.h"
28 #include "platform/include/thread.h"
29
30 #include "btm_acl.h"
31 #include "btm_controller.h"
32 #include "btm_inq_db.h"
33 #include "btm_le_sec.h"
34 #include "btm_pm.h"
35 #include "btm_sco.h"
36 #include "btm_snoop.h"
37 #include "btm_thread.h"
38 #include "btm_wl.h"
39
40 #define STATUS_NONE 0
41 #define STATUS_INITIALIZED 1
42
43 #define IS_INITIALIZED() (g_status == STATUS_INITIALIZED)
44
45 #define MODE_NONE 0
46 #define MODE_BREDR 1
47 #define MODE_LE 2
48 #define MODE_DUAL (MODE_BREDR | MODE_LE)
49
50 typedef struct {
51 const BtmCallbacks *callbacks;
52 void *context;
53 } BtmCallbacksBlock;
54
55 static uint8_t g_currentMode = MODE_NONE;
56 static Mutex *g_modeLock = NULL;
57
58 static HciFailureCallbacks g_hciFailureCallbacks;
59
60 static const int G_COUNT_OF_ALL_MODULES = 8;
61 static const char *g_allModules[] = {
62 MODULE_NAME_L2CAP,
63 MODULE_NAME_GAP,
64 MODULE_NAME_SDP,
65 MODULE_NAME_AVCTP,
66 MODULE_NAME_AVDTP,
67 MODULE_NAME_RFCOMM,
68 MODULE_NAME_ATT,
69 MODULE_NAME_SMP,
70 };
71
72 static const int G_COUNTOF_BREDR_AND_SHARED_MODULES = 8;
73 static const char *g_bredrAndSharedModules[] = {
74 MODULE_NAME_L2CAP,
75 MODULE_NAME_SMP,
76 MODULE_NAME_GAP,
77 MODULE_NAME_SDP,
78 MODULE_NAME_AVCTP,
79 MODULE_NAME_AVDTP,
80 MODULE_NAME_RFCOMM,
81 MODULE_NAME_ATT,
82 };
83
84 static const int G_COUNT_OF_BREDR_MODULES = 4;
85 static const char *g_bredrModules[] = {
86 MODULE_NAME_SDP,
87 MODULE_NAME_AVCTP,
88 MODULE_NAME_AVDTP,
89 MODULE_NAME_RFCOMM,
90 };
91
92 static const int G_COUNT_OF_LE_AND_SHARED_MODULES = 4;
93 static const char *g_leAndSharedModules[] = {
94 MODULE_NAME_L2CAP,
95 MODULE_NAME_SMP,
96 MODULE_NAME_GAP,
97 MODULE_NAME_ATT,
98 };
99
100 static const int G_COUNT_OF_LE_MODULES = 0;
101 static const char *g_leModules[] = {};
102
103 static List *g_btmCallbackList = NULL;
104 static Mutex *g_btmCallbackListLock = NULL;
105 static uint8_t g_status = STATUS_NONE;
106
BtmAllocCallbacksBlock(const BtmCallbacks * callbacks,void * context)107 static BtmCallbacksBlock *BtmAllocCallbacksBlock(const BtmCallbacks *callbacks, void *context)
108 {
109 BtmCallbacksBlock *block = MEM_MALLOC.alloc(sizeof(BtmCallbacksBlock));
110 if (block != NULL) {
111 block->callbacks = (BtmCallbacks *)callbacks;
112 block->context = context;
113 }
114 return block;
115 }
116
BtmFreeCallbacksBlock(void * block)117 static void BtmFreeCallbacksBlock(void *block)
118 {
119 MEM_MALLOC.free(block);
120 }
121
122 #ifdef DEBUG
BtmOutputCurrentStatus()123 static void BtmOutputCurrentStatus()
124 {
125 LOG_DEBUG("BR/EDR: %{public}s LE: %{public}s",
126 (g_currentMode & MODE_BREDR) ? "Enabled" : "Disabled",
127 (g_currentMode & MODE_LE) ? "Enabled" : "Disabled");
128 }
129 #endif
130
BtmInitFeatures()131 static void BtmInitFeatures()
132 {
133 BtmInitThread();
134 BtmInitSnoop();
135 BtmInitAcl();
136 BtmInitSco();
137 BtmInitPm();
138 BtmInitInquiryDb();
139 BtmInitLeSecurity();
140 BtmInitWhiteList();
141 }
142
BtmCloseFeatures()143 static void BtmCloseFeatures()
144 {
145 BtmCloseWhiteList();
146 BtmCloseLeSecurity();
147 BtmCloseInquiryDb();
148 BtmClosePm();
149 BtmCloseSco();
150 BtmCloseAcl();
151 BtmCloseSnoop();
152 BtmCloseThread();
153 }
154
BTM_Initialize()155 int BTM_Initialize()
156 {
157 LOG_DEBUG("%{public}s start", __FUNCTION__);
158
159 int result = BT_NO_ERROR;
160 do {
161 int32_t ret = AlarmModuleInit();
162 if (ret != 0) {
163 result = BT_OPERATION_FAILED;
164 break;
165 }
166
167 g_modeLock = MutexCreate();
168 if (g_modeLock == NULL) {
169 result = BT_OPERATION_FAILED;
170 break;
171 }
172
173 g_btmCallbackList = ListCreate(BtmFreeCallbacksBlock);
174 if (g_btmCallbackList == NULL) {
175 result = BT_OPERATION_FAILED;
176 break;
177 }
178
179 g_btmCallbackListLock = MutexCreate();
180 if (g_btmCallbackListLock == NULL) {
181 result = BT_OPERATION_FAILED;
182 break;
183 }
184
185 BtmInitFeatures();
186
187 LOG_DEBUG("ModuleInit start");
188 for (int i = 0; i < G_COUNT_OF_ALL_MODULES; i++) {
189 LOG_DEBUG("ModuleInit: %{public}s", g_allModules[i]);
190 ModuleInit(g_allModules[i], 0);
191 }
192 LOG_DEBUG("ModuleInit end");
193
194 g_status = STATUS_INITIALIZED;
195 } while (0);
196
197 LOG_DEBUG("%{public}s end", __FUNCTION__);
198
199 return result;
200 }
201
BTM_Close()202 int BTM_Close()
203 {
204 LOG_DEBUG("%{public}s start", __FUNCTION__);
205
206 if (BTM_Disable(LE_CONTROLLER) != BT_NO_ERROR) {
207 LOG_WARN("Disable LE Failed");
208 }
209 if (BTM_Disable(BREDR_CONTROLLER) != BT_NO_ERROR) {
210 LOG_WARN("Disable BREDR Failed");
211 }
212
213 g_status = STATUS_NONE;
214
215 LOG_DEBUG("ModuleCleanup start");
216 for (int i = G_COUNT_OF_ALL_MODULES - 1; i >= 0; i--) {
217 LOG_DEBUG("ModuleCleanup: %{public}s", g_allModules[i]);
218 ModuleCleanup(g_allModules[i]);
219 }
220 LOG_DEBUG("ModuleCleanup end");
221
222 BtmCloseFeatures();
223
224 if (g_btmCallbackListLock != NULL) {
225 MutexDelete(g_btmCallbackListLock);
226 g_btmCallbackListLock = NULL;
227 }
228
229 if (g_btmCallbackList != NULL) {
230 ListDelete(g_btmCallbackList);
231 g_btmCallbackList = NULL;
232 }
233
234 if (g_modeLock != NULL) {
235 MutexDelete(g_modeLock);
236 g_modeLock = NULL;
237 }
238
239 AlarmModuleCleanup();
240
241 LOG_DEBUG("%{public}s end", __FUNCTION__);
242
243 return BT_NO_ERROR;
244 }
245
BtmEnableBrEdrAndSharedModules()246 static int BtmEnableBrEdrAndSharedModules()
247 {
248 BtmStartSnoopOutput();
249
250 int result = HCI_Initialize();
251 if (result == BT_NO_ERROR) {
252 HCI_RegisterFailureCallback(&g_hciFailureCallbacks);
253
254 result = BtmInitController();
255 if (result == BT_NO_ERROR) {
256 BtmStartAcl();
257 BtmStartPm();
258 BtmStartSco();
259
260 LOG_DEBUG("ModuleStartup start");
261 for (int i = 0; i < G_COUNTOF_BREDR_AND_SHARED_MODULES; i++) {
262 LOG_DEBUG("ModuleStartup: %{public}s", g_bredrAndSharedModules[i]);
263 ModuleStartup(g_bredrAndSharedModules[i]);
264 }
265 LOG_DEBUG("ModuleStartup end");
266 }
267 }
268
269 if (result != BT_NO_ERROR) {
270 HCI_Close();
271
272 BtmStopSnoopOutput();
273 }
274
275 return result;
276 }
277
BtmEnableBrEdrModules()278 static int BtmEnableBrEdrModules()
279 {
280 BtmStartPm();
281 BtmStartSco();
282
283 LOG_DEBUG("ModuleStartup start");
284 for (int i = 0; i < G_COUNT_OF_BREDR_MODULES; i++) {
285 LOG_DEBUG("ModuleStartup: %{public}s", g_bredrModules[i]);
286 ModuleStartup(g_bredrModules[i]);
287 }
288 LOG_DEBUG("ModuleStartup end");
289
290 return BT_NO_ERROR;
291 }
292
BtmEnableLeAndSharedModules()293 static int BtmEnableLeAndSharedModules()
294 {
295 BtmStartSnoopOutput();
296
297 int result = HCI_Initialize();
298 if (result == BT_NO_ERROR) {
299 HCI_RegisterFailureCallback(&g_hciFailureCallbacks);
300
301 result = BtmInitController();
302 if (result == BT_NO_ERROR) {
303 BtmStartAcl();
304 BtmStartLeSecurity();
305 BtmStartWhiteList();
306
307 LOG_DEBUG("ModuleStartup start");
308 for (int i = 0; i < G_COUNT_OF_LE_AND_SHARED_MODULES; i++) {
309 LOG_DEBUG("ModuleStartup: %{public}s", g_leAndSharedModules[i]);
310 ModuleStartup(g_leAndSharedModules[i]);
311 }
312 LOG_DEBUG("ModuleStartup end");
313 }
314 }
315
316 if (result != BT_NO_ERROR) {
317 HCI_Close();
318
319 BtmStopSnoopOutput();
320 }
321
322 return result;
323 }
324
BtmEnableLeModules()325 static int BtmEnableLeModules()
326 {
327 BtmStartLeSecurity();
328 BtmStartWhiteList();
329
330 LOG_DEBUG("ModuleStartup start");
331 for (int i = 0; i < G_COUNT_OF_LE_MODULES; i++) {
332 LOG_DEBUG("ModuleStartup: %{public}s", g_leModules[i]);
333 ModuleStartup(g_leModules[i]);
334 }
335 LOG_DEBUG("ModuleStartup end");
336
337 return BT_NO_ERROR;
338 }
339
BtmDisableBrEdrAndSharedModules()340 static void BtmDisableBrEdrAndSharedModules()
341 {
342 BtmCloseAclConnectionByTransport(TRANSPORT_BREDR);
343
344 LOG_DEBUG("ModuleShutdown start");
345 for (int i = G_COUNTOF_BREDR_AND_SHARED_MODULES - 1; i >= 0; i--) {
346 LOG_DEBUG("ModuleShutdown: %{public}s", g_bredrAndSharedModules[i]);
347 ModuleShutdown(g_bredrAndSharedModules[i]);
348 }
349 LOG_DEBUG("ModuleShutdown end");
350
351 BtmClearInquiryDb();
352 BtmStopSco();
353 BtmStopPm();
354 BtmStopAcl();
355 BtmCloseController();
356
357 HCI_DeregisterFailureCallback(&g_hciFailureCallbacks);
358 HCI_Close();
359
360 BtmStopSnoopOutput();
361 }
362
BtmDisableBrEdrModules()363 static void BtmDisableBrEdrModules()
364 {
365 BtmCloseAclConnectionByTransport(TRANSPORT_BREDR);
366
367 LOG_DEBUG("ModuleShutdown start");
368 for (int i = G_COUNT_OF_BREDR_MODULES - 1; i >= 0; i--) {
369 LOG_DEBUG("ModuleShutdown: %{public}s", g_bredrModules[i]);
370 ModuleShutdown(g_bredrModules[i]);
371 }
372 LOG_DEBUG("ModuleShutdown end");
373
374 BtmClearInquiryDb();
375 BtmStopSco();
376 BtmStopPm();
377 }
378
BtmDisableLeAndSharedModules()379 static void BtmDisableLeAndSharedModules()
380 {
381 BtmCloseAclConnectionByTransport(TRANSPORT_LE);
382
383 LOG_DEBUG("ModuleShutdown start");
384 for (int i = G_COUNT_OF_LE_AND_SHARED_MODULES - 1; i >= 0; i--) {
385 LOG_DEBUG("ModuleShutdown: %{public}s", g_leAndSharedModules[i]);
386 ModuleShutdown(g_leAndSharedModules[i]);
387 }
388 LOG_DEBUG("ModuleShutdown end");
389
390 BtmStopWhiteList();
391 BtmStopLeSecurity();
392 BtmStopAcl();
393 BtmCloseController();
394
395 HCI_DeregisterFailureCallback(&g_hciFailureCallbacks);
396 HCI_Close();
397
398 BtmStopSnoopOutput();
399 }
400
BtmDisableLeModules()401 static void BtmDisableLeModules()
402 {
403 BtmCloseAclConnectionByTransport(TRANSPORT_LE);
404
405 LOG_DEBUG("ModuleShutdown start");
406 for (int i = G_COUNT_OF_LE_MODULES - 1; i >= 0; i--) {
407 LOG_DEBUG("ModuleShutdown: %{public}s", g_leModules[i]);
408 ModuleShutdown(g_leModules[i]);
409 }
410 LOG_DEBUG("ModuleShutdown end");
411
412 BtmStopWhiteList();
413 BtmStopLeSecurity();
414 }
415
BTM_Enable(int controller)416 int BTM_Enable(int controller)
417 {
418 LOG_DEBUG("%{public}s start", __FUNCTION__);
419
420 if (controller != BREDR_CONTROLLER && controller != LE_CONTROLLER) {
421 return BT_BAD_PARAM;
422 }
423
424 if (!IS_INITIALIZED()) {
425 return BT_BAD_STATUS;
426 }
427
428 int result = BT_NO_ERROR;
429
430 MutexLock(g_modeLock);
431
432 if (controller == BREDR_CONTROLLER) {
433 if (g_currentMode == MODE_NONE) {
434 result = BtmEnableBrEdrAndSharedModules();
435 } else if (g_currentMode == MODE_LE) {
436 result = BtmEnableBrEdrModules();
437 }
438
439 if (result == BT_NO_ERROR) {
440 g_currentMode |= MODE_BREDR;
441 }
442 } else if (controller == LE_CONTROLLER) {
443 if (g_currentMode == MODE_NONE) {
444 result = BtmEnableLeAndSharedModules();
445 } else if (g_currentMode == MODE_BREDR) {
446 result = BtmEnableLeModules();
447 }
448
449 if (result == BT_NO_ERROR) {
450 g_currentMode |= MODE_LE;
451 }
452 }
453
454 #ifdef DEBUG
455 BtmOutputCurrentStatus();
456 #endif
457
458 MutexUnlock(g_modeLock);
459 LOG_DEBUG("%{public}s end", __FUNCTION__);
460 return result;
461 }
462
BTM_Disable(int controller)463 int BTM_Disable(int controller)
464 {
465 LOG_DEBUG("%{public}s start", __FUNCTION__);
466 if (controller != BREDR_CONTROLLER && controller != LE_CONTROLLER) {
467 return BT_BAD_PARAM;
468 }
469
470 if (!IS_INITIALIZED()) {
471 return BT_BAD_STATUS;
472 }
473
474 MutexLock(g_modeLock);
475
476 if (controller == BREDR_CONTROLLER) {
477 if (g_currentMode == MODE_DUAL) {
478 BtmDisableBrEdrModules();
479 } else if (g_currentMode == MODE_BREDR) {
480 BtmDisableBrEdrAndSharedModules();
481 }
482
483 g_currentMode &= (~MODE_BREDR);
484 } else if (controller == LE_CONTROLLER) {
485 if (g_currentMode == MODE_DUAL) {
486 BtmDisableLeModules();
487 } else if (g_currentMode == MODE_LE) {
488 BtmDisableLeAndSharedModules();
489 }
490
491 g_currentMode &= (~MODE_LE);
492 }
493
494 #ifdef DEBUG
495 BtmOutputCurrentStatus();
496 #endif
497
498 MutexUnlock(g_modeLock);
499 LOG_DEBUG("%{public}s end", __FUNCTION__);
500 return BT_NO_ERROR;
501 }
502
BTM_IsEnabled(int controller)503 bool BTM_IsEnabled(int controller)
504 {
505 if (!IS_INITIALIZED()) {
506 return false;
507 }
508
509 bool isEnabled = false;
510
511 if (controller == BREDR_CONTROLLER) {
512 MutexLock(g_modeLock);
513 isEnabled = !!(g_currentMode & MODE_BREDR);
514 MutexUnlock(g_modeLock);
515 } else if (controller == LE_CONTROLLER) {
516 MutexLock(g_modeLock);
517 isEnabled = !!(g_currentMode & MODE_LE);
518 MutexUnlock(g_modeLock);
519 }
520
521 return isEnabled;
522 }
523
BTM_RegisterCallbacks(const BtmCallbacks * callbacks,void * context)524 int BTM_RegisterCallbacks(const BtmCallbacks *callbacks, void *context)
525 {
526 if (callbacks == NULL) {
527 return BT_BAD_PARAM;
528 }
529
530 if (!IS_INITIALIZED()) {
531 return BT_BAD_STATUS;
532 }
533
534 BtmCallbacksBlock *block = BtmAllocCallbacksBlock(callbacks, context);
535 if (block == NULL) {
536 return BT_NO_MEMORY;
537 }
538
539 MutexLock(g_btmCallbackListLock);
540 ListAddLast(g_btmCallbackList, block);
541 MutexUnlock(g_btmCallbackListLock);
542
543 return BT_NO_ERROR;
544 }
545
BTM_DeregisterCallbacks(const BtmCallbacks * callbacks)546 int BTM_DeregisterCallbacks(const BtmCallbacks *callbacks)
547 {
548 if (callbacks == NULL) {
549 return BT_BAD_PARAM;
550 }
551
552 if (!IS_INITIALIZED()) {
553 return BT_BAD_STATUS;
554 }
555
556 MutexLock(g_btmCallbackListLock);
557
558 BtmCallbacksBlock *block = NULL;
559 ListNode *node = ListGetFirstNode(g_btmCallbackList);
560 while (node != NULL) {
561 block = ListGetNodeData(node);
562 if (block != NULL) {
563 if (block->callbacks == callbacks) {
564 ListRemoveNode(g_btmCallbackList, block);
565 break;
566 }
567 }
568 node = ListGetNextNode(node);
569 }
570
571 MutexUnlock(g_btmCallbackListLock);
572
573 return BT_NO_ERROR;
574 }
575
BtmOnHCIFailure()576 static void BtmOnHCIFailure()
577 {
578 BtmCallbacksBlock *block = NULL;
579 MutexLock(g_btmCallbackListLock);
580 ListNode *node = ListGetFirstNode(g_btmCallbackList);
581 while (node != NULL) {
582 block = ListGetNodeData(node);
583 if (block->callbacks != NULL && block->callbacks->hciFailure != NULL) {
584 block->callbacks->hciFailure(block->context);
585 }
586 node = ListGetNextNode(node);
587 }
588 MutexUnlock(g_btmCallbackListLock);
589 }
590
591 static HciFailureCallbacks g_hciFailureCallbacks = {
592 .onCmdTimeout = BtmOnHCIFailure,
593 };
594