arduino-libraries / WiFiNINA

136 stars 105 forks source link

Feature request: asynchronous wifi connections #243

Open davepruitt opened 1 year ago

davepruitt commented 1 year ago

Sometimes it can take a little while to connect to a wifi network. This is especially true for enterprise wifi networks. Of course this is just on the order of milliseconds to seconds, but even that amount of time could be critical depending on the user application.

For example, let's assume I call WiFi.beginEnterprise, and it takes 2 seconds to complete. It's possible that my code could have been doing something else for those 2 seconds while the separate NINA module was doing its work, and then I could come back 2 seconds later to see if the connection attempt was succcessful.

So, it would be useful to have the ability to asynchronously connect to a wifi network, rather than blocking on the begin and beginEnterprise function calls.

I imagine there could be a few new methods that would look something like this:

int beginAsync(const char* ssid, const char *passphrase);
uint8_t beginEnterpriseAsync(const char* ssid, const char* username, const char* password);
uint8_t getAsyncConnectionStatus ();

It would also probably be necessary to define a new item in the wl_status_t enumeration called WL_CONNECTING.

Then, maybe the beginEnterpriseAsync and getAsyncConnectionStatus functions could look something like this:

uint8_t WiFiClass::beginEnterpriseAsync (const char* ssid, const char* username, const char* password, const char* identity, const char* ca)
{
    uint8_t status = WL_IDLE_STATUS;

    if (WiFiDrv::wifiSetEnterprise(0 /*PEAP/MSCHAPv2*/, ssid, strlen(ssid), username, strlen(username), password, strlen(password), identity, strlen(identity), ca, strlen(ca) + 1)!= WL_FAILURE)
    {
        _connection_start = millis();
        status = WL_CONNECTING;
    } 
    else 
    {
        status = WL_CONNECT_FAILED;
    }

    return status;
}

uint8_t WiFiClass::getAsyncConnectionStatus ()
{
    unsigned long current_millis = millis();
    uint8_t status = WL_CONNECTING;
    if (current_millis >= (_connection_start + _timeout))
    {
        status = WL_CONNECT_FAILED;
    }
    else
    {
        status = WiFiDrv::getConnectionStatus();
    }

    return status;
}

Thoughts?