Rete#
La messa in funzione del Wi-Fi (main/main.c) è una delle parti più
strumentate del firmware, perché «sono passato alla modalità Station e non è
successo niente» è il tipo di guasto più difficile da diagnosticare su una
stazione headless. Ogni percorso che lo attraversa registra ciò che ha fatto.
Modalità Wi-Fi#
g_config.wifi_mode seleziona la configurazione di interfaccia, corrispondente
alla pagina Wireless. I numeri memorizzati sono i selettori WIFI_MODE_CFG_*
di main/include/app_config.h, che ogni consumatore usa per nome:
0=WIFI_MODE_CFG_OFF1=WIFI_MODE_CFG_STA(stazione)2=WIFI_MODE_CFG_AP(punto di accesso) —WIFI_MODE_CFG_DEFAULT, il valore di fabbrica; il dispositivo è sempre raggiungibile3=WIFI_MODE_CFG_APSTA
wifi_init() attiva il SoftAP per WIFI_MODE_CFG_OFF e per qualsiasi valore
superiore a WIFI_MODE_CFG_MAX, quindi nessun valore memorizzato può lasciare
una stazione headless senza un’amministrazione web da cui correggerlo.
Sono memorizzati fino a cinque profili STA (WIFI_STA_NUM = 5), ciascuno con la
propria casella Enable. La prima voce abilitata con un SSID non vuoto è
spinta al driver, ed è l’unica usata per quell’avvio: gli slot sono credenziali
alternative fra cui scegliere, non una rotazione su cui il firmware commuta.
Connessione di stazione robusta#
Diverse scelte di progetto deliberate rendono affidabile il percorso di stazione:
Connettere da ``WIFI_EVENT_STA_START``, non immediatamente.
esp_wifi_connect()è legale solo una volta che l’interfaccia di stazione è effettivamente avviata, ciò che il driver segnala conWIFI_EVENT_STA_START. Chiamarlo subito dopoesp_wifi_start()perde quella corsa e restituisceESP_ERR_WIFI_NOT_STARTED— nessuna associazione, nessun evento di disconnessione, nessun ritentativo. La connessione è emessa dal gestore STA_START e ogni tentativo registra il suo risultato.Intervallo di riconnessione fisso, armato su un timer. Ogni disconnessione attende lo stesso
RECONNECT_INTERVAL_MS(5 s) prima del successivoesp_wifi_connect(), armato su unesp_timer— non unvTaskDelay()dentro il gestore di eventi, che fermerebbe il loop di eventi condiviso (incluso lo stessoSTA_GOT_IPche attende) e, in un loop di disconnessione stretto, affamerebbe il task idle finché non scattasse il watchdog dei task.Capacità PMF annunciata. Un
wifi_config_tazzerato lasciapmf_cfg.capable = false, e gli AP WPA3 / WPA2-con-PMF-richiesto semplicemente rifiutano tale stazione. Il firmware imposta capable, non required, che funziona contro AP vecchi e nuovi.Ripiego su AP+STA. Solo-STA senza nulla a cui unirsi lascerebbe il dispositivo irraggiungibile, quindi ripiega su AP+STA e lo dice — l’amministrazione web resta attiva.
Dump diagnostici. Se nessuno slot STA è abilitato con un SSID, il firmware scarica ogni slot e ti dice qual è l’errore («abilitato, ma il SSID è VUOTO» vs «ha un SSID, ma “Enable” non è spuntato»).
I codici di ragione di disconnessione sono registrati anziché scartati:
Ragione |
Significato |
|---|---|
15 (4WAY_HANDSHAKE_TIMEOUT), 204 (NOT_AUTHED) |
password sbagliata |
201 (NO_AP_FOUND) |
SSID non visibile: nome sbagliato, fuori portata, o solo 5 GHz |
2 / 8 / 200 |
roaming ordinario / cadute dal lato AP |
Il flag «abbiamo internet?»#
net_state.c mantiene un singolo booleano che diventa vero solo con
IP_EVENT_STA_GOT_IP e falso alla disconnessione o in modalità solo-AP.
L’IGate lo interroga e attende un IP reale prima ancora di tentare una
connessione ad APRS-IS — essere semplicemente associati a un AP non basta.
Scansione Wi-Fi#
La scansione della pagina Wireless commuta temporaneamente una radio solo-AP ad
AP+STA. Un flag s_staEnabled condiziona ogni esp_wifi_connect()
automatico così che il gestore di eventi non litighi con la scansione.
Potenza TX#
La potenza TX (dBm) della pagina Wireless è convertita ×4 in quarti di dBm per
esp_wifi_set_max_tx_power(). Il driver rifiuta tutto ciò che sta sotto gli
8 quarti di dBm, quindi l’intervallo accettato è
WIFI_TX_POWER_DBM_MIN..``WIFI_TX_POWER_DBM_MAX`` (2-20 dBm, app_config.h)
e non 0-20: un valore inferiore viene rifiutato e lascia in vigore la potenza
precedente, che si legge come «potenza minima» pur essendo «nessun cambiamento».
Il valore viene limitato nel gestore POST di Wireless e di nuovo in
config_from_json(), così i limiti del modulo sono una comodità e ciò che
viene realmente applicato è il valore memorizzato.
Sincronizzazione oraria#
time_sync.c esegue SNTP contro tre host. È una macchina a stati non
bloccante ripiegata nel tick di servizio a 1 Hz, e imposta l’orologio di
sistema su UTC (TZ=UTC0) — i timestamp zulu della specifica APRS lo
richiedono.
Lo stesso file contiene anche una tabella incorporata di offset UTC fissi (senza
regole di ora legale), selezionata da g_config.timezone_idx dalla sezione
Time della pagina System. È solo una comodità di visualizzazione:
time_sync_format_local() somma l”utc_offset_s della voce selezionata
all’istante UTC e rilegge il risultato tramite gmtime_r(). La conversione è
pura aritmetica: non prende alcun lock, non alloca nulla e non scrive mai la
variabile TZ di processo, che viene impostata a UTC0 una sola volta
durante l’avvio SNTP e non viene più riscritta. Questo conta perché la
dashboard interroga la data/ora rappresentata una volta al secondo per tutto il
tempo di accensione del dispositivo. L’orologio di sistema, tutti i timestamp
APRS e ogni altra chiamata di formattazione oraria del firmware (tutte con
gmtime_r()) restano in UTC indipendentemente dalla selezione.
Frequenza CPU#
cpu_freq.c applica la selezione di 80/160/240 MHz della pagina System via
esp_pm_configure(), così la selezione cambia il clock reale e non viene solo
memorizzata e mostrata. Viene applicata all’avvio e di nuovo a ogni salvataggio,
senza riavvio.