rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
wa_session.c File Reference

Wi-Fi access. See wa_session.h. More...

#include "wa_session.h"
#include <string.h>

Functions

void wa_secret_make (char out[WA_SECRET_LEN+1u], wa_rand_fn rand, void *ctx)
 WA_SECRET_LEN characters of WA_SECRET_CHARS and a terminator, each drawn evenly from the alphabet (words that would favour some characters are drawn again).
void wa_name (const uint8_t mac[6], char out[WA_NAME_MAX])
 "rcbench-" and the last two bytes of mac in capital hex.
void wa_conf_defaults (wa_conf_t *c)
 No home network, the code on: a fresh store, and what FORGET leaves.
static wa_conf_err_t check_net (const char *ssid, size_t ssid_len, const char *pass, size_t pass_len)
 The checks of wa_conf_set_net().
wa_conf_err_t wa_conf_set_net (wa_conf_t *c, const char *ssid, size_t ssid_len, const char *pass, size_t pass_len)
 Take a home network.
void wa_conf_load (const wa_store_t *s, wa_conf_t *out)
 What the store holds, or the defaults when it holds nothing.
bool wa_conf_save (const wa_store_t *s, const wa_conf_t *c)
 Write c into the store.
bool wa_conf_forget (const wa_store_t *s, wa_conf_t *c)
 FORGET: erase the store and leave c at the defaults.
void wa_pending_init (wa_pending_t *p)
 Nothing owed.
static void pending_touched (wa_pending_t *p)
 A change: a new generation, the failure and its tries reset.
void wa_pending_change (wa_pending_t *p)
 A change of the settings in memory: owe a save.
void wa_pending_forget (wa_pending_t *p)
 FORGET: owe an erase; a save owed before it is void.
bool wa_pending_due (const wa_pending_t *p, bool may_write, uint32_t now_ms)
 Whether a write is owed and due now.
void wa_pending_write (const wa_store_t *st, const wa_pending_t *snap, const wa_conf_t *c, bool *erase_ok, bool *save_ok)
 Write what snap owes – the erase, then c – into st.
void wa_pending_done (wa_pending_t *p, const wa_pending_t *snap, bool erase_ok, bool save_ok, uint32_t now_ms)
 Record the results of a write that started from snap.
unsigned wa_modes (const wa_conf_t *c)
 Which ways the screen offers.
void wa_scan_clear (wa_scan_t *s)
 Empty the scan list.
static void scan_sort (wa_scan_t *s)
 Sort the list strongest first.
void wa_scan_add (wa_scan_t *s, const uint8_t *ssid, size_t len, int8_t rssi, bool usable)
 One network a scan saw.
const char * wa_scan_pick (const wa_scan_t *s, unsigned i)
 The name at row i.
void wa_init (wa_t *w)
 Off, nothing kept of any session.
wa_off_t wa_gate (bool armed, bool supply, bool run)
 Why the radio may not run now.
static void enter (wa_t *w, wa_state_t st, uint32_t now_ms)
 Enter st at now_ms.
wa_off_t wa_start (wa_t *w, wa_mode_t mode, wa_off_t gate, uint32_t now_ms, wa_rand_fn rand, void *ctx)
 Start in mode when gate is WA_OFF_NONE, with a fresh password and code.
static bool off_lingers (wa_off_t why)
 Whether a session switched off for why may leave the radio up for the platform's last request.
void wa_close (wa_t *w, wa_off_t why)
 Switch off for why.
bool wa_radio (const wa_t *w)
 Whether the platform's radio should be running.
bool wa_lingers (const wa_t *w)
 Whether the radio may stay up past the session's end, for a request of the platform's own that is under way (the clock's NTP request, wall_ntp_holds()).
void wa_unlinger (wa_t *w)
 The platform needs the radio off now: a linger ends; a session that runs goes on.
bool wa_serving (const wa_t *w)
 Whether the page is being served.
void wa_on_ap_up (wa_t *w, uint32_t now_ms)
 The access point came up.
void wa_on_scan_done (wa_t *w)
 A scan session's list was read: the session ends, off WA_OFF_NONE. wa_on_scan_end() does it with the scan's result.
uint32_t wa_scan_begin (wa_t *w)
 The radio's station started in a scan session: the token of the scan the platform starts now, or 0 for none.
uint32_t wa_scan_pending (const wa_t *w)
 The scan of this session under way, its done report still owed.
bool wa_scan_is (const wa_t *w, uint32_t tok)
 Whether the scan of tok is the one under way.
bool wa_scan_refused (wa_t *w, uint32_t tok)
 The radio refused to start the scan of tok: off WA_OFF_FAILED when it is the scan under way.
bool wa_scan_read_ok (uint32_t status, unsigned reported, bool read_ok, unsigned read, unsigned room)
 Whether a scan reported done counts as done.
wa_scan_step_t wa_on_scan_end (wa_t *w, uint32_t tok, bool ok, uint32_t *next)
 The scan of tok reported done; ok as wa_scan_read_ok() says.
void wa_on_associated (wa_t *w, uint32_t now_ms)
 The station reached the home network.
void wa_on_address (wa_t *w, uint32_t ip, uint32_t now_ms)
 The station has an address.
void wa_on_join_failed (wa_t *w, wa_join_err_t why)
 A join failed or a joined network went away.
bool wa_on_drop (wa_t *w, bool auth)
 The radio dropped the station.
void wa_on_failed (wa_t *w)
 The radio could not be started: off WA_OFF_FAILED. A refused scan is wa_scan_refused().
bool wa_tick (wa_t *w, uint32_t now_ms, wa_off_t gate, bool stop)
 Once a frame: the gate, STOP and the time-outs. Off, a gate or STOP ends a linger (wa_lingers()).
void wa_request_begin (wa_t *w, uint32_t now_ms)
 A request begins; one under way holds the idle time-out off.
void wa_request_end (wa_t *w, uint32_t now_ms)
 A request ends; the idle time counts from now.
uint32_t wa_idle_left (const wa_t *w, uint32_t now_ms)
 The time left before the idle time-out.
wa_code_t wa_code_check (wa_t *w, const char *given, bool code_on)
 Check given against this session's code.

Detailed Description

Wi-Fi access. See wa_session.h.

SPDX-License-Identifier: MIT

Function Documentation

◆ check_net()

wa_conf_err_t check_net ( const char * ssid,
size_t ssid_len,
const char * pass,
size_t pass_len )
static

The checks of wa_conf_set_net().

Parameters
ssidThe name, not terminated.
ssid_lenIts bytes.
passThe passphrase, not terminated.
pass_lenIts characters.
Returns
WA_CONF_OK, or what is wrong with the pair.

◆ enter()

void enter ( wa_t * w,
wa_state_t st,
uint32_t now_ms )
static

Enter st at now_ms.

Parameters
wThe session.
stThe state.
now_msNow.

◆ off_lingers()

bool off_lingers ( wa_off_t why)
static

Whether a session switched off for why may leave the radio up for the platform's last request.

Parameters
whyThe reason.
Returns
true for WA_OFF_ASKED and WA_OFF_IDLE.

◆ pending_touched()

void pending_touched ( wa_pending_t * p)
static

A change: a new generation, the failure and its tries reset.

Parameters
pThe writes owed.

◆ scan_sort()

void scan_sort ( wa_scan_t * s)
static

Sort the list strongest first.

Parameters
sThe list.

◆ wa_close()

void wa_close ( wa_t * w,
wa_off_t why )

Switch off for why.

A joined session switched off by the operator (WA_OFF_ASKED, which is also a release check's own end) or by WA_IDLE_MS lingers (wa_lingers()). Already off: only a reason that does not linger acts, and it ends the linger.

Parameters
wThe session.
whyThe reason.

◆ wa_code_check()

wa_code_t wa_code_check ( wa_t * w,
const char * given,
bool code_on )

Check given against this session's code.

A code from an earlier session is wrong. The WA_GUESS_MAX-th wrong one switches the session off.

Parameters
wThe session.
givenThe code sent, NULL or terminated.
code_onThe code switch; false passes every request while the page is served.
Returns
The check's answer; WA_CODE_CLOSED when no page is served.

◆ wa_conf_defaults()

void wa_conf_defaults ( wa_conf_t * c)

No home network, the code on: a fresh store, and what FORGET leaves.

Parameters
cReceives the defaults.

◆ wa_conf_forget()

bool wa_conf_forget ( const wa_store_t * s,
wa_conf_t * c )

FORGET: erase the store and leave c at the defaults.

Parameters
sThe store.
cThe settings.
Returns
Whether the erase worked.

◆ wa_conf_load()

void wa_conf_load ( const wa_store_t * s,
wa_conf_t * out )

What the store holds, or the defaults when it holds nothing.

A kept network that wa_conf_set_net() would refuse is dropped; the switch stays.

Parameters
sThe store.
outReceives the settings.

◆ wa_conf_save()

bool wa_conf_save ( const wa_store_t * s,
const wa_conf_t * c )

Write c into the store.

Parameters
sThe store.
cThe settings.
Returns
Whether the write worked.

◆ wa_conf_set_net()

wa_conf_err_t wa_conf_set_net ( wa_conf_t * c,
const char * ssid,
size_t ssid_len,
const char * pass,
size_t pass_len )

Take a home network.

ssid of ssid_len bytes, 1 to WA_SSID_MAX, no NUL; pass of pass_len characters, WA_PASS_MIN to WA_PASS_MAX, each printable ASCII (American Standard Code for Information Interchange, 0x20 to 0x7E).

Parameters
cThe settings; unchanged unless WA_CONF_OK.
ssidThe network's name, not terminated.
ssid_lenIts bytes.
passThe passphrase, not terminated.
pass_lenIts characters.
Returns
WA_CONF_OK, or what is wrong with the pair.

◆ wa_gate()

wa_off_t wa_gate ( bool armed,
bool supply,
bool run )

Why the radio may not run now.

Parameters
armedAs flash_gate_open() takes it.
supplyLikewise.
runA log run is open.
Returns
The reason, or WA_OFF_NONE.

◆ wa_idle_left()

uint32_t wa_idle_left ( const wa_t * w,
uint32_t now_ms )

The time left before the idle time-out.

Parameters
wThe session.
now_msNow.
Returns
ms; 0 while a request is under way or no page is served.

◆ wa_init()

void wa_init ( wa_t * w)

Off, nothing kept of any session.

Parameters
wThe session.

◆ wa_lingers()

bool wa_lingers ( const wa_t * w)

Whether the radio may stay up past the session's end, for a request of the platform's own that is under way (the clock's NTP request, wall_ntp_holds()).

Only a joined session switched off for WA_OFF_ASKED or WA_OFF_IDLE lingers. The linger ends at once with a gate (ARM, the supply, a log run), STOP, any other wa_close() reason (an install, a failed radio), a drop of the station and any wa_start(); a new session's start takes the radio down first.

Parameters
wThe session.
Returns
true while the session is off and lingers.

◆ wa_modes()

unsigned wa_modes ( const wa_conf_t * c)

Which ways the screen offers.

Parameters
cThe settings; NULL offers the access point only.
Returns
WA_CAN_AP, with WA_CAN_JOIN when a home network is kept.

◆ wa_name()

void wa_name ( const uint8_t mac[6],
char out[WA_NAME_MAX] )

"rcbench-" and the last two bytes of mac in capital hex.

Parameters
macThe radio's MAC address.
outReceives the name, terminated.

◆ wa_on_address()

void wa_on_address ( wa_t * w,
uint32_t ip,
uint32_t now_ms )

The station has an address.

Parameters
wThe session.
ipThe address, network byte order.
now_msNow.

◆ wa_on_ap_up()

void wa_on_ap_up ( wa_t * w,
uint32_t now_ms )

The access point came up.

Parameters
wThe session.
now_msNow.

◆ wa_on_associated()

void wa_on_associated ( wa_t * w,
uint32_t now_ms )

The station reached the home network.

Parameters
wThe session.
now_msNow.

◆ wa_on_drop()

bool wa_on_drop ( wa_t * w,
bool auth )

The radio dropped the station.

Joining: an auth-class drop counts, any other drop clears the count, and the WA_AUTH_TRIES-th auth-class drop in a row ends the join as WA_JOIN_PASSWORD. On the network, with or without an address: WA_JOIN_LOST. A join that reaches WA_JOIN_MS ends as WA_JOIN_PASSWORD when its last drop was auth-class, and as WA_JOIN_NOT_FOUND after any other drop or none (wa_tick()).

Parameters
wThe session.
authThe platform reads the reason as auth-class (the key refused, a MIC (message integrity code) failure, the key handshake out of time).
Returns
Whether the platform asks the radio to connect again: true while the join goes on.

◆ wa_on_failed()

void wa_on_failed ( wa_t * w)

The radio could not be started: off WA_OFF_FAILED. A refused scan is wa_scan_refused().

Parameters
wThe session.

◆ wa_on_join_failed()

void wa_on_join_failed ( wa_t * w,
wa_join_err_t why )

A join failed or a joined network went away.

Parameters
wThe session.
whyAs the platform reads its reason code.

◆ wa_on_scan_done()

void wa_on_scan_done ( wa_t * w)

A scan session's list was read: the session ends, off WA_OFF_NONE. wa_on_scan_end() does it with the scan's result.

Parameters
wThe session.

◆ wa_on_scan_end()

wa_scan_step_t wa_on_scan_end ( wa_t * w,
uint32_t tok,
bool ok,
uint32_t * next )

The scan of tok reported done; ok as wa_scan_read_ok() says.

A report for a scan that is not the one under way changes nothing. A failed scan is started again while WA_SCAN_TRIES allows; the last one failed ends the session WA_OFF_FAILED, never as an empty list.

Parameters
wThe session.
tokThe token of the scan the report was read for.
okThe scan worked and its list was read.
nextReceives the token of the scan to start with WA_SCAN_AGAIN, 0 otherwise.
Returns
What the platform does next.

◆ wa_pending_change()

void wa_pending_change ( wa_pending_t * p)

A change of the settings in memory: owe a save.

Parameters
pThe writes owed.

◆ wa_pending_done()

void wa_pending_done ( wa_pending_t * p,
const wa_pending_t * snap,
bool erase_ok,
bool save_ok,
uint32_t now_ms )

Record the results of a write that started from snap.

Parameters
pThe writes owed.
snapThe copy the write started from.
erase_okThe erase's result.
save_okThe save's result.
now_msNow.

◆ wa_pending_due()

bool wa_pending_due ( const wa_pending_t * p,
bool may_write,
uint32_t now_ms )

Whether a write is owed and due now.

Parameters
pThe writes owed.
may_writeThis frame may write flash.
now_msNow.
Returns
true when the caller writes now.

◆ wa_pending_forget()

void wa_pending_forget ( wa_pending_t * p)

FORGET: owe an erase; a save owed before it is void.

Parameters
pThe writes owed.

◆ wa_pending_init()

void wa_pending_init ( wa_pending_t * p)

Nothing owed.

Parameters
pThe writes owed.

◆ wa_pending_write()

void wa_pending_write ( const wa_store_t * st,
const wa_pending_t * snap,
const wa_conf_t * c,
bool * erase_ok,
bool * save_ok )

Write what snap owes – the erase, then c – into st.

Runs without the caller's lock; snap and c are copies taken with wa_pending_due() under it.

Parameters
stThe store.
snapThe writes owed, a copy.
cThe settings, a copy.
erase_okReceives the erase's result; true for one not owed.
save_okReceives the save's result; true for one not owed.

◆ wa_radio()

bool wa_radio ( const wa_t * w)

Whether the platform's radio should be running.

Parameters
wThe session.
Returns
true for any state but WA_ST_OFF.

◆ wa_request_begin()

void wa_request_begin ( wa_t * w,
uint32_t now_ms )

A request begins; one under way holds the idle time-out off.

Parameters
wThe session.
now_msNow.

◆ wa_request_end()

void wa_request_end ( wa_t * w,
uint32_t now_ms )

A request ends; the idle time counts from now.

Parameters
wThe session.
now_msNow.

◆ wa_scan_add()

void wa_scan_add ( wa_scan_t * s,
const uint8_t * ssid,
size_t len,
int8_t rssi,
bool usable )

One network a scan saw.

Kept when usable (WPA2 or WPA3 personal) and named; a name already listed keeps the stronger signal. The list is held strongest first, and a full list keeps the WA_SCAN_MAX strongest.

Parameters
sThe list.
ssidThe name, len bytes, not terminated.
lenIts bytes.
rssiIts signal, dBm.
usableWPA2 or WPA3 personal.

◆ wa_scan_begin()

uint32_t wa_scan_begin ( wa_t * w)

The radio's station started in a scan session: the token of the scan the platform starts now, or 0 for none.

One scan at a time: a second report of the station's start while a scan runs starts none, as a second esp_wifi_scan_start() would replace the first and report it done with nothing found. Each scan has its own token, never 0, which the platform carries through the calls that run outside its lock: a refusal (wa_scan_refused()), a done report (wa_on_scan_end()) and a retry (wa_scan_is()) act only on the scan under way, never on a session started after it.

Parameters
wThe session.
Returns
The scan's token, once per scan session, with the session scanning and no scan under way; 0 otherwise.

◆ wa_scan_clear()

void wa_scan_clear ( wa_scan_t * s)

Empty the scan list.

Parameters
sThe list.

◆ wa_scan_is()

bool wa_scan_is ( const wa_t * w,
uint32_t tok )

Whether the scan of tok is the one under way.

Parameters
wThe session.
tokA token wa_scan_begin() or wa_on_scan_end() gave.
Returns
true for the scan under way; false for 0, for a scan that ended and for one of an earlier session.

◆ wa_scan_pending()

uint32_t wa_scan_pending ( const wa_t * w)

The scan of this session under way, its done report still owed.

Parameters
wThe session.
Returns
Its token, or 0 for none.

◆ wa_scan_pick()

const char * wa_scan_pick ( const wa_scan_t * s,
unsigned i )

The name at row i.

Parameters
sThe list; NULL reads as empty.
iThe row.
Returns
The name, or NULL past the end.

◆ wa_scan_read_ok()

bool wa_scan_read_ok ( uint32_t status,
unsigned reported,
bool read_ok,
unsigned read,
unsigned room )

Whether a scan reported done counts as done.

The read holds what the report counts, or fills the buffer when the report counts more than fit.

Parameters
statusThe done report's status: 0 success, other a failure.
reportedThe networks the done report counts.
read_okThe list was read (esp_wifi_scan_get_ap_records()).
readThe networks read.
roomThe records the read had room for.
Returns
true for a status of 0 and read equal to the smaller of reported and room.

◆ wa_scan_refused()

bool wa_scan_refused ( wa_t * w,
uint32_t tok )

The radio refused to start the scan of tok: off WA_OFF_FAILED when it is the scan under way.

Parameters
wThe session.
tokThe scan's token.
Returns
Whether the session ended; false for a scan no longer under way.

◆ wa_secret_make()

void wa_secret_make ( char out[WA_SECRET_LEN+1u],
wa_rand_fn rand,
void * ctx )

WA_SECRET_LEN characters of WA_SECRET_CHARS and a terminator, each drawn evenly from the alphabet (words that would favour some characters are drawn again).

Parameters
outReceives the secret.
randThe source of random words.
ctxPassed to rand.

◆ wa_serving()

bool wa_serving ( const wa_t * w)

Whether the page is being served.

Parameters
wThe session.
Returns
true with the access point up or joined, not for WA_MODE_FETCH.

◆ wa_start()

wa_off_t wa_start ( wa_t * w,
wa_mode_t mode,
wa_off_t gate,
uint32_t now_ms,
wa_rand_fn rand,
void * ctx )

Start in mode when gate is WA_OFF_NONE, with a fresh password and code.

A start while the radio runs ends that session first.

Parameters
wThe session.
modeWhat the session is for.
gatewa_gate()'s answer.
now_msNow.
randThe source of the secrets.
ctxPassed to rand.
Returns
WA_OFF_NONE, and the platform brings the radio up; otherwise the reason, and the radio stays off.

◆ wa_tick()

bool wa_tick ( wa_t * w,
uint32_t now_ms,
wa_off_t gate,
bool stop )

Once a frame: the gate, STOP and the time-outs. Off, a gate or STOP ends a linger (wa_lingers()).

Parameters
wThe session.
now_msNow.
gatewa_gate()'s answer.
stopSTOP pressed since the last call.
Returns
Whether this call switched the session off or ended its linger.

◆ wa_unlinger()

void wa_unlinger ( wa_t * w)

The platform needs the radio off now: a linger ends; a session that runs goes on.

Parameters
wThe session.