feat(wifi): Wechsel in und aus dem Standalone-Modus

This commit is contained in:
Michael Sauer
2026-10-01 23:41:10 +02:00
parent 1c29735eaf
commit 906a6d55f2
3 changed files with 186 additions and 1 deletions
+108
View File
@@ -282,6 +282,106 @@ static void test_standalone_without_pulse_stays_dark(void)
TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, NL_WIFI_STANDALONE_PULSE_MS).pulse_off);
}
/* Erfolg: die Lampe wechselt ins WLAN UND verlaesst den Standalone-Modus dauerhaft.
* Ohne clear_standalone staende sie nach dem naechsten Neustart wieder im eigenen AP. */
static void test_onboarding_from_standalone_clears_the_mode(void)
{
nl_wifi_sm_start(&sm, false, true, false, 0);
nl_wifi_sm_onboard(&sm, 1000);
a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 2000);
TEST_ASSERT_TRUE(a.save_test_creds);
TEST_ASSERT_TRUE(a.clear_standalone);
TEST_ASSERT_FALSE(sm.standalone);
TEST_ASSERT_EQUAL(NL_WIFI_ST_STA_CONNECTED, sm.state);
}
/* Fehlschlag: zurueck in den EIGENEN AP, nicht in den offenen Onboarding-AP. Sonst
* verloere ein Tippfehler im WLAN-Passwort den vom Nutzer gesetzten AP-Namen samt
* Passwort und entsicherte die Lampe, weil open_access() dann wieder true waere. */
static void test_failed_onboarding_returns_to_standalone(void)
{
nl_wifi_sm_start(&sm, false, true, false, 0);
nl_wifi_sm_onboard(&sm, 1000);
a = nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 2000);
TEST_ASSERT_EQUAL(NL_WIFI_ST_STANDALONE, sm.state);
TEST_ASSERT_TRUE(sm.standalone);
TEST_ASSERT_FALSE(nl_wifi_sm_open_access(&sm));
TEST_ASSERT_FALSE(a.clear_standalone);
TEST_ASSERT_EQUAL(NL_WIFI_ERR_AUTH, sm.error);
}
/* Auch der Zeitablauf des Tests fuehrt zurueck in den eigenen AP. */
static void test_onboarding_timeout_returns_to_standalone(void)
{
nl_wifi_sm_start(&sm, false, true, false, 0);
nl_wifi_sm_onboard(&sm, 1000);
nl_wifi_sm_tick(&sm, 1000 + NL_WIFI_ONBOARD_TIMEOUT_MS);
TEST_ASSERT_EQUAL(NL_WIFI_ST_STANDALONE, sm.state);
TEST_ASSERT_EQUAL(NL_WIFI_ERR_TIMEOUT, sm.error);
}
/* Der bisherige Weg bleibt unberuehrt: ohne Standalone und ohne gespeicherte Daten
* landet ein gescheiterter Test weiterhin im offenen Onboarding-AP. */
static void test_failed_onboarding_without_standalone_opens_ap(void)
{
nl_wifi_sm_start(&sm, false, false, false, 0);
nl_wifi_sm_onboard(&sm, 1000);
nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 2000);
TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state);
TEST_ASSERT_TRUE(nl_wifi_sm_open_access(&sm));
}
/* Aus dem laufenden Stationsbetrieb in den eigenen AP. */
static void test_switching_to_standalone_at_runtime(void)
{
nl_wifi_sm_start(&sm, true, false, false, 0);
nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 1000);
a = nl_wifi_sm_standalone(&sm, true, 2000);
TEST_ASSERT_TRUE(a.disconnect);
TEST_ASSERT_TRUE(a.start_ap);
TEST_ASSERT_TRUE(a.pulse_on);
TEST_ASSERT_EQUAL(NL_WIFI_ST_STANDALONE, sm.state);
TEST_ASSERT_TRUE(sm.standalone);
TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 2000 + NL_WIFI_STANDALONE_PULSE_MS).pulse_off);
}
/* Zuruecknehmen MIT gespeicherten Zugangsdaten: ab ins WLAN, nicht in den offenen AP. */
static void test_leaving_standalone_with_credentials_connects(void)
{
nl_wifi_sm_start(&sm, true, true, false, 0);
a = nl_wifi_sm_leave_standalone(&sm, true, 1000);
TEST_ASSERT_TRUE(a.connect);
TEST_ASSERT_FALSE(sm.standalone);
TEST_ASSERT_EQUAL(NL_WIFI_ST_STA_CONNECTING, sm.state);
}
/* Zuruecknehmen OHNE Zugangsdaten: offener Onboarding-AP, damit man wieder herankommt. */
static void test_leaving_standalone_without_credentials_opens_onboarding(void)
{
nl_wifi_sm_start(&sm, false, true, false, 0);
a = nl_wifi_sm_leave_standalone(&sm, false, 1000);
TEST_ASSERT_TRUE(a.start_ap);
TEST_ASSERT_TRUE(a.pulse_on);
TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state);
TEST_ASSERT_TRUE(nl_wifi_sm_open_access(&sm));
}
/* Laeuft beim Start eines Onboarding-Tests noch der Startpuls, raeumt onboard() ihn ab:
* pulse_off sofort, danach kein verwaister pulse_off mehr -- weder nach einem
* gescheiterten noch nach einem gelungenen Test. */
static void test_onboard_cancels_running_start_pulse(void)
{
nl_wifi_sm_start(&sm, false, true, true, 0);
a = nl_wifi_sm_onboard(&sm, 1000);
TEST_ASSERT_TRUE(a.pulse_off);
TEST_ASSERT_FALSE(sm.pulse_armed);
TEST_ASSERT_FALSE(sm.pulsing);
TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, NL_WIFI_STANDALONE_PULSE_MS).pulse_off);
a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 6000);
TEST_ASSERT_FALSE(a.pulse_off);
TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 20000).pulse_off);
}
int main(void)
{
UNITY_BEGIN();
@@ -306,5 +406,13 @@ int main(void)
RUN_TEST(test_standalone_drops_a_stray_connect);
RUN_TEST(test_standalone_pulse_stops_by_itself);
RUN_TEST(test_standalone_without_pulse_stays_dark);
RUN_TEST(test_onboarding_from_standalone_clears_the_mode);
RUN_TEST(test_failed_onboarding_returns_to_standalone);
RUN_TEST(test_onboarding_timeout_returns_to_standalone);
RUN_TEST(test_failed_onboarding_without_standalone_opens_ap);
RUN_TEST(test_switching_to_standalone_at_runtime);
RUN_TEST(test_leaving_standalone_with_credentials_connects);
RUN_TEST(test_leaving_standalone_without_credentials_opens_onboarding);
RUN_TEST(test_onboard_cancels_running_start_pulse);
return UNITY_END();
}