nRF51 SDK - S130 SoftDevice
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Sharing bonding information

When BLE DFU Service support is added to an application that uses the Device Manager, it is possible to transfer bonding information from the application to the bootloader. If the encryption keys are shared, both the application and the bootloader can reconnect to bonded devices. If no bonding information is available, the connection is re-established using directed advertising.

Bonding information consists of the peer address, the Identity Resolving Key (IRK), and the Long Term Key (LTK) of the connected peer.

If you include the file dfu_app_handler.c in your application, bonding information is automatically shared, and either directed advertising or whitelist advertising is used to re-establish the secure connection between the devices. Whitelist advertising is used if an Identity Resolving Key (IRK) has been distributed. In this case, the IRK of only this device is added to the whitelist, so that the device will allow connections only from the device that triggered the DFU mode. If the peer does not reconnect to the device, the system resets and loads the installed application again.

The following figure shows the process of reconnecting to a bonded device:

bledfu_bonding.svg
DFU on a bonded device

In bootloader mode, the device is advertising with the same address as in application mode if the application supports Service Changed indications. Otherwise, changes to the application cannot be indicated, and therefore the device must advertise as a new device. This is accomplished by the device advertising with the address increased by 1.

Implementation

The example bootloader uses a particular region of memory to pass the bonding information from the application to the bootloader. This memory region is designated at compile time not to be zero-initialized during a soft reset. To preserve the bonding information, the application performs a supervisor call (SVC) to the bootloader. The bootloader's SVC handler then copies the bonding information into the preserved memory region, so that the bootloader can read it back after the reset. A CRC is used to verify the integrity of the information.

Implementation in the application

In the example application, the keys that are needed to re-establish the secure connection are retrieved from the Device Manager using the function dm_distributed_keys_get. They are then passed from the application to the bootloader. The following code from dfu_app_handler.c shows how to implement bond sharing:

err_code = dm_handle_get(conn_handle, &m_dm_handle);
if (err_code == NRF_SUCCESS)
{
err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
if (err_code == NRF_SUCCESS)
{
APP_ERROR_CHECK(err_code);
m_peer_data.addr = key_set.keys_central.p_id_key->id_addr_info;
m_peer_data.irk = key_set.keys_central.p_id_key->id_info;
m_peer_data.enc_key.enc_info = key_set.keys_periph.enc_key.p_enc_key->enc_info;
m_peer_data.enc_key.master_id = key_set.keys_periph.enc_key.p_enc_key->master_id;
err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
APP_ERROR_CHECK(err_code);
app_context.len = sizeof(app_context_data);
app_context.p_data = (uint8_t *)&app_context_data;
app_context.flags = 0;
err_code = dm_application_context_set(&m_dm_handle, &app_context);
APP_ERROR_CHECK(err_code);
}
else
{
// Keys were not available, thus we have a non-encrypted connection.
err_code = dm_peer_addr_get(&m_dm_handle, &m_peer_data.addr);
APP_ERROR_CHECK(err_code);
err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
APP_ERROR_CHECK(err_code);
}
}

The dfu_ble_svc_peer_data_set function that is called in this example is a supervisor call to the bootloader. This means that the function is implemented in the bootloader code, but called from the application. For this SVC to be handled correctly, the application must know where to find the bootloader's SVC handler. To define its location, the application must call sd_softdevice_vector_table_base_set with NRF_UICR->BOOTLOADERADDR as argument. See dfu_app_handler.c for the implementation in the example application.

Note
If sd_softdevice_vector_table_base_set is not called with NRF_UICR->BOOTLOADERADDR as argument, the application will deadlock or behave erratically when dfu_ble_svc_peer_data_set is called.

Implementation in the bootloader

To ensure that the supervisor call is correctly handled by the bootloader's SVC handler and not the application's SVC handler, the bootloader must implement an SVC handler. In the example bootloader, the SVC handler (and also the dfu_ble_svc_peer_data_set function) is implemented in the file dfu_ble_svc.c.

Note
Make sure to implement an SVC handler in the bootloader. If no SVC handler is defined in the bootloader, the application will deadlock when dfu_ble_svc_peer_data_set is called.