BLE DFU Protocol
Relevant source files
The following files were used as context for generating this wiki page:
The BLE Device Firmware Update (DFU) protocol in the OpenAwair project enables over-the-air (OTA) updates for Awair Glow C and Awair Element devices. Modeled after the Nordic Secure DFU, this protocol provides a mechanism to stream firmware binaries from a host (the "Loader") to the device's bootloader via a custom GATT service.
The protocol ensures system integrity through CRC32 validation and a safe bootloader-driven update process. If an update fails, the device remains in DFU mode to prevent "bricking" and allows for subsequent retry attempts.
Sources: CLAUDE.md:88-100, host/src/firmware/bootloader/dfu.ts
Architecture and Components
The DFU system is divided between the host-side loader tooling and the device-side bootloader logic.
DFU Client (Host Side)
The DfuClient manages the transmission of firmware. It segments a firmware image into small chunks (defaulting to 128 bytes) and transmits them sequentially through a DfuTransport interface. It also tracks upload progress, including bytes sent and percentage complete.
Sources: host/src/loader/ble/dfuClient.ts:13-39
DFU Session (Device Side)
A DfuSession is initialized on the device when an update begins. It maintains an internal buffer to reconstruct the firmware from received chunks and validates the final image against an expected CRC32 checksum.
Sources: host/src/firmware/bootloader/dfu.ts:18-50
Bootloader Logic
The Bootloader class manages the lifecycle of the firmware update, including deciding whether to boot the existing application or enter DFU mode based on flash-resident flags.
Sources: host/src/firmware/bootloader/bootloader.ts:12-42
Data Flow and Protocol Sequence
The DFU process follows a specific sequence of handshake, data streaming, and validation.
Firmware Upload Sequence
The following diagram illustrates the interaction between the Loader app and the Device Bootloader during an update.
Update Logic Flowchart
This diagram describes the internal decision-making process of the device upon reset.
Data Structures and Interfaces
Firmware Components
| Structure/Interface | Properties | Description |
|---|---|---|
FirmwareImage | bytes, crc | Represents the complete firmware binary and its checksum. |
FirmwareChunk | offset, data | A segment of the firmware sent over BLE. |
DfuProgress | sentBytes, totalBytes, percentage | Used by the host to track upload status. |
BootConfig | dfuFlagKey, firmwareCrcKey, firmwareSizeKey | Keys used to retrieve metadata from flash storage. |
Sources: host/src/firmware/bootloader/dfu.ts:7-16, host/src/loader/ble/dfuClient.ts:5-11, host/src/firmware/bootloader/bootloader.ts:7-11
Firmware Validation (CRC32)
Validation is a critical step to ensure that the firmware was not corrupted during transmission. The protocol uses the CRC32 algorithm.
// host/src/firmware/bootloader/dfu.ts:44-50
public verify(): boolean {
if (!this.isComplete()) {
return false;
}
return crc32(this.buffer) === this.expectedCrc;
}
The bootloader maintains the expectedCrc and size in persistent storage (Flash) before the session begins to ensure that even if interrupted, the validation criteria remain consistent.
Sources: host/src/firmware/bootloader/dfu.ts:44-50, host/src/firmware/bootloader/bootloader.ts:28-34, host/src/shared/crc32.ts
Summary
The BLE DFU Protocol provides a robust mechanism for updating OpenAwair devices without requiring physical access to the SWD debug pins. By utilizing a segmented chunk-based transmission and mandatory CRC32 verification, the system maintains reliability across unstable BLE connections. The architecture ensures that devices only boot into validated firmware, with a fail-safe DFU mode that persists across failed update attempts.
Sources: CLAUDE.md:88-106, host/src/firmware/bootloader/bootloader.ts