0x0. 蓝牙协议栈简介
BLE Core-Specification: www.bluetooth.com/specificati…
1.GATT
作为一个通用的基于ATT的profile,为上层应用提供了一个基本的服务框架, 使得所有基于LE的应用都可以将自身的功能映射到这个框架中来。
定义了更为具体的概念:一组通用的Attribute Type,如Primary Service、Characteristic.
2.ATT
简单的说就是用来给Server和Client进行通信的协议。
Server端: 一个类似“属性数据库”(handle: attribute)的东西,包含了一系列的属性及其特性。
Client端: 可以通过ATT协议从Server端获取这些属性。可以查询(Discover)、读取(read)甚至配置(write)Server中保存的属性。
Server端也可以实时的告知Client端 属性值 的变化。通知可以是无需Client应答的(notification),也可以是需要Client响应的(indication).
3.HCI
HCI是英文Host Controller Interface的缩写。上半部分称为主机Host,下半部分称为控制器Controller。
主要完成两个任务:
- 一个是发送命令给控制器和接收来自控制器的事件;
- 另一个是发送和接收来自对端设备的数据;
传输的数据分为三类:
Command:主机向控制器发出的各种命令Event:控制器返回的信息Acl data:与对端设备传输的数据
注意:
HCI是主机与控制器之间交互通道,两个蓝牙设备之间的无线信号传输不全都通过控制器反馈到主机,因为有的无线信息交互是在控制器间完成的(eg. CONNECT_REQ)。
4.Link Layer
链路层的主要是状态机,包含广播、扫描、发起和连接等几种状态,在这几种状态中,BLE设备可以执行广播和连接等操作。定义了在各种状态下的数据包格式、时序规范和接口协议。
BLUETOOTH SPECIFICATION Version 4.1 [Vol 6]
注意: BLE设备实现多个连接的基础: 链路层可以同时拥有多个状态机 ( eg. BLE设备在一个状态机中保持连接状态的同时,另一个状态机保持广播状态,或者多个链路状态机同时处于连接状态.)
0x1. 常见的数据包怎么查看
1.packetLogger简介
Mac 平台独有的蓝牙抓包工具, 环境配置以及工具详情可见SIG小组的介绍文章
2.常见协议栈包数据查看和分析
服务特征怎么查看 & 每一条指令 handle 字段的含义
Read By Group Type Request:
Client使用该子过程来发现服务端的所有Primary Services.
当收到Error Response < Error Code: Attribute Not Found> 时;则表明该过程已经完成.
返回的结果:
- Attribute Handle : 服务声明的Handle
- End Group Handle : 服务定义中最后一个Attribute的Handle
- Attribute Value : 服务端支持的服务的Service UUID
Find Information Request:
Find Information Request被用来获取与Attribute Handles相关联的类型 (eg. "属性句柄: 属性类型")
Client使用该请求来发现Server上的Attribute-Type列表.
MTU交换事件:
具体的过程就是,Client将本地的最大RX MTU告诉Server,反过来Server也将自己最大的RX MTU告知Client;双方选择两者中较小的一个,作为双向通信的MTU size。
读取设备序列号:
同步设备时间:
Q: Write Command 和 Write Request 区别.
A:
Write Request: 对应的是Write With Response, 用来写属性值.
| Parameter | Size (octets) | Description |
|---|---|---|
| Opcode | 1 | 0x12 |
| Handle | 2 | 访问到attribute的handle |
| Value | 0 ~ ATT_mtu - 3 | 实际写的数据内容 |
Write Command: 对应的是Write Without Response, 通常是 Control-Point Attribute.
| Parameter | Size (octets) | Description |
|---|---|---|
| Opcode | 1 | 0x52 |
| Handle | 2 | 访问到attribute的handle |
| Value | 0 ~ ATT_mtu - 3 | 实际写的数据内容 |
Extension: HCI Event: Number Of Completed Packets - Handle: 0x0042 - Packets: 0x0002 含义: 代表在一个Connection interval时间内,双方交互的Packets数目.
主机通过LE Read Buffer Size命令获知缓存区的剩余数量。
每发送一个数据包给控制器,就消耗控制器中的一个缓存,控制器发送Number Of Completed Packet事件给主机,当中包含连接句柄的列表和发送数据包的数量,之后释放相应缓存区。因此,主机不仅知道控制器释放了多少个缓存区,也知道哪些数据发送到了对端设备。
0x2. 广播 & 扫描
每一个广播事件包含三个广播包,即分别在37/38/39三个射频通道上同时广播相同的信息.
Q: 射频通道是否可以配置?
A: LE Set Advertising Parameter 命令来设置广播参数:
- 广播的最小间隔时间和最大间隔时间
- 设置地址类型,固定地址或者为随机地址。如果为定向广播,那么在广播数据包中应含有对端设备的地址
- 广播信道映射,信道映射用来决定使用哪三个广播信道
- 广播过滤策略,过滤策略用来过滤不符合规则的广播数据包
1.扫描设备周期长的问题原因分析
设备B不断发送广播信号给手机, 如果手机不开启扫描窗口,手机是收不到设备B的广播的。
不仅手机要开启射频接收窗口,而且只有手机的射频接收窗口跟广播发送的发射窗口匹配成功,而且** 广播射频通道 和手机 扫描射频通道 **是同一个通道,手机才能收到设备B的广播信号。
eg. 如果设备在37通道发送广播包,而手机在扫描38通道,那么即使他们俩的射频窗口匹配,两者也是无法进行通信的。有时会很快扫到设备,比如只需要一个广播事件,手机有时又会很慢才能扫到设备,比如需要10个广播事件甚至更多。
2.被动扫描 & 主动扫描
链路层在扫描状态下在主要广播信道监听广播数据。链路层监听到广播数据,或接收到扫描响应数据,则向主机发出广播报告(LE Advertising Report).
扫描行为的持续过程称为扫描窗口scanWindow,两次扫描行为之间的时间间隔成为扫描间隔scanInterval,显然扫描窗口不能大于扫描间隔,如果扫描窗口等于扫描间隔,链路层将持续扫描(无间断)。
Q: 两者的区别是?
A: 被动扫描: BLE设备只听不问,只接收接受广播报文,并不发送SCAN_REQ
主动扫描: 不只认真听,还勤于发问(SCAN_REQ),并接收后续的 SCAN_RSP.
涉及到的指令 LE Set Scan Parameter ( 设置控制器的扫描参数 ):
- 扫描类型: 可设置为被动扫描或主动扫描
- 扫描间隔: 控制器间隔多长时间扫描一次
- 扫描窗口: 每次扫描的持续时间
- 扫描策略: 接受任何的广播数据包或者仅仅接受白名单设备的广播数据包
主动扫描和被动扫描使用的命令完全一样。但控制器要发送SCAN_REQ数据包给对端设备,以便获得扫描响应数据包,而这些数据包需要包含设备地址,所以,在使用LE Set Scan Parameter命令时需要配置一个额外参数,决定链路层的数据包使用固定地址抑或是随机地址。控制器收到了SCAN_RSP数据包将向主机发送一个LE Advertising Resport事件。
BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 6, Part D
3.public 地址 & random 地址
Public Address: 这种地址固定不变,可以根据设备地址跟踪到该设备.
- 其中前三个字节使用OUI(Organizationally Unique Identifier),后三字节自由分配。OUI代表了一个指定的组织机构识别码.
- 通过该网址可以查询已经注册的OUI信息: www.wireshark.org/tools/oui-l…
Random Address: 采用一个随机数作为地址,Random Address 包含好几个子类
| 地址类型 | 是否可变 | 作为识别地址 | 描述 |
|---|---|---|---|
| Public Address | 固定 | Yes | 固定不变,需要避免地址冲突 |
| [Random Address] | |||
| -- Static Address | 随机 | Yes | 可以在启动时更改,是公共地址的一种流行替代品,因为使用它不需要任何费用 |
| [Private Address] | 用于保护蓝牙设备的隐私、隐藏身份和防止跟踪设备。 | ||
| -- Resolvable private address | 随机 | No | 可解析随机私有地址 |
| -- Non-resolvable private address | 随机 | No | 不可解析的随机私有地址 |
一个设备可以具有多种类型的地址,但是必须拥有一个识别地址
- Public Address 和 Static Address可作为识别地址。
- 如果设备采用Resolvable private address地址类型,必须同时具有一个Public Address 或 Static Address地址。
0x3. 从蓝牙协议栈层面看设备连接流程
1.连接交互
蓝牙5.1协议 连接时序图:
BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 6, Part D
packetLogger连接交互:
前提条件: Slave蓝牙设备应处于可连接的广播状态.
- 主机使用LE Add Device To White List将对端设备添加到白名单中, 然后再与白名单中的设备进行连接,通过这种方式,控制器可以同时和多个设备发起连接。
- 当主机打算与白名单中的设备连接,则控制器发送LE Create Connetion命令
- 控制器收到白名单中某一设备的可连接广播数据包,则向对端设备发送CONNECT_REQ数据包,其中包含所有连接所需的信息。另外控制器还向主机发送LE Create Conection Complete事件。如果对端设备接收到CONECT_REQ数据包,它也会向其主机发送LE Create Conection Complete事件。
- LE Create Conection Complete 事件包含连接句柄,用于标示主机和控制器之间传输的数据包。该事件还包括当前控制器的角色信息(主、从),从设备地址、间隔时间、等待时间、监控超时和主设备的时钟精度等。
- 当连接已经建立,所有的广播或者其它的发起连接请求将会自动停止。
注意: 一旦进入连接状态,就视为建立了连接。建立连接后,主机会发出一个数据并等待从机的响应,如果在6个连接间隔内都未等到从机的数据包,则视为连接断开。
常见连接失败错误:
详情见 BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 1, Part F
2.Connect Interval 和 Slave Latency:
Connect Interval:
连接成功后,master和slave在每一个connection interval开始的时候,都必须交互一次,即master给slave发一个包,slave再给master发一个包,整个交互过程称为一个connection event.
蓝牙芯片只有在connection event期间才把射频模块打开,此时功耗比较高,其余时间蓝牙芯片都是处于idle状态的,因此蓝牙芯片平均功耗就非常低.
BLE协议规定,connInterval必须是1.25ms的倍数,范围是7.5ms~4s。
在一个connection event期间,master也可以发多个包给slave,以提高吞吐率.
Slave Latency 从设备延迟:
在每一个connection interval开始的时候,Master和Slave必须交互一次,哪怕两者之间交互的是empty packet(空包).
但如果slave定义了slave latency,比如slave latency = 9,此时slave可以每9个connection interval才回复一次master,也就是说slave可以在前面8个connection interval期间一直睡眠,直到第9个connection interval到来之后,才回复一个packet给master.
这样将大大节省slave的功耗,提高电池续航时间。当然如果slave有数据需要上报给master,它也可以不等到第9个connection interval才上报,直接像正常情况进行传输即可,这样既节省了功耗,又提高了数据传输的实时性.
小结:
- Connection Interval缩短,Master和Slave通信更加频繁,提高数据吞吐速度,缩短了数据发送的时间,当然也增加了功耗.
- Connection Interval增长,通信频率降低,数据吞吐速度降低,增加了数据发送的时间,当然,这种设置降低了功耗.
- Slave Latency减少或者设置为 0,每次Connection Events中都需要回复Master的包,功耗会上升,数据发送速度会提高.
- Slave Latency加长,功耗下降,数据发送速度降低.