赞
踩
在整个协议栈中一共分三个主要线程:bt_jni_workqueue、bt_workqueue/btu message loop、hci_thread。从名称可以看出它们分别处理着各层的事务:
这样实现的好处是调用方不会因调用方法阻塞而长期阻塞,各个模块在自己的线程中处理自己的事务,完成后通过事件通知到调用方。每个线程中有一个message loop,线程中一直在RunLoop中运行,需要将某个函数推送到线程运行时可以通过调用message_loop_->task_runner()->PostTask()
。
该线程负责处理bt interface层的事务,对于上层JNI调用协议栈的interface时,将调用方法past到该线程运行,同样的对下层的上报事件等也将事件past到该线程中处理,然后由该线程向更上层上报,它提供了以下几个接口:
bt_status_t do_in_jni_thread(const base::Closure& task);
bt_status_t do_in_jni_thread(const tracked_objects::Location& from_here,
const base::Closure& task)
bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event,
char* p_params, int param_len,
tBTIF_COPY_CBACK* p_copy_cback)
void btif_thread_post(thread_fn func, void* context);
例如:JNI初始化协议栈时,在bt_workqueue线程中调用btif_transfer_context
将btif_init_ok
函数past到bt_jni_workqueue线程执行。
// Inform the bt jni thread initialization is ok.
message_loop_->task_runner()->PostTask(
FROM_HERE, base::Bind(base::IgnoreResult(&btif_transfer_context),
btif_init_ok, 0, nullptr, 0, nullptr));
这个线程是整个协议栈中核心线程,profile、host中的处理都是在该线程中,它提供以下几个接口:
void bta_sys_sendmsg(void* p_msg);
bt_status_t do_in_bta_thread(const tracked_objects::Location& from_here,
const base::Closure& task);
协议栈中实现了一个事件驱动器,各个模块向驱动器注册事件以及事件的处理函数,事件发生时调用bta_sys_sendmsg
将其发送给驱动器进行处理。每个模块通过宏#define BTA_SYS_EVT_START(id) ((id) << 8)
生成自己模块中的事件,即每个模块中的事件数量不能超过255,收到事件时根据事件解析出该事件属于哪个模块id = (uint8_t)(p_msg->event >> 8);
,然后找到对应模块的处理函数进行处理。
hci层的线程主要是处理上层向下发送HCI 包的事务,收到HCI数据包时直接将其上报到了bt_workqueue线程中。
此处只是介绍hci_thread线程工作方式,具体的处理逻辑在后续HCI模块时详细介绍。
// 下发数据包
transmit_command()
-> enqueue_command()
-> message_loop_->task_runner()->PostTask(FROM_HERE, std::move(callback)) //此处还在bt_workqueue线程中
-> event_command_ready() // hci_thread 线程执行
-> packet_fragmenter->fragment_and_dispatch()
// 收到数据包
hci_event_received()
-> send_data_upwards.Run(from_here, packet) // send_data_upwards在初始化时由上层注册
-> post_to_hci_message_loop() // bte_main_boot_entry函数中调用set_data_cb函数注册注册到send_data_upwards
-> btu_hci_msg_process() // bt_workqueue 线程执行
在协议栈中,有大量的状态机,具体实现如下:
每个模块可能有N个事件,对应event 1~event index N,可能有M个状态,每个事件在各个状态都有两个action(最多两个,也可能只有一个,或者一个都没有),执行完action之后会切换到下一个状态。实际上bt_workqueue中的事件驱动器是结合状态机来实现的,其处理逻辑如下:
bool xxx_sm_execute(BT_HDR* p_msg) {
// 根据当前状态获取当前状态下事件的action列表
state_table = bta_sys_st_tbl[bta_sys_cb.state];
// 切换到下一个状态
bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
// 执行action
for (i = 0; i < BTA_SYS_ACTIONS; i++) {
action = state_table[p_msg->event & 0x00ff][i];
(*bta_sys_action[action])((tBTA_SYS_HW_MSG*)p_msg);
}
}
结合事件驱动之后,其逻辑关系如下图:
实际上,在事件驱动中每个模块对应一个处理函数xxx_sm_execute
,在这个函数中进入状态机中根据每个状态来决定事件真正的处理函数。
以下结构体是系统管理中核心的数据结构:
typedef struct { // 记录各个模块的事件回调函数 tBTA_SYS_REG* reg[BTA_ID_MAX]; bool is_reg[BTA_ID_MAX]; // 系统管理器的状态 tBTA_SYS_HW_STATE state; // 系统状态变化时的回调函数 tBTA_SYS_HW_CBACK* sys_hw_cback[BTA_SYS_MAX_HW_MODULES]; // 角色管理的回调,DM中注册 tBTA_SYS_CONN_CBACK* prm_cb; // 功耗管理的回调,DM中注册 tBTA_SYS_CONN_CBACK* ppm_cb; // 连接策略变化的回调,dm中注册 tBTA_SYS_CONN_CBACK* p_policy_cb; // sco连接状态变化的回调, audio/video模块中注册 tBTA_SYS_CONN_CBACK* p_sco_cb; // 角色变化回调, audio/video模块中注册 tBTA_SYS_CONN_CBACK* p_role_cb; } tBTA_SYS_CB;
bta_sys_sendmsg
函数发出事件:// 注册各个模块的事件
void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) {
bta_sys_cb.reg[id] = (tBTA_SYS_REG*)p_reg;
bta_sys_cb.is_reg[id] = true;
}
// 处理事件
void bta_sys_event(BT_HDR* p_msg) {
// 从事件中获取模块
id = (uint8_t)(p_msg->event >> 8);
//通过模块id获取到模块的事件处理函数,并执行事件处理
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
}
状态机中也提到,每个模块的事件处理函数只有一个,在模块内根据状态再做具体的事件处理。如:
// 系统管理
static const tBTA_SYS_REG bta_sys_hw_reg = {bta_sys_sm_execute, NULL};
// SDP
static const tBTA_SYS_REG bta_sdp_reg = {bta_sdp_sm_execute, NULL};
// 设备管理
static const tBTA_SYS_REG bta_dm_search_reg = {bta_dm_search_sm_execute, bta_dm_search_sm_disable};
// 等等。。。
系统管理中有4个状态,6个事件,状态转换如下:
系统管理中的状态对应的事件处理列表如下(仅举例):
// 每个状态对应的事件处理以及状态转换 const uint8_t bta_sys_hw_off[][BTA_SYS_NUM_COLS] = { /* Action 1 Action 2 Next State */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}}; const uint8_t bta_sys_hw_on[][BTA_SYS_NUM_COLS] = { /* Action 1 Action 2 Next State */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}}; // action的函数列表, 对应到各个事件 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 */ bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */ bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */ bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */ };
其中BTA_SYS_IGNORE
表示无action,遇到时直接跳过。
BTA_SYS_HW_API_ENABLE_EVT
的处理函数是bta_sys_hw_api_enable
,它的流程如下:如果state不等于HW_ON,发出BTA_SYS_EVT_ENABLED_EVT事件,否则调用DM设置的回调函数将BTA_SYS_HW_ON_EVT事件上报的DM。BTA_SYS_HW_EVT_ENABLED_EVT
事件的处理函数是bta_sys_hw_evt_enabled
,该函数中调用BTM_DeviceReset
复位bt controller。BTA_SYS_HW_EVT_STACK_ENABLED_EVT
事件的处理函数是bta_sys_hw_evt_stack_enabled
,该函数将BTA_SYS_HW_ON_EVT
事件通过tBTA_SYS_CB::sys_hw_cback
上报给DM。BTA_SYS_HW_API_DISABLE_EVT
事件的处理函数是bta_sys_hw_api_disable
,首先调用各个模块注册的disable函数(在注册事件处理函数时同时注册的), 然后切换到hw stoping状态,并发出BTA_SYS_EVT_DISABLED_EVT
。BTA_SYS_HW_EVT_DISABLED_EVT
事件的处理函数是bta_sys_hw_evt_disabled
,该函数将BTA_SYS_HW_OFF_EVT
事件通过tBTA_SYS_CB::sys_hw_cback
上报给DM。BTA_SYS_HW_ERROR_EVT
事件的处理函数是bta_sys_hw_error
,该函数将BTA_SYS_HW_ERROR_EVT
事件通过tBTA_SYS_CB::sys_hw_cback
上报给DM。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。