美文网首页ESP32
ESP32学习笔记(35)——蓝牙MAC地址

ESP32学习笔记(35)——蓝牙MAC地址

作者: Leung_ManWah | 来源:发表于2021-07-15 16:25 被阅读0次

    一、背景

    一个 BLE 设备,可以使用两种类型的地址(一个 BLE 设备可同时具备两种地址):

    • Public Device Address(公共设备地址)
    • Random Device Address(随机设备地址)可分为两类:
      • Static Device Address(静态设备地址)
      • Private Device Address(私密设备地址)又可分为两类:
        • Non-resolvable Private Address(不可解析私密地址)
        • Resolvable Private Address(可解析私密地址)

    1.1 公共设备地址 Public Device Address

    在通信系统中,设备地址是用来唯一识别一个物理设备的,如TCP/IP网络中的MAC地址、传统蓝牙中蓝牙地址等。对设备地址而言,一个重要的特性,就是唯一性。

    对于经典蓝牙(BR/EDR)来说,其设备地址是一个 48bits 的数字,称作“48-bit universal LAN MAC address”。正常情况下,该地址需要向 IEEE 申请,具有唯一性。

    这种地址分配方式在 BLE 中也保留了下来,就是公共设备地址(Public Device Address)。由 24-bit 的 company_id 和 24-bit 的 company_assigned 组成。


    高 24 位是公司标识,低 24 位公司内部自己赋值。

    1.2 随机设备地址 Random Device Address

    但是,在 BLE 时代,只有公共设备地址明显不够用了,有如下原因:

    1. 公共设备地址需要向 IEEE 购买,需要一笔开销。
    2. 公共设备地址的申请与管理相对繁琐、复杂,再加上 BLE 设备的数量众多(和传统蓝牙设备不是一个数量级的),导致维护成本增大。
    3. 安全因素。BLE 很大一部分的应用场景是广播通信,这意味着只要知道设备的地址,就可以获取所有的信息,这是很不安全的。因此固定的设备地址,加大了信息泄露的风险。

    为了解决上述问题,BLE 协议新增了一种地址:随机设备地址,即设备地址不是固定分配的,而是在设备启动后随机生成的。根据不同的目的,随机设备地址分为静态设备地址和私密设备地址。

    1.2.1 静态设备地址 Static Device Address

    静态设备地址是设备在上电时随机生成的地址,其格式如下:

    静态设备地址的特征可总结为:

    1. 最高两个 bit 为 “11”。
    2. 剩余的 46bits 是一个随机数,不能全部为0,也不能全部为1。
    3. 在一个上电周期内保持不变。
    4. 下一次上电的时候可以改变。但不是强制的,因此也可以保持不变。如果改变,上次保存的连接等信息,将不再有效。

    静态设备地址的使用场景可总结为:

    1. 46bits 的随机数,可以很好地解决“设备地址唯一性”的问题,因为两个地址相同的概率很小。
    2. 地址随机生成,可以解决公共设备地址申请所带来的费用和维护问题。

    1.2.2 私密设备地址 Private Device Address

    静态设备地址通过地址随机生成的方式,解决了部分问题。私密设备地址则更进一步,通过定时更新和地址加密两种方式,提高蓝牙地址的可靠性和安全性。根据设备地址是否加密,又分为两类:
    ① 不可解析私密地址 Non-resolvable Private Address
    不可解析私密地址和静态设备地址类似,不同之处在于不可解析私密地址会定时更新。更新的周期是由 GAP 规定的,称作 T_GAP(private_addr_int),建议值是 15 分钟。其格式如下:

    不可解析私密地址的特征可总结为:

    1. 最高两个 bit 为 “00”。
    2. 剩余的 46bits 是一个随机数,不能全部为0,也不能全部为1。
    3. 以 T_GAP(private_addr_int) 为周期,定时更新。

    ② 可解析私密地址 Resolvable Private Address
    可解析私密地址比较有用,它通过一个随机数和一个称作 identity resolving key(IRK) 的密码生成,因此只能被拥有相同 IRK 的设备扫描到,可以防止被未知设备扫描和追踪。其格式如下:

    可解析私密地址的特征可总结为:

    1. 高位 24bits 是随机数部分,其中最高两个 bit 为“10”,用于标识地址类型;低位 24bits 是随机数和 IRK 经过 hash 运算得到的 hash值,运算公式为 hash = ah(IRK, prand)。
    2. 当主端 BLE 设备扫描到该类型的蓝牙地址后,会使用保存在本机的 IRK,和该地址中的 prand,进行同样的 hash 运算,并将运算结果和地址中的 hash 字段比较,相同的时候,才进行后续的操作。这个过程称作 resolve(解析),如果不同则继续用下一个 IRK 做上面的过程,直到找到一个关联 IRK 或者一个也没找到。
    3. 以T_GAP(private_addr_int) 为周期,定时更新。哪怕在广播、扫描、已连接等过程中,也可能改变。
    4. Resolvable Private Address 不能单独使用,因此需要使用该类型的地址的话,设备要同时具备 Public Device Address 或者 Static Device Address 中的一种。

    1.3 分析广播包中蓝牙MAC地址

    使用抓包工具抓取类似如下数据包:



    其中数据包第 6 部分:



    其中 TxAdd 表示发送方的地址类型(0 为 public,1为 random)。
    RxAdd 表示接收方的地址类型。

    对于普通广播来说,只有 TxAdd 的指示是有效的,表示广播发送者的第一类型。而对于定向广播来说,TxAdd 和 RxAdd 都是有效的。

    其中数据包第 7 部分:



    如果是随机设备地址,则查看地址的最高两位。

    • 如果是 “11” 就是静态随机地址。
    • 如果是 “00” 就是不可解析私密地址。
    • 如果是 “01” 就是可解析私密地址,并执行上面说过的 ah 方法进行解析。

    二、API说明

    以下 MAC 地址接口位于 components\esp_system\include\esp_system.h

    2.1 esp_base_mac_addr_set

    esp_err_t esp_base_mac_addr_set(const uint8_t *mac)
    

    2.2 esp_read_mac

    typedef enum {
        ESP_MAC_WIFI_STA,
        ESP_MAC_WIFI_SOFTAP,
        ESP_MAC_BT,
        ESP_MAC_ETH,
    } esp_mac_type_t;
    
    esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
    

    以下随机地址接口位于 bt/host/bluedroid/api/include/api/esp_gap_ble_api.h

    2.3 esp_ble_gap_set_rand_addr

    2.4 esp_ble_gap_clear_rand_addr

    三、使用公共设备地址

    使用 examples\bluetooth\hci\controller_vhci_ble_adv 中的例程

    • 获取 MAC 地址:
    uint8_t mac[6] = {0};
    esp_read_mac(mac, ESP_MAC_BT);
    ESP_LOG_BUFFER_HEX(tag, mac, 6);
    
    • 设置 MAC 地址:
      注意:要在初始化蓝牙控制器接口 esp_bt_controller_init() 之前设置 MAC 地址。esp_base_mac_addr_set() 会在地址最后一位或上 0x01
    uint8_t mac[6] = {0xbc, 0xdd, 0xc2, 0xd1, 0xc5 ,0x6F};
    esp_base_mac_addr_set(mac);
    

    查看地址:


    四、使用随机设备地址

    使用 examples\bluetooth\bluedroid\ble\ble_ibeacon 中的例程
    注意:工程中默认使用公共设备地址。

    ble_adv_params.own_addr_type由公共设备地址 BLE_ADDR_TYPE_PUBLIC,改为随机设备地址 BLE_ADDR_TYPE_RANDOM

    static esp_ble_adv_params_t ble_adv_params = {
        .adv_int_min        = 0x20,
        .adv_int_max        = 0x40,
        .adv_type           = ADV_TYPE_NONCONN_IND,
        .own_addr_type      = BLE_ADDR_TYPE_RANDOM,
        .channel_map        = ADV_CHNL_ALL,
        .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
    };
    

    然后设置随机设备地址:

    esp_bd_addr_t mac = {0xD4, 0x5E, 0xEC, 0x0E, 0x7D, 0x9E};
    esp_ble_gap_set_rand_addr(mac);
    

    查看地址:



    • 由 Leung 写于 2021 年 7 月 15 日

    相关文章

      网友评论

        本文标题:ESP32学习笔记(35)——蓝牙MAC地址

        本文链接:https://www.haomeiwen.com/subject/irjppltx.html