fix: Verbindungs-Timeout im WLAN-Zustandsautomaten
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user