nRF52-Note(06)-广播Advertising

一、开发环境及工具

  1. nRF5 SDK v15.3.0

  2. IAR For ARM V7.80.4 / Keil uVision5(MDK-ARM) V5.33

  3. Bluetooth Core Specification V4.2 / V5.x

  4. 此工程源码下载路径 : https://gitee.com/amx/nrf52xx-project

  5. 参考好文链接(部分内容从其中摘取):

    https://www.cnblogs.com/someone-device/p/12213388.html

    https://blog.csdn.net/zhoutaopower/article/details/95104632

    http://www.wowotech.net/sort/bluetooth

    https://blog.csdn.net/Hh20161314/article/details/104501877

    https://blog.csdn.net/qq_36347513/article/details/104264490


二、nRF52系列Bluetooth 5.x特性

在这里插入图片描述


三、广播信道

  1. 在蓝牙核心规范V4.2中,广播信道使用37/38/39三个通道,其余37个是数据通道:

在这里插入图片描述


四、数据结构

  1. BLE数据包结构:preamble(前导码/报头)、access address(接入地址)、PDU(数据包)、CRC(校验码)

在这里插入图片描述


  1. PDU分为两类,广播类型PDU数据类型PDU

  2. 广播(Advertising)是一种单向的发送机制。想要被搜索到的设备可以以20毫秒到 10秒钟的时间间隔发送一段数据包。使用的时间间隔越短,电池消耗的越快,但设 备被发现的速度也就会快。数据包长度最多47个字节,由以下部分组成:

    - 1 byte preamble(1字节做报头)
    - 4 byte access address(4字节做地址)
    - 39 bytes advertising channel PDU(39个字节用于PDU数据包)
    - 3 bytes CRC(3个字节用于CRC数据校验)
    
  3. 下图是广播通道PDU分解:

在这里插入图片描述

- 对于广告通信信道,地址部分永远都是0x8E89BED6
- 对于其它数据信道,地址部分由不同的连接决定
- PDU数据也拥有自己的数据报头:2个字节:声明有效载荷数据的长度和类型——设备是否支持连接等等)和有效载荷数据(最多37个字节)
- 有效载荷数据中的头6个字节是设备的MAC地址,所以实际信息数据最高可占31个字节

在这里插入图片描述

  1. 在Header中PDU Type分下面7种(四个广播类型的PDU、两个扫描类型的PDU、一个发起连接PDU):

在这里插入图片描述

  1. 在Header中Length: PDU的长度,6 bits,有效范围 6-37 octets

  2. Header成员间的关系:

在这里插入图片描述

在这里插入图片描述

  1. Payload部分分解(ADV_IND类型):

在这里插入图片描述

可以看到,AdvData由一个个AD Structure组成,每个AD Structure包含3个部分:

  • AD length:AD Type 和AD Data的长度
  • AD Type:AD Data的数据含义
  • AD Data:AD Type所指示的数据

结合函数ble_advdata_encode(),对理解AD Structure会有更深的印象:

ret_code_t ble_advdata_encode(ble_advdata_t const * const p_advdata,uint8_t             * const p_encoded_data,uint16_t            * const p_len);

在ble_gap.h中定义的AD Type类型:

/**@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. */
#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA          0xFF /**< Manufacturer Specific Data. */
/**@} */

五、扫描响应包

广播包有两种:广播数据包(Advertising Data)和扫描相应包(Scan Response),其中广播数据包是每个设备必须广播的,而扫描响应包是可选的。

每个包都是 31 个字节,数据包中分为有效数据(significant)和无效数据(non-significant)两部分:

  1. 有效数据部分:包含若干个广播数据单元,称为 AD Structure。AD Structure 的组成是:第一个字节是长度值 Len,表示接下来的 Len 个字节是数据部分。数据部分的第一个字节表示数据的类型 AD Type,剩下的 Len - 1 个字节是真正的数据 AD Data。其中 AD Type 非常关键,决定了 AD Data 的数据代表的是什么和怎么解析。
  2. 无效数据部分:因为广播包的长度必须是 31 个字节,如果有效数据部分不到 31 个字节,剩下的就用 0 补全。这部分的数据是无效的,解析时忽略即可。
    而扫描响应包是为了给广播一个额外的 31 字节数据,用于主机 主动扫描 情况下,反馈数据使用。

不管广播数据包还是扫描响应包,都只提供 31 个字节的空间,因此需要注意可使用的空间。如果在配置广播数据时,长度大于31字节,会导致运行报错或者广播名称自动变短(nrf52xxx SDK 15.3版本)。

比如私有任务的 128bit UUID(占用较多字节),我们需要反馈给主机的时候,我们可以采用扫描响应包的方式。

在这里插入图片描述

六、代码配置

  1. 主要初始化函数,方式一(使用ble_advertising_init和ble_advertising_conn_cfg_tag_set):

    /**@brief Function for initializing the Advertising functionality.*/
    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;init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);init.srdata.uuids_complete.p_uuids  = m_adv_uuids;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.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);
    }
    
  2. 方式二(可配置更多信息,提取了ble_advertising_init和ble_advertising_conn_cfg_tag_set内容来实现):

    /**@brief Struct that contains pointers to the encoded advertising data. */
    static ble_gap_adv_data_t m_adv_data =
    {.adv_data ={.p_data = m_enc_advdata,.len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX},.scan_rsp_data ={.p_data = m_enc_scan_response_data,.len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX}
    };static void advertising_init(void)
    {ret_code_t    err_code;ble_advdata_t advdata;ble_advdata_t srdata;// Build and set advertising data.memset(&advdata, 0, sizeof(advdata));advdata.name_type          = BLE_ADVDATA_FULL_NAME;advdata.include_appearance = true;advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;memset(&srdata, 0, sizeof(srdata));srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);srdata.uuids_complete.p_uuids  = m_adv_uuids;err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);APP_ERROR_CHECK(err_code);err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);APP_ERROR_CHECK(err_code);ble_gap_adv_params_t adv_params;// Set advertising parameters.memset(&adv_params, 0, sizeof(adv_params));adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;adv_params.duration        = APP_ADV_DURATION;adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;adv_params.p_peer_addr     = NULL;adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;adv_params.interval        = APP_ADV_INTERVAL;err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);APP_ERROR_CHECK(err_code);
    }
    
  3. 可仿真查看广播实例m_advertising(IAR或MDK中),可以看到广播的数据内容:

在这里插入图片描述

  1. 空中抓包数据示例:

在这里插入图片描述



本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部