fix: Verbindungs-Timeout im WLAN-Zustandsautomaten

This commit is contained in:
Michael Sauer
2026-09-11 22:42:49 +02:00
parent 2bdeaed98d
commit 2f7cadaeee
3 changed files with 38 additions and 0 deletions
+15
View File
@@ -46,6 +46,8 @@ static void fail_test(nl_wifi_sm_t *sm, nl_wifi_error_t err, uint32_t now, nl_wi
sm->backoff = NL_WIFI_BACKOFF_MIN_MS;
sm->retry_armed = false;
a->connect = true; /* old credentials */
sm->awaiting = true;
sm->connect_at = now;
} else {
sm->state = NL_WIFI_ST_AP_ONBOARDING;
}
@@ -60,6 +62,8 @@ nl_wifi_actions_t nl_wifi_sm_start(nl_wifi_sm_t *sm, bool have_creds, uint32_t n
if (have_creds) {
begin_connecting(sm, now);
a.connect = true;
sm->awaiting = true;
sm->connect_at = now;
} else {
sm->state = NL_WIFI_ST_AP_ONBOARDING;
sm->ap_up = true;
@@ -77,6 +81,7 @@ nl_wifi_actions_t nl_wifi_sm_event(nl_wifi_sm_t *sm, nl_wifi_event_t ev, nl_wifi
switch (sm->state) {
case NL_WIFI_ST_STA_CONNECTING:
case NL_WIFI_ST_APSTA_FALLBACK:
sm->awaiting = false;
if (ev == NL_WIFI_EV_CONNECTED) {
sm->state = NL_WIFI_ST_STA_CONNECTED;
sm->retry_armed = false;
@@ -131,10 +136,20 @@ nl_wifi_actions_t nl_wifi_sm_tick(nl_wifi_sm_t *sm, uint32_t now)
a.start_ap = true;
}
}
if ((sm->state == NL_WIFI_ST_STA_CONNECTING || sm->state == NL_WIFI_ST_APSTA_FALLBACK) && sm->awaiting && !sm->retry_armed &&
due(now, sm->connect_at + NL_WIFI_CONNECT_TIMEOUT_MS)) {
sm->awaiting = false;
uint32_t timeout_at = sm->connect_at + NL_WIFI_CONNECT_TIMEOUT_MS;
sm->retry_armed = true;
sm->retry_at = timeout_at + sm->backoff;
sm->backoff = sm->backoff * 2u > NL_WIFI_BACKOFF_MAX_MS ? NL_WIFI_BACKOFF_MAX_MS : sm->backoff * 2u;
}
if ((sm->state == NL_WIFI_ST_STA_CONNECTING || sm->state == NL_WIFI_ST_APSTA_FALLBACK) && sm->retry_armed &&
due(now, sm->retry_at)) {
sm->retry_armed = false;
a.connect = true;
sm->awaiting = true;
sm->connect_at = now;
}
if (sm->state == NL_WIFI_ST_ONBOARD_TEST && due(now, sm->deadline))
fail_test(sm, NL_WIFI_ERR_TIMEOUT, now, &a);
+3
View File
@@ -10,6 +10,7 @@
#define NL_WIFI_AP_CLOSE_FALLBACK_MS 10000u
#define NL_WIFI_BACKOFF_MIN_MS 1000u
#define NL_WIFI_BACKOFF_MAX_MS 60000u
#define NL_WIFI_CONNECT_TIMEOUT_MS 30000u /* no event after a connect -> treat as failed */
typedef enum {
NL_WIFI_ST_AP_ONBOARDING = 0,
@@ -41,11 +42,13 @@ typedef struct {
bool pulsing;
bool retry_armed;
bool ap_stop_armed;
bool awaiting; /* waiting for response to a connect */
uint32_t since; /* start of the current connecting phase */
uint32_t retry_at;
uint32_t backoff;
uint32_t deadline; /* onboarding test */
uint32_t ap_stop_at;
uint32_t connect_at; /* when the pending connect was issued */
} nl_wifi_sm_t;
nl_wifi_actions_t nl_wifi_sm_start(nl_wifi_sm_t *sm, bool have_creds, uint32_t now);
+20
View File
@@ -155,6 +155,25 @@ static void test_error_names(void)
TEST_ASSERT_EQUAL_STRING("not_found", nl_wifi_error_name(NL_WIFI_ERR_NOT_FOUND));
}
static void test_connect_without_any_event_retries(void)
{
nl_wifi_sm_start(&sm, true, 0);
TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 29999).connect);
TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 30000).connect); /* retry scheduled at 31000 */
TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 31000).connect);
/* next timeout: 31000 + 30000 + 2000 backoff = 63000 */
TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 62999).connect);
TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 63000).connect);
/* fallback after 300000 ms, and attempts continue */
a = nl_wifi_sm_tick(&sm, 300000);
TEST_ASSERT_TRUE(a.start_ap);
TEST_ASSERT_EQUAL(NL_WIFI_ST_APSTA_FALLBACK, sm.state);
TEST_ASSERT_EQUAL_STRING("apsta", nl_wifi_sm_mode(&sm));
/* another attempt fires later */
a = nl_wifi_sm_tick(&sm, 360000);
TEST_ASSERT_TRUE(a.connect);
}
int main(void)
{
UNITY_BEGIN();
@@ -168,5 +187,6 @@ int main(void)
RUN_TEST(test_onboarding_timeout);
RUN_TEST(test_onboarding_while_connected_falls_back_to_old_credentials);
RUN_TEST(test_error_names);
RUN_TEST(test_connect_without_any_event_retries);
return UNITY_END();
}