From 6ac17b5020c52a3a431c4ebf4bf52125ecc17cd0 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 1 Jun 2023 22:44:11 +0200 Subject: [PATCH] Examples/network: Add Ethernet iface to sta-2-wired bridge * adds description about that it's not a bridge, but more like an 1:1 forwarder on L2 * add and describe mac spoofing for Ethernet interface * describe virtual networking for USB-NCM interface --- examples/network/.build-test-rules.yml | 3 + .../CMakeLists.txt | 5 +- .../README.md | 43 ++- .../main/CMakeLists.txt | 9 +- .../network/sta_to_eth/main/Kconfig.projbuild | 42 +++ .../network/sta_to_eth/main/ethernet_iface.c | 318 ++++++++++++++++++ .../network/sta_to_eth/main/idf_component.yml | 9 + .../main/manual_config.c | 13 +- .../main/provisioning.c | 2 +- .../main/provisioning.h | 0 .../main/scheme_generic_httpd.c | 0 .../main/sta2wired_main.c} | 172 ++-------- .../network/sta_to_eth/main/usb_ncm_iface.c | 173 ++++++++++ .../network/sta_to_eth/main/wired_iface.h | 24 ++ .../network/sta_to_eth/sdkconfig.defaults | 1 + .../sta_to_eth/sdkconfig.defaults.esp32s2 | 3 + .../sta_to_eth/sdkconfig.defaults.esp32s3 | 5 + .../main/Kconfig.projbuild | 17 - .../main/idf_component.yml | 5 - .../wifi_eth_usb_bridge/sdkconfig.defaults | 6 - 20 files changed, 642 insertions(+), 208 deletions(-) rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/CMakeLists.txt (58%) rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/README.md (71%) rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/main/CMakeLists.txt (52%) create mode 100644 examples/network/sta_to_eth/main/Kconfig.projbuild create mode 100644 examples/network/sta_to_eth/main/ethernet_iface.c create mode 100644 examples/network/sta_to_eth/main/idf_component.yml rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/main/manual_config.c (87%) rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/main/provisioning.c (98%) rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/main/provisioning.h (100%) rename examples/network/{wifi_eth_usb_bridge => sta_to_eth}/main/scheme_generic_httpd.c (100%) rename examples/network/{wifi_eth_usb_bridge/main/tusb_ncm_main.c => sta_to_eth/main/sta2wired_main.c} (55%) create mode 100644 examples/network/sta_to_eth/main/usb_ncm_iface.c create mode 100644 examples/network/sta_to_eth/main/wired_iface.h create mode 100644 examples/network/sta_to_eth/sdkconfig.defaults create mode 100644 examples/network/sta_to_eth/sdkconfig.defaults.esp32s2 create mode 100644 examples/network/sta_to_eth/sdkconfig.defaults.esp32s3 delete mode 100644 examples/network/wifi_eth_usb_bridge/main/Kconfig.projbuild delete mode 100644 examples/network/wifi_eth_usb_bridge/main/idf_component.yml delete mode 100644 examples/network/wifi_eth_usb_bridge/sdkconfig.defaults diff --git a/examples/network/.build-test-rules.yml b/examples/network/.build-test-rules.yml index 7bbb24e350..2d2e70f24d 100644 --- a/examples/network/.build-test-rules.yml +++ b/examples/network/.build-test-rules.yml @@ -11,3 +11,6 @@ examples/network/simple_sniffer: - if: IDF_TARGET not in ["esp32", "esp32c3", "esp32s3"] temporary: true reason: lack of runners +examples/network/sta_to_eth: + disable: + - if: SOC_WIFI_SUPPORTED != 1 diff --git a/examples/network/wifi_eth_usb_bridge/CMakeLists.txt b/examples/network/sta_to_eth/CMakeLists.txt similarity index 58% rename from examples/network/wifi_eth_usb_bridge/CMakeLists.txt rename to examples/network/sta_to_eth/CMakeLists.txt index 09ccbdecf3..7a48649f7a 100644 --- a/examples/network/wifi_eth_usb_bridge/CMakeLists.txt +++ b/examples/network/sta_to_eth/CMakeLists.txt @@ -3,7 +3,8 @@ cmake_minimum_required(VERSION 3.16) # This example needs a DNS server: let's use the simple DNS server implementation from captive portal example -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/protocols/http_server/captive_portal/components/dns_server) +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/protocols/http_server/captive_portal/components/dns_server + $ENV{IDF_PATH}/examples/ethernet/basic/components/ethernet_init) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(tusb_ncm) +project(wifi_to_wired) diff --git a/examples/network/wifi_eth_usb_bridge/README.md b/examples/network/sta_to_eth/README.md similarity index 71% rename from examples/network/wifi_eth_usb_bridge/README.md rename to examples/network/sta_to_eth/README.md index aa884d4c91..2b66f72924 100644 --- a/examples/network/wifi_eth_usb_bridge/README.md +++ b/examples/network/sta_to_eth/README.md @@ -1,30 +1,26 @@ | Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -# TinyUSB Network Control Model Device Example +# WiFi station to "Wired" interface L2 forwarder (See the README.md file in the upper level 'examples' directory for more information about examples.) -Network Control Model (NCM) is a sub-class of Communication Device Class (CDC) USB Device for Ethernet-over-USB applications. +This example aims to demonstrate 1-1 bridge using WiFi station and one of these interfaces (so called *wired* in this example) +- Ethernet (supported for all targets) +- USB acting as NCM device (supported for ESP32-S2 and ESP32-S3) -In this example, we implemented the ESP development board to transmit WiFi data to the Linux host via USB, so that the Linux host could access the Internet. - -As a USB stack, a TinyUSB component is used. +It also allows for reconfiguring WiFi settings using a virtual network in the Ethernet. The reconfiguration mode is initialized if the WiFi settings are not available, connection fails or manually by long pressing the Boot button (GPIO0). +It is possible to configure WiFi settings (SSID and password) in a browser on an address `"wifi.settings"` or using unified provisioning. ## How to use example -This example demonstrate usage of USB NCM device as USB-WiFi bridge. It also allows for reconfiguring WiFi settings using a virtual network in NCM device. The reconfiguration mode is initialized if the WiFi settings are not available, connection fails or manually by long pressing the Boot button (GPIO0). -It is possible to configure WiFi settings (SSID and password) in a browser on an address `"wifi.settings"` or using unified provisioning. +This example could be used to *bring* wireless connectivity to devices that support only Ethernet (or USB Ethernet implemented as NCM device). +This example also supports runtime configuration of WiFi settings by means of a webpage or unified provisioning. + ### Hardware Required -Any ESP board that have USB-OTG supported. - -#### Pin Assignment - -_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. - -See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). +Any board with either Ethernet of USB-OTG supported. ### Configure the project @@ -36,7 +32,7 @@ In the `Example Configuration` menu choose the provisioning method: To provision the device using IDF provisioning tools (if `EXAMPLE_WIFI_CONFIGURATION_PROVISIONING` is selected) you can use idf provisioning utility with transport set to `softap`: ```bash -esp-idf/tools/esp_prov$ python esp_prov.py --transport softap ... +esp-idf/tools/esp_prov$ python esp_prov.py --transport httpd ... ``` Please refer to the provisioning documentation and `esp_prov` script [documentation](../../../../../tools/esp_prov/README.md) for more details. @@ -58,15 +54,15 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui After the flashing you should see the output at idf monitor: +(note that this is the output of USB configuration) ``` -I (725) usb_net: Wi-Fi STA connected -I (735) usb_net: CONNECTED_BIT - -I (735) usb_net: connect success - -I (735) wifi:BcnInt:102400, DTIM:1 -I (745) usb_net: USB net initialization -I (745) tusb_desc: +I (1740) example_sta2wired: Wi-Fi STA connected +I (1740) example_sta2wired: WiFi station connected successfully +W (1750) TinyUSB: The device's configuration descriptor is not provided by user, using default. +W (1760) TinyUSB: The device's string descriptor is not provided by user, using default. +W (1770) TinyUSB: The device's device descriptor is not provided by user, using default. +I (1770) wifi:AP's beacon interval = 102400 us, DTIM period = 1 +I (1780) tusb_desc: ┌─────────────────────────────────┐ │ USB Device Descriptor Summary │ ├───────────────────┬─────────────┤ @@ -93,5 +89,4 @@ I (745) tusb_desc: │bNumConfigurations │ 0x1 │ └───────────────────┴─────────────┘ I (915) TinyUSB: TinyUSB Driver installed -I (925) usb_net: USB NCM initialization DONE ``` diff --git a/examples/network/wifi_eth_usb_bridge/main/CMakeLists.txt b/examples/network/sta_to_eth/main/CMakeLists.txt similarity index 52% rename from examples/network/wifi_eth_usb_bridge/main/CMakeLists.txt rename to examples/network/sta_to_eth/main/CMakeLists.txt index d9293eaaea..4e7e324ff1 100644 --- a/examples/network/wifi_eth_usb_bridge/main/CMakeLists.txt +++ b/examples/network/sta_to_eth/main/CMakeLists.txt @@ -4,6 +4,13 @@ else() set(config_method provisioning.c scheme_generic_httpd.c) endif() -idf_component_register(SRCS tusb_ncm_main.c +if(CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET) + set(wired_iface ethernet_iface.c) +else() + set(wired_iface usb_ncm_iface.c) +endif() + +idf_component_register(SRCS sta2wired_main.c + ${wired_iface} ${config_method} INCLUDE_DIRS "") diff --git a/examples/network/sta_to_eth/main/Kconfig.projbuild b/examples/network/sta_to_eth/main/Kconfig.projbuild new file mode 100644 index 0000000000..bc71e4059f --- /dev/null +++ b/examples/network/sta_to_eth/main/Kconfig.projbuild @@ -0,0 +1,42 @@ +menu "Example Configuration" + + choice EXAMPLE_WIFI_CONFIGURATION + prompt "WiFi configuration" + default EXAMPLE_WIFI_CONFIGURATION_MANUAL + help + Choose how the WiFi settings should be configured. + + config EXAMPLE_WIFI_CONFIGURATION_MANUAL + bool + prompt "Manual configuration via http server" + config EXAMPLE_WIFI_CONFIGURATION_PROVISIONING + bool + prompt "Using unified provisioning" + endchoice + + choice EXAMPLE_WIRED_INTERFACE + prompt "Choose the Wired interface" + default EXAMPLE_WIRED_INTERFACE_IS_ETHERNET + help + Choose how the WiFi settings should be configured. + + config EXAMPLE_WIRED_INTERFACE_IS_ETHERNET + bool + prompt "Ethernet" + config EXAMPLE_WIRED_INTERFACE_IS_USB + bool + depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + prompt "USB NCM" + endchoice + + config EXAMPLE_RECONFIGURE_BUTTON + int "Button for switching to reconfigure mode" + range 0 46 + default 2 if EXAMPLE_WIRED_INTERFACE_IS_ETHERNET + default 0 + help + The button on this GPIO is used to reset the board to + the reconfiguration mode, i.e. to restart provisioning + or manual configuration of Wi-Fi settings (ssid, password) + +endmenu diff --git a/examples/network/sta_to_eth/main/ethernet_iface.c b/examples/network/sta_to_eth/main/ethernet_iface.c new file mode 100644 index 0000000000..bf81f8640e --- /dev/null +++ b/examples/network/sta_to_eth/main/ethernet_iface.c @@ -0,0 +1,318 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "wired_iface.h" +#include "dhcpserver/dhcpserver_options.h" +#include "esp_mac.h" +#include "ethernet_init.h" + +/** + * Disable promiscuous mode on Ethernet interface by setting this macro to 0 + * if disabled, we'd have to rewrite MAC addressed in frames with the actual Eth interface MAC address + * - this results in better throughput + * - might cause ARP conflicts if the PC is also connected to the same AP with another NIC + */ +#define ETH_BRIDGE_PROMISCUOUS 0 + +static const char *TAG = "example_wired_ethernet"; +static esp_netif_t *s_netif = NULL; +static esp_eth_handle_t s_eth_handle = NULL; +static bool s_ethernet_is_connected = false; +static uint8_t s_eth_mac[6]; +static wired_rx_cb_t s_rx_cb = NULL; +static wired_free_cb_t s_free_cb = NULL; + +/** + * @brief Event handler for Ethernet events + */ +void eth_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + uint8_t mac_addr[6] = {0}; + /* we can get the ethernet driver handle from event data */ + esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; + + switch (event_id) { + case ETHERNET_EVENT_CONNECTED: + esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); + ESP_LOGI(TAG, "Ethernet Link Up"); + ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x", + mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + s_ethernet_is_connected = true; + break; + case ETHERNET_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "Ethernet Link Down"); + s_ethernet_is_connected = false; + break; + case ETHERNET_EVENT_START: + ESP_LOGI(TAG, "Ethernet Started"); + break; + case ETHERNET_EVENT_STOP: + ESP_LOGI(TAG, "Ethernet Stopped"); + break; + default: + ESP_LOGI(TAG, "Default Event"); + break; + } +} + +/** + * In this scenario of WiFi station to Ethernet bridge mode, we have this configuration + * + * (ISP) router ESP32 PC + * [ AP ] <-> [ sta -- eth ] <-> [ eth-NIC ] + * + * From the PC's NIC perspective the L2 forwarding should be transparent and resemble this configuration: + * + * (ISP) router PC + * [ AP ] <----------> [ virtual wifi-NIC ] + * + * In order for the ESP32 to act as L2 bridge it needs to accept all frames on the interface + * - For Ethernet we just enable `PROMISCUOUS` mode + * - For Wifi we could also enable the promiscuous mode, but in that case we'd receive encoded frames + * from 802.11 and we'd have to decode it and process (using wpa-supplicant). + * The easier option (in this scenario of only one client -- eth-NIC) we could simply "pretend" + * that we have the HW mac address of eth-NIC and receive only ethernet frames for "us" from esp_wifi API + * (we could use the same technique for Ethernet and yield better throughput, see ETH_BRIDGE_PROMISCUOUS flag) + * + * This API updates Ethernet frames to swap mac addresses of ESP32 interfaces with those of eth-NIC and AP. + * For that we'd have to parse initial DHCP packets (manually) to record the HW addresses of the AP and eth-NIC + * (note, that it is possible to simply spoof the MAC addresses, but that's not recommended technique) + */ +#define IP_V4 0x40 +#define IP_PROTO_UDP 0x11 +#define DHCP_PORT_IN 0x43 +#define DHCP_PORT_OUT 0x44 +#define DHCP_MACIG_COOKIE_OFFSET (8 + 236) +#define MIN_DHCP_PACKET_SIZE (285) +#define IP_HEADER_SIZE (20) +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_COOKIE_WITH_PKT_TYPE(type) {0x63, 0x82, 0x53, 0x63, 0x35, 1, type}; + +void mac_spoof(mac_spoof_direction_t direction, uint8_t *buffer, uint16_t len, uint8_t own_mac[6]) +{ + if (!s_ethernet_is_connected) { + return; + } + static uint8_t eth_nic_mac[6] = {}; + static bool eth_nic_mac_found = false; +#if !ETH_BRIDGE_PROMISCUOUS + static uint8_t ap_mac[6] = {}; + static bool ap_mac_found = false; +#endif + uint8_t *dest_mac = buffer; + uint8_t *src_mac = buffer + 6; + uint8_t *eth_type = buffer + 12; + if (eth_type[0] == 0x08) { // support only IPv4 + // try to find NIC HW address (look for DHCP discovery packet) + if (!eth_nic_mac_found && direction == FROM_WIRED && eth_type[1] == 0x00) { // ETH IP4 + uint8_t *ip_header = eth_type + 2; + if (len > MIN_DHCP_PACKET_SIZE && (ip_header[0] & 0xF0) == IP_V4 && ip_header[9] == IP_PROTO_UDP) { + uint8_t *udp_header = ip_header + IP_HEADER_SIZE; + const uint8_t dhcp_ports[] = {0, DHCP_PORT_OUT, 0, DHCP_PORT_IN}; + if (memcmp(udp_header, dhcp_ports, sizeof(dhcp_ports)) == 0) { + uint8_t *dhcp_magic = udp_header + DHCP_MACIG_COOKIE_OFFSET; + const uint8_t dhcp_type[] = DHCP_COOKIE_WITH_PKT_TYPE(DHCP_DISCOVER); + if (memcmp(dhcp_magic, dhcp_type, sizeof(dhcp_type)) == 0) { + eth_nic_mac_found = true; + memcpy(eth_nic_mac, src_mac, 6); + } + } // DHCP + } // UDP/IP +#if !ETH_BRIDGE_PROMISCUOUS + // try to find AP HW address (look for DHCP offer packet) + } else if (!ap_mac_found && direction == TO_WIRED && eth_type[1] == 0x00) { // ETH IP4 + uint8_t *ip_header = eth_type + 2; + if (len > MIN_DHCP_PACKET_SIZE && (ip_header[0] & 0xF0) == IP_V4 && ip_header[9] == IP_PROTO_UDP) { + uint8_t *udp_header = ip_header + IP_HEADER_SIZE; + const uint8_t dhcp_ports[] = {0, DHCP_PORT_IN, 0, DHCP_PORT_OUT}; + if (memcmp(udp_header, dhcp_ports, sizeof(dhcp_ports)) == 0) { + uint8_t *dhcp_magic = udp_header + DHCP_MACIG_COOKIE_OFFSET; + const uint8_t dhcp_type[] = DHCP_COOKIE_WITH_PKT_TYPE(DHCP_OFFER); + if (memcmp(dhcp_magic, dhcp_type, sizeof(dhcp_type)) == 0) { + ap_mac_found = true; + memcpy(ap_mac, src_mac, 6); + } + } // DHCP + } // UDP/IP +#endif // !ETH_BRIDGE_PROMISCUOUS + } + + // swap addresses in ARP probes + if (eth_type[1] == 0x06) { // ARP + uint8_t *arp = eth_type + 2 + 8; // points to sender's HW address + if (eth_nic_mac_found && direction == FROM_WIRED && memcmp(arp, eth_nic_mac, 6) == 0) { + /* updates senders HW address to our wireless */ + memcpy(arp, own_mac, 6); +#if !ETH_BRIDGE_PROMISCUOUS + } else if (ap_mac_found && direction == TO_WIRED && memcmp(arp, ap_mac, 6) == 0) { + /* updates senders HW address to our wired */ + memcpy(arp, s_eth_mac, 6); +#endif // !ETH_BRIDGE_PROMISCUOUS + } + } + // swap HW addresses in ETH frames +#if !ETH_BRIDGE_PROMISCUOUS + if (ap_mac_found && direction == FROM_WIRED && memcmp(dest_mac, s_eth_mac, 6) == 0) { + memcpy(dest_mac, ap_mac, 6); + } + if (ap_mac_found && direction == TO_WIRED && memcmp(src_mac, ap_mac, 6) == 0) { + memcpy(src_mac, s_eth_mac, 6); + } +#endif // !ETH_BRIDGE_PROMISCUOUS + if (eth_nic_mac_found && direction == FROM_WIRED && memcmp(src_mac, eth_nic_mac, 6) == 0) { + memcpy(src_mac, own_mac, 6); + } + if (eth_nic_mac_found && direction == TO_WIRED && memcmp(dest_mac, own_mac, 6) == 0) { + memcpy(dest_mac, eth_nic_mac, 6); + } + } // IP4 section of eth-type (0x08) both ETH-IP4 and ETHARP +} + +static esp_err_t wired_recv(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t len, void *priv) +{ + esp_err_t ret = s_rx_cb(buffer,len, buffer); + free(buffer); + return ret; +} + +esp_err_t wired_bridge_init(wired_rx_cb_t rx_cb, wired_free_cb_t free_cb) +{ + uint8_t eth_port_cnt = 0; + esp_eth_handle_t *eth_handles; + ESP_ERROR_CHECK(example_eth_init(ð_handles, ð_port_cnt)); + + // Check or multiple ethernet interface + if (1 < eth_port_cnt) { + ESP_LOGW(TAG, "Multiple Ethernet Interface detected: Only the first initialized interface is going to be used."); + } + s_eth_handle = eth_handles[0]; + free(eth_handles); + ESP_ERROR_CHECK(esp_eth_update_input_path(s_eth_handle, wired_recv, NULL)); +#if ETH_BRIDGE_PROMISCUOUS + bool eth_promiscuous = true; + ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_PROMISCUOUS, ð_promiscuous)); +#endif + ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_G_MAC_ADDR, &s_eth_mac)); + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, NULL)); + ESP_ERROR_CHECK(esp_eth_start(s_eth_handle)); + s_rx_cb = rx_cb; + s_free_cb = free_cb; + return ESP_OK; +} + +esp_err_t wired_send(void *buffer, uint16_t len, void *buff_free_arg) +{ + if (s_ethernet_is_connected) { + if (esp_eth_transmit(s_eth_handle, buffer, len) != ESP_OK) { + ESP_LOGE(TAG, "Ethernet send packet failed"); + return ESP_FAIL; + } + if (s_free_cb) { + s_free_cb(buff_free_arg, NULL); + } + return ESP_OK; + } + return ESP_ERR_INVALID_STATE; +} + +/** + * In this scenario of configuring WiFi, we setup Ethernet to create a network and run DHCP server, + * so it could assign an IP address to the PC + * + * ESP32 PC + * | eth | <-> [ eth-NIC ] + * | | + * | (wifi-provisioning) | + * + * From the PC's NIC perspective the board acts as a separate network with it's own IP and MAC address + * (this network's MAC address is the native ESP32's Ethernet interface MAC) + */ +static void l2_free(void *h, void* buffer) +{ + free(buffer); +} + +static esp_err_t netif_transmit (void *h, void *buffer, size_t len) +{ + if (wired_send(buffer, len, buffer) != ESP_OK) { + ESP_LOGE(TAG, "Failed to send buffer to USB!"); + } + return ESP_OK; +} + +static esp_err_t netif_recv_callback(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t len, void *priv) +{ + if (s_netif) { + void *buf_copy = malloc(len); + if (!buf_copy) { + return ESP_ERR_NO_MEM; + } + memcpy(buf_copy, buffer, len); + return esp_netif_receive(s_netif, buf_copy, len, NULL); + } + return ESP_OK; +} + +esp_err_t wired_netif_init(void) +{ + uint8_t eth_port_cnt = 0; + esp_eth_handle_t *eth_handles; + ESP_ERROR_CHECK(example_eth_init(ð_handles, ð_port_cnt)); + + // Check or multiple ethernet interface + if (1 < eth_port_cnt) { + ESP_LOGW(TAG, "Multiple Ethernet Interface detected: Only the first initialized interface is going to be used."); + } + s_eth_handle = eth_handles[0]; + free(eth_handles); + ESP_ERROR_CHECK(esp_eth_update_input_path(s_eth_handle, netif_recv_callback, NULL)); + + // 1) Derive the base config from the default AP (using DHCP server) + esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP(); + base_cfg.if_key = "wired"; + base_cfg.if_desc = "ethernet config device"; + // 2) Use static config for driver's config pointing only to static transmit and free functions + esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void*)1, // will be replaced by the driver pointer only tinyusb_net supports ti + .transmit = netif_transmit, + .driver_free_rx_buffer = l2_free + }; + + // Config the esp-netif with: + // 1) inherent config (behavioural settings of an interface) + // 2) driver's config (connection to IO functions -- usb) + // 3) stack config (using lwip IO functions -- derive from eth) + esp_netif_config_t cfg = { + .base = &base_cfg, + .driver = &driver_cfg, + // 3) use ethernet style of lwip netif settings + .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH + }; + + s_netif = esp_netif_new(&cfg); + if (s_netif == NULL) { + return ESP_FAIL; + } + + uint8_t mac[6]; + ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_G_MAC_ADDR, &mac)); + esp_netif_set_mac(s_netif, mac); + + // set the minimum lease time + uint32_t lease_opt = 1; + esp_netif_dhcps_option(s_netif, ESP_NETIF_OP_SET, IP_ADDRESS_LEASE_TIME, &lease_opt, sizeof(lease_opt)); + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, NULL)); + ESP_ERROR_CHECK(esp_eth_start(s_eth_handle)); + + // start the interface manually (as the driver has been started already) + esp_netif_action_start(s_netif, 0, 0, 0); + return ESP_OK; +} diff --git a/examples/network/sta_to_eth/main/idf_component.yml b/examples/network/sta_to_eth/main/idf_component.yml new file mode 100644 index 0000000000..bff20c669a --- /dev/null +++ b/examples/network/sta_to_eth/main/idf_component.yml @@ -0,0 +1,9 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: + version: "^1.3.0" + rules: + - if: "idf_version >=4.4" + - if: "target in [esp32s2, esp32s3]" + + idf: "^5.0" diff --git a/examples/network/wifi_eth_usb_bridge/main/manual_config.c b/examples/network/sta_to_eth/main/manual_config.c similarity index 87% rename from examples/network/wifi_eth_usb_bridge/main/manual_config.c rename to examples/network/sta_to_eth/main/manual_config.c index f2bc863062..06864f3097 100644 --- a/examples/network/wifi_eth_usb_bridge/main/manual_config.c +++ b/examples/network/sta_to_eth/main/manual_config.c @@ -58,8 +58,15 @@ static esp_err_t http_get_handler(httpd_req_t *req) if (strlen((char*)wifi_cfg.sta.ssid) > 0 && strlen((char*)wifi_cfg.sta.password)) { const char wifi_configured[] = "

Connecting...

"; - ESP_LOGI(TAG, "WiFi settings accepted!"); - esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); + esp_wifi_set_mode(WIFI_MODE_STA); + if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) == ESP_OK && + esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) == ESP_OK) { + ESP_LOGI(TAG, "WiFi settings accepted!"); + } else { + ESP_LOGE(TAG, "Failed to set WiFi config to flash"); + } +// +// esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg); httpd_resp_set_type(req, "text/html"); httpd_resp_send(req, wifi_configured, strlen(wifi_configured)); @@ -104,7 +111,7 @@ esp_err_t start_provisioning(EventGroupHandle_t *flags, int success_bit, int fai { start_webserver(); // Start the DNS server that will reply to "wifi.settings" with "usb" network interface address - dns_server_config_t config = DNS_SERVER_CONFIG_SINGLE("wifi.settings" /* name */, "usb" /* USB netif ID */); + dns_server_config_t config = DNS_SERVER_CONFIG_SINGLE("wifi.settings" /* name */, "wired" /* USB netif ID */); start_dns_server(&config); s_flags = flags; diff --git a/examples/network/wifi_eth_usb_bridge/main/provisioning.c b/examples/network/sta_to_eth/main/provisioning.c similarity index 98% rename from examples/network/wifi_eth_usb_bridge/main/provisioning.c rename to examples/network/sta_to_eth/main/provisioning.c index 6c77bb1b2a..e53ca899b4 100644 --- a/examples/network/wifi_eth_usb_bridge/main/provisioning.c +++ b/examples/network/sta_to_eth/main/provisioning.c @@ -66,7 +66,7 @@ extern const wifi_prov_scheme_t wifi_prov_scheme_httpd; esp_err_t start_provisioning(EventGroupHandle_t *flags, int success_bit, int fail_bit) { // Start the DNS server that will reply to "wifi.settings" with "usb" network interface address - dns_server_config_t dns_config = DNS_SERVER_CONFIG_SINGLE("wifi.settings" /* name */, "usb" /* USB netif ID */); + dns_server_config_t dns_config = DNS_SERVER_CONFIG_SINGLE("wifi.settings" /* name */, "wired" /* wired netif ID */); start_dns_server(&dns_config); struct events *handler_args = malloc(sizeof(struct events)); handler_args->flags = flags; diff --git a/examples/network/wifi_eth_usb_bridge/main/provisioning.h b/examples/network/sta_to_eth/main/provisioning.h similarity index 100% rename from examples/network/wifi_eth_usb_bridge/main/provisioning.h rename to examples/network/sta_to_eth/main/provisioning.h diff --git a/examples/network/wifi_eth_usb_bridge/main/scheme_generic_httpd.c b/examples/network/sta_to_eth/main/scheme_generic_httpd.c similarity index 100% rename from examples/network/wifi_eth_usb_bridge/main/scheme_generic_httpd.c rename to examples/network/sta_to_eth/main/scheme_generic_httpd.c diff --git a/examples/network/wifi_eth_usb_bridge/main/tusb_ncm_main.c b/examples/network/sta_to_eth/main/sta2wired_main.c similarity index 55% rename from examples/network/wifi_eth_usb_bridge/main/tusb_ncm_main.c rename to examples/network/sta_to_eth/main/sta2wired_main.c index 99b100a8eb..2a264a958d 100644 --- a/examples/network/wifi_eth_usb_bridge/main/tusb_ncm_main.c +++ b/examples/network/sta_to_eth/main/sta2wired_main.c @@ -4,11 +4,7 @@ * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ -/* DESCRIPTION: - * This example contains code to make ESP32-S2/S3 as a USB network Device. - */ - -#include +#include #include #include "freertos/FreeRTOS.h" @@ -20,18 +16,15 @@ #include "esp_event.h" #include "esp_private/wifi.h" #include "nvs_flash.h" -#include "dhcpserver/dhcpserver_options.h" -#include "esp_mac.h" #include "driver/gpio.h" - -#include "tinyusb.h" -#include "tinyusb_net.h" #include "provisioning.h" +#include "wired_iface.h" -static const char *TAG = "USB_NCM"; +static const char *TAG = "example_sta2wired"; static EventGroupHandle_t s_event_flags; static bool s_wifi_is_connected = false; +static uint8_t s_sta_mac[6]; const int CONNECTED_BIT = BIT0; const int DISCONNECTED_BIT = BIT1; @@ -39,15 +32,13 @@ const int RECONFIGURE_BIT = BIT2; const int PROV_SUCCESS_BIT = BIT3; const int PROV_FAIL_BIT = BIT4; -static esp_netif_t *s_netif = NULL; - /** - * WiFi -- USB bridge functionality + * WiFi -- Wired packet path */ - -static esp_err_t usb_recv_callback(void *buffer, uint16_t len, void* ctx) +static esp_err_t wired_recv_callback(void *buffer, uint16_t len, void* ctx) { if (s_wifi_is_connected) { + mac_spoof(FROM_WIRED, buffer, len, s_sta_mac); if (esp_wifi_internal_tx(ESP_IF_WIFI_STA, buffer, len) != ESP_OK) { ESP_LOGD(TAG, "Failed to send packet to WiFi!"); } @@ -60,9 +51,10 @@ static void wifi_buff_free(void* buffer, void* ctx) esp_wifi_internal_free_rx_buffer(buffer); } -static esp_err_t pkt_wifi2usb(void *buffer, uint16_t len, void *eb) +static esp_err_t wifi_recv_callback(void *buffer, uint16_t len, void *eb) { - if (tinyusb_net_send_sync(buffer, len, eb, pdMS_TO_TICKS(100)) != ESP_OK) { + mac_spoof(TO_WIRED, buffer, len, s_sta_mac); + if (wired_send(buffer, len, eb) != ESP_OK) { esp_wifi_internal_free_rx_buffer(eb); ESP_LOGD(TAG, "Failed to send packet to USB!"); } @@ -77,11 +69,12 @@ static void event_handler(void *arg, esp_event_base_t event_base, s_wifi_is_connected = false; esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL); esp_wifi_connect(); + xEventGroupClearBits(s_event_flags, CONNECTED_BIT); xEventGroupSetBits(s_event_flags, DISCONNECTED_BIT); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) { ESP_LOGI(TAG, "Wi-Fi STA connected"); - esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, pkt_wifi2usb); + esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, wifi_recv_callback); s_wifi_is_connected = true; xEventGroupClearBits(s_event_flags, DISCONNECTED_BIT); xEventGroupSetBits(s_event_flags, CONNECTED_BIT); @@ -109,137 +102,16 @@ static esp_err_t connect_wifi(void) return ESP_ERR_TIMEOUT; } -static void on_usb_net_init(void *ctx) -{ - ESP_LOGE(TAG, "USB NET device has been initialized!"); -} - -static esp_err_t usb_ncm_wifi_bridge(void) -{ - const tinyusb_config_t tusb_cfg = { - .external_phy = false, - }; - ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); - - tinyusb_net_config_t net_config = { - .on_recv_callback = usb_recv_callback, - .free_tx_buffer = wifi_buff_free, - .on_init_callback = on_usb_net_init - }; - - esp_read_mac(net_config.mac_addr, ESP_MAC_WIFI_STA); - - esp_err_t ret = tinyusb_net_init(TINYUSB_USBDEV_0, &net_config); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "USB net init but not connect wifi"); - return ret; - } - return ESP_OK; -} - -/** - * USB internal network functionality - */ - -esp_err_t netif_recv_callback(void *buffer, uint16_t len, void* ctx) -{ - if (s_netif) { - void *buf_copy = malloc(len); - if (!buf_copy) { - return ESP_ERR_NO_MEM; - } - memcpy(buf_copy, buffer, len); - return esp_netif_receive(s_netif, buf_copy, len, NULL); - } - return ESP_OK; -} - -static esp_err_t netif_transmit (void *h, void *buffer, size_t len) -{ - if (tinyusb_net_send_sync(buffer, len, NULL, pdMS_TO_TICKS(100)) != ESP_OK) { - ESP_LOGE(TAG, "Failed to send buffer to USB!"); - } - return ESP_OK; -} - -static void l2_free(void *h, void* buffer) -{ - free(buffer); -} - -static esp_err_t usb_ncm_with_network(void) -{ - const tinyusb_config_t tusb_cfg = { - .external_phy = false, - }; - ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); - - const tinyusb_net_config_t net_config = { - // locally administrated address for the ncm device as it's going to be used internally - // for configuration only - .mac_addr = {0x02, 0x02, 0x11, 0x22, 0x33, 0x01}, - .on_recv_callback = netif_recv_callback, - }; - - esp_err_t ret = tinyusb_net_init(TINYUSB_USBDEV_0, &net_config); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Cannot initialize USB Net device"); - return ret; - } - - // with OUI range MAC to create a virtual netif running http server - // this needs to be different to usb_interface_mac (==client) - uint8_t lwip_addr[6]= {0x02, 0x02, 0x11, 0x22, 0x33, 0x02}; - - - // 1) Derive the base config from the default AP (using DHCP server) - esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP(); - base_cfg.if_key = "usb"; - base_cfg.if_desc = "usb ncm config device"; - // 2) Use static config for driver's config pointing only to static transmit and free functions - esp_netif_driver_ifconfig_t driver_cfg = { - .handle = (void*)1, // will be replaced by the driver pointer only tinyusb_net supports ti - .transmit = netif_transmit, - .driver_free_rx_buffer = l2_free - }; - - // Config the esp-netif with: - // 1) inherent config (behavioural settings of an interface) - // 2) driver's config (connection to IO functions -- usb) - // 3) stack config (using lwip IO functions -- derive from eth) - esp_netif_config_t cfg = { - .base = &base_cfg, - .driver = &driver_cfg, - // 3) use ethernet style of lwip netif settings - .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH - }; - - s_netif = esp_netif_new(&cfg); - if (s_netif == NULL) { - return ESP_FAIL; - } - esp_netif_set_mac(s_netif, lwip_addr); - - // set the minimum lease time - uint32_t lease_opt = 1; - esp_netif_dhcps_option(s_netif, ESP_NETIF_OP_SET, IP_ADDRESS_LEASE_TIME, &lease_opt, sizeof(lease_opt)); - - // start the interface manually (as the driver has been started already) - esp_netif_action_start(s_netif, 0, 0, 0); - return ESP_OK; -} - /** * GPIO button functionality */ - -#define GPIO_INPUT_IO_0 0 +#define GPIO_INPUT CONFIG_EXAMPLE_RECONFIGURE_BUTTON #define GPIO_LONG_PUSH_US 2000000 /* push for 2 seconds to reconfigure */ static void IRAM_ATTR gpio_isr_handler(void* arg) { static int64_t last_pushed = -1; - if (gpio_get_level(GPIO_INPUT_IO_0) == 0) { + if (gpio_get_level(GPIO_INPUT) == 0) { last_pushed = esp_timer_get_time(); } else { uint64_t now = esp_timer_get_time(); @@ -257,19 +129,19 @@ static void IRAM_ATTR gpio_isr_handler(void* arg) static void gpio_init(void) { gpio_config_t io_conf = { .intr_type = GPIO_INTR_ANYEDGE, - .pin_bit_mask = (1ULL< +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "tinyusb.h" +#include "tinyusb_net.h" +#include "wired_iface.h" +#include "dhcpserver/dhcpserver_options.h" +#include "esp_mac.h" + +static const char *TAG = "example_wired_tusb_ncm"; +static esp_netif_t *s_netif = NULL; + +/** + * In this scenario of WiFi station to Ethernet bridge mode, we have this configuration + * + * (ISP) router ESP32 PC + * [ AP ] <-> [ sta -- USB ] <-> [ USB-NCM device acting as eth-NIC ] + * + * From the PC's NIC perspective the L2 forwarding should be transparent and resemble this configuration: + * + * (ISP) router PC + * [ AP ] <----------> [ virtual wifi-NIC ] + * + * In order for the ESP32 to act as L2 bridge it needs to accept the frames for the NCM device, + * which we have fully under control, we can modify it's MAC address, as well as the WiFi station + * MAC address, which need to be the same so the AP would see one device (virtual eth-NIC). + * No need to modify the ethernet frames here, as we can set the station's MAC to the USB NCM device. + */ +void mac_spoof(mac_spoof_direction_t direction, uint8_t *buffer, uint16_t len, uint8_t own_mac[6]) +{ + +} + +esp_err_t wired_bridge_init(wired_rx_cb_t rx_cb, wired_free_cb_t free_cb) +{ + const tinyusb_config_t tusb_cfg = { + .external_phy = false, + }; + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_net_config_t net_config = { + .on_recv_callback = rx_cb, + .free_tx_buffer = free_cb, + }; + + esp_read_mac(net_config.mac_addr, ESP_MAC_WIFI_STA); + + esp_err_t ret = tinyusb_net_init(TINYUSB_USBDEV_0, &net_config); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "USB net init but not connect wifi"); + return ret; + } + return ESP_OK; +} + + +esp_err_t wired_send(void *buffer, uint16_t len, void *buff_free_arg) +{ + return tinyusb_net_send_sync(buffer, len, buff_free_arg, pdMS_TO_TICKS(100)); +} + +static void l2_free(void *h, void* buffer) +{ + free(buffer); +} + +static esp_err_t netif_transmit (void *h, void *buffer, size_t len) +{ + if (wired_send(buffer, len, NULL) != ESP_OK) { + ESP_LOGE(TAG, "Failed to send buffer to USB!"); + } + return ESP_OK; +} + +static esp_err_t netif_recv_callback(void *buffer, uint16_t len, void* ctx) +{ + if (s_netif) { + void *buf_copy = malloc(len); + if (!buf_copy) { + return ESP_ERR_NO_MEM; + } + memcpy(buf_copy, buffer, len); + return esp_netif_receive(s_netif, buf_copy, len, NULL); + } + return ESP_OK; +} + +/** + * In this scenario of configuring WiFi, we setup USB-Ethernet to create a virtual network and run DHCP server, + * so it could assign an IP address to the PC + * + * ESP32 PC + * | lwip MAC=...01 | eth NIC MAC=...02 + * | usb | <-> [ USB-NCM device acting as eth-NIC ] + * | | + * | (wifi-provisioning) | + * + * From the PC's NIC perspective the board acts as a separate network with it's own IP and MAC address, + * but the virtual ethernet NIC has also it's own IP and MAC address (configured via tinyusb_net_init()). + * That's why we need to create the virtual network with *different* MAC address. + * Here, we use two different OUI range MAC addresses. + */ +esp_err_t wired_netif_init(void) +{ + const tinyusb_config_t tusb_cfg = { + .external_phy = false, + }; + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + const tinyusb_net_config_t net_config = { + // locally administrated address for the ncm device as it's going to be used internally + // for configuration only + .mac_addr = {0x02, 0x02, 0x11, 0x22, 0x33, 0x01}, + .on_recv_callback = netif_recv_callback, + }; + + esp_err_t ret = tinyusb_net_init(TINYUSB_USBDEV_0, &net_config); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Cannot initialize USB Net device"); + return ret; + } + + // with OUI range MAC to create a virtual netif running http server + // this needs to be different to usb_interface_mac (==client) + uint8_t lwip_addr[6]= {0x02, 0x02, 0x11, 0x22, 0x33, 0x02}; + + + // 1) Derive the base config from the default AP (using DHCP server) + esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP(); + base_cfg.if_key = "wired"; + base_cfg.if_desc = "usb ncm config device"; + // 2) Use static config for driver's config pointing only to static transmit and free functions + esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void*)1, // will be replaced by the driver pointer only tinyusb_net supports ti + .transmit = netif_transmit, + .driver_free_rx_buffer = l2_free + }; + + // Config the esp-netif with: + // 1) inherent config (behavioural settings of an interface) + // 2) driver's config (connection to IO functions -- usb) + // 3) stack config (using lwip IO functions -- derive from eth) + esp_netif_config_t cfg = { + .base = &base_cfg, + .driver = &driver_cfg, + // 3) use ethernet style of lwip netif settings + .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH + }; + + s_netif = esp_netif_new(&cfg); + if (s_netif == NULL) { + return ESP_FAIL; + } + esp_netif_set_mac(s_netif, lwip_addr); + + // set the minimum lease time + uint32_t lease_opt = 1; + esp_netif_dhcps_option(s_netif, ESP_NETIF_OP_SET, IP_ADDRESS_LEASE_TIME, &lease_opt, sizeof(lease_opt)); + + // start the interface manually (as the driver has been started already) + esp_netif_action_start(s_netif, 0, 0, 0); + return ESP_OK; +} diff --git a/examples/network/sta_to_eth/main/wired_iface.h b/examples/network/sta_to_eth/main/wired_iface.h new file mode 100644 index 0000000000..d4c3716829 --- /dev/null +++ b/examples/network/sta_to_eth/main/wired_iface.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#pragma once + +typedef esp_err_t (*wired_rx_cb_t)(void *buffer, uint16_t len, void *ctx); + +typedef void (*wired_free_cb_t)(void *buffer, void *ctx); + +typedef enum { + FROM_WIRED, + TO_WIRED +} mac_spoof_direction_t; + +void mac_spoof(mac_spoof_direction_t direction, uint8_t *buffer, uint16_t len, uint8_t own_mac[6]); + +esp_err_t wired_bridge_init(wired_rx_cb_t rx_cb, wired_free_cb_t free_cb); + +esp_err_t wired_send(void *buffer, uint16_t len, void *buff_free_arg); + +esp_err_t wired_netif_init(void); diff --git a/examples/network/sta_to_eth/sdkconfig.defaults b/examples/network/sta_to_eth/sdkconfig.defaults new file mode 100644 index 0000000000..6e41a8774f --- /dev/null +++ b/examples/network/sta_to_eth/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=y diff --git a/examples/network/sta_to_eth/sdkconfig.defaults.esp32s2 b/examples/network/sta_to_eth/sdkconfig.defaults.esp32s2 new file mode 100644 index 0000000000..a8e8359333 --- /dev/null +++ b/examples/network/sta_to_eth/sdkconfig.defaults.esp32s2 @@ -0,0 +1,3 @@ +CONFIG_EXAMPLE_WIRED_INTERFACE_IS_USB=y +CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=n +CONFIG_TINYUSB_NET_MODE_NCM=y diff --git a/examples/network/sta_to_eth/sdkconfig.defaults.esp32s3 b/examples/network/sta_to_eth/sdkconfig.defaults.esp32s3 new file mode 100644 index 0000000000..ef3717be29 --- /dev/null +++ b/examples/network/sta_to_eth/sdkconfig.defaults.esp32s3 @@ -0,0 +1,5 @@ +CONFIG_EXAMPLE_WIRED_INTERFACE_IS_USB=y +CONFIG_EXAMPLE_WIRED_INTERFACE_IS_ETHERNET=n +CONFIG_TINYUSB_TASK_AFFINITY_CPU0=y +CONFIG_TINYUSB_INIT_IN_DEFAULT_TASK=y +CONFIG_TINYUSB_NET_MODE_NCM=y diff --git a/examples/network/wifi_eth_usb_bridge/main/Kconfig.projbuild b/examples/network/wifi_eth_usb_bridge/main/Kconfig.projbuild deleted file mode 100644 index 0d3677e2dc..0000000000 --- a/examples/network/wifi_eth_usb_bridge/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - choice EXAMPLE_WIFI_CONFIGURATION - prompt "WiFi configuration" - default EXAMPLE_WIFI_CONFIGURATION_MANUAL - help - Choose how the WiFi settings should be configured. - - config EXAMPLE_WIFI_CONFIGURATION_MANUAL - bool - prompt "Manual configuration via http server" - config EXAMPLE_WIFI_CONFIGURATION_PROVISIONING - bool - prompt "Using unified provisioning" - endchoice - -endmenu diff --git a/examples/network/wifi_eth_usb_bridge/main/idf_component.yml b/examples/network/wifi_eth_usb_bridge/main/idf_component.yml deleted file mode 100644 index 73302c2ced..0000000000 --- a/examples/network/wifi_eth_usb_bridge/main/idf_component.yml +++ /dev/null @@ -1,5 +0,0 @@ -## IDF Component Manager Manifest File -dependencies: - espressif/esp_tinyusb: - version: "^1.0.1" - idf: "^5.0" diff --git a/examples/network/wifi_eth_usb_bridge/sdkconfig.defaults b/examples/network/wifi_eth_usb_bridge/sdkconfig.defaults deleted file mode 100644 index 298e827b12..0000000000 --- a/examples/network/wifi_eth_usb_bridge/sdkconfig.defaults +++ /dev/null @@ -1,6 +0,0 @@ - -# -# USB Network Class (NCM) -# -CONFIG_TINYUSB_NCM_ENABLE=y -# end of USB Network Class (NCM)