22#if PC_ENABLE_PROVISIONING && defined(ARDUINO)
28#include <Preferences.h>
36 if (!body || !key || !out || cap == 0)
41 size_t klen = strnlen(key, cap);
42 const char *val =
nullptr;
43 for (
const char *p = body; *p; p++)
46 if ((p == body || p[-1] ==
'&') && strncmp(p, key, klen) == 0 && p[klen] ==
'=')
58 for (
const char *q = val; *q && *q !=
'&'; q++)
71 c = (char)((h << 4) | l);
92#if PC_ENABLE_PROVISIONING && defined(ARDUINO)
100 uint8_t ap_ip[4] = {192, 168, 4, 1};
102static ProvCtx s_prov;
109static void prov_dns_recv(
const uint8_t *req,
size_t qlen,
const struct pc_udp_peer *peer,
void *ctx)
120 while (qend < qlen && req[qend] != 0)
122 qend += (size_t)req[qend] + 1;
131 if (qend + 16 >
sizeof(resp))
135 memcpy(resp, req, qend);
140 resp[8] = resp[9] = resp[10] = resp[11] = 0x00;
155 resp[n++] = s_prov.ap_ip[0];
156 resp[n++] = s_prov.ap_ip[1];
157 resp[n++] = s_prov.ap_ip[2];
158 resp[n++] = s_prov.ap_ip[3];
165 if (ssid && ssid_cap)
174 if (!prefs.begin(PC_PROV_NVS_NAMESPACE,
true))
178 String s = prefs.getString(PC_PROV_KEY_SSID,
"");
179 String k = prefs.getString(PC_PROV_KEY_PSK,
"");
185 strncpy(ssid, s.c_str(), ssid_cap - 1);
186 ssid[ssid_cap - 1] =
'\0';
187 strncpy(psk, k.c_str(), psk_cap - 1);
188 psk[psk_cap - 1] =
'\0';
195 if (prefs.begin(PC_PROV_NVS_NAMESPACE,
false))
202static void prov_form_handler(uint8_t slot_id,
HttpReq *req)
205 s_prov.server->send(slot_id, 200, PC_MIME_TEXT_HTML,
PC_PROV_FORM);
208static void prov_save_handler(uint8_t slot_id,
HttpReq *req)
217 s_prov.server->send(slot_id, 400, PC_MIME_TEXT_PLAIN,
"SSID required");
221 prefs.begin(PC_PROV_NVS_NAMESPACE,
false);
222 prefs.putString(PC_PROV_KEY_SSID, ssid);
223 prefs.putString(PC_PROV_KEY_PSK, psk);
232 s_prov.server = &server;
235 s_prov.ap_ip[0] = (uint8_t)(ip & 0xFF);
236 s_prov.ap_ip[1] = (uint8_t)((ip >> 8) & 0xFF);
237 s_prov.ap_ip[2] = (uint8_t)((ip >> 16) & 0xFF);
238 s_prov.ap_ip[3] = (uint8_t)((ip >> 24) & 0xFF);
251 if (ssid && ssid_cap)
Single-port HTTP server with deterministic, zero-allocation execution.
void on(const char *path, HttpMethod method, Handler callback)
Register a route handler.
Pluggable monotonic clock for all library timing.
void pcdelay(uint32_t ms)
Block for at least ms milliseconds - the library's single delay primitive.
Base-16 conversion between raw bytes and their ASCII digits.
int8_t pc_hex_val(char c)
Hex character c as 0..15, or -1 when c is not a hex digit of either case.
Shared HTTP Content-Type ("MIME") string constants (one source of truth).
bool init_wifi_ap_physical(const char *, const char *)
Bring up a softAP, enabling AP+STA coexistence so a station link can run alongside it.
uint32_t pc_net_ap_ip(void)
softAP IPv4 (network byte order), or 0 if the softAP is not up (and on host builds).
Layer 1 (Physical) - link bring-up and live egress-interface reporting.
Layer 7 (Application) - public HTTP routing API.
@ HTTP_POST
Non-idempotent create / action.
@ HTTP_GET
Safe, idempotent read.
void pc_provisioning_begin(PC &server, const char *ap_ssid)
Start the captive portal: softAP ap_ssid + catch-all DNS + form routes.
bool pc_provisioning_load(char *ssid, size_t ssid_cap, char *psk, size_t psk_cap)
Load stored WiFi credentials from NVS.
bool pc_prov_form_field(const char *body, const char *key, char *out, size_t cap)
Extract and URL-decode a field from an x-www-form-urlencoded body.
void pc_provisioning_clear()
Erase stored credentials (forces re-provisioning on next boot).
First-boot WiFi provisioning via a captive portal (PC_ENABLE_PROVISIONING).
Fully-parsed HTTP/1.1 request.
uint8_t body[BODY_BUF_SIZE+1]
Stored body bytes, always null-terminated.
bool pc_udp_listen(uint16_t port, pc_udp_handler handler, void *ctx)
Bind a UDP port and route incoming datagrams to handler.
bool pc_udp_send(const struct pc_udp_peer *peer, const uint8_t *data, size_t len)
Send a datagram back to the peer captured during the handler call.
Layer 4 (Transport) - connectionless UDP datagram service.
const char PC_PROV_FORM[]
Captive-portal form for WiFi credential entry (provisioning service).
const char PC_PROV_SAVED_HTML[]
Success page shown after credentials are saved and the device reboots.
Layer 7 (Application) - embedded web assets generated from web_assets/input/.