广播态:
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:http://blog.csdn.net/qq_21842557/article/details/50771077