From 3250b899864444f17301fac2f0af7417d988ec07 Mon Sep 17 00:00:00 2001 From: Michael Sauer Date: Fri, 11 Sep 2026 23:51:03 +0200 Subject: [PATCH] fix: Onboarding-Test trennt die Verbindung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/net/nl_wifi_sm.c | 5 +++++ src/net/nl_wifi_sm.h | 1 + test/test_wifi_sm.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/net/nl_wifi_sm.c b/src/net/nl_wifi_sm.c index 930831f..373d80a 100644 --- a/src/net/nl_wifi_sm.c +++ b/src/net/nl_wifi_sm.c @@ -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; diff --git a/src/net/nl_wifi_sm.h b/src/net/nl_wifi_sm.h index 478d16e..5db82f1 100644 --- a/src/net/nl_wifi_sm.h +++ b/src/net/nl_wifi_sm.h @@ -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; diff --git a/test/test_wifi_sm.c b/test/test_wifi_sm.c index b306afd..57a48d4 100644 --- a/test/test_wifi_sm.c +++ b/test/test_wifi_sm.c @@ -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();