From 0c561bc94d29104b44b396435f38c3a65a642dfa Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 27 Oct 2023 17:10:25 +0300 Subject: [PATCH] Split networking from WiFi (H2 can now use Ethernet) Now all libs have been checked yet. More to do on WiFi side --- CMakeLists.txt | 2 + .../ETH_W5500_Arduino_SPI/.skip.esp32h2 | 0 .../ETH_W5500_Arduino_SPI.ino | 2 +- .../examples/ETH_W5500_IDF_SPI/.skip.esp32h2 | 0 .../ETH_W5500_IDF_SPI/ETH_W5500_IDF_SPI.ino | 2 +- libraries/Ethernet/src/ETH.cpp | 155 +++--- libraries/Ethernet/src/ETH.h | 16 +- .../Networking/src/ESP_Network_Events.cpp | 342 +++++++++++++ libraries/Networking/src/ESP_Network_Events.h | 177 +++++++ .../Networking/src/ESP_Network_Interface.cpp | 218 ++++++++- .../Networking/src/ESP_Network_Interface.h | 31 +- .../Networking/src/ESP_Network_Manager.cpp | 79 +++ .../Networking/src/ESP_Network_Manager.h | 14 + libraries/Networking/src/Networking.h | 9 + .../{WiFi => Networking}/src/WiFiClient.cpp | 4 +- .../{WiFi => Networking}/src/WiFiClient.h | 0 .../{WiFi => Networking}/src/WiFiServer.cpp | 0 .../{WiFi => Networking}/src/WiFiServer.h | 0 .../{WiFi => Networking}/src/WiFiUdp.cpp | 0 libraries/{WiFi => Networking}/src/WiFiUdp.h | 0 libraries/WiFi/src/WiFiGeneric.cpp | 461 ++++-------------- libraries/WiFi/src/WiFiGeneric.h | 97 +--- 22 files changed, 1050 insertions(+), 559 deletions(-) delete mode 100644 libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/.skip.esp32h2 delete mode 100644 libraries/Ethernet/examples/ETH_W5500_IDF_SPI/.skip.esp32h2 create mode 100644 libraries/Networking/src/ESP_Network_Events.cpp create mode 100644 libraries/Networking/src/ESP_Network_Events.h create mode 100644 libraries/Networking/src/ESP_Network_Manager.cpp create mode 100644 libraries/Networking/src/ESP_Network_Manager.h create mode 100644 libraries/Networking/src/Networking.h rename libraries/{WiFi => Networking}/src/WiFiClient.cpp (99%) rename libraries/{WiFi => Networking}/src/WiFiClient.h (100%) rename libraries/{WiFi => Networking}/src/WiFiServer.cpp (100%) rename libraries/{WiFi => Networking}/src/WiFiServer.h (100%) rename libraries/{WiFi => Networking}/src/WiFiUdp.cpp (100%) rename libraries/{WiFi => Networking}/src/WiFiUdp.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index edb127400be..5113e267779 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,8 @@ set(LIBRARY_SRCS libraries/Insights/src/Insights.cpp libraries/NetBIOS/src/NetBIOS.cpp libraries/Networking/src/ESP_Network_Interface.cpp + libraries/Networking/src/ESP_Network_Events.cpp + libraries/Networking/src/ESP_Network_Manager.cpp libraries/Preferences/src/Preferences.cpp libraries/RainMaker/src/RMaker.cpp libraries/RainMaker/src/RMakerNode.cpp diff --git a/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/.skip.esp32h2 b/libraries/Ethernet/examples/ETH_W5500_Arduino_SPI/.skip.esp32h2 deleted file mode 100644 index e69de29bb2d..00000000000 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 0b7e3cf1342..081ec910407 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 @@ -91,7 +91,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_TYPE, ETH_ADDR, ETH_CS, ETH_IRQ, ETH_RST, SPI); diff --git a/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/.skip.esp32h2 b/libraries/Ethernet/examples/ETH_W5500_IDF_SPI/.skip.esp32h2 deleted file mode 100644 index e69de29bb2d..00000000000 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 d68b3e1d162..b5f9709d7ac 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 @@ -89,7 +89,7 @@ void testClient(const char * host, uint16_t port) void setup() { Serial.begin(115200); - WiFi.onEvent(onEvent); + Network.onEvent(onEvent); ETH.begin(ETH_TYPE, ETH_ADDR, ETH_CS, ETH_IRQ, ETH_RST, ETH_SPI_HOST, ETH_SPI_SCK, ETH_SPI_MISO, ETH_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 949d778e12d..a9a83dfecfd 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -39,13 +39,66 @@ #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 */ +// 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); + } + } + } +} + +esp_eth_handle_t ETHClass::handle(){ + return _eth_handle; +} + +bool ETHClass::connected() +{ + return Network.getStatusBits() & ETH_CONNECTED_BIT(_eth_index); +} + +bool ETHClass::started() +{ + return Network.getStatusBits() & ETH_STARTED_BIT(_eth_index); +} + +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; + Network.setStatusBits(ETH_CONNECTED_BIT(_eth_index)); + } else if (event_id == ETHERNET_EVENT_DISCONNECTED) { + log_v("%s Disconnected", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_DISCONNECTED; + Network.clearStatusBits(ETH_CONNECTED_BIT(_eth_index) | ETH_HAS_IP_BIT(_eth_index) | ETH_HAS_IP6_BIT(_eth_index)); + } else if (event_id == ETHERNET_EVENT_START) { + log_v("%s Started", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_START; + Network.setStatusBits(ETH_STARTED_BIT(_eth_index)); + } else if (event_id == ETHERNET_EVENT_STOP) { + log_v("%s Stopped", desc()); + arduino_event.event_id = ARDUINO_EVENT_ETH_STOP; + Network.clearStatusBits(ETH_STARTED_BIT(_eth_index) | ETH_CONNECTED_BIT(_eth_index) | ETH_HAS_IP_BIT(_eth_index) | ETH_HAS_IP6_BIT(_eth_index)); + } + + if(arduino_event.event_id < ARDUINO_EVENT_MAX){ + Network.postEvent(&arduino_event); + } +} ETHClass::ETHClass(uint8_t eth_index) - :_eth_started(false) - ,_eth_handle(NULL) + :_eth_handle(NULL) ,_eth_index(eth_index) ,_phy_type(ETH_PHY_MAX) #if ETH_SPI_SUPPORTS_CUSTOM @@ -71,9 +124,7 @@ ETHClass::~ETHClass() bool ETHClass::ethDetachBus(void * bus_pointer){ ETHClass *bus = (ETHClass *) bus_pointer; - if(bus->_eth_started){ - bus->end(); - } + bus->end(); return true; } @@ -81,12 +132,20 @@ bool ETHClass::ethDetachBus(void * bus_pointer){ bool ETHClass::begin(eth_phy_type_t type, uint8_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; } perimanSetBusDeinit(ESP32_BUS_TYPE_ETHERNET, 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; @@ -193,15 +252,14 @@ bool ETHClass::begin(eth_phy_type_t type, uint8_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((ESP_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, (void *)(this))){ goto err; } if(!perimanSetPinBus(_pin_mcd, ESP32_BUS_TYPE_ETHERNET, (void *)(this))){ goto err; } @@ -337,7 +395,7 @@ bool ETHClass::beginSPI(eth_phy_type_t type, uint8_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; } @@ -404,7 +462,13 @@ bool ETHClass::beginSPI(eth_phy_type_t type, uint8_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); @@ -555,8 +619,8 @@ bool ETHClass::beginSPI(eth_phy_type_t type, uint8_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((ESP_Network_Interface_ID)(ESP_NETIF_ID_ETH+_eth_index)); // Start Ethernet driver state machine ret = esp_eth_start(_eth_handle); @@ -565,8 +629,6 @@ bool ETHClass::beginSPI(eth_phy_type_t type, uint8_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){ @@ -616,8 +678,6 @@ bool ETHClass::begin(eth_phy_type_t type, uint8_t phy_addr, int cs, int irq, int void ETHClass::end(void) { - _eth_started = false; - destroyNetif(); if(_eth_handle != NULL){ @@ -685,16 +745,6 @@ void ETHClass::end(void) } } -bool ETHClass::connected() -{ - return WiFiGenericClass::getStatusBits() & ETH_CONNECTED_BIT; -} - -bool ETHClass::hasIP() -{ - return WiFiGenericClass::getStatusBits() & ETH_HAS_IP_BIT; -} - bool ETHClass::fullDuplex() { if(_eth_handle == NULL){ @@ -735,21 +785,14 @@ uint8_t ETHClass::linkSpeed() return (link_speed == ETH_SPEED_10M)?10:100; } -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::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(); - - out.println(); + out.printf(",ADDR:0x%lX", phyAddr()); } ETHClass ETH; diff --git a/libraries/Ethernet/src/ETH.h b/libraries/Ethernet/src/ETH.h index 78c37b46e41..fa0c752d8d4 100644 --- a/libraries/Ethernet/src/ETH.h +++ b/libraries/Ethernet/src/ETH.h @@ -63,8 +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 "ESP_Network_Interface.h" +// #include "WiFi.h" +#include "Networking.h" #if ETH_SPI_SUPPORTS_CUSTOM #include "SPI.h" @@ -137,7 +137,7 @@ class ETHClass: public ESP_Network_Interface { // Event based getters bool connected(); - bool hasIP(); + bool started(); // ETH Handle APIs bool fullDuplex(); @@ -145,8 +145,7 @@ class ETHClass: public ESP_Network_Interface { bool autoNegotiation(); uint32_t phyAddr(); - // Info APIs - void printInfo(Print & out); + esp_eth_handle_t handle(); #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); @@ -159,11 +158,14 @@ class ETHClass: public ESP_Network_Interface { esp_err_t eth_spi_write(uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len); #endif - void getMac(uint8_t* mac); + // void getMac(uint8_t* mac); + void printDriverInfo(Print & out); 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; uint8_t _eth_index; eth_phy_type_t _phy_type; diff --git a/libraries/Networking/src/ESP_Network_Events.cpp b/libraries/Networking/src/ESP_Network_Events.cpp new file mode 100644 index 00000000000..48f5cc83425 --- /dev/null +++ b/libraries/Networking/src/ESP_Network_Events.cpp @@ -0,0 +1,342 @@ +#include "ESP_Network_Events.h" +#include "ESP_Network_Manager.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 (;;) { + ((ESP_Network_Events*)arg)->checkForEvent(); + } + vTaskDelete(NULL); +} + +ESP_Network_Events::ESP_Network_Events() + : _arduino_event_group(NULL) + , _arduino_event_group_h(NULL) + , _arduino_event_queue(NULL) + , _arduino_event_task_handle(NULL) +{} + +ESP_Network_Events::~ESP_Network_Events(){ + 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_group_h != NULL){ + vEventGroupDelete(_arduino_event_group_h); + _arduino_event_group_h = 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; + } +} + +bool ESP_Network_Events::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, WIFI_DNS_IDLE_BIT); + } + if(!_arduino_event_group_h){ + _arduino_event_group_h = xEventGroupCreate(); + if(!_arduino_event_group_h){ + log_e("Network Event Group 2 Create Failed!"); + return false; + } + } + + 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 ESP_Network_Events::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 ESP_Network_Events::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 ESP_Network_Events::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 ESP_Network_Events::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 ESP_Network_Events::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; +} + +void ESP_Network_Events::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); + } + } +} + +void ESP_Network_Events::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 ESP_Network_Events::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 ESP_Network_Events::setStatusBits(int bits){ + if(!_arduino_event_group){ + return 0; + } + int l=bits & 0x00FFFFFF, h=(bits & 0xFF000000) >> 24; + if(l){ + l = xEventGroupSetBits(_arduino_event_group, l); + } + if(h){ + h = xEventGroupSetBits(_arduino_event_group_h, h); + } + return l | (h << 24); +} + +int ESP_Network_Events::clearStatusBits(int bits){ + if(!_arduino_event_group){ + return 0; + } + int l=bits & 0x00FFFFFF, h=(bits & 0xFF000000) >> 24; + if(l){ + l = xEventGroupClearBits(_arduino_event_group, l); + } + if(h){ + h = xEventGroupClearBits(_arduino_event_group_h, h); + } + return l | (h << 24); +} + +int ESP_Network_Events::getStatusBits(){ + if(!_arduino_event_group){ + return 0; + } + return xEventGroupGetBits(_arduino_event_group) | (xEventGroupGetBits(_arduino_event_group_h) << 24); +} + +int ESP_Network_Events::waitStatusBits(int bits, uint32_t timeout_ms){ + if(!_arduino_event_group){ + return 0; + } + int l=bits & 0x00FFFFFF, h=(bits & 0xFF000000) >> 24; + if(l){ + l = xEventGroupWaitBits( + _arduino_event_group, // The event group being tested. + l, // 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 ) & l; // Wait a maximum of timeout_ms for any bit to be set. + } + if(h){ + h = xEventGroupWaitBits( + _arduino_event_group, // The event group being tested. + h, // 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 ) & h; // Wait a maximum of timeout_ms for any bit to be set. + } + return l | (h << 24); +} + +const char * ESP_Network_Events::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_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/Networking/src/ESP_Network_Events.h b/libraries/Networking/src/ESP_Network_Events.h new file mode 100644 index 00000000000..058e0cb2f10 --- /dev/null +++ b/libraries/Networking/src/ESP_Network_Events.h @@ -0,0 +1,177 @@ +#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 AP_STARTED_BIT = BIT0; +static const int AP_HAS_IP6_BIT = BIT1; +static const int AP_HAS_CLIENT_BIT = BIT2; +static const int STA_STARTED_BIT = BIT3; +static const int STA_CONNECTED_BIT = BIT4; +static const int STA_HAS_IP_BIT = BIT5; +static const int STA_HAS_IP6_BIT = BIT6; +static const int WIFI_SCANNING_BIT = BIT7; +static const int WIFI_SCAN_DONE_BIT= BIT8; +#endif + +static const int WIFI_DNS_IDLE_BIT = BIT9; +static const int WIFI_DNS_DONE_BIT = BIT10; +static const int PPP_STARTED_BIT = BIT11; +static const int PPP_CONNECTED_BIT = BIT12; +static const int PPP_HAS_IP_BIT = BIT13; +static const int PPP_HAS_IP6_BIT = BIT14; +static const int ETH0_STARTED_BIT = BIT15; +static const int ETH1_STARTED_BIT = BIT16; +static const int ETH2_STARTED_BIT = BIT17; +static const int ETH0_CONNECTED_BIT = BIT18; +static const int ETH1_CONNECTED_BIT = BIT19; +static const int ETH2_CONNECTED_BIT = BIT20; +static const int ETH0_HAS_IP_BIT = BIT21; +static const int ETH1_HAS_IP_BIT = BIT22; +static const int ETH2_HAS_IP_BIT = BIT23; +static const int ETH0_HAS_IP6_BIT = BIT24; +static const int ETH1_HAS_IP6_BIT = BIT25; +static const int ETH2_HAS_IP6_BIT = BIT26; + +#define ETH_STARTED_BIT(i) (ETH0_STARTED_BIT << (i)) +#define ETH_CONNECTED_BIT(i) (ETH0_CONNECTED_BIT << (i)) +#define ETH_HAS_IP_BIT(i) (ETH0_HAS_IP_BIT << (i)) +#define ETH_HAS_IP6_BIT(i) (ETH0_HAS_IP6_BIT << (i)) + +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, + 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, +#if SOC_WIFI_SUPPORTED + 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_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 ESP_Network_Events { +public: + ESP_Network_Events(); + ~ESP_Network_Events(); + + 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(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); +protected: + bool initNetworkEvents(); +private: + EventGroupHandle_t _arduino_event_group; + EventGroupHandle_t _arduino_event_group_h; + QueueHandle_t _arduino_event_queue; + TaskHandle_t _arduino_event_task_handle; +}; + + diff --git a/libraries/Networking/src/ESP_Network_Interface.cpp b/libraries/Networking/src/ESP_Network_Interface.cpp index 0118afb9fc8..05e1597c352 100644 --- a/libraries/Networking/src/ESP_Network_Interface.cpp +++ b/libraries/Networking/src/ESP_Network_Interface.cpp @@ -6,9 +6,141 @@ #include "lwip/err.h" #include "esp32-hal-log.h" -ESP_Network_Interface::ESP_Network_Interface():_esp_netif(NULL){} -ESP_Network_Interface::ESP_Network_Interface(ESP_Network_Interface & _if){ _esp_netif = _if.netif(); } -ESP_Network_Interface::~ESP_Network_Interface(){ destroyNetif(); } +static ESP_Network_Interface * _interfaces[ESP_NETIF_ID_MAX] = { NULL, NULL, NULL, NULL, NULL, NULL}; +static esp_event_handler_instance_t _ip_ev_instance = NULL; + +static ESP_Network_Interface * 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; +} + +static ESP_Network_Interface * getNetifByID(ESP_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){ + ESP_Network_Interface * 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 ESP_Network_Interface::_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){ + _has_ip = true; +#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; + Network.setStatusBits(STA_HAS_IP_BIT); + } else +#endif + if(_interface_id == ESP_NETIF_ID_PPP){ + arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP; + Network.setStatusBits(PPP_HAS_IP_BIT); + } else if(_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX){ + arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP; + Network.setStatusBits(ETH_HAS_IP_BIT(_interface_id - ESP_NETIF_ID_ETH)); + } + } else if(event_id == _lost_ip_event_id){ + _has_ip = false; +#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; + Network.clearStatusBits(STA_HAS_IP_BIT); + } else +#endif + if(_interface_id == ESP_NETIF_ID_PPP){ + arduino_event.event_id = ARDUINO_EVENT_PPP_LOST_IP; + Network.clearStatusBits(PPP_HAS_IP_BIT); + } else if(_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX){ + arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP; + Network.clearStatusBits(ETH_HAS_IP_BIT(_interface_id - ESP_NETIF_ID_ETH)); + } + } else if(event_id == IP_EVENT_GOT_IP6){ +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data; + log_v("%s Got IPv6: IP Index: %d, Zone: %d, " IPV6STR, desc(), event->ip_index, event->ip6_info.ip.zone, 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; + Network.setStatusBits(STA_HAS_IP6_BIT); + } else if(_interface_id == ESP_NETIF_ID_AP){ + arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6; + Network.setStatusBits(AP_HAS_IP6_BIT); + } else +#endif + if(_interface_id == ESP_NETIF_ID_PPP){ + arduino_event.event_id = ARDUINO_EVENT_PPP_GOT_IP6; + Network.setStatusBits(PPP_HAS_IP6_BIT); + } else if(_interface_id >= ESP_NETIF_ID_ETH && _interface_id < ESP_NETIF_ID_MAX){ + arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; + Network.setStatusBits(ETH_HAS_IP6_BIT(_interface_id - ESP_NETIF_ID_ETH)); + } +#if SOC_WIFI_SUPPORTED + } else if(event_id == IP_EVENT_AP_STAIPASSIGNED && _interface_id == ESP_NETIF_ID_AP){ +#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); + } +} + +ESP_Network_Interface::ESP_Network_Interface() + : _esp_netif(NULL) + , _got_ip_event_id(-1) + , _lost_ip_event_id(-1) + , _interface_id(ESP_NETIF_ID_MAX) + , _has_ip(false) +{} + +ESP_Network_Interface::~ESP_Network_Interface(){ + destroyNetif(); +} + +bool ESP_Network_Interface::hasIP(){ + return _has_ip; +} IPAddress ESP_Network_Interface::calculateNetworkID(IPAddress ip, IPAddress subnet) { IPAddress networkID; @@ -53,14 +185,30 @@ uint8_t ESP_Network_Interface::calculateSubnetCIDR(IPAddress subnetMask) { return CIDR; } -void ESP_Network_Interface::destroyNetif(void){ +void ESP_Network_Interface::destroyNetif(){ if(_esp_netif != NULL){ esp_netif_destroy(_esp_netif); _esp_netif = NULL; } } -bool ESP_Network_Interface::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) +bool ESP_Network_Interface::initNetif(ESP_Network_Interface_ID interface_id){ + if(_esp_netif == NULL || interface_id >= ESP_NETIF_ID_MAX){ + return false; + } + _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(_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 ESP_Network_Interface::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2, IPAddress dns3) { if(_esp_netif == NULL){ return false; @@ -69,8 +217,10 @@ bool ESP_Network_Interface::config(IPAddress local_ip, IPAddress gateway, IPAddr 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); @@ -78,12 +228,14 @@ bool ESP_Network_Interface::config(IPAddress local_ip, IPAddress gateway, IPAddr 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; } // Stop DHCPC @@ -100,11 +252,10 @@ bool ESP_Network_Interface::config(IPAddress local_ip, IPAddress gateway, IPAddr return false; } - // Set DNS1-Server + // Set DNS Servers 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); + esp_netif_set_dns_info(_esp_netif, ESP_NETIF_DNS_FALLBACK, &d3); // Start DHCPC if static IP was set if(info.ip.addr == 0){ @@ -113,6 +264,8 @@ bool ESP_Network_Interface::config(IPAddress local_ip, IPAddress gateway, IPAddr log_w("DHCP could not be started! Error: %d", err); return false; } + } else { + _has_ip = true; } return true; @@ -186,10 +339,15 @@ String ESP_Network_Interface::impl_name(void) uint8_t * ESP_Network_Interface::macAddress(uint8_t* mac) { - if(!mac){ + 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); + // getMac(mac); return mac; } @@ -297,3 +455,43 @@ IPv6Address ESP_Network_Interface::localIPv6() } return IPv6Address(addr.addr); } + +void ESP_Network_Interface::printInfo(Print & out){ + out.print(desc()); + out.print(":"); + if(linkUp()){ + out.print(" "); + + out.print(" "); + out.print("ether "); + out.print(macAddress()); + 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(); + + out.print(" "); + out.print("inet6 "); + out.print(localIPv6()); + out.println(); + + out.println(); +} diff --git a/libraries/Networking/src/ESP_Network_Interface.h b/libraries/Networking/src/ESP_Network_Interface.h index da899bba07f..f87d2209fc0 100644 --- a/libraries/Networking/src/ESP_Network_Interface.h +++ b/libraries/Networking/src/ESP_Network_Interface.h @@ -1,22 +1,36 @@ #pragma once #include "esp_netif_types.h" +#include "esp_event.h" #include "Arduino.h" #include "IPv6Address.h" +#include "ESP_Network_Manager.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 +} ESP_Network_Interface_ID; + +#define ESP_NETIF_ID_ETH ESP_NETIF_ID_ETH0 class ESP_Network_Interface { public: ESP_Network_Interface(); - ESP_Network_Interface(ESP_Network_Interface & _if); virtual ~ESP_Network_Interface(); - 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); + 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 enableIpV6(); const char * getHostname(); bool setHostname(const char * hostname); bool linkUp(); + bool hasIP(); const char * ifkey(); const char * desc(); String impl_name(); @@ -32,13 +46,24 @@ class ESP_Network_Interface { uint8_t subnetCIDR(); IPv6Address localIPv6(); + void printInfo(Print & out); + esp_netif_t * netif(){ return _esp_netif; } protected: esp_netif_t *_esp_netif; + int32_t _got_ip_event_id; + int32_t _lost_ip_event_id; + ESP_Network_Interface_ID _interface_id; + bool _has_ip; + bool initNetif(ESP_Network_Interface_ID interface_id); void destroyNetif(); - virtual void getMac(uint8_t* mac) = 0; + // virtual void getMac(uint8_t* mac) = 0; + virtual void printDriverInfo(Print & out) = 0; + + public: + void _onIpEvent(int32_t event_id, void* event_data); private: IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet); diff --git a/libraries/Networking/src/ESP_Network_Manager.cpp b/libraries/Networking/src/ESP_Network_Manager.cpp new file mode 100644 index 00000000000..c4b22f92e66 --- /dev/null +++ b/libraries/Networking/src/ESP_Network_Manager.cpp @@ -0,0 +1,79 @@ +#include "ESP_Network_Manager.h" +#include "esp_netif.h" +#include "lwip/ip_addr.h" +#include "lwip/dns.h" +#include "esp32-hal-log.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp_mac.h" +#endif + +ESP_Network_Manager::ESP_Network_Manager(){ + +} + +bool ESP_Network_Manager::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; +} + +/** + * 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) +{ + if(ipaddr) { + (*reinterpret_cast(callback_arg)) = ipaddr->u_addr.ip4.addr; + } + Network.setStatusBits(WIFI_DNS_DONE_BIT); +} + +/** + * Resolve the given hostname to an IP address. If passed hostname is an IP address, it will be parsed into IPAddress structure. + * @param aHostname Name to be resolved or string containing IP address + * @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 ESP_Network_Manager::hostByName(const char* aHostname, IPAddress& aResult) +{ + if (!aResult.fromString(aHostname)) + { + ip_addr_t addr; + aResult = static_cast(0); + waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); + clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); + err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); + if(err == ERR_OK && addr.u_addr.ip4.addr) { + aResult = addr.u_addr.ip4.addr; + } else if(err == ERR_INPROGRESS) { + waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] + clearStatusBits(WIFI_DNS_DONE_BIT); + } + setStatusBits(WIFI_DNS_IDLE_BIT); + if((uint32_t)aResult == 0){ + log_e("DNS Failed for %s", aHostname); + } + } + return (uint32_t)aResult != 0; +} + +ESP_Network_Manager Network; diff --git a/libraries/Networking/src/ESP_Network_Manager.h b/libraries/Networking/src/ESP_Network_Manager.h new file mode 100644 index 00000000000..9d0b64a7d59 --- /dev/null +++ b/libraries/Networking/src/ESP_Network_Manager.h @@ -0,0 +1,14 @@ +#pragma once + +#include "ESP_Network_Events.h" +#include "IPAddress.h" + +class ESP_Network_Manager : public ESP_Network_Events { +public: + ESP_Network_Manager(); + + bool begin(); + int hostByName(const char *aHostname, IPAddress &aResult); +}; + +extern ESP_Network_Manager Network; diff --git a/libraries/Networking/src/Networking.h b/libraries/Networking/src/Networking.h new file mode 100644 index 00000000000..c3056942e12 --- /dev/null +++ b/libraries/Networking/src/Networking.h @@ -0,0 +1,9 @@ +#pragma once + +#include "ESP_Network_Interface.h" +#include "ESP_Network_Events.h" +#include "ESP_Network_Manager.h" + +#include "WiFiClient.h" +#include "WiFiServer.h" +#include "WiFiUdp.h" \ No newline at end of file diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/Networking/src/WiFiClient.cpp similarity index 99% rename from libraries/WiFi/src/WiFiClient.cpp rename to libraries/Networking/src/WiFiClient.cpp index a4301ad0e09..84b9807902f 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/Networking/src/WiFiClient.cpp @@ -18,7 +18,7 @@ */ #include "WiFiClient.h" -#include "WiFi.h" +#include "ESP_Network_Manager.h" #include #include #include @@ -302,7 +302,7 @@ int WiFiClient::connect(const char *host, uint16_t port) int WiFiClient::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); diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/Networking/src/WiFiClient.h similarity index 100% rename from libraries/WiFi/src/WiFiClient.h rename to libraries/Networking/src/WiFiClient.h diff --git a/libraries/WiFi/src/WiFiServer.cpp b/libraries/Networking/src/WiFiServer.cpp similarity index 100% rename from libraries/WiFi/src/WiFiServer.cpp rename to libraries/Networking/src/WiFiServer.cpp diff --git a/libraries/WiFi/src/WiFiServer.h b/libraries/Networking/src/WiFiServer.h similarity index 100% rename from libraries/WiFi/src/WiFiServer.h rename to libraries/Networking/src/WiFiServer.h diff --git a/libraries/WiFi/src/WiFiUdp.cpp b/libraries/Networking/src/WiFiUdp.cpp similarity index 100% rename from libraries/WiFi/src/WiFiUdp.cpp rename to libraries/Networking/src/WiFiUdp.cpp diff --git a/libraries/WiFi/src/WiFiUdp.h b/libraries/Networking/src/WiFiUdp.h similarity index 100% rename from libraries/WiFi/src/WiFiUdp.h rename to libraries/Networking/src/WiFiUdp.h diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index da70539e220..5014980886e 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -296,41 +296,6 @@ static void set_esp_netif_hostname(const char * 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; @@ -425,33 +390,6 @@ static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t ev 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 * */ @@ -464,8 +402,6 @@ static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t ev 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; } /* @@ -549,41 +485,13 @@ 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); + // temporary only while reworking + WiFiGenericClass::_eventCallback(&arduino_event); + Network.postEvent(&arduino_event); } } -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, WIFI_DNS_IDLE_BIT); - } - 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; @@ -599,11 +507,6 @@ static bool _start_network_event_task(){ 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; @@ -612,26 +515,6 @@ 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!"); - } - } - return initialized; -} - /* * WiFi INIT * */ @@ -658,10 +541,11 @@ 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; } + initWiFiEvents(); if(esp_netifs[ESP_IF_WIFI_AP] == NULL){ esp_netifs[ESP_IF_WIFI_AP] = esp_netif_create_default_wifi_ap(); } @@ -696,7 +580,7 @@ bool wifiLowLevelInit(bool persistent){ if(lowLevelInitDone){ arduino_event_t arduino_event; arduino_event.event_id = ARDUINO_EVENT_WIFI_READY; - postArduinoEvent(&arduino_event); + Network.postEvent(&arduino_event); } } return lowLevelInitDone; @@ -744,22 +628,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; @@ -906,129 +774,6 @@ bool WiFiGenericClass::setHostname(const char * hostname) return true; } -int WiFiGenericClass::setStatusBits(int bits){ - if(!_arduino_event_group){ - return 0; - } - return xEventGroupSetBits(_arduino_event_group, bits); -} - -int WiFiGenericClass::clearStatusBits(int bits){ - if(!_arduino_event_group){ - return 0; - } - return xEventGroupClearBits(_arduino_event_group, bits); -} - -int WiFiGenericClass::getStatusBits(){ - if(!_arduino_event_group){ - return 0; - } - 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, // 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. -} - -/** - * 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); - } - } -} - /** * callback for WiFi events * @param arg @@ -1105,10 +850,8 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) 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); @@ -1122,34 +865,6 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) 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); - } else if(event->event_id == ARDUINO_EVENT_ETH_CONNECTED) { - 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); - } 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 | STA_HAS_IP6_BIT); - } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_GOT_IP6) { - setStatusBits(AP_HAS_IP6_BIT); - } else if(event->event_id == ARDUINO_EVENT_ETH_GOT_IP6) { - setStatusBits(ETH_CONNECTED_BIT | 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, @@ -1161,21 +876,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; } @@ -1546,57 +1246,17 @@ bool WiFiGenericClass::setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2 // ------------------------------------------------ Generic Network function --------------------------------------------- // ----------------------------------------------------------------------------------------------------------------------- -/** - * 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) -{ - if(ipaddr) { - (*reinterpret_cast(callback_arg)) = ipaddr->u_addr.ip4.addr; - } - xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT); -} - -/** - * Resolve the given hostname to an IP address. If passed hostname is an IP address, it will be parsed into IPAddress structure. - * @param aHostname Name to be resolved or string containing IP address - * @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 WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) -{ - if (!aResult.fromString(aHostname)) - { - ip_addr_t addr; - aResult = static_cast(0); - waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); - clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); - err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); - if(err == ERR_OK && addr.u_addr.ip4.addr) { - aResult = addr.u_addr.ip4.addr; - } else if(err == ERR_INPROGRESS) { - waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] - clearStatusBits(WIFI_DNS_DONE_BIT); - } - setStatusBits(WIFI_DNS_IDLE_BIT); - if((uint32_t)aResult == 0){ - log_e("DNS Failed for %s", aHostname); - } - } - return (uint32_t)aResult != 0; -} +/* + * Deprecated Methods +*/ 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) { @@ -1609,26 +1269,77 @@ 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; +} + +int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) +{ + return Network.hostByName(aHostname, aResult); +} + +wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, arduino_event_id_t event) +{ + return Network.onEvent(cbEvent, event); +} + +wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event) +{ + return Network.onEvent(cbEvent, event); +} - return CIDR; +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); } diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index 38396f5a72e..3f459b592ab 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -33,83 +33,12 @@ #include "esp_eth_driver.h" #include "wifi_provisioning/manager.h" -ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS); +#include "Networking.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; +#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 @@ -126,22 +55,6 @@ typedef enum { WIFI_POWER_MINUS_1dBm = -4// -1dBm } wifi_power_t; -static const int AP_STARTED_BIT = BIT0; -static const int AP_HAS_IP6_BIT = BIT1; -static const int AP_HAS_CLIENT_BIT = BIT2; -static const int STA_STARTED_BIT = BIT3; -static const int STA_CONNECTED_BIT = BIT4; -static const int STA_HAS_IP_BIT = BIT5; -static const int STA_HAS_IP6_BIT = BIT6; -static const int ETH_STARTED_BIT = BIT7; -static const int ETH_CONNECTED_BIT = BIT8; -static const int ETH_HAS_IP_BIT = BIT9; -static const int ETH_HAS_IP6_BIT = BIT10; -static const int WIFI_SCANNING_BIT = BIT11; -static const int WIFI_SCAN_DONE_BIT= BIT12; -static const int WIFI_DNS_IDLE_BIT = BIT13; -static const int WIFI_DNS_DONE_BIT = BIT14; - typedef enum { WIFI_RX_ANT0 = 0, WIFI_RX_ANT1,