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

关键线程

在整个协议栈中一共分三个主要线程: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);

例如: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));

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);

协议栈中实现了一个事件驱动器,各个模块向驱动器注册事件以及事件的处理函数,事件发生时调用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 线程执行

状态机

在协议栈中,有大量的状态机,具体实现如下:
在这里插入图片描述
每个模块可能有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_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。
  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux 系统中有几种常见的蓝牙协议栈: 1. BlueZ:这是 Linux 系统中默认的蓝牙协议栈,它由 Linux 基金会开发并维护。BlueZ 提供了蓝牙的高级功能,并且可以让用户通过命令行或脚本来控制蓝牙设备。 2. Bluedroid:这是 Android 系统中的蓝牙协议栈,也可以在其他基于 Linux 的系统中使用。Bluedroid 提供了丰富的蓝牙功能,包括蓝牙协议栈、配对、连接、传输数据等。 3. BlueZ for Android:这是一个基于 BlueZ 的蓝牙协议栈,专门为 Android 系统开发。它兼容 BlueZ 命令行工具,可以让用户在 Android 系统中使用 BlueZ 命令行来控制蓝牙设备。 4. hciattach:这是 Linux 中用于驱动蓝牙硬件的工具,它可以将蓝牙硬件附加到蓝牙协议栈中,使蓝牙硬件可以与其他蓝牙设备通信。 总的来说,Linux 系统中的蓝牙协议栈主要有 BlueZ 和 Bluedroid 两种,其中 BlueZ 是 Linux 系统中的默认蓝牙协议栈,Bluedroid 则是 Android 系统中的蓝牙协议栈。 ### 回答2: Linux操作系统中有两种蓝牙协议栈可供选择。 1. BlueZ协议栈:BlueZ是Linux操作系统上最常用的蓝牙协议栈。它提供API和工具,用于在Linux设备上实现蓝牙功能。BlueZ支持几乎所有的蓝牙协议,包括传统的蓝牙核心规范(Bluetooth Core Specification)和最新的蓝牙低功耗(Bluetooth Low Energy)规范。BlueZ协议栈被广泛应用于各种Linux设备,包括智能手机、平板电脑、智能手表等。 2. Affix协议栈:Affix是一个开源的Linux蓝牙协议栈。它提供了蓝牙通信的基本功能,并可以在嵌入式系统上运行。Affix协议栈支持蓝牙核心规范,但对于蓝牙低功耗规范的支持相对有限。它适用于资源受限的嵌入式设备,如物联网设备、传感器等。 总结起来,Linux操作系统上有两种常用的蓝牙协议栈:BlueZ协议栈和Affix协议栈。其中,BlueZ协议栈是最常用和功能最全面的蓝牙协议栈,被广泛应用于各种Linux设备。而Affix协议栈则适用于资源受限的嵌入式设备。 ### 回答3: Linux操作系统支持多种蓝牙协议栈,以下是其中一些常见的蓝牙协议栈: 1. BlueZ:BlueZ是Linux操作系统上最为广泛使用的开源蓝牙协议栈。它提供了一套完整的蓝牙协议栈实现,包括蓝牙核心协议、蓝牙硬件驱动和一系列用户空间的工具和库。BlueZ支持众多的蓝牙协议和功能,如蓝牙文件传输、蓝牙耳机、蓝牙键盘等。 2. Affix:Affix是一种轻量级的蓝牙协议栈,旨在提供更小的内存占用和更低的功耗。它适用于嵌入式设备和资源受限的系统。Affix支持核心蓝牙协议,但不支持所有BlueZ的高级功能。 3. Bluedroid:Bluedroid最初是由Android平台使用的蓝牙协议栈,后来也被移植到了Linux操作系统中。Bluedroid基于BlueZ协议栈,但做了一些定制化的修改和优化,以适应移动设备的需求。 4. FluorideFluoride是谷歌开发的蓝牙协议栈,最初用于Android平台,后来也支持了Linux操作系统。Fluoride提供了一套用于开发蓝牙应用的API和工具,并且与BlueZ相比有一些特有的优化和功能。 这些蓝牙协议栈都有各自的特点和适用场景,开发者可以根据不同的需求选择合适的协议栈来进行蓝牙应用程序的开发和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值