硬汉嵌入式论坛

 找回密码
 立即注册
查看: 254|回复: 1
收起左侧

[技术讨论] Nordic获取设备和修改设备MAC地址的办法

[复制链接]

3

主题

8

回帖

17

积分

新手上路

积分
17
发表于 2025-4-30 14:56:02 | 显示全部楼层 |阅读模式
一、 NCS修改MAC地址的办法

每一个支持蓝牙功能的设备都被分配有一个独一无二的蓝牙 MAC 地址,就如同设备的 “身份证号码”。比如,你有两部不同品牌和型号的手机,它们的蓝牙 MAC 地址是不同的。这使得在蓝牙网络里,每个设备都能被精准识别。
Nordic芯片在FICR寄存器里面有一个随机的MAC地址,如果默认不改动的话,蓝牙协议栈使用的就是出厂设置的MAC地址,下面我讲以下如何获取默认的MAC地址已经如何修改MAC地址




一、 如何修改Nordic的芯片地址



nRF52_SDK

1.1获取MAC地址

```c
void get_ble_address(void)
{
    ble_gap_addr_t addr;
    uint32_t err_code = sd_ble_gap_addr_get(&addr);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_ERROR("Failed to get BLE address, error code: %d", err_code);
        return;
    }

    NRF_LOG_INFO("BLE Address: %02X:%02X:%02X:%02X:%02X:%02X",
                 addr.addr[5], addr.addr[4], addr.addr[3],
                 addr.addr[2], addr.addr[1], addr.addr[0]);
}
```



1.2 修改MAC地址

```
void set_ble_address(void)
{
    ble_gap_addr_t new_addr;
    new_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    new_addr.addr[0] = 0x01;
    new_addr.addr[1] = 0x02;
    new_addr.addr[2] = 0x03;
    new_addr.addr[3] = 0x04;
    new_addr.addr[4] = 0x05;
    new_addr.addr[5] = 0x06;

    uint32_t err_code = sd_ble_gap_addr_set(&new_addr);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_ERROR("Failed to set BLE address, error code: %d", err_code);
    }
    else
    {
        NRF_LOG_INFO("BLE address set successfully");
    }
}
```

二、 NCS修改NCS地址
这里我是使用NCS2.9.0版本peripheral_uart例程,硬件使用nRF54L15的DK
#### 获取MAC地址

```
static void get_mac(uint8_t mac_address[6])
{

        unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
        unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
        const uint8_t* part_0 = (const uint8_t*)&device_addr_0;
    const uint8_t* part_1 = (const uint8_t*)&device_addr_1;
        mac_address[0] = part_1[1];
        mac_address[1] = part_1[0];
        mac_address[2] = part_0[3];
        mac_address[3] = part_0[2];
        mac_address[4] = part_0[1];
        mac_address[5] = part_0[0];
}
//main bt_enable函数之后调用
uint8_t mac[6];
get_mac(mac);
LOG_INF("MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
```



2.1 修改MAC地址

```
static void set_mac()
{
        int ret;
            bt_addr_le_t addr;
    ret = bt_addr_le_from_str("FF:EED:CC:BB:AA", "random", &addr);
    if (ret) {
        printk("Invalid BT address (err %d)\n", ret);
    }

    ret = bt_id_create(&addr, NULL);
    if (ret < 0) {
        printk("Creating new ID failed (err %d)\n", ret);
    }
}
//main bt_enable函数之后调用
```



三、 如下是LOG日志

这里可能就有人问,作者,为啥我获取的是4C:BD:FF:FC:79:1B

实际设备广播的MAC地址是CC:BD:FF:FC:79:1B呢?

实际上是根据蓝牙规范,在核心规范 5.3 第 6 卷第 B 部分第 1.3.2.1 章中,对于设备地址的最高两个有效位必须等于1,所以4C|C0就结果就是CC








#### 蓝牙广播未修改的地址:




#### 蓝牙广播修改的地址






### 动态MAC地址

还有一种私密的MAC,在每次重启设备的时候,MAC地址都会变化,目的是不想让别人知道他的MAC地址,目的是为了增强蓝牙设备的隐私性。

蓝牙动态 MAC 地址是通过特定算法生成的,该算法使用了一个私钥(Identity Resolving Key,IRK)和一个随机数。在解析时,需要有相同的私钥,然后通过生成可能的动态 MAC 地址并与接收到的地址进行对比来完成解析

启用这个功能只需要在prj.conf文件添加如下的宏:

`CONFIG_BT_PRIVACY=y`

可以通过bt_id_create看到,配置了这个IRK和`CONFIG_BT_PRIVACY=y`宏,就启动了动态MAC地址,但是具体APP怎么解析我没有使用过,对动态MAC地址有兴趣的朋友可以深入学习一下




回复

使用道具 举报

1

主题

380

回帖

383

积分

高级会员

积分
383
发表于 2025-4-30 17:49:19 | 显示全部楼层
还能在这看到NCS?支持
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-11 19:48 , Processed in 0.291644 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表