diff --git a/src/PAL/Lwip/lwIP_Sockets.cpp b/src/PAL/Lwip/lwIP_Sockets.cpp index 1088636712..a061d213fb 100644 --- a/src/PAL/Lwip/lwIP_Sockets.cpp +++ b/src/PAL/Lwip/lwIP_Sockets.cpp @@ -20,6 +20,10 @@ extern "C" #include } +#if defined(PLATFORM_ESP32) +#include "NF_ESP32_Network.h" +#endif + int errorCode; //--// @@ -1288,6 +1292,7 @@ struct dhcp_client_id uint8_t clientId[6]; }; +#if !defined(PLATFORM_ESP32) HRESULT LWIP_SOCKETS_Driver::UpdateAdapterConfiguration( uint32_t interfaceIndex, uint32_t updateFlags, @@ -1389,6 +1394,135 @@ HRESULT LWIP_SOCKETS_Driver::UpdateAdapterConfiguration( return S_OK; } +#else +HRESULT LWIP_SOCKETS_Driver::UpdateAdapterConfiguration( + uint32_t interfaceIndex, + uint32_t updateFlags, + HAL_Configuration_NetworkInterface *config) +{ + NATIVE_PROFILE_PAL_NETWORK(); + bool enableDHCP = (config->StartupAddressMode == AddressMode_DHCP); + + struct netif *networkInterface = + netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber); + if (NULL == networkInterface) + { + return CLR_E_FAIL; + } + + esp_netif_t *espNetif = NF_ESP32_GetEspNetif(networkInterface); + if (NULL == espNetif) + { + return CLR_E_FAIL; + } + +#if LWIP_DNS + // when using DHCP do not use the static settings + if (0 != (updateFlags & NetworkInterface_UpdateOperation_Dns)) + { + if (config->AutomaticDNS == 0) + { + // user defined DNS addresses + if (config->IPv4DNSAddress1 != 0) + { + esp_netif_dns_info_t dnsServer; + dnsServer.ip.u_addr.ip4.addr = config->IPv4DNSAddress1; + dnsServer.ip.type = IPADDR_TYPE_V4; + + esp_netif_set_dns_info(espNetif, ESP_NETIF_DNS_MAIN, &dnsServer); + } + if (config->IPv4DNSAddress2 != 0) + { + // need to convert this first + esp_netif_dns_info_t dnsServer; + dnsServer.ip.u_addr.ip4.addr = config->IPv4DNSAddress2; + dnsServer.ip.type = IPADDR_TYPE_V4; + + esp_netif_set_dns_info(espNetif, ESP_NETIF_DNS_FALLBACK, &dnsServer); + } + } + } +#endif + +#if LWIP_DHCP + if (0 != (updateFlags & NetworkInterface_UpdateOperation_Dhcp)) + { + if (enableDHCP) + { + // Make sure DHCP option is enabled for esp_netif + espNetif->flags = (esp_netif_flags_t)(espNetif->flags | ESP_NETIF_DHCP_CLIENT); + + // Reset IP address on interface before enabling DHCP + ip_addr_t ipAddress, mask, gateway; +#if LWIP_IPV6 + ipAddress.u_addr.ip4.addr = 0; + mask.u_addr.ip4.addr = 0; + gateway.u_addr.ip4.addr = 0; +#else + ipAddress.addr = 0; + mask.addr = 0; + gateway.addr = 0; +#endif + + netif_set_addr( + networkInterface, + (const ip4_addr_t *)&ipAddress, + (const ip4_addr_t *)&mask, + (const ip4_addr_t *)&gateway); + + // Need to start DHCP + // No need to check for return value, even if it fails, it will retry + esp_netif_dhcpc_start(espNetif); + } + else + { + // stop DHCP, ignore errors + esp_netif_dhcpc_stop(espNetif); + + // Get static IPV4 address from config + esp_netif_ip_info_t ip_info; + ip_info.ip.addr = config->IPv4Address; + ip_info.gw.addr = config->IPv4GatewayAddress; + ip_info.netmask.addr = config->IPv4NetMask; + + // set interface with our static IP configs, ignore error + esp_netif_set_ip_info(espNetif, &ip_info); + + // Make sure DHCP client is disabled in esp_netif + espNetif->flags = (esp_netif_flags_t)(espNetif->flags & ~ESP_NETIF_DHCP_CLIENT); + + // Inform DHCP server of change + dhcp_inform(networkInterface); + } + } + + if (enableDHCP) + { + if (0 != (updateFlags & NetworkInterface_UpdateOperation_DhcpRelease)) + { + esp_netif_dhcpc_stop(espNetif); + } + else if (0 != (updateFlags & NetworkInterface_UpdateOperation_DhcpRenew)) + { + esp_netif_dhcpc_stop(espNetif); + esp_netif_dhcpc_start(espNetif); + } + } +#endif + + if (0 != (updateFlags & NetworkInterface_UpdateOperation_Mac)) + { + memcpy(networkInterface->hwaddr, config->MacAddress, NETIF_MAX_HWADDR_LEN); + networkInterface->hwaddr_len = NETIF_MAX_HWADDR_LEN; + + // mac address requires stack re-init + Network_Interface_Close(interfaceIndex); + g_LWIP_SOCKETS_Driver.m_interfaces[interfaceIndex].m_interfaceNumber = Network_Interface_Open(interfaceIndex); + } + + return S_OK; +} +#endif int LWIP_SOCKETS_Driver::GetNativeTcpOption(int optname) { diff --git a/targets/ESP32/_Network/CMakeLists.txt b/targets/ESP32/_Network/CMakeLists.txt index f76a1dc7ed..7e88e7429b 100644 --- a/targets/ESP32/_Network/CMakeLists.txt +++ b/targets/ESP32/_Network/CMakeLists.txt @@ -11,6 +11,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/esp32_ethernet_options.h.in ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/esp32_ethernet_options.h @ONLY) # append networking files, if enabled +list(APPEND TARGET_ESP32_IDF_NETWORK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NF_ESP32_Network.cpp) list(APPEND TARGET_ESP32_IDF_NETWORK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NF_ESP32_Ethernet.cpp) list(APPEND TARGET_ESP32_IDF_NETWORK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NF_ESP32_Wireless.cpp) list(APPEND TARGET_ESP32_IDF_NETWORK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NF_ESP32_SmartConfig.cpp) diff --git a/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp b/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp index b513a1f81e..3b062aea69 100644 --- a/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp +++ b/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp @@ -143,7 +143,7 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) buscfg.quadwp_io_num = -1; buscfg.quadhd_io_num = -1; - ESP_ERROR_CHECK(spi_bus_initialize(ESP32_ETHERNET_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + ESP_ERROR_CHECK_WITHOUT_ABORT(spi_bus_initialize(ESP32_ETHERNET_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); #pragma // Define SPI interface to use @@ -216,14 +216,14 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) #ifdef ESP32_ETHERNET_SPI // The SPI Ethernet module doesn't have a burned factory MAC address, we have to set it manually. // Supplied in the config - ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, pMacAdr)); + ESP_ERROR_CHECK_WITHOUT_ABORT(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, pMacAdr)); #endif // attach Ethernet driver to TCP/IP stack - ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle))); + ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle))); // start Ethernet driver state machine - ESP_ERROR_CHECK(esp_eth_start(eth_handle)); + ESP_ERROR_CHECK_WITHOUT_ABORT(esp_eth_start(eth_handle)); #endif // ESP32_ETHERNET_SUPPORT diff --git a/targets/ESP32/_Network/NF_ESP32_Network.cpp b/targets/ESP32/_Network/NF_ESP32_Network.cpp new file mode 100644 index 0000000000..20852e4974 --- /dev/null +++ b/targets/ESP32/_Network/NF_ESP32_Network.cpp @@ -0,0 +1,115 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +// This file includes common method for networking code + +#include "NF_ESP32_Network.h" +#include "esp_netif_net_stack.h" +#include "lwIP_Sockets.h" + +// This function retrives the esp_netif ptr from the lwip structure for use else where +// This is a copy of internal funtion of ESP_NETIF +esp_netif_t *NF_ESP32_GetEspNetif(struct netif *netif) +{ +#if LWIP_ESP_NETIF_DATA + return (esp_netif *)netif_get_client_data(netif); +#else + return (esp_netif_t *)netif->state; +#endif +} + +// Wait for the network interface to become available +int NF_ESP32_Wait_NetNumber(int num) +{ + int number = 0; + int timeoutMs = 30000; // 30 seconds timeout + int elapsedMs = 0; + esp_netif_t *espNetif; + + while (elapsedMs < timeoutMs) + { + switch (num) + { + case IDF_WIFI_STA_DEF: + espNetif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); + break; + + case IDF_WIFI_AP_DEF: + espNetif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); + break; + + case IDF_ETH_DEF: + espNetif = esp_netif_get_handle_from_ifkey("ETH_DEF"); + break; + + case IDF_OT_DEF: + espNetif = esp_netif_get_handle_from_ifkey("OT_DEF"); + break; + + default: + // can't reach here + HAL_AssertEx(); + break; + } + + if (espNetif != NULL) + { + break; + } + + const int delayMs = 20; + vTaskDelay(delayMs / portTICK_PERIOD_MS); + elapsedMs += delayMs; + } + + if (espNetif == NULL) + { + // Return error or default value + return SOCK_SOCKET_ERROR; + } + + // Add a delay before picking up "lwip_netif->num" as not been filled in yet on slower processors + vTaskDelay(50 / portTICK_PERIOD_MS); + + return espNetif->lwip_netif->num; +} + +HAL_Configuration_NetworkInterface *NF_ESP32_GetNetworkConfigBlock(int index) +{ + HAL_Configuration_NetworkInterface *networkConfig = + (HAL_Configuration_NetworkInterface *)platform_malloc(sizeof(HAL_Configuration_NetworkInterface)); + + if (networkConfig != NULL) + { + if (ConfigurationManager_GetConfigurationBlock(networkConfig, DeviceConfigurationOption_Network, index)) + { + return networkConfig; + } + platform_free(networkConfig); + } + + return NULL; +} + +esp_err_t NF_ESP32_ConfigureNetworkByConfigIndex(int index) +{ + esp_err_t ec = ESP_OK; + + HAL_Configuration_NetworkInterface *networkConfig = NF_ESP32_GetNetworkConfigBlock(index); + if (networkConfig == NULL) + { + return ESP_FAIL; + } + + // Configure network interface + LWIP_SOCKETS_Driver::UpdateAdapterConfiguration( + index, + NetworkInterface_UpdateOperation_Dns | NetworkInterface_UpdateOperation_Dhcp, + networkConfig); + + platform_free(networkConfig); + + return ec; +} diff --git a/targets/ESP32/_Network/NF_ESP32_Wireless.cpp b/targets/ESP32/_Network/NF_ESP32_Wireless.cpp index 6954849512..3d9b006b1f 100644 --- a/targets/ESP32/_Network/NF_ESP32_Wireless.cpp +++ b/targets/ESP32/_Network/NF_ESP32_Wireless.cpp @@ -155,6 +155,14 @@ esp_err_t NF_ESP32_InitaliseWifi() // create Wi-Fi STA (ignoring return) wifiStaNetif = esp_netif_create_default_wifi_sta(); + // Set static address if configured + // ignore any errors + ec = NF_ESP32_ConfigureNetworkByConfigIndex(IDF_WIFI_STA_DEF); + if (ec != ESP_OK) + { + ESP_LOGE(TAG, "Unable to configure Wifi station - result %d", ec); + } + // We need to start the WIFI stack before the station can Connect // Also we can only get the NetIf number used by ESP IDF after it has been started. // Starting will also start the Soft- AP (if we have enabled it). @@ -514,47 +522,3 @@ bool NF_ESP32_WirelessAP_Close() } #endif - -// Wait for the network interface to become available -int NF_ESP32_Wait_NetNumber(int num) -{ - int number = 0; - - esp_netif_t *espNetif; - - while (true) - { - switch (num) - { - case IDF_WIFI_STA_DEF: - espNetif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - break; - - case IDF_WIFI_AP_DEF: - espNetif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"); - break; - - case IDF_ETH_DEF: - espNetif = esp_netif_get_handle_from_ifkey("ETH_DEF"); - break; - - case IDF_OT_DEF: - espNetif = esp_netif_get_handle_from_ifkey("OT_DEF"); - break; - - default: - // can't reach here - HAL_AssertEx(); - break; - } - - if (espNetif != NULL) - { - break; - } - - vTaskDelay(20 / portTICK_PERIOD_MS); - } - - return espNetif->lwip_netif->num; -} diff --git a/targets/ESP32/_common/targetHAL_Network.cpp b/targets/ESP32/_common/targetHAL_Network.cpp index cb49b025d7..1bde5d9c4d 100644 --- a/targets/ESP32/_common/targetHAL_Network.cpp +++ b/targets/ESP32/_common/targetHAL_Network.cpp @@ -373,6 +373,15 @@ static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_ #ifdef PRINT_NET_EVENT ets_printf("ETHERNET_EVENT_CONNECTED\n"); #endif + // Make sure configuration is correct + result = NF_ESP32_ConfigureNetworkByConfigIndex(IDF_ETH_DEF); + if (result != ESP_OK) + { +#ifdef PRINT_NET_EVENT + ets_printf("Failed to configure network for ethernet on connect: %d\n", err); +#endif + } + PostAvailabilityOn(IDF_ETH_DEF); break; diff --git a/targets/ESP32/_include/NF_ESP32_Network.h b/targets/ESP32/_include/NF_ESP32_Network.h index 94e0edf837..7e60db9ee3 100644 --- a/targets/ESP32/_include/NF_ESP32_Network.h +++ b/targets/ESP32/_include/NF_ESP32_Network.h @@ -60,5 +60,7 @@ void NF_ESP32_Start_wifi_smart_config(void); // Helpers int NF_ESP32_Wait_NetNumber(int num); - +HAL_Configuration_NetworkInterface *NF_ESP32_GetNetworkConfigBlock(int index); +esp_err_t NF_ESP32_ConfigureNetworkByConfigIndex(int index); +esp_netif_t *NF_ESP32_GetEspNetif(struct netif *netif); #endif // NF_ESP32_NETWORK_H