fix(wifi): AP-Daten nach dem Onboarding zuruecksetzen, Netz trotz abgelehntem AP-Aufbau

This commit is contained in:
Michael Sauer
2026-10-02 01:17:00 +02:00
parent 18eb7b5c01
commit 24c4e38e4e
3 changed files with 68 additions and 8 deletions
+51 -6
View File
@@ -41,6 +41,12 @@ static uint8_t s_ap_channel = 6;
static char s_ap_live_ssid[NL_SSID_LEN], s_ap_live_pass[NL_PASS_LEN];
static uint8_t s_ap_live_channel;
static bool s_ap_live;
/* Drei Versuche, dann der Rueckfall auf Daten, die schon einmal getragen haben: einer koennte
* ein Zufall sein (das Funkteil raeumt gerade den alten AP ab), aber drei hintereinander
* heissen, dass das Funkteil genau diese Daten nicht annimmt. Und 3 x 5 s hoechstens
* 15 s ohne AP ist kuerzer als jede Fehlersuche vor Ort. */
#define NL_AP_CREATE_TRIES 3
static uint8_t s_ap_create_fails;
/* Vom HTTP-Task gefuellt, vom Netz-Task uebernommen; beides unter s_lock. */
static char s_req_ap_ssid[NL_SSID_LEN], s_req_ap_pass[NL_PASS_LEN];
static uint8_t s_req_ap_channel;
@@ -104,6 +110,16 @@ void nl_wifi_disable_sdk_auto_connect(void)
tls_wifi_disconnect();
}
/* Setzt Name, Passwort und Kanal des naechsten AP auf die Vorgaben zurueck: "ninlight-<mac4>"
* mit dem einkompilierten Passwort auf Kanal 6. Beruehrt einen LAUFENDEN AP nicht - der
* behaelt seine Daten, bis er abgebaut und neu aufgebaut wird. */
static void reset_ap_defaults(void)
{
s_ap_ssid[0] = '\0';
copy(s_ap_pass, NINLIGHT_AP_PASSWORD, sizeof s_ap_pass);
s_ap_channel = 6;
}
/* Reisst den AP ab und raeumt dabei auch die Buchfuehrung auf. Laeuft nur im Netz-Task
* (oder vor dessen Start) und nie unter s_lock - clear_softap_param() fasst SDK-Zustand an. */
static void destroy_ap(void)
@@ -159,7 +175,28 @@ static void start_ap(void)
copy(s_ap_live_ssid, ssid, sizeof s_ap_live_ssid);
copy(s_ap_live_pass, s_ap_pass, sizeof s_ap_live_pass);
s_ap_live_channel = s_ap_channel;
s_ap_create_fails = 0;
return;
}
/* Nimmt das Funkteil diese Daten dauerhaft nicht an, steht die Lampe ohne AP da - und mit
* in den Einstellungen gespeicherten Wunschdaten auch nach einem Neustart wieder. Dann
* lieber ein AP unter unerwartetem Namen: der ist sichtbar und reparierbar. */
if (++s_ap_create_fails < NL_AP_CREATE_TRIES)
return;
s_ap_create_fails = 0;
if (s_ap_live_ssid[0] && (strcmp(s_ap_live_ssid, ssid) != 0 ||
strcmp(s_ap_live_pass, s_ap_pass) != 0 ||
s_ap_live_channel != s_ap_channel)) {
printf("wifi: AP create keeps failing, falling back to the last working data (%s, ch %u)\r\n",
s_ap_live_ssid, (unsigned)s_ap_live_channel);
copy(s_ap_ssid, s_ap_live_ssid, sizeof s_ap_ssid);
copy(s_ap_pass, s_ap_live_pass, sizeof s_ap_pass);
s_ap_channel = s_ap_live_channel;
} else if (s_ap_ssid[0] || s_ap_channel != 6 || strcmp(s_ap_pass, NINLIGHT_AP_PASSWORD) != 0) {
printf("wifi: AP create keeps failing, falling back to %s on ch 6\r\n", s_hostname);
reset_ap_defaults();
}
/* Sonst scheitern schon die Vorgaben - dann bleibt nur, es weiter zu versuchen. */
}
static void connect_station(bool test)
@@ -201,6 +238,12 @@ static void execute(nl_wifi_actions_t a)
/* Sonst stuende die Lampe nach dem naechsten Neustart wieder in ihrem eigenen AP,
* obwohl sie gerade erfolgreich ins WLAN gewechselt ist. */
printf("wifi: standalone mode cleared\r\n");
/* Dieselbe Rueckstellung wie beim Zurueckschalten ueber die API: sonst kaeme ein
* spaeterer Rueckfall-AP (5 min ohne Station) mit Namen und Passwort des Nutzers
* hoch, obwohl standalone in den Einstellungen schon 0 ist. Gefahrlos, weil dieses
* Aktionsbuendel kein start_ap enthaelt - der noch laufende Standalone-AP bleibt
* unberuehrt, bis die Zustandsmaschine ihn abbaut. */
reset_ap_defaults();
nl_app_clear_standalone();
}
if (a.pulse_on)
@@ -270,10 +313,10 @@ static void net_task(void *arg)
} else {
/* Zurueck auf die Vorgaben: ein spaeterer Rueckfall- oder Onboarding-AP ist
* wieder der gewohnte "ninlight-<mac4>" mit dem einkompilierten Passwort,
* genau wie bei einer Lampe, die nie standalone war. */
s_ap_ssid[0] = '\0';
copy(s_ap_pass, NINLIGHT_AP_PASSWORD, sizeof s_ap_pass);
s_ap_channel = 6;
* genau wie bei einer Lampe, die nie standalone war. Das greift erst beim
* NAECHSTEN Aufbau - der noch laufende AP behaelt Name und Passwort, bis ihn
* die Zustandsmaschine abbaut. */
reset_ap_defaults();
ev = nl_wifi_sm_leave_standalone(&s_sm, s_ssid[0] != '\0', now);
}
s_req_pending = false;
@@ -327,8 +370,10 @@ void nl_wifi_start(const char *ssid, const char *pass, const char *ap_pass,
nl_names_hostname(s_mac, s_hostname, sizeof s_hostname);
copy(s_ssid, ssid, sizeof s_ssid);
copy(s_pass, pass, sizeof s_pass);
copy(s_ap_pass, ap_pass, sizeof s_ap_pass);
copy(s_ap_ssid, ap_ssid, sizeof s_ap_ssid); /* leer = Hostname */
/* Wie in nl_wifi_request_standalone(): NULL ist hier zwar von keinem Aufrufer zu
* erwarten, aber copy() wuerde darueber stolpern. */
copy(s_ap_pass, ap_pass && ap_pass[0] ? ap_pass : NINLIGHT_AP_PASSWORD, sizeof s_ap_pass);
copy(s_ap_ssid, ap_ssid ? ap_ssid : "", sizeof s_ap_ssid); /* leer = Hostname */
s_ap_channel = ap_channel ? ap_channel : 6;
/* The SDK would otherwise reconnect on its own with credentials from its parameter area. */