基于Android P版本分析
bluedroid事件响应机制
我们在分析bluedroid底层代码的时候,会经常见到bta_sys_sendmsg的函数,其中传入了一个指定的Event值,然后代码根据指定的规则来执行相应的逻辑。
但是这个过程是比较复杂的,涉及到的各个协议在init过程中的逻辑,有点凌乱。所以我们专门分析一下这一块的业务逻辑;
事件响应机制
我们以一个具体的例子(HFP协议启动),形象的描述一下该响应机制;
HFP Connect

我们之前看一下这一块的时序图,我们在调用到BTA_HfClientOpen函数的时候,在针对BTA_HF_CLIENT_API_OPEN_EVT事件,只是简单的描述了一下,然后就直接跳转到了bta_hf_client_start_open函数中,我们本章节就是用于描述该Event事件是如何和bta_hf_client_start_open函数对应上的;
BTA_HfClientOpen
我们直接根据业务流程分析,对该过程中涉及到的点进行延伸;
ini
void BTA_HfClientOpen(const RawAddress& bd_addr, tBTA_SEC sec_mask,
uint16_t* p_handle) {
APPL_TRACE_DEBUG("%s", __func__);
tBTA_HF_CLIENT_API_OPEN* p_buf =
(tBTA_HF_CLIENT_API_OPEN*)osi_malloc(sizeof(tBTA_HF_CLIENT_API_OPEN));
if (!bta_hf_client_allocate_handle(bd_addr, p_handle)) {
APPL_TRACE_ERROR("%s: could not allocate handle", __func__);
return;
}
p_buf->hdr.event = BTA_HF_CLIENT_API_OPEN_EVT;
p_buf->hdr.layer_specific = *p_handle;
p_buf->bd_addr = bd_addr;
p_buf->sec_mask = sec_mask;
bta_sys_sendmsg(p_buf);
}
在该过程中,创建了tBTA_HF_CLIENT_API_OPEN结构体,该结构体主要是用于组装open HFP过程中涉及到的一些参数信息;
arduino
/* data type for BTA_HF_CLIENT_API_OPEN_EVT */
typedef struct {
BT_HDR hdr;
RawAddress bd_addr;
uint16_t* handle;
tBTA_SEC sec_mask;
} tBTA_HF_CLIENT_API_OPEN;
在该结构体中,包含了BT_HDR类型的结构体hdr;
- RawAddress bd_addr:远端设备Address;
- uint16_t* handle:Event handle;
- tBTA_SEC sec_mask:标记;
BT_HDR结构体是一个核心的定义,用于定义蓝牙堆栈中使用的每一个缓冲区的头信息:
arduino
/* Define the header of each buffer used in the Bluetooth stack.
*/
typedef struct {
uint16_t event;
uint16_t len;
uint16_t offset;
uint16_t layer_specific;
uint8_t data[];
} BT_HDR;
- event:指定的响应事件;
- layer_specific:handle;
tBTA_HF_CLIENT_API_OPEN结构体信息组装完成之后,就可以将该消息进行发送;
bta_sys_sendmsg
scss
void bta_sys_sendmsg(void* p_msg) {
base::MessageLoop* bta_message_loop = get_message_loop();
if (!bta_message_loop || !bta_message_loop->task_runner().get()) {
APPL_TRACE_ERROR("%s: MessageLooper not initialized", __func__);
return;
}
bta_message_loop->task_runner()->PostTask(
FROM_HERE, base::Bind(&bta_sys_event, static_cast<BT_HDR*>(p_msg)));
}
我们发现,在该函数中,会将传入的p_msg消息和bta_sys_event函数绑定,即在后续的消息响应过程中响应指定的p_msg;
针对HFP connect,在该函数中传入的是tBTA_HF_CLIENT_API_OPEN类型的结构体数据,但是在函数中,最终转换为了static_cast<BT_HDR*>类型的参数;
我们分析一下base::Bind函数的架构:
bta_sys_event
scss
void bta_sys_event(BT_HDR* p_msg) {
uint8_t id;
bool freebuf = true;
APPL_TRACE_EVENT("%s: Event 0x%x", __func__, p_msg->event);
/* get subsystem id from event */
id = (uint8_t)(p_msg->event >> 8);
/* 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("%s: Received unregistered event id %d", __func__, id);
}
if (freebuf) {
osi_free(p_msg);
}
}
在该函数中,首先先根据event获取对应的subsystem id值:
vbnet
/* get subsystem id from event */
id = (uint8_t)(p_msg->event >> 8);
这里需要注意一下,这个对p_msg->event进行了 >> 8操作,之后我们再分析这一点的原因,我们先暂且记住即可;
得到id之后,判断id值的有效性,这里又涉及到了bta_sys_cb.reg的概念,我们先看一下bta_sys_cb.reg的定义,方便后续的分析;
bta_sys_cb.reg
bta_sys_cb的类型为tBTA_SYS_CB:
arduino
/* system manager control block */
typedef struct {
tBTA_SYS_REG* reg[BTA_ID_MAX]; /* registration structures */
bool is_reg[BTA_ID_MAX]; /* registration structures */
tBTA_SYS_HW_STATE state;
tBTA_SYS_HW_CBACK* sys_hw_cback[BTA_SYS_MAX_HW_MODULES]; /* enable callback
for each HW
modules */
uint32_t sys_hw_module_active; /* bitmask of all active modules */
uint16_t sys_features; /* Bitmask of sys features */
tBTA_SYS_CONN_CBACK* prm_cb; /* role management callback registered by DM */
tBTA_SYS_CONN_CBACK*
ppm_cb; /* low power management callback registered by DM */
tBTA_SYS_CONN_CBACK*
p_policy_cb; /* link policy change callback registered by DM */
tBTA_SYS_CONN_CBACK*
p_sco_cb; /* SCO connection change callback registered by AV */
tBTA_SYS_CONN_CBACK* p_role_cb; /* role change callback registered by AV */
tBTA_SYS_COLLISION colli_reg; /* collision handling module */
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
tBTA_SYS_EIR_CBACK* eir_cb; /* add/remove UUID into EIR */
#if (BTA_EIR_SUPPORT_128BIT_UUID == TRUE)
tBTA_SYS_CUST_EIR_CBACK* cust_eir_cb; /* add/remove customer UUID into EIR */
#endif
#endif
#if (BTM_SSR_INCLUDED == TRUE)
tBTA_SYS_SSR_CFG_CBACK* p_ssr_cb;
#endif
/* VS event handler */
tBTA_SYS_VS_EVT_HDLR* p_vs_evt_hdlr;
} tBTA_SYS_CB;
该结构体定义中的第一个元素就是reg,对应的类型为tBTA_SYS_REG*:
arduino
/* registration structure */
typedef struct {
tBTA_SYS_EVT_HDLR* evt_hdlr;
tBTA_SYS_DISABLE* disable;
} tBTA_SYS_REG;
scss
/* event handler function type */
typedef bool(tBTA_SYS_EVT_HDLR)(BT_HDR* p_msg);
/* disable function type */
typedef void(tBTA_SYS_DISABLE)(void);
其中就包含了两个元素:
- tBTA_SYS_EVT_HDLR* evt_hdlr:该指针代表了后续用于响应Event事件的函数,这个是核心点;
- tBTA_SYS_DISABLE* disable:该指针代表了HFP disable对应的响应函数;
typedef定义描述
在这里我们可以看出,tBTA_SYS_REG结构体中包含了tBTA_SYS_EVT_HDLR结构体,typedef定义说明,定义函数指针类型:
-
bool:代表了返回类型
-
tBTA_SYS_EVT_HDLR:函数指针变量
-
BT_HDR* p_msg
- BT_HDR*:形参类型为BT_HDR*
- p_msg:形参
bta_sys_cb.reg的定义清楚之后,我们已经知道了bta_sys_cb.reg是在什么时候被使用,但是我们还需要知道,bta_sys_cb.reg是在什么时候被赋值的。
bta_sys_register
通过分析代码可知,凡涉及到bta_sys_event函数的业务逻辑,各个协议中都会定义对应的bta_sys_cb.reg,所以在一般情况下,赋值逻辑是相同的、可复用的;
arduino
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;
}
上述是bta_sys_cb.reg的赋值逻辑,该函数中传入了两个参数:
- id:tBTA_SYS_REG*类型参数的唯一索引值;
- p_reg:tBTA_SYS_REG*类型的结构体数据;
我们看一下在HFP模块中该函数的调用逻辑:
scss
tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
tBTA_SEC sec_mask,
tBTA_HF_CLIENT_FEAT features,
const char* p_service_name) {
/* If already registered then return error */
if (bta_sys_is_register(BTA_ID_HS)) {
APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
return BTA_FAILURE;
}
/* register with BTA system manager */
bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
/* reset the control blocks */
bta_hf_client_cb_arr_init();
bta_hf_client_cb_arr.p_cback = p_cback;
bta_hf_client_cb_arr.serv_sec_mask = sec_mask;
bta_hf_client_cb_arr.features = features;
/* create SDP records */
bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
/* set same setting as AG does */
BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
/* Set the Audio service class bit */
tBTA_UTL_COD cod;
cod.service = BTM_COD_SERVICE_AUDIO;
utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
/* start RFCOMM server */
bta_hf_client_start_server();
return BTA_SUCCESS;
}
在该函数中调用了bta_sys_register函数,其中传入了两个参数:
- BTA_ID_HS:value = 27,代表了Headset;
- &bta_hf_client_reg:对应了Event事件的响应函数;
我们回顾一下之前的流程,在bta_sys_event函数中获取p_msg对应的id值的时候,是根据p_msg->event >> 8求得的,即现在BTA_ID_HS == p_msg->event >> 8 ,即p_msg->event >> 8 = 27;
我们再回到之前,p_msg->event = BTA_HF_CLIENT_API_OPEN_EVT:
scss
enum {
/* these events are handled by the state machine */
BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS),
BTA_HF_CLIENT_API_CLOSE_EVT,
BTA_HF_CLIENT_API_AUDIO_OPEN_EVT,
BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT,
BTA_HF_CLIENT_RFC_OPEN_EVT,
BTA_HF_CLIENT_RFC_CLOSE_EVT,
BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT,
BTA_HF_CLIENT_RFC_DATA_EVT,
BTA_HF_CLIENT_DISC_ACP_RES_EVT,
BTA_HF_CLIENT_DISC_INT_RES_EVT,
BTA_HF_CLIENT_DISC_OK_EVT,
BTA_HF_CLIENT_DISC_FAIL_EVT,
BTA_HF_CLIENT_SCO_OPEN_EVT,
BTA_HF_CLIENT_SCO_CLOSE_EVT,
BTA_HF_CLIENT_SEND_AT_CMD_EVT,
BTA_HF_CLIENT_MAX_EVT,
/* these events are handled outside of the state machine */
BTA_HF_CLIENT_API_ENABLE_EVT,
BTA_HF_CLIENT_API_DISABLE_EVT
};
其中BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS),BTA_ID_HS就是刚刚提供的常量值,value = 27,但是该值涉及到了BTA_SYS_EVT_START:
scss
/* Calculate start of event enumeration; id is top 8 bits of event */
#define BTA_SYS_EVT_START(id) ((id) << 8)
最后我们知道,BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS) = BTA_ID_HS << 8 = 6912;
正好对应的上,所以在bta_sys_event函数中对bta_sys_cb.reg进行有效性判断的时候,满足要求,所以可以执行bta_sys_cb.reg[id]->evt_hdlr指定的函数;
而我们知道,bta_sys_cb.reg[id]指向的为tBTA_SYS_REG类型的bta_hf_client_reg;
bta_hf_client_hdl_event
arduino
/* Event handler for the state machine */
static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
BTA_HfClientDisable};
其中bta_sys_cb.reg[id]->evt_hdlr指定的函数为bta_hf_client_hdl_event:
csharp
bool bta_hf_client_hdl_event(BT_HDR* p_msg) {
APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__,
bta_hf_client_evt_str(p_msg->event), p_msg->event);
bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
return true;
}
在该函数中调用了bta_hf_client_sm_execute函数,而该函数才是真正体现事件响应机制的地方;
bta_hf_client_sm_execute
ini
void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
tBTA_HF_CLIENT_CB* client_cb =
bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
if (client_cb == NULL) {
APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
p_data->hdr.layer_specific);
return;
}
tBTA_HF_CLIENT_ST_TBL state_table;
uint8_t action;
int i;
uint16_t in_event = event;
uint8_t in_state = client_cb->state;
/* Ignore displaying of AT results when not connected (Ignored in state
* machine) */
if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
client_cb->state,
bta_hf_client_state_str(client_cb->state), event,
bta_hf_client_evt_str(event));
}
event &= 0x00FF;
if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
return;
}
/* look up the state table for the current state */
state_table = bta_hf_client_st_tbl[client_cb->state];
/* set next state */
client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
/* execute action functions */
for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
action = state_table[event][i];
if (action != BTA_HF_CLIENT_IGNORE) {
(*bta_hf_client_action[action])(p_data);
} else {
break;
}
}
/* If the state has changed then notify the app of the corresponding change */
if (in_state != client_cb->state) {
VLOG(1) << __func__ << ": notifying state change to " << in_state << " -> "
<< client_cb->state << " device " << client_cb->peer_addr;
tBTA_HF_CLIENT evt;
memset(&evt, 0, sizeof(evt));
evt.bd_addr = client_cb->peer_addr;
if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
} else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
evt.open.handle = client_cb->handle;
bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
}
}
/* if the next state is INIT then release the cb for future use */
/* If the collision timer is scheduled, don't release the cb */
if ((client_cb->state == BTA_HF_CLIENT_INIT_ST) &&
(!alarm_is_scheduled(client_cb->collision_timer))) {
APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__,
client_cb->handle);
client_cb->is_allocated = false;
}
VLOG(2) << __func__ << ": device " << client_cb->peer_addr
<< "state change: [" << bta_hf_client_state_str(in_state) << "] -> ["
<< bta_hf_client_state_str(client_cb->state) << "] after Event ["
<< bta_hf_client_evt_str(in_event) << "]";
}
首先在这个函数中,涉及到了几个概念:
- tBTA_HF_CLIENT_CB* client_cb
- event &= 0x00FF
- bta_hf_client_st_tbl
- state_table
- set next state
- bta_hf_client_action
我们一一进行分析;
tBTA_HF_CLIENT_CB*
arduino
/* type for HF control block */
typedef struct {
// Fields useful for particular control block.
uint8_t handle; /* Handle of the control block to be
used by upper layer */
RawAddress peer_addr; /* peer bd address */
tSDP_DISCOVERY_DB* p_disc_db; /* pointer to discovery database */
uint16_t conn_handle; /* RFCOMM handle of connected service */
tBTA_SEC cli_sec_mask; /* client security mask */
tBTA_HF_CLIENT_PEER_FEAT peer_features; /* peer device features */
tBTA_HF_CLIENT_CHLD_FEAT chld_features; /* call handling features */
uint16_t peer_version; /* profile version of peer device */
uint8_t peer_scn; /* peer scn */
uint8_t role; /* initiator/acceptor role */
uint16_t sco_idx; /* SCO handle */
uint8_t sco_state; /* SCO state variable */
bool sco_close_rfc; /* true if also close RFCOMM after SCO */
tBTM_SCO_CODEC_TYPE negotiated_codec; /* negotiated codec */
bool svc_conn; /* set to true when service level connection is up */
bool send_at_reply; /* set to true to notify framework about AT results */
tBTA_HF_CLIENT_AT_CB at_cb; /* AT Parser control block */
uint8_t state; /* state machine state */
bool is_allocated; /* if the control block is already allocated */
alarm_t* collision_timer; /* Collision timer */
} tBTA_HF_CLIENT_CB;
我们看到,其中定义了一个变量:client_cb->state,该变量类型为tBTA_HF_CLIENT_CB*。其中有一个关键的元素:state,这个元素用于表明当前StateMachine,和ConnectionState不能混为一谈;
而该state的取值范围定义在:bta_hf_client_main.cc
arduino
/* state machine states */
enum {
BTA_HF_CLIENT_INIT_ST,
BTA_HF_CLIENT_OPENING_ST,
BTA_HF_CLIENT_OPEN_ST,
BTA_HF_CLIENT_CLOSING_ST
};
而state的初始值为state = BTA_HF_CLIENT_INIT_ST;
而client_cb变量值的获取,则涉及到了handle的概念, 这个我们暂且不谈,后续再说;
event &= 0x00FF
我们知道,event在修改之前,event = BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS) = BTA_ID_HS << 8 = 6912 = 0x1B00 = 1101100000000;
event &= 0x00FF = 1101100000000 & 0x00FF = 1101100000000 & 11111111 = 0;
因为这个event涉及到后续很多的逻辑,我们必须了解清楚其值;
bta_hf_client_st_tbl & state_table
ini
const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
bta_hf_client_st_closing};
其中包含了多个数组,代表了各个StateMachine对应响应的数组函数;
我们回顾之前的逻辑:
css
/* look up the state table for the current state */
state_table = bta_hf_client_st_tbl[client_cb->state];
我们刚刚分析了client_cb->state = BTA_HF_CLIENT_INIT_ST,而BTA_HF_CLIENT_INIT_ST = 0,则state_table = bta_hf_client_st_init;
arduino
/* state table for init state */
const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
/* Event Action 1 Action 2
Next state */
/* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_OPENING_ST},
/* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_OPEN_ST},
/* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
/* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_INIT_ST},
};
其中定义了很多Event以及对应的响应Action和next state映射链;
set next state
css
/* set next state */
client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
我们按照上述刚刚分析出来的值,来确定client_cb->state指定的值,该client_cb->state代表了下一个阶段的StateMachine;
old Event | Event | Action1 | Action2 | next state |
---|---|---|---|---|
event &= 0x00FF = 0 | API_OPEN_EVT | BTA_HF_CLIENT_START_OPEN | BTA_HF_CLIENT_IGNORE | BTA_HF_CLIENT_OPENING_ST |
client_cb->next_state = BTA_HF_CLIENT_OPENING_ST;
StateMachine & bta_hf_client_st_tbl映射关系
client_cb->state | bta_hf_client_st_tbl |
---|---|
BTA_HF_CLIENT_INIT_ST | bta_hf_client_st_init |
BTA_HF_CLIENT_OPENING_ST | bta_hf_client_st_opening |
BTA_HF_CLIENT_OPEN_ST | bta_hf_client_st_open |
BTA_HF_CLIENT_CLOSING_ST | bta_hf_client_st_closing |
bta_hf_client_action
arduino
/* action functions table, indexed with action enum */
const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
/* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
/* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
/* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
/* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
/* BTA_HF_CLIENT_SCO_LISTEN */ NULL,
/* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
/* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
/* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
/* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
/* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
/* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
/* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
/* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
/* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
/* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
/* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
/* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
/* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
/* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
/* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
/* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
};
其中定义的是真正用于处理BTA_HfClientOpen函数中对应的Event事件的;
我们先看一下它的使用逻辑:
ini
/* execute action functions */
for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
action = state_table[event][i];
if (action != BTA_HF_CLIENT_IGNORE) {
(*bta_hf_client_action[action])(p_data);
} else {
break;
}
}
arduino
/* state table information */
#define BTA_HF_CLIENT_ACTIONS 2 /* number of actions */
我们先看一下action值的判断:
ini
action = state_table[event][i];
- event = 0;
- i:代表了BTA_HF_CLIENT_ACTIONS,其实就是Action的取值范围值;
action的取值范围:BTA_HF_CLIENT_START_OPEN、BTA_HF_CLIENT_IGNORE,而排除BTA_HF_CLIENT_IGNORE,就只剩下BTA_HF_CLIENT_START_OPEN;
arduino
/* state machine action enumeration list */
enum {
BTA_HF_CLIENT_RFC_DO_CLOSE,
BTA_HF_CLIENT_START_CLOSE,
BTA_HF_CLIENT_START_OPEN,
BTA_HF_CLIENT_RFC_ACP_OPEN,
BTA_HF_CLIENT_SCO_LISTEN,
BTA_HF_CLIENT_SCO_CONN_OPEN,
BTA_HF_CLIENT_SCO_CONN_CLOSE,
BTA_HF_CLIENT_SCO_OPEN,
BTA_HF_CLIENT_SCO_CLOSE,
BTA_HF_CLIENT_FREE_DB,
BTA_HF_CLIENT_OPEN_FAIL,
BTA_HF_CLIENT_RFC_OPEN,
BTA_HF_CLIENT_RFC_FAIL,
BTA_HF_CLIENT_DISC_INT_RES,
BTA_HF_CLIENT_RFC_DO_OPEN,
BTA_HF_CLIENT_DISC_FAIL,
BTA_HF_CLIENT_RFC_CLOSE,
BTA_HF_CLIENT_RFC_DATA,
BTA_HF_CLIENT_DISC_ACP_RES,
BTA_HF_CLIENT_SVC_CONN_OPEN,
BTA_HF_CLIENT_SEND_AT_CMD,
BTA_HF_CLIENT_NUM_ACTIONS,
};
其中BTA_HF_CLIENT_START_OPEN = 2;
最终bta_hf_client_action[action]对应的函数为:bta_hf_client_start_open;
bta_hf_client_start_open
调转到这一步,就对应上了上述时序图中的逻辑了;
next bta_sys_sendmsg
上一个msg处理完成之后,会等待下一个msg,而在下一个msg时对应的StateMachine State = BTA_HF_CLIENT_OPENING_ST;
BTA_HF_CLIENT_OPENING_ST阶段对应的bta_hf_client_st_tbl中的数组为:
arduino
/* state table for opening state */
const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
..............................
}
后续都是根据StateMachine State阶段来执行响应的逻辑;