基于ESP32的Bluedroid蓝牙协议栈架构分析(2)--- ADV广播流程分析
程序员文章站
2022-07-13 17:21:49
...
为了分析ESP32的蓝牙接口,是如何在协议栈上运行的,现在以最简单的启动广播为例,分析Bluedroid蓝牙协议栈整体流程。
具体过程如下:
esp_ble_gap_start_advertising()
esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_START_ADV;//执行事件
memcpy(&arg.start_adv.adv_params, adv_params, sizeof(esp_ble_adv_params_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
//函数走向
btc_transfer_context()
---------->>btc_task_post()
----------------------->>> btc_thread_handler()
----------------------------->>profile_tab()
------------------------------->>>>btc_gap_ble_call_handler()
------------------------------------>>>btc_ble_start_advertising()
-------------------------------------------BTA_DmSetBleAdvParamsAll()
//传递事件,调用响应函数进行数据下发
void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own,
tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol,
tBLE_BD_ADDR *p_dir_bda, tBTA_START_ADV_CMPL_CBACK p_start_adv_cb)
{
p_msg->hdr.event = BTA_DM_API_BLE_ADV_PARAM_All_EVT;
...
p_msg->p_start_adv_cback = p_start_adv_cb;
...
bta_sys_sendmsg(p_msg);
}
bta_sys_sendmsg()
---------->>>>>btu_task_post()
------------->>>>>osi_thread_post(btu_thread, bta_sys_event, param, 0, timeout);
------------------------>>>>>bta_sys_event()
void bta_sys_event(void * param)
{
BT_HDR *p_msg = (BT_HDR *)param;
UINT8 id;
BOOLEAN freebuf = TRUE;
APPL_TRACE_EVENT("BTA got event 0x%x\n", p_msg->event);
/* get subsystem id from event */
id = (UINT8) (p_msg->event >> 8); //事件ID 通过BTA_DM_API_BLE_ADV_PARAM_All_EVT映射传递
/* verify id and call subsystem event handler */
if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
} else {
APPL_TRACE_WARNING("BTA got unregistered event id %d\n", id);
}
if (freebuf) {
osi_free(p_msg);
}
}
bta_sys_cb是函数指针集,这个函数指针的初始化在使能BT时会被初始化到。
<bta_sys_main.c>
void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
{
bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
bta_sys_cb.is_reg[id] = TRUE;
}
//sm的意思是statemachine,状态机管理穿插在整个蓝牙管理中。
static const tBTA_SYS_REG bta_dm_reg =
{
bta_dm_sm_execute,
bta_dm_sm_disable
};
static const tBTA_SYS_REG bta_dm_search_reg =
{
bta_dm_search_sm_execute,
bta_dm_search_sm_disable
};
tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback)
{
...
memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
bta_sys_register (BTA_ID_DM, &bta_dm_reg );
bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );
...
}
根据之前传递的事件ID = BTA_DM_API_BLE_ADV_PARAM_All_EVT 其调用bta_dm_sm_execute处理消息.
根据事件的不同会调用不同的注册函数。如果是事件ID BTA_DM_API_SEARCH_EVT将调用 bta_dm_search_sm_execute
//映射分配事件处理函数
BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg)
{
UINT16 event = p_msg->event & 0x00ff;
APPL_TRACE_EVENT("bta_dm_sm_execute event:0x%x", event);
/* execute action functions */
if (event < BTA_DM_NUM_ACTIONS) {
(*bta_dm_action[event])( (tBTA_DM_MSG *) p_msg);
}
return TRUE;
}
const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */
}
根据数据传递相关信息 广播事件也即bta_dm_ble_set_adv_params_all
bta_dm_ble_set_adv_params_all()
--------->>>>>BTM_BleStartAdv()
------------------>>>>>>>>btm_ble_start_adv()
------------------------------>>>>btsnd_hcic_ble_set_adv_enable()
------------------------------>>>> btu_hcif_send_cmd ();
-------------------------------------->>>>hci_layer_get_interface()->transmit_command();
------------------------------------直接操作HCI接口进行发送处理。
(仅供参考,如有问题请留言)
上一篇: nordic设备做主机发现服务失败