首页 > 编程知识 正文

Zephyr开源蓝牙协议栈,蓝牙协议栈详解

时间:2023-05-06 09:26:30 阅读:49931 作者:1417

安卓系统bluedroid启用流程分析

在上一篇文章《安卓中蓝牙系统服务层的使能流程分析》的基础上,本文分析了协议栈层的启用流程。 因此,蓝牙协议栈bluedroid的使能以在JNI层enableNative () )上调用协议栈接口enable ) )函数开始。

不言而喻,按照惯例,我们将整个映像协议栈的启用。 请参考以下时序图。

Android本机bluedroid按层次分为btif、bta、stack和hci四个层,每个层的作用不同,但实际程序运行在不同的线程上,对启用过程有更深的了解接下来,按照上述顺序分别进行说明。

蓝牙服务层JNI启用协议栈bluedroid,并通过接口函数接口发出到达协议栈入口的指示。

stack _ manager _ get _ interface (-start _ up _ stack _ async ); 向协议栈管理模块发布使能指令,模块内部通过线程stack_manage继续处理。

依次启用btif_config、btsnoop、hci等模块

1、btsnoop模块:

确定snoop开关是否打开,以及是否创建snoop文件以记录hci的交互式信息。

如果在开发人员选项中选中了snoop交换机的位置,persist.bluetooth.btsnoopenable全局变量将设置为true。 开关关闭时,变量设置为false。

snoop文件的默认存储位置:/data/misc /蓝牙/logs /

打开snoop开关的步骤很复杂,一般用户无法进入开发人员选项,甚至很难从哪里打开开发人员选项,因此在蓝牙开发过程中修改源代码或修改persist.bluetooth 目前有两种方法:

方法a :

修复在源代码中获取persist.bluetooth.btsnoopenable值时设置的错误值

由于此全局变量是在开发人员选项中首次打开snoop交换机时创建的,因此必须从未操作过snoop交换机。 操作开发人员可选的snoop开关时,获取上述全局变量将获取相应的值,错误值将不起作用。

方法b :

命令:在ADB shell setprop persist.bluetooth.btsnoopenabletrue中打开蓝牙HCI-snoop开关。

persist.bluetooth.btsnoopenable全局变量的存储路径因Android版本而稍有不同。

Android 8存储路径:/data/property/persist.bluetooth.btsnoopenable /

Android 9存储路径:/data/property/persistent _ properties /

2、HCI模块:

创建hci_thread线程,专用于hci相关进程,同时初始化蓝牙芯片。

要使用HIDL技术获取芯片控制器模块向外部提供的接口,请:

1.bthci=ibluetoothhci :3360 getservice (;

2.Android :3360 sp callbacks=newbluetoothcicallbacks (;

3.bthci-initialize(callbacks );

全名是hidl (HAL interface definition language,全称是Hal interface definition language ),以前Android有AIDL,Android binder上面有体系结构。 Android曾用于定义基于Binder通信的客户端和服务之间的接口,HIDL也起到了类似的作用,但它定义了Android框架和Android HAL实现之间的接口

Android HAL的实现方式因芯片制造商而异,实现内容都是类似Android源代码的hardwareinterfacesbluetooth1.0 的实现方式。 制造商进一步通过HAL的实现与本公司芯片进行交互。 这样可以通过统一的HAL接口实现软硬件分离,安卓系统可以集成不同厂商的蓝牙芯片。

芯片模块初始化完成后,将通过回调通知android层,让蓝牙协议栈继续后续的启用过程。

启用HCI模块后,它进入BTU_StartUp ()函数,开始初始化BTU控制模块,包括协议栈密钥模块,如BTU、BTM、L2CAP和SDP

启用controller模块实际上是使用一组HCI命令从芯片层获取支持的功能参数

类型定义结构{

Bt_HDR*(make_re

set)(void);

BT_HDR* (*make_read_buffer_size)(void);

BT_HDR* (*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count);

BT_HDR* (*make_read_local_version_info)(void);

BT_HDR* (*make_read_bd_addr)(void);

BT_HDR* (*make_read_local_supported_commands)(void);

BT_HDR* (*make_read_local_extended_features)(uint8_t page_number);

BT_HDR* (*make_write_simple_pairing_mode)(uint8_t mode);

BT_HDR* (*make_write_secure_connections_host_support)(uint8_t mode);

BT_HDR* (*make_set_event_mask)(const bt_event_mask_t* event_mask);

BT_HDR* (*make_ble_write_host_support)(uint8_t supported_host, uint8_t simultaneous_host);

BT_HDR* (*make_ble_read_white_list_size)(void);

BT_HDR* (*make_ble_read_buffer_size)(void);

BT_HDR* (*make_ble_read_supported_states)(void);

BT_HDR* (*make_ble_read_local_supported_features)(void);

BT_HDR* (*make_ble_read_resolving_list_size)(void);

BT_HDR* (*make_ble_read_suggested_default_data_length)(void);

BT_HDR* (*make_ble_read_maximum_data_length)(void);

BT_HDR* (*make_ble_read_maximum_advertising_data_length)(void);

BT_HDR* (*make_ble_read_number_of_supported_advertising_sets)(void);

BT_HDR* (*make_ble_set_event_mask)(const bt_event_mask_t* event_mask);

BT_HDR* (*make_read_local_supported_codecs)(void);

}

HCI层的交互如下图:

Reset完成后协议栈会主动下发HCI命令读取本端的蓝牙名字,并将新的名字下发给芯片,同时通过JNI层的回调将本端的蓝牙名字和地址上报给服务层。如果存在配对的蓝牙设备,也会将该设备信息上报。

紧接着会初始化协议栈的socket模块,这部分主要是为建立OBEX连接和数据交互做准备的。

协议栈所有使能工作完成,通过HAL bt_hal_cbacks->adapter_state_changed_cb回调将蓝牙使能成功的消息上报到JNI层。至此蓝牙协议栈bluedroid的使能流程的全部过程就分析完毕。

本篇协议栈使能的分析就到这儿了,感兴趣的小伙伴欢迎私信留言一起讨论。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。