复习一遍加深对整体的记忆。
1. PHY 层(Physicallayer 物理层)。PHY 层用来指定 BLE 所用的无线频段,调制解调方式和方法等。PHY 层直接决定整个 BLE 芯片的功耗,灵敏度以及 selectivity 等射频指标。
2. LL 层(LinkLayer 链路层)。LL 层是整个 BLE 协议栈的核心,也是 BLE 协议栈的难点和重点。LL 层要做的事情非常多,比如具体选择哪个射频通道进行通信,怎么识别空中数据包,具体在哪个时间点把数据包发送出去,怎么保证数据的完整性,ACK 如何接收,如何进行重传,以及如何对链路进行管理和控制等等。LL 层只负责把数据发出去或者收回来,对数据进行怎样的解析则交给上层处理。
3. HCI(Host controller interface)。HCI 是可选的,主要用于 2 颗芯片实现 BLE 协议栈的场合,用来规范两者之间的通信协议和通信命令等。
4. GAP 层(Generic access profile)。GAP 是对 LL 层有效数据进行解析的两种方式中的最简单的一种。GAP 简单的对 LL payload 进行一些规范和定义,能实现的功能极其有限,目前主要用来进行广播,扫描和发起连接等。
5. L2CAP 层(Logic link control and adaptation protocol)。L2CAP 对 LL 进行了一次简单封装,LL 只关心传输的数据本身,L2CAP 主要区分是加密通道还是普通通道,同时还要对连接间隔进行管理。
6. SMP(Secure manager protocol)。SMP 用来管理 BLE 连接的加密和安全。
7. ATT(Attribute protocol)。简单来说,ATT 层用来定义用户命令及命令操作的数据。BLE 协议栈中,开发者接触最多的就是 ATT。BLE 引入了 attribute 概念,用来描述一条一条的数据。Attribute 除了定义数据,同时定义该数据可以使用的 ATT 命令,因此这一层被称为 ATT 层。
8. GATT(Generic attribute profile )。GATT 用来规范 attribute 中的数据内容,并运用 group(分组)的概念对 attribute 进行分类管理。没有 GATT,BLE 协议栈也能跑,但互联互通就会出问题,也正是因为有了 GATT 和各种各样的应用 profile,BLE 摆脱了 ZigBee 等无线协议的兼容性困境。
L2CAP信道标示符(L2CAP Channel)
低功耗蓝牙使用了3条信道,0x0004用于属性协议(ATT);0x0005用于低功耗信令信道;0x0006为安全管理协议(SM);
长度 |
信道标示符 |
playload信息载荷 |
2 |
2 |
0~65535字节 |
playload信息载荷命令数据包结构
操作码 |
标示符 |
长度 |
参数 |
1 |
1 |
2 |
|
低功耗信令信道支持的命令操作吗如下:
书中关于操作码的类型没有做介绍,通过抓包来看,部分使用的是保留部分的CID,数据不可解。
ATT,Attribute Protocol,用于发现、读、写对端设备的协议(针对BLE设备)
ATT允许设备作为服务端提供拥有关联值的属性集,让作为客户端的设备来发现、读、写这些属性;同时服务端能主动通知客户端。
ATT定义了两种角色: 服务端(Server)和客户端(Client)
什么意思?
提供数据的为服务端,使用数据的为客户端,以传感器类举例较好理解。
引申~~若存在数据由手机去生成,设备由手机去操作的场景,如何保证安全性?
ATT中的属性包含下面三个内容
2字节 |
2或6字节 |
0~512字节 |
属性句柄 |
属性类型 |
属性值 |
属性句柄,是由Server分配的一个唯一且非零16-bit值,有效句柄范围0x0001~0xffff,0x0000为无效句柄;
作用:用来访问Attribute Value
为了区分数据类型,定义了一个128位的唯一标识码,通用唯一识别码(UUID),如下
0000xxxx-0000-1000-8000-00805F9B34FB;
为了提高效率,仅使用其中16-bit,也就是xxxx部分,其余部分接收方收到后补上即可;
其中xxxx部分分组如下:
Attribute Value是一个八位组(长度为8或可变)
当属性值太长时,可通过多个PDUs发送
而client通过使用ATT PDUs(Protocol Data Unit)来发现Attribute Handle;
- Requests : Client->Server, 请求回应
- Responses : Server->Client, 响应请求.
- Commands : Client->Server, 命令
- Notifications : Server->Client, 服务端通知
- Indications : Server->Client, 请求确认
- Confirmations : Client->Server, Ind确认
名称 |
大小 |
描述 |
Attribute Opcode |
8位 |
属性PDU操作码 0 ~ 5位:Method 6位:Command Flag 标志位为1:PDU为一个Command; 7位:Authentication Signature Flag 标志位为1:PDU包含Authentication Signatur,X = 13; 标志位为0:X = 1; |
Attribute Parameters |
0 ~ (ATT_MTU - X) |
属性PDU参数 X = 1 如果Authentication Signature Flag = 0 X = 13 如果Authentication Signature Flag = 1 |
Authentication Signature |
0 or 12 |
认证签名 |
实例:
操作码 (Attribute Opcode) |
操作码含义 |
其他参数描述 |
0x01 |
Erroe Response:用来声明一个给定的请求无法完成,并给出原因。 |
Request Opcode In Error:生成错误响应的请求 Attribute Handle In Error:错误响应请求的属性句柄 Error Code : 错误原因,含义参考下表 |
0x02 |
Exchange MTU Request: Client使用MTU Exchange Request来告知所支持的最大接收MTU size; 同时请求Server回应Server所支持的最大接收MTU size。 |
Client Rx MTU:该请求在一个连接中仅发送一次, Client Rx MTU应当设置为Client所能接收ATT PDU的最大值。 |
0x03 |
Exchange MTU Response |
Server Rx MTU: Server Rx MTU>= default ATT_MTU;Server Rx MTU应当设置为Server所能接收ATT PDU的最大值; 当完成Req-Rsp后,Server和Client将ATT_MTU均设置为Client Rx MTU和Server Rx MTU中的较小值。 |
0x04 |
Find Information Request: 被用来获取与Attribute Handles相关联的类型; Client使用该请求来发现Server上的Attribute-Type列表。 |
Starting Handle:起始标志位,或者说被response返回时带上该值以匹配 Ending Handle:结束。 |
0x05 |
Find Information Response |
Format:数据格式; Information Data:数据。 |
0x06 |
Find By Type Value Request |
Starting Handle: Ending Handle: Attribute Type:对应2位的属性类型 Attribute Value:0~(ATT_MTU - 7)的属性值 |
0x07 |
Find by Type Value Response |
Handles Information List:1 ~ (ATT_MTU - 1)至少1位的句柄信息 |
0x08 |
Read By Type Request:用来获取Attribute Values(Client已知Attribute Type但不知Attribute Handle); |
Starting Handle: Ending Handle: Attribute Type: |
0x09 |
Read By Type Response |
Length:长度; Attribute Data List:2~ (ATT_MTU - 2)位的属性数据; |
0x0A |
Read Request:用来请求Attribute Value |
Attribute Handle:应该为一个有效的Handle;因安全问题无法访问的回应同Read By Type Request |
0x0B |
Read Response |
Attribute Value:0~(ATT_MTU - 1)位的属性数据; |
0x0C |
Read Blob Request:当数据长度超过时,Client发起Read Blob Request来获取剩下数据; |
Attribute Handle: Value Offset:偏移值; |
0x0D |
Read Blob Response |
Part Attribute Value:剩下的0~(ATT_MTU - 1)位的属性数据 |
0x0E |
Read Multiple Request:用来请求两个或更多的属性集的值 |
Set Of Values:4~(ATT_MTU - 1)设置两个或者更多的属性句柄 |
0x0F |
Read Multiple Response |
Set Of Values:0~(ATT_MTU - 1)设置两个或者更多的值 |
0x10 |
Read by Group Type Request:用来请求已知Attribute Type的属性值 |
Starting Handle: Ending Handle: Attribute Group Type:2 或者16位的UUID |
0x11 |
Read by Group Type Response |
Length: Attribute Data List:2~ (ATT_MTU - 2)位的属性数据; |
0x12 |
Write Request:用来写属性值 |
Attribute Handle: Attribute Value:0~ (ATT_MTU - 3)被写入的属性值 |
0x13 |
Write Response:用来通知Client属性值已成功写入 |
|
0x14 |
Write Command:用来写属性值,通常为Control-Point Attribute |
Attribute Handle: Attribute Value:0~ (ATT_MTU - 3)被写入的属性值 |
0x15 |
Signed Write Command:用来写属性值,包含一个Authentication Signature,通常为Control-Point Attribute |
Attribute Handle: Attribute Value:0~ (ATT_MTU - 3)被写入的属性值 |
0x16 |
Prepare Write Request:将多个属性值写操作以FIFO方式入队,然后再一个原子操作中进行 |
Attribute Handle: Value Offset: Part Attribute Value:0~ (ATT_MTU - 5)被写入的属性值 |
0x17 |
Prepare Write Response |
Attribute Handle: Value Offset: +Part Attribute Value:0~ (ATT_MTU - 5)被写入的属性值 |
0x18 |
Execute Write Request |
Flags:0x00--取消所有准备写入; 0x01--马上写入所有正在准备的值; |
0x19 |
Execute Write Response::用来通知Client属性值已成功写入 |
|
0x1B |
Handle Value Notification:Server可以在任何时候向Client发送Attribute Value的通知 |
Attribute Handle: Attribute Value:0~ (ATT_MTU - 3)目前属性的值 |
0x1D |
Handle Value Indication:Server可以发送Attribute Value的指示(Indication) |
Attribute Handle: Attribute Value:0~ (ATT_MTU - 3)目前属性的值 |
0x1E |
Handle Value Confirmation:用来回应Handle Value Indication,确认Ind已接收 |
|
Error Code
名称 |
Error Code |
描述 |
Invalid Handle |
0x01 |
无效句柄 |
Read Not Permitted |
0x02 |
不允许读取 |
Write Not Permitted |
0x03 |
不允许写入 |
Invalid PDU |
0x04 |
PDU无效 |
Insufficient Authentication |
0x05 |
认证不足 |
Request Not Supported |
0x06 |
请求不支持 |
Invalid offset |
0x07 |
偏移量无效 |
Insufficient Authorization |
0x08 |
授权不足 |
Prepare Queue Full |
0x09 |
准备队列已满 |
Attribute Not Found |
0x0A |
属性不存在 |
Attribute Not Long |
0x0B |
属性非大对象 |
Insufficient Encryption Key Size |
0x0C |
密钥长度不足 |
Invalid Attribute Value Length |
0x0D |
属性长度无效 |
Unlikely Error |
0x0E |
未知错误 |
Insufficient Encryption |
0x0F |
加密不足 |
Unsupported Group Type |
0x10 |
组类型不支持 |
Insufficient Resources |
0x11 |
资源不足 |
Reserved |
0x12 ~ 0x7F |
预留 |
Application Error |
0x80 ~ 0xFF |
应用错误 |
!重点分析的数据包;
定义了如何发现与使用服务、特性与描述符的标志方法;
属性协议数据单元(ATT PDU)到GATT规程的映射
ATT PDU |
GATT Definition |
Exchange MTU Request:交换MTU请求 |
交换MTU规程 |
Find Information Request:查找信息请求 |
发现所有特性描述符规程 |
Find By Type Value Request:按类型值查找请求 |
按服务UUID发现首要服务规程 |
Read By Type Request:按类型读取请求 |
查找包含服务, 发现所有服务特性, 按UUID发现特性, 按特性UUID读取规程 |
Read Request:读取请求 |
读取特性值, 读取特性描述符规程 |
Read Blob Request:大对象读取请求 |
读取长特性值, 读取长特性描述符规程 |
Read Multiple Request:多重读取请求 |
读取多重特性描述符规程 |
Read by Group Type Request:按组类型读取请求 |
发现所有首要服务规程 |
Write Request:写入请求 |
写入特性值, 写入特性描述符规程 |
Write Command:写入命令 |
无需响应写入规程 |
Signed Write Command:签名写入命令 |
无需响应的签名写入规程 |
Prepare Write Request:准备写入请求, Execute Write Request:执行写入请求 |
写入长特性值, 特性值可靠写入, 写入长特性描述符规程 |
Handle Value Notification:句柄值通知 |
通知规程 |
Handle Value Indication:句柄值指示 |
指示规程 |
后面两种可以当作对低功耗蓝牙的工作模式、工作状态来理解。
关于SM,没有找到详细资料,书中的介绍也比较少,仅讲解简单概念。
初始认证和密钥共享
使用预先共享的密钥重新认证
文档提供授权
直接进行授权
低功耗蓝牙的五个密钥:
配对信息交换
链路认证
密钥分配
1.在绑定时保存IRK密钥;
2.使用该密钥生成一个可解析的私有地址;
3.主设备扫描所有设备,利用其所有的IRK解析每一个地址,通过验证即可进行连接。
广播者
观察者
外围设备-Slave
中央设备-Master
广播模式
不可发现模式
有限可发现模式
一般可发现模式
不可连接模式
定向可连接模式
无向可连接模式
不可绑定模式
可绑定模式
观察规程
有限发现规程
一般发现规程
名称发现规程
自动连接建立规程
一般连接建立规程
选择性连接建立规程
直接连接建立规程
连接参数更新规程
终止连接规程
绑定规程
等级1:无安全性
等级2:带加密的未认证配对
等级3:带加密的认证配对
等级4:带数据签名的未认证配对
等级5:带数据签名的认证配对
设备名
外观
外围设备隐私标识
重连地址
外围设备首选连接参数
参考:《低功耗蓝牙开发权威指南》