One of the features of our product is the ability for a user to rename their device. I have tried to implement this with the sd_ble_gap_device_name_set(...) and ble_advertising_restart_without_whitelist(...) calls. Under Android I am having absolutely zero issues. Under iOS, the name of a renamed device is always displayed as "N/A" within the nRF connect app. This occurs even if the iOS device has never connected to the renamed device.
For additional clarification, this is occurring with SDK 14.2. I am writing the "new name" of the device to an external flash chip, rather than the internal flash of the nRF52382. I initially advertise with the name stored in the nRF52 flash, initialize my hardware, then read the name from my external flash chip, and then change the name with sd_ble_gap_device_name_set(...) and ble_advertising_restart_without_whitelist(...). Even if the name read off of the external flash is exactly the same as name originally set from the internal flash, iOS reads the device name as "N/A". If I remove the code to change the device name, then iOS has no trouble seeing the proper advertising information.
Here's my initial code for setting the name, (gap_params_init):
static void gap_params_init(void) { uint32_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); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }
Here is the code I use to alter the name, which is called after all of my hardware is initialized and after advertising/BLE services have been initialized:
void update_device_name(uint8_t * name_array, uint8_t length) { for (uint8_t i = 0; i < length; i++) { device_name[i] = (uint8_t)name_array[i]; } ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); uint32_t err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) device_name, length); APP_ERROR_CHECK(err_code); err_code = ble_advertising_restart_without_whitelist(&m_advertising); if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } }
Everything else is basically identical to the ble_app_uart example.
Is there something I'm missing here? The only thing I can think of that I'm doing that's out of the ordinary is that the uint8_t array holding the 'new name' is read off of the external flash rather than off of the internal flash.
Should I just store the altered name to the internal flash, and do away with update_device_name() - or am I using ble_advertising_restart_without_whitelist() incorrectly?
EDIT:
I think this has something to do with the for-loop and uint8_t cast I'm using to change device_name via update_device_name(). I modified my code to remove ble_advertising_restart_without_whitelist(), and set device_name programatically before I start advertising. Android sees the proper name, iOS does not, even after connecting and disconnecting from the device.