nRF51 SDK - S110 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. This information is required to reconnect to bonded devices and share the encryption keys. 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 only used if the device has a Resolvable Private Address (RPA) instead of a static address. In this case, the Identity Resolving Key (IRK) of only this device is added to the whitelist. So, in both cases, the device will connect only to 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

In the 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_set_peer_data(&m_peer_data);
APP_ERROR_CHECK(err_code);
app_context.len = sizeof(app_context_data);
app_context.p_data = (uint8_t *)&app_context_data;
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_set_peer_data(&m_peer_data);
APP_ERROR_CHECK(err_code);
}
}

The dfu_ble_svc_set_peer_data function performs a supervisor call (SVC) to the bootloader to pass the bonding information. For the bootloader to receive the information, the application's SVCs must be forwarded correctly. To do so, call sd_softdevice_vector_table_base_set with NRF_UICR->BOOTLOADERADDR as argument.

To receive the bonding information, the bootloader must implement an SVC handler. If it does not, the system will end in the default SVC handler (which is an infinite loop) when the application tries to call dfu_ble_svc_set_peer_data.