C1: nl_recovery_try() verglich nichts mit der laufenden Firmware. Vor einer laufenden Rettungsstation - laut Spec 9 der Normalfall, solange eine Charge migriert - lud die Lampe bei jedem Boot dasselbe Image erneut und startete neu. nl_ota_start_recovery() setzt jetzt ein Flag, das nl_fwup_verify_tail() nur im Recovery-Pfad auswerten lässt: Trägt der Trailer dieselbe Version wie die laufende Firmware (nl_trailer_version(), bisher ungenutzt), wird das Image abgelehnt und der Boot läuft normal weiter. Ein absichtliches Neuflashen derselben Version über die REST-API bleibt möglich. Kein neuer Wert im last_ota_error-Vokabular (Spec 8.2); unterschieden wird über die Konsole. C1/I2: boot_ms wurde erst nach nl_recovery_try() gesetzt und der Power-Cycle-Zähler erst 5 s danach gelöscht - bei erfolgreicher Recovery also nie. Nach NL_FACTORY_RESET_BOOTS Runden folgte ein Werksreset. boot_ms startet jetzt am Anfang von app_task (damit gilt wieder das in Spec 3.4/5.5 zugesagte 5-s-Fenster statt faktisch ~8 s), und nl_app_clear_reset_counter() löscht den Zähler zusätzlich, sobald die Rettungsstation gefunden ist. I3: tls_sys_auto_mode_run() stößt direkt nach UserMain() einen SDK-eigenen Verbindungsversuch an; das dabei entstehende NETIF_IP_NET_UP war in recovery_join_event() nicht vom eigenen Join zu unterscheiden, die Lampe hätte im falschen Netz geladen. nl_wifi_disable_sdk_auto_connect() schaltet das Flag ab und kappt eine bestehende Verbindung jetzt am Anfang von nl_recovery_try(); zusätzlich prüft nl_wifi_join_blocking() über tls_wifi_get_current_bss(), dass die Verbindung wirklich zur erwarteten SSID gehört.
45 lines
2.3 KiB
C
45 lines
2.3 KiB
C
#ifndef NL_WIFI_H
|
|
#define NL_WIFI_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "config/nl_settings.h"
|
|
|
|
typedef struct {
|
|
const char *mode; /* "sta" | "ap" | "apsta" */
|
|
char ssid[NL_SSID_LEN]; /* configured station SSID */
|
|
int rssi; /* dBm, 0 when not connected */
|
|
char ip[16]; /* station IP, else the AP IP when the AP is up, else "" */
|
|
char sta_ip[16]; /* "" when the station has no IP */
|
|
const char *error; /* result of the last onboarding test or NULL */
|
|
} nl_wifi_status_t;
|
|
|
|
/* Incremented once per net_task loop iteration; app_main's watchdog feed checks it to make
|
|
* sure the network task is still alive, not just the light task. */
|
|
extern volatile uint32_t nl_net_beat;
|
|
|
|
/* Starts the network task. An empty ssid starts the onboarding AP. Strings are copied. */
|
|
void nl_wifi_start(const char *ssid, const char *pass, const char *ap_pass);
|
|
/* Switches the SDK's own auto-connect off and drops any connection it may already have brought
|
|
* up on its own. nl_wifi_start() does this too, but the boot recovery path runs before that and
|
|
* must not have the SDK joining its stored AP in parallel (I3, final review). Safe to call any
|
|
* number of times; only writes the SDK parameter when it is actually set. */
|
|
void nl_wifi_disable_sdk_auto_connect(void);
|
|
/* Joins a station directly (no nl_wifi_sm) and blocks until it gets an IP or timeout_ms
|
|
* elapses; returns true on success. For use before nl_wifi_start() only - e.g. the boot
|
|
* recovery path in nl_recovery.c - since it drives the SDK Wi-Fi calls itself instead of
|
|
* going through the state machine, and must not race nl_wifi_start()'s own netif status
|
|
* event registration and s_lock/s_queue setup. Feeds the watchdog itself while it waits. */
|
|
bool nl_wifi_join_blocking(const char *ssid, const char *pass, uint32_t timeout_ms);
|
|
/* Starts an onboarding test with new credentials (from the HTTP task). 0 = queued. */
|
|
int nl_wifi_request_onboard(const char *ssid, const char *pass);
|
|
/* True while the unconfigured onboarding AP is open (API without token). */
|
|
bool nl_wifi_open_access(void);
|
|
void nl_wifi_status(nl_wifi_status_t *out);
|
|
/* "ninlight-<mac4>", valid after nl_wifi_start(). */
|
|
const char *nl_wifi_hostname(void);
|
|
void nl_wifi_mac(uint8_t mac[6]);
|
|
|
|
#endif
|