119e95205Sopenharmony_ci/* 219e95205Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 319e95205Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 419e95205Sopenharmony_ci * you may not use this file except in compliance with the License. 519e95205Sopenharmony_ci * You may obtain a copy of the License at 619e95205Sopenharmony_ci * 719e95205Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 819e95205Sopenharmony_ci * 919e95205Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1019e95205Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1119e95205Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1219e95205Sopenharmony_ci * See the License for the specific language governing permissions and 1319e95205Sopenharmony_ci * limitations under the License. 1419e95205Sopenharmony_ci */ 1519e95205Sopenharmony_ci 1619e95205Sopenharmony_ci#include "btm.h" 1719e95205Sopenharmony_ci 1819e95205Sopenharmony_ci#include <stdint.h> 1919e95205Sopenharmony_ci 2019e95205Sopenharmony_ci#include "btstack.h" 2119e95205Sopenharmony_ci#include "hci/hci.h" 2219e95205Sopenharmony_ci#include "log.h" 2319e95205Sopenharmony_ci#include "module.h" 2419e95205Sopenharmony_ci#include "platform/include/alarm.h" 2519e95205Sopenharmony_ci#include "platform/include/allocator.h" 2619e95205Sopenharmony_ci#include "platform/include/list.h" 2719e95205Sopenharmony_ci#include "platform/include/mutex.h" 2819e95205Sopenharmony_ci#include "platform/include/thread.h" 2919e95205Sopenharmony_ci 3019e95205Sopenharmony_ci#include "btm_acl.h" 3119e95205Sopenharmony_ci#include "btm_controller.h" 3219e95205Sopenharmony_ci#include "btm_inq_db.h" 3319e95205Sopenharmony_ci#include "btm_le_sec.h" 3419e95205Sopenharmony_ci#include "btm_pm.h" 3519e95205Sopenharmony_ci#include "btm_sco.h" 3619e95205Sopenharmony_ci#include "btm_snoop.h" 3719e95205Sopenharmony_ci#include "btm_thread.h" 3819e95205Sopenharmony_ci#include "btm_wl.h" 3919e95205Sopenharmony_ci 4019e95205Sopenharmony_ci#define STATUS_NONE 0 4119e95205Sopenharmony_ci#define STATUS_INITIALIZED 1 4219e95205Sopenharmony_ci 4319e95205Sopenharmony_ci#define IS_INITIALIZED() (g_status == STATUS_INITIALIZED) 4419e95205Sopenharmony_ci 4519e95205Sopenharmony_ci#define MODE_NONE 0 4619e95205Sopenharmony_ci#define MODE_BREDR 1 4719e95205Sopenharmony_ci#define MODE_LE 2 4819e95205Sopenharmony_ci#define MODE_DUAL (MODE_BREDR | MODE_LE) 4919e95205Sopenharmony_ci 5019e95205Sopenharmony_citypedef struct { 5119e95205Sopenharmony_ci const BtmCallbacks *callbacks; 5219e95205Sopenharmony_ci void *context; 5319e95205Sopenharmony_ci} BtmCallbacksBlock; 5419e95205Sopenharmony_ci 5519e95205Sopenharmony_cistatic uint8_t g_currentMode = MODE_NONE; 5619e95205Sopenharmony_cistatic Mutex *g_modeLock = NULL; 5719e95205Sopenharmony_ci 5819e95205Sopenharmony_cistatic HciFailureCallbacks g_hciFailureCallbacks; 5919e95205Sopenharmony_ci 6019e95205Sopenharmony_cistatic const int G_COUNT_OF_ALL_MODULES = 8; 6119e95205Sopenharmony_cistatic const char *g_allModules[] = { 6219e95205Sopenharmony_ci MODULE_NAME_L2CAP, 6319e95205Sopenharmony_ci MODULE_NAME_GAP, 6419e95205Sopenharmony_ci MODULE_NAME_SDP, 6519e95205Sopenharmony_ci MODULE_NAME_AVCTP, 6619e95205Sopenharmony_ci MODULE_NAME_AVDTP, 6719e95205Sopenharmony_ci MODULE_NAME_RFCOMM, 6819e95205Sopenharmony_ci MODULE_NAME_ATT, 6919e95205Sopenharmony_ci MODULE_NAME_SMP, 7019e95205Sopenharmony_ci}; 7119e95205Sopenharmony_ci 7219e95205Sopenharmony_cistatic const int G_COUNTOF_BREDR_AND_SHARED_MODULES = 8; 7319e95205Sopenharmony_cistatic const char *g_bredrAndSharedModules[] = { 7419e95205Sopenharmony_ci MODULE_NAME_L2CAP, 7519e95205Sopenharmony_ci MODULE_NAME_SMP, 7619e95205Sopenharmony_ci MODULE_NAME_GAP, 7719e95205Sopenharmony_ci MODULE_NAME_SDP, 7819e95205Sopenharmony_ci MODULE_NAME_AVCTP, 7919e95205Sopenharmony_ci MODULE_NAME_AVDTP, 8019e95205Sopenharmony_ci MODULE_NAME_RFCOMM, 8119e95205Sopenharmony_ci MODULE_NAME_ATT, 8219e95205Sopenharmony_ci}; 8319e95205Sopenharmony_ci 8419e95205Sopenharmony_cistatic const int G_COUNT_OF_BREDR_MODULES = 4; 8519e95205Sopenharmony_cistatic const char *g_bredrModules[] = { 8619e95205Sopenharmony_ci MODULE_NAME_SDP, 8719e95205Sopenharmony_ci MODULE_NAME_AVCTP, 8819e95205Sopenharmony_ci MODULE_NAME_AVDTP, 8919e95205Sopenharmony_ci MODULE_NAME_RFCOMM, 9019e95205Sopenharmony_ci}; 9119e95205Sopenharmony_ci 9219e95205Sopenharmony_cistatic const int G_COUNT_OF_LE_AND_SHARED_MODULES = 4; 9319e95205Sopenharmony_cistatic const char *g_leAndSharedModules[] = { 9419e95205Sopenharmony_ci MODULE_NAME_L2CAP, 9519e95205Sopenharmony_ci MODULE_NAME_SMP, 9619e95205Sopenharmony_ci MODULE_NAME_GAP, 9719e95205Sopenharmony_ci MODULE_NAME_ATT, 9819e95205Sopenharmony_ci}; 9919e95205Sopenharmony_ci 10019e95205Sopenharmony_cistatic const int G_COUNT_OF_LE_MODULES = 0; 10119e95205Sopenharmony_cistatic const char *g_leModules[] = {}; 10219e95205Sopenharmony_ci 10319e95205Sopenharmony_cistatic List *g_btmCallbackList = NULL; 10419e95205Sopenharmony_cistatic Mutex *g_btmCallbackListLock = NULL; 10519e95205Sopenharmony_cistatic uint8_t g_status = STATUS_NONE; 10619e95205Sopenharmony_ci 10719e95205Sopenharmony_cistatic BtmCallbacksBlock *BtmAllocCallbacksBlock(const BtmCallbacks *callbacks, void *context) 10819e95205Sopenharmony_ci{ 10919e95205Sopenharmony_ci BtmCallbacksBlock *block = MEM_MALLOC.alloc(sizeof(BtmCallbacksBlock)); 11019e95205Sopenharmony_ci if (block != NULL) { 11119e95205Sopenharmony_ci block->callbacks = (BtmCallbacks *)callbacks; 11219e95205Sopenharmony_ci block->context = context; 11319e95205Sopenharmony_ci } 11419e95205Sopenharmony_ci return block; 11519e95205Sopenharmony_ci} 11619e95205Sopenharmony_ci 11719e95205Sopenharmony_cistatic void BtmFreeCallbacksBlock(void *block) 11819e95205Sopenharmony_ci{ 11919e95205Sopenharmony_ci MEM_MALLOC.free(block); 12019e95205Sopenharmony_ci} 12119e95205Sopenharmony_ci 12219e95205Sopenharmony_ci#ifdef DEBUG 12319e95205Sopenharmony_cistatic void BtmOutputCurrentStatus() 12419e95205Sopenharmony_ci{ 12519e95205Sopenharmony_ci LOG_DEBUG("BR/EDR: %{public}s LE: %{public}s", 12619e95205Sopenharmony_ci (g_currentMode & MODE_BREDR) ? "Enabled" : "Disabled", 12719e95205Sopenharmony_ci (g_currentMode & MODE_LE) ? "Enabled" : "Disabled"); 12819e95205Sopenharmony_ci} 12919e95205Sopenharmony_ci#endif 13019e95205Sopenharmony_ci 13119e95205Sopenharmony_cistatic void BtmInitFeatures() 13219e95205Sopenharmony_ci{ 13319e95205Sopenharmony_ci BtmInitThread(); 13419e95205Sopenharmony_ci BtmInitSnoop(); 13519e95205Sopenharmony_ci BtmInitAcl(); 13619e95205Sopenharmony_ci BtmInitSco(); 13719e95205Sopenharmony_ci BtmInitPm(); 13819e95205Sopenharmony_ci BtmInitInquiryDb(); 13919e95205Sopenharmony_ci BtmInitLeSecurity(); 14019e95205Sopenharmony_ci BtmInitWhiteList(); 14119e95205Sopenharmony_ci} 14219e95205Sopenharmony_ci 14319e95205Sopenharmony_cistatic void BtmCloseFeatures() 14419e95205Sopenharmony_ci{ 14519e95205Sopenharmony_ci BtmCloseWhiteList(); 14619e95205Sopenharmony_ci BtmCloseLeSecurity(); 14719e95205Sopenharmony_ci BtmCloseInquiryDb(); 14819e95205Sopenharmony_ci BtmClosePm(); 14919e95205Sopenharmony_ci BtmCloseSco(); 15019e95205Sopenharmony_ci BtmCloseAcl(); 15119e95205Sopenharmony_ci BtmCloseSnoop(); 15219e95205Sopenharmony_ci BtmCloseThread(); 15319e95205Sopenharmony_ci} 15419e95205Sopenharmony_ci 15519e95205Sopenharmony_ciint BTM_Initialize() 15619e95205Sopenharmony_ci{ 15719e95205Sopenharmony_ci LOG_DEBUG("%{public}s start", __FUNCTION__); 15819e95205Sopenharmony_ci 15919e95205Sopenharmony_ci int result = BT_SUCCESS; 16019e95205Sopenharmony_ci do { 16119e95205Sopenharmony_ci int32_t ret = AlarmModuleInit(); 16219e95205Sopenharmony_ci if (ret != 0) { 16319e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 16419e95205Sopenharmony_ci break; 16519e95205Sopenharmony_ci } 16619e95205Sopenharmony_ci 16719e95205Sopenharmony_ci g_modeLock = MutexCreate(); 16819e95205Sopenharmony_ci if (g_modeLock == NULL) { 16919e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 17019e95205Sopenharmony_ci break; 17119e95205Sopenharmony_ci } 17219e95205Sopenharmony_ci 17319e95205Sopenharmony_ci g_btmCallbackList = ListCreate(BtmFreeCallbacksBlock); 17419e95205Sopenharmony_ci if (g_btmCallbackList == NULL) { 17519e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 17619e95205Sopenharmony_ci break; 17719e95205Sopenharmony_ci } 17819e95205Sopenharmony_ci 17919e95205Sopenharmony_ci g_btmCallbackListLock = MutexCreate(); 18019e95205Sopenharmony_ci if (g_btmCallbackListLock == NULL) { 18119e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 18219e95205Sopenharmony_ci break; 18319e95205Sopenharmony_ci } 18419e95205Sopenharmony_ci 18519e95205Sopenharmony_ci BtmInitFeatures(); 18619e95205Sopenharmony_ci 18719e95205Sopenharmony_ci LOG_DEBUG("ModuleInit start"); 18819e95205Sopenharmony_ci for (int i = 0; i < G_COUNT_OF_ALL_MODULES; i++) { 18919e95205Sopenharmony_ci LOG_DEBUG("ModuleInit: %{public}s", g_allModules[i]); 19019e95205Sopenharmony_ci ModuleInit(g_allModules[i], 0); 19119e95205Sopenharmony_ci } 19219e95205Sopenharmony_ci LOG_DEBUG("ModuleInit end"); 19319e95205Sopenharmony_ci 19419e95205Sopenharmony_ci g_status = STATUS_INITIALIZED; 19519e95205Sopenharmony_ci } while (0); 19619e95205Sopenharmony_ci 19719e95205Sopenharmony_ci LOG_DEBUG("%{public}s end", __FUNCTION__); 19819e95205Sopenharmony_ci 19919e95205Sopenharmony_ci return result; 20019e95205Sopenharmony_ci} 20119e95205Sopenharmony_ci 20219e95205Sopenharmony_ciNO_SANITIZE("cfi") int BTM_Close() 20319e95205Sopenharmony_ci{ 20419e95205Sopenharmony_ci LOG_DEBUG("%{public}s start", __FUNCTION__); 20519e95205Sopenharmony_ci 20619e95205Sopenharmony_ci if (BTM_Disable(LE_CONTROLLER) != BT_SUCCESS) { 20719e95205Sopenharmony_ci LOG_WARN("Disable LE Failed"); 20819e95205Sopenharmony_ci } 20919e95205Sopenharmony_ci if (BTM_Disable(BREDR_CONTROLLER) != BT_SUCCESS) { 21019e95205Sopenharmony_ci LOG_WARN("Disable BREDR Failed"); 21119e95205Sopenharmony_ci } 21219e95205Sopenharmony_ci 21319e95205Sopenharmony_ci g_status = STATUS_NONE; 21419e95205Sopenharmony_ci 21519e95205Sopenharmony_ci LOG_DEBUG("ModuleCleanup start"); 21619e95205Sopenharmony_ci for (int i = G_COUNT_OF_ALL_MODULES - 1; i >= 0; i--) { 21719e95205Sopenharmony_ci LOG_DEBUG("ModuleCleanup: %{public}s", g_allModules[i]); 21819e95205Sopenharmony_ci ModuleCleanup(g_allModules[i]); 21919e95205Sopenharmony_ci } 22019e95205Sopenharmony_ci LOG_DEBUG("ModuleCleanup end"); 22119e95205Sopenharmony_ci 22219e95205Sopenharmony_ci BtmCloseFeatures(); 22319e95205Sopenharmony_ci 22419e95205Sopenharmony_ci if (g_btmCallbackListLock != NULL) { 22519e95205Sopenharmony_ci MutexDelete(g_btmCallbackListLock); 22619e95205Sopenharmony_ci g_btmCallbackListLock = NULL; 22719e95205Sopenharmony_ci } 22819e95205Sopenharmony_ci 22919e95205Sopenharmony_ci if (g_btmCallbackList != NULL) { 23019e95205Sopenharmony_ci ListDelete(g_btmCallbackList); 23119e95205Sopenharmony_ci g_btmCallbackList = NULL; 23219e95205Sopenharmony_ci } 23319e95205Sopenharmony_ci 23419e95205Sopenharmony_ci if (g_modeLock != NULL) { 23519e95205Sopenharmony_ci MutexDelete(g_modeLock); 23619e95205Sopenharmony_ci g_modeLock = NULL; 23719e95205Sopenharmony_ci } 23819e95205Sopenharmony_ci 23919e95205Sopenharmony_ci AlarmModuleCleanup(); 24019e95205Sopenharmony_ci 24119e95205Sopenharmony_ci LOG_DEBUG("%{public}s end", __FUNCTION__); 24219e95205Sopenharmony_ci 24319e95205Sopenharmony_ci return BT_SUCCESS; 24419e95205Sopenharmony_ci} 24519e95205Sopenharmony_ci 24619e95205Sopenharmony_cistatic int BtmEnableBrEdrAndSharedModules() 24719e95205Sopenharmony_ci{ 24819e95205Sopenharmony_ci BtmStartSnoopOutput(); 24919e95205Sopenharmony_ci 25019e95205Sopenharmony_ci int result = HCI_Initialize(); 25119e95205Sopenharmony_ci if (result == BT_SUCCESS) { 25219e95205Sopenharmony_ci HCI_RegisterFailureCallback(&g_hciFailureCallbacks); 25319e95205Sopenharmony_ci 25419e95205Sopenharmony_ci result = BtmInitController(); 25519e95205Sopenharmony_ci if (result == BT_SUCCESS) { 25619e95205Sopenharmony_ci BtmStartAcl(); 25719e95205Sopenharmony_ci BtmStartPm(); 25819e95205Sopenharmony_ci BtmStartSco(); 25919e95205Sopenharmony_ci 26019e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup start"); 26119e95205Sopenharmony_ci for (int i = 0; i < G_COUNTOF_BREDR_AND_SHARED_MODULES; i++) { 26219e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup: %{public}s", g_bredrAndSharedModules[i]); 26319e95205Sopenharmony_ci ModuleStartup(g_bredrAndSharedModules[i]); 26419e95205Sopenharmony_ci } 26519e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup end"); 26619e95205Sopenharmony_ci } 26719e95205Sopenharmony_ci } 26819e95205Sopenharmony_ci 26919e95205Sopenharmony_ci if (result != BT_SUCCESS) { 27019e95205Sopenharmony_ci HCI_Close(); 27119e95205Sopenharmony_ci 27219e95205Sopenharmony_ci BtmStopSnoopOutput(); 27319e95205Sopenharmony_ci } 27419e95205Sopenharmony_ci 27519e95205Sopenharmony_ci return result; 27619e95205Sopenharmony_ci} 27719e95205Sopenharmony_ci 27819e95205Sopenharmony_cistatic int BtmEnableBrEdrModules() 27919e95205Sopenharmony_ci{ 28019e95205Sopenharmony_ci BtmStartPm(); 28119e95205Sopenharmony_ci BtmStartSco(); 28219e95205Sopenharmony_ci 28319e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup start"); 28419e95205Sopenharmony_ci for (int i = 0; i < G_COUNT_OF_BREDR_MODULES; i++) { 28519e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup: %{public}s", g_bredrModules[i]); 28619e95205Sopenharmony_ci ModuleStartup(g_bredrModules[i]); 28719e95205Sopenharmony_ci } 28819e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup end"); 28919e95205Sopenharmony_ci 29019e95205Sopenharmony_ci return BT_SUCCESS; 29119e95205Sopenharmony_ci} 29219e95205Sopenharmony_ci 29319e95205Sopenharmony_cistatic int BtmEnableLeAndSharedModules() 29419e95205Sopenharmony_ci{ 29519e95205Sopenharmony_ci BtmStartSnoopOutput(); 29619e95205Sopenharmony_ci 29719e95205Sopenharmony_ci int result = HCI_Initialize(); 29819e95205Sopenharmony_ci if (result == BT_SUCCESS) { 29919e95205Sopenharmony_ci HCI_RegisterFailureCallback(&g_hciFailureCallbacks); 30019e95205Sopenharmony_ci 30119e95205Sopenharmony_ci result = BtmInitController(); 30219e95205Sopenharmony_ci if (result == BT_SUCCESS) { 30319e95205Sopenharmony_ci BtmStartAcl(); 30419e95205Sopenharmony_ci BtmStartLeSecurity(); 30519e95205Sopenharmony_ci BtmStartWhiteList(); 30619e95205Sopenharmony_ci 30719e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup start"); 30819e95205Sopenharmony_ci for (int i = 0; i < G_COUNT_OF_LE_AND_SHARED_MODULES; i++) { 30919e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup: %{public}s", g_leAndSharedModules[i]); 31019e95205Sopenharmony_ci ModuleStartup(g_leAndSharedModules[i]); 31119e95205Sopenharmony_ci } 31219e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup end"); 31319e95205Sopenharmony_ci } 31419e95205Sopenharmony_ci } 31519e95205Sopenharmony_ci 31619e95205Sopenharmony_ci if (result != BT_SUCCESS) { 31719e95205Sopenharmony_ci HCI_Close(); 31819e95205Sopenharmony_ci 31919e95205Sopenharmony_ci BtmStopSnoopOutput(); 32019e95205Sopenharmony_ci } 32119e95205Sopenharmony_ci 32219e95205Sopenharmony_ci return result; 32319e95205Sopenharmony_ci} 32419e95205Sopenharmony_ci 32519e95205Sopenharmony_cistatic int BtmEnableLeModules() 32619e95205Sopenharmony_ci{ 32719e95205Sopenharmony_ci BtmStartLeSecurity(); 32819e95205Sopenharmony_ci BtmStartWhiteList(); 32919e95205Sopenharmony_ci 33019e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup start"); 33119e95205Sopenharmony_ci for (int i = 0; i < G_COUNT_OF_LE_MODULES; i++) { 33219e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup: %{public}s", g_leModules[i]); 33319e95205Sopenharmony_ci ModuleStartup(g_leModules[i]); 33419e95205Sopenharmony_ci } 33519e95205Sopenharmony_ci LOG_DEBUG("ModuleStartup end"); 33619e95205Sopenharmony_ci 33719e95205Sopenharmony_ci return BT_SUCCESS; 33819e95205Sopenharmony_ci} 33919e95205Sopenharmony_ci 34019e95205Sopenharmony_cistatic void BtmDisableBrEdrAndSharedModules() 34119e95205Sopenharmony_ci{ 34219e95205Sopenharmony_ci BtmCloseAclConnectionByTransport(TRANSPORT_BREDR); 34319e95205Sopenharmony_ci 34419e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown start"); 34519e95205Sopenharmony_ci for (int i = G_COUNTOF_BREDR_AND_SHARED_MODULES - 1; i >= 0; i--) { 34619e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown: %{public}s", g_bredrAndSharedModules[i]); 34719e95205Sopenharmony_ci ModuleShutdown(g_bredrAndSharedModules[i]); 34819e95205Sopenharmony_ci } 34919e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown end"); 35019e95205Sopenharmony_ci 35119e95205Sopenharmony_ci BtmClearInquiryDb(); 35219e95205Sopenharmony_ci BtmStopSco(); 35319e95205Sopenharmony_ci BtmStopPm(); 35419e95205Sopenharmony_ci BtmStopAcl(); 35519e95205Sopenharmony_ci BtmCloseController(); 35619e95205Sopenharmony_ci 35719e95205Sopenharmony_ci HCI_DeregisterFailureCallback(&g_hciFailureCallbacks); 35819e95205Sopenharmony_ci HCI_Close(); 35919e95205Sopenharmony_ci 36019e95205Sopenharmony_ci BtmStopSnoopOutput(); 36119e95205Sopenharmony_ci} 36219e95205Sopenharmony_ci 36319e95205Sopenharmony_cistatic void BtmDisableBrEdrModules() 36419e95205Sopenharmony_ci{ 36519e95205Sopenharmony_ci BtmCloseAclConnectionByTransport(TRANSPORT_BREDR); 36619e95205Sopenharmony_ci 36719e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown start"); 36819e95205Sopenharmony_ci for (int i = G_COUNT_OF_BREDR_MODULES - 1; i >= 0; i--) { 36919e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown: %{public}s", g_bredrModules[i]); 37019e95205Sopenharmony_ci ModuleShutdown(g_bredrModules[i]); 37119e95205Sopenharmony_ci } 37219e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown end"); 37319e95205Sopenharmony_ci 37419e95205Sopenharmony_ci BtmClearInquiryDb(); 37519e95205Sopenharmony_ci BtmStopSco(); 37619e95205Sopenharmony_ci BtmStopPm(); 37719e95205Sopenharmony_ci} 37819e95205Sopenharmony_ci 37919e95205Sopenharmony_cistatic void BtmDisableLeAndSharedModules() 38019e95205Sopenharmony_ci{ 38119e95205Sopenharmony_ci BtmCloseAclConnectionByTransport(TRANSPORT_LE); 38219e95205Sopenharmony_ci 38319e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown start"); 38419e95205Sopenharmony_ci for (int i = G_COUNT_OF_LE_AND_SHARED_MODULES - 1; i >= 0; i--) { 38519e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown: %{public}s", g_leAndSharedModules[i]); 38619e95205Sopenharmony_ci ModuleShutdown(g_leAndSharedModules[i]); 38719e95205Sopenharmony_ci } 38819e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown end"); 38919e95205Sopenharmony_ci 39019e95205Sopenharmony_ci BtmStopWhiteList(); 39119e95205Sopenharmony_ci BtmStopLeSecurity(); 39219e95205Sopenharmony_ci BtmStopAcl(); 39319e95205Sopenharmony_ci BtmCloseController(); 39419e95205Sopenharmony_ci 39519e95205Sopenharmony_ci HCI_DeregisterFailureCallback(&g_hciFailureCallbacks); 39619e95205Sopenharmony_ci HCI_Close(); 39719e95205Sopenharmony_ci 39819e95205Sopenharmony_ci BtmStopSnoopOutput(); 39919e95205Sopenharmony_ci} 40019e95205Sopenharmony_ci 40119e95205Sopenharmony_cistatic void BtmDisableLeModules() 40219e95205Sopenharmony_ci{ 40319e95205Sopenharmony_ci BtmCloseAclConnectionByTransport(TRANSPORT_LE); 40419e95205Sopenharmony_ci 40519e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown start"); 40619e95205Sopenharmony_ci for (int i = G_COUNT_OF_LE_MODULES - 1; i >= 0; i--) { 40719e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown: %{public}s", g_leModules[i]); 40819e95205Sopenharmony_ci ModuleShutdown(g_leModules[i]); 40919e95205Sopenharmony_ci } 41019e95205Sopenharmony_ci LOG_DEBUG("ModuleShutdown end"); 41119e95205Sopenharmony_ci 41219e95205Sopenharmony_ci BtmStopWhiteList(); 41319e95205Sopenharmony_ci BtmStopLeSecurity(); 41419e95205Sopenharmony_ci} 41519e95205Sopenharmony_ci 41619e95205Sopenharmony_ciint BTM_Enable(int controller) 41719e95205Sopenharmony_ci{ 41819e95205Sopenharmony_ci LOG_DEBUG("%{public}s start", __FUNCTION__); 41919e95205Sopenharmony_ci 42019e95205Sopenharmony_ci if (controller != BREDR_CONTROLLER && controller != LE_CONTROLLER) { 42119e95205Sopenharmony_ci return BT_BAD_PARAM; 42219e95205Sopenharmony_ci } 42319e95205Sopenharmony_ci 42419e95205Sopenharmony_ci if (!IS_INITIALIZED()) { 42519e95205Sopenharmony_ci return BT_BAD_STATUS; 42619e95205Sopenharmony_ci } 42719e95205Sopenharmony_ci 42819e95205Sopenharmony_ci int result = BT_SUCCESS; 42919e95205Sopenharmony_ci 43019e95205Sopenharmony_ci MutexLock(g_modeLock); 43119e95205Sopenharmony_ci 43219e95205Sopenharmony_ci if (controller == BREDR_CONTROLLER) { 43319e95205Sopenharmony_ci if (g_currentMode == MODE_NONE) { 43419e95205Sopenharmony_ci result = BtmEnableBrEdrAndSharedModules(); 43519e95205Sopenharmony_ci } else if (g_currentMode == MODE_LE) { 43619e95205Sopenharmony_ci result = BtmEnableBrEdrModules(); 43719e95205Sopenharmony_ci } 43819e95205Sopenharmony_ci 43919e95205Sopenharmony_ci if (result == BT_SUCCESS) { 44019e95205Sopenharmony_ci g_currentMode |= MODE_BREDR; 44119e95205Sopenharmony_ci } 44219e95205Sopenharmony_ci } else if (controller == LE_CONTROLLER) { 44319e95205Sopenharmony_ci if (g_currentMode == MODE_NONE) { 44419e95205Sopenharmony_ci result = BtmEnableLeAndSharedModules(); 44519e95205Sopenharmony_ci } else if (g_currentMode == MODE_BREDR) { 44619e95205Sopenharmony_ci result = BtmEnableLeModules(); 44719e95205Sopenharmony_ci } 44819e95205Sopenharmony_ci 44919e95205Sopenharmony_ci if (result == BT_SUCCESS) { 45019e95205Sopenharmony_ci g_currentMode |= MODE_LE; 45119e95205Sopenharmony_ci } 45219e95205Sopenharmony_ci } 45319e95205Sopenharmony_ci 45419e95205Sopenharmony_ci#ifdef DEBUG 45519e95205Sopenharmony_ci BtmOutputCurrentStatus(); 45619e95205Sopenharmony_ci#endif 45719e95205Sopenharmony_ci 45819e95205Sopenharmony_ci MutexUnlock(g_modeLock); 45919e95205Sopenharmony_ci LOG_DEBUG("%{public}s end", __FUNCTION__); 46019e95205Sopenharmony_ci return result; 46119e95205Sopenharmony_ci} 46219e95205Sopenharmony_ci 46319e95205Sopenharmony_ciint BTM_Disable(int controller) 46419e95205Sopenharmony_ci{ 46519e95205Sopenharmony_ci LOG_DEBUG("%{public}s start", __FUNCTION__); 46619e95205Sopenharmony_ci if (controller != BREDR_CONTROLLER && controller != LE_CONTROLLER) { 46719e95205Sopenharmony_ci return BT_BAD_PARAM; 46819e95205Sopenharmony_ci } 46919e95205Sopenharmony_ci 47019e95205Sopenharmony_ci if (!IS_INITIALIZED()) { 47119e95205Sopenharmony_ci return BT_BAD_STATUS; 47219e95205Sopenharmony_ci } 47319e95205Sopenharmony_ci 47419e95205Sopenharmony_ci MutexLock(g_modeLock); 47519e95205Sopenharmony_ci 47619e95205Sopenharmony_ci if (controller == BREDR_CONTROLLER) { 47719e95205Sopenharmony_ci if (g_currentMode == MODE_DUAL) { 47819e95205Sopenharmony_ci BtmDisableBrEdrModules(); 47919e95205Sopenharmony_ci } else if (g_currentMode == MODE_BREDR) { 48019e95205Sopenharmony_ci BtmDisableBrEdrAndSharedModules(); 48119e95205Sopenharmony_ci } 48219e95205Sopenharmony_ci 48319e95205Sopenharmony_ci g_currentMode &= (~MODE_BREDR); 48419e95205Sopenharmony_ci } else if (controller == LE_CONTROLLER) { 48519e95205Sopenharmony_ci if (g_currentMode == MODE_DUAL) { 48619e95205Sopenharmony_ci BtmDisableLeModules(); 48719e95205Sopenharmony_ci } else if (g_currentMode == MODE_LE) { 48819e95205Sopenharmony_ci BtmDisableLeAndSharedModules(); 48919e95205Sopenharmony_ci } 49019e95205Sopenharmony_ci 49119e95205Sopenharmony_ci g_currentMode &= (~MODE_LE); 49219e95205Sopenharmony_ci } 49319e95205Sopenharmony_ci 49419e95205Sopenharmony_ci#ifdef DEBUG 49519e95205Sopenharmony_ci BtmOutputCurrentStatus(); 49619e95205Sopenharmony_ci#endif 49719e95205Sopenharmony_ci 49819e95205Sopenharmony_ci MutexUnlock(g_modeLock); 49919e95205Sopenharmony_ci LOG_DEBUG("%{public}s end", __FUNCTION__); 50019e95205Sopenharmony_ci return BT_SUCCESS; 50119e95205Sopenharmony_ci} 50219e95205Sopenharmony_ci 50319e95205Sopenharmony_cibool BTM_IsEnabled(int controller) 50419e95205Sopenharmony_ci{ 50519e95205Sopenharmony_ci if (!IS_INITIALIZED()) { 50619e95205Sopenharmony_ci return false; 50719e95205Sopenharmony_ci } 50819e95205Sopenharmony_ci 50919e95205Sopenharmony_ci bool isEnabled = false; 51019e95205Sopenharmony_ci 51119e95205Sopenharmony_ci if (controller == BREDR_CONTROLLER) { 51219e95205Sopenharmony_ci MutexLock(g_modeLock); 51319e95205Sopenharmony_ci isEnabled = !!(g_currentMode & MODE_BREDR); 51419e95205Sopenharmony_ci MutexUnlock(g_modeLock); 51519e95205Sopenharmony_ci } else if (controller == LE_CONTROLLER) { 51619e95205Sopenharmony_ci MutexLock(g_modeLock); 51719e95205Sopenharmony_ci isEnabled = !!(g_currentMode & MODE_LE); 51819e95205Sopenharmony_ci MutexUnlock(g_modeLock); 51919e95205Sopenharmony_ci } 52019e95205Sopenharmony_ci 52119e95205Sopenharmony_ci return isEnabled; 52219e95205Sopenharmony_ci} 52319e95205Sopenharmony_ci 52419e95205Sopenharmony_ciint BTM_RegisterCallbacks(const BtmCallbacks *callbacks, void *context) 52519e95205Sopenharmony_ci{ 52619e95205Sopenharmony_ci if (callbacks == NULL) { 52719e95205Sopenharmony_ci return BT_BAD_PARAM; 52819e95205Sopenharmony_ci } 52919e95205Sopenharmony_ci 53019e95205Sopenharmony_ci if (!IS_INITIALIZED()) { 53119e95205Sopenharmony_ci return BT_BAD_STATUS; 53219e95205Sopenharmony_ci } 53319e95205Sopenharmony_ci 53419e95205Sopenharmony_ci BtmCallbacksBlock *block = BtmAllocCallbacksBlock(callbacks, context); 53519e95205Sopenharmony_ci if (block == NULL) { 53619e95205Sopenharmony_ci return BT_NO_MEMORY; 53719e95205Sopenharmony_ci } 53819e95205Sopenharmony_ci 53919e95205Sopenharmony_ci MutexLock(g_btmCallbackListLock); 54019e95205Sopenharmony_ci ListAddLast(g_btmCallbackList, block); 54119e95205Sopenharmony_ci MutexUnlock(g_btmCallbackListLock); 54219e95205Sopenharmony_ci 54319e95205Sopenharmony_ci return BT_SUCCESS; 54419e95205Sopenharmony_ci} 54519e95205Sopenharmony_ci 54619e95205Sopenharmony_ciint BTM_DeregisterCallbacks(const BtmCallbacks *callbacks) 54719e95205Sopenharmony_ci{ 54819e95205Sopenharmony_ci if (callbacks == NULL) { 54919e95205Sopenharmony_ci return BT_BAD_PARAM; 55019e95205Sopenharmony_ci } 55119e95205Sopenharmony_ci 55219e95205Sopenharmony_ci if (!IS_INITIALIZED()) { 55319e95205Sopenharmony_ci return BT_BAD_STATUS; 55419e95205Sopenharmony_ci } 55519e95205Sopenharmony_ci 55619e95205Sopenharmony_ci MutexLock(g_btmCallbackListLock); 55719e95205Sopenharmony_ci 55819e95205Sopenharmony_ci BtmCallbacksBlock *block = NULL; 55919e95205Sopenharmony_ci ListNode *node = ListGetFirstNode(g_btmCallbackList); 56019e95205Sopenharmony_ci while (node != NULL) { 56119e95205Sopenharmony_ci block = ListGetNodeData(node); 56219e95205Sopenharmony_ci if (block != NULL) { 56319e95205Sopenharmony_ci if (block->callbacks == callbacks) { 56419e95205Sopenharmony_ci ListRemoveNode(g_btmCallbackList, block); 56519e95205Sopenharmony_ci break; 56619e95205Sopenharmony_ci } 56719e95205Sopenharmony_ci } 56819e95205Sopenharmony_ci node = ListGetNextNode(node); 56919e95205Sopenharmony_ci } 57019e95205Sopenharmony_ci 57119e95205Sopenharmony_ci MutexUnlock(g_btmCallbackListLock); 57219e95205Sopenharmony_ci 57319e95205Sopenharmony_ci return BT_SUCCESS; 57419e95205Sopenharmony_ci} 57519e95205Sopenharmony_ci 57619e95205Sopenharmony_cistatic void BtmOnHCIFailure() 57719e95205Sopenharmony_ci{ 57819e95205Sopenharmony_ci BtmCallbacksBlock *block = NULL; 57919e95205Sopenharmony_ci MutexLock(g_btmCallbackListLock); 58019e95205Sopenharmony_ci ListNode *node = ListGetFirstNode(g_btmCallbackList); 58119e95205Sopenharmony_ci while (node != NULL) { 58219e95205Sopenharmony_ci block = ListGetNodeData(node); 58319e95205Sopenharmony_ci if (block->callbacks != NULL && block->callbacks->hciFailure != NULL) { 58419e95205Sopenharmony_ci block->callbacks->hciFailure(block->context); 58519e95205Sopenharmony_ci } 58619e95205Sopenharmony_ci node = ListGetNextNode(node); 58719e95205Sopenharmony_ci } 58819e95205Sopenharmony_ci MutexUnlock(g_btmCallbackListLock); 58919e95205Sopenharmony_ci} 59019e95205Sopenharmony_ci 59119e95205Sopenharmony_cistatic HciFailureCallbacks g_hciFailureCallbacks = { 59219e95205Sopenharmony_ci .onCmdTimeout = BtmOnHCIFailure, 59319e95205Sopenharmony_ci}; 594