Merge remote-tracking branch 'upstream/mega' into UweKaditz

This commit is contained in:
uwekaditz
2021-06-14 18:26:19 +02:00
28 changed files with 572 additions and 260 deletions
+73
View File
@@ -0,0 +1,73 @@
#include "../DataStructs/MAC_address.h"
#include "../../ESPEasy_common.h"
MAC_address::MAC_address()
{}
MAC_address::MAC_address(const uint8_t new_mac[6])
{
memcpy(mac, new_mac, 6);
}
bool MAC_address::set(const char *string)
{
unsigned u[6];
int c = sscanf(string, "%x:%x:%x:%x:%x:%x", u, u + 1, u + 2, u + 3, u + 4, u + 5);
if (c != 6) {
return false;
}
for (int i = 0; i < 6; ++i) {
mac[i] = static_cast<uint8_t>(u[i]);
}
return true;
}
void MAC_address::set(const uint8_t other[6])
{
memcpy(mac, other, 6);
}
void MAC_address::get(uint8_t mac_out[6]) const
{
memcpy(mac_out, mac, 6);
}
bool MAC_address::all_zero() const
{
for (int i = 0; i < 6; ++i) {
if (mac[i] != 0) {
return false;
}
}
return true;
}
bool MAC_address::all_one() const
{
for (int i = 0; i < 6; ++i) {
if (mac[i] != 0xFF) {
return false;
}
}
return true;
}
String MAC_address::toString() const
{
char str[18] = { 0 };
sprintf_P(str, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(str);
}
bool MAC_address::mac_addr_cmp(const uint8_t other[6]) const
{
for (int i = 0; i < 6; ++i) {
if (mac[i] != other[i]) {
return false;
}
}
return true;
}
+75
View File
@@ -0,0 +1,75 @@
#ifndef DATASTRUCTS_MAC_ADDRESS_H
#define DATASTRUCTS_MAC_ADDRESS_H
#include <stdint.h>
#include <WString.h>
class __attribute__((__packed__)) MAC_address {
public:
MAC_address();
MAC_address(const uint8_t new_mac[6]);
bool operator==(const MAC_address& other) const {
return mac_addr_cmp(other.mac);
}
bool operator!=(const MAC_address& other) const {
return !mac_addr_cmp(other.mac);
}
bool operator==(const uint8_t other[6]) const {
return mac_addr_cmp(other);
}
bool operator!=(const uint8_t other[6]) const {
return !mac_addr_cmp(other);
}
// Parse string with MAC address.
// Returns false if the given string has no valid formatted mac address.
bool set(const char *string);
void set(const uint8_t other[6]);
void get(uint8_t mac_out[6]) const;
bool all_zero() const;
bool all_one() const;
String toString() const;
// An universally administered address (UAA) is uniquely assigned to a device by its manufacturer.
// The first three octets (in transmission order) identify the organization that issued
// the identifier and are known as the organizationally unique identifier (OUI)
bool isUniversal() const {
return (mac[0] & 2) == 0;
}
// A locally administered address (LAA) is assigned to a device by a network administrator, overriding the burned-in address.
bool isLocal() const {
return !isUniversal();
}
// Unicast frames are meant to be received by a single network device.
// See: https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
bool isUnicast() const {
return (mac[0] & 1) == 0;
}
// Multicast frames are meant to be received by multiple network devices
// See: https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
bool isMulticast() const {
return !isUnicast();
}
uint8_t mac[6] = { 0 };
private:
bool mac_addr_cmp(const uint8_t other[6]) const;
};
#endif // DATASTRUCTS_MAC_ADDRESS_H
+15 -18
View File
@@ -56,16 +56,22 @@ bool WiFiEventData_t::unprocessedWifiEvents() const {
}
void WiFiEventData_t::clearAll() {
lastDisconnectMoment.clear();
lastConnectMoment.clear();
lastGetIPmoment.clear();
markWiFiTurnOn();
lastGetScanMoment.clear();
last_wifi_connect_attempt_moment.clear();
timerAPstart.clear();
setWiFiDisconnected();
lastWiFiResetMoment.setNow();
wifi_considered_stable = false;
wifi_TX_pwr = 0;
usedChannel = 0;
}
void WiFiEventData_t::markWiFiTurnOn() {
setWiFiDisconnected();
lastDisconnectMoment.clear();
lastConnectMoment.clear();
lastGetIPmoment.clear();
wifi_considered_stable = false;
// Mark all flags to default to prevent handling old events.
processedConnect = true;
@@ -77,17 +83,12 @@ void WiFiEventData_t::clearAll() {
processedScanDone = true;
wifiConnectAttemptNeeded = true;
wifiConnectInProgress = false;
wifi_TX_pwr = 0;
usedChannel = 0;
processingDisconnect.clear();
}
void WiFiEventData_t::markWiFiBegin() {
setWiFiDisconnected();
lastDisconnectMoment.clear();
lastConnectMoment.clear();
lastGetIPmoment.clear();
markWiFiTurnOn();
last_wifi_connect_attempt_moment.setNow();
wifi_considered_stable = false;
wifiConnectInProgress = true;
usedChannel = 0;
++wifi_connect_attempt;
@@ -182,16 +183,12 @@ void WiFiEventData_t::markConnected(const String& ssid, const uint8_t bssid[6],
}
void WiFiEventData_t::markConnectedAPmode(const uint8_t mac[6]) {
for (byte i = 0; i < 6; ++i) {
lastMacConnectedAPmode[i] = mac[i];
}
lastMacConnectedAPmode = mac;
processedConnectAPmode = false;
}
void WiFiEventData_t::markDisconnectedAPmode(const uint8_t mac[6]) {
for (byte i = 0; i < 6; ++i) {
lastMacDisconnectedAPmode[i] = mac[i];
}
lastMacDisconnectedAPmode = mac;
processedDisconnectAPmode = false;
}
+10 -7
View File
@@ -1,6 +1,7 @@
#ifndef DATASTRUCTS_WIFIEVENTDATA_H
#define DATASTRUCTS_WIFIEVENTDATA_H
#include "../DataStructs/MAC_address.h"
#include "../DataTypes/WiFiDisconnectReason.h"
#include "../Helpers/LongTermTimer.h"
@@ -29,6 +30,7 @@ struct WiFiEventData_t {
bool unprocessedWifiEvents() const;
void clearAll();
void markWiFiTurnOn();
void markWiFiBegin();
bool WiFiDisconnected() const;
@@ -71,6 +73,8 @@ struct WiFiEventData_t {
uint8_t lastScanChannel = 0;
uint8_t usedChannel = 0;
bool eventError = false;
WiFiDisconnectReason lastDisconnectReason = WIFI_DISCONNECT_REASON_UNSPECIFIED;
LongTermTimer lastScanMoment;
@@ -83,8 +87,12 @@ struct WiFiEventData_t {
LongTermTimer timerAPoff; // Timer to check whether the AP mode should be disabled (0 = disabled)
LongTermTimer timerAPstart; // Timer to start AP mode, started when no valid network is detected.
bool intent_to_reboot = false;
uint8_t lastMacConnectedAPmode[6] = { 0 };
uint8_t lastMacDisconnectedAPmode[6] = { 0 };
MAC_address lastMacConnectedAPmode;
MAC_address lastMacDisconnectedAPmode;
// processDisconnect() may clear all WiFi settings, resulting in clearing processedDisconnect
// This can cause recursion, so a semaphore is needed here.
LongTermTimer processingDisconnect;
// Semaphore like bools for processing data gathered from WiFi events.
@@ -101,11 +109,6 @@ struct WiFiEventData_t {
bool performedClearWiFiCredentials = false;
// processDisconnect() may clear all WiFi settings, resulting in clearing processedDisconnect
// This can cause recursion, so a semaphore is needed here.
bool processingDisconnect = false;
unsigned long connectionFailures = 0;
+9 -44
View File
@@ -36,7 +36,7 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0) {
ssid = WiFi.SSID(networkItem);
rssi = WiFi.RSSI(networkItem);
channel = WiFi.channel(networkItem);
setBSSID(WiFi.BSSID(networkItem));
bssid = WiFi.BSSID(networkItem);
enc_type = WiFi.encryptionType(networkItem);
#ifdef ESP8266
isHidden = WiFi.isHidden(networkItem);
@@ -47,16 +47,6 @@ WiFi_AP_Candidate::WiFi_AP_Candidate(uint8_t networkItem) : index(0) {
last_seen = millis();
}
WiFi_AP_Candidate::WiFi_AP_Candidate(const WiFi_AP_Candidate& other)
: ssid(other.ssid), key(other.key), last_seen(other.last_seen),
rssi(other.rssi), channel(other.channel), index(other.index),
enc_type(other.enc_type), isHidden(other.isHidden),
lowPriority(other.lowPriority),
isEmergencyFallback(other.isEmergencyFallback)
{
setBSSID(other.bssid);
}
WiFi_AP_Candidate::WiFi_AP_Candidate() {}
bool WiFi_AP_Candidate::operator<(const WiFi_AP_Candidate& other) const {
@@ -83,29 +73,6 @@ bool WiFi_AP_Candidate::operator==(const WiFi_AP_Candidate& other) const {
return bssid_match(other.bssid) && ssid.equals(other.ssid) && key.equals(other.key);
}
WiFi_AP_Candidate& WiFi_AP_Candidate::operator=(const WiFi_AP_Candidate& other) {
if (this != &other) { // not a self-assignment
ssid = other.ssid;
key = other.key;
last_seen = other.last_seen;
rssi = other.rssi;
channel = other.channel;
setBSSID(other.bssid);
isHidden = other.isHidden;
index = other.index;
enc_type = other.enc_type;
lowPriority = other.lowPriority;
isEmergencyFallback = other.isEmergencyFallback;
}
return *this;
}
void WiFi_AP_Candidate::setBSSID(const uint8_t *bssid_c) {
for (byte i = 0; i < 6; ++i) {
bssid[i] = *(bssid_c + i);
}
}
bool WiFi_AP_Candidate::usable() const {
// Allow for empty pass
// if (key.isEmpty()) return false;
@@ -139,17 +106,15 @@ bool WiFi_AP_Candidate::allowQuickConnect() const {
}
bool WiFi_AP_Candidate::bssid_set() const {
for (byte i = 0; i < 6; ++i) {
if (bssid[i] != 0) { return true; }
}
return false;
return !bssid.all_zero();
}
bool WiFi_AP_Candidate::bssid_match(const uint8_t *bssid_c) const {
for (byte i = 0; i < 6; ++i) {
if (bssid[i] != bssid_c[i]) { return false; }
}
return true;
bool WiFi_AP_Candidate::bssid_match(const uint8_t bssid_c[6]) const {
return bssid == bssid_c;
}
bool WiFi_AP_Candidate::bssid_match(const MAC_address& other) const {
return bssid == other;
}
String WiFi_AP_Candidate::toString(const String& separator) const {
@@ -160,7 +125,7 @@ String WiFi_AP_Candidate::toString(const String& separator) const {
result += F("#Hidden#");
}
result += separator;
result += formatMAC(bssid);
result += bssid.toString();
result += separator;
result += F("Ch:");
result += channel;
+6 -6
View File
@@ -3,6 +3,7 @@
#include "../../ESPEasy_common.h"
#include "../DataStructs/MAC_address.h"
struct WiFi_AP_Candidate {
// Construct from stored credentials
// @param index The index of the stored credentials
@@ -16,7 +17,7 @@ struct WiFi_AP_Candidate {
// Construct using index from WiFi scan result
WiFi_AP_Candidate(uint8_t networkItem);
WiFi_AP_Candidate(const WiFi_AP_Candidate& other);
WiFi_AP_Candidate(const WiFi_AP_Candidate& other) = default;
// Default constructor
WiFi_AP_Candidate();
@@ -26,9 +27,7 @@ struct WiFi_AP_Candidate {
bool operator==(const WiFi_AP_Candidate& other) const;
WiFi_AP_Candidate& operator=(const WiFi_AP_Candidate& other);
void setBSSID(const uint8_t *bssid_c);
WiFi_AP_Candidate& operator=(const WiFi_AP_Candidate& other) = default;
// Check if the candidate data can be used to actually connect to an AP.
bool usable() const;
@@ -42,7 +41,8 @@ struct WiFi_AP_Candidate {
// Check to see if the BSSID is set
bool bssid_set() const;
bool bssid_match(const uint8_t *bssid_c) const;
bool bssid_match(const uint8_t bssid_c[6]) const;
bool bssid_match(const MAC_address& other) const;
// Create a formatted string
String toString(const String& separator = " ") const;
@@ -55,7 +55,7 @@ struct WiFi_AP_Candidate {
unsigned long last_seen = 0;
int32_t rssi = 0;
int32_t channel = 0;
uint8_t bssid[6] = { 0 };
MAC_address bssid;
byte index = 0; // Index of the matching credentials
byte enc_type = 0; // Encryption used (e.g. WPA2)
bool isHidden = false; // Hidden SSID
+8 -3
View File
@@ -82,9 +82,14 @@ void ethPrintSettings() {
}
}
uint8_t * ETHMacAddress(uint8_t* mac) {
esp_eth_get_mac(mac);
return mac;
MAC_address ETHMacAddress() {
MAC_address mac;
if(!EthEventData.ethInitSuccess) {
addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddress() only on connected Ethernet!"));
} else {
esp_eth_get_mac(mac.mac);
}
return mac;
}
bool ETHConnectRelaxed() {
+2 -1
View File
@@ -5,6 +5,7 @@
#ifdef HAS_ETHERNET
#include "../DataStructs/MAC_address.h"
bool ethUseStaticIP();
void ethSetupStaticIPconfig();
@@ -13,7 +14,7 @@ bool ethPrepare();
void ethPrintSettings();
bool ETHConnectRelaxed();
bool ETHConnected();
uint8_t* ETHMacAddress(uint8_t *mac);
MAC_address ETHMacAddress();
#endif // ifdef HAS_ETHERNET
#endif // ifndef ESPEASY_ETH_H
+11 -32
View File
@@ -126,32 +126,15 @@ IPAddress NetworkDnsIP (uint8_t dns_no) {
return WiFi.dnsIP(dns_no);
}
String NetworkMacAddress() {
MAC_address NetworkMacAddress() {
#ifdef HAS_ETHERNET
if(active_network_medium == NetworkMedium_t::Ethernet) {
if(!EthEventData.ethInitSuccess) {
addLog(LOG_LEVEL_ERROR, F("Call NetworkMacAddress() only on connected Ethernet!"));
} else {
return ETH.macAddress();
}
return ETHMacAddress();
}
#endif
uint8_t mac[] = { 0, 0, 0, 0, 0, 0 };
uint8_t *macread = NetworkMacAddressAsBytes(mac);
char macaddress[20];
formatMAC(macread, macaddress);
return String(macaddress);
}
uint8_t * NetworkMacAddressAsBytes(uint8_t* mac) {
#ifdef HAS_ETHERNET
if(active_network_medium == NetworkMedium_t::Ethernet) {
return ETHMacAddress(mac);
}
#endif
return WiFi.macAddress(mac);
MAC_address mac;
WiFi.macAddress(mac.mac);
return mac;
}
String NetworkGetHostname() {
@@ -190,19 +173,15 @@ String createRFCCompliantHostname(const String& oldString) {
}
String WifiSoftAPmacAddress() {
uint8_t mac[] = { 0, 0, 0, 0, 0, 0 };
uint8_t *macread = WiFi.softAPmacAddress(mac);
char macaddress[20];
formatMAC(macread, macaddress);
return String(macaddress);
MAC_address mac;
WiFi.softAPmacAddress(mac.mac);
return mac.toString();
}
String WifiSTAmacAddress() {
uint8_t mac[] = { 0, 0, 0, 0, 0, 0 };
uint8_t *macread = WiFi.macAddress(mac);
char macaddress[20];
formatMAC(macread, macaddress);
return String(macaddress);
MAC_address mac;
WiFi.macAddress(mac.mac);
return mac.toString();
}
void CheckRunningServices() {
+3 -2
View File
@@ -6,6 +6,8 @@
#ifndef NETWORK_H
#define NETWORK_H
#include "../DataStructs/MAC_address.h"
void setNetworkMedium(NetworkMedium_t medium);
void NetworkConnectRelaxed();
@@ -14,8 +16,7 @@ IPAddress NetworkLocalIP();
IPAddress NetworkSubnetMask();
IPAddress NetworkGatewayIP();
IPAddress NetworkDnsIP (uint8_t dns_no);
uint8_t * NetworkMacAddressAsBytes(uint8_t* mac);
String NetworkMacAddress();
MAC_address NetworkMacAddress();
String NetworkGetHostNameFromSettings(bool force_add_unitnr = false);
String NetworkGetHostname();
String NetworkCreateRFCCompliantHostname(bool force_add_unitnr = false);
+171 -14
View File
@@ -21,7 +21,132 @@
#include "../Helpers/StringConverter.h"
#include "../Helpers/StringGenerator_WiFi.h"
// FIXME TD-er: Cleanup of WiFi code
#ifdef ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
bool ESPEasyWiFi_t::begin() {
return true;
}
void ESPEasyWiFi_t::end() {
}
void ESPEasyWiFi_t::loop() {
switch (_state) {
case WiFiState_e::OFF:
break;
case WiFiState_e::AP_only:
break;
case WiFiState_e::ErrorRecovery:
// Wait for timeout to expire
// Start again from scratch
break;
case WiFiState_e::STA_Scanning:
case WiFiState_e::STA_AP_Scanning:
// Check if scanning is finished
// When scanning per channel, call for scanning next channel
break;
case WiFiState_e::STA_Connecting:
case WiFiState_e::STA_Reconnecting:
// Check if (re)connecting has finished
break;
case WiFiState_e::STA_Connected:
// Check if still connected
// Reconnect if not.
// Else mark last timestamp seen as connected
break;
}
{
// Check if we need to start AP
// Flag captive portal in webserver and/or whether we might be in setup mode
}
#ifdef USE_IMPROV
{
// Check for Improv mode.
}
#endif
}
IPAddress ESPEasyWiFi_t::getIP() const {
IPAddress res;
return res;
}
void ESPEasyWiFi_t::disconnect() {
}
void ESPEasyWiFi_t::checkConnectProgress() {
}
void ESPEasyWiFi_t::startScanning() {
_state = WiFiState_e::STA_Scanning;
WifiScan(true);
_last_state_change.setNow();
}
bool ESPEasyWiFi_t::connectSTA() {
if (!WiFi_AP_Candidates.hasKnownCredentials()) {
if (!WiFiEventData.warnedNoValidWiFiSettings) {
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid wifi settings"));
WiFiEventData.warnedNoValidWiFiSettings = true;
}
WiFiEventData.last_wifi_connect_attempt_moment.clear();
WiFiEventData.wifi_connect_attempt = 1;
WiFiEventData.wifiConnectAttemptNeeded = false;
// No need to wait longer to start AP mode.
if (!Settings.DoNotStartAP()) {
setAP(true);
}
return false;
}
WiFiEventData.warnedNoValidWiFiSettings = false;
setSTA(true);
char hostname[40];
safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname));
#if defined(ESP8266)
wifi_station_set_hostname(hostname);
#endif // if defined(ESP8266)
#if defined(ESP32)
WiFi.setHostname(hostname);
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
#endif // if defined(ESP32)
setConnectionSpeed();
setupStaticIPconfig();
// Start the process of connecting or starting AP
if (WiFi_AP_Candidates.getNext(true)) {
// Try to connect to AP
} else {
// No (known) AP, start scanning
startScanning();
}
return true;
}
#endif // ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
// ********************************************************************************
@@ -98,7 +223,7 @@ bool WiFiConnected() {
if (WiFiEventData.unprocessedWifiEvents()) { return false; }
bool wifi_isconnected = false;
bool wifi_isconnected = WiFi.isConnected();
#ifdef ESP8266
// Perform check on SDK function, see: https://github.com/esp8266/Arduino/issues/7432
station_status_t status = wifi_station_get_connect_status();
@@ -113,21 +238,12 @@ bool WiFiConnected() {
break;
case STATION_IDLE:
case STATION_CONNECTING:
wifi_isconnected = WiFiEventData.WiFiServicesInitialized();
break;
default:
wifi_isconnected = false;
break;
}
#endif
#ifdef ESP32
if (WiFi.isConnected()) {
wifi_isconnected = true;
}
#endif
if (recursiveCall) return wifi_isconnected;
@@ -205,6 +321,31 @@ void WiFiConnectRelaxed() {
// Scan is still active, so do not yet connect.
return;
}
if (WiFiEventData.unprocessedWifiEvents()) {
handle_unprocessedNetworkEvents();
}
if (WiFiEventData.unprocessedWifiEvents()) {
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
String log = F("WiFi : Connecting not possible, unprocessed WiFi events: ");
if (!WiFiEventData.processedConnect) {
log += F(" conn");
}
if (!WiFiEventData.processedDisconnect) {
log += F(" disconn");
}
if (!WiFiEventData.processedGotIP) {
log += F(" gotIP");
}
if (!WiFiEventData.processedDHCPTimeout) {
log += F(" DHCP_t/o");
}
addLog(LOG_LEVEL_ERROR, log);
}
return;
}
if (WiFiEventData.unprocessedWifiEvents()) {
// Still need to process WiFi events
return;
@@ -236,6 +377,8 @@ void AttemptWiFiConnect() {
}
}
WiFiEventData.markWiFiTurnOn();
if (WiFi_AP_Candidates.getNext(WiFiScanAllowed())) {
const WiFi_AP_Candidate& candidate = WiFi_AP_Candidates.getCurrent();
@@ -248,6 +391,7 @@ void AttemptWiFiConnect() {
}
WiFiEventData.markWiFiBegin();
if (prepareWiFi()) {
RTC.clearLastWiFi();
float tx_pwr = 0; // Will be set higher based on RSSI when needed.
// FIXME TD-er: Must check WiFiEventData.wifi_connect_attempt to increase TX power
if (Settings.UseMaxTXpowerForSending()) {
@@ -255,7 +399,7 @@ void AttemptWiFiConnect() {
}
SetWiFiTXpower(tx_pwr, candidate.rssi);
if (candidate.allowQuickConnect()) {
WiFi.begin(candidate.ssid.c_str(), candidate.key.c_str(), candidate.channel, candidate.bssid);
WiFi.begin(candidate.ssid.c_str(), candidate.key.c_str(), candidate.channel, candidate.bssid.mac);
} else {
WiFi.begin(candidate.ssid.c_str(), candidate.key.c_str());
}
@@ -602,8 +746,15 @@ void WifiDisconnect()
WiFi.disconnect();
WiFi.removeEvent(wm_event_id);
#else // if defined(ESP32)
// Only call disconnect when STA is active
if (WifiIsSTA(WiFiMode())) {
wifi_station_disconnect();
}
station_config conf{};
memset(&conf, 0, sizeof(conf));
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
wifi_station_set_config_current(&conf);
ETS_UART_INTR_ENABLE();
#endif // if defined(ESP32)
WiFiEventData.setWiFiDisconnected();
@@ -897,6 +1048,8 @@ void setWifiMode(WiFiMode_t wifimode) {
}
if (cur_mode == WIFI_OFF) {
WiFiEventData.markWiFiTurnOn();
#if defined(ESP32)
esp_wifi_set_ps(WIFI_PS_NONE);
#endif
@@ -925,6 +1078,7 @@ void setWifiMode(WiFiMode_t wifimode) {
if (wifimode == WIFI_OFF) {
WiFiEventData.markWiFiTurnOn();
delay(100);
#if defined(ESP32)
esp_wifi_set_ps(WIFI_PS_MAX_MODEM);
@@ -970,8 +1124,11 @@ void setWifiMode(WiFiMode_t wifimode) {
SetWiFiTXpower();
if (WifiIsSTA(wifimode)) {
if (!WiFi.getAutoConnect()) {
WiFi.setAutoConnect(true);
if (WiFi.getAutoConnect()) {
WiFi.setAutoConnect(false);
}
if (WiFi.getAutoReconnect()) {
WiFi.setAutoReconnect(false);
}
}
delay(100); // Must allow for some time to init.
+81
View File
@@ -13,6 +13,9 @@
#endif // if defined(ESP32)
#include "../DataTypes/WiFiConnectionProtocol.h"
#include "../DataStructs/WiFi_AP_Candidate.h"
#include "../Helpers/LongTermTimer.h"
#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds
#define WIFI_AP_OFF_TIMER_DURATION 300000 // in milliSeconds
@@ -21,6 +24,84 @@
#define WIFI_SCAN_INTERVAL_AP_USED 125000 // in milliSeconds
#define WIFI_SCAN_INTERVAL_MINIMAL 60000 // in milliSeconds
#ifdef ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
enum class WiFiState_e {
// WiFi radio off
OFF,
// Only running in AP mode
AP_only,
// WiFi was in some kind of error state, waiting period
ErrorRecovery,
// STA mode + scanning
STA_Scanning,
// STA+AP mode + scanning,
// needs some careful handling to prevent disconnecting the connected stations
STA_AP_Scanning,
// Connecting to an AP
STA_Connecting,
// Reconnecting to an AP
// May need to handle some specific disconnect reasons differently from connecting for the first time.
STA_Reconnecting,
// Connected to an AP
STA_Connected
};
class ESPEasyWiFi_t {
public:
// Start the process of connecting or start AP, depending on the existing configuration.
bool begin();
// Terminate WiFi activity
void end();
// Process the state machine for managing WiFi connection
void loop();
WiFiState_e getState() const { return _state; }
// Get the IP-address in this order:
// - STA interface if connected,
// - AP interface if active
// - 0.0.0.0 if neither connected nor active.
IPAddress getIP() const;
void disconnect();
private:
// Handle timeouts + start of AP mode
void checkConnectProgress();
// Check to see if we already have some AP to connect to.
void checkScanningProgress();
void startScanning();
bool connectSTA();
WiFi_AP_Candidate _active_sta;
WiFi_AP_Candidate _AP_conf;
String _last_ssid;
MAC_address _last_bssid;
uint8_t _last_channel = 0;
WiFiState_e _state = WiFiState_e::OFF;
LongTermTimer _last_state_change;
LongTermTimer _last_seen_connected;
};
#endif // ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
bool WiFiConnected();
void WiFiConnectRelaxed();
void AttemptWiFiConnect();
@@ -131,7 +131,9 @@ void handle_unprocessedNetworkEvents()
if (WiFiEventData.WiFiServicesInitialized() != should_be_initialized)
{
if (!WiFiEventData.WiFiServicesInitialized()) {
markWiFi_services_initialized();
WiFiEventData.processedDHCPTimeout = true; // FIXME TD-er: Find out when this happens (happens on ESP32 sometimes)
WiFiEventData.setWiFiServicesInitialized();
CheckRunningServices();
}
}
@@ -203,9 +205,16 @@ void handle_unprocessedNetworkEvents()
// These functions are called from Setup() or Loop() and thus may call delay() or yield()
// ********************************************************************************
void processDisconnect() {
if (WiFiEventData.processingDisconnect.isSet()) {
if (WiFiEventData.processingDisconnect.millisPassedSince() > 5000) {
WiFiEventData.processingDisconnect.clear();
}
}
if (WiFiEventData.processedDisconnect ||
WiFiEventData.processingDisconnect) { return; }
WiFiEventData.processingDisconnect = true;
WiFiEventData.processingDisconnect.isSet()) { return; }
WiFiEventData.processingDisconnect.setNow();
WiFiEventData.setWiFiDisconnected();
WiFiEventData.wifiConnectAttemptNeeded = true;
delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424
@@ -248,7 +257,7 @@ void processDisconnect() {
}
logConnectionStatus();
WiFiEventData.processedDisconnect = true;
WiFiEventData.processingDisconnect = false;
WiFiEventData.processingDisconnect.clear();
}
void processConnect() {
@@ -432,7 +441,7 @@ void processDisconnectAPmode() {
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
const int nrStationsConnected = WiFi.softAPgetStationNum();
String log = F("AP Mode: Client disconnected: ");
log += formatMAC(WiFiEventData.lastMacDisconnectedAPmode);
log += WiFiEventData.lastMacDisconnectedAPmode.toString();
log += F(" Connected devices: ");
log += nrStationsConnected;
addLog(LOG_LEVEL_INFO, log);
@@ -448,7 +457,7 @@ void processConnectAPmode() {
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("AP Mode: Client connected: ");
log += formatMAC(WiFiEventData.lastMacConnectedAPmode);
log += WiFiEventData.lastMacConnectedAPmode.toString();
log += F(" Connected devices: ");
log += WiFi.softAPgetStationNum();
addLog(LOG_LEVEL_INFO, log);
@@ -518,56 +527,7 @@ void processScanDone() {
}
void markWiFi_services_initialized() {
// Check to see if the WiFi status may be out of sync.
bool missedEvent = false;
if (WiFi.isConnected() != WiFiEventData.WiFiServicesInitialized()) {
// Apparently we may have missed some WiFi events.
if (WiFi.isConnected()) {
if (WiFiEventData.WiFiConnected() == 0) {
#ifndef BUILD_NO_DEBUG
addLog(LOG_LEVEL_DEBUG, F("WiFi : Force 'WiFi Connected' event"));
#endif
WiFiEventData.processedConnect = false;
missedEvent = true;
}
} else {
if (WiFiEventData.WiFiConnected()) {
#ifndef BUILD_NO_DEBUG
addLog(LOG_LEVEL_DEBUG, F("WiFi : Force 'WiFi Disconnected' event"));
#endif
WiFiEventData.processedDisconnect = false;
missedEvent = true;
}
}
}
bool hasIP = hasIPaddr();
if (hasIP != WiFiEventData.WiFiGotIP()) {
// Apparently we did miss some WiFi events.
if (hasIP) {
#ifndef BUILD_NO_DEBUG
addLog(LOG_LEVEL_DEBUG, F("WiFi : Force 'WiFi Got IP' event"));
#endif
WiFiEventData.processedGotIP = false;
missedEvent = true;
} else {
// FIXME TD-er: What to do here, as we don't get events when loosing IP address
}
}
if (missedEvent) {
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String log = F("WiFi : Missed WiFi event. Status: ");
log += ESPeasyWifiStatusToString();
addLog(LOG_LEVEL_DEBUG, log);
}
if (checkAndResetWiFi()) {
return;
}
}
WiFiEventData.processedDHCPTimeout = true; // FIXME TD-er: Find out when this happens (happens on ESP32 sometimes)
WiFiEventData.setWiFiServicesInitialized();
CheckRunningServices();
}
#ifdef HAS_ETHERNET
@@ -608,7 +568,7 @@ void processEthernetGotIP() {
String log;
log.reserve(160);
log = F("ETH MAC: ");
log += NetworkMacAddress();
log += NetworkMacAddress().toString();
log += ' ';
if (useStaticIP()) {
log += F("Static");
@@ -11,7 +11,6 @@ void processDisconnectAPmode();
void processConnectAPmode();
void processDisableAPmode();
void processScanDone();
void markWiFi_services_initialized();
#ifdef HAS_ETHERNET
void processEthernetConnected();
@@ -62,9 +62,7 @@ void backgroundtasks()
web_server.handleClient();
}
if (networkConnected) {
checkUDP();
}
checkUDP();
}
#ifdef FEATURE_DNS_SERVER
@@ -77,7 +75,7 @@ void backgroundtasks()
#ifdef FEATURE_ARDUINO_OTA
if (Settings.ArduinoOTAEnable && networkConnected) {
if (Settings.ArduinoOTAEnable) {
ArduinoOTA.handle();
}
@@ -86,9 +84,7 @@ void backgroundtasks()
{
delay(0);
if (NetworkConnected()) {
ArduinoOTA.handle();
}
ArduinoOTA.handle();
}
#endif // ifdef FEATURE_ARDUINO_OTA
+5
View File
@@ -0,0 +1,5 @@
#include "../Globals/ESPEasyWiFi.h"
#ifdef ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
ESPEasyWiFi_t ESPEasyWiFi;
#endif // ifdef ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
+14
View File
@@ -0,0 +1,14 @@
#ifndef GLOBALS_ESPEASYWIFI_H
#define GLOBALS_ESPEASYWIFI_H
#include "../ESPEasyCore/ESPEasyWifi.h"
#include "../../ESPEasy_common.h"
#ifdef ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
extern ESPEasyWiFi_t ESPEasyWiFi;
#endif // ifdef ESPEASY_WIFI_CLEANUP_WORK_IN_PROGRESS
#endif // ifndef GLOBALS_ESPEASYWIFI_H
+1 -1
View File
@@ -3,7 +3,7 @@
#include <Arduino.h>
#include "ESPEasy_time_calc.h"
#include "../Helpers/ESPEasy_time_calc.h"
class LongTermTimer {
public:
+19 -15
View File
@@ -239,11 +239,11 @@ void checkUDP()
}
byte unit = packetBuffer[12];
#ifndef BUILD_NO_DEBUG
byte mac[6];
MAC_address mac;
byte ip[4];
for (byte x = 0; x < 6; x++) {
mac[x] = packetBuffer[x + 2];
mac.mac[x] = packetBuffer[x + 2];
}
for (byte x = 0; x < 4; x++) {
@@ -279,10 +279,13 @@ void checkUDP()
#ifndef BUILD_NO_DEBUG
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
char macaddress[20];
formatMAC(mac, macaddress);
char log[80] = { 0 };
sprintf_P(log, PSTR("UDP : %s,%s,%u"), macaddress, formatIP(ip).c_str(), unit);
String log;
log += F("UDP : ");
log += mac.toString();
log += ',';
log += formatIP(ip);
log += ',';
log += unit;
addLog(LOG_LEVEL_DEBUG_MORE, log);
}
#endif // ifndef BUILD_NO_DEBUG
@@ -477,21 +480,22 @@ void sendSysInfoUDP(byte repeats)
for (byte counter = 0; counter < repeats; counter++)
{
uint8_t mac[] = { 0, 0, 0, 0, 0, 0 };
uint8_t *macread = NetworkMacAddressAsBytes(mac);
byte data[80] = { 0 };
data[0] = 255;
data[1] = 1;
for (byte x = 0; x < 6; x++) {
data[x + 2] = macread[x];
{
const MAC_address macread = NetworkMacAddress();
for (byte x = 0; x < 6; x++) {
data[x + 2] = macread.mac[x];
}
}
IPAddress ip = NetworkLocalIP();
for (byte x = 0; x < 4; x++) {
data[x + 8] = ip[x];
{
const IPAddress ip = NetworkLocalIP();
for (byte x = 0; x < 4; x++) {
data[x + 8] = ip[x];
}
}
data[12] = Settings.Unit;
data[13] = lowByte(Settings.Build);
-11
View File
@@ -110,17 +110,6 @@ String formatIP(const IPAddress& ip) {
#endif // if defined(ARDUINO_ESP8266_RELEASE_2_3_0)
}
void formatMAC(const uint8_t *mac, char (& strMAC)[20]) {
sprintf_P(strMAC, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
ZERO_TERMINATE(strMAC);
}
String formatMAC(const uint8_t *mac) {
char str[20] = { 0 };
formatMAC(mac, str);
return String(str);
}
/********************************************************************************************\
Handling HEX strings
-4
View File
@@ -42,10 +42,6 @@ bool str2ip(const char *string,
String formatIP(const IPAddress& ip);
void formatMAC(const uint8_t * mac, char (& strMAC)[20]);
String formatMAC(const uint8_t *mac);
/********************************************************************************************\
Handling HEX strings
+28 -20
View File
@@ -22,14 +22,19 @@ switch (encryptionType) {
break;
}
return F("Unknown");
return F("-");
}
#ifndef ESP32
String SDKwifiStatusToString(uint8_t sdk_wifistatus) {
#ifdef LIMIT_BUILD_SIZE
#ifdef ESP8266
#ifdef LIMIT_BUILD_SIZE
String SDKwifiStatusToString(uint8_t sdk_wifistatus)
{
return String(sdk_wifistatus);
#else
}
#else
const __FlashStringHelper * SDKwifiStatusToString(uint8_t sdk_wifistatus)
{
switch (sdk_wifistatus) {
case STATION_IDLE: return F("STATION_IDLE");
case STATION_CONNECTING: return F("STATION_CONNECTING");
@@ -39,28 +44,31 @@ String SDKwifiStatusToString(uint8_t sdk_wifistatus) {
case STATION_GOT_IP: return F("STATION_GOT_IP");
}
return F("Unknown");
#endif
}
#endif
#endif
#endif // ifndef ESP32
const __FlashStringHelper * ArduinoWifiStatusToFlashString(uint8_t arduino_corelib_wifistatus) {
switch (arduino_corelib_wifistatus) {
case WL_NO_SHIELD: return F("WL_NO_SHIELD");
case WL_IDLE_STATUS: return F("WL_IDLE_STATUS");
case WL_NO_SSID_AVAIL: return F("WL_NO_SSID_AVAIL");
case WL_SCAN_COMPLETED: return F("WL_SCAN_COMPLETED");
case WL_CONNECTED: return F("WL_CONNECTED");
case WL_CONNECT_FAILED: return F("WL_CONNECT_FAILED");
case WL_CONNECTION_LOST: return F("WL_CONNECTION_LOST");
case WL_DISCONNECTED: return F("WL_DISCONNECTED");
}
return F("-");
}
String ArduinoWifiStatusToString(uint8_t arduino_corelib_wifistatus) {
#ifdef LIMIT_BUILD_SIZE
return String(arduino_corelib_wifistatus);
#else
String log;
switch (arduino_corelib_wifistatus) {
case WL_NO_SHIELD: log += F("WL_NO_SHIELD"); break;
case WL_IDLE_STATUS: log += F("WL_IDLE_STATUS"); break;
case WL_NO_SSID_AVAIL: log += F("WL_NO_SSID_AVAIL"); break;
case WL_SCAN_COMPLETED: log += F("WL_SCAN_COMPLETED"); break;
case WL_CONNECTED: log += F("WL_CONNECTED"); break;
case WL_CONNECT_FAILED: log += F("WL_CONNECT_FAILED"); break;
case WL_CONNECTION_LOST: log += F("WL_CONNECTION_LOST"); break;
case WL_DISCONNECTED: log += F("WL_DISCONNECTED"); break;
default: log += arduino_corelib_wifistatus; break;
}
String log = ArduinoWifiStatusToFlashString(arduino_corelib_wifistatus);
log += ' ';
log += arduino_corelib_wifistatus;
return log;
#endif
}
+5 -1
View File
@@ -5,8 +5,12 @@
const __FlashStringHelper * WiFi_encryptionType(byte encryptionType);
#ifndef ESP32
#ifdef ESP8266
#ifdef LIMIT_BUILD_SIZE
String SDKwifiStatusToString(uint8_t sdk_wifistatus);
#else
const __FlashStringHelper * SDKwifiStatusToString(uint8_t sdk_wifistatus);
#endif
#endif
String ArduinoWifiStatusToString(uint8_t arduino_corelib_wifistatus);
+1 -1
View File
@@ -337,7 +337,7 @@ String getValue(LabelType::Enum label) {
getValue(LabelType::ETH_IP_SUBNET));
case LabelType::ETH_IP_GATEWAY: return NetworkGatewayIP().toString();
case LabelType::ETH_IP_DNS: return NetworkDnsIP(0).toString();
case LabelType::ETH_MAC: return NetworkMacAddress();
case LabelType::ETH_MAC: return NetworkMacAddress().toString();
case LabelType::ETH_DUPLEX: return EthLinkUp() ? (EthFullDuplex() ? F("Full Duplex") : F("Half Duplex")) : F("Link Down");
case LabelType::ETH_SPEED: return EthLinkUp() ? getEthSpeed() : F("Link Down");
case LabelType::ETH_STATE: return EthLinkUp() ? F("Link Up") : F("Link Down");
+1 -1
View File
@@ -90,7 +90,7 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode)
switch (enumval)
{
case BOOT_CAUSE: value = String(lastBootCause); break; // Integer value to be used in rules
case BSSID: value = String((WiFiEventData.WiFiDisconnected()) ? F("00:00:00:00:00:00") : WiFi.BSSIDstr()); break;
case BSSID: value = String((WiFiEventData.WiFiDisconnected()) ? MAC_address().toString() : WiFi.BSSIDstr()); break;
case CR: value = "\r"; break;
case IP: value = getValue(LabelType::IP_ADDRESS); break;
case IP4: value = String( (int) NetworkLocalIP()[3] ); break; // 4th IP octet
+12 -13
View File
@@ -152,18 +152,6 @@ bool WiFi_AP_CandidatesList::getNext(bool scanAllowed) {
}
}
if (currentCandidate.usable()) {
// Store in RTC
RTC.lastWiFiChannel = currentCandidate.channel;
for (byte i = 0; i < 6; ++i) {
RTC.lastBSSID[i] = currentCandidate.bssid[i];
}
RTC.lastWiFiSettingsIndex = currentCandidate.index;
}
if (mustPop) {
known_it = known.begin();
if (!candidates.empty()) {
@@ -202,6 +190,13 @@ void WiFi_AP_CandidatesList::markCurrentConnectionStable() {
}
}
}
if (currentCandidate.usable()) {
// Store in RTC
RTC.lastWiFiChannel = currentCandidate.channel;
currentCandidate.bssid.get(RTC.lastBSSID);
RTC.lastWiFiSettingsIndex = currentCandidate.index;
}
candidates.clear();
addFromRTC(); // Store the current one from RTC as the first candidate for a reconnect.
}
@@ -307,9 +302,13 @@ void WiFi_AP_CandidatesList::addFromRTC() {
}
WiFi_AP_Candidate fromRTC(RTC.lastWiFiSettingsIndex, ssid, key);
fromRTC.setBSSID(RTC.lastBSSID);
fromRTC.bssid = RTC.lastBSSID;
fromRTC.channel = RTC.lastWiFiChannel;
if (!fromRTC.usable()) {
return;
}
if (candidates.size() > 0 && candidates.front().ssid.equals(fromRTC.ssid)) {
// Front candidate was already from RTC.
candidates.pop_front();
+1
View File
@@ -5,6 +5,7 @@
#include "../WebServer/WebServer.h"
#include "../WebServer/HTML_wrappers.h"
#include "../WebServer/JSON.h"
#include "../WebServer/Markup.h"
#include "../WebServer/Markup_Buttons.h"
#include "../WebServer/Markup_Forms.h"
+1 -1
View File
@@ -40,7 +40,7 @@ void handle_wifiscanner_json() {
stream_next_json_object_value(F("auth"), authType);
}
stream_next_json_object_value(getLabel(LabelType::SSID), it->ssid);
stream_next_json_object_value(getLabel(LabelType::BSSID), formatMAC(it->bssid));
stream_next_json_object_value(getLabel(LabelType::BSSID), it->bssid.toString());
stream_next_json_object_value(getLabel(LabelType::CHANNEL), String(it->channel));
stream_last_json_object_value(getLabel(LabelType::WIFI_RSSI), String(it->rssi));
}