關(guān)鍵線程
在整個(gè)協(xié)議棧中一共分三個(gè)主要線程:bt_jni_workqueue、bt_workqueue/btu message loop蹈矮、hci_thread注服。從名稱可以看出它們分別處理著各層的事務(wù):
- bt_jni_workqueue:處理bt interface層的事務(wù)
- bt_workqueue/btu message loop:處理bt application/profile舆驶、bt host的事務(wù)
- hci_thread:處理hci層的事務(wù)
這樣實(shí)現(xiàn)的好處是調(diào)用方不會(huì)因調(diào)用方法阻塞而長(zhǎng)期阻塞拓轻,各個(gè)模塊在自己的線程中處理自己的事務(wù),完成后通過事件通知到調(diào)用方批幌。每個(gè)線程中有一個(gè)message loop础锐,線程中一直在RunLoop中運(yùn)行,需要將某個(gè)函數(shù)推送到線程運(yùn)行時(shí)可以通過調(diào)用message_loop_->task_runner()->PostTask()
荧缘。
bt_jni_workqueue
該線程負(fù)責(zé)處理bt interface層的事務(wù)皆警,對(duì)于上層JNI調(diào)用協(xié)議棧的interface時(shí),將調(diào)用方法past到該線程運(yùn)行截粗,同樣的對(duì)下層的上報(bào)事件等也將事件past到該線程中處理信姓,然后由該線程向更上層上報(bào)鸵隧,它提供了以下幾個(gè)接口:
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初始化協(xié)議棧時(shí),在bt_workqueue線程中調(diào)用btif_transfer_context
將btif_init_ok
函數(shù)past到bt_jni_workqueue線程執(zhí)行意推。
// 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));
bt_workqueue/btu message loop
這個(gè)線程是整個(gè)協(xié)議棧中核心線程豆瘫,profile、host中的處理都是在該線程中菊值,它提供以下幾個(gè)接口:
void bta_sys_sendmsg(void* p_msg);
bt_status_t do_in_bta_thread(const tracked_objects::Location& from_here,
const base::Closure& task);
協(xié)議棧中實(shí)現(xiàn)了一個(gè)事件驅(qū)動(dòng)器外驱,各個(gè)模塊向驅(qū)動(dòng)器注冊(cè)事件以及事件的處理函數(shù),事件發(fā)生時(shí)調(diào)用bta_sys_sendmsg
將其發(fā)送給驅(qū)動(dòng)器進(jìn)行處理腻窒。每個(gè)模塊通過宏#define BTA_SYS_EVT_START(id) ((id) << 8)
生成自己模塊中的事件昵宇,即每個(gè)模塊中的事件數(shù)量不能超過255,收到事件時(shí)根據(jù)事件解析出該事件屬于哪個(gè)模塊id = (uint8_t)(p_msg->event >> 8);
儿子,然后找到對(duì)應(yīng)模塊的處理函數(shù)進(jìn)行處理瓦哎。
hci_thread
hci層的線程主要是處理上層向下發(fā)送HCI 包的事務(wù),收到HCI數(shù)據(jù)包時(shí)直接將其上報(bào)到了bt_workqueue線程中。
此處只是介紹hci_thread線程工作方式惫周,具體的處理邏輯在后續(xù)HCI模塊時(shí)詳細(xì)介紹。
// 下發(fā)數(shù)據(jù)包
transmit_command()
-> enqueue_command()
-> message_loop_->task_runner()->PostTask(FROM_HERE, std::move(callback)) //此處還在bt_workqueue線程中
-> event_command_ready() // hci_thread 線程執(zhí)行
-> packet_fragmenter->fragment_and_dispatch()
// 收到數(shù)據(jù)包
hci_event_received()
-> send_data_upwards.Run(from_here, packet) // send_data_upwards在初始化時(shí)由上層注冊(cè)
-> post_to_hci_message_loop() // bte_main_boot_entry函數(shù)中調(diào)用set_data_cb函數(shù)注冊(cè)注冊(cè)到send_data_upwards
-> btu_hci_msg_process() // bt_workqueue 線程執(zhí)行
狀態(tài)機(jī)
在協(xié)議棧中,有大量的狀態(tài)機(jī)腕够,具體實(shí)現(xiàn)如下:
每個(gè)模塊可能有N個(gè)事件,對(duì)應(yīng)event 1~event index N晓避,可能有M個(gè)狀態(tài)交排,每個(gè)事件在各個(gè)狀態(tài)都有兩個(gè)action(最多兩個(gè),也可能只有一個(gè)扑媚,或者一個(gè)都沒有)腰湾,執(zhí)行完action之后會(huì)切換到下一個(gè)狀態(tài)。實(shí)際上bt_workqueue中的事件驅(qū)動(dòng)器是結(jié)合狀態(tài)機(jī)來(lái)實(shí)現(xiàn)的疆股,其處理邏輯如下:
bool xxx_sm_execute(BT_HDR* p_msg) {
// 根據(jù)當(dāng)前狀態(tài)獲取當(dāng)前狀態(tài)下事件的action列表
state_table = bta_sys_st_tbl[bta_sys_cb.state];
// 切換到下一個(gè)狀態(tài)
bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
// 執(zhí)行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);
}
}
結(jié)合事件驅(qū)動(dòng)之后费坊,其邏輯關(guān)系如下圖:
實(shí)際上,在事件驅(qū)動(dòng)中每個(gè)模塊對(duì)應(yīng)一個(gè)處理函數(shù)xxx_sm_execute
旬痹,在這個(gè)函數(shù)中進(jìn)入狀態(tài)機(jī)中根據(jù)每個(gè)狀態(tài)來(lái)決定事件真正的處理函數(shù)附井。
系統(tǒng)管理
核心數(shù)據(jù)結(jié)構(gòu)
以下結(jié)構(gòu)體是系統(tǒng)管理中核心的數(shù)據(jù)結(jié)構(gòu):
typedef struct {
// 記錄各個(gè)模塊的事件回調(diào)函數(shù)
tBTA_SYS_REG* reg[BTA_ID_MAX];
bool is_reg[BTA_ID_MAX];
// 系統(tǒng)管理器的狀態(tài)
tBTA_SYS_HW_STATE state;
// 系統(tǒng)狀態(tài)變化時(shí)的回調(diào)函數(shù)
tBTA_SYS_HW_CBACK* sys_hw_cback[BTA_SYS_MAX_HW_MODULES];
// 角色管理的回調(diào),DM中注冊(cè)
tBTA_SYS_CONN_CBACK* prm_cb;
// 功耗管理的回調(diào)两残,DM中注冊(cè)
tBTA_SYS_CONN_CBACK* ppm_cb;
// 連接策略變化的回調(diào)永毅,dm中注冊(cè)
tBTA_SYS_CONN_CBACK* p_policy_cb;
// sco連接狀態(tài)變化的回調(diào), audio/video模塊中注冊(cè)
tBTA_SYS_CONN_CBACK* p_sco_cb;
// 角色變化回調(diào)人弓, audio/video模塊中注冊(cè)
tBTA_SYS_CONN_CBACK* p_role_cb;
} tBTA_SYS_CB;
- 注冊(cè)事件處理函數(shù)沼死, 后續(xù)通過
bta_sys_sendmsg
函數(shù)發(fā)出事件:
// 注冊(cè)各個(gè)模塊的事件
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獲取到模塊的事件處理函數(shù),并執(zhí)行事件處理
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
}
狀態(tài)機(jī)中也提到崔赌,每個(gè)模塊的事件處理函數(shù)只有一個(gè)意蛀,在模塊內(nèi)根據(jù)狀態(tài)再做具體的事件處理耸别。如:
// 系統(tǒng)管理
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};
// 設(shè)備管理
static const tBTA_SYS_REG bta_dm_search_reg = {bta_dm_search_sm_execute, bta_dm_search_sm_disable};
// 等等。县钥。太雨。
狀態(tài)轉(zhuǎn)換
系統(tǒng)管理中有4個(gè)狀態(tài),6個(gè)事件魁蒜,狀態(tài)轉(zhuǎn)換如下:
系統(tǒng)管理中的狀態(tài)對(duì)應(yīng)的事件處理列表如下(僅舉例):
// 每個(gè)狀態(tài)對(duì)應(yīng)的事件處理以及狀態(tài)轉(zhuǎn)換
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的函數(shù)列表囊扳, 對(duì)應(yīng)到各個(gè)事件
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
表示無(wú)action,遇到時(shí)直接跳過兜看。
事件處理
-
BTA_SYS_HW_API_ENABLE_EVT
BTA_SYS_HW_API_ENABLE_EVT
的處理函數(shù)是bta_sys_hw_api_enable
锥咸,它的流程如下:如果state不等于HW_ON,發(fā)出BTA_SYS_EVT_ENABLED_EVT事件细移,否則調(diào)用DM設(shè)置的回調(diào)函數(shù)將BTA_SYS_HW_ON_EVT事件上報(bào)的DM搏予。
BTA_SYS_HW_EVT_ENABLED_EVT
BTA_SYS_HW_EVT_ENABLED_EVT
事件的處理函數(shù)是bta_sys_hw_evt_enabled
,該函數(shù)中調(diào)用BTM_DeviceReset
復(fù)位bt controller弧轧。BTA_SYS_HW_EVT_STACK_ENABLED_EVT
BTA_SYS_HW_EVT_STACK_ENABLED_EVT
事件的處理函數(shù)是bta_sys_hw_evt_stack_enabled
雪侥,該函數(shù)將BTA_SYS_HW_ON_EVT
事件通過tBTA_SYS_CB::sys_hw_cback
上報(bào)給DM。-
BTA_SYS_HW_API_DISABLE_EVT
BTA_SYS_HW_API_DISABLE_EVT
事件的處理函數(shù)是bta_sys_hw_api_disable
精绎,首先調(diào)用各個(gè)模塊注冊(cè)的disable函數(shù)(在注冊(cè)事件處理函數(shù)時(shí)同時(shí)注冊(cè)的)速缨, 然后切換到hw stoping狀態(tài),并發(fā)出BTA_SYS_EVT_DISABLED_EVT
代乃。
BTA_SYS_HW_EVT_DISABLED_EVT
BTA_SYS_HW_EVT_DISABLED_EVT
事件的處理函數(shù)是bta_sys_hw_evt_disabled
旬牲,該函數(shù)將BTA_SYS_HW_OFF_EVT
事件通過tBTA_SYS_CB::sys_hw_cback
上報(bào)給DM。BTA_SYS_HW_ERROR_EVT
BTA_SYS_HW_ERROR_EVT
事件的處理函數(shù)是bta_sys_hw_error
搁吓,該函數(shù)將BTA_SYS_HW_ERROR_EVT
事件通過tBTA_SYS_CB::sys_hw_cback
上報(bào)給DM原茅。