当前位置:   article > 正文

Android蓝牙协议栈fluoride(三) - 系统管理_static messageloopthread hci_thread

static messageloopthread hci_thread

关键线程

在整个协议栈中一共分三个主要线程:bt_jni_workqueue、bt_workqueue/btu message loop、hci_thread。从名称可以看出它们分别处理着各层的事务:

  • bt_jni_workqueue:处理bt interface层的事务
  • bt_workqueue/btu message loop:处理bt application/profile、bt host的事务
  • hci_thread:处理hci层的事务

这样实现的好处是调用方不会因调用方法阻塞而长期阻塞,各个模块在自己的线程中处理自己的事务,完成后通过事件通知到调用方。每个线程中有一个message loop,线程中一直在RunLoop中运行,需要将某个函数推送到线程运行时可以通过调用message_loop_->task_runner()->PostTask()

bt_jni_workqueue

该线程负责处理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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

例如:JNI初始化协议栈时,在bt_workqueue线程中调用btif_transfer_contextbtif_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));
  • 1
  • 2
  • 3
  • 4

bt_workqueue/btu message loop

这个线程是整个协议栈中核心线程,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);
  • 1
  • 2
  • 3

协议栈中实现了一个事件驱动器,各个模块向驱动器注册事件以及事件的处理函数,事件发生时调用bta_sys_sendmsg将其发送给驱动器进行处理。每个模块通过宏#define BTA_SYS_EVT_START(id) ((id) << 8)生成自己模块中的事件,即每个模块中的事件数量不能超过255,收到事件时根据事件解析出该事件属于哪个模块id = (uint8_t)(p_msg->event >> 8);,然后找到对应模块的处理函数进行处理。
在这里插入图片描述

hci_thread

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 线程执行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

状态机

在协议栈中,有大量的状态机,具体实现如下:
在这里插入图片描述
每个模块可能有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);
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结合事件驱动之后,其逻辑关系如下图:
在这里插入图片描述
实际上,在事件驱动中每个模块对应一个处理函数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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 注册事件处理函数, 后续通过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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

状态机中也提到,每个模块的事件处理函数只有一个,在模块内根据状态再做具体的事件处理。如:

// 系统管理
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};
// 等等。。。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

状态转换

系统管理中有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  */
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

其中BTA_SYS_IGNORE表示无action,遇到时直接跳过。

事件处理

  • BTA_SYS_HW_API_ENABLE_EVT
    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_EVT事件的处理函数是bta_sys_hw_evt_enabled,该函数中调用BTM_DeviceReset复位bt controller。
  • BTA_SYS_HW_EVT_STACK_ENABLED_EVT
    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_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_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_EVT事件的处理函数是bta_sys_hw_error,该函数将BTA_SYS_HW_ERROR_EVT事件通过tBTA_SYS_CB::sys_hw_cback上报给DM。
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号