Wifi timeout with periodic reconnection

Hello, I want to connect to a server through Wifi periodicaly, every n time I do the following steps:

1) Bring the interface up with `net_if_up(iface)`
2) Ask the wifi for a connection with `net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &connection_parameters, sizeof(struct wifi_connect_req_params))`
3) Wait for the wifi to be connected through some callback
4) Interact with the server, to test my problem I removed this part
5)  Ask the wifi for a deconnection with `net_mgmt(NET_REQUEST_WIFI_DISCONNECT, iface, NULL, 0)`
6) Wait for the wifi to be disconnected through some callback
7) Bring the interface down with `net_if_down(iface)`

My problem is the following: The first time I try to connect myself to the WiFi, the card never fails to succeed (as long as the SSID and the password of the WiFi are correct), but the second time I try, it almost always fails to connect to the WiFi with a timeout error. After some retries and by changing the time elapsed between two tests, it manages to reconnect, but I don't manage to find the correlation of why I have those timeout errors. I also tried to not change the status of the interface, but it didn't seem to fix it.

Here are some part of my code to help you understand more how I handle my connection:

  •  How I bring the interface up and down:

int8_t hc_wifi_start(){
    struct net_if *iface = net_if_get_default();
    if (net_if_up(iface)){
        printk("<Wrn> Couldn't wake up WiFi interface\n");
        return -1;
    }
    k_msleep(100);
    hc_status.is_wifi_on = 1; // this is a variable we use to keep track of the iface status
    return 0;
}

int8_t hc_wifi_stop(){
    struct net_if *iface = net_if_get_default();
    if (net_if_down(iface)){
        printk("<Wrn> Couldn't stop WiFi interface\n");
        return -1;
    }
    k_msleep(100);
    hc_status.is_wifi_on = 0; // this is a variable we use to keep track of the iface status
    return 0;
}

  • How I setup the Wifi:

static void hc_wifi_connect_events_handler(struct net_mgmt_event_callback *callback, uint32_t mgmt_event, struct net_if *interface)
{
    switch (mgmt_event) {
        case NET_EVENT_WIFI_CONNECT_RESULT:
            hc_wifi_connect_handler(callback);
            break;
        case NET_EVENT_WIFI_DISCONNECT_RESULT:
            hc_wifi_disconnect_handler(callback);
            break;
        case NET_EVENT_IPV4_DHCP_BOUND:
            hc_status.is_dhcp_bound = 1;
            break;
        default:
            break;
    }
}

void hc_init_wifi_connect(void)
{
    net_mgmt_init_event_callback(&wifi_connect_events_callback, hc_wifi_connect_events_handler, NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT);
    net_mgmt_init_event_callback(&ipv4_connect_events_callback, hc_wifi_connect_events_handler, NET_EVENT_IPV4_DHCP_BOUND);
    net_mgmt_add_event_callback(&wifi_connect_events_callback);
    net_mgmt_add_event_callback(&ipv4_connect_events_callback);
}

  • How I connect myself to the Wifi:

static void hc_wifi_connect_handler(struct net_mgmt_event_callback *callback)
{
    const struct wifi_status *status = (const struct wifi_status *)callback->info;

    if (status->status) {
        printk("<Err> WiFi connection failed (%d)\n", status->status);
        hc_status.is_wifi_connected = 0;
    } else {
        hc_status.is_wifi_connected = 1;
        net_dhcpv4_start(net_if_get_default());
    }
}

static void hc_wifi_configuration_reader(struct wifi_connect_req_params *parameters)
{
    parameters->timeout = HC_WIFI_CONNECTION_TIMEOUT_S;
    parameters->ssid = hc_config.wifi_ssid; // a variable we use to store the SSID
    parameters->ssid_length = hc_config.wifi_ssid_len;
    parameters->security = hc_config.wifi_security == 0 ? 1 : hc_config.wifi_security;  // a variable we use to store the network security
    parameters->psk = hc_config.wifi_psk;   // a variable we use to store the password
    parameters->psk_length = hc_config.wifi_psk_len;
    parameters->channel = WIFI_CHANNEL_ANY;
    parameters->mfp = WIFI_MFP_OPTIONAL;
}

int8_t hc_wifi_connect(void)
{
    struct net_if *interface = net_if_get_default();
    static struct wifi_connect_req_params connection_parameters;

    printk("<Inf> Connection requested\n");
    hc_wifi_configuration_reader(&connection_parameters);
    if (net_mgmt(NET_REQUEST_WIFI_CONNECT, interface, &connection_parameters, sizeof(struct wifi_connect_req_params))) {
        printk("<Err> Connection request failed\n");
        return -ENOEXEC;
    }
    return 0;
}

  • How I disconnect myself from the Wifi:

static void hc_wifi_disconnect_handler(struct net_mgmt_event_callback *callback)
{
    const struct wifi_status *status = (const struct wifi_status *) callback->info;

    if (status->status) {
        printk("<Err> WiFi disconnection failed (%d)\n", status->status);
    } else {
        printk("<Inf> WiFi disconnected\n");
        hc_status.is_wifi_connected = 0;
        hc_status.is_dhcp_bound = 0;
    }
    if (hc_wifi_task_id == HC_WIFI_TASK_DISCONNECT)
        k_thread_resume(wifi_thread);
}

int8_t hc_wifi_disconnect(void)
{
    struct net_if *interface = net_if_get_default();

    printk("<Inf> Disconnection requested\n");
    if (net_mgmt(NET_REQUEST_WIFI_DISCONNECT, interface, NULL, 0)) {
        printk("<Err> Disconnection request failed\n");
        return -ENOEXEC;
    }
    return 0;
}


I hope the information I provided about my connection/reconnection timeout issue is clear. Feel free to ask if you need more details. Have a great day!

  • Hi,

    Do you have any application logs you can share?

    How quickly do you try to reconnect again after disconnecting, and do you see a difference in behavior when you increase this time?

    Best regards,
    Marte

  • Hello, sorry for the delay. I had to do some tests to try and give you as much information as possible. One thing I might have forgotten to say is that the function call to connect to the Wi-Fi is made in another thread than the main thread. Here is how the thread is created:

    #define HC_WIFI_THREAD_STACK_SIZE 5000
    #define HC_THREAD_PRIORITY 1
    
    struct k_thread hc_wifi_thread_data;
    K_THREAD_STACK_DEFINE(hc_wifi_thread_stack, HC_WIFI_THREAD_STACK_SIZE);
    k_tid_t wifi_thread;
    
    static void hc_wifi_thread_init(void)
    {
        wifi_thread = k_thread_create(&hc_wifi_thread_data, hc_wifi_thread_stack,
                                     K_THREAD_STACK_SIZEOF(hc_wifi_thread_stack),
                                     hc_wifi_loop,
                                     NULL, NULL, NULL,
                                     HC_THREAD_PRIORITY, 0, K_NO_WAIT);
    }
    

    Regarding the logs, most of them are personal, but here is the log of one of my tests of Wi-Fi connection and disconnection:

    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> I: wifi_nrf_wpa_supp_associate: Association request sent successfully
    00> 
    00> I: Received: 192.168.1.38
    00> I: IPv4 address: 192.168.1.38
    00> I: Lease time: 86400 seconds
    00> I: Subnet: 255.255.255.0
    00> I: Router: 192.168.1.1
    00> <Inf> WiFi connected
    00> Fetching SNTP time, trying servers...
    00> <Inf> Timestamp received from server 0: 1707927033781
    00> <Inf> Disconnection requested
    00> <Inf> WiFi disconnected
    00> W: iface 0x20001dc8 is down
    00> W: iface 0x20001dc8 is down
    00> Waiting for next move
    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> <Err> WiFi connection failed (-116)
    00> <Wrn> Could not connect to the WiFi
    00> Waiting for next move
    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> <Err> WiFi connection failed (-116)
    00> <Wrn> Could not connect to the WiFi
    00> Waiting for next move
    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> <Err> WiFi connection failed (-116)
    00> <Wrn> Could not connect to the WiFi
    00> Waiting for next move
    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> I: wifi_nrf_wpa_supp_associate: Association request sent successfully
    00> 
    00> I: Received: 192.168.1.38
    00> I: IPv4 address: 192.168.1.38
    00> I: Lease time: 86400 seconds
    00> I: Subnet: 255.255.255.0
    00> I: Router: 192.168.1.1
    00> <Inf> WiFi connected
    00> Fetching SNTP time, trying servers...
    00> <Inf> Timestamp received from server 0: 1707927355024
    00> <Inf> Disconnection requested
    00> <Err> Disconnection request failed
    00> <Wrn> Could not deconnect from the wifi
    00> Waiting for next move
    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> <Err> WiFi connection failed (-116)
    00> <Wrn> Could not connect to the WiFi
    00> Waiting for next move
    00> <Inf> Executing GET_NTP_TIME
    00> <Inf> Connection requested
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> <Inf> WiFi disconnected
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> I: wifi_nrf_wpa_supp_associate: Association request sent successfully
    00> 
    00> I: Received: 192.168.1.38
    00> I: IPv4 address: 192.168.1.38
    00> I: Lease time: 86400 seconds
    00> I: Subnet: 255.255.255.0
    00> I: Router: 192.168.1.1
    00> <Inf> WiFi connected
    00> Fetching SNTP time, trying servers...
    00> <Err> Couldn't reach SNTP server 0
    00> <Inf> Timestamp received from server 1: 1707927612285
    00> <Inf> Disconnection requested
    00> <Err> Disconnection request failed
    00> <Wrn> Could not deconnect from the wifi
    00> I: wifi_nrf_wpa_supp_authenticate:Authentication request sent successfully
    00> 
    00> <Inf> WiFi disconnected

    To provide you with the maximum amount of information, I've conducted some tests and included their results below. Each test followed these steps:

    Connect to the Wi-Fi network.
    Record the current time.
    Disconnect from the Wi-Fi network.
    Wait for n seconds.
    Repeat steps 1-4 seven times.

    (Note: "OK" indicates successful connection to the Wi-Fi, while "KO" indicates a connection timeout.)

    Test Results:

    n = 0 seconds: [OK, KO, KO, KO, KO, KO, KO]
    n = 30 seconds: [OK, KO, KO, KO, OK, KO, OK]
    n = 2 minutes: [OK, KO, KO, OK, KO, KO, KO]
    n = 5 minutes: [OK, KO, OK, KO, KO, KO, KO]

    I hope these tests provide you with more information about my issue. Please let me know if you need any further clarification.

    Thank you for your time and assistance. Have a great day!

  • Hi,

    Based on your logs it seems like you are getting a timeout when trying to connect to Wi-Fi, but I have not been able to figure out why yet.

    Can you share a minimal sample, or your project, where this issue can be reproduced so I can test it on my side? If you do not want to share it in a public ticket, please let me know and I can make it private first.

    Best regards,
    Marte

  • Hello, sorry for the late response. After trying to isolate the bug from our codebase to provide you with more information, we noticed that the connection/reconnection issue was no longer present. We found that the issue was dependent on specific metrics, such as the type of Wi-Fi the card tries to connect to. This leaves us more opportunities to find the bug. We will look for it on our own for the moment, but we may reach out to you again later if we manage to isolate the bug with more accuracy. Thank you for your time and have a great day.

  • Hi,

    Thank you for the update. Let me know if you have an update and need more help!

    Best regards,
    Marte

Related