Hi
I am developing a healthcare device which is paired via NFC. The NFC pairing is non-standard as it needs to work on iOS, I place records for a MAC and a service UUID on the tag. My app learns these from NFC then makes a pairing. The service ID is used to facilitate pairing on iOS as the iOS low level code takes an obfuscated MAC and I have no way to generate this from the real MAC (another apple-ism).
Due to the fact that the medial device will be passed between patients and the previous patient might still be in the waiting room after config for a new patient, I need to randomise the MAC address as well as my service UUID when the device is reconfigured for the next patient. Simply deleting the pairing is not really ideal as the old patients phone will continuously try (and fail) to connect with the reconfigured app.
Using address type: BLE_GAP_ADDR_TYPE_RANDOM_STATIC does not appear to guarantee me a new MAC address every time the code is re-started from main(). The medical device is battery operated, it stores nothing in NVM, when it is restarted it needs a new MAC,and service UUID I have ended up doing this manually to guarantee me a new MAC. Changing the MAC guarantees that the previous patients device wont even try to connect to the reconfigured recorder.
My questions basically are:
1) Is there a better way?
2) Are there any dangers in doing it the way I am (eg addresses considered invalid that centrals will refuse to connect to?)
My code (test code!) is thus (based on the RNG sample)
static void gap_params_init(void) { ret_code_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); ble_gap_addr_t *DeviceMacAddress = GetRandomDeviceAddr(); err_code = sd_ble_gap_addr_set(DeviceMacAddress); ble_gap_addr_t* GetRandomDeviceAddr(void) { ble_gap_addr_t *RndBleAddr = (ble_gap_addr_t*)malloc(sizeof(ble_gap_addr_t)); uint8_t pRnd[MAC_ADDR_LEN]; if (!GetRandomBytes(pRnd,MAC_ADDR_LEN)) return NULL; RndBleAddr->addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; //Copy over the Random MAC for (int i = 0; i<MAC_ADDR_LEN; i++) { RndBleAddr->addr[MAC_ADDR_LEN-1-i] = pRnd[i]; } NRF_LOG_INFO("Randomised Current MAC: %s",GetStringFromHex(pRnd,MAC_ADDR_LEN)); NRF_LOG_FLUSH(); return RndBleAddr; } bool GetRandomBytes(uint8_t *randomBytes,uint8_t noOfBytes) { if (randomBytes == NULL) return false; random_vector_generate(randomBytes,noOfBytes); //Appear to have to do this twice - first attempt gets nothing, delay is required... nrf_delay_ms(100); uint8_t length = random_vector_generate(randomBytes,noOfBytes); if (length != noOfBytes) return false; return true; } static uint8_t random_vector_generate(uint8_t * p_buff, uint8_t size) { uint32_t err_code; uint8_t available; nrf_drv_rng_bytes_available(&available); uint8_t length = MIN(size, available); err_code = nrf_drv_rng_rand(p_buff, length); APP_ERROR_CHECK(err_code); return length; }