BT bluedroid 事件响应机制

基于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阶段来执行响应的逻辑;

相关推荐
车载诊断技术1 小时前
什么是汽车中的SDK?
网络·架构·汽车·soa·电子电器架构
沐言人生2 小时前
Android10 Framework—Init进程-9.服务端属性值初始化
android·android studio·android jetpack
追光天使2 小时前
【Mac】和【安卓手机】 通过有线方式实现投屏
android·macos·智能手机·投屏·有线
小雨cc5566ru2 小时前
uniapp+Android智慧居家养老服务平台 0fjae微信小程序
android·微信小程序·uni-app
一切皆是定数3 小时前
Android车载——VehicleHal初始化(Android 11)
android·gitee
一切皆是定数3 小时前
Android车载——VehicleHal运行流程(Android 11)
android
problc3 小时前
Android 组件化利器:WMRouter 与 DRouter 的选择与实践
android·java
图王大胜4 小时前
Android SystemUI组件(11)SystemUIVisibility解读
android·framework·systemui·visibility
弥琉撒到我5 小时前
微服务swagger解析部署使用全流程
java·微服务·架构·swagger
服装学院的IT男8 小时前
【Android 13源码分析】Activity生命周期之onCreate,onStart,onResume-2
android