• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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