Skip to content

NetIgnite V2 Esp32 Agent - #5

Merged
LeiCraft merged 8 commits into
masterfrom
v2
Oct 21, 2026
Merged

LeiCraft merged 8 commits into
masterfrom
v2

Conversation

@LeiCraft

Copy link
Copy Markdown
Member

No description provided.

…, enrollment)

NetIgnite v2, milestone 2.

- Toolchain: pioarduino 55.03.312-1 (Arduino-ESP32 3.3.12, ESP-IDF 5.5.5), pinned.
- Partition table with two 1.875 MB OTA slots; NVS stays at 0x9000 for provisioning images.
- Settings in NVS instead of a compiled-in config.h; DHCP by default, optional static IPv4.
- Serial console (setup, wifi, server, enroll, ip, name, log, status, reboot, factory-reset)
  and Improv Wi-Fi Serial for the web installer, on the same UART.
- Enrollment: the agent generates its own secret and exchanges a single-use token for a
  credential; the secret is never printed.
- Agent protocol v2 over /ws/agent: HELLO with capabilities and diagnostics, PING, WAKE,
  STATUS; reconnect with backoff and a server-silence timeout.
- Status checks in their own task: ICMP and TCP probes for IPv4, IPv6 (link-local with the
  Wi-Fi interface zone) and host names; a refused TCP connection counts as online.
- Wake-on-LAN to the subnet broadcast and 255.255.255.255 without an extra library.
- lib/netignite_core: parsers and encoders, unit-tested on the host (pio test -e native).
- test/emulator: QEMU test of Improv (with improv-wifi-serial-sdk) and the console.
- CI: tests, builds, size gate, emulator test; tagged releases with flash images,
  release.json and an optional ECDSA signature.
- Removed the unused Electron installer placeholder.

BREAKING CHANGE: v1 servers aren't supported, and config.h is gone. Boards need one USB flash
of v2 (new partition table) and are then set up from the serial console.
Start QEMU with the timer-group watchdogs disabled, as ESP-IDF's own QEMU runner does: on a slow
host they reset or crash the emulated chip during boot, which kept the CI runner's board in a
reset loop (and caused the "cache error" crash on every second boot locally). Boot waits are
longer, and on a failure the test prints the device's serial output and CI keeps it as the
emulator-serial-log artifact.
release.json now lists `name` in nvs.keys, so the server's web installer writes the agent's name
into the NVS image together with the server URL and enrollment token.
- OTA_BEGIN: downloads the image from the agent's server with its own credential, checks size,
  SHA-256 and (with keys/firmware-signing.pub.pem compiled in by scripts/signing_key.py) the ECDSA
  P-256 signature, and installs it into the other slot. The new firmware is on probation
  (ESP-IDF app rollback) until it reaches the server; after 5 minutes, or if it crashes, the
  bootloader starts the previous firmware and the agent reports the failed version in HELLO.
  OTA_PROGRESS events report the download.
- Console: a 16 KB ring of log lines (including ESP-IDF's messages), GET_LOGS, LOG_SUBSCRIBE with
  LOG events, GET_INFO, CONFIG_SET (server URL and IP settings are tried and only saved once the
  agent reaches the server; otherwise it restarts with the previous ones), REBOOT, FACTORY_RESET.
- SSH_CHECK / SSH_EXEC with LibSSH-ESP32 in a short-lived task: login only for checks, fixed
  shutdown/reboot commands with a trusted host key; secrets are wiped after use.
- Enrollment sends the agent kind; a 409 (token of a Linux agent) is a final rejection.
- Emulator tests: ota-test.ts installs images over the serial port (emulator builds only, with a
  test signing key) and checks signature/SHA rejection, probation and rollback in QEMU; CI runs it.
  improv-test.ts retries the first command after a restart (flaky on CI runners).
- Firmware size with libssh: 79.2% of an OTA slot.
On GitHub's runners the console didn't answer short commands after a restart: QEMU's UART only
hands received bytes to the firmware in blocks of its FIFO threshold. Commands are now followed by
empty lines (like in the OTA test). Restarts are power cycles of QEMU, because a software restart
with serial input still arriving crashes the next boot in the emulator.
@LeiCraft
LeiCraft merged commit 665c53f into master Oct 21, 2026
8 checks passed
@LeiCraft
LeiCraft deleted the v2 branch October 21, 2026 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant