From f2026f1e345970801084821d6e5f8f95a11fba47 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 26 Mar 2024 23:31:23 +0200 Subject: [PATCH] 3.0.0 Network Refactoring (#8760) * Create ESP_NetworkInterface class and have Ethernet extending it * Update CMakeLists.txt * Split networking from WiFi (H2 can now use Ethernet) Now all libs have been checked yet. More to do on WiFi side * Fix build errors * Guard WiFi classes and fix RMII ETH examples * Decouple network related libraries from WiFi * Fix examples and WiFiUpdate * Guard WiFiProv lib to compile only on WiFi chips * Add periman string for network and "fix" mdns on the first ETH * Revert back location of Client/Server/Udp in order to accept some PRs * Fix periman * Some fixes from merging master * Fix web server missing fs.h * Move Client, Server and Udp out of WiFi * More fixes * more fixes * Fix CMakekLists and rework lib menu dependencies * Fix CMake issues * move back WiFiClient to rebase with master * Update ETH_TLK110.ino * Move back WiFiClient * Update progress * Update WiFiGeneric.cpp * More fixes * Switch AP to the new interface * Cleanup * Rename AP methods * Add extra interface info for Printable * Rename IPv6 getters to clarify that they are returning LinkLocal address cc @sgryphon * Rename network classes cc @sgryphon * Update NetworkManager.h * Rename WiFi Server and UDP * Rename WiFiClient and WiFiClientSecure * Update CMakeLists.txt * Update on-push.sh * Rename Network library * Remove unnecessary guard * Get the correct interface MAC address for mDND Workstation service * Apply suggestions from code review Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> --------- Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> --- .github/scripts/on-push.sh | 4 +- CMakeLists.txt | 22 +- Kconfig.projbuild | 145 +- docs/en/api/wifi.rst | 2 +- .../ArduinoOTA/examples/BasicOTA/BasicOTA.ino | 2 +- libraries/ArduinoOTA/src/ArduinoOTA.cpp | 6 +- libraries/ArduinoOTA/src/ArduinoOTA.h | 6 +- libraries/DNSServer/src/DNSServer.cpp | 6 +- .../Camera/CameraWebServer/app_httpd.cpp | 3 +- .../mDNS_Web_Server/mDNS_Web_Server.ino | 6 +- libraries/ESPmDNS/src/ESPmDNS.cpp | 44 +- .../examples/ETH_LAN8720/ETH_LAN8720.ino | 10 +- .../examples/ETH_TLK110/ETH_TLK110.ino | 10 +- .../ETH_W5500_Arduino_SPI.ino | 8 +- .../ETH_W5500_IDF_SPI/ETH_W5500_IDF_SPI.ino | 8 +- libraries/Ethernet/src/ETH.cpp | 498 ++----- libraries/Ethernet/src/ETH.h | 54 +- .../BasicHttpsClient/BasicHttpsClient.ino | 8 +- .../StreamHttpClient/StreamHttpClient.ino | 2 +- libraries/HTTPClient/src/HTTPClient.cpp | 34 +- libraries/HTTPClient/src/HTTPClient.h | 16 +- .../examples/httpUpdate/httpUpdate.ino | 2 +- .../httpUpdateSPIFFS/httpUpdateSPIFFS.ino | 2 +- .../httpUpdateSecure/httpUpdateSecure.ino | 2 +- libraries/HTTPUpdate/src/HTTPUpdate.cpp | 18 +- libraries/HTTPUpdate/src/HTTPUpdate.h | 10 +- .../examples/WebUpdater/WebUpdater.ino | 2 +- libraries/NetBIOS/src/NetBIOS.cpp | 4 +- libraries/NetBIOS/src/NetBIOS.h | 2 +- libraries/Network/library.properties | 9 + libraries/Network/src/Network.h | 14 + .../src/NetworkClient.cpp} | 106 +- libraries/Network/src/NetworkClient.h | 113 ++ libraries/Network/src/NetworkEvents.cpp | 383 ++++++ libraries/Network/src/NetworkEvents.h | 169 +++ libraries/Network/src/NetworkInterface.cpp | 718 ++++++++++ libraries/Network/src/NetworkInterface.h | 99 ++ libraries/Network/src/NetworkManager.cpp | 177 +++ libraries/Network/src/NetworkManager.h | 28 + .../src/NetworkServer.cpp} | 30 +- libraries/Network/src/NetworkServer.h | 60 + .../src/NetworkUdp.cpp} | 46 +- libraries/Network/src/NetworkUdp.h | 77 ++ .../README.md | 38 +- .../WiFiClientInsecure}/.skip.esp32h2 | 0 .../WiFiClientInsecure/WiFiClientInsecure.ino | 11 +- .../examples/WiFiClientPSK}/.skip.esp32h2 | 0 .../examples/WiFiClientPSK/WiFiClientPSK.ino | 5 +- .../examples/WiFiClientSecure}/.skip.esp32h2 | 0 .../WiFiClientSecure/WiFiClientSecure.ino | 5 +- .../WiFiClientSecureEnterprise}/.skip.esp32h2 | 0 .../WiFiClientSecureEnterprise.ino | 4 +- .../.skip.esp32h2 | 0 .../WiFiClientSecureProtocolUpgrade.ino | 11 +- .../.skip.esp32h2 | 0 .../WiFiClientShowPeerCredentials.ino | 6 +- .../WiFiClientTrustOnFirstUse}/.skip.esp32h2 | 0 .../WiFiClientTrustOnFirstUse.ino | 5 +- .../keywords.txt | 4 +- .../library.properties | 2 +- .../src/NetworkClientSecure.cpp} | 82 +- .../src/NetworkClientSecure.h} | 26 +- .../src/WiFiClientSecure.h | 3 + .../src/ssl_client.cpp | 1 - .../src/ssl_client.h | 0 libraries/README.md | 4 +- .../AWS_S3_OTA_Update/AWS_S3_OTA_Update.ino | 2 +- .../HTTP_Client_AES_OTA_Update.ino | 8 +- .../HTTP_Server_AES_OTA_Update.ino | 2 +- .../AdvancedWebServer/AdvancedWebServer.ino | 2 +- .../examples/FSBrowser/FSBrowser.ino | 2 +- .../examples/HelloServer/HelloServer.ino | 2 +- .../MultiHomedServers/MultiHomedServers.ino | 2 +- .../examples/MultiHomedServers/README.md | 4 +- .../examples/PathArgServer/PathArgServer.ino | 2 +- .../examples/SDWebServer/SDWebServer.ino | 2 +- .../SimpleAuthentification.ino | 2 +- .../WebServer/examples/WebServer/README.md | 2 +- .../examples/WebServer/WebServer.ino | 1 + .../examples/WebUpdate/WebUpdate.ino | 2 +- libraries/WebServer/src/Parsing.cpp | 12 +- libraries/WebServer/src/WebServer.cpp | 6 +- libraries/WebServer/src/WebServer.h | 16 +- .../SimpleWiFiServer/SimpleWiFiServer.ino | 4 +- .../WiFiAccessPoint/WiFiAccessPoint.ino | 6 +- .../WiFiBlueToothSwitch.ino | 2 +- libraries/WiFi/examples/WiFiClient/README.md | 4 +- .../WiFi/examples/WiFiClient/WiFiClient.ino | 4 +- .../WiFiClientBasic/WiFiClientBasic.ino | 4 +- .../WiFi/examples/WiFiClientConnect/README.md | 2 +- .../WiFiClientEnterprise.ino | 2 +- .../WiFiClientStaticIP/WiFiClientStaticIP.ino | 4 +- libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino | 6 +- .../WiFiTelnetToSerial/WiFiTelnetToSerial.ino | 4 +- .../examples/WiFiUDPClient/WiFiUDPClient.ino | 4 +- libraries/WiFi/keywords.txt | 8 +- libraries/WiFi/src/AP.cpp | 340 +++++ libraries/WiFi/src/STA.cpp | 794 +++++++++++ libraries/WiFi/src/WiFi.cpp | 3 + libraries/WiFi/src/WiFi.h | 14 +- libraries/WiFi/src/WiFiAP.cpp | 283 +--- libraries/WiFi/src/WiFiAP.h | 49 +- libraries/WiFi/src/WiFiClient.h | 118 +- libraries/WiFi/src/WiFiGeneric.cpp | 1201 +++-------------- libraries/WiFi/src/WiFiGeneric.h | 143 +- libraries/WiFi/src/WiFiMulti.cpp | 3 + libraries/WiFi/src/WiFiMulti.h | 8 +- libraries/WiFi/src/WiFiSTA.cpp | 578 +------- libraries/WiFi/src/WiFiSTA.h | 116 +- libraries/WiFi/src/WiFiScan.cpp | 2 + libraries/WiFi/src/WiFiScan.h | 8 +- libraries/WiFi/src/WiFiServer.h | 65 +- libraries/WiFi/src/WiFiType.h | 7 +- libraries/WiFi/src/WiFiUdp.h | 80 +- .../.skip.esp32h2 | 0 .../WiFiClientTrustOnFirstUse/.skip.esp32h2 | 0 libraries/WiFiProv/src/WiFiProv.cpp | 5 + libraries/WiFiProv/src/WiFiProv.h | 8 +- package/package_esp32_index.template.json | 136 +- 119 files changed, 4103 insertions(+), 3153 deletions(-) create mode 100644 libraries/Network/library.properties create mode 100644 libraries/Network/src/Network.h rename libraries/{WiFi/src/WiFiClient.cpp => Network/src/NetworkClient.cpp} (85%) create mode 100644 libraries/Network/src/NetworkClient.h create mode 100644 libraries/Network/src/NetworkEvents.cpp create mode 100644 libraries/Network/src/NetworkEvents.h create mode 100644 libraries/Network/src/NetworkInterface.cpp create mode 100644 libraries/Network/src/NetworkInterface.h create mode 100644 libraries/Network/src/NetworkManager.cpp create mode 100644 libraries/Network/src/NetworkManager.h rename libraries/{WiFi/src/WiFiServer.cpp => Network/src/NetworkServer.cpp} (86%) create mode 100644 libraries/Network/src/NetworkServer.h rename libraries/{WiFi/src/WiFiUdp.cpp => Network/src/NetworkUdp.cpp} (91%) create mode 100644 libraries/Network/src/NetworkUdp.h rename libraries/{WiFiClientSecure => NetworkClientSecure}/README.md (83%) rename libraries/{Ethernet/examples/ETH_W5500_Arduino_SPI => NetworkClientSecure/examples/WiFiClientInsecure}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientInsecure/WiFiClientInsecure.ino (85%) rename libraries/{Ethernet/examples/ETH_W5500_IDF_SPI => NetworkClientSecure/examples/WiFiClientPSK}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientPSK/WiFiClientPSK.ino (96%) rename libraries/{WiFiClientSecure/examples/WiFiClientInsecure => NetworkClientSecure/examples/WiFiClientSecure}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientSecure/WiFiClientSecure.ino (99%) rename libraries/{WiFiClientSecure/examples/WiFiClientPSK => NetworkClientSecure/examples/WiFiClientSecureEnterprise}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino (99%) rename libraries/{WiFiClientSecure/examples/WiFiClientSecure => NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino (93%) rename libraries/{WiFiClientSecure/examples/WiFiClientSecureEnterprise => NetworkClientSecure/examples/WiFiClientShowPeerCredentials}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino (94%) rename libraries/{WiFiClientSecure/examples/WiFiClientSecureProtocolUpgrade => NetworkClientSecure/examples/WiFiClientTrustOnFirstUse}/.skip.esp32h2 (100%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino (99%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/keywords.txt (92%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/library.properties (92%) rename libraries/{WiFiClientSecure/src/WiFiClientSecure.cpp => NetworkClientSecure/src/NetworkClientSecure.cpp} (75%) rename libraries/{WiFiClientSecure/src/WiFiClientSecure.h => NetworkClientSecure/src/NetworkClientSecure.h} (89%) create mode 100644 libraries/NetworkClientSecure/src/WiFiClientSecure.h rename libraries/{WiFiClientSecure => NetworkClientSecure}/src/ssl_client.cpp (99%) rename libraries/{WiFiClientSecure => NetworkClientSecure}/src/ssl_client.h (100%) create mode 100644 libraries/WiFi/src/AP.cpp create mode 100644 libraries/WiFi/src/STA.cpp delete mode 100644 libraries/WiFiClientSecure/examples/WiFiClientShowPeerCredentials/.skip.esp32h2 delete mode 100644 libraries/WiFiClientSecure/examples/WiFiClientTrustOnFirstUse/.skip.esp32h2 diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index c3e32d06e83..bf311b93166 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -72,7 +72,7 @@ if [ "$BUILD_PIO" -eq 0 ]; then FQBN_ESP32H2="espressif:esp32:esp32h2:PartitionScheme=huge_app" SKETCHES_ESP32="\ - $ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ + $ARDUINO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ $ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\ $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\ $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ @@ -90,7 +90,7 @@ else BOARD="esp32dev" OPTIONS="board_build.partitions = huge_app.csv" build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" diff --git a/CMakeLists.txt b/CMakeLists.txt index 026990d264e..9aa2b55e2a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ set(ARDUINO_ALL_LIBRARIES Insights LittleFS NetBIOS + Network Preferences RainMaker SD_MMC @@ -104,7 +105,7 @@ set(ARDUINO_ALL_LIBRARIES Update USB WebServer - WiFiClientSecure + NetworkClientSecure WiFi WiFiProv Wire @@ -198,20 +199,27 @@ set(ARDUINO_LIBRARY_WebServer_SRCS libraries/WebServer/src/Parsing.cpp libraries/WebServer/src/detail/mimetable.cpp) -set(ARDUINO_LIBRARY_WiFiClientSecure_SRCS - libraries/WiFiClientSecure/src/ssl_client.cpp - libraries/WiFiClientSecure/src/WiFiClientSecure.cpp) +set(ARDUINO_LIBRARY_NetworkClientSecure_SRCS + libraries/NetworkClientSecure/src/ssl_client.cpp + libraries/NetworkClientSecure/src/NetworkClientSecure.cpp) + +set(ARDUINO_LIBRARY_Network_SRCS + libraries/Network/src/NetworkInterface.cpp + libraries/Network/src/NetworkEvents.cpp + libraries/Network/src/NetworkManager.cpp + libraries/Network/src/NetworkClient.cpp + libraries/Network/src/NetworkServer.cpp + libraries/Network/src/NetworkUdp.cpp) set(ARDUINO_LIBRARY_WiFi_SRCS libraries/WiFi/src/WiFiAP.cpp - libraries/WiFi/src/WiFiClient.cpp libraries/WiFi/src/WiFi.cpp libraries/WiFi/src/WiFiGeneric.cpp libraries/WiFi/src/WiFiMulti.cpp libraries/WiFi/src/WiFiScan.cpp - libraries/WiFi/src/WiFiServer.cpp libraries/WiFi/src/WiFiSTA.cpp - libraries/WiFi/src/WiFiUdp.cpp) + libraries/WiFi/src/STA.cpp + libraries/WiFi/src/AP.cpp) set(ARDUINO_LIBRARY_WiFiProv_SRCS libraries/WiFiProv/src/WiFiProv.cpp) diff --git a/Kconfig.projbuild b/Kconfig.projbuild index f7ee920819f..af772bd4618 100644 --- a/Kconfig.projbuild +++ b/Kconfig.projbuild @@ -256,38 +256,14 @@ config ARDUINO_SELECTIVE_COMPILATION bool "Include only specific Arduino libraries" default n -config ARDUINO_SELECTIVE_ArduinoOTA - bool "Enable ArduinoOTA" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi - select ARDUINO_SELECTIVE_ESPmDNS - default y - -config ARDUINO_SELECTIVE_AsyncUDP - bool "Enable AsyncUDP" - depends on ARDUINO_SELECTIVE_COMPILATION - default y - -config ARDUINO_SELECTIVE_AzureIoT - bool "Enable AzureIoT" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_HTTPClient - default y - -config ARDUINO_SELECTIVE_BLE - bool "Enable BLE" - depends on ARDUINO_SELECTIVE_COMPILATION - default y - -config ARDUINO_SELECTIVE_BluetoothSerial - bool "Enable BluetoothSerial" +config ARDUINO_SELECTIVE_SPI + bool "Enable SPI" depends on ARDUINO_SELECTIVE_COMPILATION default y -config ARDUINO_SELECTIVE_DNSServer - bool "Enable DNSServer" +config ARDUINO_SELECTIVE_Wire + bool "Enable Wire" depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi default y config ARDUINO_SELECTIVE_EEPROM @@ -295,21 +271,19 @@ config ARDUINO_SELECTIVE_EEPROM depends on ARDUINO_SELECTIVE_COMPILATION default y -config ARDUINO_SELECTIVE_ESP32 - bool "Enable ESP32" +config ARDUINO_SELECTIVE_Preferences + bool "Enable Preferences" depends on ARDUINO_SELECTIVE_COMPILATION default y -config ARDUINO_SELECTIVE_ESPmDNS - bool "Enable ESPmDNS" +config ARDUINO_SELECTIVE_Ticker + bool "Enable Ticker" depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi default y -config ARDUINO_SELECTIVE_FFat - bool "Enable FFat" +config ARDUINO_SELECTIVE_Update + bool "Enable Update" depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_FS default y config ARDUINO_SELECTIVE_FS @@ -317,96 +291,103 @@ config ARDUINO_SELECTIVE_FS depends on ARDUINO_SELECTIVE_COMPILATION default y -config ARDUINO_SELECTIVE_HTTPClient - bool "Enable HTTPClient" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi - select ARDUINO_SELECTIVE_WiFiClientSecure +config ARDUINO_SELECTIVE_SD + bool "Enable SD" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_FS default y -config ARDUINO_SELECTIVE_LITTLEFS - bool "Enable LITTLEFS" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_FS +config ARDUINO_SELECTIVE_SD_MMC + bool "Enable SD_MMC" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_FS default y -config ARDUINO_SELECTIVE_NetBIOS - bool "Enable NetBIOS" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi +config ARDUINO_SELECTIVE_SPIFFS + bool "Enable SPIFFS" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_FS default y -config ARDUINO_SELECTIVE_Preferences - bool "Enable Preferences" - depends on ARDUINO_SELECTIVE_COMPILATION +config ARDUINO_SELECTIVE_FFat + bool "Enable FFat" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_FS default y -config ARDUINO_SELECTIVE_SD - bool "Enable SD" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_FS +config ARDUINO_SELECTIVE_LITTLEFS + bool "Enable LITTLEFS" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_FS default y -config ARDUINO_SELECTIVE_SD_MMC - bool "Enable SD_MMC" +config ARDUINO_SELECTIVE_Networking + bool "Enable Networking" depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_FS default y -config ARDUINO_SELECTIVE_SimpleBLE - bool "Enable SimpleBLE" - depends on ARDUINO_SELECTIVE_COMPILATION +config ARDUINO_SELECTIVE_ArduinoOTA + bool "Enable ArduinoOTA" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking + select ARDUINO_SELECTIVE_ESPmDNS default y -config ARDUINO_SELECTIVE_SPI - bool "Enable SPI" - depends on ARDUINO_SELECTIVE_COMPILATION +config ARDUINO_SELECTIVE_AsyncUDP + bool "Enable AsyncUDP" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y -config ARDUINO_SELECTIVE_SPIFFS - bool "Enable SPIFFS" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_FS +config ARDUINO_SELECTIVE_DNSServer + bool "Enable DNSServer" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y -config ARDUINO_SELECTIVE_Ticker - bool "Enable Ticker" - depends on ARDUINO_SELECTIVE_COMPILATION +config ARDUINO_SELECTIVE_ESPmDNS + bool "Enable ESPmDNS" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y -config ARDUINO_SELECTIVE_Update - bool "Enable Update" - depends on ARDUINO_SELECTIVE_COMPILATION +config ARDUINO_SELECTIVE_HTTPClient + bool "Enable HTTPClient" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking + select ARDUINO_SELECTIVE_WiFiClientSecure + default y + +config ARDUINO_SELECTIVE_NetBIOS + bool "Enable NetBIOS" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y config ARDUINO_SELECTIVE_WebServer bool "Enable WebServer" - depends on ARDUINO_SELECTIVE_COMPILATION + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y select ARDUINO_SELECTIVE_FS config ARDUINO_SELECTIVE_WiFi bool "Enable WiFi" - depends on ARDUINO_SELECTIVE_COMPILATION + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y config ARDUINO_SELECTIVE_WiFiClientSecure bool "Enable WiFiClientSecure" - depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking default y config ARDUINO_SELECTIVE_WiFiProv bool "Enable WiFiProv" + depends on ARDUINO_SELECTIVE_COMPILATION && ARDUINO_SELECTIVE_Networking && ARDUINO_SELECTIVE_WiFi + default y + +config ARDUINO_SELECTIVE_BLE + bool "Enable BLE" depends on ARDUINO_SELECTIVE_COMPILATION - select ARDUINO_SELECTIVE_WiFi default y -config ARDUINO_SELECTIVE_Wire - bool "Enable Wire" +config ARDUINO_SELECTIVE_BluetoothSerial + bool "Enable BluetoothSerial" depends on ARDUINO_SELECTIVE_COMPILATION default y +config ARDUINO_SELECTIVE_SimpleBLE + bool "Enable SimpleBLE" + depends on ARDUINO_SELECTIVE_COMPILATION + default y endmenu diff --git a/docs/en/api/wifi.rst b/docs/en/api/wifi.rst index 010a11cfc1c..d18ac273686 100644 --- a/docs/en/api/wifi.rst +++ b/docs/en/api/wifi.rst @@ -345,7 +345,7 @@ Function to get the IPv6 address. .. code-block:: arduino - IPAddress softAPIPv6(); + IPAddress softAPlinkLocalIPv6(); The function will return the AP IPv6 address in ``IPAddress`` format. diff --git a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino index 83652495295..9492c8383f2 100644 --- a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino +++ b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino @@ -1,6 +1,6 @@ #include #include -#include +#include #include const char* ssid = ".........."; diff --git a/libraries/ArduinoOTA/src/ArduinoOTA.cpp b/libraries/ArduinoOTA/src/ArduinoOTA.cpp index ee9c3e95301..a0ca6075a17 100644 --- a/libraries/ArduinoOTA/src/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/src/ArduinoOTA.cpp @@ -2,8 +2,8 @@ #define LWIP_OPEN_SRC #endif #include -#include #include "ArduinoOTA.h" +#include "NetworkClient.h" #include "ESPmDNS.h" #include "MD5Builder.h" #include "Update.h" @@ -128,7 +128,7 @@ void ArduinoOTAClass::begin() { if (!_hostname.length()) { char tmp[20]; uint8_t mac[6]; - WiFi.macAddress(mac); + Network.macAddress(mac); sprintf(tmp, "esp32-%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); _hostname = tmp; } @@ -266,7 +266,7 @@ void ArduinoOTAClass::_runUpdate() { _progress_callback(0, _size); } - WiFiClient client; + NetworkClient client; if (!client.connect(_ota_ip, _ota_port)) { if (_error_callback) { _error_callback(OTA_CONNECT_ERROR); diff --git a/libraries/ArduinoOTA/src/ArduinoOTA.h b/libraries/ArduinoOTA/src/ArduinoOTA.h index cd0ba05f547..726722897f9 100644 --- a/libraries/ArduinoOTA/src/ArduinoOTA.h +++ b/libraries/ArduinoOTA/src/ArduinoOTA.h @@ -1,9 +1,9 @@ #ifndef __ARDUINO_OTA_H #define __ARDUINO_OTA_H -#include -#include +#include "Network.h" #include "Update.h" +#include #define INT_BUFFER_SIZE 16 @@ -86,7 +86,7 @@ class ArduinoOTAClass String _hostname; String _partition_label; String _nonce; - WiFiUDP _udp_ota; + NetworkUDP _udp_ota; bool _initialized; bool _rebootOnSuccess; bool _mdnsEnabled; diff --git a/libraries/DNSServer/src/DNSServer.cpp b/libraries/DNSServer/src/DNSServer.cpp index a8114733460..42b28a7d361 100644 --- a/libraries/DNSServer/src/DNSServer.cpp +++ b/libraries/DNSServer/src/DNSServer.cpp @@ -20,9 +20,13 @@ DNSServer::DNSServer(const String &domainName) : _port(DNS_DEFAULT_PORT), _ttl(h bool DNSServer::start(){ if (_resolvedIP.operator uint32_t() == 0){ // no address is set, try to obtain AP interface's IP +#if SOC_WIFI_SUPPORTED if (WiFi.getMode() & WIFI_AP){ _resolvedIP = WiFi.softAPIP(); - } else return false; // won't run if WiFi is not in AP mode + return true; + } +#endif + return false; // won't run if WiFi is not in AP mode } _udp.close(); diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index ff02152d101..64e3350fc33 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -26,13 +26,14 @@ // Face Detection will not work on boards without (or with disabled) PSRAM #ifdef BOARD_HAS_PSRAM -#define CONFIG_ESP_FACE_DETECT_ENABLED 1 // Face Recognition takes upward from 15 seconds per frame on chips other than ESP32S3 // Makes no sense to have it enabled for them #if CONFIG_IDF_TARGET_ESP32S3 #define CONFIG_ESP_FACE_RECOGNITION_ENABLED 1 +#define CONFIG_ESP_FACE_DETECT_ENABLED 1 #else #define CONFIG_ESP_FACE_RECOGNITION_ENABLED 0 +#define CONFIG_ESP_FACE_DETECT_ENABLED 0 #endif #else #define CONFIG_ESP_FACE_DETECT_ENABLED 0 diff --git a/libraries/ESPmDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino b/libraries/ESPmDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino index 0da791adc3e..e027cc2672e 100644 --- a/libraries/ESPmDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino +++ b/libraries/ESPmDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino @@ -18,13 +18,13 @@ #include #include -#include +#include const char* ssid = "............"; const char* password = ".............."; // TCP server at port 80 will respond to HTTP requests -WiFiServer server(80); +NetworkServer server(80); void setup(void) { @@ -69,7 +69,7 @@ void setup(void) void loop(void) { // Check if a client has connected - WiFiClient client = server.accept(); + NetworkClient client = server.accept(); if (!client) { return; } diff --git a/libraries/ESPmDNS/src/ESPmDNS.cpp b/libraries/ESPmDNS/src/ESPmDNS.cpp index 21d93aa4e2a..0e4f4b7b4a7 100644 --- a/libraries/ESPmDNS/src/ESPmDNS.cpp +++ b/libraries/ESPmDNS/src/ESPmDNS.cpp @@ -39,10 +39,9 @@ License (MIT license): #endif #include "ESPmDNS.h" -#include "WiFi.h" #include -#include "esp_wifi.h" -#include "esp_wifi_types.h" +#include "esp_mac.h" +#include "soc/soc_caps.h" // Add quotes around defined value #ifdef __IN_ECLIPSE__ @@ -52,6 +51,25 @@ License (MIT license): #define STR(tok) tok #endif +// static void addInterface(NetworkInterface * iface){ +// #if defined(CONFIG_MDNS_ADD_CUSTOM_NETIF) && !defined(CONFIG_MDNS_PREDEF_NETIF_STA) && !defined(CONFIG_MDNS_PREDEF_NETIF_ETH) +// /* Demonstration of adding a custom netif to mdns service, but we're adding the default example one, +// * so we must disable all predefined interfaces (PREDEF_NETIF_STA, AP and ETH) first +// */ +// ESP_ERROR_CHECK(mdns_register_netif(iface->netif())); +// /* It is not enough to just register the interface, we have to enable is manually. +// * This is typically performed in "GOT_IP" event handler, but we call it here directly +// * since the `EXAMPLE_INTERFACE` netif is connected already, to keep the example simple. +// */ +// ESP_ERROR_CHECK(mdns_netif_action(iface->netif(), MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_ENABLE_IP6)); +// ESP_ERROR_CHECK(mdns_netif_action(iface->netif(), MDNS_EVENT_ANNOUNCE_IP4 | MDNS_EVENT_ANNOUNCE_IP6)); + +// #if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES) +// ESP_ERROR_CHECK(mdns_netif_action(iface->netif(), MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP)); +// #endif +// #endif // CONFIG_MDNS_ADD_CUSTOM_NETIF +// } + // static void _on_sys_event(arduino_event_t *event){ // mdns_handle_system_event(NULL, event); // } @@ -115,7 +133,25 @@ void MDNSResponder::disableArduino(){ void MDNSResponder::enableWorkstation(esp_interface_t interface){ char winstance[21+_hostname.length()]; uint8_t mac[6]; - esp_wifi_get_mac((wifi_interface_t)interface, mac); + + esp_mac_type_t mtype = ESP_MAC_ETH; +#if SOC_WIFI_SUPPORTED + switch(interface){ + case ESP_IF_WIFI_STA: + mtype = ESP_MAC_WIFI_STA; + break; + case ESP_IF_WIFI_AP: + mtype = ESP_MAC_WIFI_SOFTAP; + break; + default: + break; + } +#endif + if(esp_read_mac(mac, mtype) != ESP_OK){ + log_e("Failed to read the MAC address"); + return; + } + sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", _hostname.c_str(), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); if(mdns_service_add(NULL, "_workstation", "_tcp", 9, NULL, 0)) { diff --git a/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino b/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino index e06e185cf9a..46c7c8bf686 100644 --- a/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino +++ b/libraries/Ethernet/examples/ETH_LAN8720/ETH_LAN8720.ino @@ -18,8 +18,8 @@ static bool eth_connected = false; -// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -void WiFiEvent(WiFiEvent_t event) +// WARNING: onEvent is called from a separate FreeRTOS task (thread)! +void onEvent(arduino_event_id_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: @@ -33,7 +33,7 @@ void WiFiEvent(WiFiEvent_t event) break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.println("ETH Got IP"); - ETH.printInfo(Serial); + Serial.println(ETH); eth_connected = true; break; case ARDUINO_EVENT_ETH_LOST_IP: @@ -58,7 +58,7 @@ void testClient(const char * host, uint16_t port) Serial.print("\nconnecting to "); Serial.println(host); - WiFiClient client; + NetworkClient client; if (!client.connect(host, port)) { Serial.println("connection failed"); return; @@ -76,7 +76,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. + Network.onEvent(onEvent); ETH.begin(); } diff --git a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino index 058e1c3f81f..a1ab4a5745f 100644 --- a/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino +++ b/libraries/Ethernet/examples/ETH_TLK110/ETH_TLK110.ino @@ -16,8 +16,8 @@ static bool eth_connected = false; -// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)! -void WiFiEvent(WiFiEvent_t event) +// WARNING: onEvent is called from a separate FreeRTOS task (thread)! +void onEvent(arduino_event_id_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: @@ -31,7 +31,7 @@ void WiFiEvent(WiFiEvent_t event) break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.println("ETH Got IP"); - ETH.printInfo(Serial); + Serial.println(ETH); eth_connected = true; break; case ARDUINO_EVENT_ETH_LOST_IP: @@ -56,7 +56,7 @@ void testClient(const char * host, uint16_t port) Serial.print("\nconnecting to "); Serial.println(host); - WiFiClient client; + NetworkClient client; if (!client.connect(host, port)) { Serial.println("connection failed"); return; @@ -74,7 +74,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread. + Network.onEvent(onEvent); // Will call onEvent() from another thread. ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_POWER, ETH_CLK_MODE); } diff --git a/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/ETH_W5500_Arduino_SPI.ino b/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/ETH_W5500_Arduino_SPI.ino index 48ac0e83c5c..da403c9f86d 100644 --- a/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/ETH_W5500_Arduino_SPI.ino +++ b/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/ETH_W5500_Arduino_SPI.ino @@ -49,9 +49,9 @@ void onEvent(arduino_event_id_t event, arduino_event_info_t info) break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif)); - ETH.printInfo(Serial); + Serial.println(ETH); #if USE_TWO_ETH_PORTS - ETH1.printInfo(Serial); + Serial.println(ETH1); #endif eth_connected = true; break; @@ -77,7 +77,7 @@ void testClient(const char * host, uint16_t port) Serial.print("\nconnecting to "); Serial.println(host); - WiFiClient client; + NetworkClient client; if (!client.connect(host, port)) { Serial.println("connection failed"); return; @@ -95,7 +95,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(onEvent); + Network.onEvent(onEvent); SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI); ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, SPI); diff --git a/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/ETH_W5500_IDF_SPI.ino b/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/ETH_W5500_IDF_SPI.ino index fe8fb725bc6..44b37233ef0 100644 --- a/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/ETH_W5500_IDF_SPI.ino +++ b/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/ETH_W5500_IDF_SPI.ino @@ -47,9 +47,9 @@ void onEvent(arduino_event_id_t event, arduino_event_info_t info) break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif)); - ETH.printInfo(Serial); + Serial.println(ETH); #if USE_TWO_ETH_PORTS - ETH1.printInfo(Serial); + Serial.println(ETH1); #endif eth_connected = true; break; @@ -75,7 +75,7 @@ void testClient(const char * host, uint16_t port) Serial.print("\nconnecting to "); Serial.println(host); - WiFiClient client; + NetworkClient client; if (!client.connect(host, port)) { Serial.println("connection failed"); return; @@ -93,7 +93,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(onEvent); + Network.onEvent(onEvent); ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, ETH_PHY_SPI_HOST, ETH_PHY_SPI_SCK, ETH_PHY_SPI_MISO, ETH_PHY_SPI_MOSI); #if USE_TWO_ETH_PORTS // Since SPI bus is shared, we should skip the SPI pins when calling ETH1.begin() diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index f60ed55e3aa..440f0c43b3f 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -42,14 +42,81 @@ #include "esp_netif_defaults.h" #include "esp_eth_phy.h" -extern void tcpipInit(); -extern void add_esp_interface_netif(esp_interface_t interface, esp_netif_t* esp_netif); /* from WiFiGeneric */ +static ETHClass * _ethernets[3] = { NULL, NULL, NULL }; +static esp_event_handler_instance_t _eth_ev_instance = NULL; +static void _eth_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + + if (event_base == ETH_EVENT){ + esp_eth_handle_t eth_handle = *((esp_eth_handle_t*)event_data); + for(int i = 0; i < 3; ++i){ + if(_ethernets[i] != NULL && _ethernets[i]->handle() == eth_handle){ + _ethernets[i]->_onEthEvent(event_id, event_data); + } + } + } +} + +// This callback needs to be aware of which interface it should match against +static void onEthConnected(arduino_event_id_t event, arduino_event_info_t info) +{ + if(event == ARDUINO_EVENT_ETH_CONNECTED){ + uint8_t index = 3; + for (int i = 0; i < 3; ++i) { + if(_ethernets[i] != NULL && _ethernets[i]->handle() == info.eth_connected){ + index = i; + break; + } + } + if(index == 3){ + log_e("Could not find ETH interface with that handle!"); + return; + } + if (_ethernets[index]->getStatusBits() & ESP_NETIF_WANT_IP6_BIT){ + esp_err_t err = esp_netif_create_ip6_linklocal(_ethernets[index]->netif()); + if(err != ESP_OK){ + log_e("Failed to enable IPv6 Link Local on ETH: [%d] %s", err, esp_err_to_name(err)); + } else { + log_v("Enabled IPv6 Link Local on %s", _ethernets[index]->desc()); + } + } + } +} + +esp_eth_handle_t ETHClass::handle() const { + return _eth_handle; +} + +void ETHClass::_onEthEvent(int32_t event_id, void* event_data){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; + + if (event_id == ETHERNET_EVENT_CONNECTED) { + log_v("%s Connected", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_CONNECTED; + arduino_event.event_info.eth_connected = handle(); + setStatusBits(ESP_NETIF_CONNECTED_BIT); + } else if (event_id == ETHERNET_EVENT_DISCONNECTED) { + log_v("%s Disconnected", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_DISCONNECTED; + clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + } else if (event_id == ETHERNET_EVENT_START) { + log_v("%s Started", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_START; + setStatusBits(ESP_NETIF_STARTED_BIT); + } else if (event_id == ETHERNET_EVENT_STOP) { + log_v("%s Stopped", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_STOP; + clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} ETHClass::ETHClass(uint8_t eth_index) - :_eth_started(false) - ,_eth_handle(NULL) - ,_esp_netif(NULL) + :_eth_handle(NULL) ,_eth_index(eth_index) ,_phy_type(ETH_PHY_MAX) #if ETH_SPI_SUPPORTS_CUSTOM @@ -75,9 +142,7 @@ ETHClass::~ETHClass() bool ETHClass::ethDetachBus(void * bus_pointer){ ETHClass *bus = (ETHClass *) bus_pointer; - if(bus->_eth_started){ - bus->end(); - } + bus->end(); return true; } @@ -85,6 +150,9 @@ bool ETHClass::ethDetachBus(void * bus_pointer){ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, int power, eth_clock_mode_t clock_mode) { esp_err_t ret = ESP_OK; + if(_eth_index > 2){ + return false; + } if(_esp_netif != NULL){ return true; } @@ -100,7 +168,12 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i perimanSetBusDeinit(ESP32_BUS_TYPE_ETHERNET_PWR, ETHClass::ethDetachBus); } - tcpipInit(); + Network.begin(); + _ethernets[_eth_index] = this; + if(_eth_ev_instance == NULL && esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &_eth_event_cb, NULL, &_eth_ev_instance)){ + log_e("event_handler_instance_register for ETH_EVENT Failed!"); + return false; + } eth_esp32_emac_config_t mac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); mac_config.clock_config.rmii.clock_mode = (clock_mode) ? EMAC_CLK_OUT : EMAC_CLK_EXT_IN; @@ -188,7 +261,11 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i char if_desc_str[10]; char num_str[3]; itoa(_eth_index, num_str, 10); - strcat(strcpy(if_key_str, "ETH_"), num_str); + if(_eth_index == 0){ + strcpy(if_key_str, "ETH_DEF"); + } else { + strcat(strcpy(if_key_str, "ETH_"), num_str); + } strcat(strcpy(if_desc_str, "eth"), num_str); esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); @@ -207,15 +284,14 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i return false; } - /* attach to WiFiGeneric to receive events */ - add_esp_interface_netif(ESP_IF_ETH, _esp_netif); + /* attach to receive events */ + initNetif((Network_Interface_ID)(ESP_NETIF_ID_ETH+_eth_index)); ret = esp_eth_start(_eth_handle); if(ret != ESP_OK){ log_e("esp_eth_start failed: %d", ret); return false; } - _eth_started = true; if(!perimanSetPinBus(_pin_rmii_clock, ESP32_BUS_TYPE_ETHERNET_CLK, (void *)(this), -1, -1)){ goto err; } if(!perimanSetPinBus(_pin_mcd, ESP32_BUS_TYPE_ETHERNET_MCD, (void *)(this), -1, -1)){ goto err; } @@ -231,6 +307,9 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i if(_pin_power != -1){ if(!perimanSetPinBus(_pin_power, ESP32_BUS_TYPE_ETHERNET_PWR, (void *)(this), -1, -1)){ goto err; } } + + Network.onSysEvent(onEthConnected, ARDUINO_EVENT_ETH_CONNECTED); + // holds a few milliseconds to let DHCP start and enter into a good state // FIX ME -- adresses issue https://github.com/espressif/arduino-esp32/issues/5733 delay(50); @@ -351,7 +430,7 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, int sck, int miso, int mosi, spi_host_device_t spi_host, uint8_t spi_freq_mhz){ esp_err_t ret = ESP_OK; - if(_eth_started || _esp_netif != NULL || _eth_handle != NULL){ + if(_esp_netif != NULL || _eth_handle != NULL){ log_w("ETH Already Started"); return true; } @@ -421,6 +500,11 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, buscfg.sclk_io_num = _pin_sck; buscfg.quadwp_io_num = -1; buscfg.quadhd_io_num = -1; + buscfg.data4_io_num = -1; + buscfg.data5_io_num = -1; + buscfg.data6_io_num = -1; + buscfg.data7_io_num = -1; + buscfg.max_transfer_sz = -1; ret = spi_bus_initialize(spi_host, &buscfg, SPI_DMA_CH_AUTO); if(ret != ESP_OK){ log_e("SPI bus initialize failed: %d", ret); @@ -428,7 +512,13 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, } } - tcpipInit(); + Network.begin(); + _ethernets[_eth_index] = this; + if(_eth_ev_instance == NULL && esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &_eth_event_cb, NULL, &_eth_ev_instance)){ + log_e("event_handler_instance_register for ETH_EVENT Failed!"); + return false; + } + // Install GPIO ISR handler to be able to service SPI Eth modules interrupts ret = gpio_install_isr_service(0); @@ -556,7 +646,11 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, char if_desc_str[10]; char num_str[3]; itoa(_eth_index, num_str, 10); - strcat(strcpy(if_key_str, "ETH_"), num_str); + if(_eth_index == 0){ + strcpy(if_key_str, "ETH_DEF"); + } else { + strcat(strcpy(if_key_str, "ETH_"), num_str); + } strcat(strcpy(if_desc_str, "eth"), num_str); esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); @@ -584,8 +678,8 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, return false; } - // attach to WiFiGeneric to receive events - add_esp_interface_netif(ESP_IF_ETH, _esp_netif); + /* attach to receive events */ + initNetif((Network_Interface_ID)(ESP_NETIF_ID_ETH+_eth_index)); // Start Ethernet driver state machine ret = esp_eth_start(_eth_handle); @@ -594,8 +688,6 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, return false; } - _eth_started = true; - // If Arduino's SPI is used, cs pin is in GPIO mode #if ETH_SPI_SUPPORTS_CUSTOM if(_spi == NULL){ @@ -624,6 +716,8 @@ bool ETHClass::beginSPI(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, if(!perimanSetPinBus(_pin_rst, ESP32_BUS_TYPE_ETHERNET_SPI, (void *)(this), -1, -1)){ goto err; } } + Network.onSysEvent(onEthConnected, ARDUINO_EVENT_ETH_CONNECTED); + return true; err: @@ -650,13 +744,16 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int cs, int irq, int void ETHClass::end(void) { - _eth_started = false; + destroyNetif(); - if(_esp_netif != NULL){ - esp_netif_destroy(_esp_netif); - _esp_netif = NULL; + if(_eth_ev_instance != NULL){ + if(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &_eth_event_cb) == ESP_OK){ + _eth_ev_instance = NULL; + } } + Network.removeEvent(onEthConnected, ARDUINO_EVENT_ETH_CONNECTED); + if(_eth_handle != NULL){ if(esp_eth_stop(_eth_handle) != ESP_OK){ log_e("Failed to stop Ethernet"); @@ -722,255 +819,7 @@ void ETHClass::end(void) } } -bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) -{ - if(_esp_netif == NULL){ - return false; - } - esp_err_t err = ESP_OK; - esp_netif_ip_info_t info; - esp_netif_dns_info_t d1; - esp_netif_dns_info_t d2; - d1.ip.type = IPADDR_TYPE_V4; - d2.ip.type = IPADDR_TYPE_V4; - - if(static_cast(local_ip) != 0){ - info.ip.addr = static_cast(local_ip); - info.gw.addr = static_cast(gateway); - info.netmask.addr = static_cast(subnet); - d1.ip.u_addr.ip4.addr = static_cast(dns1); - d2.ip.u_addr.ip4.addr = static_cast(dns2); - } else { - info.ip.addr = 0; - info.gw.addr = 0; - info.netmask.addr = 0; - d1.ip.u_addr.ip4.addr = 0; - d2.ip.u_addr.ip4.addr = 0; - } - - // Stop DHCPC - err = esp_netif_dhcpc_stop(_esp_netif); - if(err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED){ - log_e("DHCP could not be stopped! Error: %d", err); - return false; - } - - // Set IPv4, Netmask, Gateway - err = esp_netif_set_ip_info(_esp_netif, &info); - if(err != ERR_OK){ - log_e("ETH IP could not be configured! Error: %d", err); - return false; - } - - // Set DNS1-Server - esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_MAIN, &d1); - - // Set DNS2-Server - esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_BACKUP, &d2); - - // Start DHCPC if static IP was set - if(info.ip.addr == 0){ - err = esp_netif_dhcpc_start(_esp_netif); - if(err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED){ - log_w("DHCP could not be started! Error: %d", err); - return false; - } - } - - return true; -} - -IPAddress ETHClass::localIP() -{ - if(_esp_netif == NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(_esp_netif, &ip)){ - return IPAddress(); - } - return IPAddress(ip.ip.addr); -} - -IPAddress ETHClass::subnetMask() -{ - if(_esp_netif == NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(_esp_netif, &ip)){ - return IPAddress(); - } - return IPAddress(ip.netmask.addr); -} - -IPAddress ETHClass::gatewayIP() -{ - if(_esp_netif == NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(_esp_netif, &ip)){ - return IPAddress(); - } - return IPAddress(ip.gw.addr); -} - -IPAddress ETHClass::dnsIP(uint8_t dns_no) -{ - if(_esp_netif == NULL){ - return IPAddress(); - } - esp_netif_dns_info_t d; - if(esp_netif_get_dns_info(_esp_netif, dns_no?ESP_NETIF_DNS_BACKUP:ESP_NETIF_DNS_MAIN, &d) != ESP_OK){ - return IPAddress(); - } - return IPAddress(d.ip.u_addr.ip4.addr); -} - -IPAddress ETHClass::broadcastIP() -{ - if(_esp_netif == NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(_esp_netif, &ip)){ - return IPAddress(); - } - return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); -} - -IPAddress ETHClass::networkID() -{ - if(_esp_netif == NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(_esp_netif, &ip)){ - return IPAddress(); - } - return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); -} - -uint8_t ETHClass::subnetCIDR() -{ - if(_esp_netif == NULL){ - return (uint8_t)0; - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(_esp_netif, &ip)){ - return (uint8_t)0; - } - return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); -} - -const char * ETHClass::getHostname() -{ - if(_esp_netif == NULL){ - return ""; - } - const char * hostname; - if(esp_netif_get_hostname(_esp_netif, &hostname)){ - return NULL; - } - return hostname; -} - -bool ETHClass::setHostname(const char * hostname) -{ - if(_esp_netif == NULL){ - return false; - } - return esp_netif_set_hostname(_esp_netif, hostname) == 0; -} - -bool ETHClass::enableIPv6(bool en) -{ - // if(_esp_netif == NULL){ - // return false; - // } - // return esp_netif_create_ip6_linklocal(_esp_netif) == 0; - if (en) { - WiFiGenericClass::setStatusBits(ETH_WANT_IP6_BIT); - } else { - WiFiGenericClass::clearStatusBits(ETH_WANT_IP6_BIT); - } - return true; -} - -IPAddress ETHClass::localIPv6() -{ - if(_esp_netif == NULL){ - return IPAddress(IPv6); - } - static esp_ip6_addr_t addr; - if(esp_netif_get_ip6_linklocal(_esp_netif, &addr)){ - return IPAddress(IPv6); - } - return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); -} - -IPAddress ETHClass::globalIPv6() -{ - if(_esp_netif == NULL){ - return IPAddress(IPv6); - } - static esp_ip6_addr_t addr; - if(esp_netif_get_ip6_global(_esp_netif, &addr)){ - return IPAddress(IPv6); - } - return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); -} - -const char * ETHClass::ifkey(void) -{ - if(_esp_netif == NULL){ - return ""; - } - return esp_netif_get_ifkey(_esp_netif); -} - -const char * ETHClass::desc(void) -{ - if(_esp_netif == NULL){ - return ""; - } - return esp_netif_get_desc(_esp_netif); -} - -String ETHClass::impl_name(void) -{ - if(_esp_netif == NULL){ - return String(""); - } - char netif_name[8]; - esp_err_t err = esp_netif_get_netif_impl_name(_esp_netif, netif_name); - if(err != ESP_OK){ - log_e("Failed to get netif impl_name: %d", err); - return String(""); - } - return String(netif_name); -} - -bool ETHClass::connected() -{ - return WiFiGenericClass::getStatusBits() & ETH_CONNECTED_BIT; -} - -bool ETHClass::hasIP() -{ - return WiFiGenericClass::getStatusBits() & ETH_HAS_IP_BIT; -} - -bool ETHClass::linkUp() -{ - if(_esp_netif == NULL){ - return false; - } - return esp_netif_is_netif_up(_esp_netif); -} - -bool ETHClass::fullDuplex() +bool ETHClass::fullDuplex() const { if(_eth_handle == NULL){ return false; @@ -980,7 +829,7 @@ bool ETHClass::fullDuplex() return (link_duplex == ETH_DUPLEX_FULL); } -bool ETHClass::autoNegotiation() +bool ETHClass::autoNegotiation() const { if(_eth_handle == NULL){ return false; @@ -990,7 +839,7 @@ bool ETHClass::autoNegotiation() return auto_nego; } -uint32_t ETHClass::phyAddr() +uint32_t ETHClass::phyAddr() const { if(_eth_handle == NULL){ return 0; @@ -1000,7 +849,7 @@ uint32_t ETHClass::phyAddr() return phy_addr; } -uint8_t ETHClass::linkSpeed() +uint8_t ETHClass::linkSpeed() const { if(_eth_handle == NULL){ return 0; @@ -1010,91 +859,26 @@ uint8_t ETHClass::linkSpeed() return (link_speed == ETH_SPEED_10M)?10:100; } -uint8_t * ETHClass::macAddress(uint8_t* mac) -{ - if(_eth_handle == NULL){ - return NULL; - } - if(!mac){ - return NULL; - } - esp_eth_ioctl(_eth_handle, ETH_CMD_G_MAC_ADDR, mac); - return mac; -} - -String ETHClass::macAddress(void) -{ - uint8_t mac[6] = {0,0,0,0,0,0}; - char macStr[18] = { 0 }; - macAddress(mac); - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); -} +// void ETHClass::getMac(uint8_t* mac) +// { +// if(_eth_handle != NULL && mac != NULL){ +// esp_eth_ioctl(_eth_handle, ETH_CMD_G_MAC_ADDR, mac); +// } +// } -void ETHClass::printInfo(Print & out){ - out.print(desc()); - out.print(":"); - if(linkUp()){ - out.print(" "); - - out.print(" "); - out.print("ether "); - out.print(macAddress()); - out.printf(" phy 0x%lX", phyAddr()); - out.println(); - - out.print(" "); - out.print("inet "); - out.print(localIP()); - out.print(" netmask "); - out.print(subnetMask()); - out.print(" broadcast "); - out.print(broadcastIP()); - out.println(); - - out.print(" "); - out.print("gateway "); - out.print(gatewayIP()); - out.print(" dns "); - out.print(dnsIP()); - out.println(); - - static const char * types[] = { "UNKNOWN", "GLOBAL", "LINK_LOCAL", "SITE_LOCAL", "UNIQUE_LOCAL", "IPV4_MAPPED_IPV6" }; - esp_ip6_addr_t if_ip6[CONFIG_LWIP_IPV6_NUM_ADDRESSES]; - int v6addrs = esp_netif_get_all_ip6(_esp_netif, if_ip6); - for (int i = 0; i < v6addrs; ++i){ - out.print(" "); - out.print("inet6 "); - IPAddress(IPv6, (const uint8_t *)if_ip6[i].addr, if_ip6[i].zone).printTo(out, true); - out.print(" type "); - out.print(types[esp_netif_ip6_get_addr_type(&if_ip6[i])]); - out.println(); - } - - // out.print(" "); - // out.print("inet6 "); - // localIPv6().printTo(out); - // out.println(); - - // out.print(" "); - // out.print("inet6 "); - // globalIPv6().printTo(out); - // out.println(); - - out.println(); + bytes += out.print(",AUTO"); + } + bytes += out.printf(",ADDR:0x%lX", phyAddr()); + return bytes; } ETHClass ETH; diff --git a/libraries/Ethernet/src/ETH.h b/libraries/Ethernet/src/ETH.h index e3c28154932..5ed05642360 100644 --- a/libraries/Ethernet/src/ETH.h +++ b/libraries/Ethernet/src/ETH.h @@ -63,7 +63,8 @@ // This will be uncommented once custom SPI support is available in ESP-IDF #define ETH_SPI_SUPPORTS_CUSTOM 1 -#include "WiFi.h" +#include "Network.h" + #if ETH_SPI_SUPPORTS_CUSTOM #include "SPI.h" #endif @@ -105,7 +106,7 @@ typedef enum { ETH_PHY_MAX } eth_phy_type_t; -class ETHClass { +class ETHClass: public NetworkInterface { public: ETHClass(uint8_t eth_index=0); ~ETHClass(); @@ -135,43 +136,13 @@ class ETHClass { void end(); - // Netif APIs - esp_netif_t * netif(void){ return _esp_netif; } - bool config(IPAddress local_ip = (uint32_t)0x00000000, IPAddress gateway = (uint32_t)0x00000000, IPAddress subnet = (uint32_t)0x00000000, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); - const char * getHostname(); - bool setHostname(const char * hostname); - IPAddress localIP(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsIP(uint8_t dns_no = 0); - IPAddress broadcastIP(); - IPAddress networkID(); - uint8_t subnetCIDR(); - bool enableIPv6(bool en=true); - IPAddress localIPv6(); - IPAddress globalIPv6(); - const char * ifkey(void); - const char * desc(void); - String impl_name(void); - - // Event based getters - bool connected(); - bool hasIP(); - // ETH Handle APIs - uint8_t * macAddress(uint8_t* mac); - String macAddress(); - bool fullDuplex(); - bool linkUp(); - uint8_t linkSpeed(); - bool autoNegotiation(); - uint32_t phyAddr(); - - // Info APIs - void printInfo(Print & out); + bool fullDuplex() const; + uint8_t linkSpeed() const; + bool autoNegotiation() const; + uint32_t phyAddr() const; - friend class WiFiClient; - friend class WiFiServer; + esp_eth_handle_t handle() const; #if ETH_SPI_SUPPORTS_CUSTOM static esp_err_t _eth_spi_read(void *ctx, uint32_t cmd, uint32_t addr, void *data, uint32_t data_len); @@ -184,12 +155,15 @@ class ETHClass { esp_err_t eth_spi_write(uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len); #endif - static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); + // void getMac(uint8_t* mac); + size_t printDriverInfo(Print & out) const; + // static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); + + public: + void _onEthEvent(int32_t event_id, void* event_data); private: - bool _eth_started; esp_eth_handle_t _eth_handle; - esp_netif_t *_esp_netif; uint8_t _eth_index; eth_phy_type_t _phy_type; #if ETH_SPI_SUPPORTS_CUSTOM diff --git a/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index 9b55d801b37..3d56d2e9651 100644 --- a/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -12,7 +12,7 @@ #include -#include +#include // This is GandiStandardSSLCA2.pem, the root Certificate Authority that signed // the server certifcate for the demo server https://jigsaw.w3.org in this @@ -53,7 +53,7 @@ const char* rootCACertificate = \ "BT02Vf6Dsuimrdfp5gJ0iHRc2jTbkNJtUQoj1iM=\n" \ "-----END CERTIFICATE-----\n"; -// Not sure if WiFiClientSecure checks the validity date of the certificate. +// Not sure if NetworkClientSecure checks the validity date of the certificate. // Setting clock just to be sure... void setClock() { configTime(0, 0, "pool.ntp.org"); @@ -100,12 +100,12 @@ void setup() { } void loop() { - WiFiClientSecure *client = new WiFiClientSecure; + NetworkClientSecure *client = new NetworkClientSecure; if(client) { client -> setCACert(rootCACertificate); { - // Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is + // Add a scoping block for HTTPClient https to make sure it is destroyed before NetworkClientSecure *client is HTTPClient https; Serial.print("[HTTPS] begin...\n"); diff --git a/libraries/HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino b/libraries/HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino index a0d681b2c1d..823702ad770 100644 --- a/libraries/HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino +++ b/libraries/HTTPClient/examples/StreamHttpClient/StreamHttpClient.ino @@ -63,7 +63,7 @@ void loop() { uint8_t buff[128] = { 0 }; // get tcp stream - WiFiClient * stream = http.getStreamPtr(); + NetworkClient * stream = http.getStreamPtr(); // read all data from server while(http.connected() && (len > 0 || len == -1)) { diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index 1733d0cede1..d20ad6570c3 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -30,8 +30,8 @@ #include #ifdef HTTPCLIENT_1_1_COMPATIBLE -#include -#include +#include +#include #endif #include @@ -50,12 +50,12 @@ class TransportTraits { } - virtual std::unique_ptr create() + virtual std::unique_ptr create() { - return std::unique_ptr(new WiFiClient()); + return std::unique_ptr(new NetworkClient()); } - virtual bool verify(WiFiClient& client, const char* host) + virtual bool verify(NetworkClient& client, const char* host) { return true; } @@ -69,14 +69,14 @@ class TLSTraits : public TransportTraits { } - std::unique_ptr create() override + std::unique_ptr create() override { - return std::unique_ptr(new WiFiClientSecure()); + return std::unique_ptr(new NetworkClientSecure()); } - bool verify(WiFiClient& client, const char* host) override + bool verify(NetworkClient& client, const char* host) override { - WiFiClientSecure& wcs = static_cast(client); + NetworkClientSecure& wcs = static_cast(client); if (_cacert == nullptr) { wcs.setInsecure(); } else { @@ -135,7 +135,7 @@ void HTTPClient::clear() * @param https bool * @return success bool */ -bool HTTPClient::begin(WiFiClient &client, String url) { +bool HTTPClient::begin(NetworkClient &client, String url) { #ifdef HTTPCLIENT_1_1_COMPATIBLE if(_tcpDeprecated) { log_d("mix up of new and deprecated api"); @@ -174,7 +174,7 @@ bool HTTPClient::begin(WiFiClient &client, String url) { * @param https bool * @return success bool */ -bool HTTPClient::begin(WiFiClient &client, String host, uint16_t port, String uri, bool https) +bool HTTPClient::begin(NetworkClient &client, String host, uint16_t port, String uri, bool https) { #ifdef HTTPCLIENT_1_1_COMPATIBLE if(_tcpDeprecated) { @@ -862,24 +862,24 @@ int HTTPClient::getSize(void) /** * returns the stream of the tcp connection - * @return WiFiClient + * @return NetworkClient */ -WiFiClient& HTTPClient::getStream(void) +NetworkClient& HTTPClient::getStream(void) { if (connected()) { return *_client; } log_w("getStream: not connected"); - static WiFiClient empty; + static NetworkClient empty; return empty; } /** * returns a pointer to the stream of the tcp connection - * @return WiFiClient* + * @return NetworkClient* */ -WiFiClient* HTTPClient::getStreamPtr(void) +NetworkClient* HTTPClient::getStreamPtr(void) { if(connected()) { return _client; @@ -1164,7 +1164,7 @@ bool HTTPClient::connect(void) return false; } - // set Timeout for WiFiClient and for Stream::readBytesUntil() and Stream::readStringUntil() + // set Timeout for NetworkClient and for Stream::readBytesUntil() and Stream::readStringUntil() _client->setTimeout(_tcpTimeout); log_d(" connected to %s:%u", _host.c_str(), _port); diff --git a/libraries/HTTPClient/src/HTTPClient.h b/libraries/HTTPClient/src/HTTPClient.h index 0058c1ef18c..0d586916e24 100644 --- a/libraries/HTTPClient/src/HTTPClient.h +++ b/libraries/HTTPClient/src/HTTPClient.h @@ -33,8 +33,8 @@ #include #include -#include -#include +#include +#include /// Cookie jar support #include @@ -180,8 +180,8 @@ class HTTPClient * Since both begin() functions take a reference to client as a parameter, you need to * ensure the client object lives the entire time of the HTTPClient */ - bool begin(WiFiClient &client, String url); - bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false); + bool begin(NetworkClient &client, String url); + bool begin(NetworkClient &client, String host, uint16_t port, String uri = "/", bool https = false); #ifdef HTTPCLIENT_1_1_COMPATIBLE bool begin(String url); @@ -236,8 +236,8 @@ class HTTPClient int getSize(void); const String &getLocation(void); - WiFiClient& getStream(void); - WiFiClient* getStreamPtr(void); + NetworkClient& getStream(void); + NetworkClient* getStreamPtr(void); int writeToStream(Stream* stream); String getString(void); @@ -269,10 +269,10 @@ class HTTPClient #ifdef HTTPCLIENT_1_1_COMPATIBLE TransportTraitsPtr _transportTraits; - std::unique_ptr _tcpDeprecated; + std::unique_ptr _tcpDeprecated; #endif - WiFiClient* _client = nullptr; + NetworkClient* _client = nullptr; /// request handling String _host; diff --git a/libraries/HTTPUpdate/examples/httpUpdate/httpUpdate.ino b/libraries/HTTPUpdate/examples/httpUpdate/httpUpdate.ino index 3a612da7e2f..47b73acc8bc 100644 --- a/libraries/HTTPUpdate/examples/httpUpdate/httpUpdate.ino +++ b/libraries/HTTPUpdate/examples/httpUpdate/httpUpdate.ino @@ -56,7 +56,7 @@ void loop() { // wait for WiFi connection if ((WiFiMulti.run() == WL_CONNECTED)) { - WiFiClient client; + NetworkClient client; // The line below is optional. It can be used to blink the LED on the board during flashing // The LED will be on during download of one buffer of data from the network. The LED will diff --git a/libraries/HTTPUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino b/libraries/HTTPUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino index a07e6d2f4aa..ec834f85c19 100644 --- a/libraries/HTTPUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino +++ b/libraries/HTTPUpdate/examples/httpUpdateSPIFFS/httpUpdateSPIFFS.ino @@ -41,7 +41,7 @@ void loop() { Serial.println("Update SPIFFS..."); - WiFiClient client; + NetworkClient client; // The line below is optional. It can be used to blink the LED on the board during flashing // The LED will be on during download of one buffer of data from the network. The LED will diff --git a/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino b/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino index e528a9fdb1c..6c98b9a3755 100644 --- a/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino +++ b/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino @@ -92,7 +92,7 @@ void loop() { setClock(); - WiFiClientSecure client; + NetworkClientSecure client; client.setCACert(rootCACertificate); // Reading data over SSL may be slow, use an adequate timeout diff --git a/libraries/HTTPUpdate/src/HTTPUpdate.cpp b/libraries/HTTPUpdate/src/HTTPUpdate.cpp index f42bd14ae86..cc93ef82937 100644 --- a/libraries/HTTPUpdate/src/HTTPUpdate.cpp +++ b/libraries/HTTPUpdate/src/HTTPUpdate.cpp @@ -25,6 +25,9 @@ #include "HTTPUpdate.h" #include +#if SOC_WIFI_SUPPORTED +#include "WiFi.h" +#endif #include #include // get running partition @@ -51,7 +54,7 @@ HTTPUpdate::~HTTPUpdate(void) { } -HTTPUpdateResult HTTPUpdate::update(WiFiClient& client, const String& url, const String& currentVersion, HTTPUpdateRequestCB requestCB) +HTTPUpdateResult HTTPUpdate::update(NetworkClient& client, const String& url, const String& currentVersion, HTTPUpdateRequestCB requestCB) { HTTPClient http; if(!http.begin(client, url)) @@ -66,7 +69,7 @@ HTTPUpdateResult HTTPUpdate::updateSpiffs(HTTPClient& httpClient, const String& return handleUpdate(httpClient, currentVersion, true, requestCB); } -HTTPUpdateResult HTTPUpdate::updateSpiffs(WiFiClient& client, const String& url, const String& currentVersion, HTTPUpdateRequestCB requestCB) +HTTPUpdateResult HTTPUpdate::updateSpiffs(NetworkClient& client, const String& url, const String& currentVersion, HTTPUpdateRequestCB requestCB) { HTTPClient http; if(!http.begin(client, url)) @@ -82,7 +85,7 @@ HTTPUpdateResult HTTPUpdate::update(HTTPClient& httpClient, return handleUpdate(httpClient, currentVersion, false, requestCB); } -HTTPUpdateResult HTTPUpdate::update(WiFiClient& client, const String& host, uint16_t port, const String& uri, +HTTPUpdateResult HTTPUpdate::update(NetworkClient& client, const String& host, uint16_t port, const String& uri, const String& currentVersion, HTTPUpdateRequestCB requestCB) { HTTPClient http; @@ -194,8 +197,11 @@ HTTPUpdateResult HTTPUpdate::handleUpdate(HTTPClient& http, const String& curren http.setFollowRedirects(_followRedirects); http.setUserAgent("ESP32-http-Update"); http.addHeader("Cache-Control", "no-cache"); + http.addHeader("x-ESP32-BASE-MAC", Network.macAddress()); +#if SOC_WIFI_SUPPORTED http.addHeader("x-ESP32-STA-MAC", WiFi.macAddress()); http.addHeader("x-ESP32-AP-MAC", WiFi.softAPmacAddress()); +#endif http.addHeader("x-ESP32-free-space", String(ESP.getFreeSketchSpace())); http.addHeader("x-ESP32-sketch-size", String(ESP.getSketchSize())); String sketchMD5 = ESP.getSketchMD5(); @@ -309,10 +315,10 @@ HTTPUpdateResult HTTPUpdate::handleUpdate(HTTPClient& http, const String& curren _cbStart(); } - WiFiClient * tcp = http.getStreamPtr(); + NetworkClient * tcp = http.getStreamPtr(); -// To do? WiFiUDP::stopAll(); -// To do? WiFiClient::stopAllExcept(tcp); +// To do? NetworkUDP::stopAll(); +// To do? NetworkClient::stopAllExcept(tcp); delay(100); diff --git a/libraries/HTTPUpdate/src/HTTPUpdate.h b/libraries/HTTPUpdate/src/HTTPUpdate.h index 2e9f3c1b1bc..b915bb0a8bd 100644 --- a/libraries/HTTPUpdate/src/HTTPUpdate.h +++ b/libraries/HTTPUpdate/src/HTTPUpdate.h @@ -27,9 +27,7 @@ #define ___HTTP_UPDATE_H___ #include -#include -#include -#include +#include #include #include @@ -101,12 +99,12 @@ class HTTPUpdate _auth = auth; } - t_httpUpdate_return update(WiFiClient& client, const String& url, const String& currentVersion = "", HTTPUpdateRequestCB requestCB = NULL); + t_httpUpdate_return update(NetworkClient& client, const String& url, const String& currentVersion = "", HTTPUpdateRequestCB requestCB = NULL); - t_httpUpdate_return update(WiFiClient& client, const String& host, uint16_t port, const String& uri = "/", + t_httpUpdate_return update(NetworkClient& client, const String& host, uint16_t port, const String& uri = "/", const String& currentVersion = "", HTTPUpdateRequestCB requestCB = NULL); - t_httpUpdate_return updateSpiffs(WiFiClient& client, const String& url, const String& currentVersion = "", HTTPUpdateRequestCB requestCB = NULL); + t_httpUpdate_return updateSpiffs(NetworkClient& client, const String& url, const String& currentVersion = "", HTTPUpdateRequestCB requestCB = NULL); t_httpUpdate_return update(HTTPClient& httpClient, const String& currentVersion = "", diff --git a/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino b/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino index 21688c3e7c2..54fe6a102fc 100644 --- a/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino +++ b/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino @@ -3,7 +3,7 @@ */ #include -#include +#include #include #include #include diff --git a/libraries/NetBIOS/src/NetBIOS.cpp b/libraries/NetBIOS/src/NetBIOS.cpp index 22d3deca43b..5442d8722b4 100755 --- a/libraries/NetBIOS/src/NetBIOS.cpp +++ b/libraries/NetBIOS/src/NetBIOS.cpp @@ -1,5 +1,4 @@ #include "NetBIOS.h" - #include #define NBNS_PORT 137 @@ -92,7 +91,7 @@ void NetBIOS::_onPacket(AsyncUDPPacket& packet){ append_32((void *)&nbnsa.ttl, 300000); append_16((void *)&nbnsa.data_len, 6); append_16((void *)&nbnsa.flags, 0); - nbnsa.addr = WiFi.localIP(); + nbnsa.addr = packet.localIP(); _udp.writeTo((uint8_t *)&nbnsa, sizeof(nbnsa), packet.remoteIP(), NBNS_PORT); } } @@ -102,6 +101,7 @@ void NetBIOS::_onPacket(AsyncUDPPacket& packet){ NetBIOS::NetBIOS(){ } + NetBIOS::~NetBIOS(){ end(); } diff --git a/libraries/NetBIOS/src/NetBIOS.h b/libraries/NetBIOS/src/NetBIOS.h index 0321f6b8b91..248f4ed3255 100755 --- a/libraries/NetBIOS/src/NetBIOS.h +++ b/libraries/NetBIOS/src/NetBIOS.h @@ -2,7 +2,7 @@ #ifndef __ESPNBNS_h__ #define __ESPNBNS_h__ -#include +#include "Arduino.h" #include "AsyncUDP.h" class NetBIOS diff --git a/libraries/Network/library.properties b/libraries/Network/library.properties new file mode 100644 index 00000000000..65f278952f1 --- /dev/null +++ b/libraries/Network/library.properties @@ -0,0 +1,9 @@ +name=Networking +version=1.0.0 +author=Hristo Gochkov +maintainer=Hristo Gochkov +sentence=General network management library. +paragraph=This library holds all common functionality of the different network interfaces. +category=Communication +url= +architectures=esp32 \ No newline at end of file diff --git a/libraries/Network/src/Network.h b/libraries/Network/src/Network.h new file mode 100644 index 00000000000..2b10ae10c64 --- /dev/null +++ b/libraries/Network/src/Network.h @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "NetworkInterface.h" +#include "NetworkEvents.h" +#include "NetworkManager.h" + +#include "NetworkClient.h" +#include "NetworkServer.h" +#include "NetworkUdp.h" \ No newline at end of file diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/Network/src/NetworkClient.cpp similarity index 85% rename from libraries/WiFi/src/WiFiClient.cpp rename to libraries/Network/src/NetworkClient.cpp index 96eab3b5602..cafead993a9 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/Network/src/NetworkClient.cpp @@ -17,8 +17,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "WiFiClient.h" -#include "WiFi.h" +#include "NetworkClient.h" +#include "NetworkManager.h" #include #include #include @@ -37,7 +37,7 @@ #undef write #undef read -class WiFiClientRxBuffer { +class NetworkClientRxBuffer { private: size_t _size; uint8_t *_buffer; @@ -93,7 +93,7 @@ class WiFiClientRxBuffer { } public: - WiFiClientRxBuffer(int fd, size_t size=1436) + NetworkClientRxBuffer(int fd, size_t size=1436) :_size(size) ,_buffer(NULL) ,_pos(0) @@ -104,7 +104,7 @@ class WiFiClientRxBuffer { //_buffer = (uint8_t *)malloc(_size); } - ~WiFiClientRxBuffer() + ~NetworkClientRxBuffer() { free(_buffer); } @@ -167,16 +167,16 @@ class WiFiClientRxBuffer { } }; -class WiFiClientSocketHandle { +class NetworkClientSocketHandle { private: int sockfd; public: - WiFiClientSocketHandle(int fd):sockfd(fd) + NetworkClientSocketHandle(int fd):sockfd(fd) { } - ~WiFiClientSocketHandle() + ~NetworkClientSocketHandle() { close(sockfd); } @@ -187,22 +187,22 @@ class WiFiClientSocketHandle { } }; -WiFiClient::WiFiClient():_rxBuffer(nullptr),_connected(false),_sse(false),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL) +NetworkClient::NetworkClient():_rxBuffer(nullptr),_connected(false),_sse(false),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL) { } -WiFiClient::WiFiClient(int fd):_connected(true),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL) +NetworkClient::NetworkClient(int fd):_connected(true),_timeout(WIFI_CLIENT_DEF_CONN_TIMEOUT_MS),next(NULL) { - clientSocketHandle.reset(new WiFiClientSocketHandle(fd)); - _rxBuffer.reset(new WiFiClientRxBuffer(fd)); + clientSocketHandle.reset(new NetworkClientSocketHandle(fd)); + _rxBuffer.reset(new NetworkClientRxBuffer(fd)); } -WiFiClient::~WiFiClient() +NetworkClient::~NetworkClient() { stop(); } -void WiFiClient::stop() +void NetworkClient::stop() { clientSocketHandle = NULL; _rxBuffer = NULL; @@ -211,12 +211,12 @@ void WiFiClient::stop() _lastWriteTimeout = 0; } -int WiFiClient::connect(IPAddress ip, uint16_t port) +int NetworkClient::connect(IPAddress ip, uint16_t port) { return connect(ip,port,_timeout); } -int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout_ms) +int NetworkClient::connect(IPAddress ip, uint16_t port, int32_t timeout_ms) { struct sockaddr_storage serveraddr = {}; _timeout = timeout_ms; @@ -291,38 +291,38 @@ int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout_ms) ROE_WIFICLIENT(setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)),"SO_SNDTIMEO"); ROE_WIFICLIENT(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)),"SO_RCVTIMEO"); - // These are also set in WiFiClientSecure, should be set here too? + // These are also set in NetworkClientSecure, should be set here too? //ROE_WIFICLIENT(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY"); //ROE_WIFICLIENT (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE"); fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) ); - clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd)); - _rxBuffer.reset(new WiFiClientRxBuffer(sockfd)); + clientSocketHandle.reset(new NetworkClientSocketHandle(sockfd)); + _rxBuffer.reset(new NetworkClientRxBuffer(sockfd)); _connected = true; return 1; } -int WiFiClient::connect(const char *host, uint16_t port) +int NetworkClient::connect(const char *host, uint16_t port) { return connect(host,port,_timeout); } -int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout_ms) +int NetworkClient::connect(const char *host, uint16_t port, int32_t timeout_ms) { IPAddress srv((uint32_t)0); - if(!WiFiGenericClass::hostByName(host, srv)){ + if(!Network.hostByName(host, srv)){ return 0; } return connect(srv, port, timeout_ms); } -int WiFiClient::setSocketOption(int option, char* value, size_t len) +int NetworkClient::setSocketOption(int option, char* value, size_t len) { return setSocketOption(SOL_SOCKET, option, (const void*)value, len); } -int WiFiClient::setSocketOption(int level, int option, const void* value, size_t len) +int NetworkClient::setSocketOption(int level, int option, const void* value, size_t len) { int res = setsockopt(fd(), level, option, value, len); if(res < 0) { @@ -331,7 +331,7 @@ int WiFiClient::setSocketOption(int level, int option, const void* value, size_t return res; } -int WiFiClient::getSocketOption(int level, int option, const void* value, size_t size) +int NetworkClient::getSocketOption(int level, int option, const void* value, size_t size) { int res = getsockopt(fd(), level, option, (char *)value, (socklen_t*)&size); if(res < 0) { @@ -340,12 +340,12 @@ int WiFiClient::getSocketOption(int level, int option, const void* value, size_t return res; } -int WiFiClient::setOption(int option, int *value) +int NetworkClient::setOption(int option, int *value) { return setSocketOption(IPPROTO_TCP, option, (const void*)value, sizeof(int)); } -int WiFiClient::getOption(int option, int *value) +int NetworkClient::getOption(int option, int *value) { socklen_t size = sizeof(int); int res = getsockopt(fd(), IPPROTO_TCP, option, (char *)value, &size); @@ -355,30 +355,30 @@ int WiFiClient::getOption(int option, int *value) return res; } -void WiFiClient::setConnectionTimeout(uint32_t milliseconds) +void NetworkClient::setConnectionTimeout(uint32_t milliseconds) { _timeout = milliseconds; } -int WiFiClient::setNoDelay(bool nodelay) +int NetworkClient::setNoDelay(bool nodelay) { int flag = nodelay; return setOption(TCP_NODELAY, &flag); } -bool WiFiClient::getNoDelay() +bool NetworkClient::getNoDelay() { int flag = 0; getOption(TCP_NODELAY, &flag); return flag; } -size_t WiFiClient::write(uint8_t data) +size_t NetworkClient::write(uint8_t data) { return write(&data, 1); } -int WiFiClient::read() +int NetworkClient::read() { uint8_t data = 0; int res = read(&data, 1); @@ -391,7 +391,7 @@ int WiFiClient::read() return data; } -size_t WiFiClient::write(const uint8_t *buf, size_t size) +size_t NetworkClient::write(const uint8_t *buf, size_t size) { int res =0; int retry = WIFI_CLIENT_MAX_WRITE_RETRY; @@ -459,12 +459,12 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) return totalBytesSent; } -size_t WiFiClient::write_P(PGM_P buf, size_t size) +size_t NetworkClient::write_P(PGM_P buf, size_t size) { return write(buf, size); } -size_t WiFiClient::write(Stream &stream) +size_t NetworkClient::write(Stream &stream) { uint8_t * buf = (uint8_t *)malloc(1360); if(!buf){ @@ -482,7 +482,7 @@ size_t WiFiClient::write(Stream &stream) return written; } -int WiFiClient::read(uint8_t *buf, size_t size) +int NetworkClient::read(uint8_t *buf, size_t size) { if(_lastReadTimeout != _timeout){ if(fd() >= 0){ @@ -507,7 +507,7 @@ int WiFiClient::read(uint8_t *buf, size_t size) return res; } -int WiFiClient::peek() +int NetworkClient::peek() { int res = -1; if (_rxBuffer) { @@ -520,7 +520,7 @@ int WiFiClient::peek() return res; } -int WiFiClient::available() +int NetworkClient::available() { if(!_rxBuffer) { @@ -536,13 +536,13 @@ int WiFiClient::available() // Though flushing means to send all pending data, // seems that in Arduino it also means to clear RX -void WiFiClient::flush() { +void NetworkClient::flush() { if (_rxBuffer != nullptr) { _rxBuffer->flush(); } } -uint8_t WiFiClient::connected() +uint8_t NetworkClient::connected() { if (_connected) { uint8_t dummy; @@ -576,7 +576,7 @@ uint8_t WiFiClient::connected() return _connected; } -IPAddress WiFiClient::remoteIP(int fd) const +IPAddress NetworkClient::remoteIP(int fd) const { struct sockaddr_storage addr; socklen_t len = sizeof addr; @@ -597,11 +597,11 @@ IPAddress WiFiClient::remoteIP(int fd) const return IPAddress(IPv6, (uint8_t*)(saddr6->sin6_addr.s6_addr), saddr6->sin6_scope_id); } } - log_e("WiFiClient::remoteIP Not AF_INET or AF_INET6?"); + log_e("NetworkClient::remoteIP Not AF_INET or AF_INET6?"); return (IPAddress(0,0,0,0)); } -uint16_t WiFiClient::remotePort(int fd) const +uint16_t NetworkClient::remotePort(int fd) const { struct sockaddr_storage addr; socklen_t len = sizeof addr; @@ -610,17 +610,17 @@ uint16_t WiFiClient::remotePort(int fd) const return ntohs(s->sin_port); } -IPAddress WiFiClient::remoteIP() const +IPAddress NetworkClient::remoteIP() const { return remoteIP(fd()); } -uint16_t WiFiClient::remotePort() const +uint16_t NetworkClient::remotePort() const { return remotePort(fd()); } -IPAddress WiFiClient::localIP(int fd) const +IPAddress NetworkClient::localIP(int fd) const { struct sockaddr_storage addr; socklen_t len = sizeof addr; @@ -629,7 +629,7 @@ IPAddress WiFiClient::localIP(int fd) const return IPAddress((uint32_t)(s->sin_addr.s_addr)); } -uint16_t WiFiClient::localPort(int fd) const +uint16_t NetworkClient::localPort(int fd) const { struct sockaddr_storage addr; socklen_t len = sizeof addr; @@ -638,22 +638,22 @@ uint16_t WiFiClient::localPort(int fd) const return ntohs(s->sin_port); } -IPAddress WiFiClient::localIP() const +IPAddress NetworkClient::localIP() const { return localIP(fd()); } -uint16_t WiFiClient::localPort() const +uint16_t NetworkClient::localPort() const { return localPort(fd()); } -bool WiFiClient::operator==(const WiFiClient& rhs) +bool NetworkClient::operator==(const NetworkClient& rhs) { return clientSocketHandle == rhs.clientSocketHandle && remotePort() == rhs.remotePort() && remoteIP() == rhs.remoteIP(); } -int WiFiClient::fd() const +int NetworkClient::fd() const { if (clientSocketHandle == NULL) { return -1; @@ -662,12 +662,12 @@ int WiFiClient::fd() const } } -void WiFiClient::setSSE(bool sse) +void NetworkClient::setSSE(bool sse) { _sse = sse; } -bool WiFiClient::isSSE() +bool NetworkClient::isSSE() { return _sse; } diff --git a/libraries/Network/src/NetworkClient.h b/libraries/Network/src/NetworkClient.h new file mode 100644 index 00000000000..d97aabf84ba --- /dev/null +++ b/libraries/Network/src/NetworkClient.h @@ -0,0 +1,113 @@ +/* + Client.h - Base class that provides Client + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + + +#include "Arduino.h" +#include "Client.h" +#include + +class NetworkClientSocketHandle; +class NetworkClientRxBuffer; + +class ESPLwIPClient : public Client +{ +public: + virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0; + virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0; + virtual void setConnectionTimeout(uint32_t milliseconds) = 0; +}; + +class NetworkClient : public ESPLwIPClient +{ +protected: + std::shared_ptr clientSocketHandle; + std::shared_ptr _rxBuffer; + bool _connected; + bool _sse; + int _timeout; + int _lastWriteTimeout; + int _lastReadTimeout; + +public: + NetworkClient *next; + NetworkClient(); + NetworkClient(int fd); + ~NetworkClient(); + int connect(IPAddress ip, uint16_t port); + int connect(IPAddress ip, uint16_t port, int32_t timeout_ms); + int connect(const char *host, uint16_t port); + int connect(const char *host, uint16_t port, int32_t timeout_ms); + size_t write(uint8_t data); + size_t write(const uint8_t *buf, size_t size); + size_t write_P(PGM_P buf, size_t size); + size_t write(Stream &stream); + int available(); + int read(); + int read(uint8_t *buf, size_t size); + int peek(); + void flush(); + void stop(); + uint8_t connected(); + void setSSE(bool sse); + bool isSSE(); + + operator bool() + { + return connected(); + } + bool operator==(const bool value) + { + return bool() == value; + } + bool operator!=(const bool value) + { + return bool() != value; + } + bool operator==(const NetworkClient&); + bool operator!=(const NetworkClient& rhs) + { + return !this->operator==(rhs); + }; + + virtual int fd() const; + + int setSocketOption(int option, char* value, size_t len); + int setSocketOption(int level, int option, const void* value, size_t len); + int getSocketOption(int level, int option, const void* value, size_t size); + int setOption(int option, int *value); + int getOption(int option, int *value); + void setConnectionTimeout(uint32_t milliseconds); + int setNoDelay(bool nodelay); + bool getNoDelay(); + + IPAddress remoteIP() const; + IPAddress remoteIP(int fd) const; + uint16_t remotePort() const; + uint16_t remotePort(int fd) const; + IPAddress localIP() const; + IPAddress localIP(int fd) const; + uint16_t localPort() const; + uint16_t localPort(int fd) const; + + //friend class NetworkServer; + using Print::write; +}; + diff --git a/libraries/Network/src/NetworkEvents.cpp b/libraries/Network/src/NetworkEvents.cpp new file mode 100644 index 00000000000..87508107a1a --- /dev/null +++ b/libraries/Network/src/NetworkEvents.cpp @@ -0,0 +1,383 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "NetworkEvents.h" +#include "NetworkManager.h" +#include "esp_task.h" +#include "esp32-hal.h" + +typedef struct NetworkEventCbList { + static network_event_handle_t current_id; + network_event_handle_t id; + NetworkEventCb cb; + NetworkEventFuncCb fcb; + NetworkEventSysCb scb; + arduino_event_id_t event; + + NetworkEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), event(ARDUINO_EVENT_NONE) {} +} NetworkEventCbList_t; +network_event_handle_t NetworkEventCbList::current_id = 1; + +// arduino dont like std::vectors move static here +static std::vector cbEventList; + +static void _network_event_task(void * arg){ + for (;;) { + ((NetworkEvents*)arg)->checkForEvent(); + } + vTaskDelete(NULL); +} + +NetworkEvents::NetworkEvents() + : _arduino_event_group(NULL) + , _arduino_event_queue(NULL) + , _arduino_event_task_handle(NULL) +{} + +NetworkEvents::~NetworkEvents(){ + if(_arduino_event_task_handle != NULL){ + vTaskDelete(_arduino_event_task_handle); + _arduino_event_task_handle = NULL; + } + if(_arduino_event_group != NULL){ + vEventGroupDelete(_arduino_event_group); + _arduino_event_group = NULL; + } + if(_arduino_event_queue != NULL){ + arduino_event_t *event = NULL; + while(xQueueReceive(_arduino_event_queue, &event, 0) == pdTRUE){ + free(event); + } + vQueueDelete(_arduino_event_queue); + _arduino_event_queue = NULL; + } +} + +static uint32_t _initial_bits = NET_DNS_IDLE_BIT; + +bool NetworkEvents::initNetworkEvents(){ + if(!_arduino_event_group){ + _arduino_event_group = xEventGroupCreate(); + if(!_arduino_event_group){ + log_e("Network Event Group Create Failed!"); + return false; + } + xEventGroupSetBits(_arduino_event_group, _initial_bits); + } + + if(!_arduino_event_queue){ + _arduino_event_queue = xQueueCreate(32, sizeof(arduino_event_t*)); + if(!_arduino_event_queue){ + log_e("Network Event Queue Create Failed!"); + return false; + } + } + + esp_err_t err = esp_event_loop_create_default(); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + log_e("esp_event_loop_create_default failed!"); + return err; + } + + if(!_arduino_event_task_handle){ + xTaskCreateUniversal(_network_event_task, "arduino_events", 4096, this, ESP_TASKD_EVENT_PRIO - 1, &_arduino_event_task_handle, ARDUINO_EVENT_RUNNING_CORE); + if(!_arduino_event_task_handle){ + log_e("Network Event Task Start Failed!"); + return false; + } + } + + return true; +} + +bool NetworkEvents::postEvent(arduino_event_t *data) +{ + if(data == NULL || _arduino_event_queue == NULL){ + return false; + } + arduino_event_t * event = (arduino_event_t*)malloc(sizeof(arduino_event_t)); + if(event == NULL){ + log_e("Arduino Event Malloc Failed!"); + return false; + } + memcpy(event, data, sizeof(arduino_event_t)); + if (xQueueSend(_arduino_event_queue, &event, portMAX_DELAY) != pdPASS) { + log_e("Arduino Event Send Failed!"); + return false; + } + return true; +} + +void NetworkEvents::checkForEvent() +{ + arduino_event_t *event = NULL; + if(_arduino_event_queue == NULL){ + return; + } + if(xQueueReceive(_arduino_event_queue, &event, portMAX_DELAY) != pdTRUE){ + return; + } + if(event == NULL){ + return; + } + log_v("Network Event: %d - %s", event->event_id, eventName(event->event_id)); + for(uint32_t i = 0; i < cbEventList.size(); i++) { + NetworkEventCbList_t entry = cbEventList[i]; + if(entry.cb || entry.fcb || entry.scb) { + if(entry.event == (arduino_event_id_t) event->event_id || entry.event == ARDUINO_EVENT_MAX) { + if(entry.cb) { + entry.cb((arduino_event_id_t) event->event_id); + } else if(entry.fcb) { + entry.fcb((arduino_event_id_t) event->event_id, (arduino_event_info_t) event->event_info); + } else { + entry.scb(event); + } + } + } + } + free(event); +} + +network_event_handle_t NetworkEvents::onEvent(NetworkEventCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return 0; + } + NetworkEventCbList_t newEventHandler; + newEventHandler.cb = cbEvent; + newEventHandler.fcb = NULL; + newEventHandler.scb = NULL; + newEventHandler.event = event; + cbEventList.push_back(newEventHandler); + return newEventHandler.id; +} + +network_event_handle_t NetworkEvents::onEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return 0; + } + NetworkEventCbList_t newEventHandler; + newEventHandler.cb = NULL; + newEventHandler.fcb = cbEvent; + newEventHandler.scb = NULL; + newEventHandler.event = event; + cbEventList.push_back(newEventHandler); + return newEventHandler.id; +} + +network_event_handle_t NetworkEvents::onEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return 0; + } + NetworkEventCbList_t newEventHandler; + newEventHandler.cb = NULL; + newEventHandler.fcb = NULL; + newEventHandler.scb = cbEvent; + newEventHandler.event = event; + cbEventList.push_back(newEventHandler); + return newEventHandler.id; +} + +network_event_handle_t NetworkEvents::onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return 0; + } + NetworkEventCbList_t newEventHandler; + newEventHandler.cb = cbEvent; + newEventHandler.fcb = NULL; + newEventHandler.scb = NULL; + newEventHandler.event = event; + cbEventList.insert(cbEventList.begin(), newEventHandler); + return newEventHandler.id; +} + +network_event_handle_t NetworkEvents::onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return 0; + } + NetworkEventCbList_t newEventHandler; + newEventHandler.cb = NULL; + newEventHandler.fcb = cbEvent; + newEventHandler.scb = NULL; + newEventHandler.event = event; + cbEventList.insert(cbEventList.begin(), newEventHandler); + return newEventHandler.id; +} + +network_event_handle_t NetworkEvents::onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return 0; + } + NetworkEventCbList_t newEventHandler; + newEventHandler.cb = NULL; + newEventHandler.fcb = NULL; + newEventHandler.scb = cbEvent; + newEventHandler.event = event; + cbEventList.insert(cbEventList.begin(), newEventHandler); + return newEventHandler.id; +} + +void NetworkEvents::removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return; + } + + for(uint32_t i = 0; i < cbEventList.size(); i++) { + NetworkEventCbList_t entry = cbEventList[i]; + if(entry.cb == cbEvent && entry.event == event) { + cbEventList.erase(cbEventList.begin() + i); + } + } +} + +template +static size_t getStdFunctionAddress(std::function f) { + typedef T(fnType)(U...); + fnType ** fnPointer = f.template target(); + return (size_t) *fnPointer; +} + +void NetworkEvents::removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return; + } + + for(uint32_t i = 0; i < cbEventList.size(); i++) { + NetworkEventCbList_t entry = cbEventList[i]; + if(getStdFunctionAddress(entry.fcb) == getStdFunctionAddress(cbEvent) && entry.event == event) { + cbEventList.erase(cbEventList.begin() + i); + } + } +} + +void NetworkEvents::removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event) +{ + if(!cbEvent) { + return; + } + + for(uint32_t i = 0; i < cbEventList.size(); i++) { + NetworkEventCbList_t entry = cbEventList[i]; + if(entry.scb == cbEvent && entry.event == event) { + cbEventList.erase(cbEventList.begin() + i); + } + } +} + +void NetworkEvents::removeEvent(network_event_handle_t id) +{ + for(uint32_t i = 0; i < cbEventList.size(); i++) { + NetworkEventCbList_t entry = cbEventList[i]; + if(entry.id == id) { + cbEventList.erase(cbEventList.begin() + i); + } + } +} + +int NetworkEvents::setStatusBits(int bits){ + if(!_arduino_event_group){ + _initial_bits |= bits; + return _initial_bits; + } + return xEventGroupSetBits(_arduino_event_group, bits); +} + +int NetworkEvents::clearStatusBits(int bits){ + if(!_arduino_event_group){ + _initial_bits &= ~bits; + return _initial_bits; + } + return xEventGroupClearBits(_arduino_event_group, bits); +} + +int NetworkEvents::getStatusBits(){ + if(!_arduino_event_group){ + return _initial_bits; + } + return xEventGroupGetBits(_arduino_event_group); +} + +int NetworkEvents::waitStatusBits(int bits, uint32_t timeout_ms){ + if(!_arduino_event_group){ + return 0; + } + return xEventGroupWaitBits( + _arduino_event_group, // The event group being tested. + bits, // The bits within the event group to wait for. + pdFALSE, // bits should be cleared before returning. + pdTRUE, // Don't wait for all bits, any bit will do. + timeout_ms / portTICK_PERIOD_MS ) & bits; // Wait a maximum of timeout_ms for any bit to be set. +} + +/** + * @brief Convert arduino_event_id_t to a C string. + * @param [in] id The event id to be converted. + * @return A string representation of the event id. + * @note: arduino_event_id_t values as of Mar 2023 (arduino-esp32 r2.0.7) are: 0-39 (ARDUINO_EVENT_MAX=40) and are defined in WiFiGeneric.h. + */ +const char * NetworkEvents::eventName(arduino_event_id_t id) { + switch(id) { + case ARDUINO_EVENT_ETH_START: return "ETH_START"; + case ARDUINO_EVENT_ETH_STOP: return "ETH_STOP"; + case ARDUINO_EVENT_ETH_CONNECTED: return "ETH_CONNECTED"; + case ARDUINO_EVENT_ETH_DISCONNECTED: return "ETH_DISCONNECTED"; + case ARDUINO_EVENT_ETH_GOT_IP: return "ETH_GOT_IP"; + case ARDUINO_EVENT_ETH_LOST_IP: return "ETH_LOST_IP"; + case ARDUINO_EVENT_ETH_GOT_IP6: return "ETH_GOT_IP6"; + + // case ARDUINO_EVENT_PPP_START: return "PPP_START"; + // case ARDUINO_EVENT_PPP_STOP: return "PPP_STOP"; + // case ARDUINO_EVENT_PPP_CONNECTED: return "PPP_CONNECTED"; + // case ARDUINO_EVENT_PPP_DISCONNECTED: return "PPP_DISCONNECTED"; + // case ARDUINO_EVENT_PPP_GOT_IP: return "PPP_GOT_IP"; + // case ARDUINO_EVENT_PPP_LOST_IP: return "PPP_LOST_IP"; + // case ARDUINO_EVENT_PPP_GOT_IP6: return "PPP_GOT_IP6"; +#if SOC_WIFI_SUPPORTED + case ARDUINO_EVENT_WIFI_OFF: return "WIFI_OFF"; + case ARDUINO_EVENT_WIFI_READY: return "WIFI_READY"; + case ARDUINO_EVENT_WIFI_SCAN_DONE: return "SCAN_DONE"; + case ARDUINO_EVENT_WIFI_STA_START: return "STA_START"; + case ARDUINO_EVENT_WIFI_STA_STOP: return "STA_STOP"; + case ARDUINO_EVENT_WIFI_STA_CONNECTED: return "STA_CONNECTED"; + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: return "STA_DISCONNECTED"; + case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: return "STA_AUTHMODE_CHANGE"; + case ARDUINO_EVENT_WIFI_STA_GOT_IP: return "STA_GOT_IP"; + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: return "STA_GOT_IP6"; + case ARDUINO_EVENT_WIFI_STA_LOST_IP: return "STA_LOST_IP"; + case ARDUINO_EVENT_WIFI_AP_START: return "AP_START"; + case ARDUINO_EVENT_WIFI_AP_STOP: return "AP_STOP"; + case ARDUINO_EVENT_WIFI_AP_STACONNECTED: return "AP_STACONNECTED"; + case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED: return "AP_STADISCONNECTED"; + case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED: return "AP_STAIPASSIGNED"; + case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED: return "AP_PROBEREQRECVED"; + case ARDUINO_EVENT_WIFI_AP_GOT_IP6: return "AP_GOT_IP6"; + case ARDUINO_EVENT_WIFI_FTM_REPORT: return "FTM_REPORT"; + case ARDUINO_EVENT_WPS_ER_SUCCESS: return "WPS_ER_SUCCESS"; + case ARDUINO_EVENT_WPS_ER_FAILED: return "WPS_ER_FAILED"; + case ARDUINO_EVENT_WPS_ER_TIMEOUT: return "WPS_ER_TIMEOUT"; + case ARDUINO_EVENT_WPS_ER_PIN: return "WPS_ER_PIN"; + case ARDUINO_EVENT_WPS_ER_PBC_OVERLAP: return "WPS_ER_PBC_OVERLAP"; + case ARDUINO_EVENT_SC_SCAN_DONE: return "SC_SCAN_DONE"; + case ARDUINO_EVENT_SC_FOUND_CHANNEL: return "SC_FOUND_CHANNEL"; + case ARDUINO_EVENT_SC_GOT_SSID_PSWD: return "SC_GOT_SSID_PSWD"; + case ARDUINO_EVENT_SC_SEND_ACK_DONE: return "SC_SEND_ACK_DONE"; + case ARDUINO_EVENT_PROV_INIT: return "PROV_INIT"; + case ARDUINO_EVENT_PROV_DEINIT: return "PROV_DEINIT"; + case ARDUINO_EVENT_PROV_START: return "PROV_START"; + case ARDUINO_EVENT_PROV_END: return "PROV_END"; + case ARDUINO_EVENT_PROV_CRED_RECV: return "PROV_CRED_RECV"; + case ARDUINO_EVENT_PROV_CRED_FAIL: return "PROV_CRED_FAIL"; + case ARDUINO_EVENT_PROV_CRED_SUCCESS: return "PROV_CRED_SUCCESS"; +#endif + default: return ""; + } +} diff --git a/libraries/Network/src/NetworkEvents.h b/libraries/Network/src/NetworkEvents.h new file mode 100644 index 00000000000..788470002fd --- /dev/null +++ b/libraries/Network/src/NetworkEvents.h @@ -0,0 +1,169 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "soc/soc_caps.h" +#include "esp_err.h" +#include "esp_event.h" +#include "esp_netif_types.h" +#include "esp_eth_driver.h" +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "freertos/event_groups.h" + +#if SOC_WIFI_SUPPORTED +#include "esp_wifi_types.h" +#include "esp_smartconfig.h" +#include "wifi_provisioning/wifi_config.h" +#endif + +#if SOC_WIFI_SUPPORTED +static const int WIFI_SCANNING_BIT = BIT0; +static const int WIFI_SCAN_DONE_BIT= BIT1; +#endif + +static const int NET_DNS_IDLE_BIT = BIT2; +static const int NET_DNS_DONE_BIT = BIT3; + +#define NET_HAS_IP6_GLOBAL_BIT 0 + +ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS); + +typedef enum { + ARDUINO_EVENT_NONE, + ARDUINO_EVENT_ETH_START, + ARDUINO_EVENT_ETH_STOP, + ARDUINO_EVENT_ETH_CONNECTED, + ARDUINO_EVENT_ETH_DISCONNECTED, + ARDUINO_EVENT_ETH_GOT_IP, + ARDUINO_EVENT_ETH_LOST_IP, + ARDUINO_EVENT_ETH_GOT_IP6, +#if SOC_WIFI_SUPPORTED + ARDUINO_EVENT_WIFI_OFF, + ARDUINO_EVENT_WIFI_READY, + ARDUINO_EVENT_WIFI_SCAN_DONE, + ARDUINO_EVENT_WIFI_STA_START, + ARDUINO_EVENT_WIFI_STA_STOP, + ARDUINO_EVENT_WIFI_STA_CONNECTED, + ARDUINO_EVENT_WIFI_STA_DISCONNECTED, + ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE, + ARDUINO_EVENT_WIFI_STA_GOT_IP, + ARDUINO_EVENT_WIFI_STA_GOT_IP6, + ARDUINO_EVENT_WIFI_STA_LOST_IP, + ARDUINO_EVENT_WIFI_AP_START, + ARDUINO_EVENT_WIFI_AP_STOP, + ARDUINO_EVENT_WIFI_AP_STACONNECTED, + ARDUINO_EVENT_WIFI_AP_STADISCONNECTED, + ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED, + ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED, + ARDUINO_EVENT_WIFI_AP_GOT_IP6, + ARDUINO_EVENT_WIFI_FTM_REPORT, + ARDUINO_EVENT_WPS_ER_SUCCESS, + ARDUINO_EVENT_WPS_ER_FAILED, + ARDUINO_EVENT_WPS_ER_TIMEOUT, + ARDUINO_EVENT_WPS_ER_PIN, + ARDUINO_EVENT_WPS_ER_PBC_OVERLAP, + ARDUINO_EVENT_SC_SCAN_DONE, + ARDUINO_EVENT_SC_FOUND_CHANNEL, + ARDUINO_EVENT_SC_GOT_SSID_PSWD, + ARDUINO_EVENT_SC_SEND_ACK_DONE, + ARDUINO_EVENT_PROV_INIT, + ARDUINO_EVENT_PROV_DEINIT, + ARDUINO_EVENT_PROV_START, + ARDUINO_EVENT_PROV_END, + ARDUINO_EVENT_PROV_CRED_RECV, + ARDUINO_EVENT_PROV_CRED_FAIL, + ARDUINO_EVENT_PROV_CRED_SUCCESS, +#endif + // ARDUINO_EVENT_PPP_START, + // ARDUINO_EVENT_PPP_STOP, + // ARDUINO_EVENT_PPP_CONNECTED, + // ARDUINO_EVENT_PPP_DISCONNECTED, + // ARDUINO_EVENT_PPP_GOT_IP, + // ARDUINO_EVENT_PPP_LOST_IP, + // ARDUINO_EVENT_PPP_GOT_IP6, + ARDUINO_EVENT_MAX +} arduino_event_id_t; + +typedef union { + ip_event_ap_staipassigned_t wifi_ap_staipassigned; + ip_event_got_ip_t got_ip; + ip_event_got_ip6_t got_ip6; + esp_eth_handle_t eth_connected; +#if SOC_WIFI_SUPPORTED + wifi_event_sta_scan_done_t wifi_scan_done; + wifi_event_sta_authmode_change_t wifi_sta_authmode_change; + wifi_event_sta_connected_t wifi_sta_connected; + wifi_event_sta_disconnected_t wifi_sta_disconnected; + wifi_event_sta_wps_er_pin_t wps_er_pin; + wifi_event_sta_wps_fail_reason_t wps_fail_reason; + wifi_event_ap_probe_req_rx_t wifi_ap_probereqrecved; + wifi_event_ap_staconnected_t wifi_ap_staconnected; + wifi_event_ap_stadisconnected_t wifi_ap_stadisconnected; + wifi_event_ftm_report_t wifi_ftm_report; + wifi_sta_config_t prov_cred_recv; + wifi_prov_sta_fail_reason_t prov_fail_reason; + smartconfig_event_got_ssid_pswd_t sc_got_ssid_pswd; +#endif +} arduino_event_info_t; + +typedef struct{ + arduino_event_id_t event_id; + arduino_event_info_t event_info; +} arduino_event_t; + +typedef void (*NetworkEventCb)(arduino_event_id_t event); +typedef std::function NetworkEventFuncCb; +typedef void (*NetworkEventSysCb)(arduino_event_t *event); + +typedef size_t network_event_handle_t; + +class NetworkEvents { +public: + NetworkEvents(); + ~NetworkEvents(); + + network_event_handle_t onEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + network_event_handle_t onEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + network_event_handle_t onEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + void removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + void removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + void removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + void removeEvent(network_event_handle_t event_handle); + + const char * eventName(arduino_event_id_t id); + + void checkForEvent(); + bool postEvent(arduino_event_t *event); + + int getStatusBits(); + int waitStatusBits(int bits, uint32_t timeout_ms); + int setStatusBits(int bits); + int clearStatusBits(int bits); + + friend class ESP_NetworkInterface; + friend class ETHClass; +#if SOC_WIFI_SUPPORTED + friend class STAClass; + friend class APClass; + friend class WiFiGenericClass; +#endif + +protected: + bool initNetworkEvents(); + network_event_handle_t onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + network_event_handle_t onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + network_event_handle_t onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); +private: + EventGroupHandle_t _arduino_event_group; + QueueHandle_t _arduino_event_queue; + TaskHandle_t _arduino_event_task_handle; +}; + + diff --git a/libraries/Network/src/NetworkInterface.cpp b/libraries/Network/src/NetworkInterface.cpp new file mode 100644 index 00000000000..bfed01ccca8 --- /dev/null +++ b/libraries/Network/src/NetworkInterface.cpp @@ -0,0 +1,718 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "NetworkInterface.h" +#include "esp_netif.h" +#include "esp_netif_defaults.h" +#include "esp_system.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" +#include "dhcpserver/dhcpserver.h" +#include "dhcpserver/dhcpserver_options.h" +#include "esp32-hal-log.h" + +static NetworkInterface * _interfaces[ESP_NETIF_ID_MAX] = { NULL, NULL, NULL, NULL, NULL, NULL}; +static esp_event_handler_instance_t _ip_ev_instance = NULL; + +static NetworkInterface * getNetifByEspNetif(esp_netif_t *esp_netif){ + for (int i = 0; i < ESP_NETIF_ID_MAX; ++i){ + if(_interfaces[i] != NULL && _interfaces[i]->netif() == esp_netif){ + return _interfaces[i]; + } + } + return NULL; +} + +NetworkInterface * getNetifByID(Network_Interface_ID id){ + if(id < ESP_NETIF_ID_MAX){ + return _interfaces[id]; + } + return NULL; +} + +static void _ip_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + if (event_base == IP_EVENT){ + NetworkInterface * netif = NULL; + if(event_id == IP_EVENT_STA_GOT_IP || event_id == IP_EVENT_ETH_GOT_IP || event_id == IP_EVENT_PPP_GOT_IP){ + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + netif = getNetifByEspNetif(event->esp_netif); + } else if(event_id == IP_EVENT_STA_LOST_IP || event_id == IP_EVENT_PPP_LOST_IP || event_id == IP_EVENT_ETH_LOST_IP){ + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + netif = getNetifByEspNetif(event->esp_netif); + } else if(event_id == IP_EVENT_GOT_IP6){ + ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data; + netif = getNetifByEspNetif(event->esp_netif); + } else if(event_id == IP_EVENT_AP_STAIPASSIGNED){ + ip_event_ap_staipassigned_t* event = (ip_event_ap_staipassigned_t*) event_data; + netif = getNetifByEspNetif(event->esp_netif); + } + if(netif != NULL){ + netif->_onIpEvent(event_id, event_data); + } + } +} + +void NetworkInterface::_onIpEvent(int32_t event_id, void* event_data){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; + if(event_id == _got_ip_event_id){ + setStatusBits(ESP_NETIF_HAS_IP_BIT); +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + log_v("%s Got %sIP: " IPSTR " MASK: " IPSTR " GW: " IPSTR, desc(), event->ip_changed?"New ":"Same ", IP2STR(&event->ip_info.ip), IP2STR(&event->ip_info.netmask), IP2STR(&event->ip_info.gw)); +#endif + memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t)); +#if SOC_WIFI_SUPPORTED + if(_interface_id == ESP_NETIF_ID_STA){ + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP; + } else +#endif + // if(_interface_id == ESP_NETIF_ID_PPP){ + // arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP; + // } else + if(_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX){ + arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP; + } + } else if(event_id == _lost_ip_event_id){ + clearStatusBits(ESP_NETIF_HAS_IP_BIT); +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + log_v("%s Lost IP", desc()); +#endif +#if SOC_WIFI_SUPPORTED + if(_interface_id == ESP_NETIF_ID_STA){ + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP; + } else +#endif + // if(_interface_id == ESP_NETIF_ID_PPP){ + // arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP; + // } else + if(_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX){ + arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP; + } + } else if(event_id == IP_EVENT_GOT_IP6){ + ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data; + esp_ip6_addr_type_t addr_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + if(addr_type == ESP_IP6_ADDR_IS_GLOBAL){ + setStatusBits(ESP_NETIF_HAS_GLOBAL_IP6_BIT); + } else if(addr_type == ESP_IP6_ADDR_IS_LINK_LOCAL){ + setStatusBits(ESP_NETIF_HAS_LOCAL_IP6_BIT); + } +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + char if_name[NETIF_NAMESIZE] = {0,}; + netif_index_to_name(event->ip6_info.ip.zone, if_name); + static const char * addr_types[] = { "UNKNOWN", "GLOBAL", "LINK_LOCAL", "SITE_LOCAL", "UNIQUE_LOCAL", "IPV4_MAPPED_IPV6" }; + log_v("IF %s Got IPv6: Interface: %d, IP Index: %d, Type: %s, Zone: %d (%s), Address: " IPV6STR, desc(), _interface_id, event->ip_index, addr_types[addr_type], event->ip6_info.ip.zone, if_name, IPV62STR(event->ip6_info.ip)); +#endif + memcpy(&arduino_event.event_info.got_ip6, event_data, sizeof(ip_event_got_ip6_t)); +#if SOC_WIFI_SUPPORTED + if(_interface_id == ESP_NETIF_ID_STA){ + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP6; + } else if(_interface_id == ESP_NETIF_ID_AP){ + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6; + } else +#endif + // if(_interface_id == ESP_NETIF_ID_PPP){ + // arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6; + // } else + if(_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX){ + arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; + } +#if SOC_WIFI_SUPPORTED + } else if(event_id == IP_EVENT_AP_STAIPASSIGNED && _interface_id == ESP_NETIF_ID_AP){ + setStatusBits(ESP_NETIF_HAS_IP_BIT); +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + ip_event_ap_staipassigned_t* event = (ip_event_ap_staipassigned_t*) event_data; + log_v("%s Assigned IP: " IPSTR " to MAC: %02X:%02X:%02X:%02X:%02X:%02X", desc(), IP2STR(&event->ip), event->mac[0], event->mac[1], event->mac[2], event->mac[3], event->mac[4], event->mac[5]); +#endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED; + memcpy(&arduino_event.event_info.wifi_ap_staipassigned, event_data, sizeof(ip_event_ap_staipassigned_t)); +#endif + } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} + +NetworkInterface::NetworkInterface() + : _esp_netif(NULL) + , _interface_event_group(NULL) + , _initial_bits(0) + , _got_ip_event_id(-1) + , _lost_ip_event_id(-1) + , _interface_id(ESP_NETIF_ID_MAX) + , _is_server_if(false) +{} + +NetworkInterface::~NetworkInterface(){ + destroyNetif(); +} + +IPAddress NetworkInterface::calculateNetworkID(IPAddress ip, IPAddress subnet) const { + IPAddress networkID; + + for (size_t i = 0; i < 4; i++) + networkID[i] = subnet[i] & ip[i]; + + return networkID; +} + +IPAddress NetworkInterface::calculateBroadcast(IPAddress ip, IPAddress subnet) const { + IPAddress broadcastIp; + + for (int i = 0; i < 4; i++) + broadcastIp[i] = ~subnet[i] | ip[i]; + + return broadcastIp; +} + +uint8_t NetworkInterface::calculateSubnetCIDR(IPAddress subnetMask) const { + uint8_t CIDR = 0; + + for (uint8_t i = 0; i < 4; i++) { + if (subnetMask[i] == 0x80) // 128 + CIDR += 1; + else if (subnetMask[i] == 0xC0) // 192 + CIDR += 2; + else if (subnetMask[i] == 0xE0) // 224 + CIDR += 3; + else if (subnetMask[i] == 0xF0) // 242 + CIDR += 4; + else if (subnetMask[i] == 0xF8) // 248 + CIDR += 5; + else if (subnetMask[i] == 0xFC) // 252 + CIDR += 6; + else if (subnetMask[i] == 0xFE) // 254 + CIDR += 7; + else if (subnetMask[i] == 0xFF) // 255 + CIDR += 8; + } + + return CIDR; +} + +int NetworkInterface::setStatusBits(int bits) { + if(!_interface_event_group){ + _initial_bits |= bits; + return _initial_bits; + } + return xEventGroupSetBits(_interface_event_group, bits); +} + +int NetworkInterface::clearStatusBits(int bits) { + if(!_interface_event_group){ + _initial_bits &= ~bits; + return _initial_bits; + } + return xEventGroupClearBits(_interface_event_group, bits) ; +} + +int NetworkInterface::getStatusBits() const { + if(!_interface_event_group){ + return _initial_bits; + } + return xEventGroupGetBits(_interface_event_group); +} + +int NetworkInterface::waitStatusBits(int bits, uint32_t timeout_ms) const { + if(!_interface_event_group){ + return 0; + } + bits = xEventGroupWaitBits( + _interface_event_group, // The event group being tested. + bits, // The bits within the event group to wait for. + pdFALSE, // bits should be cleared before returning. + pdTRUE, // Don't wait for all bits, any bit will do. + timeout_ms / portTICK_PERIOD_MS ) & bits; // Wait a maximum of timeout_ms for any bit to be set. + return bits; +} + +void NetworkInterface::destroyNetif() { + if(_ip_ev_instance != NULL){ + esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &_ip_event_cb); + _ip_ev_instance = NULL; + } + if(_esp_netif != NULL){ + esp_netif_destroy(_esp_netif); + _esp_netif = NULL; + } + if(_interface_event_group != NULL){ + vEventGroupDelete(_interface_event_group); + _interface_event_group = NULL; + _initial_bits = 0; + } +} + +bool NetworkInterface::initNetif(Network_Interface_ID interface_id, bool server_interface) { + if(_esp_netif == NULL || interface_id >= ESP_NETIF_ID_MAX){ + return false; + } + _is_server_if = server_interface; + _interface_id = interface_id; + _got_ip_event_id = esp_netif_get_event_id(_esp_netif, ESP_NETIF_IP_EVENT_GOT_IP); + _lost_ip_event_id = esp_netif_get_event_id(_esp_netif, ESP_NETIF_IP_EVENT_LOST_IP); + _interfaces[_interface_id] = this; + + if(_interface_event_group == NULL){ + _interface_event_group = xEventGroupCreate(); + if(!_interface_event_group){ + log_e("Interface Event Group Create Failed!"); + return false; + } + setStatusBits(_initial_bits); + } + + if(_ip_ev_instance == NULL && esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &_ip_event_cb, NULL, &_ip_ev_instance)){ + log_e("event_handler_instance_register for IP_EVENT Failed!"); + return false; + } + return true; +} + +bool NetworkInterface::started() const { + return (getStatusBits() & ESP_NETIF_STARTED_BIT) != 0; +} + +bool NetworkInterface::connected() const { + return (getStatusBits() & ESP_NETIF_CONNECTED_BIT) != 0; +} + +bool NetworkInterface::hasIP() const { + return (getStatusBits() & ESP_NETIF_HAS_IP_BIT) != 0; +} + +bool NetworkInterface::hasLinkLocalIPv6() const { + return (getStatusBits() & ESP_NETIF_HAS_LOCAL_IP6_BIT) != 0; +} + +bool NetworkInterface::hasGlobalIPv6() const { + return (getStatusBits() & ESP_NETIF_HAS_GLOBAL_IP6_BIT) != 0; +} + +bool NetworkInterface::enableIPv6(bool en) +{ + if (en) { + setStatusBits(ESP_NETIF_WANT_IP6_BIT); + } else { + clearStatusBits(ESP_NETIF_WANT_IP6_BIT); + } + return true; +} + +bool NetworkInterface::dnsIP(uint8_t dns_no, IPAddress ip) +{ + if(_esp_netif == NULL || dns_no > 2){ + return false; + } + if(_is_server_if && dns_no > 0){ + log_e("Server interfaces can have only one DNS server."); + return false; + } + esp_netif_dns_info_t d; + // ToDo: can this work with IPv6 addresses? + d.ip.type = IPADDR_TYPE_V4; + if(static_cast(ip) != 0){ + d.ip.u_addr.ip4.addr = static_cast(ip); + } else { + d.ip.u_addr.ip4.addr = 0; + } + if(esp_netif_set_dns_info(_esp_netif, (esp_netif_dns_type_t)dns_no, &d) != ESP_OK){ + return false; + } + return true; +} + +bool NetworkInterface::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2, IPAddress dns3) +{ + if(_esp_netif == NULL){ + return false; + } + esp_err_t err = ESP_OK; + esp_netif_ip_info_t info; + esp_netif_dns_info_t d1; + esp_netif_dns_info_t d2; + esp_netif_dns_info_t d3; + d1.ip.type = IPADDR_TYPE_V4; + d2.ip.type = IPADDR_TYPE_V4; + d3.ip.type = IPADDR_TYPE_V4; + + if(static_cast(local_ip) != 0){ + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + d1.ip.u_addr.ip4.addr = static_cast(dns1); + d2.ip.u_addr.ip4.addr = static_cast(dns2); + d3.ip.u_addr.ip4.addr = static_cast(dns3); + } else { + info.ip.addr = 0; + info.gw.addr = 0; + info.netmask.addr = 0; + d1.ip.u_addr.ip4.addr = 0; + d2.ip.u_addr.ip4.addr = 0; + d3.ip.u_addr.ip4.addr = 0; + } + + if(_is_server_if){ + // Stop DHCPS + err = esp_netif_dhcps_stop(_esp_netif); + if(err && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED){ + log_e("DHCPS Stop Failed! 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + + // Set IPv4, Netmask, Gateway + err = esp_netif_set_ip_info(_esp_netif, &info); + if(err){ + log_e("Netif Set IP Failed! 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + + // Set DNS Server + if(d2.ip.u_addr.ip4.addr != 0){ + esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_MAIN, &d2); + } + + dhcps_lease_t lease; + lease.enable = true; + uint8_t CIDR = calculateSubnetCIDR(subnet); + log_v("SoftAP: %s | Gateway: %s | DHCP Start: %s | Netmask: %s", local_ip.toString().c_str(), gateway.toString().c_str(), dns1.toString().c_str(), subnet.toString().c_str()); + // netmask must have room for at least 12 IP addresses (AP + GW + 10 DHCP Leasing addresses) + // netmask also must be limited to the last 8 bits of IPv4, otherwise this function won't work + // IDF NETIF checks netmask for the 3rd byte: https://github.com/espressif/esp-idf/blob/master/components/esp_netif/lwip/esp_netif_lwip.c#L1857-L1862 + if (CIDR > 28 || CIDR < 24) { + log_e("Bad netmask. It must be from /24 to /28 (255.255.255. 0<->240)"); + return false; // ESP_FAIL if initializing failed + } + #define _byte_swap32(num) (((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000)) + // The code below is ready for any netmask, not limited to 255.255.255.0 + uint32_t netmask = _byte_swap32(info.netmask.addr); + uint32_t ap_ipaddr = _byte_swap32(info.ip.addr); + uint32_t dhcp_ipaddr = _byte_swap32(static_cast(dns1)); + dhcp_ipaddr = dhcp_ipaddr == 0 ? ap_ipaddr + 1 : dhcp_ipaddr; + uint32_t leaseStartMax = ~netmask - 10; + // there will be 10 addresses for DHCP to lease + lease.start_ip.addr = dhcp_ipaddr; + lease.end_ip.addr = lease.start_ip.addr + 10; + // Check if local_ip is in the same subnet as the dhcp leasing range initial address + if ((ap_ipaddr & netmask) != (dhcp_ipaddr & netmask)) { + log_e("The AP IP address (%s) and the DHCP start address (%s) must be in the same subnet", + local_ip.toString().c_str(), IPAddress(_byte_swap32(dhcp_ipaddr)).toString().c_str()); + return false; // ESP_FAIL if initializing failed + } + // prevents DHCP lease range to overflow subnet range + if ((dhcp_ipaddr & ~netmask) >= leaseStartMax) { + // make first DHCP lease addr stay in the begining of the netmask range + lease.start_ip.addr = (dhcp_ipaddr & netmask) + 1; + lease.end_ip.addr = lease.start_ip.addr + 10; + log_w("DHCP Lease out of range - Changing DHCP leasing start to %s", IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str()); + } + // Check if local_ip is within DHCP range + if (ap_ipaddr >= lease.start_ip.addr && ap_ipaddr <= lease.end_ip.addr) { + log_e("The AP IP address (%s) can't be within the DHCP range (%s -- %s)", + local_ip.toString().c_str(), IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str(), IPAddress(_byte_swap32(lease.end_ip.addr)).toString().c_str()); + return false; // ESP_FAIL if initializing failed + } + // Check if gateway is within DHCP range + uint32_t gw_ipaddr = _byte_swap32(info.gw.addr); + bool gw_in_same_subnet = (gw_ipaddr & netmask) == (ap_ipaddr & netmask); + if (gw_in_same_subnet && gw_ipaddr >= lease.start_ip.addr && gw_ipaddr <= lease.end_ip.addr) { + log_e("The GatewayP address (%s) can't be within the DHCP range (%s -- %s)", + gateway.toString().c_str(), IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str(), IPAddress(_byte_swap32(lease.end_ip.addr)).toString().c_str()); + return false; // ESP_FAIL if initializing failed + } + // all done, just revert back byte order of DHCP lease range + lease.start_ip.addr = _byte_swap32(lease.start_ip.addr); + lease.end_ip.addr = _byte_swap32(lease.end_ip.addr); + log_v("DHCP Server Range: %s to %s", IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str()); + err = esp_netif_dhcps_option( + _esp_netif, + ESP_NETIF_OP_SET, + ESP_NETIF_REQUESTED_IP_ADDRESS, + (void*)&lease, sizeof(dhcps_lease_t) + ); + if(err){ + log_e("DHCPS Set Lease Failed! 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + // Start DHCPS + err = esp_netif_dhcps_start(_esp_netif); + if(err){ + log_e("DHCPS Start Failed! 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + } else { + // Stop DHCPC + err = esp_netif_dhcpc_stop(_esp_netif); + if(err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED){ + log_e("DHCP could not be stopped! Error: 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + + clearStatusBits(ESP_NETIF_HAS_IP_BIT); + + // Set IPv4, Netmask, Gateway + err = esp_netif_set_ip_info(_esp_netif, &info); + if(err != ERR_OK){ + log_e("ETH IP could not be configured! Error: 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + + // Set DNS Servers + esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_MAIN, &d1); + esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_BACKUP, &d2); + esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_FALLBACK, &d3); + + // Start DHCPC if static IP was set + if(info.ip.addr == 0){ + err = esp_netif_dhcpc_start(_esp_netif); + if(err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED){ + log_w("DHCP could not be started! Error: 0x%04x: %s", err, esp_err_to_name(err)); + return false; + } + } else { + setStatusBits(ESP_NETIF_HAS_IP_BIT); + } + } + + return true; +} + +const char * NetworkInterface::getHostname() const +{ + if(_esp_netif == NULL){ + return ""; + } + const char * hostname; + if(esp_netif_get_hostname(_esp_netif, &hostname)){ + return NULL; + } + return hostname; +} + +bool NetworkInterface::setHostname(const char * hostname) const +{ + if(_esp_netif == NULL){ + return false; + } + return esp_netif_set_hostname(_esp_netif, hostname) == 0; +} + +bool NetworkInterface::linkUp() const +{ + if(_esp_netif == NULL){ + return false; + } + return esp_netif_is_netif_up(_esp_netif); +} + +const char * NetworkInterface::ifkey(void) const +{ + if(_esp_netif == NULL){ + return ""; + } + return esp_netif_get_ifkey(_esp_netif); +} + +const char * NetworkInterface::desc(void) const +{ + if(_esp_netif == NULL){ + return ""; + } + return esp_netif_get_desc(_esp_netif); +} + +String NetworkInterface::impl_name(void) const +{ + if(_esp_netif == NULL){ + return String(""); + } + char netif_name[8]; + esp_err_t err = esp_netif_get_netif_impl_name(_esp_netif, netif_name); + if(err != ESP_OK){ + log_e("Failed to get netif impl_name: %d", err); + return String(""); + } + return String(netif_name); +} + +uint8_t * NetworkInterface::macAddress(uint8_t* mac) const +{ + if(!mac || _esp_netif == NULL){ + return NULL; + } + esp_err_t err = esp_netif_get_mac(_esp_netif, mac); + if(err != ESP_OK){ + log_e("Failed to get netif mac: %d", err); + return NULL; + } + // getMac(mac); + return mac; +} + +String NetworkInterface::macAddress(void) const +{ + uint8_t mac[6] = {0,0,0,0,0,0}; + char macStr[18] = { 0 }; + macAddress(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +IPAddress NetworkInterface::localIP() const +{ + if(_esp_netif == NULL){ + return IPAddress(); + } + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(_esp_netif, &ip)){ + return IPAddress(); + } + return IPAddress(ip.ip.addr); +} + +IPAddress NetworkInterface::subnetMask() const +{ + if(_esp_netif == NULL){ + return IPAddress(); + } + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(_esp_netif, &ip)){ + return IPAddress(); + } + return IPAddress(ip.netmask.addr); +} + +IPAddress NetworkInterface::gatewayIP() const +{ + if(_esp_netif == NULL){ + return IPAddress(); + } + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(_esp_netif, &ip)){ + return IPAddress(); + } + return IPAddress(ip.gw.addr); +} + +IPAddress NetworkInterface::dnsIP(uint8_t dns_no) const +{ + if(_esp_netif == NULL){ + return IPAddress(); + } + esp_netif_dns_info_t d; + if(esp_netif_get_dns_info(_esp_netif, dns_no?ESP_NETIF_DNS_BACKUP:ESP_NETIF_DNS_MAIN, &d) != ESP_OK){ + return IPAddress(); + } + return IPAddress(d.ip.u_addr.ip4.addr); +} + +IPAddress NetworkInterface::broadcastIP() const +{ + if(_esp_netif == NULL){ + return IPAddress(); + } + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(_esp_netif, &ip)){ + return IPAddress(); + } + return calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +IPAddress NetworkInterface::networkID() const +{ + if(_esp_netif == NULL){ + return IPAddress(); + } + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(_esp_netif, &ip)){ + return IPAddress(); + } + return calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +uint8_t NetworkInterface::subnetCIDR() const +{ + if(_esp_netif == NULL){ + return (uint8_t)0; + } + esp_netif_ip_info_t ip; + if(esp_netif_get_ip_info(_esp_netif, &ip)){ + return (uint8_t)0; + } + return calculateSubnetCIDR(IPAddress(ip.netmask.addr)); +} + +IPAddress NetworkInterface::linkLocalIPv6() const +{ + if(_esp_netif == NULL){ + return IPAddress(IPv6); + } + static esp_ip6_addr_t addr; + if(esp_netif_get_ip6_linklocal(_esp_netif, &addr)){ + return IPAddress(IPv6); + } + return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); +} + +IPAddress NetworkInterface::globalIPv6() const +{ + if(_esp_netif == NULL){ + return IPAddress(IPv6); + } + static esp_ip6_addr_t addr; + if(esp_netif_get_ip6_global(_esp_netif, &addr)){ + return IPAddress(IPv6); + } + return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); +} + +size_t NetworkInterface::printTo(Print & out) const { + size_t bytes = 0; + bytes += out.print(esp_netif_get_desc(_esp_netif)); + bytes += out.print(":"); + if(esp_netif_is_netif_up(_esp_netif)){ + bytes += out.print(" "); + + bytes += out.print(" "); + bytes += out.print("ether "); + bytes += out.print(macAddress()); + bytes += out.println(); + + bytes += out.print(" "); + bytes += out.print("inet "); + bytes += out.print(localIP()); + bytes += out.print(" netmask "); + bytes += out.print(subnetMask()); + bytes += out.print(" broadcast "); + bytes += out.print(broadcastIP()); + bytes += out.println(); + + bytes += out.print(" "); + bytes += out.print("gateway "); + bytes += out.print(gatewayIP()); + bytes += out.print(" dns "); + bytes += out.print(dnsIP()); + bytes += out.println(); + + static const char * types[] = { "UNKNOWN", "GLOBAL", "LINK_LOCAL", "SITE_LOCAL", "UNIQUE_LOCAL", "IPV4_MAPPED_IPV6" }; + esp_ip6_addr_t if_ip6[CONFIG_LWIP_IPV6_NUM_ADDRESSES]; + int v6addrs = esp_netif_get_all_ip6(_esp_netif, if_ip6); + for (int i = 0; i < v6addrs; ++i){ + bytes += out.print(" "); + bytes += out.print("inet6 "); + bytes += IPAddress(IPv6, (const uint8_t *)if_ip6[i].addr, if_ip6[i].zone).printTo(out, true); + bytes += out.print(" type "); + bytes += out.print(types[esp_netif_ip6_get_addr_type(&if_ip6[i])]); + bytes += out.println(); + } + + return bytes; +} diff --git a/libraries/Network/src/NetworkInterface.h b/libraries/Network/src/NetworkInterface.h new file mode 100644 index 00000000000..cda046ccc6d --- /dev/null +++ b/libraries/Network/src/NetworkInterface.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_netif_types.h" +#include "esp_event.h" +#include "Arduino.h" +#include "NetworkManager.h" +#include "Printable.h" + +typedef enum { + ESP_NETIF_ID_STA, + ESP_NETIF_ID_AP, + ESP_NETIF_ID_PPP, + ESP_NETIF_ID_ETH0, + ESP_NETIF_ID_ETH1, + ESP_NETIF_ID_ETH2, + ESP_NETIF_ID_MAX +} Network_Interface_ID; + +static const int ESP_NETIF_STARTED_BIT = BIT0; +static const int ESP_NETIF_CONNECTED_BIT = BIT1; +static const int ESP_NETIF_HAS_IP_BIT = BIT2; +static const int ESP_NETIF_HAS_LOCAL_IP6_BIT = BIT3; +static const int ESP_NETIF_HAS_GLOBAL_IP6_BIT = BIT4; +static const int ESP_NETIF_WANT_IP6_BIT = BIT5; + +#define ESP_NETIF_ID_ETH ESP_NETIF_ID_ETH0 + +class NetworkInterface: public Printable { + public: + NetworkInterface(); + virtual ~NetworkInterface(); + + // For server interfaces (WiFi AP), dns1 is the DHCP lease range start and dns2 is the DNS. dns3 is not used + bool config(IPAddress local_ip = (uint32_t)0x00000000, IPAddress gateway = (uint32_t)0x00000000, IPAddress subnet = (uint32_t)0x00000000, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000, IPAddress dns3 = (uint32_t)0x00000000); + bool dnsIP(uint8_t dns_no, IPAddress ip); + + const char * getHostname() const; + bool setHostname(const char * hostname) const; + + bool started() const; + bool connected() const; + bool hasIP() const; + bool hasLinkLocalIPv6() const; + bool hasGlobalIPv6() const; + bool enableIPv6(bool en=true); + + bool linkUp() const; + const char * ifkey() const; + const char * desc() const; + String impl_name() const; + + uint8_t * macAddress(uint8_t* mac) const; + String macAddress() const; + IPAddress localIP() const; + IPAddress subnetMask() const; + IPAddress gatewayIP() const; + IPAddress dnsIP(uint8_t dns_no = 0) const; + IPAddress broadcastIP() const; + IPAddress networkID() const; + uint8_t subnetCIDR() const; + IPAddress linkLocalIPv6() const; + IPAddress globalIPv6() const; + + size_t printTo(Print & out) const; + + esp_netif_t * netif(){ return _esp_netif; } + int getStatusBits() const; + int waitStatusBits(int bits, uint32_t timeout_ms) const; + + protected: + esp_netif_t *_esp_netif; + EventGroupHandle_t _interface_event_group; + int _initial_bits; + int32_t _got_ip_event_id; + int32_t _lost_ip_event_id; + Network_Interface_ID _interface_id; + bool _is_server_if; + + bool initNetif(Network_Interface_ID interface_id, bool server_interface=false); + void destroyNetif(); + int setStatusBits(int bits); + int clearStatusBits(int bits); + + // virtual void getMac(uint8_t* mac) = 0; + virtual size_t printDriverInfo(Print & out) const = 0; + + public: + void _onIpEvent(int32_t event_id, void* event_data); + + private: + IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet) const; + IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet) const; + uint8_t calculateSubnetCIDR(IPAddress subnetMask) const; +}; diff --git a/libraries/Network/src/NetworkManager.cpp b/libraries/Network/src/NetworkManager.cpp new file mode 100644 index 00000000000..779b4bf050f --- /dev/null +++ b/libraries/Network/src/NetworkManager.cpp @@ -0,0 +1,177 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "NetworkManager.h" +#include "NetworkInterface.h" +#include "esp_netif.h" +#include "lwip/ip_addr.h" +#include "lwip/dns.h" +#include "esp32-hal-log.h" +#include "esp_mac.h" + +NetworkManager::NetworkManager(){ + +} + +bool NetworkManager::begin(){ + static bool initialized = false; + if(!initialized){ + initialized = true; +#if CONFIG_IDF_TARGET_ESP32 + uint8_t mac[8]; + if(esp_efuse_mac_get_default(mac) == ESP_OK){ + esp_base_mac_addr_set(mac); + } +#endif + initialized = esp_netif_init() == ESP_OK; + if(!initialized){ + log_e("esp_netif_init failed!"); + } + } + if(initialized){ + initNetworkEvents(); + } + return initialized; +} + +typedef struct gethostbynameParameters { + const char *hostname; + ip_addr_t addr; + uint8_t addr_type; + int result; +} gethostbynameParameters_t; + +/** + * DNS callback + * @param name + * @param ipaddr + * @param callback_arg + */ +static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) +{ + gethostbynameParameters_t *parameters = static_cast(callback_arg); + if(ipaddr) { + if(parameters->result == 0){ + memcpy(&(parameters->addr), ipaddr, sizeof(ip_addr_t)); + parameters->result = 1; + } + } else { + parameters->result = -1; + } + Network.setStatusBits(NET_DNS_DONE_BIT); +} + +/** + * Callback to execute dns_gethostbyname in lwIP's TCP/IP context + * @param param Parameters for dns_gethostbyname call + */ +static esp_err_t wifi_gethostbyname_tcpip_ctx(void *param) +{ + gethostbynameParameters_t *parameters = static_cast(param); + return dns_gethostbyname_addrtype(parameters->hostname, ¶meters->addr, &wifi_dns_found_callback, parameters, parameters->addr_type); +} + +/** + * Resolve the given hostname to an IP address. + * @param aHostname Name to be resolved + * @param aResult IPAddress structure to store the returned IP address + * @return 1 if aIPAddrString was successfully converted to an IP address, + * else error code + */ +int NetworkManager::hostByName(const char* aHostname, IPAddress& aResult, bool preferV6) +{ + err_t err = ERR_OK; + gethostbynameParameters_t params; + + // This should generally check if we have a global address assigned to one of the interfaces. + // If such address is not assigned, there is no point in trying to get V6 from DNS as we will not be able to reach it. + // That is of course, if 'preferV6' is not set to true + static bool hasGlobalV6 = false; + bool hasGlobalV6Now = false;//ToDo: implement this! + if(hasGlobalV6 != hasGlobalV6Now){ + hasGlobalV6 = hasGlobalV6Now; + dns_clear_cache(); + log_d("Clearing DNS cache"); + } + + aResult = static_cast(0); + params.hostname = aHostname; + params.addr_type = (preferV6 || hasGlobalV6)?LWIP_DNS_ADDRTYPE_IPV6_IPV4:LWIP_DNS_ADDRTYPE_IPV4; + params.result = 0; + aResult.to_ip_addr_t(&(params.addr)); + + if (!aResult.fromString(aHostname)) { + Network.waitStatusBits(NET_DNS_IDLE_BIT, 16000); + Network.clearStatusBits(NET_DNS_IDLE_BIT | NET_DNS_DONE_BIT); + + err = esp_netif_tcpip_exec(wifi_gethostbyname_tcpip_ctx, ¶ms); + if (err == ERR_OK) { + aResult.from_ip_addr_t(&(params.addr)); + } else if (err == ERR_INPROGRESS) { + Network.waitStatusBits(NET_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] + Network.clearStatusBits(NET_DNS_DONE_BIT); + if (params.result == 1) { + aResult.from_ip_addr_t(&(params.addr)); + err = ERR_OK; + } + } + Network.setStatusBits(NET_DNS_IDLE_BIT); + } + if (err == ERR_OK) { + return 1; + } + log_e("DNS Failed for '%s' with error '%d' and result '%d'", aHostname, err, params.result); + return err; +} + +uint8_t * NetworkManager::macAddress(uint8_t * mac){ + esp_base_mac_addr_get(mac); + return mac; +} + +String NetworkManager::macAddress(void){ + uint8_t mac[6]; + char macStr[18] = { 0 }; + macAddress(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +static char default_hostname[32] = {0,}; + +const char * NetworkManager::getHostname() +{ + if(default_hostname[0] == 0){ + uint8_t eth_mac[6]; + esp_base_mac_addr_get(eth_mac); + snprintf(default_hostname, 32, "%s%02X%02X%02X", CONFIG_IDF_TARGET "-", eth_mac[3], eth_mac[4], eth_mac[5]); + } + return (const char *)default_hostname; +} + +bool NetworkManager::setHostname(const char * name) +{ + if(name){ + snprintf(default_hostname, 32, "%s", name); + } + return true; +} + +NetworkInterface * getNetifByID(Network_Interface_ID id); + +size_t NetworkManager::printTo(Print & out) const { + size_t bytes = 0; + + for (int i = 0; i < ESP_NETIF_ID_MAX; ++i){ + NetworkInterface * iface = getNetifByID((Network_Interface_ID)i); + if(iface != NULL && iface->netif() != NULL){ + bytes += out.println(*iface); + } + } + return bytes; +} + + +NetworkManager Network; diff --git a/libraries/Network/src/NetworkManager.h b/libraries/Network/src/NetworkManager.h new file mode 100644 index 00000000000..0202dd95aff --- /dev/null +++ b/libraries/Network/src/NetworkManager.h @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "NetworkEvents.h" +#include "IPAddress.h" +#include "WString.h" + +class NetworkManager : public NetworkEvents, public Printable { +public: + NetworkManager(); + + bool begin(); + int hostByName(const char *aHostname, IPAddress &aResult, bool preferV6=false); + uint8_t * macAddress(uint8_t * mac); + String macAddress(); + + size_t printTo(Print & out) const; + + static const char * getHostname(); + static bool setHostname(const char * hostname); + static bool hostname(const String& aHostname) { return setHostname(aHostname.c_str()); } +}; + +extern NetworkManager Network; diff --git a/libraries/WiFi/src/WiFiServer.cpp b/libraries/Network/src/NetworkServer.cpp similarity index 86% rename from libraries/WiFi/src/WiFiServer.cpp rename to libraries/Network/src/NetworkServer.cpp index 2e8dcc9e350..a8a15c5cbe5 100644 --- a/libraries/WiFi/src/WiFiServer.cpp +++ b/libraries/Network/src/NetworkServer.cpp @@ -16,14 +16,14 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "WiFiServer.h" +#include "NetworkServer.h" #include #include #undef write #undef close -int WiFiServer::setTimeout(uint32_t seconds){ +int NetworkServer::setTimeout(uint32_t seconds){ struct timeval tv; tv.tv_sec = seconds; tv.tv_usec = 0; @@ -32,13 +32,13 @@ int WiFiServer::setTimeout(uint32_t seconds){ return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); } -WiFiClient WiFiServer::available(){ +NetworkClient NetworkServer::available(){ return accept(); } -WiFiClient WiFiServer::accept(){ +NetworkClient NetworkServer::accept(){ if(!_listening) - return WiFiClient(); + return NetworkClient(); int client_sock; if (_accepted_sockfd >= 0) { client_sock = _accepted_sockfd; @@ -58,17 +58,17 @@ WiFiClient WiFiServer::accept(){ if(setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&val, sizeof(int)) == ESP_OK) { val = _noDelay; if(setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&val, sizeof(int)) == ESP_OK) - return WiFiClient(client_sock); + return NetworkClient(client_sock); } } - return WiFiClient(); + return NetworkClient(); } -void WiFiServer::begin(uint16_t port){ +void NetworkServer::begin(uint16_t port){ begin(port, 1); } -void WiFiServer::begin(uint16_t port, int enable){ +void NetworkServer::begin(uint16_t port, int enable){ if(_listening) return; if(port){ @@ -99,15 +99,15 @@ void WiFiServer::begin(uint16_t port, int enable){ _accepted_sockfd = -1; } -void WiFiServer::setNoDelay(bool nodelay) { +void NetworkServer::setNoDelay(bool nodelay) { _noDelay = nodelay; } -bool WiFiServer::getNoDelay() { +bool NetworkServer::getNoDelay() { return _noDelay; } -bool WiFiServer::hasClient() { +bool NetworkServer::hasClient() { if (_accepted_sockfd >= 0) { return true; } @@ -124,7 +124,7 @@ bool WiFiServer::hasClient() { return false; } -void WiFiServer::end(){ +void NetworkServer::end(){ #ifdef ESP_IDF_VERSION_MAJOR lwip_close(sockfd); #else @@ -134,10 +134,10 @@ void WiFiServer::end(){ _listening = false; } -void WiFiServer::close(){ +void NetworkServer::close(){ end(); } -void WiFiServer::stop(){ +void NetworkServer::stop(){ end(); } diff --git a/libraries/Network/src/NetworkServer.h b/libraries/Network/src/NetworkServer.h new file mode 100644 index 00000000000..ce9bd2be47d --- /dev/null +++ b/libraries/Network/src/NetworkServer.h @@ -0,0 +1,60 @@ +/* + Server.h - Server class for Raspberry Pi + Copyright (c) 2016 Hristo Gochkov All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#pragma once + +#include "Arduino.h" +#include "Server.h" +#include "NetworkClient.h" +#include "IPAddress.h" + +class NetworkServer { + private: + int sockfd; + int _accepted_sockfd = -1; + IPAddress _addr; + uint16_t _port; + uint8_t _max_clients; + bool _listening; + bool _noDelay = false; + + public: + void listenOnLocalhost(){} + + NetworkServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) { + log_v("NetworkServer::NetworkServer(port=%d, ...)", port); + } + NetworkServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(addr),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) { + log_v("NetworkServer::NetworkServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port); + } + ~NetworkServer(){ end();} + NetworkClient available() __attribute__((deprecated("Renamed to accept()."))); + NetworkClient accept(); + void begin(uint16_t port=0); + void begin(uint16_t port, int reuse_enable); + void setNoDelay(bool nodelay); + bool getNoDelay(); + bool hasClient(); + + void end(); + void close(); + void stop(); + operator bool(){return _listening;} + int setTimeout(uint32_t seconds); +}; + diff --git a/libraries/WiFi/src/WiFiUdp.cpp b/libraries/Network/src/NetworkUdp.cpp similarity index 91% rename from libraries/WiFi/src/WiFiUdp.cpp rename to libraries/Network/src/NetworkUdp.cpp index 5d8b513a2d8..5771cb5dc18 100644 --- a/libraries/WiFi/src/WiFiUdp.cpp +++ b/libraries/Network/src/NetworkUdp.cpp @@ -17,7 +17,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "WiFiUdp.h" +#include "NetworkUdp.h" #include //std::nothrow #include #include @@ -26,7 +26,7 @@ #undef write #undef read -WiFiUDP::WiFiUDP() +NetworkUDP::NetworkUDP() : udp_server(-1) , server_port(0) , remote_port(0) @@ -35,11 +35,11 @@ WiFiUDP::WiFiUDP() , rx_buffer(0) {} -WiFiUDP::~WiFiUDP(){ +NetworkUDP::~NetworkUDP(){ stop(); } -uint8_t WiFiUDP::begin(IPAddress address, uint16_t port){ +uint8_t NetworkUDP::begin(IPAddress address, uint16_t port){ stop(); server_port = port; @@ -100,11 +100,11 @@ uint8_t WiFiUDP::begin(IPAddress address, uint16_t port){ return 1; } -uint8_t WiFiUDP::begin(uint16_t p){ +uint8_t NetworkUDP::begin(uint16_t p){ return begin(IPAddress(), p); } -uint8_t WiFiUDP::beginMulticast(IPAddress address, uint16_t p){ +uint8_t NetworkUDP::beginMulticast(IPAddress address, uint16_t p){ if(begin(IPAddress(), p)){ ip_addr_t addr; address.to_ip_addr_t(&addr); @@ -147,7 +147,7 @@ uint8_t WiFiUDP::beginMulticast(IPAddress address, uint16_t p){ return 0; } -void WiFiUDP::stop(){ +void NetworkUDP::stop(){ if(tx_buffer){ free(tx_buffer); tx_buffer = NULL; @@ -190,7 +190,7 @@ void WiFiUDP::stop(){ udp_server = -1; } -int WiFiUDP::beginMulticastPacket(){ +int NetworkUDP::beginMulticastPacket(){ if(!server_port || multicast_ip == IPAddress()) return 0; remote_ip = multicast_ip; @@ -198,7 +198,7 @@ int WiFiUDP::beginMulticastPacket(){ return beginPacket(); } -int WiFiUDP::beginPacket(){ +int NetworkUDP::beginPacket(){ if(!remote_port) return 0; @@ -226,13 +226,13 @@ int WiFiUDP::beginPacket(){ return 1; } -int WiFiUDP::beginPacket(IPAddress ip, uint16_t port){ +int NetworkUDP::beginPacket(IPAddress ip, uint16_t port){ remote_ip = ip; remote_port = port; return beginPacket(); } -int WiFiUDP::beginPacket(const char *host, uint16_t port){ +int NetworkUDP::beginPacket(const char *host, uint16_t port){ struct hostent *server; server = gethostbyname(host); if (server == NULL){ @@ -242,7 +242,7 @@ int WiFiUDP::beginPacket(const char *host, uint16_t port){ return beginPacket(IPAddress((const uint8_t *)(server->h_addr_list[0])), port); } -int WiFiUDP::endPacket(){ +int NetworkUDP::endPacket(){ ip_addr_t addr; remote_ip.to_ip_addr_t(&addr); @@ -272,7 +272,7 @@ int WiFiUDP::endPacket(){ return 1; } -size_t WiFiUDP::write(uint8_t data){ +size_t NetworkUDP::write(uint8_t data){ if(tx_buffer_len == 1460){ endPacket(); tx_buffer_len = 0; @@ -281,14 +281,14 @@ size_t WiFiUDP::write(uint8_t data){ return 1; } -size_t WiFiUDP::write(const uint8_t *buffer, size_t size){ +size_t NetworkUDP::write(const uint8_t *buffer, size_t size){ size_t i; for(i=0;iavailable(); } -int WiFiUDP::read(){ +int NetworkUDP::read(){ if(!rx_buffer) return -1; int out = rx_buffer->read(); if(!rx_buffer->available()){ @@ -354,11 +354,11 @@ int WiFiUDP::read(){ return out; } -int WiFiUDP::read(unsigned char* buffer, size_t len){ +int NetworkUDP::read(unsigned char* buffer, size_t len){ return read((char *)buffer, len); } -int WiFiUDP::read(char* buffer, size_t len){ +int NetworkUDP::read(char* buffer, size_t len){ if(!rx_buffer) return 0; int out = rx_buffer->read(buffer, len); if(!rx_buffer->available()){ @@ -369,22 +369,22 @@ int WiFiUDP::read(char* buffer, size_t len){ return out; } -int WiFiUDP::peek(){ +int NetworkUDP::peek(){ if(!rx_buffer) return -1; return rx_buffer->peek(); } -void WiFiUDP::flush(){ +void NetworkUDP::flush(){ if(!rx_buffer) return; cbuf *b = rx_buffer; rx_buffer = 0; delete b; } -IPAddress WiFiUDP::remoteIP(){ +IPAddress NetworkUDP::remoteIP(){ return remote_ip; } -uint16_t WiFiUDP::remotePort(){ +uint16_t NetworkUDP::remotePort(){ return remote_port; } diff --git a/libraries/Network/src/NetworkUdp.h b/libraries/Network/src/NetworkUdp.h new file mode 100644 index 00000000000..0faf513a0d5 --- /dev/null +++ b/libraries/Network/src/NetworkUdp.h @@ -0,0 +1,77 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef _NETWORKUDP_H_ +#define _NETWORKUDP_H_ + +#include +#include +#include + +class NetworkUDP : public UDP { +private: + int udp_server; + IPAddress multicast_ip; + IPAddress remote_ip; + uint16_t server_port; + uint16_t remote_port; + char * tx_buffer; + size_t tx_buffer_len; + cbuf * rx_buffer; +public: + NetworkUDP(); + ~NetworkUDP(); + uint8_t begin(IPAddress a, uint16_t p); + uint8_t begin(uint16_t p); + uint8_t beginMulticast(IPAddress a, uint16_t p); + void stop(); + int beginMulticastPacket(); + int beginPacket(); + int beginPacket(IPAddress ip, uint16_t port); + int beginPacket(const char *host, uint16_t port); + int endPacket(); + size_t write(uint8_t); + size_t write(const uint8_t *buffer, size_t size); + int parsePacket(); + int available(); + int read(); + int read(unsigned char* buffer, size_t len); + int read(char* buffer, size_t len); + int peek(); + void flush(); + IPAddress remoteIP(); + uint16_t remotePort(); +}; + +#endif /* _NETWORKUDP_H_ */ diff --git a/libraries/WiFiClientSecure/README.md b/libraries/NetworkClientSecure/README.md similarity index 83% rename from libraries/WiFiClientSecure/README.md rename to libraries/NetworkClientSecure/README.md index b5b2e7d709f..d7645a6026f 100644 --- a/libraries/WiFiClientSecure/README.md +++ b/libraries/NetworkClientSecure/README.md @@ -1,9 +1,9 @@ -WiFiClientSecure +NetworkClientSecure ================ -The WiFiClientSecure class implements support for secure connections using TLS (SSL). -It inherits from WiFiClient and thus implements a superset of that class' interface. -There are three ways to establish a secure connection using the WiFiClientSecure class: +The NetworkClientSecure class implements support for secure connections using TLS (SSL). +It inherits from NetworkClient and thus implements a superset of that class' interface. +There are three ways to establish a secure connection using the NetworkClientSecure class: using a root certificate authority (CA) cert, using a root CA cert plus a client cert and key, and using a pre-shared key (PSK). @@ -19,12 +19,12 @@ If you are accessing your own server: If you are accessing a public server: - Obtain the cert of the public CA that signed that server's cert Then: -- In WiFiClientSecure use setCACert (or the appropriate connect method) to set the root cert of your +- In NetworkClientSecure use setCACert (or the appropriate connect method) to set the root cert of your CA or of the public CA -- When WiFiClientSecure connects to the target server it uses the CA cert to verify the certificate +- When NetworkClientSecure connects to the target server it uses the CA cert to verify the certificate presented by the server, and then negotiates encryption for the connection -Please see the WiFiClientSecure example. +Please see the NetworkClientSecure example. Using a bundle of root certificate authority certificates --------------------------------------------------------- @@ -60,11 +60,11 @@ the client to the server, then negotiates an encrypted connection. - Follow steps above - Using your root CA generate cert/key for your client - Register the keys with the server you will be accessing so the server can authenticate your client -- In WiFiClientSecure use setCACert (or the appropriate connect method) to set the root cert of your +- In NetworkClientSecure use setCACert (or the appropriate connect method) to set the root cert of your CA or of the public CA, this is used to authenticate the server -- In WiFiClientSecure use setCertificate, and setPrivateKey (or the appropriate connect method) to +- In NetworkClientSecure use setCertificate, and setPrivateKey (or the appropriate connect method) to set your client's cert & key, this will be used to authenticate your client to the server -- When WiFiClientSecure connects to the target server it uses the CA cert to verify the certificate +- When NetworkClientSecure connects to the target server it uses the CA cert to verify the certificate presented by the server, it will use the cert/key to authenticate your client to the server, and it will then negotiate encryption for the connection @@ -85,13 +85,13 @@ malicious server does not divulge the password. Plus the server is also authenti To use PSK: - Generate a random hex string (generating an MD5 or SHA for some file is one way to do this) - Come up with a string id for your client and configure your server to accept the id/key pair -- In WiFiClientSecure use setPreSharedKey (or the appropriate connect method) to +- In NetworkClientSecure use setPreSharedKey (or the appropriate connect method) to set the id/key combo -- When WiFiClientSecure connects to the target server it uses the id/key combo to authenticate the +- When NetworkClientSecure connects to the target server it uses the id/key combo to authenticate the server (it must prove that it has the key too), authenticate the client and then negotiate encryption for the connection -Please see the WiFiClientPSK example. +Please see the NetworkClientPSK example. Specifying the ALPN Protocol ---------------------------- @@ -110,23 +110,23 @@ wiFiClient.setAlpnProtocols(aws_protos); Examples -------- -#### WiFiClientInsecure -Demonstrates usage of insecure connection using `WiFiClientSecure::setInsecure()` -#### WiFiClientPSK +#### NetworkClientInsecure +Demonstrates usage of insecure connection using `NetworkClientSecure::setInsecure()` +#### NetworkClientPSK Wifi secure connection example for ESP32 using a pre-shared key (PSK) This is useful with MQTT servers instead of using a self-signed cert, tested with mosquitto. Running on TLS 1.2 using mbedTLS -#### WiFiClientSecure +#### NetworkClientSecure Wifi secure connection example for ESP32 Running on TLS 1.2 using mbedTLS -#### WiFiClientSecureEnterprise +#### NetworkClientSecureEnterprise This example demonstrates a secure connection to a WiFi network using WPA/WPA2 Enterprise (for example eduroam), and establishing a secure HTTPS connection with an external server (for example arduino.php5.sk) using the defined anonymous identity, user identity, and password. .. note:: This example is outdated and might not work. For more examples see [https://github.com/martinius96/ESP32-eduroam](https://github.com/martinius96/ESP32-eduroam) -#### WiFiClientShowPeerCredentials +#### NetworkClientShowPeerCredentials Example of a establishing a secure connection and then showing the fingerprint of the certificate. This can be useful in an IoT setting to know for sure that you are connecting to the right server. Especially in situations where you cannot hardcode a trusted root certificate for long diff --git a/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientInsecure/.skip.esp32h2 similarity index 100% rename from libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientInsecure/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientInsecure/WiFiClientInsecure.ino b/libraries/NetworkClientSecure/examples/WiFiClientInsecure/WiFiClientInsecure.ino similarity index 85% rename from libraries/WiFiClientSecure/examples/WiFiClientInsecure/WiFiClientInsecure.ino rename to libraries/NetworkClientSecure/examples/WiFiClientInsecure/WiFiClientInsecure.ino index 9c519736fda..107bde570f2 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientInsecure/WiFiClientInsecure.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientInsecure/WiFiClientInsecure.ino @@ -1,10 +1,11 @@ -#include +#include +#include /* This is a very INSECURE approach. - * If for some reason the secure, proper example WiFiClientSecure + * If for some reason the secure, proper example NetworkClientSecure * does not work for you; then you may want to check the - * WiFiClientTrustOnFirstUse example first. It is less secure than - * WiFiClientSecure, but a lot better than this totally insecure + * NetworkClientTrustOnFirstUse example first. It is less secure than + * NetworkClientSecure, but a lot better than this totally insecure * approach shown below. */ @@ -13,7 +14,7 @@ const char* password = "your-password"; // your network password const char* server = "www.howsmyssl.com"; // Server URL -WiFiClientSecure client; +NetworkClientSecure client; void setup() { //Initialize serial and wait for port to open: diff --git a/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientPSK/.skip.esp32h2 similarity index 100% rename from libraries/Ethernet/examples/ETH_W5500_IDF_SPI/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientPSK/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientPSK/WiFiClientPSK.ino b/libraries/NetworkClientSecure/examples/WiFiClientPSK/WiFiClientPSK.ino similarity index 96% rename from libraries/WiFiClientSecure/examples/WiFiClientPSK/WiFiClientPSK.ino rename to libraries/NetworkClientSecure/examples/WiFiClientPSK/WiFiClientPSK.ino index bd3ffbeda05..f9a9b11ba1c 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientPSK/WiFiClientPSK.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientPSK/WiFiClientPSK.ino @@ -10,7 +10,8 @@ 2018 - Adapted for PSK by Thorsten von Eicken */ -#include +#include +#include #if 0 const char* ssid = "your-ssid"; // your network SSID (name of wifi network) @@ -27,7 +28,7 @@ const int port = 8443; // server's port (8883 for MQTT) const char* pskIdent = "Client_identity"; // PSK identity (sometimes called key hint) const char* psKey = "1a2b3c4d"; // PSK Key (must be hex string without 0x) -WiFiClientSecure client; +NetworkClientSecure client; void setup() { //Initialize serial and wait for port to open: diff --git a/libraries/WiFiClientSecure/examples/WiFiClientInsecure/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientSecure/.skip.esp32h2 similarity index 100% rename from libraries/WiFiClientSecure/examples/WiFiClientInsecure/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientSecure/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino b/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino similarity index 99% rename from libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino rename to libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino index 22116873515..d65d8196767 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino @@ -6,7 +6,8 @@ 2017 - Evandro Copercini - Apache 2.0 License. */ -#include +#include +#include const char* ssid = "your-ssid"; // your network SSID (name of wifi network) const char* password = "your-password"; // your network password @@ -44,7 +45,7 @@ const char* test_root_ca= \ //const char* test_client_cert = ""; //to verify the client -WiFiClientSecure client; +NetworkClientSecure client; void setup() { //Initialize serial and wait for port to open: diff --git a/libraries/WiFiClientSecure/examples/WiFiClientPSK/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientSecureEnterprise/.skip.esp32h2 similarity index 100% rename from libraries/WiFiClientSecure/examples/WiFiClientPSK/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientSecureEnterprise/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino b/libraries/NetworkClientSecure/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino similarity index 99% rename from libraries/WiFiClientSecure/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino rename to libraries/NetworkClientSecure/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino index 6bd68367526..9da03d1ed17 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientSecureEnterprise/WiFiClientSecureEnterprise.ino @@ -14,7 +14,7 @@ // For more examples see https://github.com/martinius96/ESP32-eduroam #include -#include +#include #if __has_include ("esp_eap_client.h") #include "esp_eap_client.h" #else @@ -59,7 +59,7 @@ const char* test_root_ca = \ // You can use x.509 client certificates if you want //const char* test_client_key = ""; //to verify the client //const char* test_client_cert = ""; //to verify the client -WiFiClientSecure client; +NetworkClientSecure client; void setup() { Serial.begin(115200); delay(10); diff --git a/libraries/WiFiClientSecure/examples/WiFiClientSecure/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade/.skip.esp32h2 similarity index 100% rename from libraries/WiFiClientSecure/examples/WiFiClientSecure/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino b/libraries/NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino similarity index 93% rename from libraries/WiFiClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino rename to libraries/NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino index 06c19d105c4..ddf00895357 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino @@ -18,11 +18,11 @@ 8. server now tells the client what (else) is supported; such as additional authentication options. ... conversation continues encrypted. - This can be enabled in WiFiClientSecure by telling it to start in plaintext: + This can be enabled in NetworkClientSecure by telling it to start in plaintext: client.setPlainStart(); - and client is than a plain, TCP, connection (just as WiFiClient would be); until the client calls + and client is than a plain, TCP, connection (just as NetworkClient would be); until the client calls the method: client.startTLS(); // returns zero on error; non zero on success. @@ -30,7 +30,8 @@ After which things switch to TLS/SSL. */ -#include +#include +#include #ifndef WIFI_NETWORK #define WIFI_NETWORK "YOUR Wifi SSID" @@ -53,7 +54,7 @@ const char* password = WIFI_PASSWD; // your network password const char* server = SMTP_HOST; // Server URL const int submission_port = SMTP_PORT; // submission port. -WiFiClientSecure client; +NetworkClientSecure client; static bool readAllSMTPLines(); @@ -138,7 +139,7 @@ static bool readAllSMTPLines() { int i; // blocking read; we cannot rely on a timeout - // of a WiFiClientSecure read; as it is non + // of a NetworkClientSecure read; as it is non // blocking. const unsigned long timeout = 15 * 1000; unsigned long start = millis(); // the timeout is for the entire CMD block response; not per character/line. diff --git a/libraries/WiFiClientSecure/examples/WiFiClientSecureEnterprise/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientShowPeerCredentials/.skip.esp32h2 similarity index 100% rename from libraries/WiFiClientSecure/examples/WiFiClientSecureEnterprise/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientShowPeerCredentials/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino b/libraries/NetworkClientSecure/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino similarity index 94% rename from libraries/WiFiClientSecure/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino rename to libraries/NetworkClientSecure/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino index 17199e20697..9ec50ab57e1 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientShowPeerCredentials/WiFiClientShowPeerCredentials.ino @@ -1,4 +1,4 @@ -// WiFiClientShowPeerCredentials +// NetworkClientShowPeerCredentials // // Example of a establishing a secure connection and then // showing the fingerprint of the certificate. This can @@ -12,7 +12,7 @@ #include #include -#include +#include #ifndef WIFI_NETWORK #define WIFI_NETWORK "MyWifiNetwork" @@ -25,7 +25,7 @@ #define URL "https://arduino.cc" void demo() { - WiFiClientSecure *client = new WiFiClientSecure; + NetworkClientSecure *client = new NetworkClientSecure; client->setInsecure(); // HTTPClient https; diff --git a/libraries/WiFiClientSecure/examples/WiFiClientSecureProtocolUpgrade/.skip.esp32h2 b/libraries/NetworkClientSecure/examples/WiFiClientTrustOnFirstUse/.skip.esp32h2 similarity index 100% rename from libraries/WiFiClientSecure/examples/WiFiClientSecureProtocolUpgrade/.skip.esp32h2 rename to libraries/NetworkClientSecure/examples/WiFiClientTrustOnFirstUse/.skip.esp32h2 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino b/libraries/NetworkClientSecure/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino similarity index 99% rename from libraries/WiFiClientSecure/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino rename to libraries/NetworkClientSecure/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino index a8b508f9db1..497f456d53f 100644 --- a/libraries/WiFiClientSecure/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino +++ b/libraries/NetworkClientSecure/examples/WiFiClientTrustOnFirstUse/WiFiClientTrustOnFirstUse.ino @@ -54,7 +54,8 @@ const char* server = "www.howsmyssl.com"; // Server to test with. const int TOFU_RESET_BUTTON = 35; /* Trust reset button wired between GPIO 35 and GND (pulldown) */ -#include +#include +#include #include /* Set aside some persistant memory (i.e. memory that is preserved on reboots and @@ -76,7 +77,7 @@ static void printSHA256(unsigned char * ptr) { Serial.println(""); }; -WiFiClientSecure client; +NetworkClientSecure client; bool get_tofu(); bool doTOFU_Protected_Connection(uint8_t * fingerprint_tofu); diff --git a/libraries/WiFiClientSecure/keywords.txt b/libraries/NetworkClientSecure/keywords.txt similarity index 92% rename from libraries/WiFiClientSecure/keywords.txt rename to libraries/NetworkClientSecure/keywords.txt index 4bab096dbd5..7b62f1728dd 100644 --- a/libraries/WiFiClientSecure/keywords.txt +++ b/libraries/NetworkClientSecure/keywords.txt @@ -6,13 +6,13 @@ # Library (KEYWORD3) ####################################### -WiFiClientSecure KEYWORD3 +NetworkClientSecure KEYWORD3 ####################################### # Datatypes (KEYWORD1) ####################################### -WiFiClientSecure KEYWORD1 +NetworkClientSecure KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) diff --git a/libraries/WiFiClientSecure/library.properties b/libraries/NetworkClientSecure/library.properties similarity index 92% rename from libraries/WiFiClientSecure/library.properties rename to libraries/NetworkClientSecure/library.properties index 11bc3a935a4..dd4b6a195dc 100644 --- a/libraries/WiFiClientSecure/library.properties +++ b/libraries/NetworkClientSecure/library.properties @@ -1,4 +1,4 @@ -name=WiFiClientSecure +name=NetworkClientSecure version=2.0.0 author=Evandro Luis Copercini maintainer=Github Community diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp b/libraries/NetworkClientSecure/src/NetworkClientSecure.cpp similarity index 75% rename from libraries/WiFiClientSecure/src/WiFiClientSecure.cpp rename to libraries/NetworkClientSecure/src/NetworkClientSecure.cpp index d7f443fa2cb..83af76867db 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp +++ b/libraries/NetworkClientSecure/src/NetworkClientSecure.cpp @@ -1,5 +1,5 @@ /* - WiFiClientSecure.cpp - Client Secure class for ESP32 + NetworkClientSecure.cpp - Client Secure class for ESP32 Copyright (c) 2016 Hristo Gochkov All right reserved. Additions Copyright (C) 2017 Evandro Luis Copercini. @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "WiFiClientSecure.h" +#include "NetworkClientSecure.h" #include "esp_crt_bundle.h" #include #include @@ -29,7 +29,7 @@ #undef read -WiFiClientSecure::WiFiClientSecure() +NetworkClientSecure::NetworkClientSecure() { _connected = false; _timeout = 30000; // Same default as ssl_client @@ -50,7 +50,7 @@ WiFiClientSecure::WiFiClientSecure() } -WiFiClientSecure::WiFiClientSecure(int sock) +NetworkClientSecure::NetworkClientSecure(int sock) { _connected = false; _timeout = 30000; // Same default as ssl_client @@ -75,13 +75,13 @@ WiFiClientSecure::WiFiClientSecure(int sock) _alpn_protos = NULL; } -WiFiClientSecure::~WiFiClientSecure() +NetworkClientSecure::~NetworkClientSecure() { stop(); delete sslclient; } -WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other) +NetworkClientSecure &NetworkClientSecure::operator=(const NetworkClientSecure &other) { stop(); sslclient->socket = other.sslclient->socket; @@ -89,7 +89,7 @@ WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other) return *this; } -void WiFiClientSecure::stop() +void NetworkClientSecure::stop() { stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key); @@ -99,45 +99,45 @@ void WiFiClientSecure::stop() _lastWriteTimeout = 0; } -int WiFiClientSecure::connect(IPAddress ip, uint16_t port) +int NetworkClientSecure::connect(IPAddress ip, uint16_t port) { if (_pskIdent && _psKey) return connect(ip, port, _pskIdent, _psKey); return connect(ip, port, _CA_cert, _cert, _private_key); } -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, int32_t timeout){ +int NetworkClientSecure::connect(IPAddress ip, uint16_t port, int32_t timeout){ _timeout = timeout; return connect(ip, port); } -int WiFiClientSecure::connect(const char *host, uint16_t port) +int NetworkClientSecure::connect(const char *host, uint16_t port) { if (_pskIdent && _psKey) return connect(host, port, _pskIdent, _psKey); return connect(host, port, _CA_cert, _cert, _private_key); } -int WiFiClientSecure::connect(const char *host, uint16_t port, int32_t timeout){ +int NetworkClientSecure::connect(const char *host, uint16_t port, int32_t timeout){ _timeout = timeout; return connect(host, port); } -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) +int NetworkClientSecure::connect(IPAddress ip, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) { return connect(ip, port, NULL, CA_cert, cert, private_key); } -int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) +int NetworkClientSecure::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) { IPAddress address; - if (!WiFi.hostByName(host, address)) + if (!Network.hostByName(host, address)) return 0; return connect(address, port, host, CA_cert, cert, private_key); } -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *host, const char *CA_cert, const char *cert, const char *private_key) +int NetworkClientSecure::connect(IPAddress ip, uint16_t port, const char *host, const char *CA_cert, const char *cert, const char *private_key) { int ret = start_ssl_client(sslclient, ip, port, host, _timeout, CA_cert, _use_ca_bundle, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos); @@ -157,7 +157,7 @@ int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *host, con return 1; } -int WiFiClientSecure::startTLS() +int NetworkClientSecure::startTLS() { int ret = 1; if (_stillinPlainStart) { @@ -174,15 +174,15 @@ int WiFiClientSecure::startTLS() return 1; } -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) { +int NetworkClientSecure::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) { return connect(ip.toString().c_str(), port, pskIdent, psKey); } -int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) { +int NetworkClientSecure::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) { log_v("start_ssl_client with PSK"); IPAddress address; - if (!WiFi.hostByName(host, address)) + if (!Network.hostByName(host, address)) return 0; int ret = start_ssl_client(sslclient, address, port, host, _timeout, NULL, false, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos); @@ -196,7 +196,7 @@ int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskId return 1; } -int WiFiClientSecure::peek(){ +int NetworkClientSecure::peek(){ if(_peek >= 0){ return _peek; } @@ -204,19 +204,19 @@ int WiFiClientSecure::peek(){ return _peek; } -size_t WiFiClientSecure::write(uint8_t data) +size_t NetworkClientSecure::write(uint8_t data) { return write(&data, 1); } -int WiFiClientSecure::read() +int NetworkClientSecure::read() { uint8_t data = -1; int res = read(&data, 1); return res < 0 ? res: data; } -size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) +size_t NetworkClientSecure::write(const uint8_t *buf, size_t size) { if (!_connected) { return 0; @@ -243,7 +243,7 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) return res; } -int WiFiClientSecure::read(uint8_t *buf, size_t size) +int NetworkClientSecure::read(uint8_t *buf, size_t size) { if(_stillinPlainStart) return get_net_receive(sslclient, buf, size); @@ -289,7 +289,7 @@ int WiFiClientSecure::read(uint8_t *buf, size_t size) return res + peeked; } -int WiFiClientSecure::available() +int NetworkClientSecure::available() { if (_stillinPlainStart) return peek_net_receive(sslclient,0); @@ -308,7 +308,7 @@ int WiFiClientSecure::available() return res+peeked; } -uint8_t WiFiClientSecure::connected() +uint8_t NetworkClientSecure::connected() { uint8_t dummy = 0; read(&dummy, 0); @@ -316,7 +316,7 @@ uint8_t WiFiClientSecure::connected() return _connected; } -void WiFiClientSecure::setInsecure() +void NetworkClientSecure::setInsecure() { _CA_cert = NULL; _cert = NULL; @@ -326,13 +326,13 @@ void WiFiClientSecure::setInsecure() _use_insecure = true; } -void WiFiClientSecure::setCACert (const char *rootCA) +void NetworkClientSecure::setCACert (const char *rootCA) { _CA_cert = rootCA; _use_insecure = false; } - void WiFiClientSecure::setCACertBundle(const uint8_t * bundle) + void NetworkClientSecure::setCACertBundle(const uint8_t * bundle) { if (bundle != NULL) { @@ -344,22 +344,22 @@ void WiFiClientSecure::setCACert (const char *rootCA) } } -void WiFiClientSecure::setCertificate (const char *client_ca) +void NetworkClientSecure::setCertificate (const char *client_ca) { _cert = client_ca; } -void WiFiClientSecure::setPrivateKey (const char *private_key) +void NetworkClientSecure::setPrivateKey (const char *private_key) { _private_key = private_key; } -void WiFiClientSecure::setPreSharedKey(const char *pskIdent, const char *psKey) { +void NetworkClientSecure::setPreSharedKey(const char *pskIdent, const char *psKey) { _pskIdent = pskIdent; _psKey = psKey; } -bool WiFiClientSecure::verify(const char* fp, const char* domain_name) +bool NetworkClientSecure::verify(const char* fp, const char* domain_name) { if (!sslclient) return false; @@ -367,7 +367,7 @@ bool WiFiClientSecure::verify(const char* fp, const char* domain_name) return verify_ssl_fingerprint(sslclient, fp, domain_name); } -char *WiFiClientSecure::_streamLoad(Stream& stream, size_t size) { +char *NetworkClientSecure::_streamLoad(Stream& stream, size_t size) { char *dest = (char*)malloc(size+1); if (!dest) { return nullptr; @@ -381,7 +381,7 @@ char *WiFiClientSecure::_streamLoad(Stream& stream, size_t size) { return dest; } -bool WiFiClientSecure::loadCACert(Stream& stream, size_t size) { +bool NetworkClientSecure::loadCACert(Stream& stream, size_t size) { if (_CA_cert != NULL) free(const_cast(_CA_cert)); char *dest = _streamLoad(stream, size); bool ret = false; @@ -392,7 +392,7 @@ bool WiFiClientSecure::loadCACert(Stream& stream, size_t size) { return ret; } -bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size) { +bool NetworkClientSecure::loadCertificate(Stream& stream, size_t size) { if (_cert != NULL) free(const_cast(_cert)); char *dest = _streamLoad(stream, size); bool ret = false; @@ -403,7 +403,7 @@ bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size) { return ret; } -bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size) { +bool NetworkClientSecure::loadPrivateKey(Stream& stream, size_t size) { if (_private_key != NULL) free(const_cast(_private_key)); char *dest = _streamLoad(stream, size); bool ret = false; @@ -414,7 +414,7 @@ bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size) { return ret; } -int WiFiClientSecure::lastError(char *buf, const size_t size) +int NetworkClientSecure::lastError(char *buf, const size_t size) { if (!_lastError) { return 0; @@ -423,17 +423,17 @@ int WiFiClientSecure::lastError(char *buf, const size_t size) return _lastError; } -void WiFiClientSecure::setHandshakeTimeout(unsigned long handshake_timeout) +void NetworkClientSecure::setHandshakeTimeout(unsigned long handshake_timeout) { sslclient->handshake_timeout = handshake_timeout * 1000; } -void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos) +void NetworkClientSecure::setAlpnProtocols(const char **alpn_protos) { _alpn_protos = alpn_protos; } -int WiFiClientSecure::fd() const +int NetworkClientSecure::fd() const { return sslclient->socket; } diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.h b/libraries/NetworkClientSecure/src/NetworkClientSecure.h similarity index 89% rename from libraries/WiFiClientSecure/src/WiFiClientSecure.h rename to libraries/NetworkClientSecure/src/NetworkClientSecure.h index 31daebbdb42..e6ce9e9f290 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.h +++ b/libraries/NetworkClientSecure/src/NetworkClientSecure.h @@ -1,5 +1,5 @@ /* - WiFiClientSecure.h - Base class that provides Client SSL to ESP32 + NetworkClientSecure.h - Base class that provides Client SSL to ESP32 Copyright (c) 2011 Adrian McEwen. All right reserved. Additions Copyright (C) 2017 Evandro Luis Copercini. @@ -18,14 +18,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef WiFiClientSecure_h -#define WiFiClientSecure_h +#ifndef NetworkClientSecure_h +#define NetworkClientSecure_h #include "Arduino.h" #include "IPAddress.h" -#include +#include "Network.h" #include "ssl_client.h" -class WiFiClientSecure : public WiFiClient +class NetworkClientSecure : public NetworkClient { protected: sslclient_context *sslclient; @@ -44,10 +44,10 @@ class WiFiClientSecure : public WiFiClient bool _use_ca_bundle; public: - WiFiClientSecure *next; - WiFiClientSecure(); - WiFiClientSecure(int socket); - ~WiFiClientSecure(); + NetworkClientSecure *next; + NetworkClientSecure(); + NetworkClientSecure(int socket); + ~NetworkClientSecure(); int connect(IPAddress ip, uint16_t port); int connect(IPAddress ip, uint16_t port, int32_t timeout); int connect(const char *host, uint16_t port); @@ -98,7 +98,7 @@ class WiFiClientSecure : public WiFiClient { return connected(); } - WiFiClientSecure &operator=(const WiFiClientSecure &other); + NetworkClientSecure &operator=(const NetworkClientSecure &other); bool operator==(const bool value) { return bool() == value; @@ -107,8 +107,8 @@ class WiFiClientSecure : public WiFiClient { return bool() != value; } - bool operator==(const WiFiClientSecure &); - bool operator!=(const WiFiClientSecure &rhs) + bool operator==(const NetworkClientSecure &); + bool operator!=(const NetworkClientSecure &rhs) { return !this->operator==(rhs); }; @@ -121,7 +121,7 @@ class WiFiClientSecure : public WiFiClient private: char *_streamLoad(Stream& stream, size_t size); - //friend class WiFiServer; + //friend class NetworkServer; using Print::write; }; diff --git a/libraries/NetworkClientSecure/src/WiFiClientSecure.h b/libraries/NetworkClientSecure/src/WiFiClientSecure.h new file mode 100644 index 00000000000..b4d6962fb35 --- /dev/null +++ b/libraries/NetworkClientSecure/src/WiFiClientSecure.h @@ -0,0 +1,3 @@ +#pragma once +#include "NetworkClientSecure.h" +#define WiFiClientSecure NetworkClientSecure diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/NetworkClientSecure/src/ssl_client.cpp similarity index 99% rename from libraries/WiFiClientSecure/src/ssl_client.cpp rename to libraries/NetworkClientSecure/src/ssl_client.cpp index a4308abb1e8..4ca512292be 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.cpp +++ b/libraries/NetworkClientSecure/src/ssl_client.cpp @@ -18,7 +18,6 @@ #include #include "ssl_client.h" #include "esp_crt_bundle.h" -#include "WiFi.h" #if !defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && !defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) # warning "Please call `idf.py menuconfig` then go to Component config -> mbedTLS -> TLS Key Exchange Methods -> Enable pre-shared-key ciphersuites and then check `Enable PSK based cyphersuite modes`. Save and Quit." diff --git a/libraries/WiFiClientSecure/src/ssl_client.h b/libraries/NetworkClientSecure/src/ssl_client.h similarity index 100% rename from libraries/WiFiClientSecure/src/ssl_client.h rename to libraries/NetworkClientSecure/src/ssl_client.h diff --git a/libraries/README.md b/libraries/README.md index 3b643ee2dbe..7fe904b4467 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -53,7 +53,7 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec Filesystem virtualization framework ### HTTPClient - A simple HTTP client, compatible with WiFiClientSecure + A simple HTTP client, compatible with NetworkClientSecure ### HTTPUpdate Download a firmware update from HTTPd and apply it using Update @@ -103,7 +103,7 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec ### WiFi Arduino compatible WiFi driver (includes Ethernet driver) -### WiFiClientSecure +### NetworkClientSecure Arduino compatible WiFi client object using embedded encryption ### Wire diff --git a/libraries/Update/examples/AWS_S3_OTA_Update/AWS_S3_OTA_Update.ino b/libraries/Update/examples/AWS_S3_OTA_Update/AWS_S3_OTA_Update.ino index 8582874f129..9f5d3d15168 100644 --- a/libraries/Update/examples/AWS_S3_OTA_Update/AWS_S3_OTA_Update.ino +++ b/libraries/Update/examples/AWS_S3_OTA_Update/AWS_S3_OTA_Update.ino @@ -22,7 +22,7 @@ #include #include -WiFiClient client; +NetworkClient client; // Variables to validate // response from S3 diff --git a/libraries/Update/examples/HTTP_Client_AES_OTA_Update/HTTP_Client_AES_OTA_Update.ino b/libraries/Update/examples/HTTP_Client_AES_OTA_Update/HTTP_Client_AES_OTA_Update.ino index e9b1aa75a5e..a07e78c11a2 100644 --- a/libraries/Update/examples/HTTP_Client_AES_OTA_Update/HTTP_Client_AES_OTA_Update.ino +++ b/libraries/Update/examples/HTTP_Client_AES_OTA_Update/HTTP_Client_AES_OTA_Update.ino @@ -48,7 +48,7 @@ espsecure.py encrypt_flash_data = runs the idf encryption function to make a en #include #include -#include +#include #include #include @@ -150,7 +150,7 @@ bool http_downloadUpdate(HTTPClient& http, uint32_t size=0) { if(size == 0){ return false; } - WiFiClient *client = http.getStreamPtr(); + NetworkClient *client = http.getStreamPtr(); if( !Update.begin(size, U_FLASH) ) { Serial.printf("Update.begin failed! (%s)\n", Update.errorString() ); @@ -207,7 +207,7 @@ bool http_updater(const String& host, const uint16_t& port, String uri, const bo //setup HTTPclient to be ready to connect & send a request to HTTP server HTTPClient http; - WiFiClient client; + NetworkClient client; uri.concat(query); //GET query added to end of uri path if( !http.begin(client, host, port, uri) ){ return false; //httpclient setup error @@ -261,7 +261,7 @@ bool http_updater(const String& host, const uint16_t& port, String uri, const bo bool http_direct(const String& host, const uint16_t& port, const String& uri, const char* user=NULL, const char* password=NULL) { //setup HTTPclient to be ready to connect & send a request to HTTP server HTTPClient http; - WiFiClient client; + NetworkClient client; if( !http.begin(client, host, port, uri) ){ return false; //httpclient setup error } diff --git a/libraries/Update/examples/HTTP_Server_AES_OTA_Update/HTTP_Server_AES_OTA_Update.ino b/libraries/Update/examples/HTTP_Server_AES_OTA_Update/HTTP_Server_AES_OTA_Update.ino index b4c611d2739..885115596c2 100644 --- a/libraries/Update/examples/HTTP_Server_AES_OTA_Update/HTTP_Server_AES_OTA_Update.ino +++ b/libraries/Update/examples/HTTP_Server_AES_OTA_Update/HTTP_Server_AES_OTA_Update.ino @@ -35,7 +35,7 @@ espsecure.py encrypt_flash_data = runs the idf encryption function to make a en */ #include -#include +#include #include #include #include diff --git a/libraries/WebServer/examples/AdvancedWebServer/AdvancedWebServer.ino b/libraries/WebServer/examples/AdvancedWebServer/AdvancedWebServer.ino index 9300b6c23b7..0362a287a59 100644 --- a/libraries/WebServer/examples/AdvancedWebServer/AdvancedWebServer.ino +++ b/libraries/WebServer/examples/AdvancedWebServer/AdvancedWebServer.ino @@ -29,7 +29,7 @@ */ #include -#include +#include #include #include diff --git a/libraries/WebServer/examples/FSBrowser/FSBrowser.ino b/libraries/WebServer/examples/FSBrowser/FSBrowser.ino index 093ff08bf9f..93b448c3b89 100644 --- a/libraries/WebServer/examples/FSBrowser/FSBrowser.ino +++ b/libraries/WebServer/examples/FSBrowser/FSBrowser.ino @@ -23,7 +23,7 @@ edit the page by going to http://esp32fs.local/edit */ #include -#include +#include #include #include diff --git a/libraries/WebServer/examples/HelloServer/HelloServer.ino b/libraries/WebServer/examples/HelloServer/HelloServer.ino index d807ff089b9..d2472995804 100644 --- a/libraries/WebServer/examples/HelloServer/HelloServer.ino +++ b/libraries/WebServer/examples/HelloServer/HelloServer.ino @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/libraries/WebServer/examples/MultiHomedServers/MultiHomedServers.ino b/libraries/WebServer/examples/MultiHomedServers/MultiHomedServers.ino index 47eb63b852f..4d54c8a885b 100644 --- a/libraries/WebServer/examples/MultiHomedServers/MultiHomedServers.ino +++ b/libraries/WebServer/examples/MultiHomedServers/MultiHomedServers.ino @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/libraries/WebServer/examples/MultiHomedServers/README.md b/libraries/WebServer/examples/MultiHomedServers/README.md index ce869dcc6c3..bf5f7dfd18a 100644 --- a/libraries/WebServer/examples/MultiHomedServers/README.md +++ b/libraries/WebServer/examples/MultiHomedServers/README.md @@ -3,10 +3,10 @@ This example tests support for multi-homed servers, i.e. a distinct web servers on distinct IP interface. It only tests the case n=2 because on a basic ESP32 device, we only have two IP interfaces, namely the WiFi station interfaces and the WiFi soft AP interface. -For this to work, the WebServer and the WiFiServer classes must correctly handle the case where an IP address is passed to their relevant constructor. +For this to work, the WebServer and the NetworkServer classes must correctly handle the case where an IP address is passed to their relevant constructor. It also requires WebServer to work with multiple, simultaneous instances. -Testing the WebServer and the WiFiServer constructors was the primary purpose of this script. +Testing the WebServer and the NetworkServer constructors was the primary purpose of this script. The part of WebServer used by this sketch does seem to work with multiple, simultaneous instances. However there is much functionality in WebServer that is not tested here. It may all be well, but that is not proven here. diff --git a/libraries/WebServer/examples/PathArgServer/PathArgServer.ino b/libraries/WebServer/examples/PathArgServer/PathArgServer.ino index 8482b2df63d..b99b6c003f9 100644 --- a/libraries/WebServer/examples/PathArgServer/PathArgServer.ino +++ b/libraries/WebServer/examples/PathArgServer/PathArgServer.ino @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/libraries/WebServer/examples/SDWebServer/SDWebServer.ino b/libraries/WebServer/examples/SDWebServer/SDWebServer.ino index b9da60c2d60..8cef84edce4 100644 --- a/libraries/WebServer/examples/SDWebServer/SDWebServer.ino +++ b/libraries/WebServer/examples/SDWebServer/SDWebServer.ino @@ -30,7 +30,7 @@ */ #include -#include +#include #include #include #include diff --git a/libraries/WebServer/examples/SimpleAuthentification/SimpleAuthentification.ino b/libraries/WebServer/examples/SimpleAuthentification/SimpleAuthentification.ino index 98cb62ebe15..b4dd21e6290 100644 --- a/libraries/WebServer/examples/SimpleAuthentification/SimpleAuthentification.ino +++ b/libraries/WebServer/examples/SimpleAuthentification/SimpleAuthentification.ino @@ -1,5 +1,5 @@ #include -#include +#include #include const char* ssid = "........"; diff --git a/libraries/WebServer/examples/WebServer/README.md b/libraries/WebServer/examples/WebServer/README.md index 09d1cac7459..e76dd1c4f37 100644 --- a/libraries/WebServer/examples/WebServer/README.md +++ b/libraries/WebServer/examples/WebServer/README.md @@ -48,7 +48,7 @@ How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espress The WebServer library offers a simple path to implement a web server on a ESP32 based board. -The advantage on using the WebServer instead of the plain simple WiFiServer is that the WebServer +The advantage on using the WebServer instead of the plain simple NetworkServer is that the WebServer takes much care about the http protocol conventions and features and allows easily access to parameters. It offers plug-in capabilities by registering specific functionalities that will be outlined below. diff --git a/libraries/WebServer/examples/WebServer/WebServer.ino b/libraries/WebServer/examples/WebServer/WebServer.ino index 1193a2e6114..0b9f72b3c30 100644 --- a/libraries/WebServer/examples/WebServer/WebServer.ino +++ b/libraries/WebServer/examples/WebServer/WebServer.ino @@ -29,6 +29,7 @@ #include #include +#include #include "secrets.h" // add WLAN Credentials in here. diff --git a/libraries/WebServer/examples/WebUpdate/WebUpdate.ino b/libraries/WebServer/examples/WebUpdate/WebUpdate.ino index a3ae1f8a1ab..8f4d3d5e134 100644 --- a/libraries/WebServer/examples/WebUpdate/WebUpdate.ino +++ b/libraries/WebServer/examples/WebUpdate/WebUpdate.ino @@ -3,7 +3,7 @@ */ #include -#include +#include #include #include #include diff --git a/libraries/WebServer/src/Parsing.cpp b/libraries/WebServer/src/Parsing.cpp index 44a01668980..4ddd034e567 100644 --- a/libraries/WebServer/src/Parsing.cpp +++ b/libraries/WebServer/src/Parsing.cpp @@ -21,8 +21,8 @@ #include #include -#include "WiFiServer.h" -#include "WiFiClient.h" +#include "NetworkServer.h" +#include "NetworkClient.h" #include "WebServer.h" #include "detail/mimetable.h" @@ -41,7 +41,7 @@ const char * _http_method_str[] = { static const char Content_Type[] PROGMEM = "Content-Type"; static const char filename[] PROGMEM = "filename"; -static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& dataLength, int timeout_ms) +static char* readBytesWithTimeout(NetworkClient& client, size_t maxLength, size_t& dataLength, int timeout_ms) { char *buf = nullptr; dataLength = 0; @@ -73,7 +73,7 @@ static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& return buf; } -bool WebServer::_parseRequest(WiFiClient& client) { +bool WebServer::_parseRequest(NetworkClient& client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); client.readStringUntil('\n'); @@ -309,7 +309,7 @@ void WebServer::_uploadWriteByte(uint8_t b){ _currentUpload->buf[_currentUpload->currentSize++] = b; } -int WebServer::_uploadReadByte(WiFiClient& client) { +int WebServer::_uploadReadByte(NetworkClient& client) { int res = client.read(); if (res < 0) { @@ -322,7 +322,7 @@ int WebServer::_uploadReadByte(WiFiClient& client) { return res; } -bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ +bool WebServer::_parseForm(NetworkClient& client, String boundary, uint32_t len){ (void) len; log_v("Parse Form: Boundary: %s Length: %d", boundary.c_str(), len); String line; diff --git a/libraries/WebServer/src/WebServer.cpp b/libraries/WebServer/src/WebServer.cpp index e423900ca52..2ded68dce7e 100644 --- a/libraries/WebServer/src/WebServer.cpp +++ b/libraries/WebServer/src/WebServer.cpp @@ -26,8 +26,8 @@ #include #include #include "esp_random.h" -#include "WiFiServer.h" -#include "WiFiClient.h" +#include "NetworkServer.h" +#include "NetworkClient.h" #include "WebServer.h" #include "FS.h" #include "detail/RequestHandlersImpl.h" @@ -435,7 +435,7 @@ void WebServer::handleClient() { } if (!keepCurrentClient) { - _currentClient = WiFiClient(); + _currentClient = NetworkClient(); _currentStatus = HC_NONE; _currentUpload.reset(); } diff --git a/libraries/WebServer/src/WebServer.h b/libraries/WebServer/src/WebServer.h index d668c4e70e7..2434855b6eb 100644 --- a/libraries/WebServer/src/WebServer.h +++ b/libraries/WebServer/src/WebServer.h @@ -26,8 +26,8 @@ #include #include -#include -#include +#include "FS.h" +#include "Network.h" #include "HTTP_Method.h" #include "Uri.h" @@ -126,7 +126,7 @@ class WebServer String uri() { return _currentUri; } HTTPMethod method() { return _currentMethod; } - virtual WiFiClient & client() { return _currentClient; } + virtual NetworkClient & client() { return _currentClient; } HTTPUpload& upload() { return *_currentUpload; } String pathArg(unsigned int i); // get request path argument by number @@ -188,13 +188,13 @@ class WebServer void _addRequestHandler(RequestHandler* handler); void _handleRequest(); void _finalizeResponse(); - bool _parseRequest(WiFiClient& client); + bool _parseRequest(NetworkClient& client); void _parseArguments(String data); static String _responseCodeToString(int code); - bool _parseForm(WiFiClient& client, String boundary, uint32_t len); + bool _parseForm(NetworkClient& client, String boundary, uint32_t len); bool _parseFormUploadAborted(); void _uploadWriteByte(uint8_t b); - int _uploadReadByte(WiFiClient& client); + int _uploadReadByte(NetworkClient& client); void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength); bool _collectHeader(const char* headerName, const char* headerValue); @@ -210,9 +210,9 @@ class WebServer }; boolean _corsEnabled; - WiFiServer _server; + NetworkServer _server; - WiFiClient _currentClient; + NetworkClient _currentClient; HTTPMethod _currentMethod; String _currentUri; uint8_t _currentVersion; diff --git a/libraries/WiFi/examples/SimpleWiFiServer/SimpleWiFiServer.ino b/libraries/WiFi/examples/SimpleWiFiServer/SimpleWiFiServer.ino index 1867533662c..b852bc9b2f2 100644 --- a/libraries/WiFi/examples/SimpleWiFiServer/SimpleWiFiServer.ino +++ b/libraries/WiFi/examples/SimpleWiFiServer/SimpleWiFiServer.ino @@ -30,7 +30,7 @@ ported for sparkfun esp32 const char* ssid = "yourssid"; const char* password = "yourpasswd"; -WiFiServer server(80); +NetworkServer server(80); void setup() { @@ -63,7 +63,7 @@ void setup() } void loop(){ - WiFiClient client = server.accept(); // listen for incoming clients + NetworkClient client = server.accept(); // listen for incoming clients if (client) { // if you get a client, Serial.println("New Client."); // print a message out the serial port diff --git a/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino b/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino index 6c113fe48b9..98c85c1f612 100644 --- a/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino +++ b/libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino @@ -12,7 +12,7 @@ */ #include -#include +#include #include #ifndef LED_BUILTIN @@ -23,7 +23,7 @@ const char *ssid = "yourAP"; const char *password = "yourPassword"; -WiFiServer server(80); +NetworkServer server(80); void setup() { @@ -48,7 +48,7 @@ void setup() { } void loop() { - WiFiClient client = server.accept(); // listen for incoming clients + NetworkClient client = server.accept(); // listen for incoming clients if (client) { // if you get a client, Serial.println("New Client."); // print a message out the serial port diff --git a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino index be9aa239627..dacb891a4f3 100644 --- a/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino +++ b/libraries/WiFi/examples/WiFiBlueToothSwitch/WiFiBlueToothSwitch.ino @@ -92,7 +92,7 @@ void WiFiEvent(WiFiEvent_t event){ break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: Serial.print("STA IPv6: "); - Serial.println(WiFi.localIPv6()); + Serial.println(WiFi.linkLocalIPv6()); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: Serial.print("STA IPv4: "); diff --git a/libraries/WiFi/examples/WiFiClient/README.md b/libraries/WiFi/examples/WiFiClient/README.md index 079ed9f29a8..b85ec43e691 100644 --- a/libraries/WiFi/examples/WiFiClient/README.md +++ b/libraries/WiFi/examples/WiFiClient/README.md @@ -1,4 +1,4 @@ -# WiFiClient +# NetworkClient This example demonstrates reading and writing data from and to a web service which can be used for logging data, creating insights and taking actions based on those data. @@ -126,7 +126,7 @@ ETag: W/"8e9c308fe2c50309f991586be1aff28d" X-Frame-Options: SAMEORIGIN 1e3 -{"channel":{"id":2005329,"name":"WiFiCLient example","description":"Default setup for Arduino ESP32 WiFiClient example","latitude":"0.0","longitude":"0.0","field1":"data0","created_at":"2023-01-11T15:56:08Z","updated_at":"2023-01-13T08:13:58Z","last_entry_id":2871},"feeds":[{"created_at":"2023-01-13T13:11:30Z","entry_id":2869,"field1":"359"},{"created_at":"2023-01-13T13:11:57Z","entry_id":2870,"field1":"361"},{"created_at":"2023-01-13T13:12:23Z","entry_id":2871,"field1":"363"}]} +{"channel":{"id":2005329,"name":"WiFiCLient example","description":"Default setup for Arduino ESP32 NetworkClient example","latitude":"0.0","longitude":"0.0","field1":"data0","created_at":"2023-01-11T15:56:08Z","updated_at":"2023-01-13T08:13:58Z","last_entry_id":2871},"feeds":[{"created_at":"2023-01-13T13:11:30Z","entry_id":2869,"field1":"359"},{"created_at":"2023-01-13T13:11:57Z","entry_id":2870,"field1":"361"},{"created_at":"2023-01-13T13:12:23Z","entry_id":2871,"field1":"363"}]} 0 diff --git a/libraries/WiFi/examples/WiFiClient/WiFiClient.ino b/libraries/WiFi/examples/WiFiClient/WiFiClient.ino index ebd207984a2..6b7a2bc0ae2 100644 --- a/libraries/WiFi/examples/WiFiClient/WiFiClient.ino +++ b/libraries/WiFi/examples/WiFiClient/WiFiClient.ino @@ -57,7 +57,7 @@ void setup() Serial.println(WiFi.localIP()); } -void readResponse(WiFiClient *client){ +void readResponse(NetworkClient *client){ unsigned long timeout = millis(); while(client->available() == 0){ if(millis() - timeout > 5000){ @@ -77,7 +77,7 @@ void readResponse(WiFiClient *client){ } void loop(){ - WiFiClient client; + NetworkClient client; String footer = String(" HTTP/1.1\r\n") + "Host: " + String(host) + "\r\n" + "Connection: close\r\n\r\n"; // WRITE -------------------------------------------------------------------------------------------- diff --git a/libraries/WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino b/libraries/WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino index ecfed5e1957..adc976ecd81 100644 --- a/libraries/WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino +++ b/libraries/WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino @@ -44,8 +44,8 @@ void loop() Serial.print("Connecting to "); Serial.println(host); - // Use WiFiClient class to create TCP connections - WiFiClient client; + // Use NetworkClient class to create TCP connections + NetworkClient client; if (!client.connect(host, port)) { Serial.println("Connection failed."); diff --git a/libraries/WiFi/examples/WiFiClientConnect/README.md b/libraries/WiFi/examples/WiFiClientConnect/README.md index 5e6760a9bee..c18950f0458 100644 --- a/libraries/WiFi/examples/WiFiClientConnect/README.md +++ b/libraries/WiFi/examples/WiFiClientConnect/README.md @@ -1,4 +1,4 @@ -# WiFiClientConnect Example +# NetworkClientConnect Example This example demonstrates how to connect to the WiFi and manage the status and disconnection from STA. diff --git a/libraries/WiFi/examples/WiFiClientEnterprise/WiFiClientEnterprise.ino b/libraries/WiFi/examples/WiFiClientEnterprise/WiFiClientEnterprise.ino index 7ae10f99e73..7a93deb84c8 100644 --- a/libraries/WiFi/examples/WiFiClientEnterprise/WiFiClientEnterprise.ino +++ b/libraries/WiFi/examples/WiFiClientEnterprise/WiFiClientEnterprise.ino @@ -66,7 +66,7 @@ void loop() { } Serial.print("Connecting to website: "); Serial.println(host); - WiFiClient client; + NetworkClient client; if (client.connect(host, 80)) { String url = "/rele/rele1.txt"; client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: ESP32\r\n" + "Connection: close\r\n\r\n"); diff --git a/libraries/WiFi/examples/WiFiClientStaticIP/WiFiClientStaticIP.ino b/libraries/WiFi/examples/WiFiClientStaticIP/WiFiClientStaticIP.ino index 1f4032f0640..67ead3609f2 100644 --- a/libraries/WiFi/examples/WiFiClientStaticIP/WiFiClientStaticIP.ino +++ b/libraries/WiFi/examples/WiFiClientStaticIP/WiFiClientStaticIP.ino @@ -56,8 +56,8 @@ void loop() Serial.print("connecting to "); Serial.println(host); - // Use WiFiClient class to create TCP connections - WiFiClient client; + // Use NetworkClient class to create TCP connections + NetworkClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); diff --git a/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino b/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino index c7edd384d82..c466493da5c 100644 --- a/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino +++ b/libraries/WiFi/examples/WiFiIPv6/WiFiIPv6.ino @@ -6,7 +6,7 @@ static volatile bool wifi_connected = false; -WiFiUDP ntpClient; +NetworkUDP ntpClient; void wifiOnConnect(){ Serial.println("STA Connected"); @@ -79,11 +79,11 @@ void WiFiEvent(WiFiEvent_t event){ break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: Serial.print("STA IPv6: "); - Serial.println(WiFi.localIPv6()); + Serial.println(WiFi.linkLocalIPv6()); break; case ARDUINO_EVENT_WIFI_AP_GOT_IP6: Serial.print("AP IPv6: "); - Serial.println(WiFi.softAPIPv6()); + Serial.println(WiFi.softAPlinkLocalIPv6()); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: wifiOnConnect(); diff --git a/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino b/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino index 92e41025e98..b4d12afb2a8 100644 --- a/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino +++ b/libraries/WiFi/examples/WiFiTelnetToSerial/WiFiTelnetToSerial.ino @@ -28,8 +28,8 @@ WiFiMulti wifiMulti; const char* ssid = "**********"; const char* password = "**********"; -WiFiServer server(23); -WiFiClient serverClients[MAX_SRV_CLIENTS]; +NetworkServer server(23); +NetworkClient serverClients[MAX_SRV_CLIENTS]; void setup() { Serial.begin(115200); diff --git a/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino b/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino index 7c5ebc39196..853bdefc08c 100644 --- a/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino +++ b/libraries/WiFi/examples/WiFiUDPClient/WiFiUDPClient.ino @@ -3,7 +3,7 @@ * */ #include -#include +#include // WiFi network name and password: const char * networkName = "your-ssid"; @@ -19,7 +19,7 @@ const int udpPort = 3333; boolean connected = false; //The udp library class -WiFiUDP udp; +NetworkUDP udp; void setup(){ // Initilize hardware serial: diff --git a/libraries/WiFi/keywords.txt b/libraries/WiFi/keywords.txt index 5720aaac81c..08b970b928f 100644 --- a/libraries/WiFi/keywords.txt +++ b/libraries/WiFi/keywords.txt @@ -13,10 +13,10 @@ WiFi KEYWORD3 ####################################### WiFi KEYWORD1 -WiFiClient KEYWORD1 -WiFiServer KEYWORD1 -WiFiUDP KEYWORD1 -WiFiClientSecure KEYWORD1 +NetworkClient KEYWORD1 +NetworkServer KEYWORD1 +NetworkUDP KEYWORD1 +NetworkClientSecure KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) diff --git a/libraries/WiFi/src/AP.cpp b/libraries/WiFi/src/AP.cpp new file mode 100644 index 00000000000..3f5e6fc9a77 --- /dev/null +++ b/libraries/WiFi/src/AP.cpp @@ -0,0 +1,340 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "WiFi.h" +#include "WiFiGeneric.h" +#include "WiFiAP.h" +#if SOC_WIFI_SUPPORTED +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dhcpserver/dhcpserver_options.h" + + +esp_netif_t* get_esp_interface_netif(esp_interface_t interface); + +static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){ + if(!dst || !src || !dst_len){ + return 0; + } + size_t src_len = strlen(src); + if(src_len >= dst_len){ + src_len = dst_len; + } else { + src_len += 1; + } + memcpy(dst, src, src_len); + return src_len; +} + +/** + * compare two AP configurations + * @param lhs softap_config + * @param rhs softap_config + * @return equal + */ +static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs) +{ + if(strncmp(reinterpret_cast(lhs.ap.ssid), reinterpret_cast(rhs.ap.ssid), 32) != 0) { + return false; + } + if(strncmp(reinterpret_cast(lhs.ap.password), reinterpret_cast(rhs.ap.password), 64) != 0) { + return false; + } + if(lhs.ap.channel != rhs.ap.channel) { + return false; + } + if(lhs.ap.authmode != rhs.ap.authmode) { + return false; + } + if(lhs.ap.ssid_hidden != rhs.ap.ssid_hidden) { + return false; + } + if(lhs.ap.max_connection != rhs.ap.max_connection) { + return false; + } + if(lhs.ap.pairwise_cipher != rhs.ap.pairwise_cipher) { + return false; + } + if(lhs.ap.ftm_responder != rhs.ap.ftm_responder) { + return false; + } + return true; +} + +static APClass * _ap_network_if = NULL; + +static esp_event_handler_instance_t _ap_ev_instance = NULL; +static void _ap_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + if (event_base == WIFI_EVENT){ + ((APClass*)arg)->_onApEvent(event_id, event_data); + } +} + +static void _onApArduinoEvent(arduino_event_id_t event, arduino_event_info_t info) +{ + if(_ap_network_if == NULL || event < ARDUINO_EVENT_WIFI_AP_START || event > ARDUINO_EVENT_WIFI_AP_GOT_IP6){ + return; + } + log_d("Arduino AP Event: %d - %s", event, Network.eventName(event)); + if(event == ARDUINO_EVENT_WIFI_AP_START) { + if (_ap_network_if->getStatusBits() & ESP_NETIF_WANT_IP6_BIT){ + esp_err_t err = esp_netif_create_ip6_linklocal(_ap_network_if->netif()); + if(err != ESP_OK){ + log_e("Failed to enable IPv6 Link Local on AP: 0x%x: %s", err, esp_err_to_name(err)); + } else { + log_v("Enabled IPv6 Link Local on %s", _ap_network_if->desc()); + } + } + } +} + +void APClass::_onApEvent(int32_t event_id, void* event_data){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; + + if (event_id == WIFI_EVENT_AP_START) { + log_v("AP Started"); + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_START; + setStatusBits(ESP_NETIF_STARTED_BIT); + } else if (event_id == WIFI_EVENT_AP_STOP) { + log_v("AP Stopped"); + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STOP; + clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + } else if (event_id == WIFI_EVENT_AP_PROBEREQRECVED) { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_ap_probe_req_rx_t * event = (wifi_event_ap_probe_req_rx_t*)event_data; + log_v("AP Probe Request: RSSI: %d, MAC: " MACSTR, event->rssi, MAC2STR(event->mac)); + #endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED; + memcpy(&arduino_event.event_info.wifi_ap_probereqrecved, event_data, sizeof(wifi_event_ap_probe_req_rx_t)); + } else if (event_id == WIFI_EVENT_AP_STACONNECTED) { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + log_v("AP Station Connected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); + #endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STACONNECTED; + memcpy(&arduino_event.event_info.wifi_ap_staconnected, event_data, sizeof(wifi_event_ap_staconnected_t)); + setStatusBits(ESP_NETIF_CONNECTED_BIT); + } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; + log_v("AP Station Disconnected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); + #endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STADISCONNECTED; + memcpy(&arduino_event.event_info.wifi_ap_stadisconnected, event_data, sizeof(wifi_event_ap_stadisconnected_t)); + // If no more clients are left + wifi_sta_list_t clients; + if(esp_wifi_ap_get_sta_list(&clients) != ESP_OK || clients.num == 0) { + clearStatusBits(ESP_NETIF_CONNECTED_BIT); + } + } else { + return; + } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} + +APClass::APClass(){ + _ap_network_if = this; +} + +APClass::~APClass(){ + end(); + _ap_network_if = NULL; +} + +bool APClass::begin(){ + + Network.begin(); + if(_ap_ev_instance == NULL && esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_ap_event_cb, this, &_ap_ev_instance)){ + log_e("event_handler_instance_register for WIFI_EVENT Failed!"); + return false; + } + if(_esp_netif == NULL){ + Network.onSysEvent(_onApArduinoEvent); + } + + if(!WiFi.enableAP(true)) { + log_e("AP enable failed!"); + return false; + } + + // attach events and esp_netif here + if(_esp_netif == NULL){ + _esp_netif = get_esp_interface_netif(ESP_IF_WIFI_AP); + /* attach to receive events */ + initNetif(ESP_NETIF_ID_AP); + } + + return true; +} + +bool APClass::end(){ + if(!WiFi.enableAP(false)) { + log_e("AP disable failed!"); + return false; + } + Network.removeEvent(_onApArduinoEvent); + // we just set _esp_netif to NULL here, so destroyNetif() does not try to destroy it. + // That would be done by WiFi.enableAP(false) if STA is not enabled, or when it gets disabled + _esp_netif = NULL; + destroyNetif(); + if(_ap_ev_instance != NULL){ + esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_ap_event_cb); + _ap_ev_instance = NULL; + } + return true; +} + +bool APClass::create(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection, bool ftm_responder){ + if(!ssid || *ssid == 0) { + // fail SSID missing + log_e("SSID missing!"); + return false; + } + + if(passphrase && (strlen(passphrase) > 0 && strlen(passphrase) < 8)) { + // fail passphrase too short + log_e("passphrase too short!"); + return false; + } + + if(!begin()) { + return false; + } + + wifi_config_t conf; + memset(&conf, 0, sizeof(wifi_config_t)); + conf.ap.channel = channel; + conf.ap.max_connection = max_connection; + conf.ap.beacon_interval = 100; + conf.ap.ssid_hidden = ssid_hidden; + conf.ap.ftm_responder = ftm_responder; + if(ssid != NULL && ssid[0] != 0){ + _wifi_strncpy((char*)conf.ap.ssid, ssid, 32); + conf.ap.ssid_len = strlen(ssid); + if(passphrase != NULL && passphrase[0] != 0){ + conf.ap.authmode = WIFI_AUTH_WPA2_PSK; + conf.ap.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP; // Disable by default enabled insecure TKIP and use just CCMP. + _wifi_strncpy((char*)conf.ap.password, passphrase, 64); + } + } + + wifi_config_t conf_current; + esp_err_t err = esp_wifi_get_config(WIFI_IF_AP, &conf_current); + if(err){ + log_e("Get AP config failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + if(!softap_config_equal(conf, conf_current)) { + err = esp_wifi_set_config(WIFI_IF_AP, &conf); + if(err){ + log_e("Set AP config failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + } + + return true; +} + +bool APClass::clear(){ + if(!begin()) { + return false; + } + wifi_config_t conf; + memset(&conf, 0, sizeof(wifi_config_t)); + conf.ap.channel = 1; + conf.ap.max_connection = 4; + conf.ap.beacon_interval = 100; + esp_err_t err = esp_wifi_set_config(WIFI_IF_AP, &conf); + if(err){ + log_e("Set AP config failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +bool APClass::bandwidth(wifi_bandwidth_t bandwidth){ + if(!begin()) { + return false; + } + esp_err_t err = esp_wifi_set_bandwidth(WIFI_IF_AP, bandwidth); + if(err){ + log_e("Could not set AP bandwidth! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + + return true; +} + +String APClass::SSID(void) const{ + if(!started()){ + return String(); + } + wifi_config_t info; + if(!esp_wifi_get_config(WIFI_IF_AP, &info)) { + return String(reinterpret_cast(info.ap.ssid)); + } + return String(); +} + +uint8_t APClass::stationCount(){ + wifi_sta_list_t clients; + if(!started()){ + return 0; + } + if(esp_wifi_ap_get_sta_list(&clients) == ESP_OK) { + return clients.num; + } + return 0; +} + +size_t APClass::printDriverInfo(Print & out) const{ + size_t bytes = 0; + wifi_config_t info; + wifi_sta_list_t clients; + if(!started()){ + return bytes; + } + if(esp_wifi_get_config(WIFI_IF_AP, &info) != ESP_OK){ + return bytes; + } + bytes += out.print(","); + bytes += out.print((const char*)info.ap.ssid); + bytes += out.print(",CH:"); + bytes += out.print(info.ap.channel); + + if(info.ap.authmode == WIFI_AUTH_OPEN){ bytes += out.print(",OPEN"); } + else if(info.ap.authmode == WIFI_AUTH_WEP){ bytes += out.print(",WEP"); } + else if(info.ap.authmode == WIFI_AUTH_WPA_PSK){ bytes += out.print(",WWPA_PSK"); } + else if(info.ap.authmode == WIFI_AUTH_WPA2_PSK){ bytes += out.print(",WWPA2_PSK"); } + else if(info.ap.authmode == WIFI_AUTH_WPA_WPA2_PSK){ bytes += out.print(",WWPA_WPA2_PSK"); } + else if(info.ap.authmode == WIFI_AUTH_ENTERPRISE){ bytes += out.print(",WEAP"); } + else if(info.ap.authmode == WIFI_AUTH_WPA3_PSK){ bytes += out.print(",WWPA3_PSK"); } + else if(info.ap.authmode == WIFI_AUTH_WPA2_WPA3_PSK){ bytes += out.print(",WWPA2_WPA3_PSK"); } + else if(info.ap.authmode == WIFI_AUTH_WAPI_PSK){ bytes += out.print(",WWAPI_PSK"); } + else if(info.ap.authmode == WIFI_AUTH_OWE){ bytes += out.print(",WOWE"); } + else if(info.ap.authmode == WIFI_AUTH_WPA3_ENT_192){ bytes += out.print(",WWPA3_ENT_SUITE_B_192_BIT"); } + + if(esp_wifi_ap_get_sta_list(&clients) == ESP_OK) { + bytes += out.print(",STA:"); + bytes += out.print(clients.num); + } + return bytes; +} + +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/STA.cpp b/libraries/WiFi/src/STA.cpp new file mode 100644 index 00000000000..6003c4347a6 --- /dev/null +++ b/libraries/WiFi/src/STA.cpp @@ -0,0 +1,794 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "WiFi.h" +#include "WiFiGeneric.h" +#include "WiFiSTA.h" +#if SOC_WIFI_SUPPORTED +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lwip/err.h" +#include "lwip/dns.h" +#include +#include +#include "esp_mac.h" + +#if __has_include ("esp_eap_client.h") +#include "esp_eap_client.h" +#else +#include "esp_wpa2.h" +#endif + +esp_netif_t* get_esp_interface_netif(esp_interface_t interface); + +static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){ + if(!dst || !src || !dst_len){ + return 0; + } + size_t src_len = strlen(src); + if(src_len >= dst_len){ + src_len = dst_len; + } else { + src_len += 1; + } + memcpy(dst, src, src_len); + return src_len; +} + +static STAClass * _sta_network_if = NULL; + +static esp_event_handler_instance_t _sta_ev_instance = NULL; +static void _sta_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { + if (event_base == WIFI_EVENT){ + ((STAClass*)arg)->_onStaEvent(event_id, event_data); + } +} + +static bool _is_staReconnectableReason(uint8_t reason) { + switch(reason) { + case WIFI_REASON_UNSPECIFIED: + //Timeouts (retry) + case WIFI_REASON_AUTH_EXPIRE: + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: + case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: + case WIFI_REASON_802_1X_AUTH_FAILED: + case WIFI_REASON_HANDSHAKE_TIMEOUT: + //Transient error (reconnect) + case WIFI_REASON_AUTH_LEAVE: + case WIFI_REASON_ASSOC_EXPIRE: + case WIFI_REASON_ASSOC_TOOMANY: + case WIFI_REASON_NOT_AUTHED: + case WIFI_REASON_NOT_ASSOCED: + case WIFI_REASON_ASSOC_NOT_AUTHED: + case WIFI_REASON_MIC_FAILURE: + case WIFI_REASON_IE_IN_4WAY_DIFFERS: + case WIFI_REASON_INVALID_PMKID: + case WIFI_REASON_BEACON_TIMEOUT: + case WIFI_REASON_NO_AP_FOUND: + case WIFI_REASON_ASSOC_FAIL: + case WIFI_REASON_CONNECTION_FAIL: + case WIFI_REASON_AP_TSF_RESET: + case WIFI_REASON_ROAMING: + return true; + default: + return false; + } +} + +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE +static const char * auth_mode_str(int authmode) +{ + switch (authmode) { + case WIFI_AUTH_OPEN: + return ("OPEN"); + break; + case WIFI_AUTH_WEP: + return ("WEP"); + break; + case WIFI_AUTH_WPA_PSK: + return ("WPA_PSK"); + break; + case WIFI_AUTH_WPA2_PSK: + return ("WPA2_PSK"); + break; + case WIFI_AUTH_WPA_WPA2_PSK: + return ("WPA_WPA2_PSK"); + break; + case WIFI_AUTH_WPA2_ENTERPRISE: + return ("WPA2_ENTERPRISE"); + break; + case WIFI_AUTH_WPA3_PSK: + return ("WPA3_PSK"); + break; + case WIFI_AUTH_WPA2_WPA3_PSK: + return ("WPA2_WPA3_PSK"); + break; + case WIFI_AUTH_WAPI_PSK: + return ("WPAPI_PSK"); + break; + default: + break; + } + return ("UNKNOWN"); +} +#endif + +static void _onStaArduinoEvent(arduino_event_id_t event, arduino_event_info_t info) +{ + if(_sta_network_if == NULL || event < ARDUINO_EVENT_WIFI_STA_START || event > ARDUINO_EVENT_WIFI_STA_LOST_IP){ + return; + } + static bool first_connect = true; + log_d("Arduino STA Event: %d - %s", event, Network.eventName(event)); + + if(event == ARDUINO_EVENT_WIFI_STA_START) { + _sta_network_if->_setStatus(WL_DISCONNECTED); + if(esp_wifi_set_ps(WiFi.getSleep()) != ESP_OK){ + log_e("esp_wifi_set_ps failed"); + } + } else if(event == ARDUINO_EVENT_WIFI_STA_STOP) { + _sta_network_if->_setStatus(WL_STOPPED); + } else if(event == ARDUINO_EVENT_WIFI_STA_CONNECTED) { + _sta_network_if->_setStatus(WL_IDLE_STATUS); + if (_sta_network_if->getStatusBits() & ESP_NETIF_WANT_IP6_BIT){ + esp_err_t err = esp_netif_create_ip6_linklocal(_sta_network_if->netif()); + if(err != ESP_OK){ + log_e("Failed to enable IPv6 Link Local on STA: 0x%x: %s", err, esp_err_to_name(err)); + } else { + log_v("Enabled IPv6 Link Local on %s", _sta_network_if->desc()); + } + } + } else if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) { + uint8_t reason = info.wifi_sta_disconnected.reason; + // Reason 0 causes crash, use reason 1 (UNSPECIFIED) instead + if(!reason) + reason = WIFI_REASON_UNSPECIFIED; + log_w("Reason: %u - %s", reason, WiFi.STA.disconnectReasonName((wifi_err_reason_t)reason)); + if(reason == WIFI_REASON_NO_AP_FOUND) { + _sta_network_if->_setStatus(WL_NO_SSID_AVAIL); + } else if((reason == WIFI_REASON_AUTH_FAIL) && !first_connect){ + _sta_network_if->_setStatus(WL_CONNECT_FAILED); + } else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) { + _sta_network_if->_setStatus(WL_CONNECTION_LOST); + } else if(reason == WIFI_REASON_AUTH_EXPIRE) { + + } else { + _sta_network_if->_setStatus(WL_DISCONNECTED); + } + + bool DoReconnect = false; + if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! + } + else if(first_connect) { //Retry once for all failure reasons + first_connect = false; + DoReconnect = true; + log_d("WiFi Reconnect Running"); + } + else if(_sta_network_if->getAutoReconnect() && _is_staReconnectableReason(reason)) { + DoReconnect = true; + log_d("WiFi AutoReconnect Running"); + } + else if(reason == WIFI_REASON_ASSOC_FAIL) { + _sta_network_if->_setStatus(WL_CONNECT_FAILED); + } + if(DoReconnect) { + _sta_network_if->disconnect(); + _sta_network_if->connect(); + } + } else if(event == ARDUINO_EVENT_WIFI_STA_GOT_IP) { +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG + uint8_t * ip = (uint8_t *)&(info.got_ip.ip_info.ip.addr); + uint8_t * mask = (uint8_t *)&(info.got_ip.ip_info.netmask.addr); + uint8_t * gw = (uint8_t *)&(info.got_ip.ip_info.gw.addr); + log_d("STA IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u", + ip[0], ip[1], ip[2], ip[3], + mask[0], mask[1], mask[2], mask[3], + gw[0], gw[1], gw[2], gw[3]); +#endif + _sta_network_if->_setStatus(WL_CONNECTED); + } else if(event == ARDUINO_EVENT_WIFI_STA_LOST_IP) { + _sta_network_if->_setStatus(WL_IDLE_STATUS); + } +} + +void STAClass::_onStaEvent(int32_t event_id, void* event_data){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_MAX; + + if (event_id == WIFI_EVENT_STA_START) { + log_v("STA Started"); + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_START; + setStatusBits(ESP_NETIF_STARTED_BIT); + } else if (event_id == WIFI_EVENT_STA_STOP) { + log_v("STA Stopped"); + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_STOP; + clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_authmode_change_t * event = (wifi_event_sta_authmode_change_t*)event_data; + log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode)); + #endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE; + memcpy(&arduino_event.event_info.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t)); + } else if (event_id == WIFI_EVENT_STA_CONNECTED) { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_connected_t * event = (wifi_event_sta_connected_t*)event_data; + log_v("STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode)); + #endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_CONNECTED; + memcpy(&arduino_event.event_info.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t)); + setStatusBits(ESP_NETIF_CONNECTED_BIT); + } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_disconnected_t * event = (wifi_event_sta_disconnected_t*)event_data; + log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason); + #endif + arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_DISCONNECTED; + memcpy(&arduino_event.event_info.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t)); + clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + } else { + return; + } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} + +STAClass::STAClass(): + _minSecurity(WIFI_AUTH_WPA2_PSK) + , _scanMethod(WIFI_FAST_SCAN) + , _sortMethod(WIFI_CONNECT_AP_BY_SIGNAL) + , _autoReconnect(true) + , _status(WL_STOPPED) +{ + _sta_network_if = this; +} + +STAClass::~STAClass(){ + end(); + _sta_network_if = NULL; +} + +wl_status_t STAClass::status(){ + return _status; +} + +void STAClass::_setStatus(wl_status_t status){ + _status = status; +} + +/** + * Sets the working bandwidth of the STA mode + * @param m wifi_bandwidth_t + */ +bool STAClass::bandwidth(wifi_bandwidth_t bandwidth) { + if(!begin()) { + return false; + } + + esp_err_t err; + err = esp_wifi_set_bandwidth(WIFI_IF_STA, bandwidth); + if(err){ + log_e("Could not set STA bandwidth! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + + return true; +} + +bool STAClass::begin(bool tryConnect){ + + Network.begin(); + if(_sta_ev_instance == NULL && esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_sta_event_cb, this, &_sta_ev_instance)){ + log_e("event_handler_instance_register for WIFI_EVENT Failed!"); + return false; + } + if(_esp_netif == NULL){ + Network.onSysEvent(_onStaArduinoEvent); + } + + if(!WiFi.enableSTA(true)) { + log_e("STA enable failed!"); + return false; + } + + // attach events and esp_netif here + if(_esp_netif == NULL){ + _esp_netif = get_esp_interface_netif(ESP_IF_WIFI_STA); + /* attach to receive events */ + initNetif(ESP_NETIF_ID_STA); + } + + if(tryConnect){ + return connect(); + } + return true; +} + +bool STAClass::end(){ + if(!WiFi.enableSTA(false)) { + log_e("STA disable failed!"); + return false; + } + Network.removeEvent(_onStaArduinoEvent); + // we just set _esp_netif to NULL here, so destroyNetif() does not try to destroy it. + // That would be done by WiFi.enableSTA(false) if AP is not enabled, or when it gets disabled + _esp_netif = NULL; + destroyNetif(); + if(_sta_ev_instance != NULL){ + esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_sta_event_cb); + _sta_ev_instance = NULL; + } + return true; +} + +bool STAClass::connect(){ + if(_esp_netif == NULL){ + log_e("STA not started! You must call begin() first."); + return false; + } + + if(connected()){ + log_w("STA already connected."); + return true; + } + + wifi_config_t current_conf; + if(esp_wifi_get_config(WIFI_IF_STA, ¤t_conf) != ESP_OK || esp_wifi_set_config(WIFI_IF_STA, ¤t_conf) != ESP_OK) { + log_e("STA config failed"); + return false; + } + + if((getStatusBits() & ESP_NETIF_HAS_IP_BIT) == 0 && !config()){ + log_e("STA failed to configure dynamic IP!"); + return false; + } + + esp_err_t err = esp_wifi_connect(); + if(err){ + log_e("STA connect failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + return true; +} + +/** + * Start Wifi connection + * if passphrase is set the most secure supported mode will be automatically selected + * @param ssid const char* Pointer to the SSID string. + * @param passphrase const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal). + * @param bssid uint8_t[6] Optional. BSSID / MAC of AP + * @param channel Optional. Channel of AP + * @param connect Optional. call connect + * @return + */ +bool STAClass::connect(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool tryConnect){ + if(_esp_netif == NULL){ + log_e("STA not started! You must call begin() first."); + return false; + } + + if(connected()){ + log_w("STA currently connected. Disconnecting..."); + if(!disconnect(true, 1000)){ + return false; + } + } + + if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { + log_e("SSID too long or missing!"); + return false; + } + + if(passphrase && strlen(passphrase) > 64) { + log_e("passphrase too long!"); + return false; + } + + wifi_config_t conf; + memset(&conf, 0, sizeof(wifi_config_t)); + conf.sta.channel = channel; + conf.sta.scan_method = _scanMethod; + conf.sta.sort_method = _sortMethod; + conf.sta.threshold.rssi = -127; + conf.sta.pmf_cfg.capable = true; + if(ssid != NULL && ssid[0] != 0){ + _wifi_strncpy((char*)conf.sta.ssid, ssid, 32); + if(passphrase != NULL && passphrase[0] != 0){ + conf.sta.threshold.authmode = _minSecurity; + _wifi_strncpy((char*)conf.sta.password, passphrase, 64); + } + if(bssid != NULL){ + conf.sta.bssid_set = 1; + memcpy(conf.sta.bssid, bssid, 6); + } + } + + esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &conf); + if(err != ESP_OK){ + log_e("STA clear config failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + + if((getStatusBits() & ESP_NETIF_HAS_IP_BIT) == 0 && !config()){ + log_e("STA failed to configure dynamic IP!"); + return false; + } + + if(tryConnect){ + esp_err_t err = esp_wifi_connect(); + if(err){ + log_e("STA connect failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + } + return true; +} + +/** + * Start Wifi connection with a WPA2 Enterprise AP + * if passphrase is set the most secure supported mode will be automatically selected + * @param ssid const char* Pointer to the SSID string. + * @param method wpa2_method_t The authentication method of WPA2 (WPA2_AUTH_TLS, WPA2_AUTH_PEAP, WPA2_AUTH_TTLS) + * @param wpa2_identity const char* Pointer to the entity + * @param wpa2_username const char* Pointer to the username + * @param password const char * Pointer to the password. + * @param ca_pem const char* Pointer to a string with the contents of a .pem file with CA cert + * @param client_crt const char* Pointer to a string with the contents of a .crt file with client cert + * @param client_key const char* Pointer to a string with the contants of a .key file with client key + * @param bssid uint8_t[6] Optional. BSSID / MAC of AP + * @param channel Optional. Channel of AP + * @param connect Optional. call connect + * @return + */ +bool STAClass::connect(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool tryConnect){ + if(_esp_netif == NULL){ + log_e("STA not started! You must call begin() first."); + return false; + } + + if(connected()){ + log_w("STA currently connected. Disconnecting..."); + if(!disconnect(true, 1000)){ + return false; + } + } + + if(!wpa2_ssid || *wpa2_ssid == 0x00 || strlen(wpa2_ssid) > 32) { + log_e("SSID too long or missing!"); + return false; + } + + if(wpa2_identity && strlen(wpa2_identity) > 64) { + log_e("identity too long!"); + return false; + } + + if(wpa2_username && strlen(wpa2_username) > 64) { + log_e("username too long!"); + return false; + } + + if(wpa2_password && strlen(wpa2_password) > 64) { + log_e("password too long!"); + return false; + } + + if(ca_pem) { +#if __has_include ("esp_eap_client.h") + esp_eap_client_set_ca_cert((uint8_t *)ca_pem, strlen(ca_pem)); +#else + esp_wifi_sta_wpa2_ent_set_ca_cert((uint8_t *)ca_pem, strlen(ca_pem)); +#endif + } + + if(client_crt) { +#if __has_include ("esp_eap_client.h") + esp_eap_client_set_certificate_and_key((uint8_t *)client_crt, strlen(client_crt), (uint8_t *)client_key, strlen(client_key), NULL, 0); +#else + esp_wifi_sta_wpa2_ent_set_cert_key((uint8_t *)client_crt, strlen(client_crt), (uint8_t *)client_key, strlen(client_key), NULL, 0); +#endif + } + +#if __has_include ("esp_eap_client.h") + esp_eap_client_set_identity((uint8_t *)wpa2_identity, strlen(wpa2_identity)); +#else + esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)wpa2_identity, strlen(wpa2_identity)); +#endif + if(method == WPA2_AUTH_PEAP || method == WPA2_AUTH_TTLS) { +#if __has_include ("esp_eap_client.h") + esp_eap_client_set_username((uint8_t *)wpa2_username, strlen(wpa2_username)); + esp_eap_client_set_password((uint8_t *)wpa2_password, strlen(wpa2_password)); +#else + esp_wifi_sta_wpa2_ent_set_username((uint8_t *)wpa2_username, strlen(wpa2_username)); + esp_wifi_sta_wpa2_ent_set_password((uint8_t *)wpa2_password, strlen(wpa2_password)); +#endif + } +#if __has_include ("esp_eap_client.h") + esp_wifi_sta_enterprise_enable(); //set config settings to enable function +#else + esp_wifi_sta_wpa2_ent_enable(); //set config settings to enable function +#endif + + return connect(wpa2_ssid, NULL, 0, NULL, tryConnect); //connect to wifi +} + +bool STAClass::disconnect(bool eraseap, unsigned long timeout){ + if(eraseap){ + if(!started()){ + log_e("STA not started! You must call begin first."); + return false; + } + wifi_config_t conf; + memset(&conf, 0, sizeof(wifi_config_t)); + esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &conf); + if(err != ESP_OK){ + log_e("STA clear config failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + } + + if(!connected()){ + log_w("STA already disconnected."); + return true; + } + + esp_err_t err = esp_wifi_disconnect(); + if(err != ESP_OK){ + log_e("STA disconnect failed! 0x%x: %s", err, esp_err_to_name(err)); + return false; + } + + if(timeout){ + const unsigned long start = millis(); + while (connected() && ((millis() - start) < timeout)) { + delay(5); + } + if(connected()){ + return false; + } + } + + return true; +} + +bool STAClass::reconnect(){ + if(connected()) { + if(esp_wifi_disconnect() != ESP_OK) { + return false; + } + } + return esp_wifi_connect() == ESP_OK; +} + +bool STAClass::erase(){ + if(!started()){ + log_e("STA not started! You must call begin first."); + return false; + } + return esp_wifi_restore()==ESP_OK; +} + +uint8_t STAClass::waitForConnectResult(unsigned long timeoutLength){ + //1 and 3 have STA enabled + if((WiFiGenericClass::getMode() & WIFI_MODE_STA) == 0) { + return WL_DISCONNECTED; + } + unsigned long start = millis(); + while((!status() || status() >= WL_DISCONNECTED) && (millis() - start) < timeoutLength) { + delay(100); + } + return status(); +} + +bool STAClass::setAutoReconnect(bool autoReconnect){ + _autoReconnect = autoReconnect; + return true; +} + +bool STAClass::getAutoReconnect(){ + return _autoReconnect; +} + +void STAClass::setMinSecurity(wifi_auth_mode_t minSecurity){ + _minSecurity = minSecurity; +} + +void STAClass::setScanMethod(wifi_scan_method_t scanMethod){ + _scanMethod = scanMethod; +} + +void STAClass::setSortMethod(wifi_sort_method_t sortMethod){ + _sortMethod = sortMethod; +} + +String STAClass::SSID() const { + if(!started()){ + return String(); + } + wifi_ap_record_t info; + if(!esp_wifi_sta_get_ap_info(&info)) { + return String(reinterpret_cast(info.ssid)); + } + return String(); +} + +String STAClass::psk() const { + if(!started()){ + return String(); + } + wifi_config_t conf; + esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_STA, &conf); + return String(reinterpret_cast(conf.sta.password)); +} + +uint8_t * STAClass::BSSID(uint8_t* buff){ + static uint8_t bssid[6]; + wifi_ap_record_t info; + if(!started()){ + return NULL; + } + esp_err_t err = esp_wifi_sta_get_ap_info(&info); + if (buff != NULL) { + if(err) { + memset(buff, 0, 6); + } else { + memcpy(buff, info.bssid, 6); + } + return buff; + } + if(!err) { + memcpy(bssid, info.bssid, 6); + return reinterpret_cast(bssid); + } + return NULL; +} + +String STAClass::BSSIDstr(){ + uint8_t* bssid = BSSID(); + if(!bssid){ + return String(); + } + char mac[18] = { 0 }; + sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); + return String(mac); +} + +int8_t STAClass::RSSI(){ + if(!started()){ + return 0; + } + wifi_ap_record_t info; + if(!esp_wifi_sta_get_ap_info(&info)) { + return info.rssi; + } + return 0; +} + +size_t STAClass::printDriverInfo(Print & out) const { + size_t bytes = 0; + wifi_ap_record_t info; + if(!started()){ + return bytes; + } + if(esp_wifi_sta_get_ap_info(&info) != ESP_OK){ + return bytes; + } + bytes += out.print(","); + bytes += out.print((const char*)info.ssid); + bytes += out.print(",CH:"); + bytes += out.print(info.primary); + bytes += out.print(",RSSI:"); + bytes += out.print(info.rssi); + bytes += out.print(","); + if(info.phy_11ax){ + bytes += out.print("AX"); + } else if(info.phy_11n){ + bytes += out.print("N"); + } else if(info.phy_11g){ + bytes += out.print("G"); + } else if(info.phy_11b){ + bytes += out.print("B"); + } + if(info.phy_lr){ + bytes += out.print(","); + bytes += out.print("LR"); + } + + if(info.authmode == WIFI_AUTH_OPEN){ bytes += out.print(",OPEN"); } + else if(info.authmode == WIFI_AUTH_WEP){ bytes += out.print(",WEP"); } + else if(info.authmode == WIFI_AUTH_WPA_PSK){ bytes += out.print(",WPA_PSK"); } + else if(info.authmode == WIFI_AUTH_WPA2_PSK){ bytes += out.print(",WPA2_PSK"); } + else if(info.authmode == WIFI_AUTH_WPA_WPA2_PSK){ bytes += out.print(",WPA_WPA2_PSK"); } + else if(info.authmode == WIFI_AUTH_ENTERPRISE){ bytes += out.print(",EAP"); } + else if(info.authmode == WIFI_AUTH_WPA3_PSK){ bytes += out.print(",WPA3_PSK"); } + else if(info.authmode == WIFI_AUTH_WPA2_WPA3_PSK){ bytes += out.print(",WPA2_WPA3_PSK"); } + else if(info.authmode == WIFI_AUTH_WAPI_PSK){ bytes += out.print(",WAPI_PSK"); } + else if(info.authmode == WIFI_AUTH_OWE){ bytes += out.print(",OWE"); } + else if(info.authmode == WIFI_AUTH_WPA3_ENT_192){ bytes += out.print(",WPA3_ENT_SUITE_B_192_BIT"); } + + return bytes; +} + +/** + * @brief Convert wifi_err_reason_t to a string. + * @param [in] reason The reason to be converted. + * @return A string representation of the error code. + * @note: wifi_err_reason_t values as of Mar 2023 (arduino-esp32 r2.0.7) are: (1-39, 46-51, 67-68, 200-208) and are defined in /tools/sdk/esp32/include/esp_wifi/include/esp_wifi_types.h. + */ +const char * STAClass::disconnectReasonName(wifi_err_reason_t reason) { + switch(reason) { + //ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2,0,7) + case WIFI_REASON_UNSPECIFIED: return "UNSPECIFIED"; + case WIFI_REASON_AUTH_EXPIRE: return "AUTH_EXPIRE"; + case WIFI_REASON_AUTH_LEAVE: return "AUTH_LEAVE"; + case WIFI_REASON_ASSOC_EXPIRE: return "ASSOC_EXPIRE"; + case WIFI_REASON_ASSOC_TOOMANY: return "ASSOC_TOOMANY"; + case WIFI_REASON_NOT_AUTHED: return "NOT_AUTHED"; + case WIFI_REASON_NOT_ASSOCED: return "NOT_ASSOCED"; + case WIFI_REASON_ASSOC_LEAVE: return "ASSOC_LEAVE"; + case WIFI_REASON_ASSOC_NOT_AUTHED: return "ASSOC_NOT_AUTHED"; + case WIFI_REASON_DISASSOC_PWRCAP_BAD: return "DISASSOC_PWRCAP_BAD"; + case WIFI_REASON_DISASSOC_SUPCHAN_BAD: return "DISASSOC_SUPCHAN_BAD"; + case WIFI_REASON_BSS_TRANSITION_DISASSOC: return "BSS_TRANSITION_DISASSOC"; + case WIFI_REASON_IE_INVALID: return "IE_INVALID"; + case WIFI_REASON_MIC_FAILURE: return "MIC_FAILURE"; + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: return "4WAY_HANDSHAKE_TIMEOUT"; + case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: return "GROUP_KEY_UPDATE_TIMEOUT"; + case WIFI_REASON_IE_IN_4WAY_DIFFERS: return "IE_IN_4WAY_DIFFERS"; + case WIFI_REASON_GROUP_CIPHER_INVALID: return "GROUP_CIPHER_INVALID"; + case WIFI_REASON_PAIRWISE_CIPHER_INVALID: return "PAIRWISE_CIPHER_INVALID"; + case WIFI_REASON_AKMP_INVALID: return "AKMP_INVALID"; + case WIFI_REASON_UNSUPP_RSN_IE_VERSION: return "UNSUPP_RSN_IE_VERSION"; + case WIFI_REASON_INVALID_RSN_IE_CAP: return "INVALID_RSN_IE_CAP"; + case WIFI_REASON_802_1X_AUTH_FAILED: return "802_1X_AUTH_FAILED"; + case WIFI_REASON_CIPHER_SUITE_REJECTED: return "CIPHER_SUITE_REJECTED"; + case WIFI_REASON_TDLS_PEER_UNREACHABLE: return "TDLS_PEER_UNREACHABLE"; + case WIFI_REASON_TDLS_UNSPECIFIED: return "TDLS_UNSPECIFIED"; + case WIFI_REASON_SSP_REQUESTED_DISASSOC: return "SSP_REQUESTED_DISASSOC"; + case WIFI_REASON_NO_SSP_ROAMING_AGREEMENT: return "NO_SSP_ROAMING_AGREEMENT"; + case WIFI_REASON_BAD_CIPHER_OR_AKM: return "BAD_CIPHER_OR_AKM"; + case WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION: return "NOT_AUTHORIZED_THIS_LOCATION"; + case WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS: return "SERVICE_CHANGE_PERCLUDES_TS"; + case WIFI_REASON_UNSPECIFIED_QOS: return "UNSPECIFIED_QOS"; + case WIFI_REASON_NOT_ENOUGH_BANDWIDTH: return "NOT_ENOUGH_BANDWIDTH"; + case WIFI_REASON_MISSING_ACKS: return "MISSING_ACKS"; + case WIFI_REASON_EXCEEDED_TXOP: return "EXCEEDED_TXOP"; + case WIFI_REASON_STA_LEAVING: return "STA_LEAVING"; + case WIFI_REASON_END_BA: return "END_BA"; + case WIFI_REASON_UNKNOWN_BA: return "UNKNOWN_BA"; + case WIFI_REASON_TIMEOUT: return "TIMEOUT"; + case WIFI_REASON_PEER_INITIATED: return "PEER_INITIATED"; + case WIFI_REASON_AP_INITIATED: return "AP_INITIATED"; + case WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT: return "INVALID_FT_ACTION_FRAME_COUNT"; + case WIFI_REASON_INVALID_PMKID: return "INVALID_PMKID"; + case WIFI_REASON_INVALID_MDE: return "INVALID_MDE"; + case WIFI_REASON_INVALID_FTE: return "INVALID_FTE"; + case WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED: return "TRANSMISSION_LINK_ESTABLISH_FAILED"; + case WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED: return "ALTERATIVE_CHANNEL_OCCUPIED"; + case WIFI_REASON_BEACON_TIMEOUT: return "BEACON_TIMEOUT"; + case WIFI_REASON_NO_AP_FOUND: return "NO_AP_FOUND"; + case WIFI_REASON_AUTH_FAIL: return "AUTH_FAIL"; + case WIFI_REASON_ASSOC_FAIL: return "ASSOC_FAIL"; + case WIFI_REASON_HANDSHAKE_TIMEOUT: return "HANDSHAKE_TIMEOUT"; + case WIFI_REASON_CONNECTION_FAIL: return "CONNECTION_FAIL"; + case WIFI_REASON_AP_TSF_RESET: return "AP_TSF_RESET"; + case WIFI_REASON_ROAMING: return "ROAMING"; + case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: return "ASSOC_COMEBACK_TIME_TOO_LONG"; + default: return ""; + } +} + +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 2191d1b9e23..84dff61b251 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -22,6 +22,7 @@ */ #include "WiFi.h" +#if SOC_WIFI_SUPPORTED extern "C" { #include @@ -99,3 +100,5 @@ bool WiFiClass::isProvEnabled() } WiFiClass WiFi; + +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index 30b9e31f744..a42c1eb2c5a 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -19,8 +19,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef WiFi_h -#define WiFi_h +#pragma once + +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include @@ -62,13 +64,13 @@ class WiFiClass : public WiFiGenericClass, public WiFiSTAClass, public WiFiScanC using WiFiScanClass::channel; public: void printDiag(Print& dest); - friend class WiFiClient; - friend class WiFiServer; - friend class WiFiUDP; + friend class NetworkClient; + friend class NetworkServer; + friend class NetworkUDP; void enableProv(bool status); bool isProvEnabled(); }; extern WiFiClass WiFi; -#endif +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiAP.cpp b/libraries/WiFi/src/WiFiAP.cpp index b02b929bce9..bd75b8b0795 100644 --- a/libraries/WiFi/src/WiFiAP.cpp +++ b/libraries/WiFi/src/WiFiAP.cpp @@ -25,8 +25,8 @@ #include "WiFi.h" #include "WiFiGeneric.h" #include "WiFiAP.h" +#if SOC_WIFI_SUPPORTED -extern "C" { #include #include #include @@ -38,92 +38,6 @@ extern "C" { #include #include #include "dhcpserver/dhcpserver_options.h" -} - - - -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------- Private functions ------------------------------------------------ -// ----------------------------------------------------------------------------------------------------------------------- - -esp_netif_t* get_esp_interface_netif(esp_interface_t interface); -esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=INADDR_NONE, IPAddress gateway=INADDR_NONE, IPAddress subnet=INADDR_NONE, IPAddress dhcp_lease_start=INADDR_NONE); -static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs); - -static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){ - if(!dst || !src || !dst_len){ - return 0; - } - size_t src_len = strlen(src); - if(src_len >= dst_len){ - src_len = dst_len; - } else { - src_len += 1; - } - memcpy(dst, src, src_len); - return src_len; -} - -/** - * compare two AP configurations - * @param lhs softap_config - * @param rhs softap_config - * @return equal - */ -static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs) -{ - if(strncmp(reinterpret_cast(lhs.ap.ssid), reinterpret_cast(rhs.ap.ssid), 32) != 0) { - return false; - } - if(strncmp(reinterpret_cast(lhs.ap.password), reinterpret_cast(rhs.ap.password), 64) != 0) { - return false; - } - if(lhs.ap.channel != rhs.ap.channel) { - return false; - } - if(lhs.ap.authmode != rhs.ap.authmode) { - return false; - } - if(lhs.ap.ssid_hidden != rhs.ap.ssid_hidden) { - return false; - } - if(lhs.ap.max_connection != rhs.ap.max_connection) { - return false; - } - if(lhs.ap.pairwise_cipher != rhs.ap.pairwise_cipher) { - return false; - } - if(lhs.ap.ftm_responder != rhs.ap.ftm_responder) { - return false; - } - return true; -} - -void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, const char * password=NULL, uint8_t channel=6, wifi_auth_mode_t authmode=WIFI_AUTH_WPA2_PSK, uint8_t ssid_hidden=0, uint8_t max_connections=4, bool ftm_responder=false, uint16_t beacon_interval=100){ - wifi_config->ap.channel = channel; - wifi_config->ap.max_connection = max_connections; - wifi_config->ap.beacon_interval = beacon_interval; - wifi_config->ap.ssid_hidden = ssid_hidden; - wifi_config->ap.authmode = WIFI_AUTH_OPEN; - wifi_config->ap.ssid_len = 0; - wifi_config->ap.ssid[0] = 0; - wifi_config->ap.password[0] = 0; - wifi_config->ap.ftm_responder = ftm_responder; - if(ssid != NULL && ssid[0] != 0){ - _wifi_strncpy((char*)wifi_config->ap.ssid, ssid, 32); - wifi_config->ap.ssid_len = strlen(ssid); - if(password != NULL && password[0] != 0){ - wifi_config->ap.authmode = authmode; - wifi_config->ap.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP; // Disable by default enabled insecure TKIP and use just CCMP. - _wifi_strncpy((char*)wifi_config->ap.password, password, 64); - } - } -} - -// ----------------------------------------------------------------------------------------------------------------------- -// ----------------------------------------------------- AP function ----------------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - /** * Set up an access point @@ -135,43 +49,7 @@ void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, cons */ bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection, bool ftm_responder) { - - if(!ssid || *ssid == 0) { - // fail SSID missing - log_e("SSID missing!"); - return false; - } - - if(passphrase && (strlen(passphrase) > 0 && strlen(passphrase) < 8)) { - // fail passphrase too short - log_e("passphrase too short!"); - return false; - } - - // last step after checking the SSID and password - if(!WiFi.enableAP(true)) { - // enable AP failed - log_e("enable AP first!"); - return false; - } - - wifi_config_t conf; - wifi_config_t conf_current; - wifi_softap_config(&conf, ssid, passphrase, channel, WIFI_AUTH_WPA2_PSK, ssid_hidden, max_connection, ftm_responder); - esp_err_t err = esp_wifi_get_config((wifi_interface_t)WIFI_IF_AP, &conf_current); - if(err){ - log_e("get AP config failed"); - return false; - } - if(!softap_config_equal(conf, conf_current)) { - err = esp_wifi_set_config((wifi_interface_t)WIFI_IF_AP, &conf); - if(err){ - log_e("set AP config failed"); - return false; - } - } - - return true; + return AP.begin() && AP.create(ssid, passphrase, channel, ssid_hidden, max_connection, ftm_responder); } /** @@ -180,14 +58,7 @@ bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, */ String WiFiAPClass::softAPSSID() const { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return String(); - } - wifi_config_t info; - if(!esp_wifi_get_config(WIFI_IF_AP, &info)) { - return String(reinterpret_cast(info.ap.ssid)); - } - return String(); + return AP.SSID(); } /** @@ -198,19 +69,9 @@ String WiFiAPClass::softAPSSID() const */ bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start) { - esp_err_t err = ESP_OK; - - if(!WiFi.enableAP(true)) { - // enable AP failed - return false; - } - - err = set_esp_interface_ip(ESP_IF_WIFI_AP, local_ip, gateway, subnet, dhcp_lease_start); - return err == ESP_OK; + return AP.config(local_ip, gateway, subnet, dhcp_lease_start); } - - /** * Disconnect from the network (close AP) * @param wifioff disable mode? @@ -218,41 +79,21 @@ bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress */ bool WiFiAPClass::softAPdisconnect(bool wifioff) { - bool ret; - wifi_config_t conf; - wifi_softap_config(&conf); - - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ + if(!AP.clear()){ return false; } - - ret = esp_wifi_set_config((wifi_interface_t)WIFI_IF_AP, &conf) == ESP_OK; - - if(ret && wifioff) { - ret = WiFi.enableAP(false) == ESP_OK; + if(wifioff) { + return AP.end(); } - - return ret; + return true; } /** * Sets the working bandwidth of the AP mode * @param m wifi_bandwidth_t */ -bool WiFiAPClass::softAPbandwidth(wifi_bandwidth_t bandwidth) { - if(!WiFi.enableAP(true)) { - log_e("AP enable failed!"); - return false; - } - - esp_err_t err; - err = esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_AP, bandwidth); - if(err){ - log_e("Could not set AP bandwidth!"); - return false; - } - - return true; +bool WiFiAPClass::softAPbandwidth(wifi_bandwidth_t bandwidth) { + return AP.bandwidth(bandwidth); } /** @@ -261,14 +102,7 @@ bool WiFiAPClass::softAPbandwidth(wifi_bandwidth_t bandwidth) { */ uint8_t WiFiAPClass::softAPgetStationNum() { - wifi_sta_list_t clients; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return 0; - } - if(esp_wifi_ap_get_sta_list(&clients) == ESP_OK) { - return clients.num; - } - return 0; + return AP.stationCount(); } /** @@ -277,15 +111,7 @@ uint8_t WiFiAPClass::softAPgetStationNum() */ IPAddress WiFiAPClass::softAPIP() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return IPAddress(ip.ip.addr); + return AP.localIP(); } /** @@ -294,15 +120,7 @@ IPAddress WiFiAPClass::softAPIP() */ IPAddress WiFiAPClass::softAPBroadcastIP() { - esp_netif_ip_info_t ip; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); + return AP.broadcastIP(); } /** @@ -311,15 +129,7 @@ IPAddress WiFiAPClass::softAPBroadcastIP() */ IPAddress WiFiAPClass::softAPNetworkID() { - esp_netif_ip_info_t ip; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); + return AP.networkID(); } /** @@ -328,15 +138,7 @@ IPAddress WiFiAPClass::softAPNetworkID() */ IPAddress WiFiAPClass::softAPSubnetMask() { - esp_netif_ip_info_t ip; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return IPAddress(ip.netmask.addr); + return AP.subnetMask(); } /** @@ -345,7 +147,7 @@ IPAddress WiFiAPClass::softAPSubnetMask() */ uint8_t WiFiAPClass::softAPSubnetCIDR() { - return WiFiGenericClass::calculateSubnetCIDR(softAPSubnetMask()); + return AP.subnetCIDR(); } /** @@ -355,10 +157,7 @@ uint8_t WiFiAPClass::softAPSubnetCIDR() */ uint8_t* WiFiAPClass::softAPmacAddress(uint8_t* mac) { - if(WiFiGenericClass::getMode() != WIFI_MODE_NULL){ - esp_wifi_get_mac((wifi_interface_t)WIFI_IF_AP, mac); - } - return mac; + return AP.macAddress(mac); } /** @@ -367,15 +166,7 @@ uint8_t* WiFiAPClass::softAPmacAddress(uint8_t* mac) */ String WiFiAPClass::softAPmacAddress(void) { - uint8_t mac[6]; - char macStr[18] = { 0 }; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return String(); - } - esp_wifi_get_mac((wifi_interface_t)WIFI_IF_AP, mac); - - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); + return AP.macAddress(); } /** @@ -384,14 +175,7 @@ String WiFiAPClass::softAPmacAddress(void) */ const char * WiFiAPClass::softAPgetHostname() { - const char * hostname = NULL; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return hostname; - } - if(esp_netif_get_hostname(get_esp_interface_netif(ESP_IF_WIFI_AP), &hostname) != ESP_OK){ - log_e("Netif Get Hostname Failed!"); - } - return hostname; + return AP.getHostname(); } /** @@ -401,10 +185,7 @@ const char * WiFiAPClass::softAPgetHostname() */ bool WiFiAPClass::softAPsetHostname(const char * hostname) { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return false; - } - return esp_netif_set_hostname(get_esp_interface_netif(ESP_IF_WIFI_AP), hostname) == ESP_OK; + return AP.setHostname(hostname); } /** @@ -413,16 +194,7 @@ bool WiFiAPClass::softAPsetHostname(const char * hostname) */ bool WiFiAPClass::softAPenableIPv6(bool enable) { - if (enable) { - WiFiGenericClass::setStatusBits(AP_WANT_IP6_BIT); - } else { - WiFiGenericClass::clearStatusBits(AP_WANT_IP6_BIT); - } - return true; - // if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - // return false; - // } - // return esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_AP)) == ESP_OK; + return AP.enableIPv6(enable); } /** @@ -430,16 +202,9 @@ bool WiFiAPClass::softAPenableIPv6(bool enable) * @return IPAddress softAP IPv6 */ -IPAddress WiFiAPClass::softAPIPv6() +IPAddress WiFiAPClass::softAPlinkLocalIPv6() { - static esp_ip6_addr_t addr; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(IPv6); - } - - if(esp_netif_get_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA), &addr)){ - return IPAddress(IPv6); - } - return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); + return AP.linkLocalIPv6(); } +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiAP.h b/libraries/WiFi/src/WiFiAP.h index a07fab54335..2cac1d1fe92 100644 --- a/libraries/WiFi/src/WiFiAP.h +++ b/libraries/WiFi/src/WiFiAP.h @@ -20,22 +20,52 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ESP32WIFIAP_H_ -#define ESP32WIFIAP_H_ +#pragma once + +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "WiFiType.h" #include "WiFiGeneric.h" + +// ---------------------------------------------------------------------------------------------- +// ------------------------------------ NEW AP Implementation ---------------------------------- +// ---------------------------------------------------------------------------------------------- + +class APClass: public NetworkInterface { + public: + APClass(); + ~APClass(); + + bool begin(); + bool end(); + + bool create(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false); + bool clear(); + + bool bandwidth(wifi_bandwidth_t bandwidth); + + String SSID(void) const; + uint8_t stationCount(); + + void _onApEvent(int32_t event_id, void* event_data); + + protected: + size_t printDriverInfo(Print & out) const; +}; + +// ---------------------------------------------------------------------------------------------- +// ------------------------------- OLD AP API (compatibility) ---------------------------------- +// ---------------------------------------------------------------------------------------------- + class WiFiAPClass { - // ---------------------------------------------------------------------------------------------- - // ----------------------------------------- AP function ---------------------------------------- - // ---------------------------------------------------------------------------------------------- - public: + APClass AP; bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false); bool softAP(const String& ssid, const String& passphrase = emptyString, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false) { @@ -48,16 +78,16 @@ class WiFiAPClass bool softAPbandwidth(wifi_bandwidth_t bandwidth); uint8_t softAPgetStationNum(); + String softAPSSID(void) const; IPAddress softAPIP(); - IPAddress softAPBroadcastIP(); IPAddress softAPNetworkID(); IPAddress softAPSubnetMask(); uint8_t softAPSubnetCIDR(); bool softAPenableIPv6(bool enable=true); - IPAddress softAPIPv6(); + IPAddress softAPlinkLocalIPv6(); const char * softAPgetHostname(); bool softAPsetHostname(const char * hostname); @@ -65,10 +95,9 @@ class WiFiAPClass uint8_t* softAPmacAddress(uint8_t* mac); String softAPmacAddress(void); - String softAPSSID(void) const; protected: }; -#endif /* ESP32WIFIAP_H_*/ +#endif /* SOC_WIFI_SUPPORTED*/ diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/WiFi/src/WiFiClient.h index 5eee16c8070..30729e27923 100644 --- a/libraries/WiFi/src/WiFiClient.h +++ b/libraries/WiFi/src/WiFiClient.h @@ -1,115 +1,3 @@ -/* - Client.h - Base class that provides Client - Copyright (c) 2011 Adrian McEwen. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _WIFICLIENT_H_ -#define _WIFICLIENT_H_ - - -#include "Arduino.h" -#include "Client.h" -#include - -class WiFiClientSocketHandle; -class WiFiClientRxBuffer; - -class ESPLwIPClient : public Client -{ -public: - virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0; - virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0; - virtual void setConnectionTimeout(uint32_t milliseconds) = 0; -}; - -class WiFiClient : public ESPLwIPClient -{ -protected: - std::shared_ptr clientSocketHandle; - std::shared_ptr _rxBuffer; - bool _connected; - bool _sse; - int _timeout; - int _lastWriteTimeout; - int _lastReadTimeout; - -public: - WiFiClient *next; - WiFiClient(); - WiFiClient(int fd); - ~WiFiClient(); - int connect(IPAddress ip, uint16_t port); - int connect(IPAddress ip, uint16_t port, int32_t timeout_ms); - int connect(const char *host, uint16_t port); - int connect(const char *host, uint16_t port, int32_t timeout_ms); - size_t write(uint8_t data); - size_t write(const uint8_t *buf, size_t size); - size_t write_P(PGM_P buf, size_t size); - size_t write(Stream &stream); - int available(); - int read(); - int read(uint8_t *buf, size_t size); - int peek(); - void flush(); - void stop(); - uint8_t connected(); - void setSSE(bool sse); - bool isSSE(); - - operator bool() - { - return connected(); - } - bool operator==(const bool value) - { - return bool() == value; - } - bool operator!=(const bool value) - { - return bool() != value; - } - bool operator==(const WiFiClient&); - bool operator!=(const WiFiClient& rhs) - { - return !this->operator==(rhs); - }; - - virtual int fd() const; - - int setSocketOption(int option, char* value, size_t len); - int setSocketOption(int level, int option, const void* value, size_t len); - int getSocketOption(int level, int option, const void* value, size_t size); - int setOption(int option, int *value); - int getOption(int option, int *value); - void setConnectionTimeout(uint32_t milliseconds); - int setNoDelay(bool nodelay); - bool getNoDelay(); - - IPAddress remoteIP() const; - IPAddress remoteIP(int fd) const; - uint16_t remotePort() const; - uint16_t remotePort(int fd) const; - IPAddress localIP() const; - IPAddress localIP(int fd) const; - uint16_t localPort() const; - uint16_t localPort(int fd) const; - - //friend class WiFiServer; - using Print::write; -}; - -#endif /* _WIFICLIENT_H_ */ +#pragma once +#include "NetworkClient.h" +#define WiFiClient NetworkClient diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index c827b3c4868..0187e1e7930 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -24,6 +24,7 @@ #include "WiFi.h" #include "WiFiGeneric.h" +#if SOC_WIFI_SUPPORTED extern "C" { #include @@ -52,26 +53,9 @@ extern "C" { #include #include "sdkconfig.h" -#define _byte_swap32(num) (((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000)) ESP_EVENT_DEFINE_BASE(ARDUINO_EVENTS); -/* - * Private (exposable) methods - * */ -static esp_netif_t* esp_netifs[ESP_IF_MAX] = {NULL, NULL, NULL}; -esp_interface_t get_esp_netif_interface(esp_netif_t* esp_netif){ - for(int i=0; i(local_ip); - info.gw.addr = static_cast(gateway); - info.netmask.addr = static_cast(subnet); - - log_v("Configuring %s static IP: " IPSTR ", MASK: " IPSTR ", GW: " IPSTR, - interface == ESP_IF_WIFI_STA ? "Station" : - interface == ESP_IF_WIFI_AP ? "SoftAP" : "Ethernet", - IP2STR(&info.ip), IP2STR(&info.netmask), IP2STR(&info.gw)); - - esp_err_t err = ESP_OK; - if(interface != ESP_IF_WIFI_AP){ - err = esp_netif_dhcpc_get_status(esp_netif, &status); - if(err){ - log_e("DHCPC Get Status Failed! 0x%04x", err); - return err; - } - err = esp_netif_dhcpc_stop(esp_netif); - if(err && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED){ - log_e("DHCPC Stop Failed! 0x%04x", err); - return err; - } - err = esp_netif_set_ip_info(esp_netif, &info); - if(err){ - log_e("Netif Set IP Failed! 0x%04x", err); - return err; - } - if(info.ip.addr == 0){ - err = esp_netif_dhcpc_start(esp_netif); - if(err){ - log_e("DHCPC Start Failed! 0x%04x", err); - return err; - } - } - } else { - err = esp_netif_dhcps_get_status(esp_netif, &status); - if(err){ - log_e("DHCPS Get Status Failed! 0x%04x", err); - return err; - } - err = esp_netif_dhcps_stop(esp_netif); - if(err && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED){ - log_e("DHCPS Stop Failed! 0x%04x", err); - return err; - } - err = esp_netif_set_ip_info(esp_netif, &info); - if(err){ - log_e("Netif Set IP Failed! 0x%04x", err); - return err; - } - - dhcps_lease_t lease; - lease.enable = true; - uint8_t CIDR = WiFiGenericClass::calculateSubnetCIDR(subnet); - log_v("SoftAP: %s | Gateway: %s | DHCP Start: %s | Netmask: %s", local_ip.toString().c_str(), gateway.toString().c_str(), dhcp_lease_start.toString().c_str(), subnet.toString().c_str()); - // netmask must have room for at least 12 IP addresses (AP + GW + 10 DHCP Leasing addresses) - // netmask also must be limited to the last 8 bits of IPv4, otherwise this function won't work - // IDF NETIF checks netmask for the 3rd byte: https://github.com/espressif/esp-idf/blob/master/components/esp_netif/lwip/esp_netif_lwip.c#L1857-L1862 - if (CIDR > 28 || CIDR < 24) { - log_e("Bad netmask. It must be from /24 to /28 (255.255.255. 0<->240)"); - return ESP_FAIL; // ESP_FAIL if initializing failed - } - // The code below is ready for any netmask, not limited to 255.255.255.0 - uint32_t netmask = _byte_swap32(info.netmask.addr); - uint32_t ap_ipaddr = _byte_swap32(info.ip.addr); - uint32_t dhcp_ipaddr = _byte_swap32(static_cast(dhcp_lease_start)); - dhcp_ipaddr = dhcp_ipaddr == 0 ? ap_ipaddr + 1 : dhcp_ipaddr; - uint32_t leaseStartMax = ~netmask - 10; - // there will be 10 addresses for DHCP to lease - lease.start_ip.addr = dhcp_ipaddr; - lease.end_ip.addr = lease.start_ip.addr + 10; - // Check if local_ip is in the same subnet as the dhcp leasing range initial address - if ((ap_ipaddr & netmask) != (dhcp_ipaddr & netmask)) { - log_e("The AP IP address (%s) and the DHCP start address (%s) must be in the same subnet", - local_ip.toString().c_str(), IPAddress(_byte_swap32(dhcp_ipaddr)).toString().c_str()); - return ESP_FAIL; // ESP_FAIL if initializing failed - } - // prevents DHCP lease range to overflow subnet range - if ((dhcp_ipaddr & ~netmask) >= leaseStartMax) { - // make first DHCP lease addr stay in the begining of the netmask range - lease.start_ip.addr = (dhcp_ipaddr & netmask) + 1; - lease.end_ip.addr = lease.start_ip.addr + 10; - log_w("DHCP Lease out of range - Changing DHCP leasing start to %s", IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str()); - } - // Check if local_ip is within DHCP range - if (ap_ipaddr >= lease.start_ip.addr && ap_ipaddr <= lease.end_ip.addr) { - log_e("The AP IP address (%s) can't be within the DHCP range (%s -- %s)", - local_ip.toString().c_str(), IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str(), IPAddress(_byte_swap32(lease.end_ip.addr)).toString().c_str()); - return ESP_FAIL; // ESP_FAIL if initializing failed - } - // Check if gateway is within DHCP range - uint32_t gw_ipaddr = _byte_swap32(info.gw.addr); - bool gw_in_same_subnet = (gw_ipaddr & netmask) == (ap_ipaddr & netmask); - if (gw_in_same_subnet && gw_ipaddr >= lease.start_ip.addr && gw_ipaddr <= lease.end_ip.addr) { - log_e("The GatewayP address (%s) can't be within the DHCP range (%s -- %s)", - gateway.toString().c_str(), IPAddress(_byte_swap32(lease.start_ip.addr)).toString().c_str(), IPAddress(_byte_swap32(lease.end_ip.addr)).toString().c_str()); - return ESP_FAIL; // ESP_FAIL if initializing failed - } - // all done, just revert back byte order of DHCP lease range - lease.start_ip.addr = _byte_swap32(lease.start_ip.addr); - lease.end_ip.addr = _byte_swap32(lease.end_ip.addr); - log_v("DHCP Server Range: %s to %s", IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str()); - // Following block is commented because it breaks AP DHCPS on recent ESP-IDF - // err = esp_netif_dhcps_option( - // esp_netif, - // ESP_NETIF_OP_SET, - // ESP_NETIF_SUBNET_MASK, - // (void*)&info.netmask.addr, sizeof(info.netmask.addr) - // ); - // if(err){ - // log_e("DHCPS Set Netmask Failed! 0x%04x", err); - // return err; - // } - err = esp_netif_dhcps_option( - esp_netif, - ESP_NETIF_OP_SET, - ESP_NETIF_REQUESTED_IP_ADDRESS, - (void*)&lease, sizeof(dhcps_lease_t) - ); - if(err){ - log_e("DHCPS Set Lease Failed! 0x%04x", err); - return err; - } - err = esp_netif_dhcps_start(esp_netif); - if(err){ - log_e("DHCPS Start Failed! 0x%04x", err); - return err; - } - } - return err; -} - -esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns=IPAddress(), IPAddress backup_dns=IPAddress(), IPAddress fallback_dns=IPAddress()){ - esp_netif_t *esp_netif = esp_netifs[interface]; - esp_netif_dns_info_t dns; - dns.ip.type = ESP_IPADDR_TYPE_V4; - dns.ip.u_addr.ip4.addr = static_cast(main_dns); - if(dns.ip.u_addr.ip4.addr && esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_MAIN, &dns) != ESP_OK){ - log_e("Set Main DNS Failed!"); - return ESP_FAIL; - } - if(interface != ESP_IF_WIFI_AP){ - dns.ip.u_addr.ip4.addr = static_cast(backup_dns); - if(dns.ip.u_addr.ip4.addr && esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_BACKUP, &dns) != ESP_OK){ - log_e("Set Backup DNS Failed!"); - return ESP_FAIL; - } - dns.ip.u_addr.ip4.addr = static_cast(fallback_dns); - if(dns.ip.u_addr.ip4.addr && esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_FALLBACK, &dns) != ESP_OK){ - log_e("Set Fallback DNS Failed!"); - return ESP_FAIL; - } - } - return ESP_OK; -} - -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE -static const char * auth_mode_str(int authmode) -{ - switch (authmode) { - case WIFI_AUTH_OPEN: - return ("OPEN"); - break; - case WIFI_AUTH_WEP: - return ("WEP"); - break; - case WIFI_AUTH_WPA_PSK: - return ("WPA_PSK"); - break; - case WIFI_AUTH_WPA2_PSK: - return ("WPA2_PSK"); - break; - case WIFI_AUTH_WPA_WPA2_PSK: - return ("WPA_WPA2_PSK"); - break; - case WIFI_AUTH_WPA2_ENTERPRISE: - return ("WPA2_ENTERPRISE"); - break; - case WIFI_AUTH_WPA3_PSK: - return ("WPA3_PSK"); - break; - case WIFI_AUTH_WPA2_WPA3_PSK: - return ("WPA2_WPA3_PSK"); - break; - case WIFI_AUTH_WAPI_PSK: - return ("WPAPI_PSK"); - break; - default: - break; - } - return ("UNKNOWN"); -} -#endif - -static char default_hostname[32] = {0,}; -static const char * get_esp_netif_hostname(){ - if(default_hostname[0] == 0){ - uint8_t eth_mac[6]; - esp_wifi_get_mac((wifi_interface_t)WIFI_IF_STA, eth_mac); - snprintf(default_hostname, 32, "%s%02X%02X%02X", CONFIG_IDF_TARGET "-", eth_mac[3], eth_mac[4], eth_mac[5]); - } - return (const char *)default_hostname; -} -static void set_esp_netif_hostname(const char * name){ - if(name){ - snprintf(default_hostname, 32, "%s", name); - } -} - -static QueueHandle_t _arduino_event_queue; -static TaskHandle_t _arduino_event_task_handle = NULL; -static EventGroupHandle_t _arduino_event_group = NULL; - -static void _arduino_event_task(void * arg){ - arduino_event_t *data = NULL; - for (;;) { - if(xQueueReceive(_arduino_event_queue, &data, portMAX_DELAY) == pdTRUE){ - WiFiGenericClass::_eventCallback(data); - free(data); - data = NULL; - } - } - vTaskDelete(NULL); - _arduino_event_task_handle = NULL; -} - -esp_err_t postArduinoEvent(arduino_event_t *data) -{ - if(data == NULL){ - return ESP_FAIL; - } - arduino_event_t * event = (arduino_event_t*)malloc(sizeof(arduino_event_t)); - if(event == NULL){ - log_e("Arduino Event Malloc Failed!"); - return ESP_FAIL; - } - memcpy(event, data, sizeof(arduino_event_t)); - if (xQueueSend(_arduino_event_queue, &event, portMAX_DELAY) != pdPASS) { - log_e("Arduino Event Send Failed!"); - return ESP_FAIL; - } - return ESP_OK; -} - static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { arduino_event_t arduino_event; arduino_event.event_id = ARDUINO_EVENT_MAX; - /* - * STA - * */ - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - log_v("STA Started"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_START; - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_STOP) { - log_v("STA Stopped"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_STOP; - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_authmode_change_t * event = (wifi_event_sta_authmode_change_t*)event_data; - log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode)); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE; - memcpy(&arduino_event.event_info.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t)); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_connected_t * event = (wifi_event_sta_connected_t*)event_data; - log_v("STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode)); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_CONNECTED; - memcpy(&arduino_event.event_info.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t)); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_disconnected_t * event = (wifi_event_sta_disconnected_t*)event_data; - log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_DISCONNECTED; - memcpy(&arduino_event.event_info.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t)); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - log_v("STA Got %sIP:" IPSTR, event->ip_changed?"New ":"Same ", IP2STR(&event->ip_info.ip)); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP; - memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t)); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_LOST_IP) { - log_v("STA IP Lost"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP; - /* * SCAN * */ - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE wifi_event_sta_scan_done_t * event = (wifi_event_sta_scan_done_t*)event_data; log_v("SCAN Done: ID: %u, Status: %u, Results: %u", event->scan_id, event->status, event->number); @@ -390,93 +79,6 @@ static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t ev arduino_event.event_id = ARDUINO_EVENT_WIFI_SCAN_DONE; memcpy(&arduino_event.event_info.wifi_scan_done, event_data, sizeof(wifi_event_sta_scan_done_t)); - /* - * AP - * */ - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START) { - log_v("AP Started"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_START; - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STOP) { - log_v("AP Stopped"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STOP; - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_PROBEREQRECVED) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_ap_probe_req_rx_t * event = (wifi_event_ap_probe_req_rx_t*)event_data; - log_v("AP Probe Request: RSSI: %d, MAC: " MACSTR, event->rssi, MAC2STR(event->mac)); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED; - memcpy(&arduino_event.event_info.wifi_ap_probereqrecved, event_data, sizeof(wifi_event_ap_probe_req_rx_t)); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; - log_v("AP Station Connected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STACONNECTED; - memcpy(&arduino_event.event_info.wifi_ap_staconnected, event_data, sizeof(wifi_event_ap_staconnected_t)); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; - log_v("AP Station Disconnected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STADISCONNECTED; - memcpy(&arduino_event.event_info.wifi_ap_stadisconnected, event_data, sizeof(wifi_event_ap_stadisconnected_t)); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_AP_STAIPASSIGNED) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - ip_event_ap_staipassigned_t * event = (ip_event_ap_staipassigned_t*)event_data; - log_v("AP Station IP Assigned:" IPSTR, IP2STR(&event->ip)); - #endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED; - memcpy(&arduino_event.event_info.wifi_ap_staipassigned, event_data, sizeof(ip_event_ap_staipassigned_t)); - - /* - * ETH - * */ - } else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_CONNECTED) { - log_v("Ethernet Link Up"); - arduino_event.event_id = ARDUINO_EVENT_ETH_CONNECTED; - memcpy(&arduino_event.event_info.eth_connected, event_data, sizeof(esp_eth_handle_t)); - } else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_DISCONNECTED) { - log_v("Ethernet Link Down"); - arduino_event.event_id = ARDUINO_EVENT_ETH_DISCONNECTED; - } else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_START) { - log_v("Ethernet Started"); - arduino_event.event_id = ARDUINO_EVENT_ETH_START; - } else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_STOP) { - log_v("Ethernet Stopped"); - arduino_event.event_id = ARDUINO_EVENT_ETH_STOP; - } else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) { - #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - log_v("Ethernet got %sip:" IPSTR, event->ip_changed?"new ":"", IP2STR(&event->ip_info.ip)); - #endif - arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP; - memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t)); - } else if (event_base == ETH_EVENT && event_id == IP_EVENT_ETH_LOST_IP) { - log_v("Ethernet Lost IP"); - arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP; - - /* - * IPv6 - * */ - } else if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) { - ip_event_got_ip6_t * event = (ip_event_got_ip6_t*)event_data; - esp_interface_t iface = get_esp_netif_interface(event->esp_netif); -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - char if_name[NETIF_NAMESIZE] = {0,}; - netif_index_to_name(event->ip6_info.ip.zone, if_name); - esp_ip6_addr_type_t addr_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); - static const char * addr_types[] = { "UNKNOWN", "GLOBAL", "LINK_LOCAL", "SITE_LOCAL", "UNIQUE_LOCAL", "IPV4_MAPPED_IPV6" }; - log_v("IF %s Got IPv6: Interface: %d, IP Index: %d, Type: %s, Zone: %d (%s), Address: " IPV6STR, esp_netif_get_desc(event->esp_netif), iface, event->ip_index, addr_types[addr_type], event->ip6_info.ip.zone, if_name, IPV62STR(event->ip6_info.ip)); -#endif - memcpy(&arduino_event.event_info.got_ip6, event_data, sizeof(ip_event_got_ip6_t)); - if(iface == ESP_IF_WIFI_STA){ - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP6; - } else if(iface == ESP_IF_WIFI_AP){ - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6; - } else if(iface == ESP_IF_ETH){ - arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; - } - /* * WPS * */ @@ -558,63 +160,21 @@ static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t ev } if(arduino_event.event_id < ARDUINO_EVENT_MAX){ - postArduinoEvent(&arduino_event); + Network.postEvent(&arduino_event); } } -static uint32_t _initial_bits = NET_DNS_IDLE_BIT; - -static bool _start_network_event_task(){ - if(!_arduino_event_group){ - _arduino_event_group = xEventGroupCreate(); - if(!_arduino_event_group){ - log_e("Network Event Group Create Failed!"); - return false; - } - xEventGroupSetBits(_arduino_event_group, _initial_bits); - } - if(!_arduino_event_queue){ - _arduino_event_queue = xQueueCreate(32, sizeof(arduino_event_t*)); - if(!_arduino_event_queue){ - log_e("Network Event Queue Create Failed!"); - return false; - } - } - - esp_err_t err = esp_event_loop_create_default(); - if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { - log_e("esp_event_loop_create_default failed!"); - return err; - } - - if(!_arduino_event_task_handle){ - xTaskCreateUniversal(_arduino_event_task, "arduino_events", 4096, NULL, ESP_TASKD_EVENT_PRIO - 1, &_arduino_event_task_handle, ARDUINO_EVENT_RUNNING_CORE); - if(!_arduino_event_task_handle){ - log_e("Network Event Task Start Failed!"); - return false; - } - } - +static bool initWiFiEvents(){ if(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){ log_e("event_handler_instance_register for WIFI_EVENT Failed!"); return false; } - if(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){ - log_e("event_handler_instance_register for IP_EVENT Failed!"); - return false; - } - if(esp_event_handler_instance_register(SC_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){ log_e("event_handler_instance_register for SC_EVENT Failed!"); return false; } - if(esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){ - log_e("event_handler_instance_register for ETH_EVENT Failed!"); - return false; - } - if(esp_event_handler_instance_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){ log_e("event_handler_instance_register for WIFI_PROV_EVENT Failed!"); return false; @@ -623,24 +183,23 @@ static bool _start_network_event_task(){ return true; } -bool tcpipInit(){ - static bool initialized = false; - if(!initialized){ - initialized = true; -#if CONFIG_IDF_TARGET_ESP32 - uint8_t mac[8]; - if(esp_efuse_mac_get_default(mac) == ESP_OK){ - esp_base_mac_addr_set(mac); - } -#endif - initialized = esp_netif_init() == ESP_OK; - if(initialized){ - initialized = _start_network_event_task(); - } else { - log_e("esp_netif_init failed!"); - } +static bool deinitWiFiEvents(){ + if(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb)){ + log_e("esp_event_handler_unregister for WIFI_EVENT Failed!"); + return false; } - return initialized; + + if(esp_event_handler_unregister(SC_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb)){ + log_e("esp_event_handler_unregister for SC_EVENT Failed!"); + return false; + } + + if(esp_event_handler_unregister(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb)){ + log_e("esp_event_handler_unregister for WIFI_PROV_EVENT Failed!"); + return false; + } + + return true; } /* @@ -669,25 +228,19 @@ extern "C" void phy_bbpll_en_usb(bool en); bool wifiLowLevelInit(bool persistent){ if(!lowLevelInitDone){ lowLevelInitDone = true; - if(!tcpipInit()){ + if(!Network.begin()){ lowLevelInitDone = false; return lowLevelInitDone; } - if(esp_netifs[ESP_IF_WIFI_AP] == NULL){ - esp_netifs[ESP_IF_WIFI_AP] = esp_netif_create_default_wifi_ap(); - } - if(esp_netifs[ESP_IF_WIFI_STA] == NULL){ - esp_netifs[ESP_IF_WIFI_STA] = esp_netif_create_default_wifi_sta(); - } wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - if(!WiFiGenericClass::useStaticBuffers()) { - cfg.static_tx_buf_num = 0; + if(!WiFiGenericClass::useStaticBuffers()) { + cfg.static_tx_buf_num = 0; cfg.dynamic_tx_buf_num = 32; - cfg.tx_buf_type = 1; + cfg.tx_buf_type = 1; cfg.cache_tx_buf_num = 4; // can't be zero! - cfg.static_rx_buf_num = 4; + cfg.static_rx_buf_num = 4; cfg.dynamic_rx_buf_num = 32; } @@ -699,15 +252,23 @@ bool wifiLowLevelInit(bool persistent){ } // Temporary fix to ensure that CDC+JTAG stay on on ESP32-C3 #if CONFIG_IDF_TARGET_ESP32C3 - phy_bbpll_en_usb(true); + phy_bbpll_en_usb(true); #endif if(!persistent){ lowLevelInitDone = esp_wifi_set_storage(WIFI_STORAGE_RAM) == ESP_OK; } if(lowLevelInitDone){ + initWiFiEvents(); + if(esp_netifs[ESP_IF_WIFI_AP] == NULL){ + esp_netifs[ESP_IF_WIFI_AP] = esp_netif_create_default_wifi_ap(); + } + if(esp_netifs[ESP_IF_WIFI_STA] == NULL){ + esp_netifs[ESP_IF_WIFI_STA] = esp_netif_create_default_wifi_sta(); + } + arduino_event_t arduino_event; arduino_event.event_id = ARDUINO_EVENT_WIFI_READY; - postArduinoEvent(&arduino_event); + Network.postEvent(&arduino_event); } } return lowLevelInitDone; @@ -715,7 +276,22 @@ bool wifiLowLevelInit(bool persistent){ static bool wifiLowLevelDeinit(){ if(lowLevelInitDone){ + lowLevelInitDone = false; + deinitWiFiEvents(); + if(esp_netifs[ESP_IF_WIFI_AP] != NULL){ + esp_netif_destroy_default_wifi(esp_netifs[ESP_IF_WIFI_AP]); + esp_netifs[ESP_IF_WIFI_AP] = NULL; + } + if(esp_netifs[ESP_IF_WIFI_STA] != NULL){ + esp_netif_destroy_default_wifi(esp_netifs[ESP_IF_WIFI_STA]); + esp_netifs[ESP_IF_WIFI_STA] = NULL; + } lowLevelInitDone = !(esp_wifi_deinit() == ESP_OK); + if(!lowLevelInitDone){ + arduino_event_t arduino_event; + arduino_event.event_id = ARDUINO_EVENT_WIFI_OFF; + Network.postEvent(&arduino_event); + } } return !lowLevelInitDone; } @@ -755,22 +331,6 @@ static bool espWiFiStop(){ // ------------------------------------------------- Generic WiFi function ----------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- -typedef struct WiFiEventCbList { - static wifi_event_id_t current_id; - wifi_event_id_t id; - WiFiEventCb cb; - WiFiEventFuncCb fcb; - WiFiEventSysCb scb; - arduino_event_id_t event; - - WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), event(ARDUINO_EVENT_WIFI_READY) {} -} WiFiEventCbList_t; -wifi_event_id_t WiFiEventCbList::current_id = 1; - - -// arduino dont like std::vectors move static here -static std::vector cbEventList; - bool WiFiGenericClass::_persistent = true; bool WiFiGenericClass::_long_range = false; wifi_mode_t WiFiGenericClass::_forceSleepLastMode = WIFI_MODE_NULL; @@ -784,416 +344,35 @@ WiFiGenericClass::WiFiGenericClass() { } -/** - * @brief Convert wifi_err_reason_t to a string. - * @param [in] reason The reason to be converted. - * @return A string representation of the error code. - * @note: wifi_err_reason_t values as of Mar 2023 (arduino-esp32 r2.0.7) are: (1-39, 46-51, 67-68, 200-208) and are defined in /tools/sdk/esp32/include/esp_wifi/include/esp_wifi_types.h. - */ const char * WiFiGenericClass::disconnectReasonName(wifi_err_reason_t reason) { - switch(reason) { - //ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2,0,7) - case WIFI_REASON_UNSPECIFIED: return "UNSPECIFIED"; - case WIFI_REASON_AUTH_EXPIRE: return "AUTH_EXPIRE"; - case WIFI_REASON_AUTH_LEAVE: return "AUTH_LEAVE"; - case WIFI_REASON_ASSOC_EXPIRE: return "ASSOC_EXPIRE"; - case WIFI_REASON_ASSOC_TOOMANY: return "ASSOC_TOOMANY"; - case WIFI_REASON_NOT_AUTHED: return "NOT_AUTHED"; - case WIFI_REASON_NOT_ASSOCED: return "NOT_ASSOCED"; - case WIFI_REASON_ASSOC_LEAVE: return "ASSOC_LEAVE"; - case WIFI_REASON_ASSOC_NOT_AUTHED: return "ASSOC_NOT_AUTHED"; - case WIFI_REASON_DISASSOC_PWRCAP_BAD: return "DISASSOC_PWRCAP_BAD"; - case WIFI_REASON_DISASSOC_SUPCHAN_BAD: return "DISASSOC_SUPCHAN_BAD"; - case WIFI_REASON_BSS_TRANSITION_DISASSOC: return "BSS_TRANSITION_DISASSOC"; - case WIFI_REASON_IE_INVALID: return "IE_INVALID"; - case WIFI_REASON_MIC_FAILURE: return "MIC_FAILURE"; - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: return "4WAY_HANDSHAKE_TIMEOUT"; - case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: return "GROUP_KEY_UPDATE_TIMEOUT"; - case WIFI_REASON_IE_IN_4WAY_DIFFERS: return "IE_IN_4WAY_DIFFERS"; - case WIFI_REASON_GROUP_CIPHER_INVALID: return "GROUP_CIPHER_INVALID"; - case WIFI_REASON_PAIRWISE_CIPHER_INVALID: return "PAIRWISE_CIPHER_INVALID"; - case WIFI_REASON_AKMP_INVALID: return "AKMP_INVALID"; - case WIFI_REASON_UNSUPP_RSN_IE_VERSION: return "UNSUPP_RSN_IE_VERSION"; - case WIFI_REASON_INVALID_RSN_IE_CAP: return "INVALID_RSN_IE_CAP"; - case WIFI_REASON_802_1X_AUTH_FAILED: return "802_1X_AUTH_FAILED"; - case WIFI_REASON_CIPHER_SUITE_REJECTED: return "CIPHER_SUITE_REJECTED"; - case WIFI_REASON_TDLS_PEER_UNREACHABLE: return "TDLS_PEER_UNREACHABLE"; - case WIFI_REASON_TDLS_UNSPECIFIED: return "TDLS_UNSPECIFIED"; - case WIFI_REASON_SSP_REQUESTED_DISASSOC: return "SSP_REQUESTED_DISASSOC"; - case WIFI_REASON_NO_SSP_ROAMING_AGREEMENT: return "NO_SSP_ROAMING_AGREEMENT"; - case WIFI_REASON_BAD_CIPHER_OR_AKM: return "BAD_CIPHER_OR_AKM"; - case WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION: return "NOT_AUTHORIZED_THIS_LOCATION"; - case WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS: return "SERVICE_CHANGE_PERCLUDES_TS"; - case WIFI_REASON_UNSPECIFIED_QOS: return "UNSPECIFIED_QOS"; - case WIFI_REASON_NOT_ENOUGH_BANDWIDTH: return "NOT_ENOUGH_BANDWIDTH"; - case WIFI_REASON_MISSING_ACKS: return "MISSING_ACKS"; - case WIFI_REASON_EXCEEDED_TXOP: return "EXCEEDED_TXOP"; - case WIFI_REASON_STA_LEAVING: return "STA_LEAVING"; - case WIFI_REASON_END_BA: return "END_BA"; - case WIFI_REASON_UNKNOWN_BA: return "UNKNOWN_BA"; - case WIFI_REASON_TIMEOUT: return "TIMEOUT"; - case WIFI_REASON_PEER_INITIATED: return "PEER_INITIATED"; - case WIFI_REASON_AP_INITIATED: return "AP_INITIATED"; - case WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT: return "INVALID_FT_ACTION_FRAME_COUNT"; - case WIFI_REASON_INVALID_PMKID: return "INVALID_PMKID"; - case WIFI_REASON_INVALID_MDE: return "INVALID_MDE"; - case WIFI_REASON_INVALID_FTE: return "INVALID_FTE"; - case WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED: return "TRANSMISSION_LINK_ESTABLISH_FAILED"; - case WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED: return "ALTERATIVE_CHANNEL_OCCUPIED"; - case WIFI_REASON_BEACON_TIMEOUT: return "BEACON_TIMEOUT"; - case WIFI_REASON_NO_AP_FOUND: return "NO_AP_FOUND"; - case WIFI_REASON_AUTH_FAIL: return "AUTH_FAIL"; - case WIFI_REASON_ASSOC_FAIL: return "ASSOC_FAIL"; - case WIFI_REASON_HANDSHAKE_TIMEOUT: return "HANDSHAKE_TIMEOUT"; - case WIFI_REASON_CONNECTION_FAIL: return "CONNECTION_FAIL"; - case WIFI_REASON_AP_TSF_RESET: return "AP_TSF_RESET"; - case WIFI_REASON_ROAMING: return "ROAMING"; - case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: return "ASSOC_COMEBACK_TIME_TOO_LONG"; - default: return ""; - } + return WiFi.STA.disconnectReasonName(reason); } -/** - * @brief Convert arduino_event_id_t to a C string. - * @param [in] id The event id to be converted. - * @return A string representation of the event id. - * @note: arduino_event_id_t values as of Mar 2023 (arduino-esp32 r2.0.7) are: 0-39 (ARDUINO_EVENT_MAX=40) and are defined in WiFiGeneric.h. - */ const char * WiFiGenericClass::eventName(arduino_event_id_t id) { - switch(id) { - case ARDUINO_EVENT_WIFI_READY: return "WIFI_READY"; - case ARDUINO_EVENT_WIFI_SCAN_DONE: return "SCAN_DONE"; - case ARDUINO_EVENT_WIFI_STA_START: return "STA_START"; - case ARDUINO_EVENT_WIFI_STA_STOP: return "STA_STOP"; - case ARDUINO_EVENT_WIFI_STA_CONNECTED: return "STA_CONNECTED"; - case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: return "STA_DISCONNECTED"; - case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: return "STA_AUTHMODE_CHANGE"; - case ARDUINO_EVENT_WIFI_STA_GOT_IP: return "STA_GOT_IP"; - case ARDUINO_EVENT_WIFI_STA_GOT_IP6: return "STA_GOT_IP6"; - case ARDUINO_EVENT_WIFI_STA_LOST_IP: return "STA_LOST_IP"; - case ARDUINO_EVENT_WIFI_AP_START: return "AP_START"; - case ARDUINO_EVENT_WIFI_AP_STOP: return "AP_STOP"; - case ARDUINO_EVENT_WIFI_AP_STACONNECTED: return "AP_STACONNECTED"; - case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED: return "AP_STADISCONNECTED"; - case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED: return "AP_STAIPASSIGNED"; - case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED: return "AP_PROBEREQRECVED"; - case ARDUINO_EVENT_WIFI_AP_GOT_IP6: return "AP_GOT_IP6"; - case ARDUINO_EVENT_WIFI_FTM_REPORT: return "FTM_REPORT"; - case ARDUINO_EVENT_ETH_START: return "ETH_START"; - case ARDUINO_EVENT_ETH_STOP: return "ETH_STOP"; - case ARDUINO_EVENT_ETH_CONNECTED: return "ETH_CONNECTED"; - case ARDUINO_EVENT_ETH_DISCONNECTED: return "ETH_DISCONNECTED"; - case ARDUINO_EVENT_ETH_GOT_IP: return "ETH_GOT_IP"; - case ARDUINO_EVENT_ETH_LOST_IP: return "ETH_LOST_IP"; - case ARDUINO_EVENT_ETH_GOT_IP6: return "ETH_GOT_IP6"; - case ARDUINO_EVENT_WPS_ER_SUCCESS: return "WPS_ER_SUCCESS"; - case ARDUINO_EVENT_WPS_ER_FAILED: return "WPS_ER_FAILED"; - case ARDUINO_EVENT_WPS_ER_TIMEOUT: return "WPS_ER_TIMEOUT"; - case ARDUINO_EVENT_WPS_ER_PIN: return "WPS_ER_PIN"; - case ARDUINO_EVENT_WPS_ER_PBC_OVERLAP: return "WPS_ER_PBC_OVERLAP"; - case ARDUINO_EVENT_SC_SCAN_DONE: return "SC_SCAN_DONE"; - case ARDUINO_EVENT_SC_FOUND_CHANNEL: return "SC_FOUND_CHANNEL"; - case ARDUINO_EVENT_SC_GOT_SSID_PSWD: return "SC_GOT_SSID_PSWD"; - case ARDUINO_EVENT_SC_SEND_ACK_DONE: return "SC_SEND_ACK_DONE"; - case ARDUINO_EVENT_PROV_INIT: return "PROV_INIT"; - case ARDUINO_EVENT_PROV_DEINIT: return "PROV_DEINIT"; - case ARDUINO_EVENT_PROV_START: return "PROV_START"; - case ARDUINO_EVENT_PROV_END: return "PROV_END"; - case ARDUINO_EVENT_PROV_CRED_RECV: return "PROV_CRED_RECV"; - case ARDUINO_EVENT_PROV_CRED_FAIL: return "PROV_CRED_FAIL"; - case ARDUINO_EVENT_PROV_CRED_SUCCESS: return "PROV_CRED_SUCCESS"; - default: return ""; - } + return Network.eventName(id); } const char * WiFiGenericClass::getHostname() { - return get_esp_netif_hostname(); + return NetworkManager::getHostname(); } bool WiFiGenericClass::setHostname(const char * hostname) { - set_esp_netif_hostname(hostname); - return true; -} - -int WiFiGenericClass::setStatusBits(int bits){ - if(!_arduino_event_group){ - _initial_bits |= bits; - return _initial_bits; - } - return xEventGroupSetBits(_arduino_event_group, bits); -} - -int WiFiGenericClass::clearStatusBits(int bits){ - if(!_arduino_event_group){ - _initial_bits &= ~bits; - return _initial_bits; - } - return xEventGroupClearBits(_arduino_event_group, bits); -} - -int WiFiGenericClass::getStatusBits(){ - if(!_arduino_event_group){ - return _initial_bits; - } - return xEventGroupGetBits(_arduino_event_group); -} - -int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){ - if(!_arduino_event_group){ - return 0; - } - return xEventGroupWaitBits( - _arduino_event_group, // The event group being tested. - bits, // The bits within the event group to wait for. - pdFALSE, // BIT_0 and BIT_4 should be cleared before returning. - pdTRUE, // Don't wait for both bits, either bit will do. - timeout_ms / portTICK_PERIOD_MS ) & bits; // Wait a maximum of 100ms for either bit to be set. -} - -/** - * set callback function - * @param cbEvent WiFiEventCb - * @param event optional filter (WIFI_EVENT_MAX is all events) - */ -wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, arduino_event_id_t event) -{ - if(!cbEvent) { - return 0; - } - WiFiEventCbList_t newEventHandler; - newEventHandler.cb = cbEvent; - newEventHandler.fcb = NULL; - newEventHandler.scb = NULL; - newEventHandler.event = event; - cbEventList.push_back(newEventHandler); - return newEventHandler.id; -} - -wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event) -{ - if(!cbEvent) { - return 0; - } - WiFiEventCbList_t newEventHandler; - newEventHandler.cb = NULL; - newEventHandler.fcb = cbEvent; - newEventHandler.scb = NULL; - newEventHandler.event = event; - cbEventList.push_back(newEventHandler); - return newEventHandler.id; -} - -wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event) -{ - if(!cbEvent) { - return 0; - } - WiFiEventCbList_t newEventHandler; - newEventHandler.cb = NULL; - newEventHandler.fcb = NULL; - newEventHandler.scb = cbEvent; - newEventHandler.event = event; - cbEventList.push_back(newEventHandler); - return newEventHandler.id; -} - -/** - * removes a callback form event handler - * @param cbEvent WiFiEventCb - * @param event optional filter (WIFI_EVENT_MAX is all events) - */ -void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, arduino_event_id_t event) -{ - if(!cbEvent) { - return; - } - - for(uint32_t i = 0; i < cbEventList.size(); i++) { - WiFiEventCbList_t entry = cbEventList[i]; - if(entry.cb == cbEvent && entry.event == event) { - cbEventList.erase(cbEventList.begin() + i); - } - } -} - -void WiFiGenericClass::removeEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event) -{ - if(!cbEvent) { - return; - } - - for(uint32_t i = 0; i < cbEventList.size(); i++) { - WiFiEventCbList_t entry = cbEventList[i]; - if(entry.scb == cbEvent && entry.event == event) { - cbEventList.erase(cbEventList.begin() + i); - } - } -} - -void WiFiGenericClass::removeEvent(wifi_event_id_t id) -{ - for(uint32_t i = 0; i < cbEventList.size(); i++) { - WiFiEventCbList_t entry = cbEventList[i]; - if(entry.id == id) { - cbEventList.erase(cbEventList.begin() + i); - } - } + return NetworkManager::setHostname(hostname); } /** * callback for WiFi events * @param arg */ -esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) +void WiFiGenericClass::_eventCallback(arduino_event_t *event) { - static bool first_connect = true; + if(!event) return; //Null would crash this function - if(!event) return ESP_OK; //Null would crash this function - - log_d("Arduino Event: %d - %s", event->event_id, WiFi.eventName(event->event_id)); + // log_d("Arduino Event: %d - %s", event->event_id, WiFi.eventName(event->event_id)); if(event->event_id == ARDUINO_EVENT_WIFI_SCAN_DONE) { WiFiScanClass::_scanDone(); - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_START) { - WiFiSTAClass::_setStatus(WL_DISCONNECTED); - setStatusBits(STA_STARTED_BIT); - if(esp_wifi_set_ps(_sleepEnabled) != ESP_OK){ - log_e("esp_wifi_set_ps failed"); - } - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_STOP) { - WiFiSTAClass::_setStatus(WL_STOPPED); - clearStatusBits(STA_STARTED_BIT | STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT | STA_HAS_IP6_GLOBAL_BIT); - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_CONNECTED) { - if (getStatusBits() & STA_WANT_IP6_BIT){ - esp_err_t err = esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA)); - if(err != ESP_OK){ - log_e("Failed to enable IPv6 Link Local on STA: [%d] %s", err, esp_err_to_name(err)); - } - } - WiFiSTAClass::_setStatus(WL_IDLE_STATUS); - setStatusBits(STA_CONNECTED_BIT); - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) { - uint8_t reason = event->event_info.wifi_sta_disconnected.reason; - // Reason 0 causes crash, use reason 1 (UNSPECIFIED) instead - if(!reason) - reason = WIFI_REASON_UNSPECIFIED; - log_w("Reason: %u - %s", reason, WiFi.disconnectReasonName((wifi_err_reason_t)reason)); - if(reason == WIFI_REASON_NO_AP_FOUND) { - WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL); - } else if((reason == WIFI_REASON_AUTH_FAIL) && !first_connect){ - WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - } else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) { - WiFiSTAClass::_setStatus(WL_CONNECTION_LOST); - } else if(reason == WIFI_REASON_AUTH_EXPIRE) { - - } else { - WiFiSTAClass::_setStatus(WL_DISCONNECTED); - } - clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT | STA_HAS_IP6_GLOBAL_BIT); - - bool DoReconnect = false; - if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! - } - else if(first_connect) { //Retry once for all failure reasons - first_connect = false; - DoReconnect = true; - log_d("WiFi Reconnect Running"); - } - else if(WiFi.getAutoReconnect() && _isReconnectableReason(reason)) { - DoReconnect = true; - log_d("WiFi AutoReconnect Running"); - } - else if(reason == WIFI_REASON_ASSOC_FAIL) { - WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - } - if(DoReconnect) { - WiFi.disconnect(); - WiFi.begin(); - } - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG - uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr); - uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr); - uint8_t * gw = (uint8_t *)&(event->event_info.got_ip.ip_info.gw.addr); - log_d("STA IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u", - ip[0], ip[1], ip[2], ip[3], - mask[0], mask[1], mask[2], mask[3], - gw[0], gw[1], gw[2], gw[3]); -#endif - WiFiSTAClass::_setStatus(WL_CONNECTED); - setStatusBits(STA_HAS_IP_BIT | STA_CONNECTED_BIT); - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_LOST_IP) { - WiFiSTAClass::_setStatus(WL_IDLE_STATUS); - clearStatusBits(STA_HAS_IP_BIT); - - } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_START) { - setStatusBits(AP_STARTED_BIT); - if (getStatusBits() & AP_WANT_IP6_BIT){ - esp_err_t err = esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_AP)); - if(err != ESP_OK){ - log_e("Failed to enable IPv6 Link Local on AP: [%d] %s", err, esp_err_to_name(err)); - } - } - } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_STOP) { - clearStatusBits(AP_STARTED_BIT | AP_HAS_CLIENT_BIT); - } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_STACONNECTED) { - setStatusBits(AP_HAS_CLIENT_BIT); - } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_STADISCONNECTED) { - wifi_sta_list_t clients; - if(esp_wifi_ap_get_sta_list(&clients) != ESP_OK || !clients.num){ - clearStatusBits(AP_HAS_CLIENT_BIT); - } - - } else if(event->event_id == ARDUINO_EVENT_ETH_START) { - setStatusBits(ETH_STARTED_BIT); - } else if(event->event_id == ARDUINO_EVENT_ETH_STOP) { - clearStatusBits(ETH_STARTED_BIT | ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT | ETH_HAS_IP6_GLOBAL_BIT); - } else if(event->event_id == ARDUINO_EVENT_ETH_CONNECTED) { - if (getStatusBits() & ETH_WANT_IP6_BIT){ - esp_err_t err = esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_ETH)); - if(err != ESP_OK){ - log_e("Failed to enable IPv6 Link Local on ETH: [%d] %s", err, esp_err_to_name(err)); - } - } - setStatusBits(ETH_CONNECTED_BIT); - } else if(event->event_id == ARDUINO_EVENT_ETH_DISCONNECTED) { - clearStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT | ETH_HAS_IP6_GLOBAL_BIT); - } else if(event->event_id == ARDUINO_EVENT_ETH_GOT_IP) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG - uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr); - uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr); - uint8_t * gw = (uint8_t *)&(event->event_info.got_ip.ip_info.gw.addr); - log_d("ETH IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u", - ip[0], ip[1], ip[2], ip[3], - mask[0], mask[1], mask[2], mask[3], - gw[0], gw[1], gw[2], gw[3]); -#endif - setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT); - } else if(event->event_id == ARDUINO_EVENT_ETH_LOST_IP) { - clearStatusBits(ETH_HAS_IP_BIT); - - } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP6) { - setStatusBits(STA_CONNECTED_BIT); - esp_ip6_addr_type_t addr_type = esp_netif_ip6_get_addr_type((esp_ip6_addr_t*)&(event->event_info.got_ip6.ip6_info.ip)); - if(addr_type == ESP_IP6_ADDR_IS_GLOBAL){ - setStatusBits(STA_HAS_IP6_GLOBAL_BIT); - } else if(addr_type == ESP_IP6_ADDR_IS_LINK_LOCAL){ - setStatusBits(STA_HAS_IP6_BIT); - } - } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_GOT_IP6) { - esp_ip6_addr_type_t addr_type = esp_netif_ip6_get_addr_type((esp_ip6_addr_t*)&(event->event_info.got_ip6.ip6_info.ip)); - if(addr_type == ESP_IP6_ADDR_IS_LINK_LOCAL){ - setStatusBits(AP_HAS_IP6_BIT); - } - } else if(event->event_id == ARDUINO_EVENT_ETH_GOT_IP6) { - setStatusBits(ETH_CONNECTED_BIT); - esp_ip6_addr_type_t addr_type = esp_netif_ip6_get_addr_type((esp_ip6_addr_t*)&(event->event_info.got_ip6.ip6_info.ip)); - if(addr_type == ESP_IP6_ADDR_IS_GLOBAL){ - setStatusBits(ETH_HAS_IP6_GLOBAL_BIT); - } else if(addr_type == ESP_IP6_ADDR_IS_LINK_LOCAL){ - setStatusBits(ETH_HAS_IP6_BIT); - } } else if(event->event_id == ARDUINO_EVENT_SC_GOT_SSID_PSWD) { WiFi.begin( (const char *)event->event_info.sc_got_ssid_pswd.ssid, @@ -1205,53 +384,6 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) esp_smartconfig_stop(); WiFiSTAClass::_smartConfigDone = true; } - - for(uint32_t i = 0; i < cbEventList.size(); i++) { - WiFiEventCbList_t entry = cbEventList[i]; - if(entry.cb || entry.fcb || entry.scb) { - if(entry.event == (arduino_event_id_t) event->event_id || entry.event == ARDUINO_EVENT_MAX) { - if(entry.cb) { - entry.cb((arduino_event_id_t) event->event_id); - } else if(entry.fcb) { - entry.fcb((arduino_event_id_t) event->event_id, (arduino_event_info_t) event->event_info); - } else { - entry.scb(event); - } - } - } - } - return ESP_OK; -} - -bool WiFiGenericClass::_isReconnectableReason(uint8_t reason) { - switch(reason) { - case WIFI_REASON_UNSPECIFIED: - //Timeouts (retry) - case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: - case WIFI_REASON_802_1X_AUTH_FAILED: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - //Transient error (reconnect) - case WIFI_REASON_AUTH_LEAVE: - case WIFI_REASON_ASSOC_EXPIRE: - case WIFI_REASON_ASSOC_TOOMANY: - case WIFI_REASON_NOT_AUTHED: - case WIFI_REASON_NOT_ASSOCED: - case WIFI_REASON_ASSOC_NOT_AUTHED: - case WIFI_REASON_MIC_FAILURE: - case WIFI_REASON_IE_IN_4WAY_DIFFERS: - case WIFI_REASON_INVALID_PMKID: - case WIFI_REASON_BEACON_TIMEOUT: - case WIFI_REASON_NO_AP_FOUND: - case WIFI_REASON_ASSOC_FAIL: - case WIFI_REASON_CONNECTION_FAIL: - case WIFI_REASON_AP_TSF_RESET: - case WIFI_REASON_ROAMING: - return true; - default: - return false; - } } /** @@ -1334,16 +466,23 @@ bool WiFiGenericClass::mode(wifi_mode_t m) return true; } if(!cm && m){ + // Turn ON WiFi if(!wifiLowLevelInit(_persistent)){ return false; } + Network.onSysEvent(_eventCallback); } else if(cm && !m){ - return espWiFiStop(); + // Turn OFF WiFi + if(!espWiFiStop()){ + return false; + } + Network.removeEvent(_eventCallback); + return true; } esp_err_t err; if(m & WIFI_MODE_STA){ - err = set_esp_interface_hostname(ESP_IF_WIFI_STA, get_esp_netif_hostname()); + err = esp_netif_set_hostname(esp_netifs[ESP_IF_WIFI_STA], NetworkManager::getHostname()); if(err){ log_e("Could not set hostname! %d", err); return false; @@ -1374,12 +513,12 @@ bool WiFiGenericClass::mode(wifi_mode_t m) return false; } - #ifdef BOARD_HAS_DUAL_ANTENNA - if(!setDualAntennaConfig(ANT1, ANT2, WIFI_RX_ANT_AUTO, WIFI_TX_ANT_AUTO)){ - log_e("Dual Antenna Config failed!"); - return false; - } - #endif +#ifdef BOARD_HAS_DUAL_ANTENNA + if(!setDualAntennaConfig(ANT1, ANT2, WIFI_RX_ANT_AUTO, WIFI_TX_ANT_AUTO)){ + log_e("Dual Antenna Config failed!"); + return false; + } +#endif return true; } @@ -1459,7 +598,7 @@ bool WiFiGenericClass::setSleep(wifi_ps_type_t sleepType) { if(sleepType != _sleepEnabled){ _sleepEnabled = sleepType; - if((getMode() & WIFI_MODE_STA) != 0){ + if(WiFi.STA.started()){ if(esp_wifi_set_ps(_sleepEnabled) != ESP_OK){ log_e("esp_wifi_set_ps failed!"); return false; @@ -1485,7 +624,7 @@ wifi_ps_type_t WiFiGenericClass::getSleep() * @return ok */ bool WiFiGenericClass::setTxPower(wifi_power_t power){ - if((getStatusBits() & (STA_STARTED_BIT | AP_STARTED_BIT)) == 0){ + if(!WiFi.STA.started() && !WiFi.AP.started()){ log_w("Neither AP or STA has been started"); return false; } @@ -1494,7 +633,7 @@ bool WiFiGenericClass::setTxPower(wifi_power_t power){ wifi_power_t WiFiGenericClass::getTxPower(){ int8_t power; - if((getStatusBits() & (STA_STARTED_BIT | AP_STARTED_BIT)) == 0){ + if(!WiFi.STA.started() && !WiFi.AP.started()){ log_w("Neither AP or STA has been started"); return WIFI_POWER_19_5dBm; } @@ -1623,103 +762,21 @@ bool WiFiGenericClass::setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2 // ------------------------------------------------ Generic Network function --------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- -typedef struct gethostbynameParameters { - const char *hostname; - ip_addr_t addr; - uint8_t addr_type; - int result; -} gethostbynameParameters_t; - -/** - * DNS callback - * @param name - * @param ipaddr - * @param callback_arg - */ -static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) -{ - gethostbynameParameters_t *parameters = static_cast(callback_arg); - if(ipaddr) { - if(parameters->result == 0){ - memcpy(&(parameters->addr), ipaddr, sizeof(ip_addr_t)); - parameters->result = 1; - } - } else { - parameters->result = -1; - } - xEventGroupSetBits(_arduino_event_group, NET_DNS_DONE_BIT); -} - -/** - * Callback to execute dns_gethostbyname in lwIP's TCP/IP context - * @param param Parameters for dns_gethostbyname call - */ -static esp_err_t wifi_gethostbyname_tcpip_ctx(void *param) -{ - gethostbynameParameters_t *parameters = static_cast(param); - return dns_gethostbyname_addrtype(parameters->hostname, ¶meters->addr, &wifi_dns_found_callback, parameters, parameters->addr_type); -} - -/** - * Resolve the given hostname to an IP address. - * @param aHostname Name to be resolved - * @param aResult IPAddress structure to store the returned IP address - * @return 1 if aIPAddrString was successfully converted to an IP address, - * else error code - */ +/* + * Deprecated Methods +*/ int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, bool preferV6) { - err_t err = ERR_OK; - gethostbynameParameters_t params; - - // This should generally check if we have a global address assigned to one of the interfaces. - // If such address is not assigned, there is no point in trying to get V6 from DNS as we will not be able to reach it. - // That is of course, if 'preferV6' is not set to true - static bool hasGlobalV6 = false; - bool hasGlobalV6Now = (getStatusBits() & NET_HAS_IP6_GLOBAL_BIT) != 0; - if(hasGlobalV6 != hasGlobalV6Now){ - hasGlobalV6 = hasGlobalV6Now; - dns_clear_cache(); - log_d("Clearing DNS cache"); - } - - aResult = static_cast(0); - params.hostname = aHostname; - params.addr_type = (preferV6 || hasGlobalV6)?LWIP_DNS_ADDRTYPE_IPV6_IPV4:LWIP_DNS_ADDRTYPE_IPV4; - params.result = 0; - aResult.to_ip_addr_t(&(params.addr)); - - if (!aResult.fromString(aHostname)) { - waitStatusBits(NET_DNS_IDLE_BIT, 16000); - clearStatusBits(NET_DNS_IDLE_BIT | NET_DNS_DONE_BIT); - - err = esp_netif_tcpip_exec(wifi_gethostbyname_tcpip_ctx, ¶ms); - if (err == ERR_OK) { - aResult.from_ip_addr_t(&(params.addr)); - } else if (err == ERR_INPROGRESS) { - waitStatusBits(NET_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] - clearStatusBits(NET_DNS_DONE_BIT); - if (params.result == 1) { - aResult.from_ip_addr_t(&(params.addr)); - err = ERR_OK; - } - } - setStatusBits(NET_DNS_IDLE_BIT); - } - if (err == ERR_OK) { - return 1; - } - log_e("DNS Failed for '%s' with error '%d' and result '%d'", aHostname, err, params.result); - return err; + return Network.hostByName(aHostname, aResult, preferV6); } IPAddress WiFiGenericClass::calculateNetworkID(IPAddress ip, IPAddress subnet) { - IPAddress networkID; + IPAddress networkID; - for (size_t i = 0; i < 4; i++) - networkID[i] = subnet[i] & ip[i]; + for (size_t i = 0; i < 4; i++) + networkID[i] = subnet[i] & ip[i]; - return networkID; + return networkID; } IPAddress WiFiGenericClass::calculateBroadcast(IPAddress ip, IPAddress subnet) { @@ -1732,26 +789,74 @@ IPAddress WiFiGenericClass::calculateBroadcast(IPAddress ip, IPAddress subnet) { } uint8_t WiFiGenericClass::calculateSubnetCIDR(IPAddress subnetMask) { - uint8_t CIDR = 0; - - for (uint8_t i = 0; i < 4; i++) { - if (subnetMask[i] == 0x80) // 128 - CIDR += 1; - else if (subnetMask[i] == 0xC0) // 192 - CIDR += 2; - else if (subnetMask[i] == 0xE0) // 224 - CIDR += 3; - else if (subnetMask[i] == 0xF0) // 242 - CIDR += 4; - else if (subnetMask[i] == 0xF8) // 248 - CIDR += 5; - else if (subnetMask[i] == 0xFC) // 252 - CIDR += 6; - else if (subnetMask[i] == 0xFE) // 254 - CIDR += 7; - else if (subnetMask[i] == 0xFF) // 255 - CIDR += 8; - } + uint8_t CIDR = 0; + + for (uint8_t i = 0; i < 4; i++) { + if (subnetMask[i] == 0x80) // 128 + CIDR += 1; + else if (subnetMask[i] == 0xC0) // 192 + CIDR += 2; + else if (subnetMask[i] == 0xE0) // 224 + CIDR += 3; + else if (subnetMask[i] == 0xF0) // 242 + CIDR += 4; + else if (subnetMask[i] == 0xF8) // 248 + CIDR += 5; + else if (subnetMask[i] == 0xFC) // 252 + CIDR += 6; + else if (subnetMask[i] == 0xFE) // 254 + CIDR += 7; + else if (subnetMask[i] == 0xFF) // 255 + CIDR += 8; + } + + return CIDR; +} + +wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, arduino_event_id_t event) +{ + return Network.onEvent(cbEvent, event); +} - return CIDR; +wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event) +{ + return Network.onEvent(cbEvent, event); } + +wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event) +{ + return Network.onEvent(cbEvent, event); +} + +void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, arduino_event_id_t event) +{ + Network.removeEvent(cbEvent, event); +} + +void WiFiGenericClass::removeEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event) +{ + Network.removeEvent(cbEvent, event); +} + +void WiFiGenericClass::removeEvent(wifi_event_id_t id) +{ + Network.removeEvent(id); +} + +int WiFiGenericClass::setStatusBits(int bits){ + return Network.setStatusBits(bits); +} + +int WiFiGenericClass::clearStatusBits(int bits){ + return Network.clearStatusBits(bits); +} + +int WiFiGenericClass::getStatusBits(){ + return Network.getStatusBits(); +} + +int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){ + return Network.waitStatusBits(bits, timeout_ms); +} + +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index d48ee0a9de8..2bb73e6b6fb 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -20,8 +20,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ESP32WIFIGENERIC_H_ -#define ESP32WIFIGENERIC_H_ +#pragma once + +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "esp_err.h" #include "esp_event.h" @@ -34,111 +36,12 @@ #include "wifi_provisioning/manager.h" #include "lwip/ip_addr.h" -ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS); +#include "Network.h" -typedef enum { - ARDUINO_EVENT_WIFI_READY = 0, - ARDUINO_EVENT_WIFI_SCAN_DONE, - ARDUINO_EVENT_WIFI_STA_START, - ARDUINO_EVENT_WIFI_STA_STOP, - ARDUINO_EVENT_WIFI_STA_CONNECTED, - ARDUINO_EVENT_WIFI_STA_DISCONNECTED, - ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE, - ARDUINO_EVENT_WIFI_STA_GOT_IP, - ARDUINO_EVENT_WIFI_STA_GOT_IP6, - ARDUINO_EVENT_WIFI_STA_LOST_IP, - ARDUINO_EVENT_WIFI_AP_START, - ARDUINO_EVENT_WIFI_AP_STOP, - ARDUINO_EVENT_WIFI_AP_STACONNECTED, - ARDUINO_EVENT_WIFI_AP_STADISCONNECTED, - ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED, - ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED, - ARDUINO_EVENT_WIFI_AP_GOT_IP6, - ARDUINO_EVENT_WIFI_FTM_REPORT, - ARDUINO_EVENT_ETH_START, - ARDUINO_EVENT_ETH_STOP, - ARDUINO_EVENT_ETH_CONNECTED, - ARDUINO_EVENT_ETH_DISCONNECTED, - ARDUINO_EVENT_ETH_GOT_IP, - ARDUINO_EVENT_ETH_LOST_IP, - ARDUINO_EVENT_ETH_GOT_IP6, - ARDUINO_EVENT_WPS_ER_SUCCESS, - ARDUINO_EVENT_WPS_ER_FAILED, - ARDUINO_EVENT_WPS_ER_TIMEOUT, - ARDUINO_EVENT_WPS_ER_PIN, - ARDUINO_EVENT_WPS_ER_PBC_OVERLAP, - ARDUINO_EVENT_SC_SCAN_DONE, - ARDUINO_EVENT_SC_FOUND_CHANNEL, - ARDUINO_EVENT_SC_GOT_SSID_PSWD, - ARDUINO_EVENT_SC_SEND_ACK_DONE, - ARDUINO_EVENT_PROV_INIT, - ARDUINO_EVENT_PROV_DEINIT, - ARDUINO_EVENT_PROV_START, - ARDUINO_EVENT_PROV_END, - ARDUINO_EVENT_PROV_CRED_RECV, - ARDUINO_EVENT_PROV_CRED_FAIL, - ARDUINO_EVENT_PROV_CRED_SUCCESS, - ARDUINO_EVENT_MAX -} arduino_event_id_t; - -typedef union { - wifi_event_sta_scan_done_t wifi_scan_done; - wifi_event_sta_authmode_change_t wifi_sta_authmode_change; - wifi_event_sta_connected_t wifi_sta_connected; - wifi_event_sta_disconnected_t wifi_sta_disconnected; - wifi_event_sta_wps_er_pin_t wps_er_pin; - wifi_event_sta_wps_fail_reason_t wps_fail_reason; - wifi_event_ap_probe_req_rx_t wifi_ap_probereqrecved; - wifi_event_ap_staconnected_t wifi_ap_staconnected; - wifi_event_ap_stadisconnected_t wifi_ap_stadisconnected; - wifi_event_ftm_report_t wifi_ftm_report; - ip_event_ap_staipassigned_t wifi_ap_staipassigned; - ip_event_got_ip_t got_ip; - ip_event_got_ip6_t got_ip6; - smartconfig_event_got_ssid_pswd_t sc_got_ssid_pswd; - esp_eth_handle_t eth_connected; - wifi_sta_config_t prov_cred_recv; - wifi_prov_sta_fail_reason_t prov_fail_reason; -} arduino_event_info_t; - -typedef struct{ - arduino_event_id_t event_id; - arduino_event_info_t event_info; -} arduino_event_t; - -typedef void (*WiFiEventCb)(arduino_event_id_t event); -typedef std::function WiFiEventFuncCb; -typedef void (*WiFiEventSysCb)(arduino_event_t *event); - -typedef size_t wifi_event_id_t; - -// General Flags -static const int NET_DNS_IDLE_BIT = BIT0; -static const int NET_DNS_DONE_BIT = BIT1; -// WiFi Scan Flags -static const int WIFI_SCANNING_BIT = BIT2; -static const int WIFI_SCAN_DONE_BIT = BIT3; -// AP Flags -static const int AP_STARTED_BIT = BIT4; -static const int AP_HAS_IP6_BIT = BIT5; -static const int AP_HAS_CLIENT_BIT = BIT6; -static const int AP_WANT_IP6_BIT = BIT7; -// STA Flags -static const int STA_STARTED_BIT = BIT8; -static const int STA_CONNECTED_BIT = BIT9; -static const int STA_HAS_IP_BIT = BIT10; -static const int STA_HAS_IP6_BIT = BIT11; -static const int STA_HAS_IP6_GLOBAL_BIT = BIT12; -static const int STA_WANT_IP6_BIT = BIT13; -// ETH Flags -static const int ETH_STARTED_BIT = BIT14; -static const int ETH_CONNECTED_BIT = BIT15; -static const int ETH_HAS_IP_BIT = BIT16; -static const int ETH_HAS_IP6_BIT = BIT17; -static const int ETH_HAS_IP6_GLOBAL_BIT = BIT18; -static const int ETH_WANT_IP6_BIT = BIT19; -// Masks -static const int NET_HAS_IP6_GLOBAL_BIT = STA_HAS_IP6_GLOBAL_BIT | ETH_HAS_IP6_GLOBAL_BIT; +#define WiFiEventCb NetworkEventCb +#define WiFiEventFuncCb NetworkEventFuncCb +#define WiFiEventSysCb NetworkEventSysCb +#define wifi_event_id_t network_event_handle_t typedef enum { WIFI_POWER_19_5dBm = 78,// 19.5dBm @@ -205,17 +108,24 @@ class WiFiGenericClass static bool setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2, wifi_rx_ant_t rx_mode, wifi_tx_ant_t tx_mode); - const char * disconnectReasonName(wifi_err_reason_t reason); - const char * eventName(arduino_event_id_t id); static const char * getHostname(); static bool setHostname(const char * hostname); static bool hostname(const String& aHostname) { return setHostname(aHostname.c_str()); } - static esp_err_t _eventCallback(arduino_event_t *event); - static void useStaticBuffers(bool bufferMode); static bool useStaticBuffers(); + static int hostByName(const char *aHostname, IPAddress &aResult, bool preferV6=false); + + static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet); + static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet); + static uint8_t calculateSubnetCIDR(IPAddress subnetMask); + + const char * disconnectReasonName(wifi_err_reason_t reason); + const char * eventName(arduino_event_id_t id); + + static void _eventCallback(arduino_event_t *event); + protected: static bool _persistent; static bool _long_range; @@ -226,21 +136,10 @@ class WiFiGenericClass static int setStatusBits(int bits); static int clearStatusBits(int bits); - private: - static bool _isReconnectableReason(uint8_t reason); - - public: - static int hostByName(const char *aHostname, IPAddress &aResult, bool preferV6=false); - - static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet); - static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet); - static uint8_t calculateSubnetCIDR(IPAddress subnetMask); - - protected: friend class WiFiSTAClass; friend class WiFiScanClass; friend class WiFiAPClass; friend class ETHClass; }; -#endif /* ESP32WIFIGENERIC_H_ */ +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiMulti.cpp b/libraries/WiFi/src/WiFiMulti.cpp index 60a25be4285..cf1223b2306 100644 --- a/libraries/WiFi/src/WiFiMulti.cpp +++ b/libraries/WiFi/src/WiFiMulti.cpp @@ -24,6 +24,7 @@ */ #include "WiFiMulti.h" +#if SOC_WIFI_SUPPORTED #include #include #include @@ -355,3 +356,5 @@ void WiFiMulti::setAllowOpenAP(bool bAllowOpenAP) { void WiFiMulti::setConnectionTestCallbackFunc(ConnectionTestCB_t cbFunc) { _connectionTestCBFunc = cbFunc; } + +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiMulti.h b/libraries/WiFi/src/WiFiMulti.h index 9dfac2c4204..c380c9ee18d 100644 --- a/libraries/WiFi/src/WiFiMulti.h +++ b/libraries/WiFi/src/WiFiMulti.h @@ -23,8 +23,10 @@ * */ -#ifndef WIFICLIENTMULTI_H_ -#define WIFICLIENTMULTI_H_ +#pragma once + +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "WiFi.h" #include @@ -76,4 +78,4 @@ class WiFiMulti void resetFails(); }; -#endif /* WIFICLIENTMULTI_H_ */ +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index 02e930943c3..aeb1eaa5923 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -25,6 +25,7 @@ #include "WiFi.h" #include "WiFiGeneric.h" #include "WiFiSTA.h" +#if SOC_WIFI_SUPPORTED #include #include @@ -49,97 +50,10 @@ #include "esp_wpa2.h" #endif -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------- Private functions ------------------------------------------------ -// ----------------------------------------------------------------------------------------------------------------------- - -esp_netif_t* get_esp_interface_netif(esp_interface_t interface); -esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns=IPAddress(), IPAddress backup_dns=IPAddress(), IPAddress fallback_dns=IPAddress()); -esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=INADDR_NONE, IPAddress gateway=INADDR_NONE, IPAddress subnet=INADDR_NONE, IPAddress dhcp_lease_start=INADDR_NONE); -static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs); - -static size_t _wifi_strncpy(char * dst, const char * src, size_t dst_len){ - if(!dst || !src || !dst_len){ - return 0; - } - size_t src_len = strlen(src); - if(src_len >= dst_len){ - src_len = dst_len; - } else { - src_len += 1; - } - memcpy(dst, src, src_len); - return src_len; -} - - -/** - * compare two STA configurations - * @param lhs station_config - * @param rhs station_config - * @return equal - */ -static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs) -{ - if(memcmp(&lhs, &rhs, sizeof(wifi_config_t)) != 0) { - return false; - } - return true; -} - -static void wifi_sta_config(wifi_config_t * wifi_config, const char * ssid=NULL, const char * password=NULL, const uint8_t * bssid=NULL, uint8_t channel=0, wifi_auth_mode_t min_security=WIFI_AUTH_WPA2_PSK, wifi_scan_method_t scan_method=WIFI_ALL_CHANNEL_SCAN, wifi_sort_method_t sort_method=WIFI_CONNECT_AP_BY_SIGNAL, uint16_t listen_interval=0, bool pmf_required=false){ - wifi_config->sta.channel = channel; - wifi_config->sta.listen_interval = listen_interval; - wifi_config->sta.scan_method = scan_method;//WIFI_ALL_CHANNEL_SCAN or WIFI_FAST_SCAN - wifi_config->sta.sort_method = sort_method;//WIFI_CONNECT_AP_BY_SIGNAL or WIFI_CONNECT_AP_BY_SECURITY - wifi_config->sta.threshold.rssi = -127; - wifi_config->sta.pmf_cfg.capable = true; - wifi_config->sta.pmf_cfg.required = pmf_required; - wifi_config->sta.bssid_set = 0; - memset(wifi_config->sta.bssid, 0, 6); - wifi_config->sta.threshold.authmode = WIFI_AUTH_OPEN; - wifi_config->sta.ssid[0] = 0; - wifi_config->sta.password[0] = 0; - if(ssid != NULL && ssid[0] != 0){ - _wifi_strncpy((char*)wifi_config->sta.ssid, ssid, 32); - if(password != NULL && password[0] != 0){ - wifi_config->sta.threshold.authmode = min_security; - _wifi_strncpy((char*)wifi_config->sta.password, password, 64); - } - if(bssid != NULL){ - wifi_config->sta.bssid_set = 1; - memcpy(wifi_config->sta.bssid, bssid, 6); - } - } -} - // ----------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------- STA function ----------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- -bool WiFiSTAClass::_autoReconnect = true; -bool WiFiSTAClass::_useStaticIp = false; -wifi_auth_mode_t WiFiSTAClass::_minSecurity = WIFI_AUTH_WPA2_PSK; -wifi_scan_method_t WiFiSTAClass::_scanMethod = WIFI_FAST_SCAN; -wifi_sort_method_t WiFiSTAClass::_sortMethod = WIFI_CONNECT_AP_BY_SIGNAL; - -static wl_status_t _sta_status = WL_STOPPED; -static EventGroupHandle_t _sta_status_group = NULL; - -void WiFiSTAClass::_setStatus(wl_status_t status) -{ - if(!_sta_status_group){ - _sta_status_group = xEventGroupCreate(); - if(!_sta_status_group){ - log_e("STA Status Group Create Failed!"); - _sta_status = status; - return; - } - } - xEventGroupClearBits(_sta_status_group, 0x00FFFFFF); - xEventGroupSetBits(_sta_status_group, status); -} - /** * Return Connection status. * @return one of the value defined in wl_status_t @@ -147,170 +61,33 @@ void WiFiSTAClass::_setStatus(wl_status_t status) */ wl_status_t WiFiSTAClass::status() { - if(!_sta_status_group){ - return _sta_status; - } - return (wl_status_t)xEventGroupClearBits(_sta_status_group, 0); + return STA.status(); } -/** - * Start Wifi connection with a WPA2 Enterprise AP - * if passphrase is set the most secure supported mode will be automatically selected - * @param ssid const char* Pointer to the SSID string. - * @param method wpa2_method_t The authentication method of WPA2 (WPA2_AUTH_TLS, WPA2_AUTH_PEAP, WPA2_AUTH_TTLS) - * @param wpa2_identity const char* Pointer to the entity - * @param wpa2_username const char* Pointer to the username - * @param password const char * Pointer to the password. - * @param ca_pem const char* Pointer to a string with the contents of a .pem file with CA cert - * @param client_crt const char* Pointer to a string with the contents of a .crt file with client cert - * @param client_key const char* Pointer to a string with the contants of a .key file with client key - * @param bssid uint8_t[6] Optional. BSSID / MAC of AP - * @param channel Optional. Channel of AP - * @param connect Optional. call connect - * @return - */ wl_status_t WiFiSTAClass::begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool connect) { - if(!WiFi.enableSTA(true)) { - log_e("STA enable failed!"); + if(!STA.begin()) { return WL_CONNECT_FAILED; } - if(!wpa2_ssid || *wpa2_ssid == 0x00 || strlen(wpa2_ssid) > 32) { - log_e("SSID too long or missing!"); + if(!STA.connect(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, channel, bssid, connect)){ return WL_CONNECT_FAILED; } - if(wpa2_identity && strlen(wpa2_identity) > 64) { - log_e("identity too long!"); - return WL_CONNECT_FAILED; - } - - if(wpa2_username && strlen(wpa2_username) > 64) { - log_e("username too long!"); - return WL_CONNECT_FAILED; - } - - if(wpa2_password && strlen(wpa2_password) > 64) { - log_e("password too long!"); - } - - if(ca_pem) { -#if __has_include ("esp_eap_client.h") - esp_eap_client_set_ca_cert((uint8_t *)ca_pem, strlen(ca_pem)); -#else - esp_wifi_sta_wpa2_ent_set_ca_cert((uint8_t *)ca_pem, strlen(ca_pem)); -#endif - } - - if(client_crt) { -#if __has_include ("esp_eap_client.h") - esp_eap_client_set_certificate_and_key((uint8_t *)client_crt, strlen(client_crt), (uint8_t *)client_key, strlen(client_key), NULL, 0); -#else - esp_wifi_sta_wpa2_ent_set_cert_key((uint8_t *)client_crt, strlen(client_crt), (uint8_t *)client_key, strlen(client_key), NULL, 0); -#endif - } - -#if __has_include ("esp_eap_client.h") - esp_eap_client_set_identity((uint8_t *)wpa2_identity, strlen(wpa2_identity)); -#else - esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)wpa2_identity, strlen(wpa2_identity)); -#endif - if(method == WPA2_AUTH_PEAP || method == WPA2_AUTH_TTLS) { -#if __has_include ("esp_eap_client.h") - esp_eap_client_set_username((uint8_t *)wpa2_username, strlen(wpa2_username)); - esp_eap_client_set_password((uint8_t *)wpa2_password, strlen(wpa2_password)); -#else - esp_wifi_sta_wpa2_ent_set_username((uint8_t *)wpa2_username, strlen(wpa2_username)); - esp_wifi_sta_wpa2_ent_set_password((uint8_t *)wpa2_password, strlen(wpa2_password)); -#endif - } -#if __has_include ("esp_eap_client.h") - esp_wifi_sta_enterprise_enable(); //set config settings to enable function -#else - esp_wifi_sta_wpa2_ent_enable(); //set config settings to enable function -#endif - WiFi.begin(wpa2_ssid); //connect to wifi - - return status(); + return STA.status(); } -/** - * Start Wifi connection - * if passphrase is set the most secure supported mode will be automatically selected - * @param ssid const char* Pointer to the SSID string. - * @param passphrase const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal). - * @param bssid uint8_t[6] Optional. BSSID / MAC of AP - * @param channel Optional. Channel of AP - * @param connect Optional. call connect - * @return - */ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { - - if(!WiFi.enableSTA(true)) { - log_e("STA enable failed!"); + if(!STA.begin()) { return WL_CONNECT_FAILED; } - if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { - log_e("SSID too long or missing!"); + if(!STA.connect(ssid, passphrase, channel, bssid, connect)){ return WL_CONNECT_FAILED; } - if(passphrase && strlen(passphrase) > 64) { - log_e("passphrase too long!"); - return WL_CONNECT_FAILED; - } - - wifi_config_t conf; - memset(&conf, 0, sizeof(wifi_config_t)); - - wifi_sta_config(&conf, ssid, passphrase, bssid, channel, _minSecurity, _scanMethod, _sortMethod); - - wifi_config_t current_conf; - if(esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_STA, ¤t_conf) != ESP_OK){ - log_e("get current config failed!"); - return WL_CONNECT_FAILED; - } - if(!sta_config_equal(current_conf, conf)) { - if(esp_wifi_disconnect()){ - log_e("disconnect failed!"); - return WL_CONNECT_FAILED; - } - - if(esp_wifi_set_config((wifi_interface_t)ESP_IF_WIFI_STA, &conf) != ESP_OK){ - log_e("set config failed!"); - return WL_CONNECT_FAILED; - } - } else if(status() == WL_CONNECTED){ - return WL_CONNECTED; - } else { - if(esp_wifi_set_config((wifi_interface_t)ESP_IF_WIFI_STA, &conf) != ESP_OK){ - log_e("set config failed!"); - return WL_CONNECT_FAILED; - } - } - - if(!_useStaticIp){ - if(set_esp_interface_ip(ESP_IF_WIFI_STA) != ESP_OK) { - return WL_CONNECT_FAILED; - } - } - - if(connect){ - if(esp_wifi_connect() != ESP_OK) { - log_e("connect failed!"); - return WL_CONNECT_FAILED; - } - } - - return status(); -} - -wl_status_t WiFiSTAClass::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) -{ - return begin((const char*) ssid, (const char*) passphrase, channel, bssid, connect); + return STA.status(); } /** @@ -319,32 +96,11 @@ wl_status_t WiFiSTAClass::begin(char* ssid, char *passphrase, int32_t channel, c */ wl_status_t WiFiSTAClass::begin() { - - if(!WiFi.enableSTA(true)) { - log_e("STA enable failed!"); - return WL_CONNECT_FAILED; - } - - wifi_config_t current_conf; - if(esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_STA, ¤t_conf) != ESP_OK || esp_wifi_set_config((wifi_interface_t)ESP_IF_WIFI_STA, ¤t_conf) != ESP_OK) { - log_e("config failed"); + if(!STA.begin(true)) { return WL_CONNECT_FAILED; } - if(!_useStaticIp && set_esp_interface_ip(ESP_IF_WIFI_STA) != ESP_OK) { - log_e("set ip failed!"); - return WL_CONNECT_FAILED; - } - - if(status() != WL_CONNECTED){ - esp_err_t err = esp_wifi_connect(); - if(err){ - log_e("connect failed! 0x%x", err); - return WL_CONNECT_FAILED; - } - } - - return status(); + return STA.status(); } /** @@ -353,12 +109,7 @@ wl_status_t WiFiSTAClass::begin() */ bool WiFiSTAClass::reconnect() { - if(WiFi.getMode() & WIFI_MODE_STA) { - if(esp_wifi_disconnect() == ESP_OK) { - return esp_wifi_connect() == ESP_OK; - } - } - return false; + return STA.reconnect(); } /** @@ -369,26 +120,7 @@ bool WiFiSTAClass::reconnect() */ bool WiFiSTAClass::disconnectAsync(bool wifioff, bool eraseap) { - wifi_config_t conf; - wifi_sta_config(&conf); - - if(WiFi.getMode() & WIFI_MODE_STA){ - if(eraseap){ - if(esp_wifi_set_config((wifi_interface_t)ESP_IF_WIFI_STA, &conf)){ - log_e("clear config failed!"); - } - } - if(esp_wifi_disconnect()){ - log_e("disconnect failed!"); - return false; - } - if(wifioff) { - return WiFi.enableSTA(false); - } - return true; - } - - return false; + return disconnect(wifioff, eraseap, 0); } /** @@ -400,36 +132,31 @@ bool WiFiSTAClass::disconnectAsync(bool wifioff, bool eraseap) */ bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap, unsigned long timeoutLength) { - if (!disconnectAsync(wifioff, eraseap)) { + if (!STA.disconnect(eraseap, timeoutLength)) { return false; } - if (!timeoutLength) { - return true; - } - const unsigned long start = millis(); - while ((WiFiGenericClass::getStatusBits() & STA_CONNECTED_BIT) != 0) { - if((millis() - start) >= timeoutLength){ - return false; - } - delay(2); + if (wifioff) { + return STA.end(); } return true; } /** * @brief Reset WiFi settings in NVS to default values. + * + * This function will reset settings made using the following APIs: + * - esp_wifi_set_bandwidth, + * - esp_wifi_set_protocol, + * - esp_wifi_set_config related + * - esp_wifi_set_mode + * * @return true if erase succeeded * @note: Resets SSID, password, protocol, mode, etc. * These settings are maintained by WiFi driver in IDF. * WiFi driver must be initialized. */ bool WiFiSTAClass::eraseAP(void) { - if(WiFi.getMode()==WIFI_MODE_NULL) { - if(!WiFi.enableSTA(true)) - return false; - } - - return esp_wifi_restore()==ESP_OK; + return STA.erase(); } /** @@ -442,37 +169,7 @@ bool WiFiSTAClass::eraseAP(void) { */ bool WiFiSTAClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) { - esp_err_t err = ESP_OK; - - if(!WiFi.enableSTA(true)) { - return false; - } - err = set_esp_interface_ip(ESP_IF_WIFI_STA, local_ip, gateway, subnet); - if(err == ESP_OK){ - err = set_esp_interface_dns(ESP_IF_WIFI_STA, dns1, dns2); - } - _useStaticIp = err == ESP_OK; - return err == ESP_OK; -} - -/** - * Sets the working bandwidth of the STA mode - * @param m wifi_bandwidth_t - */ -bool WiFiSTAClass::bandwidth(wifi_bandwidth_t bandwidth) { - if(!WiFi.enableSTA(true)) { - log_e("STA enable failed!"); - return false; - } - - esp_err_t err; - err = esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, bandwidth); - if(err){ - log_e("Could not set STA bandwidth!"); - return false; - } - - return true; + return STA.config(local_ip, gateway, subnet, dns1, dns2); } /** @@ -482,10 +179,18 @@ bool WiFiSTAClass::bandwidth(wifi_bandwidth_t bandwidth) { */ bool WiFiSTAClass::setDNS(IPAddress dns1, IPAddress dns2) { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL) + if(!STA.started()){ return false; - esp_err_t err = set_esp_interface_dns(ESP_IF_WIFI_STA, dns1, dns2); - return err == ESP_OK; + } + return STA.dnsIP(0, dns1) && STA.dnsIP(1, dns2); +} + +/** + * Sets the working bandwidth of the STA mode + * @param m wifi_bandwidth_t + */ +bool WiFiSTAClass::bandwidth(wifi_bandwidth_t bandwidth) { + return STA.bandwidth(bandwidth); } /** @@ -494,7 +199,7 @@ bool WiFiSTAClass::setDNS(IPAddress dns1, IPAddress dns2) */ bool WiFiSTAClass::isConnected() { - return (status() == WL_CONNECTED); + return STA.connected(); } /** @@ -504,7 +209,7 @@ bool WiFiSTAClass::isConnected() */ void WiFiSTAClass::setMinSecurity(wifi_auth_mode_t minSecurity) { - _minSecurity = minSecurity; + return STA.setMinSecurity(minSecurity); } /** @@ -515,7 +220,7 @@ void WiFiSTAClass::setMinSecurity(wifi_auth_mode_t minSecurity) */ void WiFiSTAClass::setScanMethod(wifi_scan_method_t scanMethod) { - _scanMethod = scanMethod; + return STA.setScanMethod(scanMethod); } /** @@ -526,30 +231,7 @@ void WiFiSTAClass::setScanMethod(wifi_scan_method_t scanMethod) */ void WiFiSTAClass::setSortMethod(wifi_sort_method_t sortMethod) { - _sortMethod = sortMethod; -} - -/** - * Deprecated. Setting the ESP32 station to connect to the AP (which is recorded) - * automatically or not when powered on. Enable auto-connect by default. - * @deprecated use `setAutoReconnect` - * @param autoConnect bool - * @return if saved - */ -bool WiFiSTAClass::setAutoConnect(bool autoConnect) -{ - return false;//now deprecated -} - -/** - * Deprecated. Checks if ESP32 station mode will connect to AP - * automatically or not when it is powered on. - * @deprecated use `getAutoReconnect` - * @return auto connect - */ -bool WiFiSTAClass::getAutoConnect() -{ - return false;//now deprecated + return STA.setSortMethod(sortMethod); } /** @@ -559,8 +241,7 @@ bool WiFiSTAClass::getAutoConnect() */ bool WiFiSTAClass::setAutoReconnect(bool autoReconnect) { - _autoReconnect = autoReconnect; - return true; + return STA.setAutoReconnect(autoReconnect); } /** * Function used to get the automatic reconnection if the connection is lost. @@ -568,7 +249,7 @@ bool WiFiSTAClass::setAutoReconnect(bool autoReconnect) */ bool WiFiSTAClass::getAutoReconnect() { - return _autoReconnect; + return STA.getAutoReconnect(); } /** @@ -578,15 +259,7 @@ bool WiFiSTAClass::getAutoReconnect() */ uint8_t WiFiSTAClass::waitForConnectResult(unsigned long timeoutLength) { - //1 and 3 have STA enabled - if((WiFiGenericClass::getMode() & WIFI_MODE_STA) == 0) { - return WL_DISCONNECTED; - } - unsigned long start = millis(); - while((!status() || status() >= WL_DISCONNECTED) && (millis() - start) < timeoutLength) { - delay(100); - } - return status(); + return STA.waitForConnectResult(timeoutLength); } /** @@ -595,15 +268,7 @@ uint8_t WiFiSTAClass::waitForConnectResult(unsigned long timeoutLength) */ IPAddress WiFiSTAClass::localIP() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return IPAddress(ip.ip.addr); + return STA.localIP(); } @@ -614,13 +279,7 @@ IPAddress WiFiSTAClass::localIP() */ uint8_t* WiFiSTAClass::macAddress(uint8_t* mac) { - if(WiFiGenericClass::getMode() != WIFI_MODE_NULL){ - esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_STA, mac); - } - else{ - esp_read_mac(mac, ESP_MAC_WIFI_STA); - } - return mac; + return STA.macAddress(mac); } /** @@ -629,16 +288,7 @@ uint8_t* WiFiSTAClass::macAddress(uint8_t* mac) */ String WiFiSTAClass::macAddress(void) { - uint8_t mac[6]; - char macStr[18] = { 0 }; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - esp_read_mac(mac, ESP_MAC_WIFI_STA); - } - else{ - esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_STA, mac); - } - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); + return STA.macAddress(); } /** @@ -647,15 +297,7 @@ String WiFiSTAClass::macAddress(void) */ IPAddress WiFiSTAClass::subnetMask() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return IPAddress(ip.netmask.addr); + return STA.subnetMask(); } /** @@ -664,15 +306,7 @@ IPAddress WiFiSTAClass::subnetMask() */ IPAddress WiFiSTAClass::gatewayIP() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return IPAddress(ip.gw.addr); + return STA.gatewayIP(); } /** @@ -682,11 +316,7 @@ IPAddress WiFiSTAClass::gatewayIP() */ IPAddress WiFiSTAClass::dnsIP(uint8_t dns_no) { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - const ip_addr_t * dns_ip = dns_getserver(dns_no); - return IPAddress(dns_ip->u_addr.ip4.addr); + return STA.dnsIP(dns_no); } /** @@ -695,15 +325,7 @@ IPAddress WiFiSTAClass::dnsIP(uint8_t dns_no) */ IPAddress WiFiSTAClass::broadcastIP() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); + return STA.broadcastIP(); } /** @@ -712,15 +334,7 @@ IPAddress WiFiSTAClass::broadcastIP() */ IPAddress WiFiSTAClass::networkID() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(); - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); + return STA.networkID(); } /** @@ -729,15 +343,7 @@ IPAddress WiFiSTAClass::networkID() */ uint8_t WiFiSTAClass::subnetCIDR() { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return (uint8_t)0; - } - esp_netif_ip_info_t ip; - if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){ - log_e("Netif Get IP Failed!"); - return IPAddress(); - } - return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); + return STA.subnetCIDR(); } /** @@ -746,14 +352,7 @@ uint8_t WiFiSTAClass::subnetCIDR() */ String WiFiSTAClass::SSID() const { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return String(); - } - wifi_ap_record_t info; - if(!esp_wifi_sta_get_ap_info(&info)) { - return String(reinterpret_cast(info.ssid)); - } - return String(); + return STA.SSID(); } /** @@ -762,12 +361,7 @@ String WiFiSTAClass::SSID() const */ String WiFiSTAClass::psk() const { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return String(); - } - wifi_config_t conf; - esp_wifi_get_config((wifi_interface_t)ESP_IF_WIFI_STA, &conf); - return String(reinterpret_cast(conf.sta.password)); + return STA.psk(); } /** @@ -776,25 +370,7 @@ String WiFiSTAClass::psk() const */ uint8_t* WiFiSTAClass::BSSID(uint8_t* buff) { - static uint8_t bssid[6]; - wifi_ap_record_t info; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return NULL; - } - esp_err_t err = esp_wifi_sta_get_ap_info(&info); - if (buff != NULL) { - if(err) { - memset(buff, 0, 6); - } else { - memcpy(buff, info.bssid, 6); - } - return buff; - } - if(!err) { - memcpy(bssid, info.bssid, 6); - return reinterpret_cast(bssid); - } - return NULL; + return STA.BSSID(); } /** @@ -803,13 +379,7 @@ uint8_t* WiFiSTAClass::BSSID(uint8_t* buff) */ String WiFiSTAClass::BSSIDstr(void) { - uint8_t* bssid = BSSID(); - if(!bssid){ - return String(); - } - char mac[18] = { 0 }; - sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - return String(mac); + return STA.BSSIDstr(); } /** @@ -818,14 +388,7 @@ String WiFiSTAClass::BSSIDstr(void) */ int8_t WiFiSTAClass::RSSI(void) { - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return 0; - } - wifi_ap_record_t info; - if(!esp_wifi_sta_get_ap_info(&info)) { - return info.rssi; - } - return 0; + return STA.RSSI(); } /** @@ -836,28 +399,16 @@ int8_t WiFiSTAClass::RSSI(void) */ bool WiFiSTAClass::enableIPv6(bool en) { - if (en) { - WiFiGenericClass::setStatusBits(STA_WANT_IP6_BIT); - } else { - WiFiGenericClass::clearStatusBits(STA_WANT_IP6_BIT); - } - return true; + return STA.enableIPv6(en); } /** * Get the station interface link-local IPv6 address. * @return IPAddress */ -IPAddress WiFiSTAClass::localIPv6() +IPAddress WiFiSTAClass::linkLocalIPv6() { - static esp_ip6_addr_t addr; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(IPv6); - } - if(esp_netif_get_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA), &addr)){ - return IPAddress(IPv6); - } - return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); + return STA.linkLocalIPv6(); } /** @@ -866,14 +417,7 @@ IPAddress WiFiSTAClass::localIPv6() */ IPAddress WiFiSTAClass::globalIPv6() { - static esp_ip6_addr_t addr; - if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ - return IPAddress(IPv6); - } - if(esp_netif_get_ip6_global(get_esp_interface_netif(ESP_IF_WIFI_STA), &addr)){ - return IPAddress(IPv6); - } - return IPAddress(IPv6, (const uint8_t *)addr.addr, addr.zone); + return STA.globalIPv6(); } @@ -941,3 +485,5 @@ bool WiFiSTAClass::smartConfigDone() { return _smartConfigDone; } + +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiSTA.h b/libraries/WiFi/src/WiFiSTA.h index f66a9e3aa0c..a85ef78344a 100644 --- a/libraries/WiFi/src/WiFiSTA.h +++ b/libraries/WiFi/src/WiFiSTA.h @@ -20,9 +20,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ESP32WIFISTA_H_ -#define ESP32WIFISTA_H_ +#pragma once +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "WiFiType.h" #include "WiFiGeneric.h" @@ -36,13 +37,70 @@ typedef enum { WPA2_AUTH_TTLS = 2 } wpa2_auth_method_t; + +// ---------------------------------------------------------------------------------------------- +// ------------------------------------ NEW STA Implementation ---------------------------------- +// ---------------------------------------------------------------------------------------------- + +class STAClass: public NetworkInterface { + public: + STAClass(); + ~STAClass(); + + bool begin(bool tryConnect = false); + bool end(); + + bool bandwidth(wifi_bandwidth_t bandwidth); + + bool connect(); + bool connect(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + bool connect(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); + bool disconnect(bool eraseap = false, unsigned long timeout = 0); + bool reconnect(); + bool erase(); + + uint8_t waitForConnectResult(unsigned long timeoutLength = 60000); + + bool setAutoReconnect(bool autoReconnect); + bool getAutoReconnect(); + + // Next group functions must be called before WiFi.begin() + void setMinSecurity(wifi_auth_mode_t minSecurity);// Default is WIFI_AUTH_WPA2_PSK + void setScanMethod(wifi_scan_method_t scanMethod);// Default is WIFI_FAST_SCAN + void setSortMethod(wifi_sort_method_t sortMethod);// Default is WIFI_CONNECT_AP_BY_SIGNAL + + wl_status_t status(); + + String SSID() const; + String psk() const; + uint8_t * BSSID(uint8_t* bssid = NULL); + String BSSIDstr(); + int8_t RSSI(); + + const char * disconnectReasonName(wifi_err_reason_t reason); + + // Private Use + void _setStatus(wl_status_t status); + void _onStaEvent(int32_t event_id, void* event_data); + + protected: + wifi_auth_mode_t _minSecurity; + wifi_scan_method_t _scanMethod; + wifi_sort_method_t _sortMethod; + bool _autoReconnect; + wl_status_t _status; + + size_t printDriverInfo(Print & out) const; +}; + +// ---------------------------------------------------------------------------------------------- +// ------------------------------- OLD STA API (compatibility) ---------------------------------- +// ---------------------------------------------------------------------------------------------- + class WiFiSTAClass { - // ---------------------------------------------------------------------------------------------- - // ---------------------------------------- STA function ---------------------------------------- - // ---------------------------------------------------------------------------------------------- - public: + STAClass STA; wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); wl_status_t begin(const String& wpa2_ssid, wpa2_auth_method_t method, const String& wpa2_identity = (const char*)NULL, const String& wpa2_username = (const char*)NULL, const String& wpa2_password = (const char*)NULL, const String& ca_pem = (const char*)NULL, const String& client_crt = (const char*)NULL, const String& client_key = (const char*)NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true) { @@ -52,10 +110,10 @@ class WiFiSTAClass wl_status_t begin(const String& ssid, const String& passphrase = (const char*)NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true) { return begin(ssid.c_str(), passphrase.c_str(), channel, bssid, connect); } - wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); wl_status_t begin(); bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + bool setDNS(IPAddress dns1, IPAddress dns2 = (uint32_t)0x00000000); // sets DNS IP for all network interfaces bool bandwidth(wifi_bandwidth_t bandwidth); @@ -67,9 +125,6 @@ class WiFiSTAClass bool isConnected(); - bool setAutoConnect(bool autoConnect); - bool getAutoConnect(); - bool setAutoReconnect(bool autoReconnect); bool getAutoReconnect(); @@ -80,7 +135,16 @@ class WiFiSTAClass void setScanMethod(wifi_scan_method_t scanMethod);// Default is WIFI_FAST_SCAN void setSortMethod(wifi_sort_method_t sortMethod);// Default is WIFI_CONNECT_AP_BY_SIGNAL - // STA network info + // STA WiFi info + wl_status_t status(); + String SSID() const; + String psk() const; + + uint8_t * BSSID(uint8_t* bssid = NULL); + String BSSIDstr(); + + int8_t RSSI(); + IPAddress localIP(); uint8_t * macAddress(uint8_t* mac); @@ -95,38 +159,22 @@ class WiFiSTAClass uint8_t subnetCIDR(); bool enableIPv6(bool en=true); - IPAddress localIPv6(); + IPAddress linkLocalIPv6(); IPAddress globalIPv6(); - // STA WiFi info - static wl_status_t status(); - String SSID() const; - String psk() const; - - uint8_t * BSSID(uint8_t* bssid = NULL); - String BSSIDstr(); - - int8_t RSSI(); - - static void _setStatus(wl_status_t status); - + // ---------------------------------------------------------------------------------------------- + // ---------------------------------------- Smart Config ---------------------------------------- + // ---------------------------------------------------------------------------------------------- protected: - static bool _useStaticIp; - static bool _autoReconnect; - static wifi_auth_mode_t _minSecurity; - static wifi_scan_method_t _scanMethod; - static wifi_sort_method_t _sortMethod; - -public: + static bool _smartConfigStarted; +public: bool beginSmartConfig(smartconfig_type_t type = SC_TYPE_ESPTOUCH, char* crypt_key = NULL); bool stopSmartConfig(); bool smartConfigDone(); static bool _smartConfigDone; -protected: - static bool _smartConfigStarted; }; -#endif /* ESP32WIFISTA_H_ */ +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiScan.cpp b/libraries/WiFi/src/WiFiScan.cpp index e3604c9723f..4ec7e1471e5 100644 --- a/libraries/WiFi/src/WiFiScan.cpp +++ b/libraries/WiFi/src/WiFiScan.cpp @@ -26,6 +26,7 @@ #include "WiFi.h" #include "WiFiGeneric.h" #include "WiFiScan.h" +#if SOC_WIFI_SUPPORTED extern "C" { #include @@ -288,3 +289,4 @@ int32_t WiFiScanClass::channel(uint8_t i) return it->primary; } +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiScan.h b/libraries/WiFi/src/WiFiScan.h index ec3ee155e7e..31a06d310ec 100644 --- a/libraries/WiFi/src/WiFiScan.h +++ b/libraries/WiFi/src/WiFiScan.h @@ -20,8 +20,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef ESP32WIFISCAN_H_ -#define ESP32WIFISCAN_H_ +#pragma once + +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "WiFiType.h" #include "WiFiGeneric.h" @@ -63,4 +65,4 @@ class WiFiScanClass }; -#endif /* ESP32WIFISCAN_H_ */ +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiServer.h b/libraries/WiFi/src/WiFiServer.h index bef9b9b1e3b..39d984486cf 100644 --- a/libraries/WiFi/src/WiFiServer.h +++ b/libraries/WiFi/src/WiFiServer.h @@ -1,62 +1,3 @@ -/* - Server.h - Server class for Raspberry Pi - Copyright (c) 2016 Hristo Gochkov All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef _WIFISERVER_H_ -#define _WIFISERVER_H_ - -#include "Arduino.h" -#include "Server.h" -#include "WiFiClient.h" -#include "IPAddress.h" - -class WiFiServer { - private: - int sockfd; - int _accepted_sockfd = -1; - IPAddress _addr; - uint16_t _port; - uint8_t _max_clients; - bool _listening; - bool _noDelay = false; - - public: - void listenOnLocalhost(){} - - WiFiServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) { - log_v("WiFiServer::WiFiServer(port=%d, ...)", port); - } - WiFiServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(addr),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) { - log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port); - } - ~WiFiServer(){ end();} - WiFiClient available() __attribute__((deprecated("Renamed to accept()."))); - WiFiClient accept(); - void begin(uint16_t port=0); - void begin(uint16_t port, int reuse_enable); - void setNoDelay(bool nodelay); - bool getNoDelay(); - bool hasClient(); - - void end(); - void close(); - void stop(); - operator bool(){return _listening;} - int setTimeout(uint32_t seconds); -}; - -#endif /* _WIFISERVER_H_ */ +#pragma once +#include "NetworkServer.h" +#define WiFiServer NetworkServer diff --git a/libraries/WiFi/src/WiFiType.h b/libraries/WiFi/src/WiFiType.h index 0b273e85fed..d85e457e1ec 100644 --- a/libraries/WiFi/src/WiFiType.h +++ b/libraries/WiFi/src/WiFiType.h @@ -19,9 +19,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#pragma once -#ifndef ESP32WIFITYPE_H_ -#define ESP32WIFITYPE_H_ +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "esp_wifi_types.h" @@ -51,4 +52,4 @@ typedef enum { WL_DISCONNECTED = 6 } wl_status_t; -#endif /* ESP32WIFITYPE_H_ */ +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/libraries/WiFi/src/WiFiUdp.h b/libraries/WiFi/src/WiFiUdp.h index b543d5f9646..b0b11570fa6 100644 --- a/libraries/WiFi/src/WiFiUdp.h +++ b/libraries/WiFi/src/WiFiUdp.h @@ -1,77 +1,3 @@ -/* - * Udp.cpp: Library to send/receive UDP packets. - * - * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) - * 1) UDP does not guarantee the order in which assembled UDP packets are received. This - * might not happen often in practice, but in larger network topologies, a UDP - * packet can be received out of sequence. - * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being - * aware of it. Again, this may not be a concern in practice on small local networks. - * For more information, see http://www.cafeaulait.org/course/week12/35.html - * - * MIT License: - * Copyright (c) 2008 Bjoern Hartmann - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * bjoern@cs.stanford.edu 12/30/2008 - */ - -#ifndef _WIFIUDP_H_ -#define _WIFIUDP_H_ - -#include -#include -#include - -class WiFiUDP : public UDP { -private: - int udp_server; - IPAddress multicast_ip; - IPAddress remote_ip; - uint16_t server_port; - uint16_t remote_port; - char * tx_buffer; - size_t tx_buffer_len; - cbuf * rx_buffer; -public: - WiFiUDP(); - ~WiFiUDP(); - uint8_t begin(IPAddress a, uint16_t p); - uint8_t begin(uint16_t p); - uint8_t beginMulticast(IPAddress a, uint16_t p); - void stop(); - int beginMulticastPacket(); - int beginPacket(); - int beginPacket(IPAddress ip, uint16_t port); - int beginPacket(const char *host, uint16_t port); - int endPacket(); - size_t write(uint8_t); - size_t write(const uint8_t *buffer, size_t size); - int parsePacket(); - int available(); - int read(); - int read(unsigned char* buffer, size_t len); - int read(char* buffer, size_t len); - int peek(); - void flush(); - IPAddress remoteIP(); - uint16_t remotePort(); -}; - -#endif /* _WIFIUDP_H_ */ +#pragma once +#include "NetworkUdp.h" +#define WiFiUDP NetworkUDP diff --git a/libraries/WiFiClientSecure/examples/WiFiClientShowPeerCredentials/.skip.esp32h2 b/libraries/WiFiClientSecure/examples/WiFiClientShowPeerCredentials/.skip.esp32h2 deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/WiFiClientSecure/examples/WiFiClientTrustOnFirstUse/.skip.esp32h2 b/libraries/WiFiClientSecure/examples/WiFiClientTrustOnFirstUse/.skip.esp32h2 deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libraries/WiFiProv/src/WiFiProv.cpp b/libraries/WiFiProv/src/WiFiProv.cpp index 8acb684993b..2b401b41f51 100644 --- a/libraries/WiFiProv/src/WiFiProv.cpp +++ b/libraries/WiFiProv/src/WiFiProv.cpp @@ -17,6 +17,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include #include @@ -191,3 +193,6 @@ void WiFiProvClass :: printQR(const char *name, const char *pop, const char *tr } WiFiProvClass WiFiProv; + +#endif /* SOC_WIFI_SUPPORTED */ + diff --git a/libraries/WiFiProv/src/WiFiProv.h b/libraries/WiFiProv/src/WiFiProv.h index 57342668770..014d636be9e 100644 --- a/libraries/WiFiProv/src/WiFiProv.h +++ b/libraries/WiFiProv/src/WiFiProv.h @@ -17,8 +17,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef WiFiProv_h -#define WiFiProv_h +#pragma once + +#include "soc/soc_caps.h" +#if SOC_WIFI_SUPPORTED #include "WiFi.h" #include "wifi_provisioning/manager.h" @@ -54,4 +56,4 @@ class WiFiProvClass extern WiFiProvClass WiFiProv; -#endif +#endif /* SOC_WIFI_SUPPORTED */ diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index f878062ef70..94bb5c1f75f 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -62,7 +62,7 @@ { "packager": "esp32", "name": "xtensa-esp-elf-gdb", - "version": "12.1_20221002" + "version": "12.1_20231023" }, { "packager": "esp32", @@ -72,7 +72,7 @@ { "packager": "esp32", "name": "riscv32-esp-elf-gdb", - "version": "12.1_20221002" + "version": "12.1_20231023" }, { "packager": "esp32", @@ -353,63 +353,63 @@ }, { "name": "xtensa-esp-elf-gdb", - "version": "12.1_20221002", + "version": "12.1_20231023", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:d056f2435ef05cccadac5d8fcefa3efd8f8c456c3d853f5eba1edb501acfe4f7", - "size": "32006939" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-x86_64-linux-gnu.tar.gz", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-x86_64-linux-gnu.tar.gz", + "checksum": "SHA-256:d0743ec43cd92c35452a9097f7863281de4e72f04120d63cfbcf9d591a373529", + "size": "36942094" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-aarch64-linux-gnu.tar.gz", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-aarch64-linux-gnu.tar.gz", - "checksum": "SHA-256:7fc9674cc4f4c5e7bc94ca05bc5deaaa4c4bbcc972a9caee6fcd6a872c804c02", - "size": "32227425" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-aarch64-linux-gnu.tar.gz", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-aarch64-linux-gnu.tar.gz", + "checksum": "SHA-256:bc1fac0366c6a08e26c45896ca21c8c90efc2cdd431b8ba084e8772e15502d0e", + "size": "37134601" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-arm-linux-gnueabi.tar.gz", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-arm-linux-gnueabi.tar.gz", - "checksum": "SHA-256:68118ff36e9dd2284d92a7a529d0e2a8d20f6426036a0736fa1147935614ece2", - "size": "29960020" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-arm-linux-gnueabi.tar.gz", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-arm-linux-gnueabi.tar.gz", + "checksum": "SHA-256:25efc51d52b71f097ccec763c5c885c8f5026b432fec4b5badd6a5f36fe34d04", + "size": "34579556" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-i586-linux-gnu.tar.gz", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-i586-linux-gnu.tar.gz", - "checksum": "SHA-256:cf6cac8ed70726d390d30713d537754544872715e1b70a8a4a28b5dc616193b9", - "size": "30877187" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-i586-linux-gnu.tar.gz", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-i586-linux-gnu.tar.gz", + "checksum": "SHA-256:e0af0b3b4a6b29a843cd5f47e331a966d9258f7d825b4656c6251490f71b05b2", + "size": "35676578" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-x86_64-apple-darwin14.tar.gz", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-x86_64-apple-darwin14.tar.gz", - "checksum": "SHA-256:417fcf8d1b596b9481603d6987def1d6cfcebdb9739f53940887334a7de855fa", - "size": "45941853" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-x86_64-apple-darwin14.tar.gz", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-x86_64-apple-darwin14.tar.gz", + "checksum": "SHA-256:bd146fd99a52b2d71c7ce0f62b9e18f3423d6cae7b2b2c954046b0dd7a23142f", + "size": "52863941" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-aarch64-apple-darwin21.1.tar.gz", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-aarch64-apple-darwin21.1.tar.gz", - "checksum": "SHA-256:95d6ed2311d6a72bf349e152d096aeeb151f9c5989bfa3120facb1c99e879196", - "size": "27596410" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-aarch64-apple-darwin21.1.tar.gz", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-aarch64-apple-darwin21.1.tar.gz", + "checksum": "SHA-256:5edc76565bf9d2fadf24e443ddf3df7567354f336a65d4af5b2ee805cdfcec24", + "size": "33504923" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-i686-w64-mingw32.zip", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-i686-w64-mingw32.zip", - "checksum": "SHA-256:642b6a135c38ff1d5e54ad2c29469b769f8e1b101dab363d06101b02284bb979", - "size": "27387730" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-i686-w64-mingw32.zip", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-i686-w64-mingw32.zip", + "checksum": "SHA-256:ea4f3ee6b95ad1ad2e07108a21a50037a3e64a420cdeb34b2ba95d612faed898", + "size": "31068749" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-x86_64-w64-mingw32.zip", - "archiveFileName": "xtensa-esp-elf-gdb-12.1_20221002-x86_64-w64-mingw32.zip", - "checksum": "SHA-256:2d958570ff6aa69ed32cbb076cbaf303349a26b3301a7c4628be8d7ad39cf9f1", - "size": "29561472" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/xtensa-esp-elf-gdb-12.1_20231023-x86_64-w64-mingw32.zip", + "archiveFileName": "xtensa-esp-elf-gdb-12.1_20231023-x86_64-w64-mingw32.zip", + "checksum": "SHA-256:13bb97f39173948d1cfb6e651d9b335ea9d52f1fdd0dda1eda3a2d23d8c63644", + "size": "33514906" } ] }, @@ -477,63 +477,63 @@ }, { "name": "riscv32-esp-elf-gdb", - "version": "12.1_20221002", + "version": "12.1_20231023", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:f0cf0821eaac7e8cf2c63b14f2b69d612f4f8c266b29d02d5547b7d7cbbd0e11", - "size": "32035173" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-x86_64-linux-gnu.tar.gz", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-x86_64-linux-gnu.tar.gz", + "checksum": "SHA-256:2c78b806be176b1e449e07ff83429d38dfc39a13f89a127ac1ffa6c1230537a0", + "size": "36630145" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-aarch64-linux-gnu.tar.gz", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-aarch64-linux-gnu.tar.gz", - "checksum": "SHA-256:6812344dfb5c50a81d2fd8354463516f0aa5f582e8ab406cbaeca8722b45fa94", - "size": "32362642" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-aarch64-linux-gnu.tar.gz", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-aarch64-linux-gnu.tar.gz", + "checksum": "SHA-256:33f80117c8777aaff9179e27953e41764c5c46b3c576dc96a37ecc7a368807ec", + "size": "36980143" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-arm-linux-gnueabi.tar.gz", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-arm-linux-gnueabi.tar.gz", - "checksum": "SHA-256:b73042b8e1df5a3fc8008ec3cd000ef579f155d72a66c6ade1d48906d843e738", - "size": "30580290" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-arm-linux-gnueabi.tar.gz", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-arm-linux-gnueabi.tar.gz", + "checksum": "SHA-256:292e6ec0a9381c1480bbadf5caae25e86428b68fb5d030c9be7deda5e7f070e0", + "size": "34950318" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-i586-linux-gnu.tar.gz", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-i586-linux-gnu.tar.gz", - "checksum": "SHA-256:3f07a1b8dc87127a1a6bec6fbace4f8daca44755356f0692e9a5d4c8c4bfd81d", - "size": "31309798" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-i586-linux-gnu.tar.gz", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-i586-linux-gnu.tar.gz", + "checksum": "SHA-256:68a25fbcfc6371ec4dbe503ec92211977eb2006f0c29e67dbce6b93c70c6b7ec", + "size": "35801607" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-x86_64-apple-darwin14.tar.gz", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-x86_64-apple-darwin14.tar.gz", - "checksum": "SHA-256:bb139229f9a4998cab9cfb617d3ecb05b77cbfa9a3a59c54969035f1b4007487", - "size": "46120661" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-x86_64-apple-darwin14.tar.gz", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-x86_64-apple-darwin14.tar.gz", + "checksum": "SHA-256:322c722e6c12225ed8cd97f95a0375105756dc5113d369958ce0858ad1a90257", + "size": "52618688" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-aarch64-apple-darwin21.1.tar.gz", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-aarch64-apple-darwin21.1.tar.gz", - "checksum": "SHA-256:f6513b57f28245497f9c39a201f3f6444d4180e16b39765c629e01036286c0e6", - "size": "27662484" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-aarch64-apple-darwin21.1.tar.gz", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-aarch64-apple-darwin21.1.tar.gz", + "checksum": "SHA-256:c2224b3a8d02451c530cf004c29653292d963a1b4021b4b472b862b6dbe97e0b", + "size": "33149392" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-i686-w64-mingw32.zip", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-i686-w64-mingw32.zip", - "checksum": "SHA-256:8287fa2891e8d032e8283210048d653705791cda31504369418288d3e4753dd6", - "size": "27839143" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-i686-w64-mingw32.zip", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-i686-w64-mingw32.zip", + "checksum": "SHA-256:4b42149a99dd87ee7e6dde25c99bad966c7f964253fa8f771593d7cef69f5602", + "size": "31635103" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-x86_64-w64-mingw32.zip", - "archiveFileName": "riscv32-esp-elf-gdb-12.1_20221002-x86_64-w64-mingw32.zip", - "checksum": "SHA-256:9debae1135df8f5868a9d945468f0480cdaab25f77ead6a55cc85142c4487abd", - "size": "29404989" + "url": "https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20231023/riscv32-esp-elf-gdb-12.1_20231023-x86_64-w64-mingw32.zip", + "archiveFileName": "riscv32-esp-elf-gdb-12.1_20231023-x86_64-w64-mingw32.zip", + "checksum": "SHA-256:728231546ad5006d34463f972658b2a89e52f660a42abab08a29bedd4a8046ad", + "size": "33400816" } ] },