1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-09-05 08:04:28 +03:00

Merge pull request #7619 from Erriez/redesign-wifi-multi

Redesign ESP8266WiFiMulti.[cpp|h]
This commit is contained in:
Develo
2020-10-02 16:02:29 -03:00
committed by GitHub
3 changed files with 626 additions and 349 deletions

View File

@@ -1,33 +1,49 @@
/* /*
This sketch trys to Connect to the best AP based on a given list This sketch shows how to use multiple WiFi networks.
In this example, ESP8266 works in AP mode.
It demonstrates:
- Fast connect to previous WiFi network at startup
- Registering multiple networks (at least 1)
- Connect to WiFi with strongest signal (RSSI)
- Fall back to connect to next WiFi when a connection failed or lost
To enable debugging output, select in the Arduino iDE:
- Tools | Debug Port: Serial
- Tools | Debug Level: WiFi
*/ */
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h> #include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti; ESP8266WiFiMulti wifiMulti;
// WiFi connect timeout per AP. Increase when connecting takes longer.
const uint32_t connectTimeoutMs = 5000;
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
Serial.println("\nESP8266 Multi WiFi example");
// Set WiFi to station mode
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
// Register multi WiFi networks
wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
// More is possible
Serial.println("Connecting Wifi...");
if (wifiMulti.run() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
} }
void loop() { void loop() {
if (wifiMulti.run() != WL_CONNECTED) { // Maintain WiFi connection
if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED) {
Serial.print("WiFi connected: ");
Serial.print(WiFi.SSID());
Serial.print(" ");
Serial.println(WiFi.localIP());
} else {
Serial.println("WiFi not connected!"); Serial.println("WiFi not connected!");
delay(1000);
} }
delay(1000);
} }

View File

@@ -1,267 +1,512 @@
/** /**
* *
* @file ESP8266WiFiMulti.cpp * @file ESP8266WiFiMulti.cpp
* @date 16.05.2015 * @date 30.09.2020
* @author Markus Sattler * @author Markus Sattler, Erriez
* *
* Copyright (c) 2015 Markus Sattler. All rights reserved. * Copyright (c) 2015-2020 Markus Sattler. All rights reserved.
* This file is part of the esp8266 core for Arduino environment. * This file is part of the esp8266 core for Arduino environment.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*/ */
#include "ESP8266WiFiMulti.h" #include "PolledTimeout.h"
#include <limits.h> #include "ESP8266WiFiMulti.h"
#include <string.h> #include <limits.h>
#include <string.h>
ESP8266WiFiMulti::ESP8266WiFiMulti() {
} /**
* @brief Print WiFi status
ESP8266WiFiMulti::~ESP8266WiFiMulti() { * @details
APlistClean(); * Macro DEBUG_ESP_WIFI and DEBUG_ESP_PORT must be configured
} * @param status
* WiFi status
bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) { */
return APlistAdd(ssid, passphrase); static void printWiFiStatus(wl_status_t status)
} {
#ifdef DEBUG_ESP_WIFI
void ESP8266WiFiMulti::cleanAPlist(void) { IPAddress ip;
APlistClean(); uint8_t *mac;
}
switch (status) {
bool ESP8266WiFiMulti::existsAP(const char* ssid, const char *passphrase) { case WL_CONNECTED:
return APlistExists(ssid, passphrase); ip = WiFi.localIP();
} mac = WiFi.BSSID();
wl_status_t ESP8266WiFiMulti::run(uint32_t connectTimeoutMs) { DEBUG_WIFI_MULTI("[WIFIM] Connected:\n");
DEBUG_WIFI_MULTI("[WIFIM] SSID: %s\n", WiFi.SSID().c_str());
wl_status_t status = WiFi.status(); DEBUG_WIFI_MULTI("[WIFIM] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) { DEBUG_WIFI_MULTI("[WIFIM] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
int8_t scanResult = WiFi.scanComplete(); DEBUG_WIFI_MULTI("[WIFIM] CH: %d\n", WiFi.channel());
DEBUG_WIFI_MULTI("[WIFIM] RSSI: %d\n", WiFi.RSSI());
if(scanResult == WIFI_SCAN_RUNNING) { break;
// scan is running, do nothing yet case WL_NO_SSID_AVAIL:
status = WL_NO_SSID_AVAIL; DEBUG_WIFI_MULTI("[WIFIM] Connecting failed AP not found.\n");
return status; break;
} case WL_CONNECT_FAILED:
DEBUG_WIFI_MULTI("[WIFIM] Connecting failed.\n");
if(scanResult == 0) { break;
// scan done, no ssids found. Start another scan. default:
DEBUG_WIFI_MULTI("[WIFI] scan done\n"); DEBUG_WIFI_MULTI("[WIFIM] Connecting failed (%d).\n", status);
DEBUG_WIFI_MULTI("[WIFI] no networks found\n"); break;
WiFi.scanDelete(); }
DEBUG_WIFI_MULTI("\n\n"); #else
delay(0); // Suppress warning unused variable
WiFi.disconnect(); (void)(status);
DEBUG_WIFI_MULTI("[WIFI] start scan\n"); #endif
// scan wifi async mode }
WiFi.scanNetworks(true);
return status; /**
} * @brief Wait for WiFi connect status change, protected with timeout
* @param connectTimeoutMs
if(scanResult > 0) { * WiFi connection timeout in ms
// scan done, analyze * @return
WifiAPEntry bestNetwork { NULL, NULL }; * WiFi connection status
int bestNetworkDb = INT_MIN; */
uint8 bestBSSID[6]; static wl_status_t waitWiFiConnect(uint32_t connectTimeoutMs)
int32_t bestChannel; {
wl_status_t status;
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
delay(0); // Set WiFi connect timeout
using esp8266::polledTimeout::oneShotMs;
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult); oneShotMs connectTimeout(connectTimeoutMs);
for(int8_t i = 0; i < scanResult; ++i) {
// Wait for WiFi status change or timeout
String ssid_scan; do {
int32_t rssi_scan; // Refresh watchdog
uint8_t sec_scan; delay(0);
uint8_t* BSSID_scan;
int32_t chan_scan; // Get WiFi status
bool hidden_scan; status = WiFi.status();
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan); // Check status
if (status == WL_CONNECTED) {
bool known = false; // Connected, print WiFi status
for(auto entry : APlist) { printWiFiStatus(status);
if(ssid_scan == entry.ssid) { // SSID match
known = true; // Return WiFi status
if(rssi_scan > bestNetworkDb) { // best network return status;
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan } else if (status == WL_CONNECT_FAILED) {
bestNetworkDb = rssi_scan; DEBUG_WIFI_MULTI("[WIFIM] Connect failed\n");
bestChannel = chan_scan;
bestNetwork = entry; // Return WiFi connect failed
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID)); return WL_CONNECT_FAILED;
} }
} } while (!connectTimeout);
break;
} DEBUG_WIFI_MULTI("[WIFIM] Connect timeout\n");
}
return WL_CONNECT_FAILED;
if(known) { }
DEBUG_WIFI_MULTI(" ---> ");
} else { /**
DEBUG_WIFI_MULTI(" "); * @brief Constructor
} */
ESP8266WiFiMulti::ESP8266WiFiMulti() : _firstRun(true)
DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*'); {
delay(0); }
}
/**
// clean up ram * @brief Destructor
WiFi.scanDelete(); */
ESP8266WiFiMulti::~ESP8266WiFiMulti()
DEBUG_WIFI_MULTI("\n\n"); {
delay(0); // Cleanup memory
APlistClean();
if(bestNetwork.ssid) { }
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
/**
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID); * @brief Add Access Point
status = WiFi.status(); * @param ssid
* WiFi SSID char array, max 32 characters + NULL character
auto startTime = millis(); * @param passphrase
// wait for connection, fail, or timeout * WiFi password char array, max 63 characters + NULL character
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeoutMs) { * @retval true
delay(10); * Success
status = WiFi.status(); * @retval false
} * Failure
*/
#ifdef DEBUG_ESP_WIFI bool ESP8266WiFiMulti::addAP(const char *ssid, const char *passphrase)
IPAddress ip; {
uint8_t * mac; return APlistAdd(ssid, passphrase);
switch(status) { }
case WL_CONNECTED:
ip = WiFi.localIP(); /**
mac = WiFi.BSSID(); * @brief Remove all Access Points from list
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n"); */
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID().c_str()); void ESP8266WiFiMulti::cleanAPlist(void)
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); {
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); APlistClean();
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel()); }
break;
case WL_NO_SSID_AVAIL: /**
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n"); * @brief Check if Access Point exists in list
break; * @param ssid
case WL_CONNECT_FAILED: * WiFi SSID
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n"); * @param passphrase
break; * WiFi Password
default: * @retval true
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status); * Success
break; * @retval false
} * Failure
#endif */
} else { bool ESP8266WiFiMulti::existsAP(const char *ssid, const char *passphrase)
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n"); {
} return APlistExists(ssid, passphrase);
}
return status;
} /**
* @brief Keep WiFi connected to Access Point with strongest WiFi signal (RSSI)
* @param connectTimeoutMs
// scan failed, or some other condition not handled above. Start another scan. * Timeout in ms per WiFi connection (excluding fixed 5 seconds scan timeout)
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n"); * @return
WiFi.disconnect(); * WiFi status
*/
DEBUG_WIFI_MULTI("[WIFI] start scan\n"); wl_status_t ESP8266WiFiMulti::run(uint32_t connectTimeoutMs)
// scan wifi async mode {
WiFi.scanNetworks(true); int8_t scanResult;
} wl_status_t status;
return status;
} // Fast connect to previous WiFi on startup
if (_firstRun) {
// ################################################################################## _firstRun = false;
bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) { // Check if previous WiFi connection saved
if (strlen(WiFi.SSID().c_str())) {
WifiAPEntry newAP; DEBUG_WIFI_MULTI("[WIFIM] Connecting saved WiFi\n");
if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { // Connect to previous saved WiFi
// fail SSID too long or missing! WiFi.begin();
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid too long\n");
return false; // Wait for status change
} status = waitWiFiConnect(connectTimeoutMs);
}
//for passphrase, max is 63 ascii + null. For psk, 64hex + null. }
if(passphrase && strlen(passphrase) > 64) {
// fail passphrase too long! // Check connection state
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase too long\n"); status = WiFi.status();
return false; if (status == WL_CONNECTED) {
} // Already connected
return status;
if(APlistExists(ssid, passphrase)) { }
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s already exists\n", ssid);
return true; // Start WiFi scan
} scanResult = startScan();
if (scanResult < 0) {
newAP.ssid = strdup(ssid); // No WiFi scan results
return WL_NO_SSID_AVAIL;
if(!newAP.ssid) { }
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n");
return false; // Try to connect to multiple WiFi's with strongest signal (RSSI)
} return connectWiFiMulti(connectTimeoutMs);
}
if(passphrase) {
newAP.passphrase = strdup(passphrase); /**
} else { * @brief Start WiFi scan
newAP.passphrase = strdup(""); * @retval >0
} * Number of detected WiFi SSID's
* @retval 0
if(!newAP.passphrase) { * No WiFi connections found
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n"); * @retval -2
free(newAP.ssid); * WiFi scan failed
return false; */
} int8_t ESP8266WiFiMulti::startScan()
{
APlist.push_back(newAP); int8_t scanResult;
DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid);
return true; DEBUG_WIFI_MULTI("[WIFIM] Start scan\n");
}
// Clean previous scan
bool ESP8266WiFiMulti::APlistExists(const char* ssid, const char *passphrase) { WiFi.scanDelete();
if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
// fail SSID too long or missing! // Remove previous WiFi SSID/password
DEBUG_WIFI_MULTI("[WIFI][APlistExists] no ssid or ssid too long\n"); WiFi.disconnect();
return false;
} // Start wifi scan in async mode
for(auto entry : APlist) { WiFi.scanNetworks(true);
if(!strcmp(entry.ssid, ssid)) {
if(!passphrase) { // Set WiFi scan timeout
if(!strcmp(entry.passphrase, "")) { using esp8266::polledTimeout::oneShotMs;
return true; oneShotMs scanTimeout(WIFI_SCAN_TIMEOUT_MS);
}
} else { // Wait for WiFi scan change or timeout
if(!strcmp(entry.passphrase, passphrase)) { do {
return true; // Refresh watchdog
} delay(0);
}
} // Check scan timeout which may occur when scan does not report completion
} if (scanTimeout) {
return false; DEBUG_WIFI_MULTI("[WIFIM] Scan timeout\n");
} return WIFI_SCAN_FAILED;
}
void ESP8266WiFiMulti::APlistClean(void) {
for(auto entry : APlist) { // Get scan result
if(entry.ssid) { scanResult = WiFi.scanComplete();
free(entry.ssid); } while (scanResult < 0);
}
if(entry.passphrase) { // Print WiFi scan result
free(entry.passphrase); printWiFiScan();
}
} // Return (positive) number of detected WiFi networks
APlist.clear(); return scanResult;
} }
/**
* @brief Connect to multiple WiFi's
* @param connectTimeoutMs
* WiFi connect timeout in ms
* @return
* WiFi conneciton status
*/
wl_status_t ESP8266WiFiMulti::connectWiFiMulti(uint32_t connectTimeoutMs)
{
int8_t scanResult;
String ssid;
int32_t rssi;
uint8_t encType;
uint8_t *bssid;
int32_t channel;
bool hidden;
// Get scan results
scanResult = WiFi.scanComplete();
// Find known WiFi networks
uint8_t known[_APlist.size()];
uint8_t numNetworks = 0;
for (int8_t i = 0; i < scanResult; i++) {
// Get network information
WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel, hidden);
// Check if the WiFi network contains an entry in AP list
for (auto entry : _APlist) {
// Check SSID
if (ssid == entry.ssid) {
// Known network
known[numNetworks++] = i;
}
}
}
// Sort WiFi networks by RSSI
for (int i = 0; i < numNetworks; i++) {
for (int j = i + 1; j < numNetworks; j++) {
if (WiFi.RSSI(known[j]) > WiFi.RSSI(known[i])) {
int8_t tmp;
// Swap indices
tmp = known[i];
known[i] = known[j];
known[j] = tmp;
}
}
}
// Print sorted indices
DEBUG_WIFI_MULTI("[WIFIM] Sorted indices: ");
for (int8_t i = 0; i < numNetworks; i++) {
DEBUG_WIFI_MULTI("%d ", known[i]);
}
DEBUG_WIFI_MULTI("\n");
// Connect to known WiFi AP's sorted by RSSI
for (int8_t i = 0; i < numNetworks; i++) {
// Get network information
WiFi.getNetworkInfo(known[i], ssid, encType, rssi, bssid, channel, hidden);
for (auto entry : _APlist) {
// Check SSID
if (ssid == entry.ssid) {
DEBUG_WIFI_MULTI("[WIFIM] Connecting %s\n", ssid);
// Connect to WiFi
WiFi.begin(ssid, entry.passphrase, channel, bssid);
// Wait for status change
if (waitWiFiConnect(connectTimeoutMs) == WL_CONNECTED) {
return WL_CONNECTED;
}
}
}
}
DEBUG_WIFI_MULTI("[WIFIM] Could not connect\n", ssid);
// Coult not connect to any WiFi network
return WL_CONNECT_FAILED;
}
// ##################################################################################
/**
* @brief Add WiFi connection to internal AP list
* @param ssid
* WiFi SSID
* @param passphrase
* WiFi Password
* @retval true
* Success
* @retval false
* Failure
*/
bool ESP8266WiFiMulti::APlistAdd(const char *ssid, const char *passphrase)
{
WifiAPEntry newAP;
if (!ssid || (*ssid == 0x00) || (strlen(ssid) > 32)) {
// Fail SSID too long or missing!
DEBUG_WIFI_MULTI("[WIFIM][APlistAdd] No ssid or ssid too long\n");
return false;
}
// For passphrase, max is 63 ascii + null. For psk, 64hex + null.
if (passphrase && (strlen(passphrase) > 64)) {
// fail passphrase too long!
DEBUG_WIFI_MULTI("[WIFIM][APlistAdd] Passphrase too long\n");
return false;
}
if (APlistExists(ssid, passphrase)) {
DEBUG_WIFI_MULTI("[WIFIM][APlistAdd] SSID: %s already exists\n", ssid);
return true;
}
newAP.ssid = strdup(ssid);
if (!newAP.ssid) {
DEBUG_WIFI_MULTI("[WIFIM][APlistAdd] Fail newAP.ssid == 0\n");
return false;
}
if (passphrase) {
newAP.passphrase = strdup(passphrase);
} else {
newAP.passphrase = strdup("");
}
if (!newAP.passphrase) {
DEBUG_WIFI_MULTI("[WIFIM][APlistAdd] Fail newAP.passphrase == 0\n");
free(newAP.ssid);
return false;
}
_APlist.push_back(newAP);
DEBUG_WIFI_MULTI("[WIFIM][APlistAdd] Add SSID: %s\n", newAP.ssid);
return true;
}
/**
* @brief Check if AP exists in list
* @param ssid
* WiFi SSID
* @param passphrase
* WiFi Password
* @return
*/
bool ESP8266WiFiMulti::APlistExists(const char *ssid, const char *passphrase)
{
if (!ssid || (*ssid == 0x00) || (strlen(ssid) > 32)) {
// Fail SSID too long or missing
DEBUG_WIFI_MULTI("[WIFIM][APlistExists] No ssid or ssid too long\n");
return false;
}
for (auto entry : _APlist) {
if (!strcmp(entry.ssid, ssid)) {
if (!passphrase) {
if (!strcmp(entry.passphrase, "")) {
return true;
}
} else {
if (!strcmp(entry.passphrase, passphrase)) {
return true;
}
}
}
}
return false;
}
/**
* @brief Remove all AP's from list
*/
void ESP8266WiFiMulti::APlistClean(void)
{
// Remove all entries from APlist
for (auto entry : _APlist) {
if (entry.ssid) {
free(entry.ssid);
}
if (entry.passphrase) {
free(entry.passphrase);
}
}
_APlist.clear();
}
/**
* @brief Print WiFi scan results
* @details
* Macro DEBUG_ESP_WIFI and DEBUG_ESP_PORT must be configured
*/
void ESP8266WiFiMulti::printWiFiScan()
{
#ifdef DEBUG_ESP_WIFI
String ssid;
int32_t rssi;
uint8_t encryptionType;
uint8_t* bssid;
int32_t channel;
bool hidden;
int8_t scanResult;
scanResult = WiFi.scanComplete();
DEBUG_WIFI_MULTI("[WIFIM] %d networks found:\n", scanResult);
// Print unsorted scan results
for (int8_t i = 0; i < scanResult; i++) {
bool known = false;
WiFi.getNetworkInfo(i, ssid, encryptionType, rssi, bssid, channel, hidden);
for(auto entry : _APlist) {
if(ssid == entry.ssid) {
// SSID match
known = true;
}
}
if (known) {
DEBUG_WIFI_MULTI(" --->");
} else {
DEBUG_WIFI_MULTI(" ");
}
DEBUG_WIFI_MULTI(" %d: [CH %02d] [%02X:%02X:%02X:%02X:%02X:%02X] %ddBm %c %s\n",
i,
channel,
bssid[0], bssid[1], bssid[2],
bssid[3], bssid[4], bssid[5],
rssi,
(encryptionType == ENC_TYPE_NONE) ? ' ' : '*',
ssid.c_str());
delay(0);
}
#endif
}

View File

@@ -1,70 +1,86 @@
/** /**
* *
* @file ESP8266WiFiMulti.h * @file ESP8266WiFiMulti.h
* @date 16.05.2015 * @date 30.09.2020
* @author Markus Sattler * @author Markus Sattler, Erriez
* *
* Copyright (c) 2015 Markus Sattler. All rights reserved. * Copyright (c) 2015-2020 Markus Sattler. All rights reserved.
* This file is part of the esp8266 core for Arduino environment. * This file is part of the esp8266 core for Arduino environment.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*/ */
#ifndef WIFICLIENTMULTI_H_ #ifndef WIFI_CLIENT_MULTI_H_
#define WIFICLIENTMULTI_H_ #define WIFI_CLIENT_MULTI_H_
#include "ESP8266WiFi.h" #include "ESP8266WiFi.h"
#include <vector> #include <vector>
#ifdef DEBUG_ESP_WIFI #ifdef DEBUG_ESP_WIFI
#ifdef DEBUG_ESP_PORT #ifdef DEBUG_ESP_PORT
#define DEBUG_WIFI_MULTI(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ ) #define DEBUG_WIFI_MULTI(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ )
#endif #endif
#endif #endif
#ifndef DEBUG_WIFI_MULTI #ifndef DEBUG_WIFI_MULTI
#define DEBUG_WIFI_MULTI(...) do { (void)0; } while (0) #define DEBUG_WIFI_MULTI(...) do { (void)0; } while (0)
#endif #endif
struct WifiAPEntry { //! Default WiFi connection timeout in ms
char * ssid; #ifndef WIFI_CONNECT_TIMEOUT_MS
char * passphrase; #define WIFI_CONNECT_TIMEOUT_MS 5000
}; #endif
typedef std::vector<WifiAPEntry> WifiAPlist; //! Default WiFi scan timeout in ms
#ifndef WIFI_SCAN_TIMEOUT_MS
class ESP8266WiFiMulti { #define WIFI_SCAN_TIMEOUT_MS 5000
public: #endif
ESP8266WiFiMulti();
~ESP8266WiFiMulti(); struct WifiAPEntry {
char *ssid;
bool addAP(const char* ssid, const char *passphrase = NULL); char *passphrase;
bool existsAP(const char* ssid, const char *passphrase = NULL); };
wl_status_t run(uint32_t connectTimeoutMs=5000); typedef std::vector<WifiAPEntry> WifiAPlist;
void cleanAPlist(void); class ESP8266WiFiMulti
{
private: public:
WifiAPlist APlist; ESP8266WiFiMulti();
bool APlistAdd(const char* ssid, const char *passphrase = NULL); ~ESP8266WiFiMulti();
bool APlistExists(const char* ssid, const char *passphrase = NULL);
void APlistClean(void); bool addAP(const char *ssid, const char *passphrase = NULL);
bool existsAP(const char *ssid, const char *passphrase = NULL);
};
wl_status_t run(uint32_t connectTimeoutMs=WIFI_CONNECT_TIMEOUT_MS);
#endif /* WIFICLIENTMULTI_H_ */
void cleanAPlist();
private:
WifiAPlist _APlist;
bool _firstRun;
bool APlistAdd(const char *ssid, const char *passphrase = NULL);
bool APlistExists(const char *ssid, const char *passphrase = NULL);
void APlistClean();
wl_status_t connectWiFiMulti(uint32_t connectTimeoutMs);
int8_t startScan();
void printWiFiScan();
};
#endif // WIFI_CLIENT_MULTI_H_