【广播数据包结构讲解】

【BLE】广播数据包结构讲解,五颗蓝牙芯片对比_自定义

广播数据包的讲解网上可参考的也挺多,讲解了整个数据包的每个字节每个位的功能描述,非常详细。

今天我们换个方式,按照代码编写的方式,只要是被SDK封装的部分都不做考虑,例如报头、crc校验等,讲讲应用层需要关心的部分,对比下五颗蓝牙芯片的广播包数据。

上图所示为广播包的结构图,需要注意的是数据段最大为37字节,其中广播设备的mac地址占用6字节,所以广播最大的有效的数据是31字节。

 

广播数据结构

广播数据包最长31字节,而这31字节又被拆成很多小数据包,每个小数据包代表一类广播数据。例如有设备名称数据包,外观数据包,发射功率数据包,服务UUID数据包,服务数据数据包,厂商自定义数据包。

每个小数据包结构如下:

{    unsigned char length;        //整数据长度-1    unsigned char type;          //数据类型    unsigned char data[length-1];//数据}

举个例子:如果我全部使用自定义数据包,length=30,type=0xff,data[29],真实能够填充的就是29个字节

广播数据包类型type

type值是蓝牙联盟定义的,全球统一,宏的命名是每个厂家自己定义的,如下是nordic sdk的定义。



/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
 * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
 * @{ */
#define BLE_GAP_AD_TYPE_FLAGS                               0x01 /**< Flags for discoverability. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE   0x02 /**< Partial list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE         0x03 /**< Complete list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE   0x04 /**< Partial list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE         0x05 /**< Complete list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE  0x06 /**< Partial list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE        0x07 /**< Complete list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME                    0x08 /**< Short local device name. */
#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME                 0x09 /**< Complete local device name. */
#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL                      0x0A /**< Transmit power level. */
#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE                     0x0D /**< Class of device. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C               0x0E /**< Simple Pairing Hash C. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R         0x0F /**< Simple Pairing Randomizer R. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE           0x10 /**< Security Manager TK Value. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS          0x11 /**< Security Manager Out Of Band Flags. */
#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE     0x12 /**< Slave Connection Interval Range. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT       0x14 /**< List of 16-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT      0x15 /**< List of 128-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA                        0x16 /**< Service Data - 16-bit UUID. */
#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS               0x17 /**< Public Target Address. */
#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS               0x18 /**< Random Target Address. */
#define BLE_GAP_AD_TYPE_APPEARANCE                          0x19 /**< Appearance. */
#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL                0x1A /**< Advertising Interval. */
#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS         0x1B /**< LE Bluetooth Device Address. */
#define BLE_GAP_AD_TYPE_LE_ROLE                             0x1C /**< LE Role. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256            0x1D /**< Simple Pairing Hash C-256. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256      0x1E /**< Simple Pairing Randomizer R-256. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID             0x20 /**< Service Data - 32-bit UUID. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID            0x21 /**< Service Data - 128-bit UUID. */
#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE             0x22 /**< LE Secure Connections Confirmation Value */
#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE                   0x23 /**< LE Secure Connections Random Value */
#define BLE_GAP_AD_TYPE_URI                                 0x24 /**< URI */
#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA                 0x3D /**< 3D Information Data. */

根据上面的定义,我们解析下上篇文章中,广播数据包的信息。

ESP32的广播数据代码:(广播包数据最多31的字节)

static void hci_cmd_send_ble_set_adv_data(void)
{
    char *adv_name = "ESP-BLE-HELLO";
    uint8_t name_len = (uint8_t)strlen(adv_name);
    uint8_t adv_data[31] = {0x02, 0x01, 0x06, 0x0, 0x09};
    uint8_t adv_data_len;

    adv_data[3] = name_len + 1;
    for (int i = 0; i < name_len; i++) {
        adv_data[5 + i] = (uint8_t)adv_name[i];
    }
    adv_data_len = 5 + name_len;

    uint16_t sz = make_cmd_ble_set_adv_data(hci_cmd_buf, adv_data_len, (uint8_t *)adv_data);
    esp_vhci_host_send_packet(hci_cmd_buf, sz);
}

【BLE】广播数据包结构讲解,五颗蓝牙芯片对比_BLE_02

 

看下其他几家广播数据

 

  • TI的CC254X,可以自己分析分析,内部有UUID了,让扫描者(手机)提前知道我有那些功能。

static uint8 advertData[] =
{
  //自定义的广播数据段
  0x03,
  GAP_ADTYPE_MANUFACTURER_SPECIFIC,
  0,//自定义数据1
  0,//自定义数据2
  
  // Flags; this sets the device to use limited discoverable
  // mode (advertises for 30 seconds at a time) instead of general
  // discoverable mode (advertises indefinitely)
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
 
  // service UUID, to notify central devices what services are included
  // in this peripheral
  0x03,   // length of this data
  GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
  LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
  HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
};
  • 瑞昱的RTL87XX,里面有个0xFF类型的小数据包,下面有他的结构解释图。

static uint8_t advertData[] =
{
    0x02,
    GAP_ADTYPE_FLAGS,
    GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

    0x08,           // length     
    0x09,           // type="Complete local name" 
    'R', 'T', 'L', '8', '7', '6','2',  
    
    0x0F,                           /* length     */
    0xFF,                           /* type="GAP_ADTYPE_MANUFACTURER_SPECIFIC" */
    0x00, 0x00,                     /* company Id*/
    0x00,0x00,0x00,0x00,0x00,0x00,  /*MAC Address*/
    0x01,                            /*TYPE=0x01,0x02,0x03,0x04*/
    0x01,0x00,                      /**/
    0x00,0x00,0x00,
};

【BLE】广播数据包结构讲解,五颗蓝牙芯片对比_自定义_03

0xFF主要用于厂商信息和自定义数据,数据区前两个字节是芯片的生产厂家(也可自定义),后面数据自定义。上面图片的长度有问题,不说了。

  • 沁恒的CH579,中规中矩,一个flag,一个uuid

 

static uint8 advertData[] = 
{ 
  // flags
  0x02,
  GAP_ADTYPE_FLAGS,
  GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
  // service UUIDs
  0x05,
  GAP_ADTYPE_16BIT_MORE,
  LO_UINT16(HEARTRATE_SERV_UUID),
  HI_UINT16(HEARTRATE_SERV_UUID),
  LO_UINT16(BATT_SERV_UUID),
  HI_UINT16(BATT_SERV_UUID)
};
  • nordic,它就是封装了一层,ble_advertising_init()内部又进行拆解,然后放入协议栈,可能协议栈(不开源)组合成类似的。已注释。

static void advertising_init(void)//广播初始化
{
    ret_code_t             err_code;
    ble_advertising_init_t init;

    memset(&init, 0, sizeof(init));

    init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;//设备名称
    init.advdata.include_appearance      = true;//外观
    init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;//flag:一般可发现模式,不支持BR/EDR
    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids  = m_adv_uuids;//首要服务的UUID

    init.config.ble_adv_fast_enabled  = true;//快速广播模式
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;//广播间隔
    init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;//广播持续时间
    init.config.ble_adv_fast_timeout  = 0;//广播持续时间

    init.evt_handler = on_adv_evt;//广播回调

    err_code = ble_advertising_init(&m_advertising, &init);//广播模块初始化
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);//连接设置标记:没啥用,为了以后使用
}

资料下载

市面上nordic的资料最多,我搜集了些,大家需要的话,自行下载。

公众号后台回复关键词【52832】,发送后收到链接即可下载。

【BLE】广播数据包结构讲解,五颗蓝牙芯片对比_BLE_04