BLE跟其他无线技术一样,BLE分了多个层,每层都有其目的和作用;
host层:
- GAP:Generic Access Profile,通用访问规范
- GATT:Generic Attribute Profile ,通用属性规范
- L2CAP:Logical Link Control and Adaptation Protocol ,逻辑链路控制和适配协议
- ATT:Attribute Protocol ,属性协议
- SM:Security Manager Protocol,安全管理协议
- HCI:Host Controller Interface,Host side,主机控制器接口,主机端
Controller层:
- HCI:Host Controller Interface,Controller side,主机控制器接口,控制器端
- LL:Link Layer,链路层
- PHY:Physical Layer,物理层
由于内容较多,此篇文章主要讲控制器部分;后面整理完,陆续发出来后面的讲解,以及对应抓包,以及设备分析。
此部分为比较偏硬件部分的数据通信,实际抓包一般为广播和数据报文,讲此部分是为了对主机层更好的理解,以及挑一些关键点出来讲解。
1. 物理层(PHY)
物理层包含用于调制和解调模拟信号并将其转换为数字符号的模拟通信电路。BLE可以通过2.4000 GHz至2.4835 GHz的40个信道进行通信。这些频道中的37个用于连接数据,最后三个频道(37、38和39)用作广播频道以建立连接并发送广播数据。BLE使用一种称为跳频扩频的技术,在该技术中,每次连接事件时,无线电都会在通道之间跳跃。建立连接时会传送跃点的值,因此对于每个新建立的连接,跃点的值都不同。该技术使任何无线电干扰的影响最小化。
2. 链接层(LL)
链路层是直接与物理层连接的部分,通常将其实现为自定义硬件和软件的组合。
查看上图,链路层介于主机和控制器之间,实际通信情况如下图:
设备内部也存在数据通信和各种数据控制、配置的命令,但是我们分析和测试的均为广播和两个设备之间的通信,内部数据无法抓取,但是其控制命令的解释大同小异,只是内部数据通信类型比起设备之前多了许多,可参考书中内容进行了解。
链路层根据逻辑组为其设备定义以下角色:
Advertiser -发送广播包的设备,
Scanner -扫描广播包的设备。
Master(Central)-启动连接并在以后进行管理的设备,
Slave(Peripheral)-接受连接请求并遵循主设备时间的设备。
链路层还负责蓝牙设备地址:一个48位数字,可唯一标识对等设备。 您可以将蓝牙设备地址视为类似于IP中的MAC地址。
链路层还负责建立连接, 它根据蓝牙地址或基于数据本身过滤掉广播数据包。并且还管理 连接间隔-两个连续的连接事件开始之间的时间。 链路层还可以配置加密,这在很多设备处于相同范围内的情况下非常需要。
报文
报文分为广播报文(3个广播信道)和数据报文(37个数据信道);
设备利用广播报文发现、连接其他设备;
建立连接后,用数据报文;
报文格式:
前导 | 接入地址 | 报头 | 长度 | 数据 | 循环冗余检验CRC |
8 | 32 | 8 | 8 | 0~296 | 24(比特) |
前导:
报文最开始的8比特是01010101,或者10101010序列,也就是55或者aa;(?与实际抓包和查看文档不符,BLE版本缘故?)
接入地址:
广播信道,接入地址固定,值为0x8E89BED6,传输时是低字节在前,看到的是D6BE898E;
数据信道为随机值,每次建立连接,固定一个值,所以无法根据接入地址来确定某个连接中是哪两个设备;
报头:
报头分为两种,广播报文和数据报文;
广播报文;
报头包含了广播报文的类型以及一些标记位,这些标记位指出报文使用的是公共地址还是随机地址等,Wireshark会自动识别;
ADV_IND | 通用广播指示 | 常见的广播形式 |
ADV_DIRECT_IND | 定向连接指示 | 广播数据中只包含两个必须的地址 |
ADV_NONCONN_IND | 不可连接指示 | 用于只广播数据但不被连接也不被扫描的设备 |
ADV_SCAN_IND | 可扫描指示 | 用于只广播数据,可被发现/扫描,但不被连接的设备 |
SCAN_REQ | 主动扫描请求 |
|
SCAN_RSP | 主动扫描响应 |
|
CONNECT_REQ | 连接请求 |
|
ADV_IND广播包
数据报文;
逻辑链路标识符(LLID)
当传输数据大于27字节时,需要分开传输,此时数据需要带有标识以用于数据拼接识别;
- 链路层控制报文(11)----用于管理连接
- 高层报文开始(10)----也可用于一个完整报文
- 高层报文延续(01)
序列号(SN)
第一个包的序号为0,第二个为1,后面新的数据包序列号需与上一个数据包的序列号不同,虽然只能为0或为1,但也可区分,以此让数据传输变得可靠。
下一个预期序列号(NESN)
用于数据包确认,通知对方自己期望接收的数据包的序列号。
更多数据(MD)
为1:通知对端设备,自己还有其他数据准备发送。
为0:相反。
可以看到Wireshark可以解析蓝牙的数据报文;
长度:
广播报文相对数据报文更长,多了广播设备地址;
数据:
净荷,“真实”数据;
CRC:
24位;
公式:
管理连接(理解为数据报文的类型)
Control Opcode: LL_CONNECTION_UPDATE_REQ |
连接参数更新 | 携带参数:
|
Control Opcode: LL_CHANNEL_MAP_REQ |
自适应调频 | 设备可以通过信令更改当前的信道图;
|
Control Opcode: LL_ENC_REQ LL_ENC_RSP |
启动加密 | 主-->从:LL_ENC_REQ,发送加密请求【包含4字节初始化向量(initialization vector),8字节会话密钥分散器(session key diversifier)】 从-->主:LL_ENC_RSP,回复加密响应消息【存在LTK(长期密钥)才可以加密】
后面还会有三次握手;而会话密钥的生成由LTK和会话密钥分散器来决定。 |
Control Opcode: LL_PAUSE_ENC_REQ LL_PAUSE_ENC_RSP |
重启加密 | 用于刷新会话密钥,比较少见; 主-->从,发送暂停加密请求; 从-->主,停止其应用数据,发送暂停加密响应,并停止接收加密的数据包; 主-->从,收到来自从的响应包后,回一个暂停加密的响应包;
此时,加密被禁用了,设备会重新发送加密请求,启动加密,从而刷新会话密钥。 |
Control Opcode: LL_VERSION_IND |
版本交换 | 为调试或解决问题用(可以理解,蓝牙设备为群居物种,若没有与任何人联系了,还是需要告知医生,你是什么形态)
|
Control Opcode: LL_FEATURE_REQ LL_FEATURE_RSP |
功能交换 | 对端设备利用功能信息来判断本端设备能做什么。 |
Control Opcode: LL_TERMINATE_IND |
终止连接 | 顾名思义 |
LL_LENGTH_RSP | 最大长度(实际抓包中还有这一种数据报文) | Wireshark也可解析他的意思。 |
下图为几个实际抓包;
版本交换
功能交换
主机控制器接口(HCI)
此处仅讲解一些概念,因为均为硬件内部数据通信和控制,数据的大体形式与上面展示差不多;
物理接口
- UART
- 3线UART
- USB
- SDIO
逻辑接口
信道
HIC信道
数据包格式
命令数据包
- 配置控制器的状态
- 请求执行特定的操作
- 管理连接
事件数据包
- 通用命令完成事件
- 通用命令状态事件
- 特定命令完成事件
流控
- 命令流控
- 数据流控
控制器配置
- 重置控制器为已知状态
- 读取设备地址
- 设置事件掩码
- 读取缓冲区大小
- 读取控制器支持的功能
- 读取控制器支持的状态
- 随机数
- 加密数据
- 设置随机地址
- 白名单
广播
- 可连接的非定向广播
- 可连接的定向广播
- 可扫描的非定向广播
- 不可连接的非定向广播
HCI广播流程
HCI被动扫描流程
HCI主动扫描流程
发起连接
- 与白名单设备发去连接
- 与单一设备发器连接
- 取消连接请求
连接管理
- 更新连接
- 更新信道映射图
- 交换功能列表
- 交换版本信息
- 加密连接
- 重启连接
- 终止连接
下图为设备打开蓝牙后,设备主机和控制器的一些配置通信;
此图的数据抓取非air抓包方式,后面会补充此种抓包方式;
事件分别为读取设备地址、设置事件掩码、读取缓冲区大小、读取控制器支持的功能、读取控制器支持的状态