目录
蓝牙
蓝牙规范网站:
https://www.bluetooth.com/specifications/specs/
蓝牙技术基于FHSS(Frequency-Hopping Spread Spectrum)跳频扩频技术 (动态切换传输信道,以提升抗干扰能力)
蓝牙旨在解决移动电话与耳机等设备间的有线连接问题.
蓝牙技术历经迭代升级,关键里程碑包括:
蓝牙1.1(2001年) :首个稳定版本,支持基础数据传输与语音通信
蓝牙2.0(2004年) :引入 增强数据速率(EDR) ,传输速度提升至3 Mbps,支持CD级音质。
蓝牙4.0(2010年) :新增 低功耗(BLE) 模式,推动物联网设备普及。
蓝牙5.0(2016年) :传输距离扩展至300米,速率达2 Mbps,支持多设备连接。
蓝牙5.2(2020年) :强化音频传输与定位功能,适配智能家居与可穿戴设备。
工作频段: 2.4 GHz ISM频段,通过79个跳频信道减少与WiFi的干扰, 兼容 IEEE 802.15.1
Android的蓝牙框架分为
3.高层应用层___________高层有 SDP(服务发现)、RFCOMM(串口模拟)、AVCTP(音频控制)等支持应用场景
2.中间协议层___________中间层有 HCI(Host硬件控制接口)、L2CAP(逻辑链路控制)
1.底层硬件模块_________RF(射频)、BB(基带)、LM(链路管理)
Android 4.2前:使用BlueZ协议栈,架构依赖Linux内核与用户空间库(libbluetooth.so )。
Android 4.2后:过渡到BlueDroid,结构更简洁,与DBus解耦并通过HAL标准化硬件交互。 BTE负责核心功能,BTA与应用层通信
Android 11及更新版本:引入 Gabeldorsche 作为协议栈重构,目标为降低延迟并提升稳定性。
═══════════════════════════════════════
Android蓝牙系统分为六个层次:内核层、BlueZ库、适配库、JNI、Java框架和应用层
6.蓝牙应用层
5.蓝牙Java框架 框架层在 /framework/base/core/java/android/bluetooth
4.蓝牙JNI层
3.蓝牙硬件抽象层(HAL) 蓝牙适配库
2.BlueDroid库_蓝牙协议栈
1.蓝牙内核层
__________________________________
6.蓝牙应用层使用逻辑
包括用户开发的蓝牙应用(如设备扫描、数据传输等),通过Android提供的android.bluetooth API与底层交互。
开发者可使用BluetoothAdapter、BluetoothSocket等类实现功能
5.蓝牙Java框架 框架层在 /framework/base/core/java/android/bluetooth
提供标准的蓝牙API接口(如配对、连接、数据传输)
蓝牙系统服务:以独立APK形式存在 /packages/apps/Bluetooth 通过Binder IPC机制与应用交互,管理蓝牙服务和Profile(如 HFP、A2DP)
4.JNI层
代码位于 /packages/apps/Bluetooth/jni 实现Java框架层与本地C/C++代码的交互 调用HAL接口并接收回调
3. 蓝牙硬件抽象层(HAL)
定义标准接口(如bluetooth.h),协议栈通过HAL与硬件驱动通信
2.BlueDroid库_蓝牙协议栈
BlueDroid :分为两层: BTE 和 BTA
BTE(Bluetooth Embedded System) :实现核心功能(如L2CAP、RFCOMM协议)
BTA(Bluetooth Application Layer) :与框架层通信,处理应用逻辑
代码位置:external/bluetooth/bluedroid
1.蓝牙内核层
Linux内核模块:包括HCI驱动(如UART、USB)、协议支持(如L2CAP、SCO)及BlueZ遗留组件(部分版本保留)
厂商驱动:如高通、博通的定制实现,通过 hciattach 等工具加载
════════════════════════════════════════════════════
蓝牙音频编码
SBC
SBC(Subband Codec,支持的转码器)是蓝牙装置采用的标准音频编码技术,
几乎所有的蓝牙耳机都支持SBC。SBC的单声198kb/s、双声道是345kb/s
AAC
AAC编码
杜比实验室提供的技术,是一种高压缩比的编码算法,
Apple music上有大量采用AAC音频,同码率下音质优于MP3,
iPhone进行蓝牙传输时会使用AAC编码。所以当你使用AirPods Pro的时候,其音频编码就是使用AAC。
虽然AAC码率和 SBC 一样,但是因为用了更好的编码技术,即使在同样的低码率下,AAC的听感也好于SBC
aptX编码
高通芯片厂主推的编码技术,其专利权也是在高通,其传输量比传统蓝牙编码效率更高,
一般的aptx可以传输352kbps数据传输速度,
新的aptX-HD则最高可以达576kbps,
声音压缩的情况比较不失真,细节更多,大部分安卓新机配备AptX
但需要蓝牙耳机也支持AptX才能发挥效果。
由于高通拥有aptX的专利权,要使用的此编码的耳机商及设备商都要缴纳专利费,所以有些耳机或是手机(如iPhone)不支持。
aptX HD以增加延迟为代价,换取提高几乎一倍的码率,可达576kbps,音质大幅提升。
LDAC编码
LDAC是索尼开发音频编码,高传输码率使得高解析度的音频文件不会被过分压缩,保证了音质。
LDAC可以传输CD级音质,但是并不能无损传输Hi-Res音频,只是接近无损
索尼中高端的蓝牙耳机基本都支持。这应该是最接近“无损”的编码器了,最高码率达990kpbs。
LHDC编码
LHDC全称是Low-Latency Hi-Definition Audio Codec,是一种高音质蓝牙编解码方案,由台湾厂商Savitech盛微先进科技开发。
作为目前公认的第一档蓝牙音频编码技术,LHDC可支持传输24bit/96KHz的高解析度音频,最高数据传输速率可达900Kbps,
是常规SBC编码器(328Kbps)的近3倍,并且通过LHDC可将蓝牙音频的传输延迟降到80ms,
相比于SBC技术的400ms延迟可以说是显著提升了高清蓝牙标准设备的使用体验
蓝牙断开原因列表
ZBook.git中 蓝牙技术基础.pdf 第 503页 标注了 蓝牙断开原因列表
错误码 | 描述 | 详细说明 |
---|---|---|
0x01 | 未知的HCI指令 | 未知的主控制器接口指令 |
0x02 | 不能连接 | 当主机发出一个请求连接的指令_并且当前不存在一个对应于指定连接句柄或B地址的连接时,主控制器将在某一事件的状态参数中返回“0x02不能连接”错误码 |
0x03 | 硬件故障 | 当主机发出了一条指令,但该指令由于硬件故障不能执行时,主控制器将在事件状态参数中返回错误码—“0x03硬件故障”。 |
0x04 | 呼叫超时 | 如果主机发出一个Create_Connection指令,而且要连接的设备在呼叫定时器失效前没有在基带层次上进行应答,主控制器将在连接完成事件的状态参数中返回错误码‘0x04呼叫超时’。 |
0x05 | 身份验证失败 | 当由于丢失PIN码或链接字导致匹配/验证计算结果错误,进而引起匹配或验证失败时,主控制器将在连接完成事件或验证完成事件的状态参数中返回“0x05验证失败”错误码。 |
0x06 | 键丢失 | 当由于失去PIN |
0x07 | 存储器已满 | 当主机发出一指令时,该指令要求主控制器保存新参数,但主控制器制器并无对该指令的存储能力,主控制器将在指令完成事件的状态参数中返回“0x07存储器已满”错误码。 |
0x08 | 连接超时 | 【该错误码可用于指示连接断开的原因】。当链路监控定时器失效,并因此考虑释放链路时,主控制器将在一事件中发出“0x08连接超时”原因码。 |
0x09 | 超过最大连接数 | 当蓝牙模块不能再设置连接时,主控制器将在指令状态事件、连接完成事件或远程命名请求完成事件的状态参数中返回“0x09最大连接数”错误码。该错误原因可能是由于硬件或固件限制而引起的。 |
0x0A | 接到设备一个的最大SCO连接数 | 当达到设备最大SOC连接数时,主控制器将在指令状态事件或连接完成事件的状态参数中返回此0x0A错误码。 |
0x0B | ACL连接已存在 | 当与一设备已有ACL连接,并且主机又试图使用Create_Connection建立另外一个连接时,主控制器将在指令状态事件或连接完成事件的状态参数中返回”ACL连接已存在”错误码。 |
0x0C | 指令非法 | 当主控制器处于准备接收带有某些操作码的指令,并且收到的 |
0x0D | 由于资源有限,主机被拒绝 | 【错误码通常用于指示拒绝呼入连接的原因】_当主机已收到一个连接请求事件,并且主机通过发出Reject_Connection_Request指令拒绝呼入连接时,就可以使用一个原因码作为原因参数的值。 |
0x0E | 由于资源有限,主机被拒绝 | 【错误码通常用于指示拒绝呼入连接的原因】_当主机已收到一个连接请求事件,并且主机通过发出Reject_Connection_Request指令拒绝呼入连接时,就可以使用一个原因码作为原因参数的值。 |
0x0F | 由于远程设备是一个人设备,主机被拒绝。 | 【错误码通常用于指示拒绝呼入连接的原因】 |
0x10 | 主机超时 | 假定主机已收到一个连接请求事件,而且在连接定时器(其连接接受超时可使用Write_Connection_Accept_Timeout进行设置)终止前,主机没有发出Accept_Connection_Request指令或Reject_Connection_Request指令。 |
0x11 | 不支持的特性或参数值 | 当主控制器收到了含有一个或多个不被硬件支持的参数值的指令时,主控制器将在事件状态参数中返回"不支持特性或参数值"错误码。 |
0x12 | 非法的主控制器接口指令参数 | 当总的参数长度(或收到指令中的一个或多个参数值)不符合本文件所指定长度,主控制器将在事件的状态参数中返回"错误的HCI指令参数"错误码 |
0x13 | 由于另一端引起连接中断:用户中断连接 | 另一端引起连接中断 |
0x14 | 由于另一端引起连接中断:资源限制 | 另一端引起连接中断 |
0x15 | 由于另一端引起连接中断:关机 | 另一端引起连接中断 |
0x16 | 本地主机中断连 | 本地主机终止连接,由于它在连接断开完成事件的原因参数中返回,该错误码称为原因码 |
0x17 | 重复尝试 | 当设备由于验证或匹配失败的原因而没有更多时间再进行验证或匹配时,主控制器将在连接完成事件或验证完成事件的状态参数中返回"尝试重复"错误码 |
0x18 | 不允许匹配 | 当设备由于某些原因不允许匹配时,主控制器将在连接完成事件或验证完成事件的状态参数中返回“不允许匹配”错误码。 |
0x19 | 未知的LMP_PDU | 链路管理器协议报文_未知的链路管理器协议的协议数据单元 |
0x1A | 不支持的远程特性 | 当指令参数中指定的远程设备不支持与发出指令有关的特性时,主控制器将在与发出指令有关事件的状态参数中返回”不支持的远程特性”错误码。 |
0x1B | 拒绝SC0补偿 | 链路管理器协议报文_同步面向连接拒绝 |
0x1C | 拒绝SC0间歇模式 | 链路管理器协议报文_同步面向连接间隔拒绝 |
0x1D | 拒绝SC0无线模式 | 链路管理器协议报文_同步面向连接_无线模式拒绝 |
0x1E | 非法链路管理器协议(LMP)参数 | 链路管理器协议报文_错误的链路管理器协议参数 |
0x1F | 未特别指明的错误 | 当本文件没有指定适用错误码时,适用“未定义错误”错误码 |
0x20 | 不支持的链路管理器协议参数值 | 当指令参数中指定的远程设备返回包含LMP错误码0x20(即不支持的LMP参数值)的LMP消息时,主控制器将在与发出指令有关事件的状态参数中返回“不支持的LMP参数值”错误码 |
0x21 | 不允许的角色改变 | 当不允许角色变化时,主机在连接完成事件或角色变化事件状态参数中返回“不允许的角色变化”错误码 |
0x22 | 链路管理器协议响应超时 | 链路管理器协议响应超时 |
0x23 | 链路管理器协议错误处理事务冲突 | 链路管理器协议错误处理事务冲突 |
0x24 | 不允许的LMP_PDU | 不允许的LMP_PDU |
0x25-0xFF | 保留 | 保留 |
BLE蓝牙广播类型
BLE蓝牙广播类型主要有四种:
ADV === Advertisement === 广播
1. 可连接非定向 (ADV_IND) : 这是最常见的广播类型,可以被任何设备扫描并连接(最常用的广播方式)。
2. 可连接定向 (ADV_DIRECT_IND) : 这种类型的广播是直接针对特定设备的,只有被指定的设备才能连接(用于快速连接)。
3. 不可连接非定向 (ADV_NONCONN_IND): 这种类型的广播不能被扫描也不能被连接,通常用于发送广播数据。又分为两种分别是(用于信标,传感器):
(1) 定向高占空比模式:在这种模式下,设备会以非常高的频率发送广播,这样可以使得接收设备更快地发现广播设备,从而减少连接建立的延迟。但是,这种模式会消耗更多的电能。
(2) 定向低占空比模式:在这种模式下,设备会以较低的频率发送广播,这样可以节省设备的电能,但可能会增加连接建立的延迟
4. 可扫描非定向 (ADV_SCAN_IND) : 这种类型的广播可以被任何设备扫描,但不能被连接。
安卓蓝牙核心系统架构
整个bluedroid可以分为两大模块:BTIF,BTE
BTIF:提供 bluedroid 对外的接口
BTE:bluedroid 的内部处理,又细分为 BTA,BTU,BTM 和 HCI
BTM:蓝牙配对与链路管理
BTA:bluedroid 中各 profile 的逻辑实现和处理
BTU:承接 BTA 与 HCI
HCI:读取或写入数据到蓝牙硬件
缩词
ISOAL
ISOAL === Isochronous Adaptation Layer === 同步适配层
ISOAL(同步适配层,Isochronous Adaptation Layer)是蓝牙技术中用于优化实时数据传输的关键功能
定义:解决同步通信中设备间的时序差异,适配数据流传输。
功能: 将上层服务数据单元(SDU)分割为更小的协议数据单元(PDU),或反向重组
通过HCI与上层交互,支持同步数据流的传输
蓝牙5.2中新增,支持LE Audio的低延迟传输;蓝牙6.0进一步优化其数据分帧模式,提升可靠性。
BB
BB == Base Band == 基带
接下来是BB,即基带(Baseband)。
和都提到BB层提供两种物理链路:同步面向连接(SCO)和异步无连接(ACL),并支持纠错编码。
BB负责跳频和数据帧传输。因此,BB处理【数字信号】与【射频信号】之间的转换,管理物理链路和错误纠正。
RF
RF === Radio Frequency === 射频
RF层工作在2.4 GHz ISM频段,负责数据过滤和传输
RF是蓝牙技术中负责无线信号传输的物理层部分
处理物理数据流的过滤和调制/解调 , 物理层核心模块,实现蓝牙设备间的无线信号收发
BTIF
BTIF === Bluetooth Interface === 提供 bluedroid 对外的接口
- 作为 Bluedroid 与上层 Java Framework 的通道,提供 Bluedroid 对外的接口。
- 包含所有 Bluetooth Profile 的操作函数,客户端应用通过操作这个 Instance 来操作 Profile。
BTE
BTE === Bluetooth embedded system === 安卓蓝牙嵌入式系统
Bluedroid 的内部处理模块,包括 BTA、BTU、BTM 和 HCI。
- 负责实现蓝牙协议栈的通用功能和相关协议
BTA
BTA === Bluetooth Application Layer === 蓝牙应用层
- 实现各种蓝牙 Profile 的逻辑和处理
- 负责蓝牙设备管理、状态管理以及一些应用规范的操作和状态机。
BTU
BTA === Bluetooth Upper Layer === 蓝牙Upper层
- 承接 BTA 与 HCI (Host Controller Interface) 之间的交互。
- 负责处理来自 HCI 层的数据,并将其转发给 BTA 层。
BTM
BTM === Bluetooth Manager === 蓝牙管理器
- 负责蓝牙配对与链路管理。
- 管理设备的配对状态、连接状态等。
EIR
EIR === (Excess Information Rate) === BR/EDR新增带加密的EIR
HCI
HCI === Host Controller Interface = 蓝牙主机控制器接口
蓝牙主机控制器接口(HCI)
- 负责读取或写入数据到蓝牙硬件。
- 作为软硬件之间的接口,提供统一命令来访问硬件。
HCI位于主机和控制器之间,属于协议栈的一部分,无论是经典蓝牙、双模还是BLE-only都包含HCI层
HCI在蓝牙协议栈中位于 逻辑链路控制与适配协议(L2CAP)层与 链路管理协议(LMP)层之间,是软硬件交互的桥梁
它向上为主机提供统一访问蓝牙硬件的接口,向下通过物理传输层(如UART、USB等)与蓝牙控制器通信.
主机通过HCI发送命令 【 Command 】控制蓝牙控制器,例如设备初始化、连接建立等操作
控制器通过HCI返回事件【 Event 】反馈执行结果或状态更新,如连接成功、数据接收完成等
HCI支持两种数据包类型:
ACL(异步无连接数据包) :用于可靠的非实时数据传输,如文件传输或传感器数据。
SCO(同步连接导向数据包) :专为低延迟实时音频设计,如蓝牙耳机通话
以设备连接为例:
1. 主机发送Inquiry Command搜索周围设备。
2. 控制器返回Inquiry Complete Event报告搜索结果。
3. 主机发送Create Connection Command发起连接请求。
4. 控制器通过Connection Complete Event通知连接状态。
Inquiry_传统蓝牙搜索
Inquiry顾名思义就是检测和收集周围环境中的蓝牙设备
询问的方式可分为 两种搜索模式
One-Time Inquiry(一次性询问)
Periodic inquiry(周期性询问)
在当前查询期间响应的蓝牙设备如果未被上报过
且该设备没有被命令Set_Event_Filter过滤掉应始终以如下
三种事件之一(
1.Inquiry Result、
2.Inquiry Result with RSSI
3.Extended Inquiry Result) 上报主机Host查询的结果,不管采用哪个事件上报Host,都是将查询到的设备信息告知主机
ATT
ATT === Attribute Protocol === ATT(属性协议)
ATT 定义了客户端-服务器模型,客户端通过操作码(OpCode)向服务器发送请求(如读取、写入特征值),服务器返回响应或通知
属性操作与服务发现
属性协议是由于需要在BLE设备尽量少传输数据的需求而被设计出来 , ATT 通过 L2CAP通道往底层输入 命令 和 事件 以及数据
Gabeldorsche
代码路径:
/packages/modules/Bluetooth/system/gd/
Gabeldorsche在德语中是“叉须鳕鱼” , (简称“gd”) 同时与蓝牙名称的历史人物Harald Bluetooth有关联,是双关语
Gabeldorsche(简称“gd”)是Android系统蓝牙功能的核心软件层,负责设备发现、连接管理、数据传输等
Gabeldorsche 是Android 13中集成的蓝牙技术,替代了旧版的 Bluedroid 协议栈
Android 13中 Gabeldorsche作为新的蓝牙栈被默认启用,主要用于扫描、广告、连接管理等功能
Gabeldorsche 用【 Rust 】编写 , 模块化设计,处理线程和进程交互, 提高安全性和可靠性,特别是内存安全方面
GKI
GKI === Generic Kernel Interface === 通用内核接口
- 提供统一内核接口,适配了 OS 相关的进程、内存相关的管理。
- 用于线程间通信,主要通过变量 gki_cb 实现对进程的统一管理。
GATT
GATT === General Attribute Profile === 通用属性规范
通用属性配置文件 (GATT)
GATT 配置文件是一种通用规范,内容针对在 BLE 链路上发送和接收称为“属性”的简短数据片段。
所有最新的 BLE 应用配置文件都基于 GATT。
GATT 以属性协议 (ATT) 为基础构建而成。二者的关系也被称为 GATT/ATT。
ATT 经过优化,可在 BLE 设备上运行。
为此,【该协议尽可能少地使用字节。】
每个属性均由通用唯一标识符 (UUID) 进行唯一标识,
UUID 是用于对信息进行唯一标识的字符串 ID 的 128 位标准化格式。
ATT 传输的属性采用特征和服务格式
PSM
PSM === Protocol Service Multiplexer === 协议服务多路复用器
PSM全称是Protocol/Service Multiplexer,也就是协议/服务多路复用器,
这在蓝牙的L2CAP层中使用,用于标识不同的协议或服务,以便【在同一个物理链路上多路复用不同的逻辑通道】
GATT PSM的作用可能分为两种情况:
经典蓝牙(BR/EDR)上运行GATT/ATT时,使用特定的PSM值(如通过gatttool的-p选项指定);
BLE中,当使用L2CAP CoC时,PSM是动态分配的,范围在0x0080到0x00FF,并通过GATT服务进行发现或通知。
ATT协议的PSM是BT_PSM_ATT,值为0x0017,但只能通过LE信道连接,而不能通过传统L2CAP信令
GAP
GAP === General Access Profile === 通用访问规范
SMP
SMP === Security Manager Profile === 通用管理规范
Stack
- 核心协议栈,包括 L2CAP、SDP、GATT、GAP 等协议的实现。
- 负责处理蓝牙协议栈的底层通信和数据传输。
SCO
SCO === Synchronous Connection Oriented link === 面向连接的同步链路
支持对时延敏感的信息如【语音】。蓝牙中定义的两种数据链路方式之一。
蓝牙基带技术支持两种链路类型:
基于同步的连接 SCO(用于话音);
非同步连接类型 ACL(于分组数据)
蓝牙耳机bt sco播放不能是4 channel
SDP
SDP === Service Discvery Profile === 蓝牙服务发现协议
SDP 蓝牙服务发现协议(SDP)
蓝牙服务发现协议(SDP)是蓝牙协议栈中的核心组件,用于设备间动态发现对方支持的服务及其属性
服务发现:SDP允许设备在建立连接前查询对方支持的服务类型、属性及访问参数。
例如,手机连接蓝牙耳机时,会通过SDP查询耳机支持的音频服务(如A2DP)和控制命令。
工作机制
客户端-服务器模型:
SDP服务器:提供服务的一方(如蓝牙耳机、打印机)维护服务记录列表,每个记录描述服务的属性(如服务类型、协议通道号)
SDP客户端:发起查询的设备(如手机)通过发送SDP请求获取服务信息。发现服务后,客户端需通过其他协议(如RFCOMM)建立实际连接
SSP
SSP === Secure Simple Pairing === 安全简单配对
SSP流程根据两个配对连接的蓝牙设备双方的I/O能力来确定采用如下哪种模型
示例场景
手机与音箱配对:采用Just Works模式,用户无需操作但安全性较低。
手机与键盘配对:使用Passkey Entry模式,用户在键盘输入手机显示的6位数。
手机与手机配对:通过Numeric Comparison模式,用户需确认双方显示的数字一致
1、Numeric Comparison:数字比较模型,配对连接的两个蓝牙设备都有屏幕显示一个六位数字,并且有提供用户输入“Yes”或者“No”的选项。
显示的这6位数字的范围是:000000~999999,用户比较两个设备上显示的数字是否一致。连个设备上都确定Yes,配对才能成功,这样可以有效防止中间人(MITM)攻击。
使用场景:手机、车机、个人电脑等带有屏幕可以显示六位数字且提供Yes/No选项的设备间进行配对。
2、Passkey Entry:密码输入模型,配对连接的设备中其中一个设备具有输入能力,但不具有显示六位数字的能力,
另一个设备具有输出显示六位数字的能力。只具有输入能力的设备正确输入另一个设备上显示的六位数字,配对才能成功,有效防止中间人(MITM)攻击。
使用场景:手机和蓝牙键盘这样的组合,一个设备只具有输入能力,另一个设备具备输出显示能力。
3、Just Works:工作模型,配对连接的设备中至少有一台设备没有能够显示六位数字的显示器,也没有能够输入六位数字的键盘。该模型使用类似Numeric Comparison数字比较,但不会向用户显示那六位数字,应用程序可以简单地要求用户接受连接即可。由于看不到配对过程,总是同意配对,所以无法防止中间人(MITM)攻击。
使用场景:蓝牙耳机和其他设备配对,因为大部分蓝牙耳机没有显示也没有数字输入功能。
4、Out Of Band:简称OOB,两个配对设备通过其他途径交换配对信息,比如带有NFC功能的蓝牙音箱等,
但此种模型很少使用到,本篇不做过多讲解。
链路密钥(Link Key)通过HCI命令 HCI_Link_Key_Notification上报协议栈Host并保存,
存储路径:/data/misc/bluedroid/bt_config.conf
LinkKey
LinkKey === 蓝牙配对同信密钥 === bt_config.conf 中保存
cat /data/misc/bluedroid/bt_config.conf
[Info]
FileSource = Empty
TimeCreated = 2025-03-25 11:01:46
[Metrics]
Salt256Bit = 0aae69b153cd98e7623c70613e804561fa5c85606df703f67618b67ac29b39c0
[Adapter]
Address = 50:13:1d:67:4a:ea
LE_LOCAL_KEY_IRK = 3ff82936d385ec9e42e4a19f2390c8b5
LE_LOCAL_KEY_IR = 87161322a78679d0a3e91ed310bf1f36
LE_LOCAL_KEY_DHK = c826e710329396bc957c0189fc52d305
LE_LOCAL_KEY_ER = 7ad3964a2ee88a287fee9a429463e024
ScanMode = 0
DiscoveryTimeout = 120
[41:42:16:45:90:94]
ClockOffset = 28152
Timestamp = 1746601252
Name = 联想thinkplus-HE05X Ⅱ代
DevClass = 2360324
DevType = 1
AddrType = 0
Manufacturer = 1602
LmpVer = 12
LmpSubVer = 3
SecureConnectionsSupported = 0
LinkKeyType = 4
PinLength = 0
LinkKey = c4e693fc9f52f3b1e901aadddb84ac9c
MetricsId = 1
AvrcpControllerVersion = 0601
AvrcpPeerFeatures = 0100
Service = 0000110b-0000-1000-8000-00805f9b34fb 0000110e-0000-1000-8000-00805f9b34fb 0000111e-0000-1000-8000-00805f9b34fb
HfpVersion = 0701
HfpSdpFeatures = 3500
MaxSessionKeySize = 16
AvdtpVersion = 0301
Codecs = SBC,AAC
L2CAP
L2CAP === Logical Link Control and Adaptation Protocol === 逻辑链路控制与适配协议
L2CAP(Logical Link Control and Adaptation Protocol,逻辑链路控制与适配协议)是蓝牙协议栈中的核心协议,
主要负责在蓝牙设备之间建立逻辑链路,为上层协议提供数据传输服务,并支持多种功能
L2CAP通过 通道标识符(CID) 区分不同逻辑连接,支持多路复用
CID=0x0001用于信令通道,0x0002用于无连接通信,0x0004(ATT)、0x0006(SMP)等用于BLE特定协议
ISO数据包
ISO === isochronous === ISO data === 等时(Isochronous)数据包
蓝牙5.0和LE Audio的普及,HCI新增了对ISO数据包(等时传输)的支持,以满足超低延迟音频传输需
蓝牙等时数据包通过分组同步(CIG/BIG)、时间戳对齐及LC3编解码优化,解决了音频传输中的延迟与同步问题,扩展了蓝牙在无线音频领域的应用场景
同步连接组(CIG)
广播同步组(BIG)
等时数据包分为两种模式:
连接模式(CIS,Connected Isochronous Stream) :用于双向同步通信,例如真无线耳机的左右声道同步。多个CIS可组成 同步连接组(CIG) ,组内所有数据流共享相同时间戳,确保播放同步性
CIG/CIS适用于需高可靠性、双向同步的私有音频场景(如耳机),通过时间戳对齐实现精准同步
广播模式(BIS,Broadcast Isochronous Stream) :用于单向广播通信,例如车站广播或多人共享音频。多个BIS可形成 广播同步组(BIG) ,接收设备(称为同步接收器)通过周期性的PDU(协议数据单元)同步数据
BIG/BIS适用于一对多广播的公共场景,通过简化协议实现高效同步,支持无限接收设备
CIG有三种状态:
1.可配置(Configurable) :定义CIS参数
2.激活(Active) :启用CIS传输;
3.非激活(Inactive) :断开所有CIS
LE Audio
LE Audio === Low Energy Audio === 低功耗语音
LE Audio是蓝牙技术联盟推出的新一代低功耗音频标准,全称为Bluetooth Low Energy Audio。它基于蓝牙5.2及以上版本实现
SPP
SPP === Serial Port Profile === 串口通信协议
SPP蓝牙串口APP是一款为蓝牙相关开发人员量身定制的蓝牙串口调试工具。
它是一款专业的蓝牙调试软件,可帮助用户在移动端轻松实现调整蓝牙的模式功能,参数和各种系统设置,可以帮助用户简单就使用到蓝牙的所有功能,可以连接任何支持串行端口模式的蓝牙设备(如手机)
AFH
AFH === Adaptive Frequency Hopping === 自适应频率跳频
AFH的主要目的是避免固定频率的干扰,蓝牙1.2版本首次引入AFH , 特别是在蓝牙语音通信中使用 , AFH属于物理层机制
所有在微微网(piconet)中的设备都必须支持AFH才能启用该功能。
连接和发现过程中AFH不生效,这时候可能不会应用跳频策略。
AFH的组成四个主要部分:信道分类、链路管理、跳频序列修改 和 信道维护
信道分类: 检测干扰或使用预定义的通道掩码,将信道分为【“好”(可用)】、【“坏”(受干扰)】和【“未知”】三类
链路管理: 协调AFH信息并在蓝牙网络内部分发,确保所有设备同步跳频策略
跳频序列修改: 选择性减少跳频信道数量(最少需20个可用信道),避开干扰区域
信道维护: 定期重新评估信道状态,动态更新分类结果
AFH通过动态调整跳频序列,排除被干扰的信道 , AFH通过排除被WiFi占用的信道(如2.4GHz频段中的1-11信道)减少冲突
AFH通过动态调整跳频序列,避开WiFi(802.11b)、微波炉等同频段设备的干扰
RFCOMM
RFCOMM === Radio Frequency Communication Protocol === 蓝牙无线电通讯协议
RFCOMM 基于L2CAP协议的串行通信模拟协议 提供可靠的数据流传输,类似于TCP
UUID
UUID === 通用唯一识别码
它用于标识蓝牙设备提供的服务(Service)和特征(Characteristic)
使用预设UUID的好处是客户端可以快速准确的识别服务端是什么设备,可以提供什么服务。
手机系统很多都把使用预设UUID的服务和相关代码添加进去了,这样可以在不安装另外App的情况下,
正确的解析出从服务端(从设备,如血压计、心率计、温度计等)上传的信息(前提是该设备不只UUID遵循了标准,数据结构也要遵循协议标准)。
BT_Tip
User's headset is dual mode device which supports BR/EDR and BLE.
, as this name and address corresponding to the headset ble mode device, which didn't support any available profile,
so it only bonded but no profile to be connected.
MTK_抓取BT_HCI_Log
1.
settings -> developer options -> enable bluetooth hci snoop log >> enabled
settings -> developer options -> enable bluetooth stack log >> verbose
2.
adb root && adb remunt && adb pull /vendor/etc/bt_stack_debug.conf
把 bt_stack_debug.conf 中所有 TRC_* 的 Key 的 Value值改为 6
TRC_BTM=6
TRC_HCI=6
TRC_L2CAP=6
adb root && adb remunt && adb push bt_stack_debug.conf /vendor/etc/bt_stack_debug.conf
3.
拨号盘输入 *#*#3646633#*#* 进入工程模式 >> Log and Debugging >> DebuggerUI
提供HCILog,抓取步骤如下:
1.打开debugloggerUI
2.点击右上角设置
3.点击mobilelog打开mobilelog setting, sub log全勾选
4.点击connsyslog打开connsyslog setting, 勾选HCI log, stack log, 并将BT Firmware Log Level设置为DEBUG
5.返回setting界面点击log path选择system data
6.开始录制后记得BT OFF/ON一次
ps: adb pull时路径一定与UI下方的/data路径一致,pull出来后除了mobilelog文件夹外还有一个connsyslog文件夹,里面会有.cfa文件,请自行确认。
BT_配置
/vendor/mediatek/proprietary/packages/modules/Bluetooth/system/internal_include/bt_target.h
#define BTM_INQ_DB_SIZE 80 // 当前最大能扫描设备, (设备太多 导致扫描不到 调整该值)
MTK蓝牙固件版本
adb shell getprop | grep bt_fw_ver
[vendor.connsys.bt_fw_ver]: [t-neptune-main-soc7_0-2104-LEPIN_SOC7_0_E1_ASIC-20211206113401]
【 查询bt固件版本文件 】 adb shell "cd /vendor/firmware ls -ld $PWD/* | grep _bt_"
adb shell head -1 /vendor/firmware/soc7_0_ram_bt_1_1_hdr.bin
20211206113530ALPS 【当前打印第一行就是蓝牙固件版本】
MTK蓝牙固件文件
adb shell "cd /vendor/firmware ; ls -ld $PWD/* | grep _mcu_ ; ls -ld $PWD/* | grep _bt_"
-rw-r--r-- 1 root root 147124 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_mcu_1_1_hdr.bin
-rw-r--r-- 1 root root 143250 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_mcu_1a_1_hdr.bin
-rw-r--r-- 1 root root 147124 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_mcu_1b_1_hdr.bin
-rw-r--r-- 1 root root 2927412 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_bt_1_1_hdr.bin
-rw-r--r-- 1 root root 2927092 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_bt_1a_1_hdr.bin
-rw-r--r-- 1 root root 2927460 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_bt_1b_1_hdr.bin
MTK更换蓝牙固件
1.查询固件文件
adb shell "cd /vendor/firmware ; ls -ld $PWD/* | grep _mcu_ ; ls -ld $PWD/* | grep _bt_"
-rw-r--r-- 1 root root 147124 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_mcu_1_1_hdr.bin
-rw-r--r-- 1 root root 143250 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_mcu_1a_1_hdr.bin
-rw-r--r-- 1 root root 147124 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_mcu_1b_1_hdr.bin
-rw-r--r-- 1 root root 2927412 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_bt_1_1_hdr.bin
-rw-r--r-- 1 root root 2927092 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_bt_1a_1_hdr.bin
-rw-r--r-- 1 root root 2927460 2009-01-01 08:00 /vendor/firmware/soc7_0_ram_bt_1b_1_hdr.bin
2.依次替换蓝牙固件文件
adb root
adb remount
adb push soc7_0_ram_mcu_1_1_hdr.bin /vendor/firmware/
adb push soc7_0_ram_mcu_1a_1_hdr.bin /vendor/firmware/
adb push soc7_0_ram_mcu_1b_1_hdr.bin /vendor/firmware/
adb push soc7_0_ram_bt_1_1_hdr.bin /vendor/firmware/
adb push soc7_0_ram_bt_1a_1_hdr.bin /vendor/firmware/
adb push soc7_0_ram_bt_1b_1_hdr.bin /vendor/firmware/
adb shell sync
adb reboot
BT_相关宏
[init.svc.bt_dump]: [running]
[init.svc_debug_pid.bt_dump]: [1404]
[net.bt.name]: [Android]
[persist.bluetooth.btsnoopdefaultmode]: [disabled]
[persist.bluetooth.btsnooplogmode]: [full]
[persist.xxt_bt.aptx_cert]: [true]
[persist.xxt_bt.dbg_snoopsize]: [20]
[persist.xxt_bt.dbg_verbose]: [false]
[persist.xxt_bt.le_scan_interval_downgrade]: [true]
[persist.xxt_bt.phone_audio_asr]: [true]
[persist.xxt_bt.phone_audio_crystal_talk]: [true]
[persist.vendor.bluetooth.btsnoopautostart]: [true]
[ro.boot.btmacaddr]: [50:13:1D:67:4A:EA]
[ro.boottime.bt_dump]: [10363076846]
[ro.vendor.bt.connac3]: [no]
[ro.vendor.bt.platform]: [6878]
[ro.vendor.connsys.dedicated.log.port]: [bt,wifi,ics,btmcu,wifimcu]
[vendor.connsys.bt.adie.chipid]: [0x6637]
[vendor.debug.sf.fbthint]: [1]
[bluetooth.profile.a2dp.source.enabled]: [true]
[bluetooth.profile.asha.central.enabled]: [true]
[bluetooth.profile.avrcp.target.enabled]: [true]
[bluetooth.profile.bap.broadcast.assist.enabled]: [false]
[bluetooth.profile.bap.unicast.client.enabled]: [true]
[bluetooth.profile.bas.client.enabled]: [true]
[bluetooth.profile.ccp.server.enabled]: [true]
[bluetooth.profile.csip.set_coordinator.enabled]: [true]
[bluetooth.profile.gatt.enabled]: [true]
[bluetooth.profile.hap.client.enabled]: [true]
[bluetooth.profile.hfp.ag.enabled]: [true]
[bluetooth.profile.hid.host.enabled]: [true]
[bluetooth.profile.map.server.enabled]: [true]
[bluetooth.profile.mcp.server.enabled]: [true]
[bluetooth.profile.opp.enabled]: [true]
[bluetooth.profile.pan.nap.enabled]: [true]
[bluetooth.profile.pan.panu.enabled]: [true]
[bluetooth.profile.pbap.server.enabled]: [true]
[bluetooth.profile.sap.server.enabled]: [true]
[bluetooth.profile.vcp.controller.enabled]: [true]
[init.svc.bluetooth-1-1]: [running]
[init.svc.bluetooth_hal_service]: [running]
[init.svc_debug_pid.bluetooth-1-1]: [1116]
[init.svc_debug_pid.bluetooth_hal_service]: [1114]
[persist.bluetooth.a2dp_offload.cap]: [sbc-aac]
[persist.bluetooth.a2dp_offload.disabled]: [false]
[persist.bluetooth.btsnoopdefaultmode]: [disabled]
[persist.bluetooth.btsnooplogmode]: [full]
[persist.bluetooth.leaudio_offload.disabled]: [false]
[persist.vendor.bluetooth.broadcaster.tx_pwr]: [10]
[persist.vendor.bluetooth.btsnoopautostart]: [true]
[persist.vendor.bluetooth.connection_improve]: [yes]
[persist.vendor.bluetooth.hostloglevel]: [off]
[persist.vendor.bluetooth.leaudio_mode]: [ums-cg]
[persist.vendor.bluetooth.supportopphdt]: [no]
[ro.bluetooth.a2dp_offload.supported]: [true]
[ro.bluetooth.leaudio_offload.supported]: [true]
[ro.boottime.bluetooth-1-1]: [9452629538]
[ro.boottime.bluetooth_hal_service]: [9446266999]
[vendor.bluetooth.ldac.abr]: [true]
BT_LOG 打印
BluetoothAdapter:*connected|LocalBluetoothProfileManager: Adding local|ActiveDeviceManager: handleAdapterStateChanged:|AdapterProperties: Setting state to|CachedBluetoothDevice: connect CachedBluetoothDevice|HeadsetService: connect: device|BluetoothPhonePolicy: onUuidsDiscovered: discovered|BluetoothAdapterService: sendUuidsInternal: index|BluetoothAdapterService: disable|BluetoothAdapterService: enable|Received service discovery UUIDs|BluetoothPhonePolicy: processProfileStateChanged|Audio routes updated: AudioRoutesInfo|onnectEnabledProfiles: Connecting|LocalBluetoothProfileManager: New Profiles|CachedBluetoothDevice: No profiles|CachedBluetoothDevice: anonymizedAddress|SavedBluetoothDeviceUpdater: isFilterMatched|mCachedDevice: CachedBluetoothDevice|btm_sec_disconnected: Disconnection complete|: in state: WAIT_AUTH_COMPLETE,|BluetoothEventManager: DeviceFoundHandler:|hanging up call|Telephony: onDisconnect|HCI_Remote_Name_Request_Complete Page Timeout|BluetoothAdapterService: cancelDiscovery|UDevice : ScanDialog.onAttached|ACL Disconnected|Cannot establish Connection|RFCOMM connection closed|bluetoothConnectionStateChanged|\+routingOutputDevice|btif_get_device_type: Device|BluetoothSocket: close