LinkLayer(LL) 位于最底层,负责广播通信有关功能的定义和实现,包括物理通道的选择、相关的链路状态的定义、PDU的定义、设备过滤(Device Filtering)机制的实现等。
HCI负责将LL提供的所有功能,以Command/Event的形式抽象出来,供上层使用。
GAP负责从应用程序的角度,抽象并封装LL提供的功能,以便让应用以比较傻瓜的方式进行广播通信。
3.3 Link Layer
3.3.1 状态定义
从LL层看,参与广播通信的BLE设备,可有三种状态:
Advertising,数据发送方,周期性的发送广播数据;
Scanning,数据接收方,扫描、接收广播数据;
Initiating,连接发起方,扫描带有“可连接”标志的广播数据,一旦发现,则发起连接请求(都是由Link Layer自动完成,不需要上层软件参与)。
3.3.2 PDU
处于不同状态的BLE设备可以发送不同类型的PDU数据。
PDU格式:(具体每个字段的意义如图所标)
图6 pdu格式
PDU类型:
图7 PDU类型
举例:
1)如果只需要定时传输一些简单的数据(如某一个温度节点的温度信息),后续不需要建立连接,则可以使用ADV_NONCONN_IND。广播者只需要周期性的广播该类型的PDU即可,接收者按照自己的策略扫描、接收,二者不需要任何额外的数据交互。
2)如果除了广播数据之外,还有一些额外的数据需要传输,由于种种原因,如广播数据的长度限制、私密要求等,可以使用ADV_SCAN_IND。广播者在周期性广播的同时,会监听SCAN_REQ请求。接收者在接收到广播数据之后,可以通过SCAN_REQ PDU,请求更多的数据。
3)如果后续需要建立点对点的连接,则可使用ADV_IND。广播者在周期性广播的同时,会监听CONNECT_REQ请求。接收者在接收到广播数据之后,可以通过CONNECT_REQ PDU,请求建立连接。
4)通过ADV_IND/CONNECT_REQ的组合建立连接,花费的时间比较长。如果双方不关心广播数据,而只是想快速建立连接,恰好如果连接发起者又知道对方(广播者)的蓝牙地址(如通过扫码的方式获取),则可以通过ADV_DIRECT_IND/CONNECT_REQ的方式。
3.3.3 Advertising状态
BLE使用40个RF Channel(前文有述)中的3个作为广播信道,信道频段信息等如下:
图8 广播信道
BLE设备处于Advertising状态的目的,就是要广播数据。并且,根据应用场景的不同,可在3个channel上广播4种类型的数据。
BLE协议对广播通信的期望,是非常明确的,不在乎速率、只在乎功耗。对于连接来说,如果事先不知道连接发起者的设备地址,则最快的连接速度可能是20ms。如果事先知道地址,则可能在3.75ms内建立连接。由此可以看出,BLE的连接建立时间,比传统蓝牙少了很多,这也是BLE设备之间不需要保持连接的原因。
3.3.4 Scanning状态
scanWindow指示一次扫描的时间,scanInterval指示两次扫描之间的间隔。如果这两个参数的值相同,表示连续不停地扫描。Scanning的扫描就是由 scanWindow和scanInterval两个参数决定的。
BLE协议规定,scanWindow和scanInterval最大不能超过10.24s,并且scanWindow不能大于scanInterval。
Passive Scanning和Active Scanning
Passive Scanning称作消极的扫描,是因为这种扫描模式下,BLE设备只听不问,也就是说,只接收ADV_DIRECT_IND、ADV_IND、ADV_SCAN_IND、ADV_NONCONN_IND等类型的PDU,并不发送SCAN_REQ。而Active Scanning,不只认真听讲,还勤于发问(SCAN_REQ),并接收后续的 SCAN_RSP。
这两种Scanning的最终结果,就是把接收到的数据(包括Advertiser地址、Advertiser数据等),反馈给上层。
3.3.5 Initiating状态