add Ethernet

This commit is contained in:
proddy
2021-01-18 19:38:22 +01:00
parent b81435e713
commit 44045ae658
60 changed files with 905 additions and 973 deletions

View File

@@ -20,6 +20,10 @@ void APSettingsService::reconfigureAP() {
}
void APSettingsService::loop() {
// if we have an ETH connection, quit
if (ETH.linkUp()) {
return;
}
unsigned long currentMillis = uuid::get_uptime();
unsigned long manageElapsed = (uint32_t)(currentMillis - _lastManaged);
if (manageElapsed >= MANAGE_NETWORK_DELAY) {
@@ -42,13 +46,13 @@ void APSettingsService::manageAP() {
}
void APSettingsService::startAP() {
// Serial.println(F("Starting software access point"));
Serial.println(F("Starting software access point"));
WiFi.softAPConfig(_state.localIP, _state.gatewayIP, _state.subnetMask);
WiFi.softAP(_state.ssid.c_str(), _state.password.c_str());
if (!_dnsServer) {
IPAddress apIp = WiFi.softAPIP();
// Serial.print(F("Starting captive portal on "));
// Serial.println(apIp);
Serial.print(F("Starting captive portal on "));
Serial.println(apIp);
_dnsServer = new DNSServer;
_dnsServer->start(DNS_PORT, "*", apIp);
}
@@ -56,12 +60,12 @@ void APSettingsService::startAP() {
void APSettingsService::stopAP() {
if (_dnsServer) {
// Serial.println(F("Stopping captive portal"));
Serial.println(F("Stopping captive portal"));
_dnsServer->stop();
delete _dnsServer;
_dnsServer = nullptr;
}
// Serial.println(F("Stopping software access point"));
Serial.println(F("Stopping software access point"));
WiFi.softAPdisconnect(true);
}

View File

@@ -7,8 +7,10 @@
#include <DNSServer.h>
#include <IPAddress.h>
#include <uuid/common.h>
#include <ETH.h>
#include <uuid/common.h>
#define MANAGE_NETWORK_DELAY 10000
@@ -111,7 +113,7 @@ class APSettingsService : public StatefulService<APSettings> {
// for the captive portal
DNSServer * _dnsServer;
// for the mangement delay loop
// for the management delay loop
volatile unsigned long _lastManaged;
volatile boolean _reconfigureAp;

View File

@@ -3,35 +3,19 @@
ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
: _featureService(server)
, _securitySettingsService(server, fs)
, _wifiSettingsService(server, fs, &_securitySettingsService)
, _networkSettingsService(server, fs, &_securitySettingsService)
, _wifiScanner(server, &_securitySettingsService)
, _wifiStatus(server, &_securitySettingsService)
, _networkStatus(server, &_securitySettingsService)
, _apSettingsService(server, fs, &_securitySettingsService)
, _apStatus(server, &_securitySettingsService, &_apSettingsService)
,
#if FT_ENABLED(FT_NTP)
_ntpSettingsService(server, fs, &_securitySettingsService)
, _ntpSettingsService(server, fs, &_securitySettingsService)
, _ntpStatus(server, &_securitySettingsService)
,
#endif
#if FT_ENABLED(FT_OTA)
_otaSettingsService(server, fs, &_securitySettingsService)
,
#endif
#if FT_ENABLED(FT_UPLOAD_FIRMWARE)
_uploadFirmwareService(server, &_securitySettingsService)
,
#endif
#if FT_ENABLED(FT_MQTT)
_mqttSettingsService(server, fs, &_securitySettingsService)
, _otaSettingsService(server, fs, &_securitySettingsService)
, _uploadFirmwareService(server, &_securitySettingsService)
, _mqttSettingsService(server, fs, &_securitySettingsService)
, _mqttStatus(server, &_mqttSettingsService, &_securitySettingsService)
,
#endif
#if FT_ENABLED(FT_SECURITY)
_authenticationService(server, &_securitySettingsService)
,
#endif
_restartService(server, &_securitySettingsService)
, _authenticationService(server, &_securitySettingsService)
, _restartService(server, &_securitySettingsService)
, _factoryResetService(server, fs, &_securitySettingsService)
, _systemStatus(server, &_securitySettingsService) {
#ifdef PROGMEM_WWW
@@ -91,29 +75,17 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
}
void ESP8266React::begin() {
_wifiSettingsService.begin();
_networkSettingsService.begin();
_apSettingsService.begin();
#if FT_ENABLED(FT_NTP)
_ntpSettingsService.begin();
#endif
#if FT_ENABLED(FT_OTA)
_otaSettingsService.begin();
#endif
#if FT_ENABLED(FT_MQTT)
_mqttSettingsService.begin();
#endif
#if FT_ENABLED(FT_SECURITY)
_securitySettingsService.begin();
#endif
}
void ESP8266React::loop() {
_wifiSettingsService.loop();
_networkSettingsService.loop();
_apSettingsService.loop();
#if FT_ENABLED(FT_OTA)
_otaSettingsService.loop();
#endif
#if FT_ENABLED(FT_MQTT)
_mqttSettingsService.loop();
#endif
}

View File

@@ -3,13 +3,9 @@
#include <Arduino.h>
#ifdef ESP32
#include <AsyncTCP.h>
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ETH.h>
#include <FeaturesService.h>
#include <APSettingsService.h>
@@ -26,8 +22,8 @@
#include <SecuritySettingsService.h>
#include <SystemStatus.h>
#include <WiFiScanner.h>
#include <WiFiSettingsService.h>
#include <WiFiStatus.h>
#include <NetworkSettingsService.h>
#include <NetworkStatus.h>
#ifdef PROGMEM_WWW
#include <WWWData.h>
@@ -44,33 +40,26 @@ class ESP8266React {
return &_securitySettingsService;
}
#if FT_ENABLED(FT_SECURITY)
StatefulService<SecuritySettings> * getSecuritySettingsService() {
return &_securitySettingsService;
}
#endif
StatefulService<WiFiSettings> * getWiFiSettingsService() {
return &_wifiSettingsService;
StatefulService<NetworkSettings> * getNetworkSettingsService() {
return &_networkSettingsService;
}
StatefulService<APSettings> * getAPSettingsService() {
return &_apSettingsService;
}
#if FT_ENABLED(FT_NTP)
StatefulService<NTPSettings> * getNTPSettingsService() {
return &_ntpSettingsService;
}
#endif
#if FT_ENABLED(FT_OTA)
StatefulService<OTASettings> * getOTASettingsService() {
return &_otaSettingsService;
}
#endif
#if FT_ENABLED(FT_MQTT)
StatefulService<MqttSettings> * getMqttSettingsService() {
return &_mqttSettingsService;
}
@@ -78,7 +67,6 @@ class ESP8266React {
AsyncMqttClient * getMqttClient() {
return _mqttSettingsService.getMqttClient();
}
#endif
void factoryReset() {
_factoryResetService.factoryReset();
@@ -87,31 +75,21 @@ class ESP8266React {
private:
FeaturesService _featureService;
SecuritySettingsService _securitySettingsService;
WiFiSettingsService _wifiSettingsService;
NetworkSettingsService _networkSettingsService;
WiFiScanner _wifiScanner;
WiFiStatus _wifiStatus;
NetworkStatus _networkStatus;
APSettingsService _apSettingsService;
APStatus _apStatus;
#if FT_ENABLED(FT_NTP)
NTPSettingsService _ntpSettingsService;
NTPStatus _ntpStatus;
#endif
#if FT_ENABLED(FT_OTA)
OTASettingsService _otaSettingsService;
#endif
#if FT_ENABLED(FT_UPLOAD_FIRMWARE)
UploadFirmwareService _uploadFirmwareService;
#endif
#if FT_ENABLED(FT_MQTT)
MqttSettingsService _mqttSettingsService;
MqttStatus _mqttStatus;
#endif
#if FT_ENABLED(FT_SECURITY)
AuthenticationService _authenticationService;
#endif
RestartService _restartService;
FactoryResetService _factoryResetService;
SystemStatus _systemStatus;
NTPSettingsService _ntpSettingsService;
NTPStatus _ntpStatus;
OTASettingsService _otaSettingsService;
UploadFirmwareService _uploadFirmwareService;
MqttSettingsService _mqttSettingsService;
MqttStatus _mqttStatus;
AuthenticationService _authenticationService;
RestartService _restartService;
FactoryResetService _factoryResetService;
SystemStatus _systemStatus;
};
#endif

View File

@@ -40,13 +40,8 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur
, _disconnectedAt(0)
, _disconnectReason(AsyncMqttClientDisconnectReason::TCP_DISCONNECTED)
, _mqttClient() {
#ifdef ESP32
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.onEvent(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
#elif defined(ESP8266)
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&MqttSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&MqttSettingsService::onStationModeGotIP, this, std::placeholders::_1));
#endif
_mqttClient.onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, std::placeholders::_1));
_mqttClient.onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, std::placeholders::_1));
addUpdateHandler([&](const String & originId) { onConfigUpdated(); }, false);

View File

@@ -140,16 +140,8 @@ class MqttSettingsService : public StatefulService<MqttSettings> {
// the MQTT client instance
AsyncMqttClient _mqttClient;
#ifdef ESP32
void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
#elif defined(ESP8266)
WiFiEventHandler _onStationModeDisconnectedHandler;
WiFiEventHandler _onStationModeGotIPHandler;
void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
#endif
void onMqttConnect(bool sessionPresent);
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
void configureMqtt();

View File

@@ -3,20 +3,13 @@
NTPSettingsService::NTPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
: _httpEndpoint(NTPSettings::read, NTPSettings::update, this, server, NTP_SETTINGS_SERVICE_PATH, securityManager)
, _fsPersistence(NTPSettings::read, NTPSettings::update, this, fs, NTP_SETTINGS_FILE)
, _timeHandler(TIME_PATH,
securityManager->wrapCallback(std::bind(&NTPSettingsService::configureTime, this, std::placeholders::_1, std::placeholders::_2),
AuthenticationPredicates::IS_ADMIN)) {
, _timeHandler(TIME_PATH, securityManager->wrapCallback(std::bind(&NTPSettingsService::configureTime, this, std::placeholders::_1, std::placeholders::_2), AuthenticationPredicates::IS_ADMIN)) {
_timeHandler.setMethod(HTTP_POST);
_timeHandler.setMaxContentLength(MAX_TIME_SIZE);
server->addHandler(&_timeHandler);
#ifdef ESP32
WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2),
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
#elif defined(ESP8266)
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1));
#endif
WiFi.onEvent(std::bind(&NTPSettingsService::WiFiEvent, this, std::placeholders::_1));
addUpdateHandler([&](const String & originId) { configureNTP(); }, false);
}
@@ -25,43 +18,36 @@ void NTPSettingsService::begin() {
configureNTP();
}
#ifdef ESP32
void NTPSettingsService::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
// Serial.println(F("Got IP address, starting NTP Synchronization"));
configureNTP();
}
// handles both WiFI and Ethernet
void NTPSettingsService::WiFiEvent(WiFiEvent_t event) {
switch (event) {
case SYSTEM_EVENT_STA_DISCONNECTED:
// Serial.println(F("WiFi connection dropped, stopping NTP."));
connected_ = false;
configureNTP();
break;
void NTPSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
// Serial.println(F("WiFi connection dropped, stopping NTP."));
configureNTP();
}
#elif defined(ESP8266)
void NTPSettingsService::onStationModeGotIP(const WiFiEventStationModeGotIP & event) {
// Serial.println(F("Got IP address, starting NTP Synchronization"));
configureNTP();
}
case SYSTEM_EVENT_STA_GOT_IP:
case SYSTEM_EVENT_ETH_GOT_IP:
// Serial.println(F("Got IP address, starting NTP Synchronization"));
connected_ = true;
configureNTP();
break;
void NTPSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
// Serial.println(F("WiFi connection dropped, stopping NTP."));
configureNTP();
default:
break;
}
}
#endif
void NTPSettingsService::configureNTP() {
if (WiFi.isConnected() && _state.enabled) {
if (connected_ && _state.enabled) {
// Serial.println(F("Starting NTP..."));
#ifdef ESP32
configTzTime(_state.tzFormat.c_str(), _state.server.c_str());
#elif defined(ESP8266)
configTime(_state.tzFormat.c_str(), _state.server.c_str());
#endif
} else {
#ifdef ESP32
setenv("TZ", _state.tzFormat.c_str(), 1);
tzset();
#elif defined(ESP8266)
setTZ(_state.tzFormat.c_str());
#endif
sntp_stop();
}
}

View File

@@ -5,11 +5,8 @@
#include <FSPersistence.h>
#include <time.h>
#ifdef ESP32
#include <lwip/apps/sntp.h>
#elif defined(ESP8266)
#include <sntp.h>
#endif
#include <ETH.h>
#ifndef FACTORY_NTP_ENABLED
#define FACTORY_NTP_ENABLED true
@@ -67,16 +64,8 @@ class NTPSettingsService : public StatefulService<NTPSettings> {
FSPersistence<NTPSettings> _fsPersistence;
AsyncCallbackJsonWebHandler _timeHandler;
#ifdef ESP32
void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
#elif defined(ESP8266)
WiFiEventHandler _onStationModeDisconnectedHandler;
WiFiEventHandler _onStationModeGotIPHandler;
void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
#endif
bool connected_ = false;
void WiFiEvent(WiFiEvent_t event);
void configureNTP();
void configureTime(AsyncWebServerRequest * request, JsonVariant & json);
};

View File

@@ -0,0 +1,90 @@
#include <NetworkSettingsService.h>
NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
: _httpEndpoint(NetworkSettings::read, NetworkSettings::update, this, server, NETWORK_SETTINGS_SERVICE_PATH, securityManager)
, _fsPersistence(NetworkSettings::read, NetworkSettings::update, this, fs, NETWORK_SETTINGS_FILE)
, _lastConnectionAttempt(0) {
// We want the device to come up in opmode=0 (WIFI_OFF), when erasing the flash this is not the default.
// If needed, we save opmode=0 before disabling persistence so the device boots with WiFi disabled in the future.
if (WiFi.getMode() != WIFI_OFF) {
WiFi.mode(WIFI_OFF);
}
// Disable WiFi config persistance and auto reconnect
WiFi.persistent(false);
WiFi.setAutoReconnect(false);
WiFi.mode(WIFI_MODE_MAX);
WiFi.mode(WIFI_MODE_NULL);
WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, std::placeholders::_1));
addUpdateHandler([&](const String & originId) { reconfigureWiFiConnection(); }, false);
}
void NetworkSettingsService::begin() {
_fsPersistence.readFromFS();
reconfigureWiFiConnection();
}
void NetworkSettingsService::reconfigureWiFiConnection() {
// reset last connection attempt to force loop to reconnect immediately
_lastConnectionAttempt = 0;
// disconnect and de-configure wifi
if (WiFi.disconnect(true)) {
_stopping = true;
}
}
void NetworkSettingsService::loop() {
unsigned long currentMillis = millis();
if (!_lastConnectionAttempt || (uint32_t)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
_lastConnectionAttempt = currentMillis;
manageSTA();
}
}
void NetworkSettingsService::manageSTA() {
// Abort if already connected, or if we have no SSID
if (WiFi.isConnected() || _state.ssid.length() == 0) {
return;
}
// Connect or reconnect as required
if ((WiFi.getMode() & WIFI_STA) == 0) {
if (_state.staticIPConfig) {
WiFi.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); // configure for static IP
} else {
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); // configure for DHCP
}
WiFi.setHostname(_state.hostname.c_str()); // set hostname
WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); // attempt to connect to the network
}
}
// handles both WiFI and Ethernet
void NetworkSettingsService::WiFiEvent(WiFiEvent_t event) {
switch (event) {
case SYSTEM_EVENT_STA_DISCONNECTED:
WiFi.disconnect(true);
break;
case SYSTEM_EVENT_STA_STOP:
if (_stopping) {
_lastConnectionAttempt = 0;
_stopping = false;
}
break;
case SYSTEM_EVENT_ETH_START:
if (_state.staticIPConfig) {
ETH.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); // configure for static IP
}
break;
default:
break;
}
}

View File

@@ -1,13 +1,15 @@
#ifndef WiFiSettingsService_h
#define WiFiSettingsService_h
#ifndef NetworkSettingsService_h
#define NetworkSettingsService_h
#include <StatefulService.h>
#include <FSPersistence.h>
#include <HttpEndpoint.h>
#include <JsonUtils.h>
#define WIFI_SETTINGS_FILE "/config/wifiSettings.json"
#define WIFI_SETTINGS_SERVICE_PATH "/rest/wifiSettings"
#include <ETH.h>
#define NETWORK_SETTINGS_FILE "/config/networkSettings.json"
#define NETWORK_SETTINGS_SERVICE_PATH "/rest/networkSettings"
#define WIFI_RECONNECTION_DELAY 1000 * 30
#ifndef FACTORY_WIFI_SSID
@@ -22,13 +24,14 @@
#define FACTORY_WIFI_HOSTNAME ""
#endif
class WiFiSettings {
class NetworkSettings {
public:
// core wifi configuration
String ssid;
String password;
String hostname;
bool staticIPConfig;
String ssid;
String password;
String hostname;
bool staticIPConfig;
uint8_t ethernet_profile;
// optional configuration for static IP address
IPAddress localIP;
@@ -37,12 +40,13 @@ class WiFiSettings {
IPAddress dnsIP1;
IPAddress dnsIP2;
static void read(WiFiSettings & settings, JsonObject & root) {
static void read(NetworkSettings & settings, JsonObject & root) {
// connection settings
root["ssid"] = settings.ssid;
root["password"] = settings.password;
root["hostname"] = settings.hostname;
root["static_ip_config"] = settings.staticIPConfig;
root["ethernet_profile"] = settings.ethernet_profile;
// extended settings
JsonUtils::writeIP(root, "local_ip", settings.localIP);
@@ -52,11 +56,12 @@ class WiFiSettings {
JsonUtils::writeIP(root, "dns_ip_2", settings.dnsIP2);
}
static StateUpdateResult update(JsonObject & root, WiFiSettings & settings) {
settings.ssid = root["ssid"] | FACTORY_WIFI_SSID;
settings.password = root["password"] | FACTORY_WIFI_PASSWORD;
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
settings.staticIPConfig = root["static_ip_config"] | false;
static StateUpdateResult update(JsonObject & root, NetworkSettings & settings) {
settings.ssid = root["ssid"] | FACTORY_WIFI_SSID;
settings.password = root["password"] | FACTORY_WIFI_PASSWORD;
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
settings.staticIPConfig = root["static_ip_config"] | false;
settings.ethernet_profile = root["ethernet_profile"] | 0; // no ethernet
// extended settings
JsonUtils::readIP(root, "local_ip", settings.localIP);
@@ -77,33 +82,28 @@ class WiFiSettings {
if (settings.staticIPConfig && (settings.localIP == INADDR_NONE || settings.gatewayIP == INADDR_NONE || settings.subnetMask == INADDR_NONE)) {
settings.staticIPConfig = false;
}
return StateUpdateResult::CHANGED;
}
};
class WiFiSettingsService : public StatefulService<WiFiSettings> {
class NetworkSettingsService : public StatefulService<NetworkSettings> {
public:
WiFiSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
void begin();
void loop();
private:
HttpEndpoint<WiFiSettings> _httpEndpoint;
FSPersistence<WiFiSettings> _fsPersistence;
unsigned long _lastConnectionAttempt;
HttpEndpoint<NetworkSettings> _httpEndpoint;
FSPersistence<NetworkSettings> _fsPersistence;
unsigned long _lastConnectionAttempt;
#ifdef ESP32
bool _stopping;
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
void onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info);
#elif defined(ESP8266)
WiFiEventHandler _onStationModeDisconnectedHandler;
void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
#endif
void WiFiEvent(WiFiEvent_t event);
void reconfigureWiFiConnection();
void manageSTA();
};
#endif // end WiFiSettingsService_h
#endif

View File

@@ -0,0 +1,57 @@
#include <NetworkStatus.h>
NetworkStatus::NetworkStatus(AsyncWebServer * server, SecurityManager * securityManager) {
server->on(NETWORK_STATUS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&NetworkStatus::networkStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
}
void NetworkStatus::networkStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_NETWORK_STATUS_SIZE);
JsonObject root = response->getRoot();
bool ethernet_connected = ETH.linkUp();
wl_status_t wifi_status = WiFi.status();
// see if Ethernet is connected
if (ethernet_connected) {
root["status"] = 10; // custom code #10 - ETHERNET_STATUS_CONNECTED
} else {
root["status"] = (uint8_t)wifi_status;
}
// for Wifi
if (wifi_status == WL_CONNECTED) {
root["local_ip"] = WiFi.localIP().toString();
root["mac_address"] = WiFi.macAddress();
root["rssi"] = WiFi.RSSI();
root["ssid"] = WiFi.SSID();
root["bssid"] = WiFi.BSSIDstr();
root["channel"] = WiFi.channel();
root["subnet_mask"] = WiFi.subnetMask().toString();
root["gateway_ip"] = WiFi.gatewayIP().toString();
IPAddress dnsIP1 = WiFi.dnsIP(0);
IPAddress dnsIP2 = WiFi.dnsIP(1);
if (dnsIP1 != INADDR_NONE) {
root["dns_ip_1"] = dnsIP1.toString();
}
if (dnsIP2 != INADDR_NONE) {
root["dns_ip_2"] = dnsIP2.toString();
}
} else if (ETH.linkUp()) {
// Ethernet
root["local_ip"] = ETH.localIP().toString();
root["mac_address"] = ETH.macAddress();
root["subnet_mask"] = ETH.subnetMask().toString();
root["gateway_ip"] = ETH.gatewayIP().toString();
IPAddress dnsIP1 = ETH.dnsIP(0);
IPAddress dnsIP2 = ETH.dnsIP(1);
if (dnsIP1 != INADDR_NONE) {
root["dns_ip_1"] = dnsIP1.toString();
}
if (dnsIP2 != INADDR_NONE) {
root["dns_ip_2"] = dnsIP2.toString();
}
}
response->setLength();
request->send(response);
}

View File

@@ -0,0 +1,25 @@
#ifndef NetworkStatus_h
#define NetworkStatus_h
#include <WiFi.h>
#include <ETH.h>
#include <AsyncTCP.h>
#include <ArduinoJson.h>
#include <AsyncJson.h>
#include <ESPAsyncWebServer.h>
#include <IPAddress.h>
#include <SecurityManager.h>
#define MAX_NETWORK_STATUS_SIZE 1024
#define NETWORK_STATUS_SERVICE_PATH "/rest/networkStatus"
class NetworkStatus {
public:
NetworkStatus(AsyncWebServer * server, SecurityManager * securityManager);
private:
void networkStatus(AsyncWebServerRequest * request);
};
#endif

View File

@@ -1,44 +1,25 @@
#include <SystemStatus.h>
SystemStatus::SystemStatus(AsyncWebServer * server, SecurityManager * securityManager) {
server->on(SYSTEM_STATUS_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
server->on(SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
}
void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_ESP_STATUS_SIZE);
JsonObject root = response->getRoot();
#ifdef ESP32
root["esp_platform"] = "esp32";
root["max_alloc_heap"] = ESP.getMaxAllocHeap();
root["psram_size"] = ESP.getPsramSize();
root["free_psram"] = ESP.getFreePsram();
#elif defined(ESP8266)
root["esp_platform"] = "esp8266";
root["max_alloc_heap"] = ESP.getMaxFreeBlockSize();
root["heap_fragmentation"] = ESP.getHeapFragmentation();
#endif
root["cpu_freq_mhz"] = ESP.getCpuFreqMHz();
root["free_heap"] = ESP.getFreeHeap();
root["sketch_size"] = ESP.getSketchSize();
root["free_sketch_space"] = ESP.getFreeSketchSpace();
root["sdk_version"] = ESP.getSdkVersion();
root["flash_chip_size"] = ESP.getFlashChipSize();
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
root["esp_platform"] = "esp32";
root["max_alloc_heap"] = ESP.getMaxAllocHeap();
root["psram_size"] = ESP.getPsramSize();
root["free_psram"] = ESP.getFreePsram();
root["cpu_freq_mhz"] = ESP.getCpuFreqMHz();
root["free_heap"] = ESP.getFreeHeap();
root["sdk_version"] = ESP.getSdkVersion();
root["flash_chip_size"] = ESP.getFlashChipSize();
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
// ESP8266 and ESP32 do not have feature parity in FS.h which currently makes that difficult.
#ifdef ESP32
root["fs_total"] = SPIFFS.totalBytes();
root["fs_used"] = SPIFFS.usedBytes();
#elif defined(ESP8266)
FSInfo fs_info;
LittleFS.info(fs_info); // // proddy added
root["fs_total"] = fs_info.totalBytes;
root["fs_used"] = fs_info.usedBytes;
#endif
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); // proddy added
root["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
response->setLength();
request->send(response);

View File

@@ -1,12 +1,8 @@
#include <WiFiScanner.h>
WiFiScanner::WiFiScanner(AsyncWebServer * server, SecurityManager * securityManager) {
server->on(SCAN_NETWORKS_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest(std::bind(&WiFiScanner::scanNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
server->on(LIST_NETWORKS_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest(std::bind(&WiFiScanner::listNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
server->on(SCAN_NETWORKS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WiFiScanner::scanNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
server->on(LIST_NETWORKS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WiFiScanner::listNetworks, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
};
void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) {
@@ -24,16 +20,12 @@ void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
JsonObject root = response->getRoot();
JsonArray networks = root.createNestedArray("networks");
for (int i = 0; i < numNetworks; i++) {
JsonObject network = networks.createNestedObject();
network["rssi"] = WiFi.RSSI(i);
network["ssid"] = WiFi.SSID(i);
network["bssid"] = WiFi.BSSIDstr(i);
network["channel"] = WiFi.channel(i);
#ifdef ESP32
JsonObject network = networks.createNestedObject();
network["rssi"] = WiFi.RSSI(i);
network["ssid"] = WiFi.SSID(i);
network["bssid"] = WiFi.BSSIDstr(i);
network["channel"] = WiFi.channel(i);
network["encryption_type"] = (uint8_t)WiFi.encryptionType(i);
#elif defined(ESP8266)
network["encryption_type"] = convertEncryptionType(WiFi.encryptionType(i));
#endif
}
response->setLength();
request->send(response);
@@ -43,26 +35,3 @@ void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
scanNetworks(request);
}
}
#ifdef ESP8266
/*
* Convert encryption type to standard used by ESP32 rather than the translated form which the esp8266 libaries expose.
*
* This allows us to use a single set of mappings in the UI.
*/
uint8_t WiFiScanner::convertEncryptionType(uint8_t encryptionType) {
switch (encryptionType) {
case ENC_TYPE_NONE:
return AUTH_OPEN;
case ENC_TYPE_WEP:
return AUTH_WEP;
case ENC_TYPE_TKIP:
return AUTH_WPA_PSK;
case ENC_TYPE_CCMP:
return AUTH_WPA2_PSK;
case ENC_TYPE_AUTO:
return AUTH_WPA_WPA2_PSK;
}
return -1;
}
#endif

View File

@@ -1,111 +0,0 @@
#include <WiFiSettingsService.h>
WiFiSettingsService::WiFiSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
: _httpEndpoint(WiFiSettings::read, WiFiSettings::update, this, server, WIFI_SETTINGS_SERVICE_PATH, securityManager)
, _fsPersistence(WiFiSettings::read, WiFiSettings::update, this, fs, WIFI_SETTINGS_FILE)
, _lastConnectionAttempt(0) {
// We want the device to come up in opmode=0 (WIFI_OFF), when erasing the flash this is not the default.
// If needed, we save opmode=0 before disabling persistence so the device boots with WiFi disabled in the future.
if (WiFi.getMode() != WIFI_OFF) {
WiFi.mode(WIFI_OFF);
}
// Disable WiFi config persistance and auto reconnect
WiFi.persistent(false);
WiFi.setAutoReconnect(false);
#ifdef ESP32
// Init the wifi driver on ESP32
WiFi.mode(WIFI_MODE_MAX);
WiFi.mode(WIFI_MODE_NULL);
WiFi.onEvent(std::bind(&WiFiSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2),
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.onEvent(std::bind(&WiFiSettingsService::onStationModeStop, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_STOP);
#elif defined(ESP8266)
// proddy added
#if defined(ESP8266)
// WiFi.setSleepMode(WIFI_NONE_SLEEP); // added to possibly fix wifi dropouts in arduino core 2.5.0
// ref: https://github.com/esp8266/Arduino/issues/6471
// ref: https://github.com/esp8266/Arduino/issues/6366
// high tx power causing weird behavior, slightly lowering from 20.5 to 20.0 may help stability
// WiFi.setOutputPower(20.0); // in dBm
#endif
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&WiFiSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
#endif
addUpdateHandler([&](const String & originId) { reconfigureWiFiConnection(); }, false);
}
void WiFiSettingsService::begin() {
_fsPersistence.readFromFS();
reconfigureWiFiConnection();
}
void WiFiSettingsService::reconfigureWiFiConnection() {
// reset last connection attempt to force loop to reconnect immediately
_lastConnectionAttempt = 0;
// disconnect and de-configure wifi
#ifdef ESP32
if (WiFi.disconnect(true)) {
_stopping = true;
}
#elif defined(ESP8266)
WiFi.disconnect(true);
#endif
}
void WiFiSettingsService::loop() {
unsigned long currentMillis = millis();
if (!_lastConnectionAttempt || (uint32_t)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
_lastConnectionAttempt = currentMillis;
manageSTA();
}
}
void WiFiSettingsService::manageSTA() {
// Abort if already connected, or if we have no SSID
if (WiFi.isConnected() || _state.ssid.length() == 0) {
return;
}
// Connect or reconnect as required
if ((WiFi.getMode() & WIFI_STA) == 0) {
// Serial.println(F("Connecting to WiFi."));
if (_state.staticIPConfig) {
// configure for static IP
WiFi.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2);
} else {
// configure for DHCP
#ifdef ESP32
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
#elif defined(ESP8266)
WiFi.config(INADDR_ANY, INADDR_ANY, INADDR_ANY);
#endif
}
// set hostname
#ifdef ESP32
WiFi.setHostname(_state.hostname.c_str());
#elif defined(ESP8266)
WiFi.hostname(_state.hostname);
#endif
// attempt to connect to the network
WiFi.begin(_state.ssid.c_str(), _state.password.c_str());
}
}
#ifdef ESP32
void WiFiSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
WiFi.disconnect(true);
}
void WiFiSettingsService::onStationModeStop(WiFiEvent_t event, WiFiEventInfo_t info) {
if (_stopping) {
_lastConnectionAttempt = 0;
_stopping = false;
}
}
#elif defined(ESP8266)
void WiFiSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
WiFi.disconnect(true);
}
#endif

View File

@@ -1,72 +0,0 @@
#include <WiFiStatus.h>
WiFiStatus::WiFiStatus(AsyncWebServer * server, SecurityManager * securityManager) {
server->on(WIFI_STATUS_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest(std::bind(&WiFiStatus::wifiStatus, this, std::placeholders::_1), AuthenticationPredicates::IS_AUTHENTICATED));
#ifdef ESP32
WiFi.onEvent(onStationModeConnected, WiFiEvent_t::SYSTEM_EVENT_STA_CONNECTED);
WiFi.onEvent(onStationModeDisconnected, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.onEvent(onStationModeGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
#elif defined(ESP8266)
_onStationModeConnectedHandler = WiFi.onStationModeConnected(onStationModeConnected);
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(onStationModeDisconnected);
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(onStationModeGotIP);
#endif
}
#ifdef ESP32
void WiFiStatus::onStationModeConnected(WiFiEvent_t event, WiFiEventInfo_t info) {
// Serial.println(F("WiFi Connected."));
}
void WiFiStatus::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
// Serial.print(F("WiFi Disconnected. Reason code="));
// Serial.println(info.disconnected.reason);
}
void WiFiStatus::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
// Serial.printf_P(PSTR("WiFi Got IP. localIP=%s, hostName=%s\r\n"), WiFi.localIP().toString().c_str(), WiFi.getHostname());
}
#elif defined(ESP8266)
void WiFiStatus::onStationModeConnected(const WiFiEventStationModeConnected & event) {
// Serial.print(F("WiFi Connected. SSID="));
// Serial.println(event.ssid);
}
void WiFiStatus::onStationModeDisconnected(const WiFiEventStationModeDisconnected & event) {
// Serial.print(F("WiFi Disconnected. Reason code="));
// Serial.println(event.reason);
}
void WiFiStatus::onStationModeGotIP(const WiFiEventStationModeGotIP & event) {
// Serial.printf_P(PSTR("WiFi Got IP. localIP=%s, hostName=%s\r\n"), event.ip.toString().c_str(), WiFi.hostname().c_str());
}
#endif
void WiFiStatus::wifiStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_WIFI_STATUS_SIZE);
JsonObject root = response->getRoot();
wl_status_t status = WiFi.status();
root["status"] = (uint8_t)status;
if (status == WL_CONNECTED) {
root["local_ip"] = WiFi.localIP().toString();
root["mac_address"] = WiFi.macAddress();
root["rssi"] = WiFi.RSSI();
root["ssid"] = WiFi.SSID();
root["bssid"] = WiFi.BSSIDstr();
root["channel"] = WiFi.channel();
root["subnet_mask"] = WiFi.subnetMask().toString();
root["gateway_ip"] = WiFi.gatewayIP().toString();
IPAddress dnsIP1 = WiFi.dnsIP(0);
IPAddress dnsIP2 = WiFi.dnsIP(1);
if (dnsIP1 != INADDR_NONE) {
root["dns_ip_1"] = dnsIP1.toString();
}
if (dnsIP2 != INADDR_NONE) {
root["dns_ip_2"] = dnsIP2.toString();
}
}
response->setLength();
request->send(response);
}

View File

@@ -1,45 +0,0 @@
#ifndef WiFiStatus_h
#define WiFiStatus_h
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ArduinoJson.h>
#include <AsyncJson.h>
#include <ESPAsyncWebServer.h>
#include <IPAddress.h>
#include <SecurityManager.h>
#define MAX_WIFI_STATUS_SIZE 1024
#define WIFI_STATUS_SERVICE_PATH "/rest/wifiStatus"
class WiFiStatus {
public:
WiFiStatus(AsyncWebServer * server, SecurityManager * securityManager);
private:
#ifdef ESP32
// static functions for logging WiFi events to the UART
static void onStationModeConnected(WiFiEvent_t event, WiFiEventInfo_t info);
static void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
static void onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info);
#elif defined(ESP8266)
// handler refrences for logging important WiFi events over serial
WiFiEventHandler _onStationModeConnectedHandler;
WiFiEventHandler _onStationModeDisconnectedHandler;
WiFiEventHandler _onStationModeGotIPHandler;
// static functions for logging WiFi events to the UART
static void onStationModeConnected(const WiFiEventStationModeConnected & event);
static void onStationModeDisconnected(const WiFiEventStationModeDisconnected & event);
static void onStationModeGotIP(const WiFiEventStationModeGotIP & event);
#endif
void wifiStatus(AsyncWebServerRequest * request);
};
#endif // end WiFiStatus_h