#include "NetworkConnection.h" using namespace NetworkUtils; void NetworkConnection::setup(bool useDhcp) { setUseDhcp(useDhcp); #if defined(ARDUINO_ARCH_ESP8266) wifi_set_event_handler_cb(NetworkConnection::onEvent); #elif defined(ARDUINO_ARCH_ESP32) WiFi.onEvent(NetworkConnection::onEvent); #endif } void NetworkConnection::reset() { status = Status::NONE; rawDisconnectReason = 0; disconnectReason = DisconnectReason::NONE; } void NetworkConnection::setUseDhcp(bool value) { useDhcp = value; } NetworkConnection::Status NetworkConnection::getStatus() { return status; } NetworkConnection::DisconnectReason NetworkConnection::getDisconnectReason() { return disconnectReason; } #if defined(ARDUINO_ARCH_ESP8266) void NetworkConnection::onEvent(System_Event_t *event) { switch (event->event) { case EVENT_STAMODE_CONNECTED: status = useDhcp ? Status::CONNECTING : Status::CONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::NONE; break; case EVENT_STAMODE_GOT_IP: status = Status::CONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::NONE; break; case EVENT_STAMODE_DHCP_TIMEOUT: status = Status::DISCONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::DHCP_TIMEOUT; break; case EVENT_STAMODE_DISCONNECTED: status = Status::DISCONNECTED; rawDisconnectReason = event->event_info.disconnected.reason; disconnectReason = convertDisconnectReason(event->event_info.disconnected.reason); // https://github.com/esp8266/Arduino/blob/d5eb265f78bff9deb7063d10030a02d021c8c66c/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L231 if ((wifi_station_get_connect_status() == STATION_GOT_IP) && !wifi_station_get_reconnect_policy()) { wifi_station_disconnect(); } break; case EVENT_STAMODE_AUTHMODE_CHANGE: // https://github.com/esp8266/Arduino/blob/d5eb265f78bff9deb7063d10030a02d021c8c66c/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L241 { auto& src = event->event_info.auth_change; if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { status = Status::DISCONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::OTHER; wifi_station_disconnect(); } } break; default: break; } } #elif defined(ARDUINO_ARCH_ESP32) void NetworkConnection::onEvent(WiFiEvent_t event, WiFiEventInfo_t info) { switch (event) { case ARDUINO_EVENT_WIFI_STA_CONNECTED: status = useDhcp ? Status::CONNECTING : Status::CONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::NONE; break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP6: status = Status::CONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::NONE; break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: status = Status::DISCONNECTED; rawDisconnectReason = 0; disconnectReason = DisconnectReason::DHCP_TIMEOUT; break; case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: status = Status::DISCONNECTED; rawDisconnectReason = info.wifi_sta_disconnected.reason; disconnectReason = convertDisconnectReason(info.wifi_sta_disconnected.reason); break; default: break; } } #endif NetworkConnection::DisconnectReason NetworkConnection::convertDisconnectReason(uint8_t reason) { switch (reason) { #if defined(ARDUINO_ARCH_ESP8266) case REASON_BEACON_TIMEOUT: return DisconnectReason::BEACON_TIMEOUT; case REASON_NO_AP_FOUND: return DisconnectReason::NO_AP_FOUND; case REASON_AUTH_FAIL: return DisconnectReason::AUTH_FAIL; case REASON_ASSOC_FAIL: return DisconnectReason::ASSOC_FAIL; case REASON_HANDSHAKE_TIMEOUT: return DisconnectReason::HANDSHAKE_TIMEOUT; #elif defined(ARDUINO_ARCH_ESP32) case WIFI_REASON_BEACON_TIMEOUT: return DisconnectReason::BEACON_TIMEOUT; case WIFI_REASON_NO_AP_FOUND: return DisconnectReason::NO_AP_FOUND; case WIFI_REASON_AUTH_FAIL: return DisconnectReason::AUTH_FAIL; case WIFI_REASON_ASSOC_FAIL: return DisconnectReason::ASSOC_FAIL; case WIFI_REASON_HANDSHAKE_TIMEOUT: return DisconnectReason::HANDSHAKE_TIMEOUT; #endif default: return DisconnectReason::OTHER; } } bool NetworkConnection::useDhcp = false; NetworkConnection::Status NetworkConnection::status = Status::NONE; NetworkConnection::DisconnectReason NetworkConnection::disconnectReason = DisconnectReason::NONE; uint8_t NetworkConnection::rawDisconnectReason = 0;