how to specify a public MAC address

To read the MAC addresses defined I use the following code (with CONFIG_BT_ID_MAX=2 in prj.conf):::

    bt_addr_le_t addr[CONFIG_BT_ID_MAX];    //space for random address and public address
    size_t count = 2;                       //request both addresses
    bt_id_get(addr, &count);                //count will contain the number of addresses returned

In reply, count is set to 1 hence only one address is defined. addr[0] contains an address of type random.
I order to define a public MAC address I got inspired by the following post:

https://devzone.nordicsemi.com/f/nordic-q-a/99585/config-for-using-sdc_hci_cmd-functions

This uses an hci command similar to setting TX power. I had to adapt it for a later version of SDK/Toolchain.
My code is as follows:

static int set_bd_addr(void)
{
    int err = 0;
    struct net_buf *buf;
    struct bt_hci_cp_vs_write_bd_addr *cmd_params;

    buf = bt_hci_cmd_create(BT_VS_CMD_BIT_WRITE_BDADDR , sizeof(*cmd_params));
    if (!buf) {
        printk("Could not allocate command buffer\n");
        return -ENOMEM;
    }

    cmd_params = net_buf_add(buf, sizeof(*cmd_params));

    cmd_params->bdaddr.val[0]= 0xCC;
    cmd_params->bdaddr.val[1]= 0xCC;
    cmd_params->bdaddr.val[2]= 0xCC;
    cmd_params->bdaddr.val[3]= 0xCC;
    cmd_params->bdaddr.val[4]= 0xCC;
    cmd_params->bdaddr.val[5]= 0xCC;

    err = bt_hci_cmd_send_sync(BT_VS_CMD_BIT_WRITE_BDADDR, buf, NULL);
    printk("err: %d \n",err);
    if (err) {
        printk("err: %d \n",err);
        return err;
    }

    printk("Successfully set bd addr \n");

    return 0;
}
I call set_bd_addr() before bl_enable(NULL).
The project built without errors for nrf15l15dk/nrf15l15/cpuapp.
Executing function bt_hci_cmd_send_sync does not return since I get the following fatal error:
[00:06:03.052,316] <err> os: ***** MPU FAULT *****
[00:06:03.052,322] <err> os:   Data Access Violation
[00:06:03.052,326] <err> os:   MMFAR Address: 0x12c1d
[00:06:03.052,336] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000004  r2/a3:  0x00012c1d
[00:06:03.052,342] <err> os: r3/a4:  0x200063c8 r12/ip:  0x00000000 r14/lr:  0x0002259f
[00:06:03.052,347] <err> os:  xpsr:  0x29000000
[00:06:03.052,351] <err> os: Faulting instruction address (r15/pc): 0x00022ca0
[00:06:03.052,369] <err> os: >>> ZEPHYR FATAL ERROR 19: Unknown error on CPU 0
[00:06:03.052,384] <err> os: Current thread: 0x20002ee0 (unknown)
[00:06:03.129,332] <err> os: Halting system
The development board is dead. I needed do an erase via Segger J-Flash.
Hence my question: How does one specify a public MAC address and how can one signal that is should be used ?
Parents
  • When the Softdevice controller is enabled, you will not be able to debug and step through code. You can set breakpoints, to look at things, but as soon as you step to far, or resume executing, the softdevice controller will have lost too many time critical events, and it will assert or hard fault. 

    Will I be able to reproduce what you are seeing on a DK? If so, can you zip and upload the application folder that you are using? What NCS version are you currently using?

    Best regards,

    Edvin

  • Hi,
    I include a project which shows the fault setting the MAC address.
    The project has plenty of other stuff in it - just ignore.
    Go in main at line 301.
    After flashing using the latest SDK and Toolchain (3.0.0) and flashing I get the following output:

    *** Booting nRF Connect SDK v2.8.0-a2386bfc8401 ***
    *** Using Zephyr OS v3.7.99-0bc3393fb112 ***
    [00:00:00.000,253] <inf> Blyott_Anchor: Starting Blyott_Anchor_v2a
    0x200194fc
    [00:00:00.002,931] <err> os: ***** SECURE FAULT *****
    [00:00:00.002,935] <err> os:   Address: 0x0
    [00:00:00.002,940] <err> os:   Attribution unit violation
    [00:00:00.002,949] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000004  r2/a3:  0x00000040
    [00:00:00.002,956] <err> os: r3/a4:  0x200135f4 r12/ip:  0x0000000c r14/lr:  0x000691f9
    [00:00:00.002,961] <err> os:  xpsr:  0x21000000
    [00:00:00.002,965] <err> os: Faulting instruction address (r15/pc): 0x000698ea
    [00:00:00.002,984] <err> os: >>> ZEPHYR FATAL ERROR 41: Unknown error on CPU 0
    [00:00:00.002,998] <err> os: Current thread: 0x20015d18 (unknown)
    [00:00:00.080,817] <err> os: Halting system

    mac_test.zip

  • Sorry for the late reply, but I struggled for a while with this one. But now I have something that works. As mentioned in one of the other tickets (I think it was the one mentioned in your main.c file), it was mentioned that public addresses are not very much used, which is probably why it was a bit difficult to find any good answers. 

    First of all, set_bd_addr() being called before bt_enable() was what caused your zephyr fatal error. So to begin with, I moved it after. I also did some modifications, and ended up with this:

    static int set_bd_addr(void)
    {
    	int err = 0;
    	struct net_buf *buf;
    	struct bt_hci_cp_vs_write_bd_addr *cmd_params;
    
    	buf = bt_hci_cmd_create(BT_HCI_OP_VS_WRITE_BD_ADDR ,
    				sizeof(*cmd_params));
    	if (!buf) {
    		LOG_ERR("Could not allocate command buffer\n");
    		return -ENOMEM;
    	}
    
    	cmd_params = net_buf_add(buf, sizeof(*cmd_params));
    	LOG_INF("%p\n",cmd_params);
    
    	cmd_params->bdaddr.val[0]= 0xCC;
    	cmd_params->bdaddr.val[1]= 0xCC;
    	cmd_params->bdaddr.val[2]= 0xCC;
    	cmd_params->bdaddr.val[3]= 0xCC;
    	cmd_params->bdaddr.val[4]= 0xCC;
    	cmd_params->bdaddr.val[5]= 0xCC;
    
        LOG_INF("preparing...");
    
    	err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_BD_ADDR, buf, NULL);
    	LOG_INF("err: %d \n",err);
    	LOG_INF("Successfully? set bd addr \n");
    
    	return err;
    }

    Then make sure to add CONFIG_BT_HCI_VS=y in prj.conf

    So then it returned successfully, but the public address was not being used. To do that, you need to restart the BT stack. So add this after set_bd_addr():

        err = bt_disable();
        if (err) {
            LOG_ERR("bt_disable, err %d", err);
        }
    
        err = bt_enable(NULL);
        if (err) {
            LOG_ERR("bt_enable, err %d", err);
        }

    That should work. Let me know if it doesn't. I'll add a copy of the modified sample, but note that I removed a lot of your functionality, just to see the basic advertisement after changing the address:

    6708.mac_test.zip

  • This works super.
    Thank you very very much for this professional reply.

Reply Children
No Data
Related