fix: Onboarding-Test trennt die Verbindung

I1: fail_test() kehrte ohne gespeicherte Zugangsdaten stillschweigend nach
AP_ONBOARDING zurück, ohne den Stationsversuch zu trennen; ein danach doch
noch eintreffendes CONNECTED wurde in AP_ONBOARDING ignoriert, aber der
Treiber rief nl_mdns_on_ip_up() unabhängig vom Zustand auf - die Lampe
landete offen im LAN, ohne dass Zugangsdaten gespeichert wurden.

nl_wifi_actions_t bekommt ein neues Feld `disconnect`:
- fail_test() ohne Zugangsdaten setzt es (Timeout/Fehler beendet den
  Stationsversuch).
- Ein CONNECTED-Event in AP_ONBOARDING gilt als Ausreißer eines bereits
  gescheiterten Versuchs und wird ebenfalls getrennt (Zustand bleibt
  unverändert).
- M1: nl_wifi_sm_onboard() trennt jetzt immer vor dem Testverbindungsaufbau,
  damit veraltete Events eines vorherigen Versuchs nicht mehr zählen; der
  Treiber (nl_wifi_request_onboard) meldet zusätzlich "wifi busy" (503),
  solange bereits ein Onboarding-Test läuft.

Der Treiber (src/net/nl_wifi_w600.c) führt `disconnect` vor `connect` aus
und ruft nl_mdns_on_ip_up() nur noch, wenn der Zustand nach der Verarbeitung
tatsächlich STA_CONNECTED ist.

Tests (test_wifi_sm.c): Timeout/Fehler ohne Zugangsdaten -> disconnect;
CONNECTED während AP_ONBOARDING -> disconnect, Zustand unverändert;
erneutes Onboarding während laufendem Test -> disconnect vor dem neuen
connect.
This commit is contained in:
Michael Sauer
2026-09-11 23:51:03 +02:00
parent 89c764514a
commit 3250b89986
3 changed files with 37 additions and 1 deletions
+5
View File
@@ -50,6 +50,7 @@ static void fail_test(nl_wifi_sm_t *sm, nl_wifi_error_t err, uint32_t now, nl_wi
sm->connect_at = now;
} else {
sm->state = NL_WIFI_ST_AP_ONBOARDING;
a->disconnect = true; /* I1: no stored creds -> drop the stray station attempt */
}
}
@@ -114,6 +115,9 @@ nl_wifi_actions_t nl_wifi_sm_event(nl_wifi_sm_t *sm, nl_wifi_event_t ev, nl_wifi
}
break;
case NL_WIFI_ST_AP_ONBOARDING:
if (ev == NL_WIFI_EV_CONNECTED)
a.disconnect = true; /* I1: stray success of a timed-out/failed attempt */
break;
default:
break;
}
@@ -169,6 +173,7 @@ nl_wifi_actions_t nl_wifi_sm_onboard(nl_wifi_sm_t *sm, uint32_t now)
sm->deadline = now + NL_WIFI_ONBOARD_TIMEOUT_MS;
sm->retry_armed = false;
sm->ap_stop_armed = false;
a.disconnect = true; /* M1: drop any stale station attempt so its events don't count */
a.connect = true;
a.use_test_creds = true;
return a;
+1
View File
@@ -30,6 +30,7 @@ typedef struct {
bool connect; /* connect the station ... */
bool use_test_creds; /* ... with the onboarding credentials instead of the stored ones */
bool save_test_creds; /* onboarding succeeded: persist the onboarding credentials */
bool disconnect; /* drop a stray/failed station attempt (before any connect in the same set) */
bool pulse_on;
bool pulse_off;
} nl_wifi_actions_t;
+31 -1
View File
@@ -112,6 +112,7 @@ static void test_onboarding_failure_without_credentials(void)
TEST_ASSERT_FALSE(a.pulse_off);
TEST_ASSERT_FALSE(a.stop_ap);
TEST_ASSERT_FALSE(a.connect);
TEST_ASSERT_TRUE(a.disconnect); /* I1: stray station attempt must not linger */
TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state);
TEST_ASSERT_EQUAL(NL_WIFI_ERR_AUTH, sm.error);
TEST_ASSERT_EQUAL_STRING("auth", nl_wifi_error_name(sm.error));
@@ -125,9 +126,22 @@ static void test_onboarding_timeout(void)
TEST_ASSERT_EQUAL(NL_WIFI_ST_ONBOARD_TEST, sm.state);
nl_wifi_sm_tick(&sm, 5000 + NL_WIFI_ONBOARD_TIMEOUT_MS - 1);
TEST_ASSERT_EQUAL(NL_WIFI_ST_ONBOARD_TEST, sm.state);
nl_wifi_sm_tick(&sm, 5000 + NL_WIFI_ONBOARD_TIMEOUT_MS);
a = nl_wifi_sm_tick(&sm, 5000 + NL_WIFI_ONBOARD_TIMEOUT_MS);
TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state);
TEST_ASSERT_EQUAL_STRING("timeout", nl_wifi_error_name(sm.error));
TEST_ASSERT_TRUE(a.disconnect); /* I1: timed-out onboarding test leaves no station attempt running */
}
static void test_onboarding_connected_event_while_ap_onboarding_is_stray(void)
{
/* I1: fail_test() returns to AP_ONBOARDING; a late CONNECTED for the timed-out
* attempt must be treated as stray and disconnected, not accepted. */
nl_wifi_sm_start(&sm, false, 0);
nl_wifi_sm_onboard(&sm, 5000);
nl_wifi_sm_tick(&sm, 5000 + NL_WIFI_ONBOARD_TIMEOUT_MS); /* -> AP_ONBOARDING */
a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 40000);
TEST_ASSERT_TRUE(a.disconnect);
TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state);
}
static void test_onboarding_while_connected_falls_back_to_old_credentials(void)
@@ -149,6 +163,20 @@ static void test_onboarding_while_connected_falls_back_to_old_credentials(void)
TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 16000).stop_ap);
}
static void test_onboard_while_test_running_disconnects_stale_attempt(void)
{
/* M1: a repeated onboarding request while a test connect is already in flight
* must disconnect first so stale events from the previous attempt don't count. */
nl_wifi_sm_start(&sm, false, 0);
nl_wifi_sm_onboard(&sm, 5000);
TEST_ASSERT_EQUAL(NL_WIFI_ST_ONBOARD_TEST, sm.state);
a = nl_wifi_sm_onboard(&sm, 6000);
TEST_ASSERT_TRUE(a.disconnect);
TEST_ASSERT_TRUE(a.connect);
TEST_ASSERT_TRUE(a.use_test_creds);
TEST_ASSERT_EQUAL(NL_WIFI_ST_ONBOARD_TEST, sm.state);
}
static void test_error_names(void)
{
TEST_ASSERT_NULL(nl_wifi_error_name(NL_WIFI_ERR_NONE));
@@ -185,7 +213,9 @@ int main(void)
RUN_TEST(test_onboarding_success);
RUN_TEST(test_onboarding_failure_without_credentials);
RUN_TEST(test_onboarding_timeout);
RUN_TEST(test_onboarding_connected_event_while_ap_onboarding_is_stray);
RUN_TEST(test_onboarding_while_connected_falls_back_to_old_credentials);
RUN_TEST(test_onboard_while_test_running_disconnects_stale_attempt);
RUN_TEST(test_error_names);
RUN_TEST(test_connect_without_any_event_retries);
return UNITY_END();