0%

BLE 广播基础概述

前言

本文主要讲述BLE链路层交互的空中包相关概念

BLE的协议栈架构层级划分简述如下:

层级 功能 示例
物理层(PHY) 负责无线信号的调制/解调,工作在 2.4GHz ISM 频段(40个信道:37 data, 3 advertising) GFSK 调制,1Mbps(BLE 5.0 支持2Mbps)
链路层(Link Layer) 管理广播、扫描、连接建立和数据传输 处理 ADV_IND 或 CONNECT_REQ
主机控制接口层(HCI) 定义主机(Host)与控制器(Controller)间的通信协议(如指令、事件、数据流) 通过 UART/USB 传输 HCI 命令包
逻辑链路控制与适配协议(L2CAP) 提供数据分片、重组和多路复用,管理协议通道 将 ATT 数据分片为适合链路层的包
安全管理层(SM) 处理配对、加密和密钥分发,保障通信安全 使用 AES-CCM 加密链路数据
属性协议层(ATT) 定义设备间数据访问的协议(读/写/通知),基于客户端-服务器模型 读取设备的电量值(0x180F 服务)
通用属性配置文件(GATT) 在 ATT 基础上组织数据为服务(Service)、特征(Characteristic)等结构 心率服务(0x180D)包含测量特征
通用访问配置文件(GAP) 管理设备可见性、连接模式和安全性(角色:广播者、观察者、外围/中心设备) 设置设备为可连接模式

蓝牙设备间的通信,归根到底都是基于空中数据包的交互,本文主要讲述BLE空中包,以及涉及到空中包的相关知识、应用、场景。

BLE空中包基础

BLE链路层(Link Layer)只定义了一种空中包格式:Preamble(前导帧)| Access Address | PDU(protocol data unit,协议数据单元) | CRC(cyclic redundancy check,循环冗余校验)

ATT、GATT、GAP层 都是基于数据信道包的payload的概念

Preamble(前导帧):0x55或者0xAA

Access Address

Access Address用来标示接收者ID或者空中包身份,根据Access Address的不同,区分两种Packet类型:广播包数据包

  • 广播包Access Address 固定为0x8E89BED6
  • 数据包,是数据信道空中包的简称,数据包只在数据信道上传输,即除37/38/39之外的其余37信道(Bluetooth LE总共占用40个信道)。

PDU

PDU(protocol data unit,协议数据单元)前两个字节固定为LL header(1个字节长)和payload length(1个字节长,又称data length)

PDU进一步为:LL Header | Payload Length | Payload

PDU 是 BLE 协议栈链路层的核心概念,定义了设备间数据交换的基本格式。无论是广播还是连接状态下的通信,都依赖于特定类型的 PDU 来完成任务。

BLE广播包

广播包,全名蓝牙广播通道(channel)空中包,即在蓝牙广播通道上传输的空中包,为两种空中包的一种。

对于广播包,PDU段的格式为:LL Header(1 Byte) | Payload Length(1 Byte) | Payload(6-37 Bytes)

PDU段的LL Header,即Advertising Header,其8个bit定义如下所示:

  • Bit0:接收地址类型
  • Bit1:发送地址类型
  • Bit2-3:保留
  • Bit4-7:广播报文类型,具体定义如下:
    类型 用法
    0000 ADV_IND 可连接非定向广播
    0001 ADV_DIRECT_IND 可连接定向广播
    0010 ADV_NONCONN_IND 不可连接非定向广播
    0011 SCAN_REQ 扫描者需要获得更多信息的扫描请求
    0100 SCAN_RSP 响应来自扫描者的扫描请求
    0101 CONNECT_REQ 发起者的连接请求
    0110 ADV_SCAN_IND 可扫描、不可连接的无定向广播
    xxxx 保留

Payload Length: 广播报文规范的长度范围是6-37字节

Payload:

  • Device Address:蓝牙MAC地址(6 Bytes)是强制的
  • 对于ADV_IND、SCAN_RSP两种类型的广播包,Advertising data的最大值为37 - 6 = 31字节,这就是广播包数据最长只能为31个字节的由来
  • ADV_DIRECT_IND 直连广播包净荷格式由6字节的广播设备地址和6字节的目标设备地址组成
  • SCAN_REQ 扫描请求包净荷格式由6字节的扫描设备地址和6字节的广播设备地址组成。远程发起连接的设备,搜索到周围正在广播的设备后,一般会发送扫描请求。

    对于一个可连接非定向广播而言,主机设备仅通过广播能够获取到其的数据长度为被动接收的ADV_IND:31个字节 + 主动扫描的回复包SCAN_RSP:31个字节 = 62个字节

广播包数据(Advertising data)

广播包的数据由多个 AD Structure 组成,每个结构包含3个字段:

  • 应用数据的结构格式:AD Structure 1 | AD Structure 2 | ... | AD Structure N
  • AD structure的格式为:Length(1 Byte) | Type(1 Byte) | Data
  • Length(1字节):表示TypeData的长度
  • Type(1字节):数据类型标识,表示Data的用途。0x02表示不完整的16位服务UUID(示例值:0x180A),0x09表示设备完整名称,0x0A表示发射功率等级,0x19表示设备外观,0xFF表示自定义数据(可以私有定义)等等,具体定义见如下:
  • 特别地说明,广播名称属于type:0x09,可以选择放置在ADV_IND(主动广播包),或者ADV_RSP(扫描响应包),由于LengthType各占用了一个字节,那么BLE广播名称的最大有效长度为31 - 2 = 29个字节。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    /*eir packet_type*/
    typedef enum {
    HCI_EIR_DATATYPE_FLAGS = 0x01,
    HCI_EIR_DATATYPE_MORE_16BIT_SERVICE_UUIDS = 0x02,
    HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS = 0x03,
    HCI_EIR_DATATYPE_MORE_32BIT_SERVICE_UUIDS = 0x04,
    HCI_EIR_DATATYPE_COMPLETE_32BIT_SERVICE_UUIDS = 0x05,
    HCI_EIR_DATATYPE_MORE_128BIT_SERVICE_UUIDS = 0x06,
    HCI_EIR_DATATYPE_COMPLETE_128BIT_SERVICE_UUIDS = 0x07,
    HCI_EIR_DATATYPE_SHORTENED_LOCAL_NAME = 0x08,
    HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME = 0x09,
    HCI_EIR_DATATYPE_TX_POWER_LEVEL = 0x0A,
    HCI_EIR_DATATYPE_CLASS_OF_DEVICE = 0x0D,
    HCI_EIR_DATATYPE_SIMPLE_PAIRING_HASH_C = 0x0E,
    HCI_EIR_DATATYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F,
    HCI_EIR_DATATYPE_SECURITY_MANAGER_TK_VALUE = 0x10,
    HCI_EIR_DATATYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11,
    HCI_EIR_DATATYPE_SLAVE_CONNECTION_INTERVAL_RANGE = 0x12,
    HCI_EIR_DATATYPE_16BIT_SERVICE_SOLICITATION_UUIDS = 0x14,
    HCI_EIR_DATATYPE_128BIT_SERVICE_SOLICITATION_UUIDS = 0x15,
    HCI_EIR_DATATYPE_SERVICE_DATA = 0x16,
    HCI_EIR_DATATYPE_APPEARANCE_DATA = 0x19,
    HCI_EIR_DATATYPE_ADVERTISING_INTERVAL = 0X1A,
    HCI_EIR_DATATYPE_LE_BLUETOOTH_DEVICE_ADDRESS = 0X1B,
    HCI_EIR_DATATYPE_LE_ROLE = 0X1C,
    HCI_EIR_DATATYPE_SIMPLE_PAIRING_HASH_C256 = 0X1D,
    HCI_EIR_DATATYPE_SIMPLE_PAIRING_RANDOMIZER_R256 = 0X1E,
    HCI_EIR_DATATYPE_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS = 0X1F,
    HCI_EIR_DATATYPE_SERVICE_DATA_32BIT_UUID = 0X20,
    HCI_EIR_DATATYPE_SERVICE_DATA_128BIT_UUID = 0X21,
    HCI_EIR_DATATYPE_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE = 0X22,
    HCI_EIR_DATATYPE_LE_SECURE_CONNECTIONS_RANDOM_VALUE = 0X23,
    HCI_EIR_DATATYPE_URI = 0X24,
    HCI_EIR_DATATYPE_INDOOR_POSITIONING = 0X25,
    HCI_EIR_DATATYPE_TRANSPORT_DISCOVERY_DATA = 0X26,
    HCI_EIR_DATATYPE_LE_SUPPORTED_FEATURES = 0X27,
    HCI_EIR_DATATYPE_CHANNEL_MAP_UPDATE_INDICATION = 0X28,
    HCI_EIR_DATATYPE_BIGINFO = 0X2C,
    HCI_EIR_DATATYPE_BROADCAST_CODE = 0X2D,
    HCI_EIR_DATATYPE_RESOLVABLE_SET_IDENTIFIER = 0X2E,
    HCI_EIR_DATATYPE_ADVERTISING_INTERVAL_LONG = 0X2F,
    HCI_EIR_DATATYPE_BROADCAST_NAME = 0X30,
    HCI_EIR_DATATYPE_3D_INFORMATION_DATA = 0X3D,
    HCI_EIR_DATATYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF
    } HCI_EIR_datatype_t;

广播信道空中包类型及应用

定向与非定向广播的区别与联系、应用

定向广播 的 Payload 中包含两个地址:

  • 广播设备地址(6字节)
  • 目标设备地址(6字节)

连接与非连接广播的区别与联系、应用

物理信道

BLE信道:40个,其中3个为广播信道,其余37个为连接信道

信标是什么

实际应用案例设计讲解

定向连接广播应用

一个Server设备如果已经与主机设备配对连接过,那么如果想要实现后续回连,只能这个主机去单独连接。避免其它设备点击误连接。 则可以设置定向广播,首次没有连接过时,设置为非定向广播。有连接记录后,记录目标设备的MAC地址,下次连接时,设置定向广播,指定目标MAC地址。

  • 从而限制仅目标设备可以连接此个广播。

比如音箱与手环,如果是非定向广播,那么任何主机设备都能点击连接到广播,就会导致有时候想点击连接时,被其它设备占用了连接。

多个广播、多主机连接应用

ble5.0 扩展广播同时支持多个广播,如何配置呢?
需要注意 多个广播和多主机连接的区别与应用

Server(从机)广播参数设置

主动广播包(Advertising Packet)扫描响应包(Scan Response Packet)

两种广播包,主动广播包和响应包,各31个字节,共62字节
adv packet:放置其它字段
adv resonse:可以只用来放置名称

代码应用示例(以杰理方案为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*!
* \brief 配置广播参数.
* \param [in] adv_interval 广播周期,Range: 0x0020 to 0x4000 (unit: 0.625ms).
* \param [in] adv_type 广播类型,Range: 0x00 to 0x04.
* \param [in] adv_channel 广播类型通道,range:Range: 0x01 to 0x07.
* \note !!!注意:设置的时候必现在广播关闭的状态下.
*/
#define ble_op_set_adv_param(adv_interval,adv_type,adv_channel) \
ble_user_cmd_prepare(BLE_CMD_ADV_PARAM, 3, (int)adv_interval, (int)adv_type, (int)adv_channel)

/*************************************************************************************************/
/*!
* \brief 配置广播参数+配对信息(相比配对广播参数,这个函数主要是针对定向广播使用).
* \param [in] adv_interval 广播周期,Range: 0x0020 to 0x4000 (unit: 0.625ms).
* \param [in] adv_type 广播类型,Range: 0x00 to 0x04.
* \param [in] adv_channel 广播类型通道,range:Range: 0x01 to 0x07.
* \param [in] peer_info (全局变量地址),定向广播时,填入对方的地址信息.
*/
#define ble_op_set_adv_param_ext(adv_interval,adv_type,adv_channel,peer_info) \
ble_user_cmd_prepare(BLE_CMD_ADV_PARAM_EXT, 4, (int)adv_interval, (int)adv_type, (int)adv_channel, (void*)peer_info)
#define ble_op_set_adv_data(adv_len,adv_data) \
ble_user_cmd_prepare(BLE_CMD_ADV_DATA, 2, (int)adv_len, (void*)adv_data)
#define ble_op_set_rsp_data(rsp_len,rsp_data) \
ble_user_cmd_prepare(BLE_CMD_RSP_DATA, 2, (int)rsp_len, (void*)rsp_data)

static void advertisements_setup_init()
{
uint8_t adv_type = ADV_IND; // 广播类型
uint8_t adv_channel = ADV_CHANNEL_ALL; // 37 38 39
int ret = 0;

ble_op_set_adv_param(ADV_INTERVAL_MIN, adv_type, adv_channel);

ret |= make_set_adv_data();
ret |= make_set_rsp_data();

if (ret) {
puts("advertisements_setup_init fail !!!!!!\n");
return;
}
}

思考与拓展

BLE的加密、配对是怎样的?LTK是什么?一般不都是直接点击就连接成功了吗?

BLE 支持配对(Pairing)和绑定(Bonding)。配对、绑定是 BLE 安全机制的一部分,位于 GAP 和 SM 层,不属于 GATT 层。

配对绑定流程简述
连接建立
发起配对请求(Pairing Request)
交换 IO 能力(Display Only / Keyboard Only / No Input No Output 等)
计算 TK、LTK、CSRK
设备确认(MITM Protection)
绑定信息保存到 Flash/NVS
完成:进入 BONDED 状态

密钥类型 描述
LTK(Long Term Key) 加密通信使用的主密钥
IRK(Identity Resolving Key) 解析私有地址(Private Address)
CSRK(Connection Signature Resolving Key) 数据签名验证
EDIV & RAND 用于 LTK 再生

可以通过按键确认绑定配对。
绑定 启用 bond = 1 并保存密钥
用户确认 按钮触发配对响应
下次连接 自动恢复加密状态,无需重新配对

情况一:只连接不配对
可以读写 GATT 特性
但不能访问受保护的特性(如带加密要求的服务)
安全等级较低,适合调试
✅ 情况二:配对但不绑定
当前连接可以加密通信
下次连接仍需重新配对
✅ 情况三:配对并绑定
第一次连接后保存密钥
下次连接可直接恢复加密通道(无需重新配对)

不是说广播一包最大255个字节吗?为什么又说广播包数据最多只能放31个字节?

空中包的数据包类型的有效载荷最大296字节?

BLE名称通常放在哪个广播包?可以分散放在不同包中吗?为什么?

可以放在ADV_IND,也可以放在ADV_RSP,但只能放在一个广播包中
说明名称的长度最大29个字节

广播参数有哪些?连接参数有哪些?有什么区别与联系?

slot是什么

手机扫描周围的广播时,会向所有发现的广播发送扫描请求吗?这个发送过程是怎样的?

是向周围广播 扫描请求 包吗?

BLE 4.x 和 BLE 5.x 有什么区别?在空中包上的体现有哪些?

信道上的区别
4.x 默认信道 37 38 39

从蓝牙5.0开始广播包可以在其它信道上传输

格式的兼容性

BLE连接后,通信所在的信道会动态变化吗?

LE-Audio走的是广播信道包?还是数据信道包?

BIS走广播信道?CIS走走数据信道?

BIS的接收过程是怎样的?
CIS的连接过程是怎样的?

特征服务可以放到广播包里面吗?跟一般的放在数据信道包有什么区别?

可连接、不可连接、定向、非定向的广播包有什么区别?优劣对比?应用场景分别是?

如何区分BLE连接与非连接情况下的通信?

在数据信道上通信,就是连接状态?
在广播信道上通信,就是非连接状态?

广播信道空中包的间隔有什么要求?一般是多少?设置不同的间隔有什么影响?与数据信道空中包的间隔设计有什么差异?

当广播包(ADV_IND)和扫描响应包(SCAN_RSP)​同时包含0x09类型(设备名称)字段且名称内容不同,主机端扫描显示名称结果是怎样的?

取决于主机端的软件设计逻辑

扫描结果的可能表现
​​(1)优先显示扫描响应包(SCAN_RSP)的名称
​原因:扫描设备(如手机)在主动发送SCAN_REQ后,SCAN_RSP被视为对广播数据的补充,部分系统会优先使用SCAN_RSP中的名称覆盖ADV_IND的名称。
​示例:
若ADV_IND中设备名为”Device_A”,SCAN_RSP中为”Device_B”,最终显示为”Device_B”。
例如在Nordic SDK中,SCAN_RSP的配置会覆盖ADV_IND的同类型字段。
​​(2)合并显示或冲突处理
​合并逻辑:某些设备可能将两个名称拼接(如”Device_A_Device_B”),但此行为不符合蓝牙规范。
​冲突处理:若名称字段重复且内容不一致,部分系统可能触发错误日志或直接忽略其中一个字段。
​​(3)仅显示首次接收的名称
​无主动扫描时:若扫描设备未主动发送SCAN_REQ(如仅被动监听),则只显示ADV_IND中的名称。
​主动扫描时:若设备同时接收两个包,可能优先显示SCAN_RSP的最新数据

参考站点