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->backoff = NL_WIFI_BACKOFF_MIN_MS;
|
||||||
sm->retry_armed = false;
|
sm->retry_armed = false;
|
||||||
a->connect = true; /* old credentials */
|
a->connect = true; /* old credentials */
|
||||||
|
sm->awaiting = true;
|
||||||
|
sm->connect_at = now;
|
||||||
} else {
|
} else {
|
||||||
sm->state = NL_WIFI_ST_AP_ONBOARDING;
|
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) {
|
if (have_creds) {
|
||||||
begin_connecting(sm, now);
|
begin_connecting(sm, now);
|
||||||
a.connect = true;
|
a.connect = true;
|
||||||
|
sm->awaiting = true;
|
||||||
|
sm->connect_at = now;
|
||||||
} else {
|
} else {
|
||||||
sm->state = NL_WIFI_ST_AP_ONBOARDING;
|
sm->state = NL_WIFI_ST_AP_ONBOARDING;
|
||||||
sm->ap_up = true;
|
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) {
|
switch (sm->state) {
|
||||||
case NL_WIFI_ST_STA_CONNECTING:
|
case NL_WIFI_ST_STA_CONNECTING:
|
||||||
case NL_WIFI_ST_APSTA_FALLBACK:
|
case NL_WIFI_ST_APSTA_FALLBACK:
|
||||||
|
sm->awaiting = false;
|
||||||
if (ev == NL_WIFI_EV_CONNECTED) {
|
if (ev == NL_WIFI_EV_CONNECTED) {
|
||||||
sm->state = NL_WIFI_ST_STA_CONNECTED;
|
sm->state = NL_WIFI_ST_STA_CONNECTED;
|
||||||
sm->retry_armed = false;
|
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;
|
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 &&
|
if ((sm->state == NL_WIFI_ST_STA_CONNECTING || sm->state == NL_WIFI_ST_APSTA_FALLBACK) && sm->retry_armed &&
|
||||||
due(now, sm->retry_at)) {
|
due(now, sm->retry_at)) {
|
||||||
sm->retry_armed = false;
|
sm->retry_armed = false;
|
||||||
a.connect = true;
|
a.connect = true;
|
||||||
|
sm->awaiting = true;
|
||||||
|
sm->connect_at = now;
|
||||||
}
|
}
|
||||||
if (sm->state == NL_WIFI_ST_ONBOARD_TEST && due(now, sm->deadline))
|
if (sm->state == NL_WIFI_ST_ONBOARD_TEST && due(now, sm->deadline))
|
||||||
fail_test(sm, NL_WIFI_ERR_TIMEOUT, now, &a);
|
fail_test(sm, NL_WIFI_ERR_TIMEOUT, now, &a);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#define NL_WIFI_AP_CLOSE_FALLBACK_MS 10000u
|
#define NL_WIFI_AP_CLOSE_FALLBACK_MS 10000u
|
||||||
#define NL_WIFI_BACKOFF_MIN_MS 1000u
|
#define NL_WIFI_BACKOFF_MIN_MS 1000u
|
||||||
#define NL_WIFI_BACKOFF_MAX_MS 60000u
|
#define NL_WIFI_BACKOFF_MAX_MS 60000u
|
||||||
|
#define NL_WIFI_CONNECT_TIMEOUT_MS 30000u /* no event after a connect -> treat as failed */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NL_WIFI_ST_AP_ONBOARDING = 0,
|
NL_WIFI_ST_AP_ONBOARDING = 0,
|
||||||
@@ -41,11 +42,13 @@ typedef struct {
|
|||||||
bool pulsing;
|
bool pulsing;
|
||||||
bool retry_armed;
|
bool retry_armed;
|
||||||
bool ap_stop_armed;
|
bool ap_stop_armed;
|
||||||
|
bool awaiting; /* waiting for response to a connect */
|
||||||
uint32_t since; /* start of the current connecting phase */
|
uint32_t since; /* start of the current connecting phase */
|
||||||
uint32_t retry_at;
|
uint32_t retry_at;
|
||||||
uint32_t backoff;
|
uint32_t backoff;
|
||||||
uint32_t deadline; /* onboarding test */
|
uint32_t deadline; /* onboarding test */
|
||||||
uint32_t ap_stop_at;
|
uint32_t ap_stop_at;
|
||||||
|
uint32_t connect_at; /* when the pending connect was issued */
|
||||||
} nl_wifi_sm_t;
|
} nl_wifi_sm_t;
|
||||||
|
|
||||||
nl_wifi_actions_t nl_wifi_sm_start(nl_wifi_sm_t *sm, bool have_creds, uint32_t now);
|
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));
|
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)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -168,5 +187,6 @@ int main(void)
|
|||||||
RUN_TEST(test_onboarding_timeout);
|
RUN_TEST(test_onboarding_timeout);
|
||||||
RUN_TEST(test_onboarding_while_connected_falls_back_to_old_credentials);
|
RUN_TEST(test_onboarding_while_connected_falls_back_to_old_credentials);
|
||||||
RUN_TEST(test_error_names);
|
RUN_TEST(test_error_names);
|
||||||
|
RUN_TEST(test_connect_without_any_event_retries);
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user