Handing incorrect wifi credentials with end users

Hi All,

I’m currently struggling with a design decision to handle a bug brought up by an alpha tester of my product.

The end user received a device with the Photon inside and attempted to connect the device to his wifi. Before sending him the device, I had cleared the memory and the wifi credentials, so that he would have a brand new device. I have set up SoftAP for easy wifi setup from a mobile device; basically when the user first opens the device, the external LEDs start blinking a certain color pattern to let the user know to set up wifi before using the product. **The problem was that he accidentally put in the wrong wifi credentials through SoftAP and now “his device is stuck.” ** I replicated this issue with my test device; to clarify what he meant, if the user enters the incorrect wifi credentials, upon resetting the device, the Photon blinks green indefinitely. It’s unable to connect to the network, as it has stored incorrect credentials, but it tries to connect anyways with the incorrect credentials.

What’s weird is that this also prevents the user from interacting from the device in any other way. The buttons aren’t registering, which makes me think the application code isn’t running. For context, I have system thread enabled, and it’s in semi-automatic mode. In setup(), the Photon attempts connecting to wifi if it scans a network in the area for which it has stored credentials.

Here’s some code:

void begin_listening() {
    // If the device has one set of incorrect credentials, after reset, it will try to connect to WiFi with those credentials 
    WiFi.on(); 
    attachInterrupt(btn2, exit_listening_isr, RISING); 
    WiFi.listen(); 

// Let the user know the device is in listening mode 
    while(WiFi.listening()) { flash_lights(1, 0, 20, 20); flash_lights(1, 20, 20, 0); }
// Let the user know the device is attempting to connect 
    while(WiFi.connecting()) { flash_lights(1, 0, 20, 20); flash_lights(1, 0, 20, 0); }

    detachInterrupt(btn2); 

    if(WiFi.ready()) {
        flash_lights(5, 0, 20, 0); // Let the user know the connection was successful 
    } else { flash_lights(5, 20, 0, 0); } // Let the user know the connection was not successful 


}

// In case the photon attempts to connect to the new network for a long time 
void exit_listening_isr() {
    detachInterrupt(btn2); 
    WiFi.listen(false); 
    System.reset(); 
}

bool is_wifi_available() { 
    WiFiAccessPoint my_aps[5];
    int num_ap = 0; 
    num_ap = WiFi.getCredentials(my_aps, 5); 
    WiFiAccessPoint scanned_aps[20];
    int found_aps = WiFi.scan(scanned_aps, 20);

    for(int i = 0; i < num_ap; i++) {
        for(int j = 0; j < found_aps; j++) {
            if(String(my_aps[i].ssid) == String(scanned_aps[j].ssid)) return true; 
        }
    }
    WiFi.off(); 
    return false; 
}

If the device is “new,” begin_listening is called in setup. After entering the incorrect wifi credentials, the user said his device blinked red, which was expected. The device went to sleep after 10 seconds, which was also expected. However, after waking it back up, the device attempted to connect to the only network it had credentials for, which were incorrect. This caused the Photon to be “stuck” flashing green, attempting to connect to the network.

I apologize if this has been addressed before. I looked through the forums for quite a bit, but I couldn’t find anything that directly addressed this problem.

Thanks in advance for your help.

Best,
Rishub

What device OS version are you running?
This seems somewhat similar to two issues I’ve seen in the past.
One is already closed

The other one I currently cannot find :blush:
Normally WiFi credentials should only be saved after a valid connection was esablished (unless you use the four parameter overload of WiFi.setCredentials() - e.g. for hidden or non-present networks).
However, with that issue even invalid credentials got stored - but IIRC that bug was squashed too.

Either you are using a version where either of these issues are still present or we see a regression.


This also closed issue might be of interest too

Thank you for the prompt response and resources @ScruffR, I sincerely appreciate the help.

I’m currently running 1.5.0 on the device. Also, I read through the two previous posts, but I’m not exactly sure how to apply their insights to my problem.

Is there anything I can do to ensure that the WiFi credentials are stored after an established connection? How do you suggest I implement that check? I’m not sure how to access the WiFi credentials received from the SoftAP.

To start off, under normal conditions invalid credentials should not be stored on the device - if they do then something is wrong on the device (or you forced them to be stored - as mentioned above).
Given that, you should be able to use WiFi.hasCredentials() to check whether the device has any WiFi creds stored at all - when planning to only having one set of creds stored this check should be enough.
If you may plan on having multiple sets stored you can use WiFi.getCredentials to check which networks are known and use WiFi.scan() to see if you find an SSID to which your device has stored credentials.

I currently don’t use setCredentials() at all, which is why I’m wondering why the incorrect WiFi credentials are getting stored.

I call WiFi.hasCredentials() in setup() to check if this is a “new” device for the user; if so, it starts flashing the LEDs to let them know to set up the wifi. The strange behavior is that if they enter an incorrect password, WiFi.hasCredentials() returns true the next time the device starts up.

Also, I do plan on having multiple sets stored. In the code I sent in the earlier post, that’s what the is_wifi_available() function does (it scans for available networks and checks if the SSID has been stored previously). That part seems to be working fine from my other tests. In fact, when the user types the incorrect credentials, WiFi.getCredentials() returns them.

So it seems that something is wrong with the device itself? Is there nothing I can do about this to help the user other than send him a new device?

I'd consider this a bug which should be investigated (@avtolstoy?).
Can you file a support ticket at support.particle.io?

@ScruffR sure I’ll file a support ticket.

UPDATE: I updated the OS to 1.5.1. Same issue.

Also, what’s interesting is that this happens every time I enter incorrect WiFi credentials. Previously, I thought that the incorrect WiFi credentials were only stored if there were no other credentials on the device. After some testing, I noticed that if I have the correct credentials stored in for “Network 1”, and then entered incorrect credentials for “Network 2,” the device stored the credentials for both of them.

The next time the device attempts to connect to WiFi, if “Network 1” is unavailable, it will endlessly attempt to connect to “Network 2,” and I’m unable to do anything e.g. interact with peripherals, write to EEPROM, etc.

Suggest that you store a default WiFi credentiial via your setup code (after first checking for its existence). This way the client will always be able to connect by setting up a hotspot on their mobile phone using the same credentials.

@Rishub
I am experiencing similar issue with 1.5.2. Did you manage to resolve this?

Any movement on this? I also haven’t found how to properly handle an incorrect password.