BLE 链路层(LL)的数据结构

一 链路层的数据结构

在链路层上传输的数据格式如下图所示:
BLE 链路层(LL)的数据结构_第1张图片
广播报文和数据报文都包含 Preamble(前导码), AccessAddress(接入地址),PDU(数据),CRC。其中Constant Tone Extension是可选的。

  • 前导码
  • 接入地址
  • PDU
    • Header
    • Length
    • payload
    • MIC(可选)
  • CRC
  • Constant Tone Extension(可选)

1 前导码

报文最开始的8bit是01010101(0x55)或者10101010(0xAA)。这是很简单的交替序列。接收机可以用它来配置自动增益控制,以及确定 “0”、"1"比特所使用的的频率。

这段序列之所以非常重要,是因为芯片必须能够应对输入信号强度的可能范围。接收机需要应付 -10dBm到-90dBm的信号强度,也就是80dB的动态范围。从接收机的角度讲,也就是1pW到0.1pW的能量。自动增益控制器必须检测出输入信号的能量等级,并调整增益,使得信号刚好处于接收机能够轻容工作的范围之中。

2M PHY的前导码为2个字节

2 接入地址(Access Address)

接入地址的第一个比特决定了前导是01010101还是10101010。如果接入地址的第一个比特为0,则使用01010101序列;如果是1则使用10101010序列。这保证了任一报文的前9个比特都是交替的,即要么为101010101要么为010101010。

LL层使用接入地址来区分当前发送的数据是广播包还是数据包,广播包接入地址固定为0x8E89BED6,数据包使用是在连接时生成的接入地址。

  • 连接时主设备分配一个32位的随机数并发送给从设备,这就是接入地址。
  • 接入地址被用来表示一个连接,在连接期间保持不变。
  • 对于同一个从设备,断开从新连接接入地址也会重新生成。

3 数据(PDU)

根据使用的通道不同可以分为广播报文数据报文。广播报文在广播通道上传输(37, 38, 39), 数据报文在数据通道上传输(0到36)。

二 广播通道上的PDU

广播通道上的PDU格式:
BLE 链路层(LL)的数据结构_第2张图片

  • 两个字节的header
  • 1到255字节数据

广播通道上的Header格式
BLE 链路层(LL)的数据结构_第3张图片

  • PDU Type(4bit) 广播报文类型
  • RFU(1bit) 未使用
  • ChSel(1bit) 未使用
  • TxAdd(1bit) 发送地址类型
    • 0: public地址
    • 1: 随机地址
      • 静态随机地址,地址最高两位为11
      • 私有随机地址
        • 不可解析私有随机地址,地址的最高两位为00
        • 可解析私有随机地址,地址的最高两位为1(最高位)0(次高位)
  • RxAdd(1bit) 接收地址类型,规则和TxAdd一样
  • length(8bit),长度,取值范围1到255

1 广播报文的类型

BLE 链路层(LL)的数据结构_第4张图片

  • ADV_IND,通用广播,外设发出的一般称为通用广播,广播中包含mac地址设备名字等信息。
  • ADV_DERECT_IND,定向广播,某个外设在工作的时候就希望某个主设备来连接它,就可以向这个中央设备发起一个定向广播。
  • ADV_NONCONN_IND,不可连接的广播,比如货架上的广告机,会不断的向外发送广播信息。
  • ADV_SCAN_IND,可发现广播,包含了比通用广播更加丰富的信息。
  • SCAN_REQ,扫描请求,当中央设备发现通用广播中包含的信息并不全,这个时候主设备可以发一个扫描请求。
  • SCAN_RSP,外设响应主设备的扫描请求,返回给中央设备更多的信息。
  • CONNECT_REQ,连接请求,当主设备得到足够的信息之后就可以发送一个连接请求。来建立连接。
  • ADV_EXT_IND, 通用扩展广播
  • AUX 开头的广播类型和ADV_EXT_IND是蓝牙5.0新引入的,暂且不表。

2 广播通道上的报文

2.1 ADV_IND 通用广播

BLE 链路层(LL)的数据结构_第5张图片

  • AdvA, 6个字节广播者的mac地址
  • 最多31个字节的广播数据, AdvData来自上层

通用广播是用途最广的广播方式。进行通用广播的设备能够被扫描设备扫描到,或者在接收到连接请求时作为从设备进入连接态。

2.2 ADV_DERECT_IND 定向广播

BLE 链路层(LL)的数据结构_第6张图片

  • AdvA, 6字节的广播者地址
  • TargetA,接收广播者的地址

有时候,设备间需要快速建立连接。如果从设备想这么做,就需要进行广播。定向广播事件就是为了尽可能快的建立连接。这种报文只能包含两个地址,广播者和发起者的地址。发起设备收到发给自己的定向广播报文后,可以立即发送连接请求作为回应。
定向广播有特殊的时序要求。完整的广播事件必须每3.75ms重发一次。这一要求使得扫描设备只需要扫描3.75ms便可收到定向广播设备的消息。定向广播不可以持续1.28s以上的时间。
当使用定向广播时,设备不能被主动发现。

该报文不包含任何上层数据

2.3 ADV_NONCONN_IND 不可连接的广播

BLE 链路层(LL)的数据结构_第7张图片

  • AdvA, 6个字节广播者的mac地址
  • 最多31个字节的广播数据, AdvData来自上层

不想被连接的设备使用不可连接广播。这种广播的典型应用包括设备只想广播数据,而不想被扫描或者连接。不可连接广播不会进入连接态,只能在就绪态和广播态之间进行切换。

2.4 ADV_SCAN_IND 可发现广播

BLE 链路层(LL)的数据结构_第8张图片

  • AdvA, 6个字节广播者的mac地址
  • 最多31个字节的广播数据, AdvData来自上层

可发现广播允许其他设备扫描该设备,但是不能进入连接态。这意味着该设备可以被发现,既可以广播数据,又可以响应扫描,但不能建立连接。这是一种适用于广播数据的广播形式,动态数据可以包含在广播数据中,而静态数据可以包含于扫描响应数据中。

2.5 SCAN_REQ 扫描请求

BLE 链路层(LL)的数据结构_第9张图片

  • ScanA, 请求者的地址
  • AdvA, 广播者地址

2.6 SCAN_RSP 扫描响应

BLE 链路层(LL)的数据结构_第10张图片

  • AdvA, 广播者的地址
  • ScanRspData, 来自上层的扫描数据

2.7 CONNECT_REQ 连接请求

连接过程
BLE 链路层(LL)的数据结构_第11张图片

连接请求的数据包
BLE 链路层(LL)的数据结构_第12张图片
BLE 链路层(LL)的数据结构_第13张图片

  • InitA: 发起连接者的mac地址,BLE的MAC地址,随机地址的最高两位应该为11b
  • AdvA: 广播者的地址mac地址
  • AA: 接入地址。LL层使用接入地址来区分当前发送的数据是广播包还是数据包,广播包接入地址固定为0x8E89BED6,数据包使用就是该值。
  • CRCInit(CRC initialization value): CRC初始值,主设备提供的一个随机数,防止多个连接AA相同。
  • WinSize(transmitWindowSize): 发送窗口大小, 单位是1.25ms
  • WinOffset(transmitWindowOffset): 发送窗口偏移, 单位是1.25ms
  • Interval(connInterval): 连接间隔 单位是1.25ms
  • Latency(connSlaveLatency): 从设备延时,表示从设备可以跳过多少个连接事件。
  • Timeout(connSupervisionTimeout): 监控超时。单位是ms
  • ChM(Channel Map): 信道图,表示当前环境中哪一个信道可用,每一个bit表示一个信道1表示可用,0表示不可用。比如ff ff ff ff 1f(0x1fffffffff), 二进制为0001111111111111111111111111111111111111b
  • Hop(hopIncrement): 跳频算法的hop值,比如110b, 6
  • masterSCA: 00100b, 休眠时钟精度, 151 ppm to 250 ppm

三 数据通道上的报文

数据通道上的报文格式:
BLE 链路层(LL)的数据结构_第14张图片
数据通道上的Header格式:
BLE 链路层(LL)的数据结构_第15张图片

BLE 链路层(LL)的数据结构_第16张图片

  • LLID(2bit),逻辑链路标识符,用来判断数据报文属于下列哪种类型
    • 0b00, 保留
    • 0b01, 来自L2CAP的延续帧,或者是一个空包。
    • 0b10, 来自L2CAP的开始帧,或者是一个完整的报文。
    • 0b11, 控制报文。
    • 链路层控制报文(11),用来管理连接,
    • 高层报文开始(10),也可用于一个完整的报文
    • 高层报文延续(01),也可以是一个空包
  • NESN(1bit),预期序列号
  • SN(1bit),序列号
  • MD(1bit),更多数据
  • CP(1bit),是否包含CTEinfo
  • RFU(3bit),保留
  • length(8bit),长度
  • CTEinfo(8bit), 指明Constant Tone Extension的类型和长度
  • payload,数据,长度为0到251字节,
  • MIC,消息完整性校验,4个字节,可选

为了使数据传输变得可靠,所有的数据均带有序列号(SN)。连接建立之后,第一个数据包的SN为0;每次发送新的数据包时,其SN与上一个数据包的SN不同。这使得接收方能够判断接收数据包的性质: 如果SN与之前的一样,接收方认为该报文为重传报文,如果SN和上一个数据包的SN不同,则认为是新报文。
数据包的确认还需要用到另外一个比特,预期序列号(NESN)。NESN的发送方用其通知对方字节预期接收的数据包的SN。
如果设备成功接收SN为0的报文,在其确认报文中,应该将NESN设为1,向对方表明自己希望下一个数据包的SN为1,如果不讲NESN设置为1,那么发送方就认为从设备没有成功接收到自己的报文,将进行重传。因此NESN作为一个标志来判断数据包是否被正确接收还是需要重传。
数据信道报文的Header里还有一个更多数据位(MD), 用来通知对端设备自己还有其它的数据准备发送。如果收到设置了MD位的数据包,应该在当前连接事件中继续与对端设备通信。这样一来,只要还有数据要发送,连接事件就会自动扩展;一旦不再有数据发送,连接事件会迅速关闭。如果把MD设置为0,设备可以快速、优雅的结束连接事件,从而节省能量。
另外,NESN还可以用来进行流量控制。设备一旦没有足够的缓存空间来处理消息,可以不更新NESN。这迫使对端设备重新发送当前消息,从而把对缓存的要求从接收端转嫁到发送端。

下面是一个具体的例子:
BLE 链路层(LL)的数据结构_第17张图片

  1. 主设备发送第一包数据(SN=0,NESN=0,MD=1)
  2. 从设备接收到之后回复(SN=0,NESN=1,MD=1),但是这一包数据主设备没有收到。
  3. 主设备没有收到从设备的回复,因此重传这一包数据(SN=0,NESN=0,MD=01
  4. 从设备回复(SN=0,NESN=1,MD=1)
  5. 主设备收到从设备的回复,开始发送下一包数据(SN=1,NESN=1,MD=0)
  6. 从设备回复(SN=1,NESN=0,MD=0)
  7. 主设备收到从设备的回复,结束当前的连接事件。注意上述过程都在同一个连接事件内完成的。
  8. 在下一个连接事件中,主设备有数据需要发送(SN=0,NESN=0,MD=0)
  9. 从设备回复(SN=0,NESN=1,MD=0)
  10. 主设备收到从设备回复,结束当前连接事件。

3.1 数据报文

LLID为0b01或者0b10。

Header 中的 LLID 字段设置为 0b01,长度字段设置为 0b00000000 被称为空 PDU。 主机的链路层可以向从机发送一个空的 PDU,以允许从机响应任何数据的 PDU,包括一个空的 PDU。
如果LLID字段为0b10,长度字段不应该被设置为0b00000000。

如果链路层接收到 Data_Total_Length 等于 0b00000000 且 Packet_Boundary_Flag 设置为 0b00(即开始片段)的 HCI ACL 数据包,则链路层不能简单地通过空中传输该片段,而是必须将其与一个或 更多的以下延续片段形成一个 PDU,LLID 设置为 0b10 和非零长度。

数据报文的Payload来自上层。

3.2 控制报文

控制报文是用来控制连接链路的。

数据格式如下:
BLE 链路层(LL)的数据结构_第18张图片

  • Opcode,操作码,1个字节
  • CTRData,控制数据,0到250个字节

控制报文中的 CtrData 字段由操作码字段指定。 对于给定的操作码,CtrData 字段的长度是固定的。

操作码类型如下(详细信息参看: 核心卷,vol6, PartB, 2.4.2):
BLE 链路层(LL)的数据结构_第19张图片
如果接收到不支持控制报文或保留供将来使用的报文,则链路层应以 LL_UNKNOWN_RSP PDU 进行响应。 LL_UNKNOWN_RSP PDU 的 UnknownType 字段应设置为接收到的 PDU 中操作码的值。

LL_UNKNOWN_RSP 的CtrData数据格式:
BLE 链路层(LL)的数据结构_第20张图片

如果接收到的控制报文长度错误或 CtrData 字段无效,链路层可以继续执行该命令,并对数据进行特定于实现的解释(例如,如果PDU太长,它可以忽略额外数据;如果字段超出范围,则可以使用最接近的允许值)。 如果它不继续该规程,它应以LL_UNKNOWN_RSP PDU响应,或者,如果相关规程允许,则响应 LL_REJECT_IND 或 LL_REJECT_EXT_IND PDU。 LL_UNKNOWN_RSP PDU 的 UnknownType 字段或 LL_REJECT_EXT_IND PDU 的 RejectOpcode 字段应设置为接收到的 PDU 中的 Opcode 值。

LL_REJECT_IND的CtrData数据格式:
BLE 链路层(LL)的数据结构_第21张图片
LL_REJECT_EXT_IND 的CtrData数据格式:
BLE 链路层(LL)的数据结构_第22张图片

你可能感兴趣的:(BLE,BLE,链路层,数据结构,物联网,嵌入式)