文章目录

  • 1 蓝牙BLE简介
  • 2 蓝牙BLE概述
  • 2.1 ISM Band 2.4GMHz
  • 3 蓝牙BLE协议架构
  • 3.1 Physical Layer
  • 3.2 Link Layer
  • 3.2.1 Physical Channel 的共享
  • 3.2.2 状态(state)和角色(role)的定义
  • 3.2.3 Air Interface Protocol
  • 3.2.4 Link Layer Control
  • 3.3 HCI
  • 3.4 L2CAP Protocol
  • 3.4.1 Protocol/channel multiplexing
  • 3.5 Attribute Protocol
  • 3.6 Generic Attribute Profile
  • 3.6.1 层次结构
  • 3.7 Security Manager(SM)
  • 3.8 Generic Access Profile(GAP)
  • 4 蓝牙BLE广播
  • 4.1 广播包详解
  • 4.1.1 广播数据类型Advertising Data Types
  • 4.2 广播时间分析
  • 4.3 广播类型Advertising_Type
  • 4.4 广播信道Physical Channel
  • 4.5 广播事件Advertising Event
  • 5 蓝牙BLE扫描
  • 5.1 扫描参数
  • 5.1.1 扫描窗口
  • 5.1.2 扫描类型


1 蓝牙BLE简介

蓝牙BLE英文为Bluetooh Low Energy,即低功耗蓝牙。
参考文章:

  1. 蜗蜗科技
  2. 乐鑫科技《esp32_bluetooth_architecture_cn》


2 蓝牙BLE概述

2.1 ISM Band 2.4GMHz

下图是对Bluetooth Core的一个概述,从RF的Physical Channel,到Baseband的Physical Link、Logical Link、LMP、L2CAP等概念,都有一些粗略的介绍。

iOS蓝牙ble和传统蓝牙_iOS蓝牙ble和传统蓝牙

3 蓝牙BLE协议架构

iOS蓝牙ble和传统蓝牙_物联网_02


如上图所示,BLE的协议可分为Bluetooth Application和Bluetooth Core两大部分,而Bluetooth Core又包含BLE Controller和BLE Host两部分。

3.1 Physical Layer

任何一个通信系统,首先要确定的就是通信介质(物理通道,Physical Channel)。在BLE协议中,“通信介质”的定义是由Physical Layer 负责。 在Physical Layer 中,BLE物理信道RF使用2.4GHz ISM(Industrial Scientific Medical) 频段,频率范围是2.400-2.4835 GHz。 其信道划分频点分别是‘f=2402+k*2 MHz, k=0, … ,39’,带宽为2MHz”的40个RF Channel。

3.2 Link Layer

在Physical Layer中定义了通信所需的物理通道,即40个RF Channel(后面统一使用Physical Channel指代)。至此,Link Layer主要功能是在这些Physical Channel上收发数据,与此同时,不可避免的需要控制RF收发相关的参数。因此Link Layer 还需解决如下问题:

  • Physical Layer仅仅提供了有限的40个Physical Channel,而BLE中参与通信的实体的数量,肯定不是这个数量级。Link Layer需要解决Physical Channel的共享问题;
  • 通信是两个实体之间的事情,对这两个实体来说,它们希望看到一条为自己独享的传输通道(就是我们所熟悉的逻辑链路,Logical Link)。这也是Link Layer需要解决的;
  • Physical Channel是不可靠的,任何数据传输都可能由于干扰等问题二损毁、丢失,这对有些应用来说,是接受不了的。因此Link Layer需要提供校验、重传等机制,确保数据传输的可靠性;
  • ……

3.2.1 Physical Channel 的共享

BLE系统只有有限的40个Physical Channel,怎么容纳多个通信实体呢?其解决方法如下,Link Layer将BLE的通信场景分为两类:

  • 数据量比较少、发送不频繁、对时延不是很敏感的场景
    例如一个传感器节点(如温度传感器),需要定时(如1s)向处理中心发送传感器数据(如温度)。 针对这种场景,BLE的Link Layer采取的处理方式是广播通信: 从40个Physical Channel中选取3个,作为广播通道(advertising channel),在广播通道上,任何参与者都可以随意收发数据,且共享同一个逻辑传输通道(广播通道)。当然该方法存在较多的问题,如不可靠、不高效、不安全等。
  • 数据量较大、发送频率较高、对时延较敏感的场景
    这种场景下,BLE的Link Layer会从剩余的37个Physical Channel中,选取一个,为这种场景里面的通信双方建立单独的通道(data channel),这就是 连接(connection) 的过程。同时,为了增加容量,增大抗干扰能力,连接不会长期使用一个固定的Physical Channel,而是在多个Channel(如37个)之间随机但有规律的切换,这就是BLE的跳频(Hopping)技术。

3.2.2 状态(state)和角色(role)的定义

基于上面“3.2.1 Physical Channel 的共享”小节的思路,BLE协议在Link Layer抽象出5种状态: 并以如下的状态机进行切换(设备在同一时刻只能处于这些状态的一种)

  • Standby State
  • Advertising State
  • Scanning State
  • Initiating State
  • Connection State
    注1:从横向看,协议的每个层次(如这里的Link Layer)都可以当做可相互通信的实体。这里的状态,就是指这每一层实体的状态。因此,在协议的多个层次上,都可能有状态定义,甚至名字也一样,我们阅读协议栈的时候,一定要留意,不要被绕晕了。

iOS蓝牙ble和传统蓝牙_链路_03

  1. Standby状态是初始状态,即不发送数据,也不接收数据。根据上层实体的命令(如位于host软件中GAP),可由其它任何一种状态进入,也可以切换到除Connection状态外的任意一种状态。
  2. Advertising状态是可以通过广播通道发送数据的状态,由Standby状态进入。它广播的数据可以由处于Scanning或者Initiating状态的实体接收。上层实体可通过命令将Advertising状态切换回Standby状态。另外,连接成功后,也可切换为Connection状态。
  3. Scanning状态是可以通过广播通道接收数据的状态,由Standby状态进入。根据Advertiser所广播的数据的类型,有些Scanner还可以主动向Advertiser请求一些额外数据。上层实体可通过命令将Scanning状态切换回Standby状态。
  4. Initiating状态和Scanning状态类似,不过是一种特殊的接收状态,由Standby状态进入,只能接收Advertiser广播的connectable的数据,并在接收到数据后,发送连接请求,以便和Advertiser建立连接。当连接成功后,Initiater和对应的Advertiser都会切换到Connection状态。
  5. Connection状态是和某个实体建立了单独通道的状态,在通道建立之后,由Initiating或者Advertising自动切换而来。通道断开后,会重新回到Standby状态。

通道建立后(通常说“已连接”),处于Connection状态的双方,分别有两种角色,Master和Slave: Initiater方称作Mater、Advertiser方称作Slave。

3.2.3 Air Interface Protocol

在状态和角色定义完成后,主要操作包括两类,提供某一状态下,和其它实体对应状态之间的数据交换机制;根据上层实体的指令,以及当前的实际情况,负责状态之间的切换。且由Air Interface Protocol负责,主要思路如下。

  1. 定义在Physical Channel上收发的数据包的格式(packet format)
    在BLE中,两种类型的Physical Channel(advertising channel和data channel)统一使用一种packet format,如下:
    Preamble(1 octet) Access Address(4 octets) PDU(2 to 257 octets) CRC(3 octets)
    Access Address:用于识别;
    PDU:BLE在Link Layer的PDU长度最大为257 octets(当做bytes理解就行了)。这决定了上层实体,如L2CAP、Application等,如上层实体数据过大,需要拆分、重组才能传输;
    Link Layer总packet长度是9~264bytes。
  2. 定义不同类型的PDU及其格式
    由(3.2.2 状态(state)和角色(role)的定义 )小节的描述,Link Layer有5种状态,每种状态下所传输数据的功能不尽相同,基于此,Air Interface Protocol定义出如下的PDU类型:
    1)Advertising channel中Advertising有关的PDU
    ADV_IND:Advertiser发送的,可被连接的、无方向的广播数据(connectable undirected advertising event);
    ADV_DIRECT_IND:Advertiser发送的,可被连接的、单向广播数据(connectable directed advertising event);
    ADV_NONCONN_IND:Advertiser发送的,不可被连接的、无方向的广播数据(non-connectable undirected advertising event);
    ADV_SCAN_IND:Advertiser发送的、可接受SCAN_REQ请求的、无方向的广播数据(scannable undirected advertising event)。
    2)Advertising channel中Scanning有关的PDU
    SCAN_REQ:Scanner发送的,向Advertiser请求额外信息的数据包(一般需要在收到ADV_SCAN_IND后才可发送);
    SCAN_RSP:Advertiser发送的,响应SCAN_REQ请求的数据包。
    3)Advertising channel中Initialing有关的PDU
    CONNECT_REQ:Initiater发起的,请求建立连接的数据包。
    4)Data channel中LL data有关的PDU
    已连接的双方进行数据通信所用的PDU,有效的payload长度为0~251bytes。
    5)Data channel中LL control有关的PDU
    用于管理、维护、更新已连接的数据通道的PDU,包括:
    LL_CHANNEL_MAP_REQ:请求更改所使用的Physical Channel的数据包;
    LL_TERMINATE_IND:告知对方此次连接即将结束,以及结束的原因;
    等等。
  3. 以白名单(White List)的形式定义Link Layer的数据过滤机制
    主要针对广播通道,因为随着通信设备的增多,空中的广播数据将会呈几何级的增长,为了避免资源的浪费(特别是BLE Host),有必要在Link Layer过滤掉一些数据包,例如根据蓝牙地址,过滤掉不是给自己的packet。
  4. 执行广播通道上实际的packet收发操作
    Advertising State下的Advertising Channel的选择、Advertising的间隔、Advertising PDU的类型等;
    Scanning State/Initialing State下的scanWindow、scanInterval等。
  5. 定义连接建立的方式及过之后的应答、流控等机制

3.2.4 Link Layer Control

经过(3.2.3 Air Interface Protocol)小结的抽象,BLE实体已经具备广播通信、点对点连接的建立和释放、点对点通信等基本的能力。除此之外,Link Layer又抽象出来一个链路控制协议(Link Layer Control),用于管理、控制两个Link Layer实体之间所建立的这个Connection,主要功能包括:

  1. 更新Connection相关的参数,如transmitWindowSize、transmitWindowOffset、connInterval等等;
  2. 更新该连接所使用的跳频图谱(使用哪些Physical Channels);
  3. 执行链路加密(Encryption)有关的过程。

3.3 HCI

定义Host和Controller(通常是两颗IC)之间的通信协议,可基于Uart、USB等物理介质,对理解蓝牙协议来说,是无关紧要的,这里暂不介绍。

3.4 L2CAP Protocol

L2CAP(Logical Link Control and Adaptation Protocol)即逻辑链路控制及自适应协议。
经过Link Layer的抽象之后,两个BLE设备之间可存在两条逻辑上的数据通道:一条是无连接的广播通道;另一条是基于连接的数据通道,是一个点对点(Master对Slave)的逻辑通道。
广播通道暂且不展开,而数据通道(后面简称逻辑通道,Logical Channel),要怎么使用,还需要一番思索,例如:

  • Logical Channel只有一条,而要利用它传输数据的上层应用却不止一个(例如协议框架图中的ATT和SMP),怎么复用?
  • Logical Channel所能传输的有效payload长度最大只有251bytes,是否意味着上层应用每次只能传输少于这个长度的数据?
  • Logical Channel仅提供了简单的应答和流控机制,如果传输的数据出错怎么办?
  • ……

以上问题,都是由L2CAP,一个介于应用程序(Profile、Application等)和Link Layer之间的protocol,负责回答,它提供的功能主要包括:

  • Protocol/channel multiplexing,协议/通道的多路复用;
  • Segmentation and reassembly,上层应用数据(L2CAP Service Data Units,SDUs)的分割(和重组),生成协议数据单元(L2CAP Packet Data Units,PDUs),以满足用户数据传输对延时的要求,并便于后续的重传、流控等机制的实现;
  • Flow control per L2CAP channel,基于L2CAP Channel的流控机制;
  • Error control and retransmissions,错误控制和重传机制;
  • Support for Streaming,支持流式传输(如音频、视频等,不需要重传或者只需要有限重传);
  • Fragmentation and Recombination,协议数据单元(PDUs)的分片(和重组),生成符合Link Layer传输要求的数据片(长度不超过251);
  • Quality of Service,QoS的支持。

3.4.1 Protocol/channel multiplexing

multiplexing(多路复用)即,可用于传输用户数据的逻辑链路只有一条,而L2CAP需要服务的上层Profile和Application的数目,肯定远不止一个。因此,需要使用多路复用的手段,将这些用户数据映射到有限的链路资源上去。
而multiplexing的手段,当数据发送时,将用户数据分割为一定长度的数据包(L2CAP Packet Data Units,PDUs),加上一个包含特定“ID”的header后,通过逻辑链路发送出去;当数据接收时,从逻辑链路接收数据,解析其中的“ID”,并以此判断需要将数据转发给哪个应用。
这里所说的ID,就是多路复用的手段,L2CAP提供两种复用手段:

  1. 基于连接的方法(这里的连接为L2CAP connection,不要和Link Layer的connection混淆了
    这里的连接,是指基于L2CAP的应用程序,在通信之前,先建立一个基于Logical Channel的虚拟通道(称作L2CAP channel)。L2CAP会为这个通道分配一个编号,称作channel ID(简称CID)。L2CAP channel建立之后,就可以把CID放到数据包的header中,以达到multiplexing的目的。这些基于CID实现的多路复用,就称作channel multiplexing(基于通道的多路复用)。那CID是怎么确定的呢?有一些固定用途的L2CAP Channel,其CID是固定值,另外一些则是动态分配的,具体如下:
  2. 无连接的方法
    另外,为了提高数据传输的效率,方便广播通信等应用场景,L2CAP在提供基于连接的通信机制之外,也提供了无连接的数据传输方法。基于这种方法,CID不存在了,取而代之的是一个称作Protocol/Service Multiplexer(PSM)的字段。这种多路复用的手段则成为Protocol multiplexing(基于协议的多路复用)。由于Protocol multiplexing只允许在BR/EDR controller中使用,本文就不再详细介绍了。

3.5 Attribute Protocol

由上面章节的描述可知,在BLE协议栈中:Physical Layer负责提供一系列的Physical Channel;基于这些Physical Channel,Link Layer可在两个设备之间建立用于点对点通信的Logical Channel;而L2CAP则将这个Logical Channel换分为一个个的L2CAP Channel,以便提供应用程序级别的通道复用。到此之后,基本协议栈已经构建完毕,应用程序已经可以基于L2CAP跑起来了。
BLE最重要的初衷----物联网。物联网中最重要、最广泛的一类应用是:信息的采集。 这些信息往往都很简单,如温度、湿度、速度、位置信息、电量、水压、等等。采集的过程也很简单,节点设备定时的向中心设备汇报信息数据,或者,中心设备在需要的时候主动查询。
基于信息采集的需求,BLE抽象出一个协议:Attribute protocol,该协议将这些“信息”以“Attribute(属性)”的形式抽象出来,并提供一些方法,供远端设备(remote device)读取、修改这些属性的值(Attribute value)。
Attribute Protocol的主要思路包括:

  1. 基于L2CAP,使用固定的Channel ID(0x004,具体可参考上文CID)。
  2. 采用client-server的形式。提供信息(以后都称作Attribute)的一方称作ATT server(服务器,一般是那些传感器节点),访问信息的一方称作ATT client(客户端),下面是服务器和客户端间的常用操作:
    1)客户端给服务端发数据:通过对服务器的数据进行写操作 (Write),来完成数据发送工作。写操作分两种,一种是写入请求 (Write Request),一种是写入命令 (WriteCommand),两者的主要区别是前者需要对方回复响应 (Write Response),而后者不需要对方回复响应。
    2)服务端给客户端发数据:主要通过服务端指示 (Indication) 或者通知 (Notification) 的形式,实现将服务端更新的数据发给客户端。与写操作类似,指示和通知的主要区别是前者需要对方设备在收到数据指示后,进行回复 (Confirmation)。
    3)客户端也可以主动通过读操作读取服务端的数据。
  3. iOS蓝牙ble和传统蓝牙_数据_04

  4. 一个Attribute由Attribute Type、Attribute Handle、Attribute Value和Attribute Permissions组成。
    1)Attribute Type:每个数据有⾃己需要代表的意思,例如表示温度、发射功率、电池等等各种各样的信息。蓝牙组织 (Bluetooth SIG) 对常用的一些数据类型进行了归类,赋予不同的数据类型不同的标识码 (UUID)。例如 0x2A09 表示电池信息,0x2A6E 表示温度信息。UUID 可以是 16 比特的 (16-bit UUID),也可以是 128 比特的 (128-bit UUID)。
    2)Attribute Handle:是一个16-bit的数值,用作唯一识别Attribute server上的所有Attribute。Attribute Handle的存在有如下意义:
    a)一个server上可能存在多个相同类型的Attribute,显然,client有区分这些Attribute的需要。
    b)同一类型的多个Attribute,可以组成一个Group,client可以通过这个Group中的起、始handle访问所有的Attributes。
    3) Attribute Value:属性值是每个属性真正要承载的信息,其他 3 个元素都是为了让对方能够更更好地获取属性值。有些属性的⻓度是固定的,例如电池属性(Battery Level) 的长度只有 1 个字节,因为需要表示的数据仅有 0~100%,而 1 个字节足以表示 1~100 的范围;而有些属性的⻓长度是可变的,例如基于 BLE 实现的透传模块。
    4) Attribute Permissions:属性许可,每个属性对各自的属性值有相应的访问限制,比如有些属性是可读的、有些是可写的、有些是可读又可写的等等。拥有数据的⼀方可以通过属性许可,控制本地数据的可读写属性。
    授权有关的权限(authorization permissions),Authorization Required和No Authorization Required。

3.6 Generic Attribute Profile

ATT(Attribute )之所以称作“protocol”,是因为它还比较抽象,仅仅定义了一套机制,允许client和server通过Attribute的形式共享信息。而具体共享哪些信息,ATT并不关心,这是GATT(Generic Attribute Profile)所负责。
GATT相对ATT只多了一个‘G‘,但含义却大不同,因为GATT是一个profile(更准确的说是profile framework)。
在蓝牙协议中,profile一直是一个比较抽象的概念,我们可以将其理解为“应用场景、功能、使用方式”都被规定好的Application。上面我们讲过,BLE很大一部分的应用场景是信息(Attribute)的共享,因此,BLE协议栈基于Attribute Protocol,定义了一个称作GATT(Generic Attribute)的profile framework(它本身也是一个profile),用于提供通用的、信息的存储和共享等功能。

3.6.1 层次结构

作为一个Profile framework,GATT profile提出了如下的层次结构:

iOS蓝牙ble和传统蓝牙_iOS蓝牙ble和传统蓝牙_05


由上面图片可知,GATT profile的层次结构依次是:Profile—>Service—>characteristic。

“Profile”是基于GATT所派生出的真正的Profile,位于GATT Profile hierarchy的最顶层,由一个或者多个和某一应用场景有关的Service组成。

一个Service包含一个或者多个Characteristic(特征),也可以通过Include的方式,包含其它Service。

Characteristic则是GATT profile中最基本的数据单位,由一个Properties、一个Value、一个或者多个Descriptor组成。

  1. Characteristic Properties定义了characteristic的Value如何被使用,以及characteristic的Descriptor如何被访问。
  2. Characteristic Value是特征的实际值,例如一个温度特征,其Characteristic Value就是温度值就。
  3. Characteristic Descriptor则保存了一些和Characteristic Value相关的信息。

以上除“Profile”外的每一个定义,Service、Characteristic、Characteristic Properties、Characteristic Value、Characteristic Descriptor等等,都是作为一个Attribute存在的,具备(3.5 Attribute Protocol)所描述的Attribute的所有特征:Attribute Handle、Attribute Types、Attribute Value和AttributePermissions。

3.7 Security Manager(SM)

Security Manager负责BLE通信中有关安全的内容,包括配对(pairing,)、认证(authentication)和加密(encryption)等过程。

3.8 Generic Access Profile(GAP)

BLE协议栈定义了一个称作Generic Access(通用访问)的profile,以实现如下功能:

  1. 定义GAP层的蓝牙设备角色(role)
    和的Link Layer的role类似,只不过GAP层的role更接近用户(可以等同于从用户的角度看到的蓝牙设备的role),包括:
    1)Broadcaster Role,设备正在发送advertising events;
    2)Observer Role,设备正在接收advertising events;
    3)Peripheral Role,设备接受Link Layer连接(对应Link Layer的slave角色);
    4)Central Role,设备发起Link Layer连接(对应Link Layer的master角色)。
  2. 定义GAP层的、用于实现各种通信的操作模式(Operational Mode)和过程(Procedures),包括:
    1)Broadcast mode and observation procedure,实现单向的、无连接的通信方式;
    2)Discovery modes and procedures,实现蓝牙设备的发现操作;
    3)Connection modes and procedures,实现蓝牙设备的连接操作;
    4)Bonding modes and procedures,实现蓝牙设备的配对操作。
  3. 定义User Interface有关的蓝牙参数,包括:
    1)蓝牙地址(Bluetooth Device Address);
    2)蓝牙名称(Bluetooth Device Name);
    3)蓝牙的pincode(Bluetooth Passkey);
    4)蓝牙的class(Class of Device,和发射功率有关);
    5)等等。
  4. Security有关的定义

4 蓝牙BLE广播

广播包分为两种:

  • 广播包(Advertising Data)
  • 响应包(Scan Response)

iOS蓝牙ble和传统蓝牙_物联网_06

其中广播包是每个外设都必须广播的,而响应包是可选的。每个广播包的长度必须是31个字节,如果不到31个字节 ,则剩下的全用0填充补全,这部分的数据是无效的。

iOS蓝牙ble和传统蓝牙_物联网_07

4.1 广播包详解

广播包中包含若干个广播数据单元,广播数据单元也称为 AD Structure。其格式如下,

广播数据单元 = 长度值Length + AD type + AD Data

长度值Length只占一个字节,并且位于广播数据单元的第一个字节。举例分析如下

iOS蓝牙ble和传统蓝牙_多路复用_08


结合下文广播数据类型Advertising Data Types可知,

  1. TYPE 为 0x01 表示 GAP_DATA_TYPE_FLAGS 类型,VALUE 为 0x06,具体意义如下

    bit 0: LE 有限发现模式
    bit 1: LE 普通发现模式
    bit 2: 不支持 BR/EDR
    bit 3: 对 Same Device Capable(Controller) 同时支持 BLE 和 BR/EDR
    bit 4: 对 Same Device Capable(Host) 同时支持 BLE 和 BR/EDR
    bit 5…7: 预留
    这bit 1~7分别代表着发送该广播的蓝牙芯片的物理连接状态。当bit的值为1时,表示支持该功能。
  2. TYPE 为 0x09 表示 GAP_DATA_TYPE_LOCAL_NAME,VALUE 为 0x52616E676550 ,根据“ASCII码字符对照表”其表示“RangeP”。
  3. TYPE 为 0x21 表示 GAP_DATA_TYPE_UUID128_SVC_DATA ,VALUE 为 0xBCBE1BE07AFAC0ADE811D385A40C124F ,转为字符串为 “4f120ca4-85d3-11e8-adc0-fa7ae01bbebc”

4.1.1 广播数据类型Advertising Data Types

/**
 * GAP Advertising Data Types, as defined by Bluetooth Core 4.2 specification
 *
 * \note: only data types valid for Advertising Data are included
 */
typedef enum {
        /** Flags */
        GAP_DATA_TYPE_FLAGS               = 0x01,
        /** Incomplete List of 16-bit Service Class UUIDs */
        GAP_DATA_TYPE_UUID16_LIST_INC     = 0x02,
        /** Complete List of 16-bit Service Class UUIDs */
        GAP_DATA_TYPE_UUID16_LIST         = 0x03,
        /** Incomplete List of 32-bit Service Class UUIDs */
        GAP_DATA_TYPE_UUID32_LIST_INC     = 0x04,
        /** Complete List of 32-bit Service Class UUIDs */
        GAP_DATA_TYPE_UUID32_LIST         = 0x05,
        /** Incomplete List of 128-bit Service Class UUIDs */
        GAP_DATA_TYPE_UUID128_LIST_INC    = 0x06,
        /** Complete List of 128-bit Service Class UUIDs */
        GAP_DATA_TYPE_UUID128_LIST        = 0x07,
        /** Shortened Local Name */
        GAP_DATA_TYPE_SHORT_LOCAL_NAME    = 0x08,
        /** Complete Local Name */
        GAP_DATA_TYPE_LOCAL_NAME          = 0x09,
        /** Tx Power Level */
        GAP_DATA_TYPE_TX_POWER_LEVEL      = 0x0A,
        /** Class of Device */
        GAP_DATA_TYPE_CLASS_OF_DEVICE     = 0x0D,
        /** Simple Pairing Hash C-192 */
        GAP_DATA_TYPE_SP_HASH_C           = 0x0E,
        /** Simple Pairing Randomizer R-192 */
        GAP_DATA_TYPE_SP_RANDOMIZER_R     = 0x0F,
        /** Security Manager TK Value */
        GAP_DATA_TYPE_TK_VALUE            = 0x10,
        /** Security Manager Out of Band Flags */
        GAP_DATA_TYPE_OOB_FLAGS           = 0x11,
        /** Slave Connection Interval Range */
        GAP_DATA_TYPE_SLAVE_CONN_INTV     = 0x12,
        /** List of 16-bit Service Solicitation UUIDs */
        GAP_DATA_TYPE_UUID16_SOLIC        = 0x14,
        /** List of 128-bit Service Solicitation UUIDs */
        GAP_DATA_TYPE_UUID128_SOLIC       = 0x15,
        /** Service Data - 16-bit UUID */
        GAP_DATA_TYPE_UUID16_SVC_DATA     = 0x16,
        /** Public Target Address */
        GAP_DATA_TYPE_PUBLIC_ADDRESS      = 0x17,
        /** Random Target Address */
        GAP_DATA_TYPE_RANDOM_ADDRESS      = 0x18,
        /** Appearance */
        GAP_DATA_TYPE_APPEARANCE          = 0x19,
        /** Advertising Interval */
        GAP_DATA_TYPE_ADV_INTERVAL        = 0x1A,
        /** LE Bluetooth Device Address */
        GAP_DATA_TYPE_LE_BT_ADDR          = 0x1B,
        /** LE Role */
        GAP_DATA_TYPE_LE_ROLE             = 0x1C,
        /** Simple Pairing Hash C */
        GAP_DATA_TYPE_SPAIR_HASH          = 0x1D,
        /** Simple Pairing Randomizer R */
        GAP_DATA_TYPE_SPAIR_RAND          = 0x1E,
        /** List of 32-bit Service Solicitation UUIDs */
        GAP_DATA_TYPE_UUID32_SOLIC        = 0x1F,
        /** Service Data - 32-bit UUID */
        GAP_DATA_TYPE_UUID32_SVC_DATA     = 0x20,
        /** Service Data - 128-bit UUID */
        GAP_DATA_TYPE_UUID128_SVC_DATA    = 0x21,
        /** LE Secure Connections Confirmation Value */
        GAP_DATA_TYPE_LE_SEC_CONN_CFM_VAL = 0x22,
        /** LE Secure Connections Random Value */
        GAP_DATA_TYPE_LE_SEC_CONN_RAND_VAL= 0x23,
        /** URI */
        GAP_DATA_TYPE_URI                 = 0x24,
        /** Indoor Positioning */
        GAP_DATA_TYPE_INDOOR_POSITIONING  = 0x25,
        /** Transport Discovery Data */
        GAP_DATA_TYPE_TRANSPORT_DISC_DATA = 0x26,
        /** LE Supported Features */
        GAP_DATA_TYPE_LE_SUPP_FEATURES    = 0x27,
        /** Channel Map Update Indication */
        GAP_DATA_TYPE_CHNL_MAP_UPD_IND    = 0x28,
        /** PB-ADV */
        GAP_DATA_TYPE_PB_ADV              = 0x29,
        /** Mesh Message */
        GAP_DATA_TYPE_MESH_MESSAGE        = 0x2A,
        /** Mesh Beacon */
        GAP_DATA_TYPE_MESH_BEACON         = 0x2B,
        /** 3D Information Data */
        GAP_DATA_TYPE_INFO_DATA_3D        = 0x3D,
        /** Manufacturer Specific Data */
        GAP_DATA_TYPE_MANUFACTURER_SPEC   = 0xFF,
} gap_data_type_t;

4.2 广播时间分析

设备每次广播时,会在3个广播信道(详见下文)上发送相同的报文,这些报文被称为广播事件。除了定向报文(已配对的蓝牙之间传输的数据)以外,其他广播事件均可以选择“20ms ~ 10.28s”不等的间隔。两个相邻广播事件之间的时间称为广播间隔

但是,设备周期性的发送广播时,由于设备间的时钟会不同程度的漂移,两个设备可能在很长一段时间同时广播而造成干扰。为防止这一情况的发生,除定向广播之外的其他广播类型,发送时间均会被扰动。实现该扰动的方式为,在上一次广播事件后加入“0 ~ 10ms”的随机延时。所以,即使两个设备广播间隔相同,并在相同信道及时间点上发送造成了冲突,但加入伪随机延时后,它们发送下一个广播事件时就会有很大可能不再冲突。

两个相邻广播事件之间的时间间隔(T_advEvent)为:T_AdvEvent = advInterval + advDelay

其中,advInterval 必须是“0.625ms”的整数倍,范围是“20ms ~ 10.24s”之间。 advDelay是Link Layer(链接层)分配的一个伪随机数,它的范围为“0 ~ 10ms”。

iOS蓝牙ble和传统蓝牙_链路_09

在程序实际设置过程中没有广播间隔参数,而是设置Advertising_Interval_Min(最小广播间隔)和Advertising_Interval_Max(最大广播间隔)这两个参数来调整广播间隔,它们都是以“0.625ms”为单位,如果要固定广播间隔为某一个值,只需要将这两个参数设置为同一个有效数值即可。

对BLE广播通信来说,Advertising的周期是一个比较重要的参数,因为它关系到系统的功耗和通信的效率,因此需要根据使用场景,小心设定。

4.3 广播类型Advertising_Type

iOS蓝牙ble和传统蓝牙_数据_10

  • 可连接的非定向广播(Connectable Undirected Event Type)。这是一种用途最广的广播类型,包括广播数据和扫描响应数据,它表示当前设备可以接受其他任何设备的连接请求。
  • 可连接的定向广播(Connectable Directed Event Type)。定向广播类型是为了尽可能快的建立连接。这种报文包含两个地址:广播者的地址和发起者的地址。发起者收到发给自己的定向广播报文之后,可以立即发送连接请求作为回应。
  • 不可连接的非定向广播(Non-connectable Undirected Event Type)。仅仅发送广播数据。
  • 可扫描的非定向广播(Scannable Undirected Event Type)。这种广播不能用于发起连接,但允许其他设备扫描该广播设备。这意味着该设备可以被发现,既可以发送广播数据,也可以响应扫描发送扫描回应数据,但不能建立连接。这是一种适用于广播数据的广播形式,动态数据可以包含于广播数据之中,而静态数据可以包含于扫描响应数据之中。

使用经验总结:

  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的方式。

4.4 广播信道Physical Channel

BLE可以使用40个Physical Channel中的3个作为广播通信的物理信道,综合各种因素(抗干扰等),最终选取了如下三个:

iOS蓝牙ble和传统蓝牙_链路_11


与此同时,Link Layer允许Host在这这三个物理信道中,任意选取一个或者多个,用于广播。Link Layer将相同的广播数据,在每一个被选中的Channel中,发送一次。

4.5 广播事件Advertising Event

Advertising Event是在所有被使用的物理Channel上,发送的Advertising PDU的组合。
BLE设备处于Advertising状态的目的,就是要广播数据。并且,根据应用场景的不同,可广播4种类型的数据。另外,BLE设备最多可以在3个物理Channel上广播数据。也就是说,同一个数据(4中类型中的一种)需要在多个Channel上依次广播。因此,这样依次在多个Channel上广播的过程,就叫做一个Advertising Event。

与此同时,有些广播(如可连接、可扫描)发送出去之后,允许接收端在对应的Channel上,回应一些请求(如连接请求、扫描请求)。并且,广播者接收到扫描请求后,需要在同样的Channel上回应。这些过程,也会计算在一个Advertising Event中。

iOS蓝牙ble和传统蓝牙_数据_12

5 蓝牙BLE扫描

5.1 扫描参数

5.1.1 扫描窗口

  • window 扫描窗口:每次扫描所持续的时间,在持续时间内扫描设备一直在广播信道上运行;
  • interval 扫描间隔:表示控制器多久扫描一次,也就是两个连续的扫描窗口的开始时间的时间间隔;

5.1.2 扫描类型

  • Passive Scanning 被动扫描:这种扫描模式下,BLE设备只听不问,也就是说,只接收ADV_DIRECT_IND、ADV_IND、ADV_SCAN_IND、ADV_NONCONN_IND等类型的PDU,并不发送SCAN_REQ;
  • Active Scanning 主动扫描:这种扫描模式下,不只认真听讲,还勤于发问(SCAN_REQ),并接收后续的 SCAN_RSP。