BLE学习(4) - BLE广播报文解析

广播报文结构

BLE广播报文格式如下:
在这里插入图片描述

前导

接收机可根据前导码执行频率同步、符号时序预估和自动增益控制(AGC)训练。
LE 1M物理层上发送的数据包前导码为8比特;
LE 2M物理层上发送的数据包前导码为16比特。
LE Coded物理层数据包的前导码由10组二进制序列’00111100’构成,合计为80比特。
这里我们只讨论LE 1M物理层上的数据包,即前导是一个8比特的交替序列。

接入地址

接入地址为一个随机的4byte地址。对于广播来说,其值固定为0X8E89BED6。
接收机可以通过接入地址的值确定为广播包,以及防止数据信号干扰。

报头

广播报文的报头和数据报文的报头是不一样的。
对于广播报文来说,报头格式为 4bit广播报文类型 + 2bit预留值 + 1bit发送地址类型 + 1bit接收地址类型
在这里插入图片描述

广播报文类型

蓝牙内核协议中一共有7种广播报文类型,接收机根据4bit的类型值确定属于哪种广播类型。
在这里插入图片描述

发送地址类型和接收地址类型

共有两种地址类型,分别为公共地址(public address)和随机地址(random address)。
在这里插入图片描述

长度

这里指数据域的长度。
由于广播数据域为0~37byte,故用6bit表示。剩余的2bit预留。

数据

广播数据最大长度为37byte,为6byte MAC地址 + 31byte 实际数据组成。
对于广播包来说,6byte MAC地址是必须包含的,故剩余给用户的实际数据最大为31byte。
注: 对于数据包而言,不包含6byte MAC地址。故数据包长度为0~31byte,用5bit长度表示即可。

数据定义规则

广播包中的数据域使用LTV的格式进行定义,即 length + type + value
length表示(type + value)的总长度;
type为1byte数据类型,蓝牙协议规范定义类型如下:

/// The type of advertising data(not adv_type)
typedef enum {
    ESP_BLE_AD_TYPE_FLAG              = 0x01,  /* relate to BTM_BLE_AD_TYPE_FLAG in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_16SRV_PART        = 0x02,  /* relate to BTM_BLE_AD_TYPE_16SRV_PART in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_16SRV_CMPL        = 0x03,  /* relate to BTM_BLE_AD_TYPE_16SRV_CMPL in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_32SRV_PART        = 0x04,  /* relate to BTM_BLE_AD_TYPE_32SRV_PART in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_32SRV_CMPL        = 0x05,  /* relate to BTM_BLE_AD_TYPE_32SRV_CMPL in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_128SRV_PART       = 0x06,  /* relate to BTM_BLE_AD_TYPE_128SRV_PART in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_128SRV_CMPL       = 0x07,  /* relate to BTM_BLE_AD_TYPE_128SRV_CMPL in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_NAME_SHORT        = 0x08,  /* relate to BTM_BLE_AD_TYPE_NAME_SHORT in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_NAME_CMPL         = 0x09,  /* relate to BTM_BLE_AD_TYPE_NAME_CMPL in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_TX_PWR            = 0x0A,  /* relate to BTM_BLE_AD_TYPE_TX_PWR in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_DEV_CLASS         = 0x0D,  /* relate to BTM_BLE_AD_TYPE_DEV_CLASS in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_SM_TK             = 0x10,  /* relate to BTM_BLE_AD_TYPE_SM_TK in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_SM_OOB_FLAG       = 0x11,  /* relate to BTM_BLE_AD_TYPE_SM_OOB_FLAG in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_INT_RANGE         = 0x12,  /* relate to BTM_BLE_AD_TYPE_INT_RANGE in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_SOL_SRV_UUID      = 0x14,  /* relate to BTM_BLE_AD_TYPE_SOL_SRV_UUID in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_128SOL_SRV_UUID   = 0x15,  /* relate to BTM_BLE_AD_TYPE_128SOL_SRV_UUID in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_SERVICE_DATA      = 0x16,  /* relate to BTM_BLE_AD_TYPE_SERVICE_DATA in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_PUBLIC_TARGET     = 0x17,  /* relate to BTM_BLE_AD_TYPE_PUBLIC_TARGET in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_RANDOM_TARGET     = 0x18,  /* relate to BTM_BLE_AD_TYPE_RANDOM_TARGET in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_APPEARANCE        = 0x19,  /* relate to BTM_BLE_AD_TYPE_APPEARANCE in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_ADV_INT           = 0x1A,  /* relate to BTM_BLE_AD_TYPE_ADV_INT in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_LE_DEV_ADDR       = 0x1b,  /* relate to BTM_BLE_AD_TYPE_LE_DEV_ADDR in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_LE_ROLE           = 0x1c,  /* relate to BTM_BLE_AD_TYPE_LE_ROLE in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_SPAIR_C256        = 0x1d,  /* relate to BTM_BLE_AD_TYPE_SPAIR_C256 in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_SPAIR_R256        = 0x1e,  /* relate to BTM_BLE_AD_TYPE_SPAIR_R256 in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_32SOL_SRV_UUID    = 0x1f,  /* relate to BTM_BLE_AD_TYPE_32SOL_SRV_UUID in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_32SERVICE_DATA    = 0x20,  /* relate to BTM_BLE_AD_TYPE_32SERVICE_DATA in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_128SERVICE_DATA   = 0x21,  /* relate to BTM_BLE_AD_TYPE_128SERVICE_DATA in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_LE_SECURE_CONFIRM = 0x22,  /* relate to BTM_BLE_AD_TYPE_LE_SECURE_CONFIRM in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_LE_SECURE_RANDOM  = 0x23,  /* relate to BTM_BLE_AD_TYPE_LE_SECURE_RANDOM in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_URI               = 0x24,  /* relate to BTM_BLE_AD_TYPE_URI in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_INDOOR_POSITION   = 0x25,  /* relate to BTM_BLE_AD_TYPE_INDOOR_POSITION in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_TRANS_DISC_DATA   = 0x26,  /* relate to BTM_BLE_AD_TYPE_TRANS_DISC_DATA in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_LE_SUPPORT_FEATURE= 0x27,  /* relate to BTM_BLE_AD_TYPE_LE_SUPPORT_FEATURE in stack/btm_ble_api.h */
    ESP_BLE_AD_TYPE_CHAN_MAP_UPDATE   = 0x28,    /* relate to BTM_BLE_AD_TYPE_CHAN_MAP_UPDATE in stack/btm_ble_api.h */
    ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE  = 0xFF,    /* relate to BTM_BLE_AD_MANUFACTURER_SPECIFIC_TYPE in stack/btm_ble_api.h */
} esp_ble_adv_data_type;

部分常见类型定义解析如下:
在这里插入图片描述
value为具体数据类型定义的值。

校验

校验为24bit的CRC校验,对报头,长度和数据进行计算。

广播抓包分析

我们使用wireshark对广播包进行抓包分析,如下为所抓实际数据:
在这里插入图片描述
注意:

  1. 广播数据为小段模式,即低字节在前,如接入地址4byte为0X8E89BED6,在广播数据中的存在格式为 “d6 be 89 8e” 。
  2. 广播1byte前导是在接收时被底层处理掉,不会存在抓包后的广播数据中显示的。
  3. wireshark抓到的广播数据除了蓝牙本身数据外,还会增加软件自己的头信息。另我们去掉wireshark软件自带的头信息。
    我们去掉wireshark自带的数据信息,实际广播数据是从4byte接入地址开始的,即 “d6 be 89 8e”。
    在这里插入图片描述
    根据广播包格式,在4byte接入地址后,为1byte的报头 + 1byte 的数据长度,这2byte组成了抓包数据中的Packet Header,如下:
    在这里插入图片描述
    Packet Header的数据解析格式如下:
    在这里插入图片描述
    根据解析格式,我们可以0x2520值解析如下:
  4. RxAddr和TxAddr位均为0,表示使用的是Public address地址
  5. PDU Type为0000,表示使用的广播模式为通用广播
  6. Length为37,表示广播数据域长度为37byte

然后我们来看看37byte数据域的内容:
前面我们说过,广播包必须带6byte的MAC地址,这里的Advertising Address为 34:85:18:b8:35:82,即为广播设备的MAC地址。

还剩31byte的实际数据如下:
在这里插入图片描述
第1个LTV数据组合为L = 2,T = 0x01,V = ‘0000 0110’
L = 2, 表示T+V的数据长度为2bytre
T = 0x01, 表示数据类型为ESP_BLE_AD_TYPE_FLAG ,表示设置广播标志
在ESP32中是这么定义广播标志的:

/**
 * @brief BLE_ADV_DATA_FLAG data flag bit definition used for advertising data flag
 */
#define ESP_BLE_ADV_FLAG_LIMIT_DISC         (0x01 << 0)
#define ESP_BLE_ADV_FLAG_GEN_DISC           (0x01 << 1)
#define ESP_BLE_ADV_FLAG_BREDR_NOT_SPT      (0x01 << 2)
#define ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT (0x01 << 3)
#define ESP_BLE_ADV_FLAG_DMT_HOST_SPT       (0x01 << 4)
#define ESP_BLE_ADV_FLAG_NON_LIMIT_DISC     (0x00 )

V = ‘0000 0110’,表示使用ESP_BLE_ADV_FLAG_GEN_DISC 和 ESP_BLE_ADV_FLAG_BREDR_NOT_SPT ,即使用通用广播发现模式,不支持BR/EDR。

依次类推:
第2个TLV数据组合为L = 3,T = 0x19, V = 0x0040 ,设置蓝牙外观显示。可以设置为手表、手机等等外观形式,这里设置成手机外观。
第3个TLV数据组合为L = 13,T = 0x09, V = CcBle-123456,为蓝牙名称
第4个TLV数据组合为L = 3, T = 0x03, V = 0x00ee, 为2byte广播UUID
第5个LTV数据组合为L = 5, T = 0x12,V = 6和16, 表示表示从机连接最小间隔和最大间隔时间。实际时间为 值*1.25毫秒

到此,一共5个LTV数据组合全部解析完成。
一共为5byte + L总长度(2+3+13+3+5) = 31byte,刚好与我们前面解析出来的31byte实际数据长度对应。

最后是3byte的CRC值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值