fix: Recovery-Rettungsweg gegen Endlosschleife, Werksreset und Fremdnetz absichern
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.
This commit is contained in:
+36
-7
@@ -69,6 +69,25 @@ static void clear_softap_param(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* I3: tls_sys_auto_mode_run() (sdk/Platform/Sys/tls_sys.c) kicks off an SDK-driven join right
|
||||
* after UserMain() whenever the persisted auto-connect flag is on - and tls_sys.c:264-267 turns a
|
||||
* temporary WIFI_AUTO_CNT_TMP_OFF back into WIFI_AUTO_CNT_ON and persists that, so the factory
|
||||
* default "off" is not something we may rely on. Any such join is indistinguishable from our own
|
||||
* in the netif status events, so switch it off (and drop a connection it already made) before the
|
||||
* recovery scan, not only in nl_wifi_start(). */
|
||||
void nl_wifi_disable_sdk_auto_connect(void)
|
||||
{
|
||||
u8 auto_mode = WIFI_AUTO_CNT_OFF;
|
||||
|
||||
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_GET, &auto_mode);
|
||||
if (auto_mode != WIFI_AUTO_CNT_OFF) {
|
||||
printf("wifi: SDK auto-connect was %u, switching it off\r\n", auto_mode);
|
||||
auto_mode = WIFI_AUTO_CNT_OFF;
|
||||
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_SET, &auto_mode);
|
||||
}
|
||||
tls_wifi_disconnect();
|
||||
}
|
||||
|
||||
static void start_ap(void)
|
||||
{
|
||||
struct tls_softap_info_t ap;
|
||||
@@ -220,7 +239,6 @@ static void net_task(void *arg)
|
||||
|
||||
void nl_wifi_start(const char *ssid, const char *pass, const char *ap_pass)
|
||||
{
|
||||
u8 auto_mode = WIFI_AUTO_CNT_OFF;
|
||||
nl_wifi_actions_t a;
|
||||
struct netif *nif;
|
||||
|
||||
@@ -233,12 +251,7 @@ void nl_wifi_start(const char *ssid, const char *pass, const char *ap_pass)
|
||||
copy(s_ap_pass, ap_pass, sizeof s_ap_pass);
|
||||
|
||||
/* The SDK would otherwise reconnect on its own with credentials from its parameter area. */
|
||||
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_GET, &auto_mode);
|
||||
if (auto_mode != WIFI_AUTO_CNT_OFF) {
|
||||
auto_mode = WIFI_AUTO_CNT_OFF;
|
||||
tls_wifi_auto_connect_flag(WIFI_AUTO_CNT_FLAG_SET, &auto_mode);
|
||||
}
|
||||
tls_wifi_disconnect();
|
||||
nl_wifi_disable_sdk_auto_connect();
|
||||
if (tls_wifi_softap_get_state() != WM_WIFI_DISCONNECTED) {
|
||||
/* C2: the SDK already brought up its own softap (e.g. from NETIF_IP_NET_UP before
|
||||
* we got a chance to run) - tear it down, our state machine owns AP lifecycle. */
|
||||
@@ -369,5 +382,21 @@ bool nl_wifi_join_blocking(const char *ssid, const char *pass, uint32_t timeout_
|
||||
tls_wifi_disconnect(); /* cancel a stuck/timed-out join attempt */
|
||||
return false;
|
||||
}
|
||||
/* I3 backstop: NETIF_IP_NET_UP carries no SSID, so an SDK-initiated join to its own stored AP
|
||||
* would look exactly like ours - and the lamp would then fetch http://192.168.8.1/... from a
|
||||
* foreign network. tls_wifi_get_current_bss() does report the SSID actually associated with
|
||||
* (sdk/Include/WiFi/wm_wifi.h:190), so verify it before the caller starts a download. */
|
||||
{
|
||||
struct tls_curr_bss_t bss;
|
||||
size_t n = strlen(ssid);
|
||||
|
||||
memset(&bss, 0, sizeof bss);
|
||||
tls_wifi_get_current_bss(&bss);
|
||||
if (bss.ssid_len != (u8)n || memcmp(bss.ssid, ssid, n) != 0) {
|
||||
printf("wifi: joined a different network than %s, dropping the connection\r\n", ssid);
|
||||
tls_wifi_disconnect();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user