1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

add WiFi scan Async mode

This commit is contained in:
Markus Sattler 2015-06-16 18:26:34 +02:00
parent 7a9563d6c6
commit 9a1ff7f70d
3 changed files with 176 additions and 95 deletions

View File

@ -40,7 +40,9 @@ extern "C" void esp_schedule();
extern "C" void esp_yield(); extern "C" void esp_yield();
ESP8266WiFiClass::ESP8266WiFiClass() ESP8266WiFiClass::ESP8266WiFiClass()
: _useApMode(false) : _smartConfigStarted(false)
, _smartConfigDone(false)
, _useApMode(false)
, _useClientMode(false) , _useClientMode(false)
, _useStaticIp(false) , _useStaticIp(false)
{ {
@ -121,7 +123,7 @@ uint8_t ESP8266WiFiClass::waitForConnectResult(){
} }
// You will have to set the DNS-Server manually later since this will not enable DHCP // You will have to set the DNS-Server manually later since this will not enable DHCP2
void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet) void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
{ {
struct ip_info info; struct ip_info info;
@ -357,12 +359,47 @@ void ESP8266WiFiClass::_scanDone(void* result, int status)
} }
} }
esp_schedule();
ESP8266WiFiClass::_scanStarted = false;
ESP8266WiFiClass::_scanComplete = true;
if(!ESP8266WiFiClass::_scanAsync) {
esp_schedule();
}
} }
int8_t ESP8266WiFiClass::scanComplete() {
int8_t ESP8266WiFiClass::scanNetworks() if(_scanStarted) {
return WIFI_SCAN_RUNNING;
}
if(_scanComplete) {
return ESP8266WiFiClass::_scanCount;
}
return WIFI_SCAN_FAILD;
}
void ESP8266WiFiClass::scanDelete()
{ {
if (ESP8266WiFiClass::_scanResult)
{
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiClass::_scanResult);
ESP8266WiFiClass::_scanResult = 0;
ESP8266WiFiClass::_scanCount = 0;
}
_scanComplete = false;
}
int8_t ESP8266WiFiClass::scanNetworks(bool async)
{
if(ESP8266WiFiClass::_scanStarted) {
return WIFI_SCAN_RUNNING;
}
ESP8266WiFiClass::_scanAsync = async;
if(_useApMode) { if(_useApMode) {
// turn on AP+STA mode // turn on AP+STA mode
mode(WIFI_AP_STA); mode(WIFI_AP_STA);
@ -377,21 +414,28 @@ int8_t ESP8266WiFiClass::scanNetworks()
disconnect(); disconnect();
} }
if (ESP8266WiFiClass::_scanResult) scanDelete();
{
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiClass::_scanResult);
ESP8266WiFiClass::_scanResult = 0;
ESP8266WiFiClass::_scanCount = 0;
}
struct scan_config config; struct scan_config config;
config.ssid = 0; config.ssid = 0;
config.bssid = 0; config.bssid = 0;
config.channel = 0; config.channel = 0;
config.show_hidden = 0; config.show_hidden = 0;
wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiClass::_scanDone)); if(wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiClass::_scanDone))) {
esp_yield(); ESP8266WiFiClass::_scanComplete = false;
return ESP8266WiFiClass::_scanCount; ESP8266WiFiClass::_scanStarted = true;
if(ESP8266WiFiClass::_scanAsync) {
delay(0); // time for the OS to trigger the scan
return WIFI_SCAN_RUNNING;
}
esp_yield();
return ESP8266WiFiClass::_scanCount;
} else {
return WIFI_SCAN_FAILD;
}
} }
void * ESP8266WiFiClass::_getScanInfoByIndex(int i) void * ESP8266WiFiClass::_getScanInfoByIndex(int i)
@ -644,6 +688,10 @@ void ESP8266WiFiClass::printDiag(Print& p)
} }
bool ESP8266WiFiClass::_scanAsync = false;
bool ESP8266WiFiClass::_scanStarted = false;
bool ESP8266WiFiClass::_scanComplete = false;
size_t ESP8266WiFiClass::_scanCount = 0; size_t ESP8266WiFiClass::_scanCount = 0;
void* ESP8266WiFiClass::_scanResult = 0; void* ESP8266WiFiClass::_scanResult = 0;

View File

@ -32,6 +32,9 @@ extern "C" {
#include "WiFiClient.h" #include "WiFiClient.h"
#include "WiFiServer.h" #include "WiFiServer.h"
#define WIFI_SCAN_RUNNING (-1)
#define WIFI_SCAN_FAILD (-2)
enum WiFiMode { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 }; enum WiFiMode { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 };
class ESP8266WiFiClass class ESP8266WiFiClass
@ -189,12 +192,26 @@ public:
int32_t RSSI(); int32_t RSSI();
/*
* called to get the scan state in Async mode
*
* return -1 if scan not fin
* return -2 if scan not triggered
*/
int8_t scanComplete();
/*
* delete last scan result from RAM
*/
void scanDelete();
/* /*
* Start scan WiFi networks available * Start scan WiFi networks available
* *
* return: Number of discovered networks * return: Number of discovered networks
*/ */
int8_t scanNetworks(); int8_t scanNetworks(bool async = false);
/* /*
* Return the SSID discovered during the network scan. * Return the SSID discovered during the network scan.
@ -314,13 +331,17 @@ protected:
void * _getScanInfoByIndex(int i); void * _getScanInfoByIndex(int i);
static void _smartConfigCallback(uint32_t status, void* result); static void _smartConfigCallback(uint32_t status, void* result);
static void _eventCallback(void *event); static void _eventCallback(void *event);
bool _smartConfigStarted = false; bool _smartConfigStarted;
bool _smartConfigDone = false; bool _smartConfigDone;
bool _useApMode; bool _useApMode;
bool _useClientMode; bool _useClientMode;
bool _useStaticIp; bool _useStaticIp;
static bool _scanAsync;
static bool _scanStarted;
static bool _scanComplete;
static size_t _scanCount; static size_t _scanCount;
static void* _scanResult; static void* _scanResult;

View File

@ -40,107 +40,119 @@ bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) {
wl_status_t ESP8266WiFiMulti::run(void) { wl_status_t ESP8266WiFiMulti::run(void) {
int8_t scanResult;
wl_status_t status = WiFi.status(); wl_status_t status = WiFi.status();
if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) { if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) {
WifiAPlist_t bestNetwork { NULL, NULL }; scanResult = WiFi.scanComplete();
int bestNetworkDb = INT_MIN; if(scanResult == WIFI_SCAN_RUNNING) {
uint8 bestBSSID[6]; // scan is running
int32_t bestChannel; return WL_NO_SSID_AVAIL;
} else if(scanResult > 0) {
// scan done analyze
WifiAPlist_t bestNetwork { NULL, NULL };
int bestNetworkDb = INT_MIN;
uint8 bestBSSID[6];
int32_t bestChannel;
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n"); DEBUG_WIFI_MULTI("[WIFI] scan done\n");
WiFi.disconnect(); delay(0);
DEBUG_WIFI_MULTI("[WIFI] start scan\n"); if(scanResult <= 0) {
// WiFi.scanNetworks will return the number of networks found DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
int8_t n = WiFi.scanNetworks(); } else {
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
for(int8_t i = 0; i < scanResult; ++i) {
DEBUG_WIFI_MULTI("[WIFI] scan done\n"); String ssid_scan;
delay(0); int32_t rssi_scan;
uint8_t sec_scan;
uint8_t* BSSID_scan;
int32_t chan_scan;
bool hidden_scan;
if(n <= 0) { WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
} else {
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", n);
for(int8_t i = 0; i < n; ++i) {
String ssid_scan; bool known = false;
int32_t rssi_scan; for(uint32_t x = 0; x < APlist.size(); x++) {
uint8_t sec_scan; WifiAPlist_t entry = APlist[x];
uint8_t* BSSID_scan;
int32_t chan_scan;
bool hidden_scan;
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan); if(ssid_scan == entry.ssid) { // SSID match
known = true;
bool known = false; if(rssi_scan > bestNetworkDb) { // best network
for(uint32_t x = 0; x < APlist.size(); x++) { if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
WifiAPlist_t entry = APlist[x]; bestNetworkDb = rssi_scan;
bestChannel = chan_scan;
if(ssid_scan == entry.ssid) { // SSID match memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
known = true; memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
if(rssi_scan > bestNetworkDb) { // best network }
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
bestNetworkDb = rssi_scan;
bestChannel = chan_scan;
memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
} }
break;
} }
break;
} }
}
if(known) { if(known) {
DEBUG_WIFI_MULTI(" ---> "); DEBUG_WIFI_MULTI(" ---> ");
} else { } else {
DEBUG_WIFI_MULTI(" "); DEBUG_WIFI_MULTI(" ");
} }
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) ? ' ' : '*'); 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); delay(0);
}
} }
}
DEBUG_WIFI_MULTI("\n\n"); // clean up ram
delay(0); WiFi.scanDelete();
if(bestNetwork.ssid) { DEBUG_WIFI_MULTI("\n\n");
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channal: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb); delay(0);
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID); if(bestNetwork.ssid) {
status = WiFi.status(); DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channal: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
// wait for connection or fail WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED) {
delay(10);
status = WiFi.status(); status = WiFi.status();
}
IPAddress ip; // wait for connection or fail
uint8_t * mac; while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED) {
switch(status) { delay(10);
case WL_CONNECTED: status = WiFi.status();
ip = WiFi.localIP(); }
mac = WiFi.BSSID();
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n"); IPAddress ip;
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID()); uint8_t * mac;
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); switch(status) {
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); case WL_CONNECTED:
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel()); ip = WiFi.localIP();
break; mac = WiFi.BSSID();
case WL_NO_SSID_AVAIL: DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n"); DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID());
break; DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
case WL_CONNECT_FAILED: DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild.\n"); DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
break; break;
default: case WL_NO_SSID_AVAIL:
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild (%d).\n", status); DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n");
break; break;
case WL_CONNECT_FAILED:
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild.\n");
break;
default:
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild (%d).\n", status);
break;
}
} else {
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
} }
} else { } else {
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n"); // start scan
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
WiFi.disconnect();
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
// scan wifi async mode
WiFi.scanNetworks(true);
} }
} }
return status; return status;