#include #include "unity.h" #include "net/nl_wifi_sm.h" static nl_wifi_sm_t sm; static nl_wifi_actions_t a; void setUp(void) { memset(&sm, 0, sizeof sm); } void tearDown(void) {} static void test_start_without_credentials_opens_ap(void) { a = nl_wifi_sm_start(&sm, false, 0); TEST_ASSERT_TRUE(a.start_ap); TEST_ASSERT_TRUE(a.pulse_on); TEST_ASSERT_FALSE(a.connect); TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state); TEST_ASSERT_TRUE(nl_wifi_sm_open_access(&sm)); TEST_ASSERT_EQUAL_STRING("ap", nl_wifi_sm_mode(&sm)); } static void test_start_with_credentials_connects(void) { a = nl_wifi_sm_start(&sm, true, 0); TEST_ASSERT_TRUE(a.connect); TEST_ASSERT_FALSE(a.use_test_creds); TEST_ASSERT_FALSE(a.start_ap); TEST_ASSERT_FALSE(nl_wifi_sm_open_access(&sm)); a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 3000); TEST_ASSERT_EQUAL(NL_WIFI_ST_STA_CONNECTED, sm.state); TEST_ASSERT_EQUAL_STRING("sta", nl_wifi_sm_mode(&sm)); } static void test_retry_with_backoff(void) { nl_wifi_sm_start(&sm, true, 0); nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 1000); TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 1999).connect); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 2000).connect); nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 3000); TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 4999).connect); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 5000).connect); /* 2 s */ nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 6000); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 10000).connect); /* 4 s */ for (int i = 0; i < 10; i++) nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 20000); TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 79999).connect); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 80000).connect); /* capped at 60 s */ } static void test_fallback_after_five_minutes(void) { nl_wifi_sm_start(&sm, true, 0); nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_NOT_FOUND, 1000); a = nl_wifi_sm_tick(&sm, NL_WIFI_FALLBACK_MS - 1); TEST_ASSERT_FALSE(a.start_ap); a = nl_wifi_sm_tick(&sm, NL_WIFI_FALLBACK_MS); TEST_ASSERT_TRUE(a.start_ap); TEST_ASSERT_FALSE(a.pulse_on); TEST_ASSERT_EQUAL(NL_WIFI_ST_APSTA_FALLBACK, sm.state); TEST_ASSERT_EQUAL_STRING("apsta", nl_wifi_sm_mode(&sm)); TEST_ASSERT_FALSE(nl_wifi_sm_open_access(&sm)); /* retries continue */ nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_NOT_FOUND, 400000); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 460000).connect); /* reconnect closes the AP 10 s later */ a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 500000); TEST_ASSERT_FALSE(a.stop_ap); TEST_ASSERT_EQUAL(NL_WIFI_ST_STA_CONNECTED, sm.state); TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 509999).stop_ap); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 510000).stop_ap); TEST_ASSERT_EQUAL_STRING("sta", nl_wifi_sm_mode(&sm)); } static void test_disconnect_while_connected(void) { nl_wifi_sm_start(&sm, true, 0); nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 1000); nl_wifi_sm_event(&sm, NL_WIFI_EV_DISCONNECTED, NL_WIFI_ERR_NONE, 100000); TEST_ASSERT_EQUAL(NL_WIFI_ST_STA_CONNECTING, sm.state); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 101000).connect); /* fallback timer restarts at the disconnect */ TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 100000 + NL_WIFI_FALLBACK_MS - 1).start_ap); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 100000 + NL_WIFI_FALLBACK_MS).start_ap); } static void test_onboarding_success(void) { nl_wifi_sm_start(&sm, false, 0); a = nl_wifi_sm_onboard(&sm, 5000); TEST_ASSERT_FALSE(a.start_ap); /* already up */ TEST_ASSERT_TRUE(a.connect); TEST_ASSERT_TRUE(a.use_test_creds); TEST_ASSERT_EQUAL(NL_WIFI_ST_ONBOARD_TEST, sm.state); TEST_ASSERT_TRUE(nl_wifi_sm_open_access(&sm)); TEST_ASSERT_EQUAL_STRING("apsta", nl_wifi_sm_mode(&sm)); TEST_ASSERT_FALSE(nl_wifi_sm_event(&sm, NL_WIFI_EV_DISCONNECTED, NL_WIFI_ERR_NONE, 6000).save_test_creds); a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 9000); TEST_ASSERT_TRUE(a.save_test_creds); TEST_ASSERT_TRUE(a.pulse_off); TEST_ASSERT_EQUAL(NL_WIFI_ST_STA_CONNECTED, sm.state); TEST_ASSERT_FALSE(nl_wifi_sm_open_access(&sm)); TEST_ASSERT_FALSE(nl_wifi_sm_tick(&sm, 9000 + NL_WIFI_AP_CLOSE_ONBOARD_MS - 1).stop_ap); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 9000 + NL_WIFI_AP_CLOSE_ONBOARD_MS).stop_ap); } static void test_onboarding_failure_without_credentials(void) { nl_wifi_sm_start(&sm, false, 0); nl_wifi_sm_onboard(&sm, 5000); a = nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_AUTH, 8000); TEST_ASSERT_FALSE(a.pulse_off); TEST_ASSERT_FALSE(a.stop_ap); TEST_ASSERT_FALSE(a.connect); 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)); TEST_ASSERT_TRUE(nl_wifi_sm_open_access(&sm)); } static void test_onboarding_timeout(void) { nl_wifi_sm_start(&sm, false, 0); nl_wifi_sm_onboard(&sm, 5000); 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); TEST_ASSERT_EQUAL(NL_WIFI_ST_AP_ONBOARDING, sm.state); TEST_ASSERT_EQUAL_STRING("timeout", nl_wifi_error_name(sm.error)); } static void test_onboarding_while_connected_falls_back_to_old_credentials(void) { nl_wifi_sm_start(&sm, true, 0); nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 1000); a = nl_wifi_sm_onboard(&sm, 2000); TEST_ASSERT_TRUE(a.start_ap); TEST_ASSERT_FALSE(a.pulse_on); TEST_ASSERT_TRUE(a.use_test_creds); TEST_ASSERT_FALSE(nl_wifi_sm_open_access(&sm)); a = nl_wifi_sm_event(&sm, NL_WIFI_EV_JOIN_FAILED, NL_WIFI_ERR_NOT_FOUND, 4000); TEST_ASSERT_TRUE(a.connect); TEST_ASSERT_FALSE(a.use_test_creds); TEST_ASSERT_EQUAL(NL_WIFI_ST_APSTA_FALLBACK, sm.state); TEST_ASSERT_EQUAL_STRING("not_found", nl_wifi_error_name(sm.error)); a = nl_wifi_sm_event(&sm, NL_WIFI_EV_CONNECTED, NL_WIFI_ERR_NONE, 6000); TEST_ASSERT_FALSE(a.save_test_creds); TEST_ASSERT_TRUE(nl_wifi_sm_tick(&sm, 16000).stop_ap); } static void test_error_names(void) { TEST_ASSERT_NULL(nl_wifi_error_name(NL_WIFI_ERR_NONE)); 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(); RUN_TEST(test_start_without_credentials_opens_ap); RUN_TEST(test_start_with_credentials_connects); RUN_TEST(test_retry_with_backoff); RUN_TEST(test_fallback_after_five_minutes); RUN_TEST(test_disconnect_while_connected); RUN_TEST(test_onboarding_success); RUN_TEST(test_onboarding_failure_without_credentials); 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(); }