1. Overview
Bluetooth Enable Flow Arch bte_main_enable Flow2.
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));
}
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
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);
}
以上二者的真实回调
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
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 回调流程继续执行
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 执行完毕。
网友评论