You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
15
15
### Added
16
16
17
+
-**OTA MVP** — three new crates for end-to-end firmware update on ESP32-C3 (and ESP32-C6 / ESP32 for the bare-metal stack), aligned with `docs/adr/011-ota-crate-hosting-and-transport.md` and `docs/features/ota-mvp-v1.md`. All public APIs are explicitly experimental for MVP; stabilization is owned by the future `ota-library` feature.
18
+
-`ota-pure` (new crate, **experimental API**) — platform-independent, `no_std`, host-tested. Surface: `Version` semver parser (`u16` components, `Display`, `Ord`), `StreamingVerifier` (chunk-fed SHA-256 over `sha2 = { default-features = false }`), `bytes_to_hex` / `hex_to_bytes` fixed-size helpers (returns `heapless::String<64>`), `ImageMetadata` sidecar parser (`.bin.sha256` + `.bin.version`), backend-neutral `OtaState` enum (`Idle → Downloading → Verifying → Writing → SwapPending → Booted`) with `next_state()`, and `OtaError` with the 8 MVP variants (`ServerUnreachable`, `DownloadFailed { status: u16 }`, `DownloadTimeout`, `ChecksumMismatch`, `VersionInvalid`, `FlashWriteFailed`, `PartitionNotFound`, `InsufficientSpace`). `DownloadFailed { status: 0 }` is reserved as a sentinel for protocol-shape rejections from the bare-metal HTTP client. 37 host unit tests.
19
+
-`rustyfarian-esp-idf-ota` (new crate, **experimental API**, blocking) — ESP-IDF std, lifted from `rustyfarian-beekeeper/src/ota/`. Surface: `OtaSession::new(config)`, `fetch_and_apply(url, &expected_sha256)`, `mark_valid()`, `rollback()`. Wraps `EspOta` / `EspOtaUpdate` and `EspHttpConnection`; streams download → SHA-256 verify (`StreamingVerifier`) → flash → swap in one pass without holding the full image in RAM. Strips RFC 3986 userinfo from URLs before logging (no credential leakage to `espflash monitor`). HTTPS rejected at MVP scope per ADR 011 (`ota-hardened` will revisit).
20
+
-`rustyfarian-esp-hal-ota` (new crate, **experimental API**, async-only) — bare-metal `no_std`, built fresh against `esp_bootloader_esp_idf::OtaUpdater` over `esp-storage` and `embassy-net::TcpSocket`. Surface: `EspHalOtaManager::new(config, FLASH<'d>)`, `async fetch_and_apply(socket, url, &expected_sha256)`, `mark_valid()`, `rollback()`. Carries an internal hand-rolled HTTP/1.1 GET parser (per ADR 011 §2): accepts only `HTTP/1.1 200 OK` with exactly one valid `Content-Length`; rejects redirects, `Transfer-Encoding: chunked`/`identity`, missing or duplicate `Content-Length`, non-`1*DIGIT` numeric values (incl. leading `+`/`-`), whitespace before colon, oversized bodies, and short reads. Chip features `esp32c3` (MVP), `esp32c6`, `esp32`; stack features `unstable`, `rt`, `embassy`. Host stub mirrors the wifi-crate pattern (typecheck-only). 29 parser unit tests.
21
+
- Workspace: `sha2 = { version = "0.10", default-features = false }`, `esp-storage = "=0.9.0"`, `embedded-storage = "0.3"` added to `[workspace.dependencies]`; `embedded-svc = "0.29"` declared (aligning with `esp-idf-svc 0.52`).
- CI (`.github/workflows/rust.yml`): host tests for `ota-pure` and `rustyfarian-esp-hal-ota --no-default-features` added to the "Test pure crates" block.
17
24
- Build scripts: `scripts/detect-port.sh` narrows `espflash`'s auto-detect to USB serial devices (`usbmodem*`/`usbserial*` on macOS, `ttyUSB*`/`ttyACM*` on Linux) so paired Bluetooth ports stop hijacking the probe; used by `flash.sh`, `just run`, `just monitor`, and `just erase-flash`. `ESPFLASH_PORT=…` still wins when set explicitly
18
25
-`rustyfarian-esp-hal-wifi`: `embassy` Cargo feature + `WiFiManager::init_async()` returning an `AsyncWifiHandle { controller, stack, runner }` wired into an `embassy-net` stack with automatic DHCPv4 (`AsyncWifiHandle::wait_for_ip().await` awaits the first lease). Originally landed alongside a synchronous `WiFiManager::init` path that drove `smoltcp` directly; that sync path was removed later in this same release cycle when the stack moved to `esp-radio 0.18` (see the breaking-change entry below). The `embassy` feature is now the only supported Wi-Fi path on bare-metal — see `docs/features/embassy-feature-flag-v1.md` and `docs/features/wifi-manager-async-v1.md`
19
26
-`rustyfarian-esp-hal-wifi`: `hal_c3_connect_async` example — first async bare-metal Wi-Fi demo on ESP32-C3, uses `#[esp_rtos::main]` with two spawned tasks (`wifi_task` for association + reconnection, `net_task` for the embassy-net runner), prints the DHCP-assigned IP and idles asynchronously (see `docs/features/hal-c3-connect-async-example-v1.md`)
Wi-Fi, MQTT, LoRa, and ESP-NOW networking libraries for ESP32 projects.
10
+
Wi-Fi, MQTT, LoRa, ESP-NOW, and OTA support libraries for ESP32 projects.
11
11
12
12
> Note: Large parts of this library (and documentation) were developed with the assistance of AI tools.
13
13
> All generated code has been reviewed and curated by the maintainer.
@@ -23,7 +23,8 @@ Wi-Fi, MQTT, LoRa, and ESP-NOW networking libraries for ESP32 projects.
23
23
- A growing platform-independent layer (`rustyfarian-network-pure`) that can be unit-tested on the host
24
24
- Minimal friction: a few lines of `Cargo.toml` and no surprises
25
25
26
-
**Out of scope:** Application-layer protocols (HTTP, CoAP, WebSocket) and provisioning/SoftAP flows.
26
+
**Out of scope:** General-purpose application-layer clients (HTTP, CoAP, WebSocket) and provisioning/SoftAP flows.
27
+
The OTA crates (`rustyfarian-esp-idf-ota`, `rustyfarian-esp-hal-ota`) carry their own internal HTTP/1.1 GET clients for firmware download, but these are implementation details and not published as reusable workspace HTTP APIs.
27
28
28
29
*Full vision, success signals, and open questions: [VISION.md](./VISION.md)*
29
30
@@ -41,18 +42,21 @@ a pattern common in application development but rare in embedded Rust.
Copy file name to clipboardExpand all lines: VISION.md
+5-2Lines changed: 5 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,7 @@ Any ESP32-IDF project can add Wi-Fi and MQTT in minutes, with confidence.
20
20
-**An `esp-hal` bare-metal tier** — dedicated `rustyfarian-esp-hal-*` crates provide bare-metal alternatives alongside the existing ESP-IDF path.
21
21
This generalises the earlier LoRa-only `esp-hal` goal into a workspace-wide pattern: separate crates per HAL tier with shared `*-pure` crates for platform-independent types and traits (see [ADR 005](docs/adr/005-crate-naming-for-dual-hal-drivers.md)).
22
22
Active: `rustyfarian-esp-hal-lora` (LoRa radio driver) and `rustyfarian-esp-hal-wifi` (Wi-Fi via `esp-wifi 0.14.0`, in progress).
23
+
-**OTA as firmware-update plumbing** — OTA support may live in this workspace when it reuses the same Wi-Fi, bootloader, partition-table, and dual-HAL foundations as the networking crates.
23
24
24
25
## Target Beneficiaries
25
26
@@ -28,8 +29,8 @@ but with an API clean enough that any ESP32-IDF project can adopt it with confid
28
29
29
30
## Non-Goals
30
31
31
-
-**Application-layer protocols** — HTTP, CoAP, WebSocket, and similar are out of scope;
32
-
this library stops at Wi-Fi association and MQTT pub/sub.
32
+
-**General-purpose application-layer clients** — HTTP, CoAP, WebSocket, and similar reusable clients are out of scope.
33
+
Feature-specific private transports may exist behind crate APIs, such as OTA fetching, but are not exported as protocol libraries.
33
34
-**Provisioning / SoftAP mode** — no captive portal, BLE provisioning, or Wi-Fi setup flows.
34
35
-**Full `no_std` / `esp-hal` MQTT** — MQTT over bare-metal Wi-Fi (`rustyfarian-esp-hal-mqtt`) is a long-term goal but not an active workstream; Wi-Fi association is the current `esp-hal` frontier.
35
36
@@ -54,3 +55,5 @@ _(none at this time)_
54
55
- 2026-03-12 — `esp-hal` Wi-Fi promoted from non-goal to active goal; LoRa path blocked on hardware.
55
56
`rustyfarian-esp-hal-wifi` added to long-term goals; non-goal narrowed to `esp-hal` MQTT only.
56
57
The `esp-hal` goal was generalised from LoRa-only to a workspace-wide dual-HAL pattern (ADR 005).
58
+
- 2026-04-29 — OTA accepted as firmware-update plumbing in this workspace, with private transports only.
59
+
General-purpose HTTP clients remain a non-goal (ADR 011).
0 commit comments