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:
parent
7a9563d6c6
commit
9a1ff7f70d
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user