Files
kvida-os/components/transport/include/commissioning.h
Ronny Eia af0c2da146 Add Wi-Fi commissioning: SoftAP captive portal with IPv6 support
Implements first-boot Wi-Fi setup with no companion app required: a
SoftAP + captive portal (DNS wildcard redirect, DHCP option 114, HTTP
form) lets the user submit Wi-Fi credentials from any browser. On
submit, credentials are saved to NVS and the device switches to STA
mode; on subsequent boots it reconnects automatically via stored
credentials. dns_server.c/.h are vendored from ESP-IDF's official
captive_portal example (Unlicense/CC0).

Requests both link-local and global IPv6 addresses once the STA
connection has an IPv4 address (not on WIFI_EVENT_STA_CONNECTED --
esp_netif_create_ip6_linklocal() reliably fails there because
esp-netif's own handler, which marks the lwIP netif "up", hasn't run
yet due to event-handler registration order). Verified end-to-end on
real ESP32-C6 hardware: SoftAP comes up, credential submission works,
STA reconnects on reboot, and both a link-local and a router-assigned
global IPv6 address are obtained via SLAAC.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 21:24:38 +02:00

33 lines
972 B
C++

#pragma once
namespace kvida {
enum class CommissioningState {
Idle,
ApActive,
Connecting,
Connected,
Failed,
};
// Starts a SoftAP + captive portal so the user can submit Wi-Fi
// credentials from any browser -- no companion app needed. Intended to
// be triggered by a physical action (e.g. a button press), per the
// "configuration mode requires physical user interaction" security
// principle in AGENTS.md. No-op if already active or already connected.
void start_commissioning();
// Stops the SoftAP/captive portal (e.g. on timeout, or once connected).
// Safe to call even if not active.
void stop_commissioning();
CommissioningState commissioning_state();
// Attempts to connect using credentials already stored in NVS from a
// previous commissioning session. Returns false immediately if none are
// stored; otherwise the result arrives asynchronously via
// commissioning_state().
bool try_stored_credentials();
} // namespace kvida