广播态:
LSB | MSB | ||||||||||
链路层帧(10-47 Octet) | |||||||||||
Preamble | Access Address | PDU (2-39 Octet) | CRC | ||||||||
PDU type | RFU | TxAdd | RxAdd | length | RFU | 广播的数据(0-37 Octet) | |||||
AdvA | 0-31 byte | ||||||||||
1 Octet | 4 Octet | 4 bit | 2 bit | 1 bit | 1 bit | 6 bit | 2bit | 6 bytet | 3 Octet |
preamble = 10101010 or 01010101
Access Address = 0x8e89bedd6
PDU type: 1)0000 - connected undirected advertising event 可连接非定向广播事件 2)0001 - connected directed advertising event 可连接定向广播事件 3)0010 - non-connected undirected advertising event 不可连接非定向广播事件 4)0011 - response to scan request form scanner扫描请求响应 5)0101 - connect request by initiator连接请求 6)0110 -connected directed advertising event 可发现非定向广播事件 | |||
非定向广播包(Undirected advertising packets) | 定向广播包(Directed advertising packets | ||
AdvA (6 Bytes) | AdvData (31 Bytes max.) | AdvA (6 Bytes) | InitA(6 Bytes) |
AdvA contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0 | AdvData advertising data | AdvA contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0; | InitA contains initiator's address if RxAdd = 1, or a random address if RxAdd = 0; |
PDU type: 1)0011 - scan request for further information from advertiser 扫描请求 2)0100 - response to scan request from scanner 扫描响应 | |||
扫描请求 | 扫描响应 | ||
ScanA (6 Bytes) | AdvA(6 Bytes) | AdvA(6 Bytes) | ScanRspData(0~31Bytes) |
ScanA contains Scanner's public address if TxAdd = 1, or a random address if TxAdd = 0; | AdvA contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0; | ScanRspData data from advertiser’s host; | AdvA contains advertiser‘s public address if TxAdd = 1, or a random address if TxAdd = 0; |
PDU type: 0101 - connect request by initiator | ||
连接请求 | ||
InitA(6 Bytes) | AdvA(6bytes) | LLData(22 Bytes) |
连接态:(非链路层控制报文)
LSB | MSB | |||||||||||||||
链路层帧(10-41 Octet) | ||||||||||||||||
Preamble | Access Address | PDU (2-33 Octet) | CRC | |||||||||||||
LLID | NESN | SN | MD | RFU | length | RFU | L2CAP层(0-27 Octet) | MIC | ||||||||
length | Channel ID | ATT_MTU=23协议帧(0-23 Octet) | ||||||||||||||
attribute opcode | attribute handle | attribute Value | ||||||||||||||
1 Octet | 4 Octet | 2bit | 1bit | 1bit | 1bit | 3bit | 5bit | 3bit | 2 byte | 2 byte | 1 byte | 2 byte | 0-(MTU-3) | 4 byte | 3 Octet |
MIC为4字节,只有在链路加密的情况下才会存在,为 消息完整性校验,防止消息被篡改。PS:加密链路中的空包不会存在MIC
1字节opcode用来指示 write,notify,indication
2字节handle为句柄用来标识是操作哪个特性值的。
规范中默认这个MTU最大为23字节,这个值其实是可以通过命令来协商的
Host层的GAP(通用访问协议)
l 负责:连接前数据广播
l 本层有定义了4种不同类型的广播(gap.h):
1. 通用的:GAP_ADTYPE_ADV_IND (可被扫描,可被连接)
2. 定向的:GAP_ADTYPE_ADV_DIRECT_IND (不可被扫描,可被连接)
3. 不可连接的:GAP_ADTYPE_ADV_DISCOVER_IND (可被扫描,不可被连接)
4. 可发现的:GAP_ADTYPE_ADV_NONCONN_IND (不可被扫描,不可被连接)
通用广播:通用广播是用途最广的广播方式。进行通用广播的设备能够被扫描设备扫描到,或者在接收到连接请求时作为从设备进入一个连接。通用广播可以在没有连接的情况下发出,换句话说,没有主从设备之分。
定向广播:有时候,设备间需要快速建立连接。如果从设备想这么做,就需要进行广播。定向广播事件就是为了尽可能快的建立连接。这种报文包含两个地址:广播者的地址和发起者的地址。发起设备收到发绐自己的定向广播报文后,可以立即发送连接请求作为回应。
不可连接广播:不想被连接的设备使用不可连接广播事件。这种广播的典型应用包括设备只想广播数据,而不想被扫描或者连接。也是唯一可用于只有发射机而没有接收机设备的广播类型。不可连接广播设备不会进入连接态,因此,它只能根据主机的要求在广播态和就绪态之间切换。
可发现广播:最后一种广播事件是可发现广播。这种广播不能用于发起连接,但允许其他设备扫描该广播设备。这意味着该设备可以被发现,既可以广播数据,又可以响应扫描,但不能建立连接。这是一种适用于广播数据的广播形式,动态数据可以包含于广播数据之中,而静态数据可以包含于扫描响应数据之中。可发现广播不会进入连接态,而只能在停止后回到就绪态。
协议规定,payload 最大 27。剩下的就 23 个字节 MTU。就是你看到的。就剩下 20了。这剩下的 20 字节就是我们常说的发送的 20 字节的数据。
payload 最大 27 | |||
L2CAP | 23 个字节 MTU | ||
ATT 层op code | ATT 层attribute handle | 可用 | |
4 个字节 | 1 个字 | 2 个字节 | 20byte |
上面是蓝牙协议 4.0 中的内容。所以这个 MTU 是不少于 23,也是可以修改的,但是前提是 client 支持修改 MTU,如果 client 只支持 Default Value,那就不能修改。如果一个设备既有 client 又有 server,那么 client Rx MTU 和 server Rx MTU 必须是一样的。
但是这个修改我不确定是不是 BLE 的特性,问了 TI 的人,给的回答是 BLE 允许修改 MTU 是蓝牙 4.1 的新特性,姑且相信他吧。
广播PDU格式:
无方向广播包:
PDU Type = ADV_IND类型的:PDU解析
协议数据单元PDU | ||||||
Header(16bits) | Payload=advA(6byte)+advdata(0-31byte) | |||||
PDU Type (4 bits)
| RFU (2 bits)
| TxAdd (1 bit) | RxAdd (1 bit) | Length (6 bits) | RFU (2 bits) | Payload (长度由Header中的“Length”字段决定) |
指示PDU(协议数据单元)的类型 | reserved | 由具体的PDU Type决定 | 由具体的PDU Type决定 | PDU的长度 | reserved | XXX |
0 | / | 0 | 0 | 13 | / |
|
32 octets(octet专指8 bits构成的字节) | 说明 | |||
有效数据部分 significant | 长度 Len (1 octes) | Data (len octes) | / | |
AD Type(n )AD Type.c | AD data(len-n) | / | ||
表示这个 AD Structure 的长度(除去 len本身 1) | 标记这段广播数据代表什么, 比如设备名, uuid | 数据 | / | |
02 | 01 | 06 | 广播数据单元1 AD Structure | |
03 | 02 | F0 FF | 广播数据单元2 AD Structure | |
。。。 | 。。。 | 。。。 | 广播数据单元n AD Structure | |
无效数据 non-significant | 补充 0;到32octets | / |
扫描请求包和扫描回应包分析:
扫描请求包:
扫描回应广播包:
连接请求和回应包:
Host层的GATT(通用属性协议)
l 负责:连接后的数据传输。在属性协议(ATT)的基础上构建,为属性协议传输和存储数据建立了一些通用操作和框架。
l 本层有定义两个角色:服务器和客户端
l GATT的角色并不一定与特定的GAP角色有关联,但可能由更高层级的配置文件指定。
l GATT和ATT不是传输专用,也可以用于BR/EDR和低耗能。但是,由于GATT和ATT用作发现服务,故必须在低耗能技术中实施。
l GATT服务器存储通过属性协议传输的数据,并接受GATT客户端发出的属性协议请求、指令及确认。
参考:BLE]低功耗蓝牙之GAP、GATT: