NRF52832学习笔记(11)——蓝牙MAC地址

一、背景

一个 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

静态设备地址是设备在上电时随机生成的地址,NRF52832 官方工程默认都是使用静态地址,其格式如下:


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

  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 中的一种。

二、分析广播包中蓝牙MAC地址

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



其中数据包第 6 部分:



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

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

其中数据包第 7 部分:



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

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

三、读取MAC地址

  1. 包含头文件
#include "ble_gap.h"
  1. 定义结构体变量
ble_gap_addr_t bleAddr;

BLE 的地址由 ble_gap_addr_t 进行管理:

/**@brief Bluetooth Low Energy address. */
typedef struct
{
  uint8_t addr_id_peer : 1;       /**< Only valid for peer addresses.
                                       This bit is set by the SoftDevice to indicate whether the address has been resolved from
                                       a Resolvable Private Address (when the peer is using privacy).
                                       If set to 1, @ref addr and @ref addr_type refer to the identity address of the resolved address.

                                       This bit is ignored when a variable of type @ref ble_gap_addr_t is used as input to API functions. */
  uint8_t addr_type    : 7;       /**< See @ref BLE_GAP_ADDR_TYPES. */
  uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format.
                                       @ref addr is not used if @ref addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */
} ble_gap_addr_t;
  • addr_id_peer:仅对匹配地址有效。此位由软件设置,以指示该地址是否已从可解析私密地址中解析(当匹配加密时)
  • addr_type:地址类型,作为传入参数时可忽略
  • addr:48-bit 的MAC地址数组,低字节在前,所以与我们实际看到的地址顺序相反
  1. 调用获取地址函数
    uint32_t sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)
sd_ble_gap_addr_get(&bleAddr);
  1. 将地址逆序并打印出来
#include "nrf_log.h"

uint8 address[6];
uint8 i;
for(i = 0; i < 6; i++)
{
  address[i] = bleAddr.addr[5 - i];    // 逆序
}

NRF_LOG_INFO("address:%02x", address[0]);
NRF_LOG_INFO("address:%02x", address[1]);
NRF_LOG_INFO("address:%02x", address[2]);
NRF_LOG_INFO("address:%02x", address[3]);
NRF_LOG_INFO("address:%02x", address[4]);
NRF_LOG_INFO("address:%02x", address[5]);

这样打印出来的地址就跟我们实际扫描到的地址顺序相同。



四、修改MAC地址

首先采用 sd_ble_gap_addr_get 读取官方默认的 MAC 地址,然后再默认地址+1,再用 sd_ble_gap_addr_set 写入到设备中。

void mac_set(void)
{
  ble_gap_addr_t addr;
  uint32_t err_code = sd_ble_gap_addr_get(&addr);
  APP_ERROR_CHECK(err_code);

  // Increase the BLE address by one when advertising openly.
  addr.addr[0] += 1;

  err_code = sd_ble_gap_addr_set(&addr);
  APP_ERROR_CHECK(err_code);
}

主函数中进行调用,注意,一定要在广播开始前设置,下次广播后新的 MAC 地址就设置成功。

/**@brief Application main function.
 */
int main(void)
{
    bool erase_bonds;

    // Initialize.
    uart_init();
    log_init();
    timers_init();
    buttons_leds_init(&erase_bonds);
    power_management_init();
    ble_stack_init();
    gap_params_init();
      mac_set();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

    // Start execution.
    advertising_start();

    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
}

新的 MAC 地址加1,设置成功。



• 由 Leung 写于 2020 年 2 月 19 日

• 参考:青风电子社区

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容