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, Passkeyint (*ssp_reply)(const RawAddress* bd_addr, bt_ssp_variant_t variant, uint8_t accept, uint32_t passkey);// 获取profile的interfaceconst 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_ONadapter_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_STARTEDdiscovery_state_changed_callback discovery_state_changed_cb;// 传统配对 请求pincode时回调,通过bt_interface_t中的pin_reply向协议栈设置pincodepin_request_callback pin_request_cb;// 简单安全配对 请求passkey时回调,通过bt_interface_t中的ssp_reply向协议栈设置passkeyssp_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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/209931.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测YOLO系列从入门到精通技术详解100篇-【图像处理】边缘检测

目录 知识储备 算法原理 边缘检测(Canny算子) Canny算子边缘检测流程 应用案例

[Linux] LAMP架构

一、LAMP架构架构的概述 LAMP 架构是一种流行的 Web 应用程序架构,它的名称是由四个主要组件的首字母组成的: Linux(操作系统): 作为操作系统,Linux 提供了服务器的基础。它负责处理硬件资源、文件系统管理…

解读 | 阿里通义千问模型全尺寸开源 “诚意满满“背后的名与利

大家好,我是极智视界,欢迎关注我的公众号,获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq 12 月 1 日阿里开源…

基于Web和深度学习的辣椒检测产量预测系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 辣椒是一种重要的经济作物,被广泛种植和消费。然而,辣椒的产量预测一直是农业生产中的重要问题。准确地预测辣椒的产量可以帮助农民合理安…

第10节:Vue3 论点

如何在UniApp中使用Vue3框架创建论点&#xff1a; <template> <view> <text>{{ segments[currentSegment].content }}</text> </view> </template> <script> import { ref, computed } from vue; export default { setup…

高项备考葵花宝典-项目进度管理输入、输出、工具和技术(下,很详细考试必过)

项目进度管理的目标是使项目按时完成。有效的进度管理是项目管理成功的关键之一&#xff0c;进度问题在项目生命周期内引起的冲突最多。 小型项目中&#xff0c;定义活动、排列活动顺序、估算活动持续时间及制定进度模型形成进度计划等过程的联系非常密切&#xff0c;可以视为一…

【论文笔记】FSD V2: Improving Fully Sparse 3D Object Detection with Virtual Voxels

原文链接&#xff1a;https://arxiv.org/abs/2308.03755 1. 引言 完全稀疏检测器在基于激光雷达的3D目标检测中有较高的效率和有效性&#xff0c;特别是对于长距离场景而言。 但是&#xff0c;由于点云的稀疏性&#xff0c;完全稀疏检测器面临的一大困难是中心特征丢失&…

vFW搭建IRF

正文共&#xff1a;2328字 40图&#xff0c;预估阅读时间&#xff1a;5 分钟 IRF&#xff08;Intelligent Resilient Framework&#xff0c;智能弹性架构&#xff09;技术通过将多台设备连接在一起&#xff0c;虚拟化成一台设备&#xff0c;集成多台设备的硬件资源和软件处理能…

C++如何通过调用ffmpeg接口对H265文件进行编码和解码

要对H265文件进行编码和解码&#xff0c;需要使用FFmpeg库提供的相关API。以下是一个简单的C程序&#xff0c;演示如何使用FFmpeg进行H265文件的编码和解码&#xff1a; 编码&#xff1a; #include <cstdlib> #include <cstdio> #include <cstring> #inclu…

两个月软考-高项上岸

文章目录 前言结缘软考功亏一篑有始有终2个月计划资料部分计划截图 总结 前言 我们看小说或者电视剧电影都会看到这样的情节&#xff0c;主角一开始锦衣玉食&#xff0c;突然家道中落&#xff0c;啥都没了&#xff0c;主角再一路奋起重新找回了属于自己的一切&#xff1b;还有…

Vue项目中实现浏览器标签页名字的动态修改

修改router/index.js文件 路由条目下面添加meta属性 meta:{title:DevOps运维平台 }示例 使用Vue的全局守卫函数beforeEach&#xff0c;在路由切换前动态修改浏览器标签页名字 router.beforeEach((to,from,next) > {document.title to.meta.titlenext() })

Error: Cannot find module ‘E:\Workspace_zwf\mall\build\webpack.dev.conf.js‘

执行&#xff1a;npm run dev E:\Workspace_zwf\zengwenfeng-master>npm run dev> mall-app-web1.0.0 dev E:\Workspace_zwf\zengwenfeng-master > webpack-dev-server --inline --progress --config build/webpack.dev.conf.jsinternal/modules/cjs/loader.js:983thr…

[笔记]ARMv7/ARMv8 交叉编译器下载

开发 Cortex-A7、Cortex-A72 或其他 ARM 架构 profile 芯片时&#xff0c;经常需要下载对应架构的交叉编译器&#xff0c;所以写这篇笔记&#xff0c;用于记录一下交叉编译器下载流程&#xff0c;免得搞忘。 编译环境&#xff1a;ubuntu 虚拟机 下载地址 我们可以从 ARM 官网…

09 视频分片上传Minio和播放

文章目录 一、流程设计1. 分片上传实现思路2. 文件分片上传流程3. 视频播放流程 二、代码实现1. 后端代码2. 文件上传前端代码3. 视频播放前端代码 一、流程设计 1. 分片上传实现思路 2. 文件分片上传流程 3. 视频播放流程 二、代码实现 1. 后端代码 pom.xml <dependenc…

多线程案例-单例模式

单例模式 设计模式的概念 设计模式好比象棋中的"棋谱".红方当头炮,黑方马来跳.针对红方的一些走法,黑方应招的时候有一些固定的套路.按照套路来走局势就不会吃亏. 软件开发中也有很多常见的"问题场景".针对这些问题的场景,大佬们总结出了一些固定的套路.按…

vue实现可拖拽列表

直接上代码 <!-- vue实现可拖拽列表 --> <template><div><button click"logcolig">打印数据</button><TransitionGroup name"list" tag"div" class"container"><divclass"item"v-f…

常见请求头与响应头你了解哪些?

常见的 HTTP 请求头和响应头包括&#xff1a; 常见的请求头&#xff1a; User-Agent&#xff1a;标识客户端代理信息&#xff0c;通常用于识别用户使用的浏览器或设备类型。 Accept&#xff1a;指示客户端可以接受的内容类型&#xff0c;例如 text/html, application/json 等…

深度学习记录--激活函数

激活函数的种类 对于激活函数的选择&#xff0c;通常有以下几种 sigmoid&#xff0c;tanh&#xff0c;ReLU&#xff0c;leaky ReLU 激活函数的选择 之前logistic回归一直使用的激活函数都是sigmoid函数&#xff0c;但一般来说&#xff0c;tanh函数是比sigmoid函数更加好的选…

【Python】 生成二维码

创建了一个使用 python 创建二维码的程序。 下面是生成的程序的图像。 功能描述 输入网址&#xff08;URL&#xff09;。 输入二维码的名称。 当单击 QR 码生成按钮时&#xff0c;将使用 QRname 中输入的字符将 QR 码生成为图像。 程序代码 import qrcode import tkinterd…

java泛型:泛型类,泛型方法

今日记录我的泛型使用&#xff0c;供后期查阅。 主要包含泛型类&#xff0c;泛型属性&#xff0c;泛型方法&#xff0c;静态方法中使用泛型。 public class GenericOperationResultRep<T> {private boolean success; // 是否操作成功。true&#xff0c;成功&#xff1b;f…