nRF5 SDK v14.2.0
Buttonless Secure DFU Service
This information applies to the following SoftDevices: S132, S140

This module implements the Buttonless Secure DFU Service. It is a proprietary BLE service that enables entering DFU mode from a BLE application during a Secure Device Firmware Update. This service is intended to be used in scenarios where there is limited or no physical access to the device, to provide better user experience on devices with limited I/O capabilities, or to automate the process of running a Device Firmware Update from a smart device.

This service is used by the Buttonless DFU Template Application.

Configuration

You can configure the Buttonless Secure DFU Service to either support bonds or not. With bond support, the application will exchange information about bonded devices with the bootloader, guaranteeing that only bonded devices are allowed to perform DFU operations. To enable or disable the support of bonds, modify the configuration parameters in the sdk_config file. For details on editing the SDK configurations, see SDK configuration header file.

Changing this value to 0 configures the Buttonless Secure DFU Service to not share bond information with the Secure DFU bootloader.

Service and Characteristics

The Buttonless Secure DFU Service uses the Nordic-proprietary 16-bit UUID for Secure DFU (0xFE59).

One of the following Buttonless DFU characteristics will be available in the Buttonless Secure DFU Service, depending on the configuration:

Characteristic UUID

Access

Buttonless DFU without bonds 0x8EC90003-F315-4F60-9FB8-838830DAEA50

Write, Indicate

Buttonless DFU with bonds 0x8EC90004-F315-4F60-9FB8-838830DAEA50 Write, Indicate

Buttonless Secure DFU Service with bonds

Configuring the Buttonless Secure DFU Service with bond support restricts write access to the Buttonless DFU Characteristic. In this configuration, only bonded devices can write to the Buttonless DFU characteristic to enter DFU mode.

Prerequisites for entering DFU mode:

When the Buttonless Secure DFU Service enters the bootloader, the Buttonless Secure DFU Service forwards the current peer data from the Peer Manager data storage to the Secure DFU bootloader. This data is stored in flash, and is activated when the device enters DFU mode.

In this scenario, it is assumed that it is always the same client that requests to enter DFU mode and connects to the device to execute the Device Firmware Update. This is the only device that will have access to do so.

Warning
Enabling this service with a Secure DFU bootloader that does not require bonds will lead to a failure during initialization.
Note
Only the peer data of the currently connected (and bonded) client will be forwarded to the Secure DFU. This peer data will be cleared when the Device Firmware Update is finished, or if the DFU mode times out due to inactivity.

Buttonless Secure DFU Service without bonds

Configuring the Buttonless Secure DFU service to not support bonds does not restrict write access to the buttonless service. Any device will be able to write to the Buttonless DFU characteristic to enter DFU mode.

Prerequisites for entering DFU mode:

When the Buttonless Secure DFU Service enters the bootloader, the device enters DFU mode and starts advertising on BLE address + 1. This is done to prevent the client from using cached BLE services and characteristics data for the device.

Setting an alternative advertisement name was added to help locate peer devices in DFU mode when the API for the client application does not provide direct access to the Bluetooth address.

Setting a new advertisement name is optional, but it must be done prior to requesting to enter DFU mode. It is not possible to set it more than once before entering DFU mode. The advertisement name will be reset upon a successful Device Firmware Update, or when the DFU mode times out due to inactivity.

Warning
Enabling this service with a Secure DFU bootloader that requires bonds will lead to a failure during initialization.

Buttonless operations

This section presents the details of the operations of the Buttonless Secure DFU Service.

Entering DFU mode

This operation will exchange bond data with the Secure DFU bootloader if the Secure DFU bootloader requires it and the Buttonless Secure DFU Service is configured to support bonds. Exchanging bond information is an asynchronous operation that will succeed when the bond information is stored in Secure DFU Bootloader local flash storage. Entering DFU mode happens after bond information is successfully stored.

The Buttonless Secure DFU Service enters DFU mode by writing a reserved value to the general purpose memory retention register in nRF5x devices (GPREGRET) and executing a system reset. After the device is reset, it remains in DFU mode until the firmware is upgraded or until the DFU mode times out due to inactivity.

The result of a request to enter DFU mode is sent as an indication, which must be acknowledged by the client application. When the indication is acknowledged, the device will immediately enter DFU mode. This means that the client will be disconnected.

The device will start advertising as a BLE service when Secure DFU is available. The client application must reconnect to the device to start the Device Firmware Update process. If the device is not connected, then the Secure DFU will time out and restart the main application.

Setting new advertisement name

This operation is only available if the Buttonless Secure DFU Service is configured to not use bonds and the Secure DFU bootloader does not require bonds.

This operation is optional, but must be executed prior to a request to enter DFU mode. Setting advertisement name can only be done once. The new advertisement name can be generated randomly, and it is up to the client application to keep track of the new name to use for a subsequent reconnection.

Max length of the new advertisement name is 20 characters.

Operations and format

Operations are requested by writing commands to the available Buttonless DFU characteristic. Operations are only valid if indication is enabled on the characteristic in question, and if all other prerequisites are met.

The format of the commands is as follows:

opcode data

The opcode is one byte of type ble_dfu_buttonless_op_code_t. The following table lists the available opcodes and their parameters.

Opcode Procedure Description

Parameters

0x01 Enter DFU mode Jump from the main application to Secure DFU bootloader (DFU mode)

N/A

0x02 Set advertisement name Set a new advertisement name when jumping to Secure DFU bootloader (DFU mode)

Length(uint8_t), name(uint8_t[])

0x20 Response Code Request opcode, result code

The following table lists the result codes that are sent as part of the response.

Result code Definition Description
0x00 Invalid code The provided opcode was missing or malformed.
0x01 Success The operation completed successfully.
0x02 Opcode not supported The provided opcode was invalid.
0x04 Operation failed The operation failed.
0x05 Invalid advertisement name The requested advertisement name was invalid (empty or too long). Only available without bond support.
0x06 Busy The request was rejected due to a ongoing asynchronous operation.
0x07 Not bonded The request was rejected because no bond was created.

Message sequence charts

The following message sequence chart shows a successful request to enter DFU mode:

msc_inline_mscgraph_6
Note
This operation requires that indications are enabled for the Buttonless characteristic.

The following message sequence chart shows a succesful request to set advertisement name:

msc_inline_mscgraph_7
Note
This operation is only available if Buttonless Secure DFU Service does not use bonds. This operation requires that indications are enabled for the Buttonless DFU characteristic.

Adding Buttonless Secure DFU Service to a BLE application

Follow these steps to add a Secure DFU Service to a BLE application.

Prerequisites

The prerequisites for the application is that it is a peripheral or a central application that uses the Peer Manager. The application is responsible for initializing the BLE stack. The application must be configured to use the power management module (Power Management library).

Implement the DFU event handler

Implement the DFU event handler
static void ble_dfu_buttonless_evt_handler(ble_dfu_buttonless_evt_type_t event)
{
switch (event)
{
NRF_LOG_INFO("Device is preparing to enter bootloader mode\r\n");
break;
NRF_LOG_INFO("Device will enter bootloader mode\r\n");
break;
NRF_LOG_ERROR("Device will enter bootloader mode\r\n");
break;
default:
NRF_LOG_INFO("Unknown event from ble_dfu.\r\n");
break;
}
}

Configure the power management module

The power management module must be added to the project and enabled through SDK configuration header file. For information about the power management module, see Power Management library.

The power management module controls the time when the reset into DFU is executed. It can be used to delay the reset into DFU mode to finalize any ongoing application-specific asynchronous operations. Power management auto shutdown retry must be enabled to make it possible to delay the reset into DFU mode. Enabling this will make the power management poll to see if reset is possible every second. You can enable auto shutdown retry in SDK configuration header file in the following manner:

Enabling power management auto shutdown retry
#ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 1
#endif

The main application must also implement an app_shutdown_handler with the following function signature:

Implement the power management
static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
{
switch (event)
{
NRF_LOG_INFO("Power management wants to reset to DFU mode\r\n");
// Change this code to tailor to your reset strategy.
// Returning false here means that the device is not ready to jump to DFU mode yet.
//
// Here is an example using a variable to delay resetting the device:
if (!m_ready_for_reset)
{
return false;
}
break;
default:
// Implement any of the other events available from the power management module:
// -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
// -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
// -NRF_PWR_MGMT_EVT_PREPARE_RESET
return true;
}
NRF_LOG_INFO("Power management allowed to reset to DFU mode\r\n");
return true;
}

Initialize the Buttonless Secure DFU Service

Initialize the Buttonless Secure DFU Service by calling ble_dfu_buttonless_init.

Initializing the Buttonless Secure DFU Service
static void services_init(void)
{
...
{
.evt_handler = ble_dfu_buttonless_evt_handler
};
err_code = ble_dfu_buttonless_init(&dfus_init);
APP_ERROR_CHECK(err_code);
...
}

This adds the Buttonless Secure DFU Service and the characteristic according to the project configuration (with bonds or without bonds).


Documentation feedback | Developer Zone | Subscribe | Updated