nRF52833 MAC Address ramdonly changing while advertising

Hello,

I am experiencing instances when my device (peripheral) MAC address changes randomly while the device is running and advertising.

MAC address changed during runtime from C7:2A:7D:C9:44:39 to 17:8B:E9:C7:E4:A1
MAC address reverted back from 17:8B:E9:C7:E4:A1 to C7:2A:7D:C9:44:39  after a reset/restart.

When this happens my other BLE PC application (central) cannot connect to it. However, if I reset/restart my peripheral device the original address is restored and my central can connect again. According to the Bluetooth documentation a static address does not change until a power cycle.

Below are the boot-up logs showing the 'static' address I usually see.

[00:01:16.123,107] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:01:16.123,107] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
[00:01:16.123,138] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 2.6 Build 99
[00:01:16.123,931] <inf> bt_hci_core: Identity: C7:2A:7D:C9:44:39 (random)
[00:01:16.123,931] <inf> bt_hci_core: HCI: version 5.2 (0x0b) revision 0x0000, manufacturer 0x05f1
[00:01:16.123,931] <inf> bt_hci_core: LMP: version 5.2 (0x0b) subver 0xffff

According to the above log from bt_hci_core,

[00:01:16.123,931] <inf> bt_hci_core: Identity: C7:2A:7D:C9:44:39 (random)

The MAC address is supposed to be random, yet every time I reset my device after I notice a change in its MAC address, it reverts back to the old address. This does not look like a random address. So, what is meant by 'random' in this context?

Note, I have had a look at other similar cases e.g. Case ID: 313249 but no explanation or solution has been provided yet.

I would appreciate it if you could respond as soon as possible. Thank you.

Kind regards

Mohamed

  • Hi Amanda,

    Apologies for not responding earlier. I was away on holiday.

    Unfortunately, there is no specific way to reproduce this anomaly. In fact, it happens very rarely, perhaps once in few months. I have added some logging in my code so that if/when it happens I will share with you the logs. Please have a look at the attached code I added.

    /**
     *****************************************************************************************************************************************************
     *  @brief  Reads the static BLE MAC address of the device (local) from the structure
     *          bt_hci_vs_static_addr then compare to the one stored in the FICR register.
     *          If the two do not match then a device reset is forced.
     *
     *  @return Non Zero - If the BLE MAC address is read successfully
     *          Zero     - If the BLE MAC address is NOT read successfully
     *
     *****************************************************************************************************************************************************
     */
    int bluetooth_read_static_addr( void )
    {
        struct bt_hci_vs_static_addr    addr[1];
        static char                     addr_str[BT_ADDR_STR_LEN];
        int                             addr_count;
    
        addr_count = bt_read_static_addr( addr, 1 );
    
        if ( addr_count > 0 )
        {
            bt_addr_to_str( &(addr[0].bdaddr), addr_str, sizeof(addr_str) );
            LOG_INF( "BT addr: %s\n", &addr_str );
            LOG_HEXDUMP_DBG( addr_str,  sizeof(addr_str),   "Static Addr" );
    
            /* Read the source (local?) MAC address from the FICR register */
            {
                uint8_t mac_address[6];
                unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
                unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
    
                LOG_INF( "device_addr_0 = 0x%X, device_addr_1 = 0x%X", device_addr_0, device_addr_1 );
    
                const uint8_t* part_0 = (const uint8_t*)(&device_addr_0);
                const uint8_t* part_1 = (const uint8_t*)(&device_addr_1);
    
                /* According to the BLE spec on valid MAC addresses, in Core Spec 5.3, Vol 6,
                 * Part B, §1.3.2.1, the two MSB of the address must be equal to 1 for a static
                 * device address. If you don't do this, it will not match what you get with the
                 * bt_read_static_addr() and bt_conn_get_info() functions.
                 */
                mac_address[5] = part_1[1] | 0xC0;
                mac_address[4] = part_1[0];
                mac_address[3] = part_0[3];
                mac_address[2] = part_0[2];
                mac_address[1] = part_0[1];
                mac_address[0] = part_0[0];
    
                LOG_HEXDUMP_DBG( mac_address,  sizeof(mac_address),   "FICR Static Addr" );
    
                /* compare the local MAC address with the one read from the FICR register */
                if ( memcmp( &(addr[0].bdaddr.val), mac_address, sizeof(mac_address) ) )
                {
                     LOG_WRN( "Local MAC address does not match FICR" );
    
                    /* Maybe we should also raise an alarm to flag this event */
                    /*!!!TBD event_AddHighPriority(EV_HOME_STATION_RESET); */
    
                    /* Reboot system with a software reset to retrieve the static random MAC address from the FICR */
                    system_Reset();
                }
            }
        }
    
        return addr_count;
    }
    
    

    Are you interested in any other specific logs ?

    I noticed when I run the above code I see these errors 

    <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().

    See below the output of my code in the debugger window.

    [00:00:25.395,416] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:25.395,416] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:25.409,820] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:25.409,820] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:26.231,933] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:26.232,696] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:26.281,250] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:26.281,280] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:27.281,158] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:27.281,188] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:27.281,860] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:27.283,172] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:28.281,066] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:28.281,097] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:29.281,250] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:29.281,280] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:29.284,210] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:29.285,308] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:30.281,158] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:30.281,188] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:31.281,005] <inf> bt: BT addr: C7:2A:7D:C9:44:39

    [00:00:31.281,005] <inf> bt: device_addr_0 = 0x7DC94439, device_addr_1 = 0x70F3072A
    [00:00:31.286,132] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().
    [00:00:31.287,200] <err> log: argument 0 in source bt log message "BT addr: " missinglog_strdup().

    It seems that the error is caused by this line of code,

    LOG_INF( "BT addr: %s\n", &addr_str );

    Can you please explain why this error is manifesting itself now and how to get rid of it. I use LOG_INF throughout my code but I don't see this error except in the code attached above,

    Thank you.

    Kind regards

    Mohamed

Related