This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Switching between random and normal mac address?

I'm using sd_ble_gap_address_set() to randomize mac address and it's working fine. But I'm confused about how to change it back to normal(initial value I see) once I wan't to stop randomizing my mac address.

I'm on nrf51-DK, softdevice 7.0 and sdk 6.1. Here is the condition snippet I'm using to randomize and normalize the mac address, only the random part works. I'm calling it right after ble_stack_init() and expecting it to work after stopping/starting advertising again as stated in the docs.

if(<condition_is_satisfied>) {
		// set interval for changing mac address
		opt.gap.privacy.interval_s = 10;
		err_code = sd_ble_opt_set(BLE_GAP_OPT_PRIVACY, &opt);
		APP_ERROR_CHECK(err_code);

		gap_address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
		err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &gap_address);
		APP_ERROR_CHECK(err_code);
	} else {
            // there is a problem here
		gap_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
		err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &gap_address);
		APP_ERROR_CHECK(err_code);
	}

Once the second part gets called with cycle mode none, I get a stable mac address but it's not the initial one I see. I don't understand what I'm doing wrong, any idea how can I go back to the initial mac address I've seen? (not a static one, but the very first mac address I see when I don't do any operations regarding the mac address).

EDIT:

Editing my question after Aryan's answer.

Changing the code and logic as below fixed my problem.

Prior to randomizing mac address, I save it's initial value using;

sd_ble_gap_address_get(&gap_address);

Then I save it inside non-volatile storage and load it back once I want to go back to normal mac address:

gap_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &initial_address);
APP_ERROR_CHECK(err_code);
Parents
  • You can do it in two ways

    1. save the original one before changing it using sd_ble_gap_address_get

    The Original device address is always present at NRF_FICR->DEVICEADD[0] and NRF_FICR->DEVICEADD[1]

    You can fetch it by ble_gap_addr_t gap_address

       gap_address.addr_type     = NRF_FICR->DEVICEADDRTYPE & 0x01UL;
    *((uint32_t PACKED *)&gap_address.addr[0]) = NRF_FICR->DEVICEADDR[0];
    *((uint16_t PACKED *)&gap_address.addr[sizeof(uint32_t)]) = (NRF_FICR->DEVICEADDR[1] & 0x0000FFFFUL);
    
        err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &gap_address);
    

    Since this is just reading, it can be done safely while softdevice is active.

  • I did not understand your comments. When the softdevice initializes it gets the device address and type from FICR and keeps the value inside its structures. when you change the value using sd_ble_gap_address_set, it does not change the value in FICR but changes it inside the softdevice structure (which is used in radio packets). This means that once you have called sd_ble_gap_address_set, softdevice completely forgot the original device address. It is upto the application to remember this before changing the value or the application can read it from FICR. So if you want the device address to reset to its inital state, you have to either restart the softdevice (like resetting the device) which will make the SD to fetch this value from FICR again or read FICR explicitly.

Reply
  • I did not understand your comments. When the softdevice initializes it gets the device address and type from FICR and keeps the value inside its structures. when you change the value using sd_ble_gap_address_set, it does not change the value in FICR but changes it inside the softdevice structure (which is used in radio packets). This means that once you have called sd_ble_gap_address_set, softdevice completely forgot the original device address. It is upto the application to remember this before changing the value or the application can read it from FICR. So if you want the device address to reset to its inital state, you have to either restart the softdevice (like resetting the device) which will make the SD to fetch this value from FICR again or read FICR explicitly.

Children
No Data
Related