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