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.