Page 1 of 1

WiFi.Begin does not accept specified BSSID for Access Point when connecting to WPA2 Enterprise Network

Posted: Sat Mar 16, 2024 1:21 pm
by MrSwirlyPants
Dear all,

My intention is to connect my ESP32 to the strongest AP available in a WPA2 Enterprise network. I have the luxury to test my code as well in a WPA2-PSK version of the same network, however this is only possible for test purposes. A few observations:

Examples | WiFi | WiFiScan works and shows all available AP's, with RSSI
Examples | WiFi | WiFiClient works with WPA2-PSK and connects
Examples | WiFi | WiFiClientEnterprise works with WPA2-Enterprise and connects

Thanks to several forumposts around the internet I have the code as shown below. It searches for the strongest AP and tells WiFi.begin to connect to the AP with the BSSID belonging to the strongest AP.

If I run the code for the WPA2-PSK network, it does exactly as specified: it shows the BSSID of the AP I'm connected to, and it corresponds to the strongest from the list shown by the scan of the AP's.

If I run the code for the WPA2-Enterprise network, it takes a bit longer to connect, but IT NEVER CONNECTS TO THE SPECIFIED BSSID. I almost always get a connection to an AP with lower RSSI.

In the code I have specified where a line should be commented / uncommented to connect to either a regular network or an enterprise network.

I have searched several forums but I can't seem to find anyone mentioning this exact problem. Could this be something in the code supplied by "esp_wpa2.h", or could this be something in the network I'm trying to connect to - though I can't fathom what.

Thank you for reading and much obliged for any help anyone can offer, even if it's just reproducing the problem.

With kind regards,

Swirly

Code: Select all

#include "WiFi.h"
#include "esp_wpa2.h"

const char* ssid     = "********"; // Change this to your WiFi SSID
const char* username = "********"; // Change this to your WiFi username, if needed for WPA2 enterprise
const char* password = "********"; // Change this to your WiFi password

void setup()
{
  Serial.begin(115200);
  while(!Serial){delay(100);}
  Serial.println("Connecting to WiFi");

  WiFi.persistent(false); //Avoid to store Wifi configuration in Flash
  WiFi.mode(WIFI_STA);
  WiFi.disconnect(); // delete old config
  delay(100);

  int i_strongest = -1;
  int32_t rssi_strongest = -100;
  Serial.printf("Start scanning for SSID %s\r\n", ssid);

  int n = WiFi.scanNetworks(); // WiFi.scanNetworks will return the number of networks found
  Serial.println("Scan done.");

  if (n == 0)
  {
    Serial.println("No networks found!");  
  }
  else
  {
    Serial.printf("%d networks found:\n", n);
    for (int i = 0; i < n; ++i)
    {
      // Print SSID and RSSI for each network found
      Serial.printf("%d: BSSID: %s  %2ddBm, %3d%%  %9s  %s\r\n", i, WiFi.BSSIDstr(i).c_str(), WiFi.RSSI(i), constrain(2 * (WiFi.RSSI(i) + 100), 0, 100), (WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? "open" : "encrypted", WiFi.SSID(i).c_str());
      if ((String(ssid) == String(WiFi.SSID(i)) && (WiFi.RSSI(i)) > rssi_strongest))
      {
        rssi_strongest = WiFi.RSSI(i);
        i_strongest = i;
      }
    }
  }

  if (i_strongest < 0)
  {
    Serial.printf("No network with SSID %s found!\r\n", ssid);
  }
  Serial.printf("SSID match found at %d. Connecting...\r\n", i_strongest);

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  
  //Select this line to make connection to WPA2 enterprise network
  WiFi.begin(ssid, WPA2_AUTH_PEAP, username, username, password,NULL,NULL,NULL,0,WiFi.BSSID(i_strongest),true);
  
  //Select this line to make connection to WPA2 personal network / regular wifi network
  //WiFi.begin(ssid,password,0,WiFi.BSSID(i_strongest),true);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(100);
  }

  Serial.println(" connected!");
  Serial.print("BSSID: ");
  Serial.println(WiFi.BSSIDstr());
  Serial.print("RSSI: ");
  Serial.println(WiFi.RSSI());
  Serial.println(WiFi.localIP()); //print LAN IP
}

void loop()
{
}