Bluetooth initialization - enable in Bluetooth process - Native(Cpp)

1. Overview

Bluetooth Enable Flow Arch
bte_main_enable Flow

2.

packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

public class AdapterService extends Service {

    class AdapterServiceHandler extends Handler {
        ......
        private void processProfileServiceStateChanged(ProfileService profile, int state) {
            switch (state) {
                case BluetoothAdapter.STATE_ON:
                    ......
                    if (GattService.class.getSimpleName().equals(profile.getName())) {
                        enableNative();   //  GattService 启动后,执行 enable native
                    } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                            && mRegisteredProfiles.size() == mRunningProfiles.size()) {
                        ......
                    }
                    break;
                    ......
            }
        }
    }



    native boolean enableNative();
}

packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

static jboolean enableNative(JNIEnv* env, jobject obj) {
......
  int ret = sBluetoothInterface->enable();
  return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;
}

system/bt/btif/src/bluetooth.cc

static int enable() {
......
  stack_manager_get_interface()->start_up_stack_async();
  return BT_STATUS_SUCCESS;
}

system/bt/btif/src/stack_manager.cc

static void start_up_stack_async() {
  management_thread.DoInThread(FROM_HERE,
                               base::Bind(event_start_up_stack, nullptr));
}



static void event_start_up_stack(UNUSED_ATTR void* context) {
......

  ensure_stack_is_initialized();

  future_t* local_hack_future = future_new();
  hack_future = local_hack_future;

  module_start_up(get_module(BTIF_CONFIG_MODULE));
  bte_main_enable();

  if (future_await(local_hack_future) != FUTURE_SUCCESS) {
......
    return;
  }

  stack_is_running = true;
  do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_up, nullptr));
}

system/bt/main/bte_main.cc

void bte_main_enable() {
  if (bluetooth::shim::is_gd_shim_enabled()) {
    module_start_up(get_module(GD_SHIM_MODULE));
    module_start_up(get_module(GD_HCI_MODULE));
  } else {
    module_start_up(get_module(BTSNOOP_MODULE));
    module_start_up(get_module(HCI_MODULE));
  }

  BTU_StartUp();
}

system/bt/stack/btu/btu_init.cc

void BTU_StartUp() {
......
  bt_startup_thread.StartUp();
  if (!bt_startup_thread.EnableRealTimeScheduling()) {
......
    return;
  }

  if (!bt_startup_thread.DoInThread(FROM_HERE,
                                    base::Bind(btu_task_start_up, nullptr))) {
......
    return;
  }
}

system/bt/stack/btu/btu_task.cc

void btu_task_start_up(UNUSED_ATTR void* context) {
  LOG(INFO) << "Bluetooth chip preload is complete";

  /* Initialize the mandatory core stack control blocks (BTU, BTM, L2CAP, and SDP) */
  btu_init_core();

  /* Initialize any optional stack components */
  BTE_InitStack();

  bta_sys_init();

  module_init(get_module(BTE_LOGMSG_MODULE));

  main_thread.StartUp();
  if (!main_thread.EnableRealTimeScheduling()) {
......
  }

  if (do_in_jni_thread(FROM_HERE, base::Bind(btif_init_ok, 0, nullptr)) !=
      BT_STATUS_SUCCESS) {
......
  }
}

2.1 Init Stack

初始化 Stack,包括核心组件和可选组件
主要是以下两个函数:
btu_init_core();
BTE_InitStack();

2.2 bta_sys_init

system/bt/bta/sys/bta_sys_main.cc

void bta_sys_init(void) {
......

  /* register BTA SYS message handler */
  bta_sys_register(BTA_ID_SYS, &bta_sys_hw_reg);

  /* register for BTM notifications */
  BTM_RegisterForDeviceStatusNotif(&bta_sys_hw_btm_cback);

#if (defined BTA_AR_INCLUDED) && (BTA_AR_INCLUDED == TRUE)
  bta_ar_init();
#endif
}

bta_sys_register的详情,请参考Stack Function - bta_sys_sendmsg()

system/bt/stack/btm/btm_devctl.cc

tBTM_DEV_STATUS_CB* BTM_RegisterForDeviceStatusNotif(tBTM_DEV_STATUS_CB* p_cb) {
  tBTM_DEV_STATUS_CB* p_prev = btm_cb.devcb.p_dev_status_cb;

  btm_cb.devcb.p_dev_status_cb = p_cb;
  return (p_prev);
}



void btm_report_device_status(tBTM_DEV_STATUS status) {
  tBTM_DEV_STATUS_CB* p_cb = btm_cb.devcb.p_dev_status_cb;

  /* Call the call back to pass the device status to application */
  if (p_cb) (*p_cb)(status);
}

注册回调函数和使用该回调函数的函数。

2.3 btif_init_ok

system/bt/btif/src/btif_core.cc

void btif_init_ok(UNUSED_ATTR uint16_t event, UNUSED_ATTR char* p_param) {
  btif_dm_load_ble_local_keys();
  BTA_EnableBluetooth(bte_dm_evt);
}

2.3.1 btif_dm_load_ble_local_keys

system/bt/btif/src/btif_dm.cc

void btif_dm_load_ble_local_keys(void) {
  memset(&ble_local_key_cb, 0, sizeof(btif_dm_local_key_cb_t));

  if (btif_storage_get_ble_local_key(
          BTIF_DM_LE_LOCAL_KEY_ER, &ble_local_key_cb.er) == BT_STATUS_SUCCESS) {
    ble_local_key_cb.is_er_rcvd = true;
    BTIF_TRACE_DEBUG("%s BLE ER key loaded", __func__);
  }

  if ((btif_storage_get_ble_local_key(BTIF_DM_LE_LOCAL_KEY_IR,
                                      &ble_local_key_cb.id_keys.ir) ==
       BT_STATUS_SUCCESS) &&
      (btif_storage_get_ble_local_key(BTIF_DM_LE_LOCAL_KEY_IRK,
                                      &ble_local_key_cb.id_keys.irk) ==
       BT_STATUS_SUCCESS) &&
      (btif_storage_get_ble_local_key(BTIF_DM_LE_LOCAL_KEY_DHK,
                                      &ble_local_key_cb.id_keys.dhk) ==
       BT_STATUS_SUCCESS)) {
    ble_local_key_cb.is_id_keys_rcvd = true;
    BTIF_TRACE_DEBUG("%s BLE ID keys loaded", __func__);
  }
}

2.3.2 BTA_EnableBluetooth

system/bt/bta/dm/bta_dm_api.cc

tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK* p_cback) {
......

  bta_sys_register(BTA_ID_DM_SEARCH, &bta_dm_search_reg);

  bta_sys_eir_register(bta_dm_eir_update_uuid);

  do_in_main_thread(FROM_HERE, base::Bind(bta_dm_enable, p_cback));
  return BTA_SUCCESS;
}

system/bt/bta/dm/bta_dm_act.cc

void bta_dm_enable(tBTA_DM_SEC_CBACK* p_sec_cback) {
......

  /* first, register our callback to SYS HW manager */
  bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback);

  /* make sure security callback is saved - if no callback, do not erase the
  previous one,
  it could be an error recovery mechanism */
  if (p_sec_cback != NULL) bta_dm_cb.p_sec_cback = p_sec_cback;
  /* notify BTA DM is now active */
  bta_dm_cb.is_bta_dm_active = true;

  /* send a message to BTA SYS */
  tBTA_SYS_HW_MSG* sys_enable_event =
      (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
  sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;
  sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;

  bta_sys_sendmsg(sys_enable_event);

  btm_local_io_caps = btif_storage_get_local_io_caps();
}

system/bt/bta/sys/bta_sys_main.cc

void bta_sys_hw_register(tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK* cback) {
  bta_sys_cb.sys_hw_cback[module] = cback;
}
bool bta_sys_sm_execute(BT_HDR* p_msg) {
  bool freebuf = true;
  tBTA_SYS_ST_TBL state_table;
  uint8_t action;
  int i;

  /* look up the state table for the current state */
  state_table = bta_sys_st_tbl[bta_sys_cb.state];
  /* update state */
  bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];

  /* execute action functions */
  for (i = 0; i < BTA_SYS_ACTIONS; i++) {
    action = state_table[p_msg->event & 0x00ff][i];
    if (action != BTA_SYS_IGNORE) {
      (*bta_sys_action[action])((tBTA_SYS_HW_MSG*)p_msg);
    } else {
      break;
    }
  }
  return freebuf;
}



const tBTA_SYS_ACTION bta_sys_action[] = {
    /* device manager local device API events - cf bta_sys.h for events */
    bta_sys_hw_api_enable,        /* 0  BTA_SYS_HW_API_ENABLE_EVT    */
    bta_sys_hw_evt_enabled,       /* 1  BTA_SYS_HW_EVT_ENABLED_EVT */
    bta_sys_hw_evt_stack_enabled, /* 2  BTA_SYS_HW_EVT_STACK_ENABLED_EVT */
......
};
void bta_sys_hw_api_enable(tBTA_SYS_HW_MSG* p_sys_hw_msg) {
  if ((!bta_sys_cb.sys_hw_module_active) &&
      (bta_sys_cb.state != BTA_SYS_HW_ON)) {
    /* register which HW module was turned on */
    bta_sys_cb.sys_hw_module_active |= ((uint32_t)1 << p_sys_hw_msg->hw_module);

    tBTA_SYS_HW_MSG* p_msg =
        (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
    p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;
    p_msg->hw_module = p_sys_hw_msg->hw_module;

    bta_sys_sendmsg(p_msg);
  } else {
    ......
  }
}
void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG* p_sys_hw_msg) {
  BTM_DeviceReset(NULL);
}

system/bt/stack/btm/btm_devctl.cc

void BTM_DeviceReset(UNUSED_ATTR tBTM_CMPL_CB* p_cb) {
  /* Flush all ACL connections */
  btm_acl_device_down();

  /* Clear the callback, so application would not hang on reset */
  btm_db_reset();

  if (bluetooth::shim::is_gd_shim_enabled()) {
    ......
  } else {
    module_start_up_callbacked_wrapper(get_module(CONTROLLER_MODULE),
                                       &bt_startup_thread, reset_complete);
  }
}

Controller 启动

system/bt/btcore/src/module.cc

void module_start_up_callbacked_wrapper(const module_t* module,
                                        MessageLoopThread* callback_thread,
                                        thread_fn callback) {
  std::shared_ptr<CallbackWrapper> wrapper =
      std::make_shared<CallbackWrapper>(module, callback_thread, callback);
  wrapper->lifecycle_thread.StartUp();
  // Run the actual module start up
  wrapper->lifecycle_thread.DoInThread(
      FROM_HERE, base::BindOnce(run_wrapped_start_up, wrapper));
}



static void run_wrapped_start_up(std::shared_ptr<CallbackWrapper> wrapper) {
  CHECK(wrapper);
  wrapper->success = module_start_up(wrapper->module);
  // Post the result back to the callback
  wrapper->callback_thread->DoInThread(
      FROM_HERE, base::BindOnce(post_result_to_callback, wrapper));
}



bool module_start_up(const module_t* module) {
  ......
  if (!call_lifecycle_function(module->start_up)) {
    return false;
  }

  set_module_state(module, MODULE_STATE_STARTED);
  return true;
}



static void post_result_to_callback(std::shared_ptr<CallbackWrapper> wrapper) {
  CHECK(wrapper);
  wrapper->lifecycle_thread.ShutDown();
  wrapper->callback(wrapper->success ? FUTURE_SUCCESS : FUTURE_FAIL);
}

system/bt/device/include/controller.h

static const char CONTROLLER_MODULE[] = "controller_module";

system/bt/device/src/controller.cc

EXPORT_SYMBOL extern const module_t controller_module = {
    .name = CONTROLLER_MODULE,
    .init = NULL,
    .start_up = start_up,
    .shut_down = shut_down,
    .clean_up = NULL,
    .dependencies = {HCI_MODULE, NULL}};


static future_t* start_up(void) {
  BT_HDR* response;

  // Send the initial reset command
  response = AWAIT_COMMAND(packet_factory->make_reset());
  packet_parser->parse_generic_command_complete(response);

  // Request the classic buffer size next
  response = AWAIT_COMMAND(packet_factory->make_read_buffer_size());
  packet_parser->parse_read_buffer_size_response(
      response, &acl_data_size_classic, &acl_buffer_count_classic);

  ......

  readable = true;
  return future_new_immediate(FUTURE_SUCCESS);
}
static void reset_complete(void* result) {
  CHECK(result == FUTURE_SUCCESS);
  const controller_t* controller = controller_get_interface();

  /* Tell L2CAP that all connections are gone */
  l2cu_device_reset();

  /* Clear current security state */
  list_foreach(btm_cb.sec_dev_rec, set_sec_state_idle, NULL);

  /* After the reset controller should restore all parameters to defaults. */
  btm_cb.btm_inq_vars.inq_counter = 1;
  btm_cb.btm_inq_vars.inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW;
  btm_cb.btm_inq_vars.inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL;
  btm_cb.btm_inq_vars.inq_scan_type = HCI_DEF_SCAN_TYPE;

  btm_cb.btm_inq_vars.page_scan_window = HCI_DEF_PAGESCAN_WINDOW;
  btm_cb.btm_inq_vars.page_scan_period = HCI_DEF_PAGESCAN_INTERVAL;
  btm_cb.btm_inq_vars.page_scan_type = HCI_DEF_SCAN_TYPE;

  btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE;
  connection_manager::reset(true);

  btm_pm_reset();

  l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic());

  // setup the random number generator
  std::srand(std::time(nullptr));

#if (BLE_PRIVACY_SPT == TRUE)
  /* Set up the BLE privacy settings */
  if (controller->supports_ble() && controller->supports_ble_privacy() &&
      controller->get_ble_resolving_list_max_size() > 0) {
    btm_ble_resolving_list_init(controller->get_ble_resolving_list_max_size());
    /* set the default random private address timeout */
    btsnd_hcic_ble_set_rand_priv_addr_timeout(
        btm_get_next_private_addrress_interval_ms() / 1000);
  }
#endif

  if (controller->supports_ble()) {
    btm_ble_white_list_init(controller->get_ble_white_list_size());
    l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble());
  }

  BTM_SetPinType(btm_cb.cfg.pin_type, btm_cb.cfg.pin_code,
                 btm_cb.cfg.pin_code_len);

  for (int i = 0; i <= controller->get_last_features_classic_index(); i++) {
    btm_decode_ext_features_page(i,
                                 controller->get_features_classic(i)->as_array);
  }

  btm_report_device_status(BTM_DEV_STATUS_UP);
}

system/bt/bta/sys/bta_sys_main.cc

void bta_sys_hw_btm_cback(tBTM_DEV_STATUS status) {
  ......

  /* send a message to BTA SYS */
  if (status == BTM_DEV_STATUS_UP) {
    sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT;
  } else if (status == BTM_DEV_STATUS_DOWN) {
    ......
  }

  if (sys_event) bta_sys_sendmsg(sys_event);
}
void bta_sys_hw_evt_stack_enabled(UNUSED_ATTR tBTA_SYS_HW_MSG* p_sys_hw_msg) {
  uint8_t hw_module_index;

  for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES;
       hw_module_index++) {
    if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL)
      bta_sys_cb.sys_hw_cback[hw_module_index](BTA_SYS_HW_ON_EVT);
  }
}

system/bt/bta/dm/bta_dm_act.cc

static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status) {
  DEV_CLASS dev_class;
  tBTA_DM_SEC_CBACK* temp_cback;
  uint8_t key_mask = 0;
  tBTA_BLE_LOCAL_ID_KEYS id_key;

  ......

  if (status == BTA_SYS_HW_OFF_EVT) {
    ......
  } else if (status == BTA_SYS_HW_ON_EVT) {
    /* save security callback */
    temp_cback = bta_dm_cb.p_sec_cback;
    /* make sure the control block is properly initialized */
    bta_dm_init_cb();
    /* and retrieve the callback */
    bta_dm_cb.p_sec_cback = temp_cback;
    bta_dm_cb.is_bta_dm_active = true;

    /* hw is ready, go on with BTA DM initialization */
    alarm_free(bta_dm_search_cb.search_timer);
    alarm_free(bta_dm_search_cb.gatt_close_timer);
    memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));

    bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer");
    bta_dm_search_cb.gatt_close_timer =
        alarm_new("bta_dm_search.gatt_close_timer");

    memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs));
    memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));

    memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
    BTM_SetDeviceClass(dev_class);

    /* load BLE local information: ID keys, ER if available */
    Octet16 er;
    bta_dm_co_ble_load_local_keys(&key_mask, &er, &id_key);

    if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) {
      BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER,
                           (tBTM_BLE_LOCAL_KEYS*)&er);
    }
    if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) {
      BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID,
                           (tBTM_BLE_LOCAL_KEYS*)&id_key);
    }
    bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;

    BTM_SecRegister(&bta_security);
    BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout);
    BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
    bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings;
    BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
    BTM_RegBusyLevelNotif(bta_dm_bl_change_cback, NULL,
                          BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK);

#if (BLE_VND_INCLUDED == TRUE)
    BTM_BleReadControllerFeatures(bta_dm_ctrl_features_rd_cmpl_cback);
#else
    /* If VSC multi adv commands are available, advertising will be initialized
     * when capabilities are read. If they are not avaliable, initialize
     * advertising here */
    btm_ble_adv_init();
#endif

    BTM_ReadLocalDeviceNameFromController(bta_dm_local_name_cback);

    bta_sys_rm_register(bta_dm_rm_cback);

    /* initialize bluetooth low power manager */
    bta_dm_init_pm();

    bta_sys_policy_register(bta_dm_policy_cback);

    bta_dm_gattc_register();
  }
}

BTM_BleReadControllerFeatures 执行,对端回复后的回调

system/bt/stack/btm/btm_ble_gap.cc

static void btm_ble_vendor_capability_vsc_cmpl_cback(
    tBTM_VSC_CMPL* p_vcs_cplt_params) {
  uint8_t status = 0xFF;
  uint8_t* p;

  p = p_vcs_cplt_params->p_param_buf;
  STREAM_TO_UINT8(status, p);
  ......
  STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.adv_inst_max, p);
  STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.rpa_offloading, p);
  STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg, p);
  STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, p);
  STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.filter_support, p);
  STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.max_filter, p);
  STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.energy_support, p);

  if (p_vcs_cplt_params->param_len >
      BTM_VSC_CHIP_CAPABILITY_RSP_LEN_L_RELEASE) {
    STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.version_supported, p);
  } else {
    btm_cb.cmn_ble_vsc_cb.version_supported = BTM_VSC_CHIP_CAPABILITY_L_VERSION;
  }

  if (btm_cb.cmn_ble_vsc_cb.version_supported >=
      BTM_VSC_CHIP_CAPABILITY_M_VERSION) {
    CHECK(p_vcs_cplt_params->param_len >= BTM_VSC_CHIP_CAPABILITY_RSP_LEN_M_RELEASE);
    STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.total_trackable_advertisers, p);
    STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.extended_scan_support, p);
    STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.debug_logging_supported, p);
  }
  btm_cb.cmn_ble_vsc_cb.values_read = true;

  btm_ble_adv_init();

  if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) btm_ble_adv_filter_init();

#if (BLE_PRIVACY_SPT == TRUE)
  /* VS capability included and non-4.2 device */
  if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz > 0 &&
      controller_get_interface()->get_ble_resolving_list_max_size() == 0)
    btm_ble_resolving_list_init(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz);
#endif /* (BLE_PRIVACY_SPT == TRUE) */

  if (btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg > 0) btm_ble_batchscan_init();

  if (p_ctrl_le_feature_rd_cmpl_cback != NULL)
    p_ctrl_le_feature_rd_cmpl_cback(status);
}

system/bt/stack/btm/btm_ble_multi_adv.cc

void btm_ble_adv_init() {
  BleAdvertiserHciInterface::Initialize();
  BleAdvertisingManager::Initialize(BleAdvertiserHciInterface::Get());
  BleAdvertiserHciInterface::Get()->SetAdvertisingEventObserver(
      (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get().get());

  if (BleAdvertiserHciInterface::Get()->QuirkAdvertiserZeroHandle()) {
    // If handle 0 can't be used, register advertiser for it, but never use it.
    BleAdvertisingManager::Get().get()->RegisterAdvertiser(base::DoNothing());
  }
}

BTM_BleReadControllerFeatures 注册的回调(执行完成后回调)

system/bt/bta/dm/bta_dm_act.cc

static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result) {
......
    if (bta_dm_cb.p_sec_cback)
      bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
......
}

BTM_ReadLocalDeviceNameFromController 注册的回调

system/bt/bta/dm/bta_dm_act.cc

static void bta_dm_local_name_cback(UNUSED_ATTR void* p_name) {
  tBTA_DM_SEC sec_event;

  sec_event.enable.status = BTA_SUCCESS;

  if (bta_dm_cb.p_sec_cback)
    bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
}

以上二者的真实回调

system/bt/btif/src/btif_dm.cc

void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
  bt_status_t status = btif_transfer_context(
      btif_dm_upstreams_evt, (uint16_t)event, (char*)p_data,
      sizeof(tBTA_DM_SEC), btif_dm_data_copy);
}

根据 Stack Function - btif_transfer_context() 可知:相当于在 jni_thread 线程中执行btif_dm_upstreams_evt (event, p_data)

BTM_BleReadControllerFeatures 回调流程继续到 JNI、Framework

system/bt/btif/src/btif_dm.cc

static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
  tBTA_DM_SEC* p_data = (tBTA_DM_SEC*)p_param;
  tBTA_SERVICE_MASK service_mask;
  uint32_t i;
  RawAddress bd_addr;

  switch (event) {
    ......
    case BTA_DM_LE_FEATURES_READ: {
      tBTM_BLE_VSC_CB cmn_vsc_cb;
      bt_local_le_features_t local_le_features;
      char buf[512];
      bt_property_t prop;
      prop.type = BT_PROPERTY_LOCAL_LE_FEATURES;
      prop.val = (void*)buf;
      prop.len = sizeof(buf);

      /* LE features are not stored in storage. Should be retrived from stack */
      BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
      local_le_features.local_privacy_enabled = BTM_BleLocalPrivacyEnabled();

      prop.len = sizeof(bt_local_le_features_t);
      if (cmn_vsc_cb.filter_support == 1)
        local_le_features.max_adv_filter_supported = cmn_vsc_cb.max_filter;
      else
        local_le_features.max_adv_filter_supported = 0;

      ...... // 存储从Controller 获取的 BLE Controller Features  的各个字段

      memcpy(prop.val, &local_le_features, prop.len);
      HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop);
      break;
    }
    ......
}

HAL_CBACK 回调到 JNI,之后回调到 AdapterProperties ,更新 BLE Controller Features 的各个字段。

BTM_ReadLocalDeviceNameFromController 回调流程继续执行

system/bt/btif/src/btif_dm.cc

static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
  tBTA_DM_SEC* p_data = (tBTA_DM_SEC*)p_param;
  tBTA_SERVICE_MASK service_mask;
  uint32_t i;
  RawAddress bd_addr;

  switch (event) {
    case BTA_DM_ENABLE_EVT: {
      BD_NAME bdname;
      bt_status_t status;
      bt_property_t prop;
      prop.type = BT_PROPERTY_BDNAME;
      prop.len = BD_NAME_LEN;
      prop.val = (void*)bdname;

      status = btif_storage_get_adapter_property(&prop);
      if (status == BT_STATUS_SUCCESS) {
        /* A name exists in the storage. Make this the device name */
        BTA_DmSetDeviceName((char*)prop.val);
      } else {
        /* Storage does not have a name yet.
         * Use the default name and write it to the chip
         */
        BTA_DmSetDeviceName(btif_get_default_local_name());
      }

      /* Enable local privacy */
      BTA_DmBleConfigLocalPrivacy(BLE_LOCAL_PRIVACY_ENABLED);

      /* for each of the enabled services in the mask, trigger the profile
       * enable */
      service_mask = btif_get_enabled_services_mask();
      for (i = 0; i <= BTA_MAX_SERVICE_ID; i++) {
        if (service_mask &
            (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) {
          btif_in_execute_service_request(i, true);
        }
      }
      /* clear control blocks */
      memset(&pairing_cb, 0, sizeof(btif_dm_pairing_cb_t));
      pairing_cb.bond_type = BOND_TYPE_PERSISTENT;

      /* This function will also trigger the adapter_properties_cb
      ** and bonded_devices_info_cb
      */
      btif_storage_load_bonded_devices();
      bluetooth::bqr::EnableBtQualityReport(true);
      btif_enable_bluetooth_evt(p_data->enable.status);
    } break;
    ......

btif_in_execute_service_request

启动服务,目前仅启动 SDP

btif_storage_load_bonded_devices

加载已绑定的设备,可以不详细分析

EnableBtQualityReport

内容较少,仅仅启动一个 BQR

btif_enable_bluetooth_evt

以上四个函数执行完毕,则 enableNative 执行完毕。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容