Skip to content

Commit a1b9491

Browse files
committed
ESP8266WiFiMulti: refactor ESP8266WiFiMulti::run in preparation for reducing blocking
1 parent 614f7c3 commit a1b9491

File tree

2 files changed

+105
-77
lines changed

2 files changed

+105
-77
lines changed

libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp

Lines changed: 98 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,98 @@ bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) {
3838
return APlistAdd(ssid, passphrase);
3939
}
4040

41+
void ESP8266WiFiMulti::handleConnectComplete(wl_status_t status) {
42+
#ifdef DEBUG_ESP_WIFI
43+
IPAddress ip;
44+
uint8_t * mac;
45+
switch(status) {
46+
case WL_CONNECTED:
47+
ip = WiFi.localIP();
48+
mac = WiFi.BSSID();
49+
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
50+
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID().c_str());
51+
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
52+
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
53+
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
54+
break;
55+
case WL_NO_SSID_AVAIL:
56+
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n");
57+
break;
58+
case WL_CONNECT_FAILED:
59+
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n");
60+
break;
61+
default:
62+
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status);
63+
break;
64+
}
65+
#else
66+
(void)status;
67+
#endif
68+
}
69+
70+
struct BestNetwork {
71+
WifiAPEntry Network;
72+
int NetworkDb;
73+
uint8 BSSID[6];
74+
int32_t Channel;
75+
76+
BestNetwork() : Network({NULL, NULL}), NetworkDb(INT_MIN) {}
77+
};
78+
79+
void ESP8266WiFiMulti::selectBest(BestNetwork& best, int8_t scanResult) {
80+
for(int8_t i = 0; i < scanResult; ++i) {
81+
82+
String ssid_scan;
83+
int32_t rssi_scan;
84+
uint8_t sec_scan;
85+
uint8_t* BSSID_scan;
86+
int32_t chan_scan;
87+
bool hidden_scan;
88+
89+
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
90+
91+
bool known = false;
92+
for(auto entry : APlist) {
93+
if(ssid_scan == entry.ssid) { // SSID match
94+
known = true;
95+
if(rssi_scan > best.NetworkDb) { // best network
96+
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
97+
best.NetworkDb = rssi_scan;
98+
best.Channel = chan_scan;
99+
best.Network = entry;
100+
memcpy((void*) &best.BSSID, (void*) BSSID_scan, sizeof(best.BSSID));
101+
}
102+
}
103+
break;
104+
}
105+
}
106+
107+
if(known) {
108+
DEBUG_WIFI_MULTI(" ---> ");
109+
} else {
110+
DEBUG_WIFI_MULTI(" ");
111+
}
112+
113+
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) ? ' ' : '*');
114+
delay(0);
115+
}
116+
}
117+
118+
wl_status_t ESP8266WiFiMulti::connectLoop() {
119+
static const uint32_t connectTimeout = 5000; //5s timeout
120+
121+
auto startTime = millis();
122+
wl_status_t status = WiFi.status();
123+
// wait for connection, fail, or timeout
124+
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) {
125+
delay(10);
126+
status = WiFi.status();
127+
}
128+
129+
handleConnectComplete(status);
130+
return status;
131+
}
132+
41133
wl_status_t ESP8266WiFiMulti::run(void) {
42134

43135
wl_status_t status = WiFi.status();
@@ -67,97 +159,26 @@ wl_status_t ESP8266WiFiMulti::run(void) {
67159

68160
if(scanResult > 0) {
69161
// scan done, analyze
70-
WifiAPEntry bestNetwork { NULL, NULL };
71-
int bestNetworkDb = INT_MIN;
72-
uint8 bestBSSID[6];
73-
int32_t bestChannel;
162+
BestNetwork best;
74163

75164
DEBUG_WIFI_MULTI("[WIFI] scan done\n");
76165
delay(0);
77166

78167
DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult);
79-
for(int8_t i = 0; i < scanResult; ++i) {
80-
81-
String ssid_scan;
82-
int32_t rssi_scan;
83-
uint8_t sec_scan;
84-
uint8_t* BSSID_scan;
85-
int32_t chan_scan;
86-
bool hidden_scan;
87-
88-
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan);
89-
90-
bool known = false;
91-
for(auto entry : APlist) {
92-
if(ssid_scan == entry.ssid) { // SSID match
93-
known = true;
94-
if(rssi_scan > bestNetworkDb) { // best network
95-
if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan
96-
bestNetworkDb = rssi_scan;
97-
bestChannel = chan_scan;
98-
bestNetwork = entry;
99-
memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID));
100-
}
101-
}
102-
break;
103-
}
104-
}
105-
106-
if(known) {
107-
DEBUG_WIFI_MULTI(" ---> ");
108-
} else {
109-
DEBUG_WIFI_MULTI(" ");
110-
}
111-
112-
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) ? ' ' : '*');
113-
delay(0);
114-
}
168+
selectBest(best, scanResult);
115169

116170
// clean up ram
117171
WiFi.scanDelete();
118172

119173
DEBUG_WIFI_MULTI("\n\n");
120174
delay(0);
121175

122-
if(bestNetwork.ssid) {
123-
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);
176+
if(best.Network.ssid) {
177+
DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)\n", best.BSSID[0], best.BSSID[1], best.BSSID[2], best.BSSID[3], best.BSSID[4], best.BSSID[5], best.Network.ssid, best.Channel, best.NetworkDb);
124178

125-
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
126-
status = WiFi.status();
179+
WiFi.begin(best.Network.ssid, best.Network.passphrase, best.Channel, best.BSSID);
127180

128-
static const uint32_t connectTimeout = 5000; //5s timeout
129-
130-
auto startTime = millis();
131-
// wait for connection, fail, or timeout
132-
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) {
133-
delay(10);
134-
status = WiFi.status();
135-
}
136-
137-
#ifdef DEBUG_ESP_WIFI
138-
IPAddress ip;
139-
uint8_t * mac;
140-
switch(status) {
141-
case WL_CONNECTED:
142-
ip = WiFi.localIP();
143-
mac = WiFi.BSSID();
144-
DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n");
145-
DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID().c_str());
146-
DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
147-
DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
148-
DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel());
149-
break;
150-
case WL_NO_SSID_AVAIL:
151-
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n");
152-
break;
153-
case WL_CONNECT_FAILED:
154-
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n");
155-
break;
156-
default:
157-
DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status);
158-
break;
159-
}
160-
#endif
181+
status = connectLoop();
161182
} else {
162183
DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n");
163184
}

libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ struct WifiAPEntry {
4747

4848
typedef std::vector<WifiAPEntry> WifiAPlist;
4949

50+
struct BestNetwork;
51+
5052
class ESP8266WiFiMulti {
5153
public:
5254
ESP8266WiFiMulti();
@@ -58,6 +60,11 @@ class ESP8266WiFiMulti {
5860

5961
private:
6062
WifiAPlist APlist;
63+
64+
void selectBest(BestNetwork& best, int8_t scanResult);
65+
void handleConnectComplete(wl_status_t status);
66+
wl_status_t connectLoop();
67+
6168
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
6269
void APlistClean(void);
6370

0 commit comments

Comments
 (0)