@@ -33,10 +33,9 @@ WiFiMulti::WiFiMulti()
33
33
ipv6_support = false ;
34
34
}
35
35
36
- WiFiMulti::~WiFiMulti ( )
36
+ void WiFiMulti::APlistClean ( void )
37
37
{
38
- for (uint32_t i = 0 ; i < APlist.size (); i++) {
39
- WifiAPlist_t entry = APlist[i];
38
+ for (auto entry : APlist) {
40
39
if (entry.ssid ) {
41
40
free (entry.ssid );
42
41
}
@@ -47,17 +46,22 @@ WiFiMulti::~WiFiMulti()
47
46
APlist.clear ();
48
47
}
49
48
49
+ WiFiMulti::~WiFiMulti ()
50
+ {
51
+ APlistClean ();
52
+ }
53
+
50
54
bool WiFiMulti::addAP (const char * ssid, const char *passphrase)
51
55
{
52
56
WifiAPlist_t newAP;
53
57
54
- if (!ssid || *ssid == 0x00 || strlen (ssid) > 31 ) {
58
+ if (!ssid || *ssid == ' \0 ' || strlen (ssid) > 31 ) {
55
59
// fail SSID too long or missing!
56
60
log_e (" [WIFI][APlistAdd] no ssid or ssid too long" );
57
61
return false ;
58
62
}
59
63
60
- if (passphrase && strlen (passphrase) > 64 ) {
64
+ if (passphrase && strlen (passphrase) > 63 ) {
61
65
// fail passphrase too long!
62
66
log_e (" [WIFI][APlistAdd] passphrase too long" );
63
67
return false ;
@@ -70,7 +74,7 @@ bool WiFiMulti::addAP(const char* ssid, const char *passphrase)
70
74
return false ;
71
75
}
72
76
73
- if (passphrase && *passphrase != 0x00 ) {
77
+ if (passphrase && *passphrase != ' \0 ' ) {
74
78
newAP.passphrase = strdup (passphrase);
75
79
if (!newAP.passphrase ) {
76
80
log_e (" [WIFI][APlistAdd] fail newAP.passphrase == 0" );
@@ -80,7 +84,7 @@ bool WiFiMulti::addAP(const char* ssid, const char *passphrase)
80
84
} else {
81
85
newAP.passphrase = NULL ;
82
86
}
83
-
87
+ newAP. hasFailed = false ;
84
88
APlist.push_back (newAP);
85
89
log_i (" [WIFI][APlistAdd] add SSID: %s" , newAP.ssid );
86
90
return true ;
@@ -91,9 +95,20 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
91
95
int8_t scanResult;
92
96
uint8_t status = WiFi.status ();
93
97
if (status == WL_CONNECTED) {
94
- for (uint32_t x = 0 ; x < APlist.size (); x++) {
95
- if (WiFi.SSID ()==APlist[x].ssid ) {
98
+ if (!_bWFMInit && _connectionTestCBFunc != NULL ){
99
+ if (_connectionTestCBFunc () == true ) {
100
+ _bWFMInit = true ;
101
+ return status;
102
+ }
103
+ } else {
104
+ if (!_bStrict) {
96
105
return status;
106
+ } else {
107
+ for (auto ap : APlist) {
108
+ if (WiFi.SSID () == ap.ssid ) {
109
+ return status;
110
+ }
111
+ }
97
112
}
98
113
}
99
114
WiFi.disconnect (false ,false );
@@ -102,22 +117,27 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
102
117
}
103
118
104
119
scanResult = WiFi.scanNetworks ();
105
- if (scanResult == WIFI_SCAN_RUNNING) {
120
+ if (scanResult == WIFI_SCAN_RUNNING) {
106
121
// scan is running
107
122
return WL_NO_SSID_AVAIL;
108
- } else if (scanResult >= 0 ) {
123
+ } else if (scanResult >= 0 ) {
109
124
// scan done analyze
110
- WifiAPlist_t bestNetwork { NULL , NULL };
125
+ int32_t bestIndex = 0 ;
126
+ WifiAPlist_t bestNetwork { NULL , NULL , false };
111
127
int bestNetworkDb = INT_MIN;
128
+ int bestNetworkSec = WIFI_AUTH_MAX;
112
129
uint8_t bestBSSID[6 ];
113
130
int32_t bestChannel = 0 ;
114
131
115
132
log_i (" [WIFI] scan done" );
116
133
117
- if (scanResult == 0 ) {
134
+ if (scanResult == 0 ) {
118
135
log_e (" [WIFI] no networks found" );
119
136
} else {
120
137
log_i (" [WIFI] %d networks found" , scanResult);
138
+
139
+ int8_t failCount = 0 ;
140
+ int8_t foundCount = 0 ;
121
141
for (int8_t i = 0 ; i < scanResult; ++i) {
122
142
123
143
String ssid_scan;
@@ -127,22 +147,47 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
127
147
int32_t chan_scan;
128
148
129
149
WiFi.getNetworkInfo (i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
150
+ // add any Open WiFi AP to the list, if allowed with setAllowOpenAP(true)
151
+ if (_bAllowOpenAP && sec_scan == WIFI_AUTH_OPEN){
152
+ bool found = false ;
153
+ for (auto check : APlist) {
154
+ if (ssid_scan == check.ssid ){
155
+ found = true ;
156
+ break ;
157
+ }
158
+ }
159
+ // If we didn't find it, add this Open WiFi AP to the list
160
+ if (!found){
161
+ log_i (" [WIFI][APlistAdd] adding Open WiFi SSID: %s" , ssid_scan.c_str ());
162
+ addAP (ssid_scan.c_str ());
163
+ }
164
+ }
130
165
131
166
bool known = false ;
132
- for (uint32_t x = APlist.size () ; x > 0 ; x-- ) {
133
- WifiAPlist_t entry = APlist[x- 1 ];
167
+ for (uint32_t x = 0 ; x < APlist.size (); x++ ) {
168
+ WifiAPlist_t entry = APlist[x];
134
169
135
170
if (ssid_scan == entry.ssid ) { // SSID match
136
- known = true ;
137
- if (rssi_scan > bestNetworkDb) { // best network
138
- if (sec_scan == WIFI_AUTH_OPEN || entry.passphrase ) { // check for passphrase if not open wlan
139
- bestNetworkDb = rssi_scan;
140
- bestChannel = chan_scan;
141
- memcpy ((void *) &bestNetwork, (void *) &entry, sizeof (bestNetwork));
142
- memcpy ((void *) &bestBSSID, (void *) BSSID_scan, sizeof (bestBSSID));
171
+ log_v (" known ssid: %s, has failed: %s" , entry.ssid , entry.hasFailed ? " yes" : " no" );
172
+ foundCount++;
173
+ if (!entry.hasFailed ){
174
+ known = true ;
175
+ log_v (" rssi_scan: %d, bestNetworkDb: %d" , rssi_scan, bestNetworkDb);
176
+ if (rssi_scan > bestNetworkDb) { // best network
177
+ if (_bAllowOpenAP || (sec_scan == WIFI_AUTH_OPEN || entry.passphrase )) { // check for passphrase if not open wlan
178
+ log_v (" best network is now: %s" , ssid_scan);
179
+ bestIndex = x;
180
+ bestNetworkSec = sec_scan;
181
+ bestNetworkDb = rssi_scan;
182
+ bestChannel = chan_scan;
183
+ memcpy ((void *) &bestNetwork, (void *) &entry, sizeof (bestNetwork));
184
+ memcpy ((void *) &bestBSSID, (void *) BSSID_scan, sizeof (bestBSSID));
185
+ }
143
186
}
187
+ break ;
188
+ } else {
189
+ failCount++;
144
190
}
145
- break ;
146
191
}
147
192
}
148
193
@@ -152,8 +197,12 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
152
197
log_d (" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c" , 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 == WIFI_AUTH_OPEN) ? ' ' : ' *' );
153
198
}
154
199
}
200
+ log_v (" foundCount = %d, failCount = %d" , foundCount, failCount);
201
+ // if all the APs in the list have failed, reset the failure flags
202
+ if (foundCount == failCount) {
203
+ resetFails (); // keeps trying the APs in the list
204
+ }
155
205
}
156
-
157
206
// clean up ram
158
207
WiFi.scanDelete ();
159
208
@@ -163,12 +212,15 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
163
212
if (ipv6_support == true ) {
164
213
WiFi.enableIPv6 ();
165
214
}
166
- WiFi.begin (bestNetwork.ssid , bestNetwork.passphrase , bestChannel, bestBSSID);
215
+ WiFi.disconnect ();
216
+ delay (10 );
217
+ WiFi.begin (bestNetwork.ssid , (_bAllowOpenAP && bestNetworkSec == WIFI_AUTH_OPEN) ? NULL : bestNetwork.passphrase , bestChannel, bestBSSID);
167
218
status = WiFi.status ();
219
+ _bWFMInit = true ;
168
220
169
221
auto startTime = millis ();
170
222
// wait for connection, fail, or timeout
171
- while (status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && ( millis () - startTime) <= connectTimeout) {
223
+ while (status != WL_CONNECTED && ( millis () - startTime) <= connectTimeout) { // && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED
172
224
delay (10 );
173
225
status = WiFi.status ();
174
226
}
@@ -180,15 +232,32 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
180
232
log_d (" [WIFI] IP: %s" , WiFi.localIP ().toString ().c_str ());
181
233
log_d (" [WIFI] MAC: %s" , WiFi.BSSIDstr ().c_str ());
182
234
log_d (" [WIFI] Channel: %d" , WiFi.channel ());
235
+
236
+ if (_connectionTestCBFunc != NULL ) {
237
+ // We connected to an AP but if it's a captive portal we're not going anywhere. Test it.
238
+ if (_connectionTestCBFunc ()) {
239
+ resetFails ();
240
+ } else {
241
+ markAsFailed (bestIndex);
242
+ WiFi.disconnect ();
243
+ delay (10 );
244
+ status = WiFi.status ();
245
+ }
246
+ } else {
247
+ resetFails ();
248
+ }
183
249
break ;
184
250
case WL_NO_SSID_AVAIL:
185
251
log_e (" [WIFI] Connecting Failed AP not found." );
252
+ markAsFailed (bestIndex);
186
253
break ;
187
254
case WL_CONNECT_FAILED:
188
255
log_e (" [WIFI] Connecting Failed." );
256
+ markAsFailed (bestIndex);
189
257
break ;
190
258
default :
191
259
log_e (" [WIFI] Connecting Failed (%d)." , status);
260
+ markAsFailed (bestIndex);
192
261
break ;
193
262
}
194
263
} else {
@@ -210,3 +279,27 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
210
279
void WiFiMulti::enableIPv6 (bool state) {
211
280
ipv6_support = state;
212
281
}
282
+
283
+ void WiFiMulti::markAsFailed (int32_t i) {
284
+ APlist[i].hasFailed = true ;
285
+ log_d (" [WIFI] Marked SSID %s as failed" , APlist[i].ssid );
286
+ }
287
+
288
+ void WiFiMulti::resetFails (){
289
+ for (uint32_t i = 0 ; i < APlist.size (); i++) {
290
+ APlist[i].hasFailed = false ;
291
+ }
292
+ log_d (" [WIFI] Resetting failure flags" );
293
+ }
294
+
295
+ void WiFiMulti::setStrictMode (bool bStrict) {
296
+ _bStrict = bStrict;
297
+ }
298
+
299
+ void WiFiMulti::setAllowOpenAP (bool bAllowOpenAP) {
300
+ _bAllowOpenAP = bAllowOpenAP;
301
+ }
302
+
303
+ void WiFiMulti::setConnectionTestCallbackFunc (ConnectionTestCB_t cbFunc) {
304
+ _connectionTestCBFunc = cbFunc;
305
+ }
0 commit comments