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.
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.
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 |
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.
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.
This section presents the details of the operations of the Buttonless Secure DFU Service.
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.
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 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. |
The following message sequence chart shows a successful request to enter DFU mode:
The following message sequence chart shows a succesful request to set advertisement name:
Follow these steps to add a Secure DFU Service to a BLE application.
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).
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:
The main application must also implement an app_shutdown_handler with the following function signature:
Initialize the Buttonless Secure DFU Service by calling ble_dfu_buttonless_init.
This adds the Buttonless Secure DFU Service and the characteristic according to the project configuration (with bonds or without bonds).