Skip to content

Commit 9a1ff7f

Browse files
committed
add WiFi scan Async mode
1 parent 7a9563d commit 9a1ff7f

File tree

3 files changed

+182
-101
lines changed

3 files changed

+182
-101
lines changed

libraries/ESP8266WiFi/src/ESP8266WiFi.cpp

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ extern "C" void esp_schedule();
4040
extern "C" void esp_yield();
4141

4242
ESP8266WiFiClass::ESP8266WiFiClass()
43-
: _useApMode(false)
43+
: _smartConfigStarted(false)
44+
, _smartConfigDone(false)
45+
, _useApMode(false)
4446
, _useClientMode(false)
4547
, _useStaticIp(false)
4648
{
@@ -121,7 +123,7 @@ uint8_t ESP8266WiFiClass::waitForConnectResult(){
121123
}
122124

123125

124-
// You will have to set the DNS-Server manually later since this will not enable DHCP
126+
// You will have to set the DNS-Server manually later since this will not enable DHCP2
125127
void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
126128
{
127129
struct ip_info info;
@@ -357,12 +359,47 @@ void ESP8266WiFiClass::_scanDone(void* result, int status)
357359
}
358360

359361
}
360-
esp_schedule();
362+
363+
ESP8266WiFiClass::_scanStarted = false;
364+
ESP8266WiFiClass::_scanComplete = true;
365+
366+
if(!ESP8266WiFiClass::_scanAsync) {
367+
esp_schedule();
368+
}
361369
}
362370

371+
int8_t ESP8266WiFiClass::scanComplete() {
372+
373+
if(_scanStarted) {
374+
return WIFI_SCAN_RUNNING;
375+
}
376+
377+
if(_scanComplete) {
378+
return ESP8266WiFiClass::_scanCount;
379+
}
363380

364-
int8_t ESP8266WiFiClass::scanNetworks()
381+
return WIFI_SCAN_FAILD;
382+
}
383+
384+
void ESP8266WiFiClass::scanDelete()
365385
{
386+
if (ESP8266WiFiClass::_scanResult)
387+
{
388+
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiClass::_scanResult);
389+
ESP8266WiFiClass::_scanResult = 0;
390+
ESP8266WiFiClass::_scanCount = 0;
391+
}
392+
_scanComplete = false;
393+
}
394+
395+
int8_t ESP8266WiFiClass::scanNetworks(bool async)
396+
{
397+
if(ESP8266WiFiClass::_scanStarted) {
398+
return WIFI_SCAN_RUNNING;
399+
}
400+
401+
ESP8266WiFiClass::_scanAsync = async;
402+
366403
if(_useApMode) {
367404
// turn on AP+STA mode
368405
mode(WIFI_AP_STA);
@@ -376,22 +413,29 @@ int8_t ESP8266WiFiClass::scanNetworks()
376413
{
377414
disconnect();
378415
}
379-
380-
if (ESP8266WiFiClass::_scanResult)
381-
{
382-
delete[] reinterpret_cast<bss_info*>(ESP8266WiFiClass::_scanResult);
383-
ESP8266WiFiClass::_scanResult = 0;
384-
ESP8266WiFiClass::_scanCount = 0;
385-
}
386416

417+
scanDelete();
418+
387419
struct scan_config config;
388420
config.ssid = 0;
389421
config.bssid = 0;
390422
config.channel = 0;
391423
config.show_hidden = 0;
392-
wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiClass::_scanDone));
393-
esp_yield();
394-
return ESP8266WiFiClass::_scanCount;
424+
if(wifi_station_scan(&config, reinterpret_cast<scan_done_cb_t>(&ESP8266WiFiClass::_scanDone))) {
425+
ESP8266WiFiClass::_scanComplete = false;
426+
ESP8266WiFiClass::_scanStarted = true;
427+
428+
if(ESP8266WiFiClass::_scanAsync) {
429+
delay(0); // time for the OS to trigger the scan
430+
return WIFI_SCAN_RUNNING;
431+
}
432+
433+
esp_yield();
434+
return ESP8266WiFiClass::_scanCount;
435+
} else {
436+
return WIFI_SCAN_FAILD;
437+
}
438+
395439
}
396440

397441
void * ESP8266WiFiClass::_getScanInfoByIndex(int i)
@@ -644,6 +688,10 @@ void ESP8266WiFiClass::printDiag(Print& p)
644688

645689
}
646690

691+
bool ESP8266WiFiClass::_scanAsync = false;
692+
bool ESP8266WiFiClass::_scanStarted = false;
693+
bool ESP8266WiFiClass::_scanComplete = false;
694+
647695
size_t ESP8266WiFiClass::_scanCount = 0;
648696
void* ESP8266WiFiClass::_scanResult = 0;
649697

libraries/ESP8266WiFi/src/ESP8266WiFi.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ extern "C" {
3232
#include "WiFiClient.h"
3333
#include "WiFiServer.h"
3434

35+
#define WIFI_SCAN_RUNNING (-1)
36+
#define WIFI_SCAN_FAILD (-2)
37+
3538
enum WiFiMode { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 };
3639

3740
class ESP8266WiFiClass
@@ -189,12 +192,26 @@ class ESP8266WiFiClass
189192

190193
int32_t RSSI();
191194

195+
196+
/*
197+
* called to get the scan state in Async mode
198+
*
199+
* return -1 if scan not fin
200+
* return -2 if scan not triggered
201+
*/
202+
int8_t scanComplete();
203+
204+
/*
205+
* delete last scan result from RAM
206+
*/
207+
void scanDelete();
208+
192209
/*
193210
* Start scan WiFi networks available
194211
*
195212
* return: Number of discovered networks
196213
*/
197-
int8_t scanNetworks();
214+
int8_t scanNetworks(bool async = false);
198215

199216
/*
200217
* Return the SSID discovered during the network scan.
@@ -314,13 +331,17 @@ class ESP8266WiFiClass
314331
void * _getScanInfoByIndex(int i);
315332
static void _smartConfigCallback(uint32_t status, void* result);
316333
static void _eventCallback(void *event);
317-
bool _smartConfigStarted = false;
318-
bool _smartConfigDone = false;
334+
bool _smartConfigStarted;
335+
bool _smartConfigDone;
319336

320337
bool _useApMode;
321338
bool _useClientMode;
322339
bool _useStaticIp;
323340

341+
static bool _scanAsync;
342+
static bool _scanStarted;
343+
static bool _scanComplete;
344+
324345
static size_t _scanCount;
325346
static void* _scanResult;
326347

libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp

Lines changed: 96 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -40,107 +40,119 @@ bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) {
4040

4141
wl_status_t ESP8266WiFiMulti::run(void) {
4242

43+
int8_t scanResult;
4344
wl_status_t status = WiFi.status();
4445
if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) {
4546

46-
WifiAPlist_t bestNetwork { NULL, NULL };
47-
int bestNetworkDb = INT_MIN;
48-
uint8 bestBSSID[6];
49-
int32_t bestChannel;
50-
51-
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
52-
WiFi.disconnect();
53-
54-
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
55-
// WiFi.scanNetworks will return the number of networks found
56-
int8_t n = WiFi.scanNetworks();
57-
58-
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
59-
delay(0);
60-
61-
if(n <= 0) {
62-
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
63-
} else {
64-
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", n);
65-
for(int8_t i = 0; i < n; ++i) {
66-
67-
String ssid_scan;
68-
int32_t rssi_scan;
69-
uint8_t sec_scan;
70-
uint8_t* BSSID_scan;
71-
int32_t chan_scan;
72-
bool hidden_scan;
73-
74-
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
75-
76-
bool known = false;
77-
for(uint32_t x = 0; x < APlist.size(); x++) {
78-
WifiAPlist_t entry = APlist[x];
79-
80-
if(ssid_scan == entry.ssid) { // SSID match
81-
known = true;
82-
if(rssi_scan > bestNetworkDb) { // best network
83-
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
84-
bestNetworkDb = rssi_scan;
85-
bestChannel = chan_scan;
86-
memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
87-
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
47+
scanResult = WiFi.scanComplete();
48+
if(scanResult == WIFI_SCAN_RUNNING) {
49+
// scan is running
50+
return WL_NO_SSID_AVAIL;
51+
} else if(scanResult > 0) {
52+
// scan done analyze
53+
WifiAPlist_t bestNetwork { NULL, NULL };
54+
int bestNetworkDb = INT_MIN;
55+
uint8 bestBSSID[6];
56+
int32_t bestChannel;
57+
58+
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
59+
delay(0);
60+
61+
if(scanResult <= 0) {
62+
DEBUG_WIFI_MULTI("[WIFI] no networks found\n");
63+
} else {
64+
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
65+
for(int8_t i = 0; i < scanResult; ++i) {
66+
67+
String ssid_scan;
68+
int32_t rssi_scan;
69+
uint8_t sec_scan;
70+
uint8_t* BSSID_scan;
71+
int32_t chan_scan;
72+
bool hidden_scan;
73+
74+
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
75+
76+
bool known = false;
77+
for(uint32_t x = 0; x < APlist.size(); x++) {
78+
WifiAPlist_t entry = APlist[x];
79+
80+
if(ssid_scan == entry.ssid) { // SSID match
81+
known = true;
82+
if(rssi_scan > bestNetworkDb) { // best network
83+
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
84+
bestNetworkDb = rssi_scan;
85+
bestChannel = chan_scan;
86+
memcpy((void*) &bestNetwork, (void*) &entry, sizeof(bestNetwork));
87+
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
88+
}
8889
}
90+
break;
8991
}
90-
break;
9192
}
92-
}
9393

94-
if(known) {
95-
DEBUG_WIFI_MULTI(" ---> ");
96-
} else {
97-
DEBUG_WIFI_MULTI(" ");
98-
}
94+
if(known) {
95+
DEBUG_WIFI_MULTI(" ---> ");
96+
} else {
97+
DEBUG_WIFI_MULTI(" ");
98+
}
9999

100-
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) ? ' ' : '*');
101-
delay(0);
100+
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) ? ' ' : '*');
101+
delay(0);
102+
}
102103
}
103-
}
104104

105-
DEBUG_WIFI_MULTI("\n\n");
106-
delay(0);
105+
// clean up ram
106+
WiFi.scanDelete();
107107

108-
if(bestNetwork.ssid) {
109-
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);
108+
DEBUG_WIFI_MULTI("\n\n");
109+
delay(0);
110110

111-
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
112-
status = WiFi.status();
111+
if(bestNetwork.ssid) {
112+
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);
113113

114-
// wait for connection or fail
115-
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED) {
116-
delay(10);
114+
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
117115
status = WiFi.status();
118-
}
119116

120-
IPAddress ip;
121-
uint8_t * mac;
122-
switch(status) {
123-
case WL_CONNECTED:
124-
ip = WiFi.localIP();
125-
mac = WiFi.BSSID();
126-
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
127-
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID());
128-
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
129-
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
130-
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
131-
break;
132-
case WL_NO_SSID_AVAIL:
133-
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n");
134-
break;
135-
case WL_CONNECT_FAILED:
136-
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild.\n");
137-
break;
138-
default:
139-
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild (%d).\n", status);
140-
break;
117+
// wait for connection or fail
118+
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED) {
119+
delay(10);
120+
status = WiFi.status();
121+
}
122+
123+
IPAddress ip;
124+
uint8_t * mac;
125+
switch(status) {
126+
case WL_CONNECTED:
127+
ip = WiFi.localIP();
128+
mac = WiFi.BSSID();
129+
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
130+
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID());
131+
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
132+
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
133+
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
134+
break;
135+
case WL_NO_SSID_AVAIL:
136+
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild AP not found.\n");
137+
break;
138+
case WL_CONNECT_FAILED:
139+
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild.\n");
140+
break;
141+
default:
142+
DEBUG_WIFI_MULTI("[WIFI] Connecting Faild (%d).\n", status);
143+
break;
144+
}
145+
} else {
146+
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
141147
}
142148
} else {
143-
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
149+
// start scan
150+
DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n");
151+
WiFi.disconnect();
152+
153+
DEBUG_WIFI_MULTI("[WIFI] start scan\n");
154+
// scan wifi async mode
155+
WiFi.scanNetworks(true);
144156
}
145157
}
146158
return status;

0 commit comments

Comments
 (0)