Arduino icon indicating copy to clipboard operation
Arduino copied to clipboard

[BUG]: No Return of status `WRONG_PASSWORD` during WiFi Connect

Open hasenradball opened this issue 4 years ago • 17 comments

Basic Infos

  • [x] This issue complies with the issue POLICY doc.
  • [x] I have read the documentation at readthedocs and the issue is not addressed there.
  • [x] I have tested that the issue is present in current master branch (aka latest git).
  • [x] I have searched the issue tracker for a similar issue.
  • [ ] If there is a stack dump, I have decoded it.
  • [x] I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [latest git hash or date]
  • Development Env: [Arduino IDE]
  • Operating System: [Windows|]

Settings in IDE

  • Module: [Wemos D1 mini]
  • Flash Mode: []
  • Flash Size: [4MB]
  • lwip Variant: []
  • Reset Method: [ck|nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz|]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200)

Problem Description

When try to provoke the return off info WL_WRONG_PASSWORD this does not happen. sketch is provided.

MCVE Sketch

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "wifi_secrets.h"

constexpr int LED {5};

wl_status_t get_wifi_status(void) {
  // keep in mind
  /*
    WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
    WL_IDLE_STATUS      = 0,
    WL_NO_SSID_AVAIL    = 1,
    WL_SCAN_COMPLETED   = 2,
    WL_CONNECTED        = 3,
    WL_CONNECT_FAILED   = 4,
    WL_CONNECTION_LOST  = 5,
    WL_WRONG_PASSWORD   = 6,
    WL_DISCONNECTED     = 7
  */
  wl_status_t status = WiFi.status();
  if (status == WL_NO_SHIELD) {
     Serial.println(F("\n WiFI.status == NO_SHIELD"));
  }
  else if (status == WL_IDLE_STATUS) {
    Serial.println(F("\n WiFI.status == IDLE_STATUS"));
  }
  else if (status == WL_NO_SSID_AVAIL) {
    Serial.println(F("\n WiFI.status == NO_SSID_AVAIL"));
  }
  else if (status == WL_SCAN_COMPLETED) {
    Serial.println(F("\n WiFI.status == SCAN_COMPLETED"));
  }
  else if (status == WL_CONNECTED) {
    Serial.println(F("\n WiFI.status == CONNECTED"));
  }
  else if (status == WL_CONNECT_FAILED) {
    Serial.println(F("\n WiFI.status == CONNECT_FAILED"));
  }
  else if (status == WL_CONNECTION_LOST) {
    Serial.println(F("\n WiFI.status == CONNECTION_LOST"));
  }
  else if (status == WL_WRONG_PASSWORD) {
    Serial.println(F("\n WiFI.status == WRONG_PASSWORD"));
  }
  else if (status == WL_DISCONNECTED) {
    Serial.println(F("\n WiFI.status == DISCONNECTED"));
  }
  else {
     Serial.println(F("\n No appropriate Status available!"));
  }
  return status;
}


bool wifi_connect(const char *_SSID, const char * _PASSWORD, const char *_hostname = nullptr){
  Serial.printf("Set WiFi mode to WIFI_STA - %d\n", WiFi.mode(WIFI_STA));
  if (_hostname != nullptr) WiFi.hostname(_hostname);
  // Warte auf Verbindung
  WiFi.begin(_SSID, "test");
  while (WiFi.status() != WL_CONNECTED) {
    // Status function from API
    uint8_t status_API = wifi_station_get_connect_status(); 
    Serial.printf(" 1 - Wifi status API:\t%d\n", status_API);
    
    // Status from Arduino core
    wl_status_t status_CORE = WiFi.status(); 
    Serial.printf(" 2 - Wifi status core:\t%d\n", status_CORE);

    Serial.printf(" 3 - Wifi status:\t%d\n", get_wifi_status());
    
    if ((status_API == STATION_WRONG_PASSWORD) || (status_CORE == WL_WRONG_PASSWORD)){
      return true;
    }
    delayMicroseconds(100);
  }
  return true;
}
  /*
   * if (WiFi.waitForConnectResult() == WL_CONNECTED) {
    Serial.printf(" Wifi status: %d\n", get_wifi_status());
    Serial.println("\n Connection - success! <<<");
    return true;
  }
  else {
    Serial.printf(" Wifi status: %d\n", WiFi.status());
    Serial.printf(" Wifi status: %d\n", get_wifi_status());
    Serial.println("\n Connection - failed! <<<");
    return false;
  }
}
*/

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  while (!Serial) yield();
  Serial.print("\n\n");
  WiFi.printDiag(Serial);
  //WiFi.setAutoReconnect(false);
  WiFi.setAutoConnect(false);
  WiFi.persistent(false);

  time_t tic {millis()};
  digitalWrite(LED, HIGH);
  if (wifi_connect(SSID, PASSWORD)) {
    Serial.printf("time until connect: %0.3f s\n", (millis() - tic)/1000.0);
    WiFi.disconnect();
    digitalWrite(LED, LOW);
    delay(1000);
  }
}


void loop() {
  // put your main code here, to run repeatedly:

}

Debug Messages

Debug messages go here

hasenradball avatar Jul 23 '21 08:07 hasenradball

See the following shot for example...

15 min until the ESP raises WRONG_PASSWORD

grafik

hasenradball avatar Jul 23 '21 15:07 hasenradball

Does it have different results replacing

- WiFi.setAutoConnect(false);
+ WiFi.setAutoConnect(true);

? (maybe also reconnect)

edit: is this related to the https://github.com/esp8266/Arduino/issues/7432?

mcspr avatar Jul 23 '21 16:07 mcspr

I will try

hasenradball avatar Jul 23 '21 17:07 hasenradball

Does it have different results replacing

- WiFi.setAutoConnect(false);
+ WiFi.setAutoConnect(true);

? (maybe also reconnect)

edit: is this related to the #7432?

see also this Note:

grafik

hasenradball avatar Jul 23 '21 21:07 hasenradball

With the setting WiFi.setAutoConnect(true); no positive changes --> after nearly 60 min detection of WRONG_PASSWORD. So is this Emum not usable.

 WiFI.status == DISCONNECTED
 3 - Wifi status:	7
 1 - Wifi status API:	1
 2 - Wifi status core:	7

 WiFI.status == DISCONNECTED
 3 - Wifi status:	7
 1 - Wifi status API:	1
 2 - Wifi status core:	6

 WiFI.status == WRONG_PASSWORD
 3 - Wifi status:	6
time until connect: 3498.974 s

hasenradball avatar Jul 23 '21 22:07 hasenradball

With the setting WiFi.setAutoReConnect(true); no positive changes --> after nearly 60 min detection of WRONG_PASSWORD.


 WiFI.status == DISCONNECTED
 3 - Wifi status:       7
 1 - Wifi status API:   1
 2 - Wifi status core:  7

 WiFI.status == DISCONNECTED
 3 - Wifi status:       7
 1 - Wifi status API:   1
 2 - Wifi status core:  7

 WiFI.status == DISCONNECTED
 3 - Wifi status:       7
 1 - Wifi status API:   1
 2 - Wifi status core:  7

 WiFI.status == DISCONNECTED
 3 - Wifi status:       7
 1 - Wifi status API:   2
 2 - Wifi status core:  6

 WiFI.status == WRONG_PASSWORD
 3 - Wifi status:       6
time until connect: 3522.949 s

hasenradball avatar Jul 24 '21 16:07 hasenradball

looking at the event handler, it does not see the invalid psk reason as well

int reason{0};

// insert this in the connect-check loop
void dump_reason() {
  if (reason > 0) {
    int copy{reason};
    reason = 0;
    Serial.printf(" 4 - WiFi disconnect event: %d\n", copy);
  }
}

void setup() {
  static auto disconnected = WiFi.onStationModeDisconnected([](const auto& event) {
    reason = event.reason;
  });

  ... the rest ...
}
 4 - WiFi disconnect event: 2

while on the ap box, hostapd logs psk mismatch

hostapd: wlan1-1: AP-STA-POSSIBLE-PSK-MISMATCH xx:xx:xx:xx:xx:xx

also note the invalid psk test should be at least 8bytes long i.e. something like testtest

mcspr avatar Jul 24 '21 17:07 mcspr

Do I have it implemented Correctly?

bool wifi_connect(const char *_SSID, const char * _PASSWORD, const char *_hostname = nullptr){
  Serial.printf("Set WiFi mode to WIFI_STA - %d\n", WiFi.mode(WIFI_STA));
  if (_hostname != nullptr) WiFi.hostname(_hostname);
  // Warte auf Verbindung
  WiFi.begin(_SSID, "testtest");
  while (WiFi.status() != WL_CONNECTED) {
    dump_reason();
    // Status function from API
    uint8_t status_API = wifi_station_get_connect_status(); 
    Serial.printf(" 1 - Wifi status API:\t%d\n", status_API);
    
    // Status from Arduino core
    wl_status_t status_CORE = WiFi.status(); 
    Serial.printf(" 2 - Wifi status core:\t%d\n", status_CORE);

    Serial.printf(" 3 - Wifi status:\t%d\n", get_wifi_status());
    
    if ((status_API == STATION_WRONG_PASSWORD) || (status_CORE == WL_WRONG_PASSWORD)){
      return true;
    }
    delayMicroseconds(100);
  }
  return true;
}
void setup() {
    static auto disconnected = WiFi.onStationModeDisconnected([](const auto& event) {
    reason = event.reason;
  });
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  while (!Serial) yield();
  Serial.print("\n\n");
  WiFi.printDiag(Serial);
  WiFi.setAutoReconnect(false);
  WiFi.setAutoConnect(false);
  WiFi.persistent(false);

  time_t tic {millis()};
  digitalWrite(LED, HIGH);
  if (wifi_connect(SSID, PASSWORD)) {
    Serial.printf("time until connect: %0.3f s\n", (millis() - tic)/1000.0);
    WiFi.disconnect();
    digitalWrite(LED, LOW);
    delay(1000);
  }
}

hasenradball avatar Jul 24 '21 18:07 hasenradball

@mcspr your event will not be print in my code, maybee I implemented it wrong?

hasenradball avatar Jul 25 '21 10:07 hasenradball

the reason seems to be always 0

hasenradball avatar Jul 25 '21 10:07 hasenradball

as I modified it to run - https://gist.github.com/mcspr/c7b40fea7dd1323c11ad45b08103b979 different led and wifi_connect func receives the actual real SSID and invalid PASSWORD ("testtesttest")

mcspr avatar Jul 25 '21 16:07 mcspr

Thanks for Your Update :-)

Here is the result:


 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == DISCONNECTED
 1 - Wifi status API:	1
 2 - Wifi status core:	7
 3 - Wifi status:	7

 WiFI.status == WRONG_PASSWORD
 1 - Wifi status API:	2
 2 - Wifi status core:	6
 3 - Wifi status:	6
 4 - reason:	204
time until connect: 5427.494 s

after 5400 s the WRONG PASSWORD rises... :-(

hasenradball avatar Jul 25 '21 19:07 hasenradball

how could we proceed now?

hasenradball avatar Jul 27 '21 11:07 hasenradball

from the examples above, imo it's a duplicate of the #7432

  • there is no direct 'wrong password' wifi event, only authentication related issues, so idk what it actually means from the connection manager point of view
  • wifi_station_get_connect_status() can't really be trusted to report any issues asap, until something breaks internally / some timeout only-known-to-the-sdk expires. it does not report wrong password for neither short passphrase, same as wifi_station_set_config_current() btw, or after the auth error disconnection event
  • disabling reconnect may leave the device in STATION_CONNECTING state for a long time, unless some external timeout is tracking the connection attempt and it won't report STATION_CONNECT_FAIL for a very long time

mcspr avatar Jul 27 '21 19:07 mcspr

So you mean the introduced Enum WRONG_PASSWORD in core 3.0.0 has no intention to get the info of a wrong password within a few ms?

hasenradball avatar Jul 28 '21 07:07 hasenradball

this might be a historical feature that was never implemented / broken? one mention of it is here - https://github.com/tzapu/WiFiManager/issues/528#issuecomment-366836252 although, @tablatronix might have a better explanation about the STATION_WRONG_PASSWORD and when it actually happens, since https://github.com/esp8266/Arduino/issues/4152 and https://github.com/esp8266/Arduino/pull/7652 don't go into much details and there's also https://github.com/espressif/ESP8266_NONOS_SDK/issues/218

mcspr avatar Jul 28 '21 15:07 mcspr

Good to see its not a me problem, I was going crazy with this. I get 4 as the result of WiFi.status() when I purposefully enter the wrong password, simply a connection failed error.

CodeCanna avatar Aug 01 '22 13:08 CodeCanna