配置蓝牙广播地址类型

esp32-s3 如何配置蓝牙广播地址类型

概述

1 BLE_ADDR_TYPE_PUBLIC

这个是蓝牙的公共地址,它可以使用 esp32-s3 自带的,也可以使用自己设置,这个地址设置好了之后就是一直不变的。

1.1 自己设置 mac 地址

/* 
设置 MAC 地址:
注意:要在初始化蓝牙控制器接口 esp_bt_controller_init() 之前设置 MAC 地址。esp_base_mac_addr_set() 会在地址最后一位或上 0x01        也有可能是加2
*/
uint8_t mac[6] = {0xbc, 0xdd, 0xc2, 0xd1, 0xc5 ,0x6F};
esp_base_mac_addr_set(mac);
//基本MAC必须是单播MAC(第一个字节的最低有效位必须为零)。
//E (403) system_api: Base MAC must be a unicast MAC

1.2 使用默认的 mac 地址

img

2 BLE_ADDR_TYPE_RANDOM

BLE_ADDR_TYPE_RANDOM 表示随机静态地址(Random Static Address),是一种固定的、不变的地址类型。虽然它也是随机生成的,但在设备生命周期内不会更改。

每次电源重启后设备可选择将其静态设备地址初始化并赋予新的静态地址值。设备完成初始化后在下一次电源重启前不得再修改其静态地址值。

备注: 设备的静态地址修改后存储其原来地址的对等设备将无法与其自动重连。

2.1 静态随机地址配置代码

static esp_ble_adv_params_t hidd_adv_params = {
    .adv_int_min        = 0x20,
    .adv_int_max        = 0x30,
    .adv_type           = ADV_TYPE_IND,
    .own_addr_type      = BLE_ADDR_TYPE_RANDOM,
    //.peer_addr            =
    //.peer_addr_type       =
    .channel_map        = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

//设置地址的位置最好在广播数据配置之前,也就是 esp_ble_gap_config_adv_data 函数之前
// esp_ble_gap_config_local_privacy(true);  这句是不需要的,是私有可解析的地址才会用到
uint8_t test_mac[6];
esp_fill_random(test_mac,6);
test_mac[0] = test_mac[0] | ((0x01 << 7) | (0x01 << 6));
esp_ble_gap_set_rand_addr(test_mac);
esp_ble_gap_config_adv_data(&hidd_adv_data);

3 BLE_ADDR_TYPE_RPA_PUBLIC

3.1 ble_addr_type_rpa_public 的使用示例

  1. 将 BLE 设备的地址类型设置为 "ble_addr_type_rpa_public"。
  2. 在设备启动时,生成一个随机数作为低 24 位,并将上 24 位设置为公共设备 ID。
  3. 将生成的地址广播出去,以供其他设备扫描和连接。

这样,其他设备就可以使用公共设备 ID 来识别设备,并且每次设备启动时都会生成一个新的随机数,从而提高了设备的安全性和隐私性。同时,由于地址仍然是可解析的,因此其他设备可以继续与该设备通信。

这种类型的地址需要进行购买吗?

4 BLE_ADDR_TYPE_RPA_RANDOM

4.1 不可解析私有地址配置

不可解析私有地址随机部分和随机静态地址的随机部分是一样的,个人理解这两个地址的不同就在于,随机静态地址在电源重启之前都不能改变其地址。而不可解析私有地址可以在每次广播之前都可以改变自己的地址。

static esp_ble_adv_params_t hidd_adv_params = {
    .adv_int_min        = 0x20,
    .adv_int_max        = 0x30,
    .adv_type           = ADV_TYPE_IND,
    .own_addr_type      = BLE_ADDR_TYPE_RPA_RANDOM,
    //.peer_addr            =
    //.peer_addr_type       =
    .channel_map        = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};


//在蓝牙设备配置广播数据之前,设定一次蓝牙的 MAC 地址
// esp_ble_gap_config_local_privacy(true); // 这句是不需要的,是私有可解析的地址才会用到
uint8_t test_mac[6];
esp_fill_random(test_mac,6);
test_mac[0] = test_mac[0] & (~((0x01 << 7) | (0x01 << 6)));
esp_ble_gap_set_rand_addr(test_mac);
esp_ble_gap_config_adv_data(&hidd_adv_data);

//每次断开连接之后,重新进行广播时,都重新设立一个 MAC 地址
case ESP_HIDD_EVENT_BLE_DISCONNECT: {
    sec_conn = false;
    ESP_LOGI(HID_DEMO_TAG, "ESP_HIDD_EVENT_BLE_DISCONNECT");
    uint8_t test_mac[6];
    esp_fill_random(test_mac,6);
    test_mac[0] = test_mac[0] & (~((0x01 << 7) | (0x01 << 6)));
    esp_ble_gap_set_rand_addr(test_mac);
    esp_ble_gap_start_advertising(&hidd_adv_params);
    break;
}

4.2 可解析私有地址配置

只要设备里面保存的那几个密钥不改变,设备断电、重启等,都不会影响已配对设备的连接。但是删除配对之后就需要重新交换密钥才能连接了。

可解析地址对于未配对的设备来说是地址随机的,但是已配对的设备来说,这个地址却是已知的。

static esp_ble_adv_params_t hidd_adv_params = {
    .adv_int_min        = 0x20,
    .adv_int_max        = 0x30,
    .adv_type           = ADV_TYPE_IND,
    .own_addr_type      = BLE_ADDR_TYPE_RPA_RANDOM,
    //.peer_addr            =
    //.peer_addr_type       =
    .channel_map        = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

// 可解析私有地址,只需要这一句(esp_ble_gap_config_local_privacy)即可,它的地址会由系统自动生成。
//这一句的最佳位置就是在配置广播数据之前。
esp_ble_gap_config_local_privacy(true);
esp_ble_gap_config_adv_data(&hidd_adv_data);

  1. 配对成功之后,改变广播地址类型,手机扫描到的广播地址仍然不会改变。此时只有先忘记配对,然后才能看到广播地址的改变。
  2. 可解析私有地址是可以实现自动重连的,不可解析私有地址不能实现自动重连。
  3. esp_ble_gap_set_rand_addr 此函数设置应用程序的静态随机地址和不可解析专用地址。

参考文档

  1. RPA和Static Random Address_ble_rpa
  2. 低功耗蓝牙(BLE)中的设备地址
posted @ 2023-05-06 23:57  SpinJump  阅读(1217)  评论(0编辑  收藏  举报