Loader App (iOS/Mac)
Relevant source files
The following files were used as context for generating this wiki page:
The Loader App is a cross-platform application recommended to be built using Swift/SwiftUI with Mac Catalyst. Its primary purpose is to provide a user interface and communication bridge for restoring local-first functionality to Awair Glow C and Awair Element devices. It facilitates the Device Firmware Update (DFU) process over Bluetooth Low Energy (BLE) and the subsequent Wi-Fi provisioning of the hardware.
The app handles the high-level orchestration of scanning for devices in DFU mode, streaming custom firmware binaries in chunks, validating the transfer via CRC32, and configuring network credentials to integrate the sensors with local MQTT or REST-based home automation systems.
Sources: CLAUDE.md:85-88, README.md:1-5
Device Discovery and Connection
The app utilizes CoreBluetooth to interact with Awair hardware. Devices are identified by specific BLE advertisements such as "GlowC-DFU" or other custom UUIDs when in bootloader mode.
BLE Workflow
- Scan: The app scans for devices advertising the DFU service.
- Connect: Establishes a GATT connection to the selected device.
- Information Retrieval: Displays hardware information and current firmware versions.
- Command Issue: Initiates the transition to DFU mode if the device is not already in that state.
Sources: CLAUDE.md:91-95
The diagram above shows the initial connection and discovery sequence for the Loader App.
Sources: CLAUDE.md:91-96
Device Firmware Update (DFU) Client
The DfuClient is responsible for the reliable delivery of firmware images from the host to the device. It segments the firmware binary into manageable chunks to be sent over the BLE transport.
Chunked Data Transfer
The client uses a DfuTransport interface to write data. It defaults to a chunk size of 128 bytes but can be configured otherwise. During the upload, the client calculates and reports real-time progress, including the percentage completed and bytes sent.
| Component | Description |
|---|---|
DfuClient | Orchestrates the upload loop and chunking logic. |
DfuTransport | Abstract interface for writing raw bytes to the BLE characteristic. |
DfuProgress | Data structure containing sentBytes, totalBytes, and percentage. |
| Sources: host/src/loader/ble/dfuClient.ts:4-20 |
Upload Implementation
// host/src/loader/ble/dfuClient.ts:22-35
public async upload(image: Uint8Array, onProgress: (progress: DfuProgress) => void): Promise<number> {
let sent = 0;
while (sent < image.length) {
const chunk = image.slice(sent, sent + this.chunkSize);
await this.transport.writeChunk(chunk);
sent += chunk.length;
onProgress({
sentBytes: sent,
totalBytes: image.length,
percentage: Math.round((sent / image.length) * 100)
});
}
return crc32(image);
}
Sources: host/src/loader/ble/dfuClient.ts:22-37
Wi-Fi Provisioning Flow
After a successful firmware update, the device reboots and advertises a "Provisioning" service. The Loader App provides a flow to send WifiCredentials (SSID and Password) to the device.
Provisioning Components
- ProvisioningFlow: Manages the logic of ensuring credentials (like SSID) are present before transmission.
- WifiProvisioner: The underlying transport mechanism that sends the credentials to the device.
The sequence diagram illustrates the credential handover from the app to the hardware.
Sources: host/src/loader/wifi/provisioning.ts:6-23, CLAUDE.md:96-97
Integrity and Validation
To prevent bricking, the system relies on CRC32 checksums. The DfuClient returns a CRC32 of the uploaded image, which must match the metadata processed by the device's bootloader.
| Field | Type | Description |
|---|---|---|
expectedCrc | number | The CRC32 checksum the firmware image must match. |
size | number | Total size of the firmware in bytes. |
received | number | Counter of bytes successfully received by the session. |
| Sources: host/src/firmware/bootloader/dfu.ts:18-24, host/src/loader/ble/dfuClient.ts:36 |
Bootloader Interaction
The app's activities are verified by the device bootloader, which checks for a specific DFU flag in the flash storage. If the flag is set (typically via a command from the loader app or a physical button hold), the device enters the DFU state.
Sources: host/src/firmware/bootloader/bootloader.ts:21-24, CLAUDE.md:73-74
Summary
The Loader App (iOS/Mac) serves as the primary tool for end-users to transition their Awair hardware to the OpenAwair ecosystem. By handling BLE discovery, chunked firmware transmission via the DfuClient, and Wi-Fi credential provisioning, it ensures a controlled and verifiable installation process for custom firmware.