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

Parents
  • Hi, 

    What type of address would you like to set? Bluetooth Low Energy comes with different address types, which you can read about in our DevAcademy course: https://academy.nordicsemi.com/topic/bluetooth-address/ 

    Only public address type is liable to a fee (to the IEEE registration authority), random addresses can be used freely. The default address used by the Bluetooth Stacks in nRF52833 is a random static address obtained from the DEVICEADDR[n] FICR registers (random number programmed during chip manufacturing).

    If you want to set Resolvable Private Addresses, you could use CONFIG_BT_PRIVACY

    Regards,
    Amanda H.

  • Hi Amanda,

    Thank you for your prompt response.

    I do not want to set the MAC address. I am happy to use the default address.

    The default address used by the Bluetooth Stacks in nRF52833 is a random static address obtained from the DEVICEADDR[n] FICR registers (random number programmed during chip manufacturing).

    According to Nordic's Academy Bluetooth-address page,

    "A random static address can be allocated and then fixed throughout the lifetime of the device. It can be altered at bootup, but not during runtime. "

    So, why am I seeing the random static MAC address of my device changing at runtime?

    Then when I restart (hard reset) the device it reverts back to the original MAC address.

    As far as I can make out, I am not doing anything in my application code to change it.

    Please explain what could be happening.

    Also, according to Nordic's documentation,

    "Factory information configuration registers (FICR) are pre-programmed in factory and cannot be erased by the user. "

    However, you said in your reply a random static address can be changed at bootup. Please explain how.

    Thank you.

    Kind regards

    Mohamed

  • Hi Amanda,

    Thank you. Clap

    But you still have not commented on why, before I added the option BT_LE_ADV_OPT_USE_IDENTITYmy device was sometimes changing its MAC address without going through a reset.                              According to Nordic's documentation this is not the expected behaviour.

    Kind regards

    Mohamed

  • Hi,

    Learner said:
    my device was sometimes changing its MAC address without going through a reset. 

    Could you explain the frequency and in what situation it changes the MAC address, in advertising or in connection? Which type of address do you use? Do you use CONFIG_BT_PRIVACY?

    Do you use a sample as a base to develop your application? If so, what is that?

    Could you provide the sniffer log and device log when you observe the MAC address change?

    -Amanda H.

  • Hi Amanda,

    Could you explain the frequency and in what situation it changes the MAC address, in advertising or in connection?

    As I stated in a previous message, the MAC address is very infrequent. The device can go for months without changing its address. I believe the change is occurring during advertising. The reason I noticed the change is because our proprietary application running under Windows 10 could not connect to the device anymore over BLE. So, I checked the list of BLE devices that the application can see and noticed the MAC address of the device has changed.

    Which type of address do you use?

    The default Static Random.

    Do you use a sample as a base to develop your application?

    No, I am using our own application.

    Note, this is not an isolated case; other users on Devzone have experienced the same problem, see Case ID: 313249.

    Could you provide the sniffer log and device log when you observe the MAC address change?

    It is going to be difficult because it may take months before the MAC address change can occur.

    Kind regards

    Mohamed

  • Hi,

    Learner said:
    As I stated in a previous message, the MAC address is very infrequent. The device can go for months without changing its address. I believe the change is occurring during advertising. The reason I noticed the change is because our proprietary application running under Windows 10 could not connect to the device anymore over BLE. So, I checked the list of BLE devices that the application can see and noticed the MAC address of the device has changed.

    That sounds so strange. With the information you provided, it's hard to say what could cause the issue. If there are device logs, sniffer logs, or reproduction instructions, they might help investigate the issue.  

    Regards,
    Amanda H.

  • 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

Reply
  • 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

Children
Related