Android蓝牙协议栈fluoride(四) - 设备管理(bt interface)

设备管理的接口实现了蓝牙的开/关、属性设置、发现设备、获取profile的接口等等。

接口声明

接口声明如下:

// include/hardware/bluetooth.h
typedef struct {
  // 打开接口并注册回调函数
  int (*init)(bt_callbacks_t* callbacks, bool is_atv);
  // 关闭接口
  void (*cleanup)(void);
  
  // 打开蓝牙
  int (*enable)(bool guest_mode);
  // 关闭蓝牙
  int (*disable)(void);
  
  // 获取所有属性
  int (*get_adapter_properties)(void);
  // 获取指定type的属性
  int (*get_adapter_property)(bt_property_type_t type);
  // 设置属性
  int (*set_adapter_property)(const bt_property_t* property);
  // 获取指定对端设备的所有属性
  int (*get_remote_device_properties)(RawAddress* remote_addr);
  // 获取指定对端设备的指定属性
  int (*get_remote_device_property)(RawAddress* remote_addr, bt_property_type_t type);
  // 设置指定对端设备的属性
  int (*set_remote_device_property)(RawAddress* remote_addr, const bt_property_t* property);
  // 获取对端设备指定UUID的服务
  int (*get_remote_service_record)(const RawAddress& remote_addr,const bluetooth::Uuid& uuid);
  // 获取对端设备所有服务
  int (*get_remote_services)(RawAddress* remote_addr);
  
  // 开始扫描周围的设备
  int (*start_discovery)(void);
  // 取消扫描
  int (*cancel_discovery)(void);

  // 发起配对
  int (*create_bond)(const RawAddress* bd_addr, int transport);
  int (*create_bond_out_of_band)(const RawAddress* bd_addr, int transport, const bt_out_of_band_data_t* oob_data);
  // 删除已配对设备
  int (*remove_bond)(const RawAddress* bd_addr);
  // 取消配对
  int (*cancel_bond)(const RawAddress* bd_addr);
  // 获取制定设备的连接状态
  int (*get_connection_state)(const RawAddress* bd_addr);
  // 传统配对的pincode 输入
  int (*pin_reply)(const RawAddress* bd_addr, uint8_t accept, uint8_t pin_len, bt_pin_code_t* pin_code);
  // 简单安全配对的 pass key输入,包括Just Works, Numeric Comparison, Passkey
  int (*ssp_reply)(const RawAddress* bd_addr, bt_ssp_variant_t variant, uint8_t accept, uint32_t passkey);

  // 获取profile的interface
  const void* (*get_profile_interface)(const char* profile_id);
  bluetooth::avrcp::ServiceInterface* (*get_avrcp_service)(void);
  ...
} bt_interface_t;

typedef struct {
  // 蓝牙打开/关闭时状态变化BT_STATE_OFF、BT_STATE_ON
  adapter_state_changed_callback adapter_state_changed_cb;
  // 获取/设置属性时回调
  adapter_properties_callback adapter_properties_cb;
  // 获取/设置对端设备属性时回调
  remote_device_properties_callback remote_device_properties_cb;
  // 发现设备时回调
  device_found_callback device_found_cb;
  // 发现状态变化时回调BT_DISCOVERY_STOPPED、BT_DISCOVERY_STARTED
  discovery_state_changed_callback discovery_state_changed_cb;
  // 传统配对 请求pincode时回调,通过bt_interface_t中的pin_reply向协议栈设置pincode
  pin_request_callback pin_request_cb;
  // 简单安全配对 请求passkey时回调,通过bt_interface_t中的ssp_reply向协议栈设置passkey
  ssp_request_callback ssp_request_cb;
  // 绑定状态变化时回调,主要是create_bond, cancel_bond, remove_bond几个函数调用时
  bond_state_changed_callback bond_state_changed_cb;
  // ACL连接状态变化
  acl_state_changed_callback acl_state_changed_cb;
  ...
} bt_callbacks_t;

bt_callbacks_t在framwork中实现,调用init函数时注册到协议栈。bt_interface_t在btif/src/bluetooth.cc中实现,对外提供的名称时bluetoothInterface

#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"

EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
    sizeof(bluetoothInterface),
    init,
    enable,
    disable,
    cleanup,
    get_adapter_properties,
    get_adapter_property,
    set_adapter_property,
    get_remote_device_properties,
    get_remote_device_property,
    set_remote_device_property,
    get_remote_service_record,
    get_remote_services,
    start_discovery,
    cancel_discovery,
    create_bond,
    create_bond_out_of_band,
    remove_bond,
    cancel_bond,
    get_connection_state,
    pin_reply,
    ssp_reply,
    get_profile_interface,
    dut_mode_configure,
    dut_mode_send,
    le_test_mode,
    set_os_callouts,
    read_energy_info,
    dump,
    dumpMetrics,
    config_clear,
    interop_database_clear,
    interop_database_add,
    get_avrcp_service,
};

接下来将重点梳理几个接口,其他接口也是类似的。

init()

init()
 -> stack_manager_get_interface()->init_stack()
  -> event_init_stack()
   -> btif_init_bluetooth()
    -> bte_main_boot_entry()
     -> hci_layer_get_interface()->set_data_cb(post_to_hci_message_loop)
    -> run_message_loop()

init 接口通过set_data_cb向hci层注册了收到HCI数据包的回调,后续协议栈接收hci的数据都是通过这个回调,然后启动一个message loop。此外,init函数中还加载了一些动态库,在此处不具体列出。

enable()

// 上层调用
enable()
 -> stack_manager_get_interface()->start_up_stack_async()
  -> bte_main_enable()
  -> event_signal_stack_up()
   ->  callback->adapter_state_changed_cb(BT_STATE_ON)

// bte_main_enable中初始化协议栈完成后调用
-> btif_init_ok()
 -> BTA_EnableBluetooth(bte_dm_evt)

打开蓝牙分两个部分:

  • 协议栈的各个模块和profile初始化,入口为bte_main_enable
  • 蓝牙服务启动,同时注册dm 事件的回调

get_adapter_properties、get_adapter_property、set_adapter_property

// 获取所有属性
get_adapter_properties()
 -> btif_get_adapter_properties()
  -> execute_storage_request(BTIF_CORE_STORAGE_ADAPTER_READ_ALL)
   -> btif_in_get_adapter_properties()
    -> btif_storage_get_adapter_property()
    -> btif_storage_get_adapter_property()
    -> bt_callbacks_t::adapter_properties_cb()

// 获取指定属性
get_adapter_property(type)
 -> btif_get_adapter_property(type)
  -> execute_storage_request(BTIF_CORE_STORAGE_ADAPTER_READ)
   -> btif_storage_get_adapter_property()
    -> bt_callbacks_t::adapter_properties_cb()

// 设置指定属性
set_adapter_property()
 -> btif_set_adapter_property()
  -> case BT_PROPERTY_BDNAME:
   -> BTA_DmSetDeviceName()
  -> case BT_PROPERTY_ADAPTER_SCAN_MODE:
   -> BTA_DmSetVisibility()
  -> case BT_PROPERTY_xxx:
  -> execute_storage_request(BTIF_CORE_STORAGE_ADAPTER_WRITE)
   -> btif_storage_set_adapter_property()
   -> bt_callbacks_t::adapter_properties_cb()

属性获取主要是从本次存储的配置文件中获取,设置时会先设置到蓝牙协议栈然后保存到配置文件中,对端设备属性的设置与获取也是类似的,此处不具体列出。
支持的属性类型如下:

typedef enum {
  /*******************************以上类型是本地设备和对端设备共用*********************************/
  // 设备名称,本地设备的可以获取/设置,对端设备的只能获取
  BT_PROPERTY_BDNAME = 0x1,
  // 设备地址, 只能获取
  BT_PROPERTY_BDADDR,
  // 服务的UUID, 只能获取
  BT_PROPERTY_UUIDS,
  // BR/EDR设备类别,只能获取
  BT_PROPERTY_CLASS_OF_DEVICE,
  // 蓝牙类型:BREDR, BLE, DUAL Mode, 只能获取
  BT_PROPERTY_TYPE_OF_DEVICE,
  // 服务记录, 只能获取
  BT_PROPERTY_SERVICE_RECORD,
  /******************************************************************************************/
  /***********************************以下类型是仅本地设备使用***********************************/
  // 扫描模式,可获取/设置
  BT_PROPERTY_ADAPTER_SCAN_MODE,
  // 已绑定/配对的设备列表,只能获取
  BT_PROPERTY_ADAPTER_BONDED_DEVICES,
  // 扫描超时时间,可以获取/设置
  BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
  
  /***********************************以下类型是仅对端设备使用***********************************/
  // 可读性高的设备名称,可获取/设置
  BT_PROPERTY_REMOTE_FRIENDLY_NAME,
  // 信号强度,只能获取
  BT_PROPERTY_REMOTE_RSSI,
  // 版本信息,可获取/设置
  BT_PROPERTY_REMOTE_VERSION_INFO,
  /******************************************************************************************/
} bt_property_type_t;

start_discovery、cancel_discovery

start_discovery()
 -> btif_dm_start_discovery()
  -> BTA_DmSearch(&inq_params, services, bte_search_devices_evt)

cancel_discovery()
 -> btif_dm_cancel_discovery()
  -> BTA_DmSearchCancel()

bte_search_devices_evt()
 -> btif_dm_search_devices_evt()
  -> case BTA_DM_DISC_RES_EVT
   -> btif_storage_set_remote_device_property()
   -> bt_callbacks_t::remote_device_properties_cb()
  -> case BTA_DM_INQ_RES_EVT
   -> btif_storage_add_remote_device()
   -> bt_callbacks_t::device_found_cb()
  -> case BTA_DM_DISC_CMPL_EVT
   -> bt_callbacks_t::discovery_state_changed_cb(BT_DISCOVERY_STOPPED)
  -> case BTA_DM_SEARCH_CANCEL_CMPL_EVT
   -> bt_callbacks_t::discovery_state_changed_cb(BT_DISCOVERY_STOPPED)

发现周围设备和取消发现过程都是调用dm模块提供的api,结果通过bte_search_devices_evt上报,其中BTA_DM_DISC_RES_EVT事件表示是已发现设备的属性有更新,BTA_DM_INQ_RES_EVT事件表示发现的是新的设备。

create_bond

发起配对请求。

create_bond()
 -> btif_dm_create_bond()
  -> btif_dm_generic_evt(BTIF_DM_CB_CREATE_BOND)
   -> case BTIF_DM_CB_CREATE_BOND
    -> btif_dm_cb_create_bond()
     -> bond_state_changed()
      -> bt_callbacks_t::bond_state_changed_cb(BT_BOND_STATE_BONDING)
      -> BTA_DmBondByTransport()

ssp_reply

简单安全配对时的reply,包括Just Works, Numeric Comparison, Passkey Entry。

ssp_reply()
 -> btif_dm_ssp_reply()
  -> BTA_DmConfirm()

bte_dm_evt

在调用enable打开蓝牙时,注册了设备管理的事件处理回调bte_dm_evt,其回调后处理流程如下:

bte_dm_evt()
 -> btif_dm_upstreams_evt()
  -> case BTA_DM_ENABLE_EVT  //打开蓝牙的事件
   -> BTA_DmSetDeviceName()
   -> btif_in_execute_service_request() //enable各个profile
   -> btif_enable_bluetooth_evt()
    -> bt_callbacks_t::adapter_properties_cb(BT_PROPERTY_BDADDR)
    -> btif_sock_init()
     -> btsock_rfc_init()
     -> btsock_l2cap_init()
     -> btsock_sco_init()
  -> case BTA_DM_DISABLE_EVT //关闭蓝牙事件
   -> btif_in_execute_service_request() //disable各个profile
   -> btif_disable_bluetooth_evt()
    -> bte_main_disable()
  -> case BTA_DM_PIN_REQ_EVT //请求pincode获取
   -> btif_dm_pin_req_evt()
    -> bt_callbacks_t::pin_request_cb()
  -> case BTA_DM_AUTH_CMPL_EVT // 身份认证完成事件
   -> btif_dm_auth_cmpl_evt()
    -> btif_storage_add_bonded_device()
    -> bt_callbacks_t::bond_state_changed_cb(BT_BOND_STATE_BONDED)
  -> case BTA_DM_SP_CFM_REQ_EVT //请求用户确认简单安全配对的事件
   -> btif_dm_ssp_cfm_req_evt()
    -> bt_callbacks_t::bond_state_changed_cb(BT_BOND_STATE_BONDING)
    -> bt_callbacks_t::ssp_request_cb(BT_SSP_VARIANT_PASSKEY_CONFIRMATION)
  -> case BTA_DM_SP_KEY_NOTIF_EVT // 简单安全配对的passkey通知事件
   -> btif_dm_ssp_key_notif_evt()
    -> bt_callbacks_t::bond_state_changed_cb(BT_BOND_STATE_BONDING)
  	-> ssp_request_cb(BT_SSP_VARIANT_PASSKEY_NOTIFICATION)
  -> case BTA_DM_DEV_UNPAIRED_EVT // 解除配对事件
   -> btif_storage_remove_bonded_device()
    -> bt_callbacks_t::bond_state_changed_cb(BT_BOND_STATE_NONE)
  -> case BTA_DM_LINK_UP_EVT //ACL连接事件
   -> bt_callbacks_t::bond_state_changed_cb(BT_ACL_STATE_CONNECTED)
  -> case BTA_DM_LINK_DOWN_EVT //ACL断开事件
   -> bt_callbacks_t::bond_state_changed_cb(BT_ACL_STATE_DISCONNECTED)
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值