352 lines
9.2 KiB
C++
352 lines
9.2 KiB
C++
#include "WifiDevice.h"
|
|
#include "../PreferencesKeys.h"
|
|
#include "../Logger.h"
|
|
#include "../RestartReason.h"
|
|
#include "../EspMillis.h"
|
|
|
|
WifiDevice::WifiDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration)
|
|
: NetworkDevice(hostname, preferences, ipConfiguration),
|
|
_preferences(preferences)
|
|
{
|
|
#ifndef NUKI_HUB_UPDATER
|
|
NetworkDevice::init();
|
|
#endif
|
|
}
|
|
|
|
const String WifiDevice::deviceName() const
|
|
{
|
|
return "Built-in Wi-Fi";
|
|
}
|
|
|
|
void WifiDevice::initialize()
|
|
{
|
|
if (_hostname != "fakep4forhosted") {
|
|
ssid = _preferences->getString(preference_wifi_ssid, "");
|
|
ssid.trim();
|
|
pass = _preferences->getString(preference_wifi_pass, "");
|
|
pass.trim();
|
|
WiFi.setHostname(_hostname.c_str());
|
|
|
|
WiFi.onEvent([&](WiFiEvent_t event, WiFiEventInfo_t info)
|
|
{
|
|
onWifiEvent(event, info);
|
|
});
|
|
|
|
if(isWifiConfigured())
|
|
{
|
|
Log->println(String("Attempting to connect to saved SSID ") + String(ssid));
|
|
_openAP = false;
|
|
}
|
|
else
|
|
{
|
|
Log->println("No SSID or Wifi password saved, opening AP");
|
|
_openAP = true;
|
|
}
|
|
|
|
scan(false, true);
|
|
}
|
|
else
|
|
{
|
|
WiFi.disconnect(true);
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.disconnect();
|
|
delay(5000);
|
|
Log->println("Dummy WiFi device for Hosted on P4 done");
|
|
}
|
|
return;
|
|
}
|
|
|
|
void WifiDevice::scan(bool passive, bool async)
|
|
{
|
|
if (!_openAP)
|
|
{
|
|
WiFi.disconnect(true);
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.disconnect();
|
|
}
|
|
|
|
WiFi.scanDelete();
|
|
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
|
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
|
|
|
if(async)
|
|
{
|
|
Log->println("Wi-Fi async scan started");
|
|
}
|
|
else
|
|
{
|
|
Log->println("Wi-Fi sync scan started");
|
|
}
|
|
if(passive)
|
|
{
|
|
WiFi.scanNetworks(async,false,true,75U);
|
|
}
|
|
else
|
|
{
|
|
WiFi.scanNetworks(async);
|
|
}
|
|
}
|
|
|
|
void WifiDevice::openAP()
|
|
{
|
|
if(_startAP)
|
|
{
|
|
Log->println("Starting AP with SSID NukiHub and Password NukiHubESP32");
|
|
_startAP = false;
|
|
WiFi.mode(WIFI_AP);
|
|
delay(500);
|
|
WiFi.softAPsetHostname(_hostname.c_str());
|
|
delay(500);
|
|
WiFi.softAP("NukiHub", "NukiHubESP32");
|
|
|
|
//if(MDNS.begin(_hostname.c_str())){
|
|
// MDNS.addService("http", "tcp", 80);
|
|
//}
|
|
}
|
|
}
|
|
|
|
bool WifiDevice::connect()
|
|
{
|
|
WiFi.mode(WIFI_STA);
|
|
WiFi.setHostname(_hostname.c_str());
|
|
delay(500);
|
|
|
|
int bestConnection = -1;
|
|
|
|
if(_preferences->getBool(preference_find_best_rssi, false))
|
|
{
|
|
for (int i = 0; i < _foundNetworks; i++)
|
|
{
|
|
if (ssid == WiFi.SSID(i))
|
|
{
|
|
Log->println(String("Saved SSID ") + ssid + String(" found with RSSI: ") +
|
|
String(WiFi.RSSI(i)) + String(("(")) +
|
|
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
|
String(" %) and BSSID: ") + WiFi.BSSIDstr(i) +
|
|
String(" and channel: ") + String(WiFi.channel(i)));
|
|
if (bestConnection == -1)
|
|
{
|
|
bestConnection = i;
|
|
}
|
|
else
|
|
{
|
|
if (WiFi.RSSI(i) > WiFi.RSSI(bestConnection))
|
|
{
|
|
bestConnection = i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bestConnection == -1)
|
|
{
|
|
Log->print("No network found with SSID: ");
|
|
Log->println(ssid);
|
|
}
|
|
else
|
|
{
|
|
Log->println(String("Trying to connect to SSID ") + ssid + String(" found with RSSI: ") +
|
|
String(WiFi.RSSI(bestConnection)) + String(("(")) +
|
|
String(constrain((100.0 + WiFi.RSSI(bestConnection)) * 2, 0, 100)) +
|
|
String(" %) and BSSID: ") + WiFi.BSSIDstr(bestConnection) +
|
|
String(" and channel: ") + String(WiFi.channel(bestConnection)));
|
|
}
|
|
}
|
|
|
|
if(!_ipConfiguration->dhcpEnabled())
|
|
{
|
|
WiFi.config(_ipConfiguration->ipAddress(), _ipConfiguration->dnsServer(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet());
|
|
}
|
|
|
|
WiFi.begin(ssid, pass);
|
|
|
|
Log->print("WiFi connecting");
|
|
int loop = 0;
|
|
while(!isConnected() && loop < 150)
|
|
{
|
|
Log->print(".");
|
|
delay(100);
|
|
loop++;
|
|
}
|
|
Log->println("");
|
|
|
|
if (!isConnected())
|
|
{
|
|
Log->println("Failed to connect within 15 seconds");
|
|
|
|
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
|
|
{
|
|
Log->println("Restart on disconnect watchdog triggered, rebooting");
|
|
delay(100);
|
|
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
|
}
|
|
else
|
|
{
|
|
Log->println("Retrying WiFi connection");
|
|
scan(false, true);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool WifiDevice::isWifiConfigured() const
|
|
{
|
|
return ssid.length() > 0 && pass.length() > 0;
|
|
}
|
|
|
|
void WifiDevice::reconfigure()
|
|
{
|
|
_preferences->putString(preference_wifi_ssid, "");
|
|
_preferences->putString(preference_wifi_pass, "");
|
|
delay(200);
|
|
restartEsp(RestartReason::ReconfigureWifi);
|
|
}
|
|
|
|
bool WifiDevice::isConnected()
|
|
{
|
|
return WiFi.isConnected();
|
|
}
|
|
|
|
void WifiDevice::onConnected()
|
|
{
|
|
Log->println("Wi-Fi connected");
|
|
_connected = true;
|
|
}
|
|
|
|
void WifiDevice::onDisconnected()
|
|
{
|
|
if (!_connected)
|
|
{
|
|
return;
|
|
}
|
|
_connected = false;
|
|
|
|
Log->println("Wi-Fi disconnected");
|
|
connect();
|
|
}
|
|
|
|
int8_t WifiDevice::signalStrength()
|
|
{
|
|
return WiFi.RSSI();
|
|
}
|
|
|
|
String WifiDevice::localIP()
|
|
{
|
|
return WiFi.localIP().toString();
|
|
}
|
|
|
|
String WifiDevice::BSSIDstr()
|
|
{
|
|
return WiFi.BSSIDstr();
|
|
}
|
|
|
|
bool WifiDevice::isApOpen()
|
|
{
|
|
return _openAP;
|
|
}
|
|
|
|
void WifiDevice::onWifiEvent(const WiFiEvent_t &event, const WiFiEventInfo_t &info)
|
|
{
|
|
Log->printf("[WiFi-event] event: %d\n", event);
|
|
|
|
switch (event) {
|
|
case ARDUINO_EVENT_WIFI_READY:
|
|
Log->println("WiFi interface ready");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_SCAN_DONE:
|
|
Log->println("Completed scan for access points");
|
|
_foundNetworks = WiFi.scanComplete();
|
|
|
|
for (int i = 0; i < _foundNetworks; i++)
|
|
{
|
|
Log->println(String("SSID ") + WiFi.SSID(i) + String(" found with RSSI: ") +
|
|
String(WiFi.RSSI(i)) + String(("(")) +
|
|
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
|
String(" %) and BSSID: ") + WiFi.BSSIDstr(i) +
|
|
String(" and channel: ") + String(WiFi.channel(i)));
|
|
}
|
|
|
|
if (_openAP)
|
|
{
|
|
openAP();
|
|
}
|
|
else if (_foundNetworks > 0 || _preferences->getBool(preference_find_best_rssi, false))
|
|
{
|
|
esp_wifi_scan_stop();
|
|
connect();
|
|
}
|
|
else
|
|
{
|
|
Log->println("No networks found, restarting scan");
|
|
scan(false, true);
|
|
}
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_START:
|
|
Log->println("WiFi client started");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_STOP:
|
|
Log->println("WiFi clients stopped");
|
|
if(!_openAP)
|
|
{
|
|
onDisconnected();
|
|
}
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
|
|
Log->println("Connected to access point");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
|
Log->println("Disconnected from WiFi access point");
|
|
if(!_openAP)
|
|
{
|
|
onDisconnected();
|
|
}
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE:
|
|
Log->println("Authentication mode of access point has changed");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
|
Log->print("Obtained IP address: ");
|
|
Log->println(WiFi.localIP());
|
|
if(!_openAP)
|
|
{
|
|
onConnected();
|
|
}
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
|
|
Log->println("Lost IP address and IP address is reset to 0");
|
|
if(!_openAP)
|
|
{
|
|
onDisconnected();
|
|
}
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_START:
|
|
Log->println("WiFi access point started");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_STOP:
|
|
Log->println("WiFi access point stopped");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
|
|
Log->println("Client connected");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:
|
|
Log->println("Client disconnected");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED:
|
|
Log->println("Assigned IP address to client");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED:
|
|
Log->println("Received probe request");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_AP_GOT_IP6:
|
|
Log->println("AP IPv6 is preferred");
|
|
break;
|
|
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
|
|
Log->println("STA IPv6 is preferred");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} |