diff --git a/components/esp_wifi_remote/CMakeLists.txt b/components/esp_wifi_remote/CMakeLists.txt index 577a37e00..e8460c874 100644 --- a/components/esp_wifi_remote/CMakeLists.txt +++ b/components/esp_wifi_remote/CMakeLists.txt @@ -1,15 +1,20 @@ if(NOT CONFIG_ESP_WIFI_ENABLED) - set(src_wifi_is_remote esp_wifi_remote.c esp_wifi_with_remote.c) + set(src_wifi_is_remote esp_wifi_remote.c esp_wifi_with_remote.c esp_wifi_remote_net.c) +endif() + +if(CONFIG_ESP_WIFI_REMOTE_LIBRARY_EPPP) + set(src_wifi_remote_eppp eppp/wifi_remote_rpc_client.cpp eppp/wifi_remote_rpc_server.cpp eppp/eppp_init.c) +else() + set(src_wifi_remote_weak esp_wifi_remote_weak.c) endif() idf_component_register(INCLUDE_DIRS include - SRCS ${src_wifi_is_remote} - esp_wifi_remote_net.c - esp_wifi_remote_weak.c + SRCS ${src_wifi_remote_weak} + ${src_wifi_remote_eppp} + ${src_wifi_is_remote} + PRIV_INCLUDE_DIRS eppp REQUIRES esp_event esp_netif - PRIV_REQUIRES esp_wifi) - -idf_component_optional_requires(PRIVATE esp_hosted) + PRIV_REQUIRES esp_wifi esp-tls) idf_component_get_property(wifi esp_wifi COMPONENT_LIB) target_link_libraries(${wifi} PUBLIC ${COMPONENT_LIB}) diff --git a/components/esp_wifi_remote/Kconfig b/components/esp_wifi_remote/Kconfig index c59c60db7..918e11bfa 100644 --- a/components/esp_wifi_remote/Kconfig +++ b/components/esp_wifi_remote/Kconfig @@ -5,6 +5,7 @@ menu "Wi-Fi Remote" default y orsource "./Kconfig.soc_wifi_caps.in" + orsource "./Kconfig.rpc.in" config ESP_WIFI_STATIC_RX_BUFFER_NUM int "Max number of WiFi static RX buffers" @@ -191,7 +192,7 @@ menu "Wi-Fi Remote" Set the size of WiFi Block Ack RX window. Generally a bigger value means higher throughput and better compatibility but more memory. Most of time we should NOT change the default value unless special reason, e.g. test the maximum UDP RX throughput with iperf etc. For iperf test in shieldbox, the - recommended value is 9~12. If PSRAM is used and WiFi memory is prefered to allocat in PSRAM first, + recommended value is 9~12. If PSRAM is used and WiFi memory is preferred to allocate in PSRAM first, the default and minimum value should be 16 to achieve better throughput and compatibility with both stations and APs. @@ -228,14 +229,14 @@ menu "Wi-Fi Remote" help ESP-MESH utilizes beacon frames to detect and resolve root node conflicts (see documentation). However the default length of a beacon frame can simultaneously hold only five root node identifier structures, - meaning that a root node conflict of up to five nodes can be detected at one time. In the occurence of + meaning that a root node conflict of up to five nodes can be detected at one time. In the occurrence of more root nodes conflict involving more than five root nodes, the conflict resolution process will detect five of the root nodes, resolve the conflict, and re-detect more root nodes. This process will repeat until all root node conflicts are resolved. However this process can generally take a very long time. To counter this situation, the beacon frame length can be increased such that more root nodes can be - detected simultaneously. Each additional root node will require 36 bytes and should be added ontop of + detected simultaneously. Each additional root node will require 36 bytes and should be added on top of the default beacon frame length of 752 bytes. For example, if you want to detect 10 root nodes simultaneously, you need to set the beacon frame length as @@ -487,9 +488,9 @@ menu "Wi-Fi Remote" help Select this option to use MbedTLS TLS client for WPA2 enterprise connection. Please note that from MbedTLS-3.0 onwards, MbedTLS does not support SSL-3.0 - TLS-v1.0, TLS-v1.1 versions. Incase your server is using one of these version, + TLS-v1.0, TLS-v1.1 versions. In case your server is using one of these version, it is advisable to update your server. - Please disable this option for compatibilty with older TLS versions. + Please disable this option for compatibility with older TLS versions. config ESP_WIFI_EAP_TLS1_3 bool "Enable EAP-TLS v1.3 Support for WiFi Enterprise connection" @@ -556,6 +557,26 @@ menu "Wi-Fi Remote" help Select this option to enable WiFi Multiband operation certification support. + config ESP_WIFI_ENABLE_ROAMING_APP + bool "Advanced support for Wi-Fi Roaming (Experimental)" + depends on IDF_EXPERIMENTAL_FEATURES + default n + select ESP_WIFI_SCAN_CACHE + help + Enable Espressif's roaming app to allow for efficient Wi-Fi roaming. + This includes configurable periodic environment scans, maintaining a cache of the + best APs, handling low rssi events etc. + + Risk Warning + Please note that this feature is still experimental and enabling this potentially can + lead to unpredictable scanning, connection and roaming attempts. + We are still working on tuning and optimising this feature to ensure reliable and stable use. + + menu "Configure roaming App" + depends on ESP_WIFI_ENABLE_ROAMING_APP + rsource "wifi_apps/roaming_app/src/Kconfig.roaming" + endmenu + config ESP_WIFI_DPP_SUPPORT bool "Enable DPP support" default n @@ -597,7 +618,7 @@ menu "Wi-Fi Remote" default n help Select this option to enable validate each WPS attribute - rigorously. Disabling this add the workaorunds with various APs. + rigorously. Disabling this add the workarounds with various APs. Enabling this may cause inter operability issues with some APs. config ESP_WIFI_WPS_PASSPHRASE @@ -605,9 +626,9 @@ menu "Wi-Fi Remote" default n help Select this option to get passphrase during WPS configuration. - This option fakes the virtual display capabilites to get the + This option fakes the virtual display capabilities to get the configuration in passphrase mode. - Not recommanded to be used since WPS credentials should not + Not recommended to be used since WPS credentials should not be shared to other devices, making it in readable format increases that risk, also passphrase requires pbkdf2 to convert in psk. diff --git a/components/esp_wifi_remote/Kconfig.rpc.in b/components/esp_wifi_remote/Kconfig.rpc.in new file mode 100644 index 000000000..204a40083 --- /dev/null +++ b/components/esp_wifi_remote/Kconfig.rpc.in @@ -0,0 +1,73 @@ +choice ESP_WIFI_REMOTE_LIBRARY + prompt "Choose WiFi-remote implementation" + default ESP_WIFI_REMOTE_LIBRARY_EPPP + help + Select type of WiFi Remote implementation + + ESP-HOSTED is the default and most versatile option. + It's also possible to use EPPP, which uses PPPoS link between micros and NAPT, so it's slower + and less universal. + + config ESP_WIFI_REMOTE_LIBRARY_HOSTED + bool "ESP-HOSTED" + config ESP_WIFI_REMOTE_LIBRARY_EPPP + bool "EPPP" +endchoice + + if ESP_WIFI_REMOTE_LIBRARY_EPPP + menu "WiFi remote by EPPP" + + choice ESP_WIFI_REMOTE_EPPP_TRANSPORT + prompt "Choose EPPP transport" + default ESP_WIFI_REMOTE_EPPP_TRANSPORT_UART + help + Select type of EPPP transport + + config ESP_WIFI_REMOTE_EPPP_TRANSPORT_UART + bool "UART" + config ESP_WIFI_REMOTE_EPPP_TRANSPORT_SPI + bool "SPI" + endchoice + + if ESP_WIFI_REMOTE_EPPP_TRANSPORT_UART + config ESP_WIFI_REMOTE_EPPP_UART_TX_PIN + int "TXD Pin Number" + default 10 + range 0 31 + help + Pin number of UART TX. + + config ESP_WIFI_REMOTE_EPPP_UART_RX_PIN + int "RXD Pin Number" + default 11 + range 0 31 + help + Pin number of UART RX. + endif + + config ESP_WIFI_REMOTE_EPPP_SERVER_CA + string "Servers CA certificate" + default "--- Please copy content of the CA certificate ---" + + config ESP_WIFI_REMOTE_EPPP_CLIENT_CRT + string "Client certificate" + default "--- Please copy content of the Client certificate ---" + + config ESP_WIFI_REMOTE_EPPP_CLIENT_KEY + string "Client key" + default "--- Please copy content of the Client key ---" + + config ESP_WIFI_REMOTE_EPPP_CLIENT_CA + string "Clients CA certificate" + default "--- Please copy content of the CA certificate ---" + + config ESP_WIFI_REMOTE_EPPP_SERVER_CRT + string "Server certificate" + default "--- Please copy content of the Client certificate ---" + + config ESP_WIFI_REMOTE_EPPP_SERVER_KEY + string "Server key" + default "--- Please copy content of the Client key ---" + endmenu + + endif diff --git a/components/esp_wifi_remote/Kconfig.soc_wifi_caps.in b/components/esp_wifi_remote/Kconfig.soc_wifi_caps.in index a0aee080a..1ec5de2b2 100644 --- a/components/esp_wifi_remote/Kconfig.soc_wifi_caps.in +++ b/components/esp_wifi_remote/Kconfig.soc_wifi_caps.in @@ -227,3 +227,11 @@ endif # ESP32C6 if SLAVE_IDF_TARGET_ESP32H2 endif # ESP32H2 + +if SLAVE_IDF_TARGET_ESP32P4 + + config SLAVE_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH + int + default 12 + +endif # ESP32P4 diff --git a/components/esp_wifi_remote/eppp/eppp_init.c b/components/esp_wifi_remote/eppp/eppp_init.c new file mode 100644 index 000000000..574ebfd2a --- /dev/null +++ b/components/esp_wifi_remote/eppp/eppp_init.c @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_log.h" +#include "esp_wifi.h" +#include "eppp_link.h" + +esp_netif_t *wifi_remote_eppp_init(eppp_type_t role) +{ + uint32_t our_ip = role == EPPP_SERVER ? EPPP_DEFAULT_SERVER_IP() : EPPP_DEFAULT_CLIENT_IP(); + uint32_t their_ip = role == EPPP_SERVER ? EPPP_DEFAULT_CLIENT_IP() : EPPP_DEFAULT_SERVER_IP(); + eppp_config_t config = EPPP_DEFAULT_CONFIG(our_ip, their_ip); +#if CONFIG_ESP_WIFI_REMOTE_EPPP_TRANSPORT_UART + config.transport = EPPP_TRANSPORT_UART; + config.uart.tx_io = CONFIG_ESP_WIFI_REMOTE_EPPP_UART_TX_PIN; + config.uart.rx_io = CONFIG_ESP_WIFI_REMOTE_EPPP_UART_RX_PIN; +#else +#error ESP_WIFI_REMOTE supports only UART transport +#endif + return eppp_open(role, &config, portMAX_DELAY); +} diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp b/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp new file mode 100644 index 000000000..2bbb76685 --- /dev/null +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_client.cpp @@ -0,0 +1,277 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "esp_log.h" +#include "esp_tls.h" +#include "esp_wifi.h" +#include "esp_check.h" +#include "wifi_remote_rpc_impl.hpp" +#include "eppp_link.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "wifi_remote_rpc_params.h" + +extern "C" esp_netif_t *wifi_remote_eppp_init(eppp_type_t role); + +namespace eppp_rpc { + +namespace client { +const char *TAG = "rpc_client"; + +const unsigned char ca_crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CA "\n-----END CERTIFICATE-----"; +const unsigned char crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CRT "\n-----END CERTIFICATE-----"; +const unsigned char key[] = "-----BEGIN RSA PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_KEY "\n-----END RSA PRIVATE KEY-----"; + +} + +using namespace client; + +struct Sync { + void lock() + { + xSemaphoreTake(mutex, portMAX_DELAY); + } + void unlock() + { + xSemaphoreGive(mutex); + } + esp_err_t init() + { + mutex = xSemaphoreCreateMutex(); + events = xEventGroupCreate(); + return mutex == nullptr || events == nullptr ? ESP_ERR_NO_MEM : ESP_OK; + } + esp_err_t wait_for(EventBits_t bits, uint32_t timeout = portMAX_DELAY) + { + return xEventGroupWaitBits(events, bits, pdTRUE, pdTRUE, timeout) == bits ? ESP_OK : ESP_FAIL; + } + esp_err_t notify(EventBits_t bits) + { + xEventGroupSetBits(events, bits); + return ESP_OK; + } + ~Sync() + { + if (mutex) { + vSemaphoreDelete(mutex); + } + if (events) { + vEventGroupDelete(events); + } + } + SemaphoreHandle_t mutex{nullptr}; + EventGroupHandle_t events{nullptr}; + const int request = 1; + const int resp_header = 2; + const int resp_payload = 4; + +}; + +class RpcInstance { +public: + template + esp_err_t send(api_id id, T *t) + { + ESP_RETURN_ON_ERROR(sync.notify(sync.request), TAG, "failed to notify req"); + pending_resp = id; + ESP_RETURN_ON_ERROR(rpc.send(id, t), TAG, "Failed to send request"); + return ESP_OK; + } + + // specialization for (void) + esp_err_t send(api_id id) + { + ESP_RETURN_ON_ERROR(sync.notify(sync.request), TAG, "failed to notify req"); + pending_resp = id; + ESP_RETURN_ON_ERROR(rpc.send(id), TAG, "Failed to send request"); + return ESP_OK; + } + + template + T get_resp(api_id id) + { + sync.wait_for(sync.resp_header); + auto ret = rpc.template get_payload(id, pending_header); + sync.notify(sync.resp_payload); + return ret; + } + esp_err_t init() + { + ESP_RETURN_ON_FALSE(netif = wifi_remote_eppp_init(EPPP_CLIENT), ESP_FAIL, TAG, "Failed to connect to EPPP server"); + ESP_RETURN_ON_ERROR(sync.init(), TAG, "Failed to init sync primitives"); + ESP_RETURN_ON_ERROR(rpc.init(), TAG, "Failed to init RPC engine"); + return xTaskCreate(task, "client", 8192, this, 5, nullptr) == pdTRUE ? ESP_OK : ESP_FAIL; + } + RpcEngine rpc{eppp_rpc::role::CLIENT}; + Sync sync; +private: + api_id pending_resp{api_id::UNDEF}; + RpcHeader pending_header{}; + esp_err_t process_ip_event(RpcHeader &header) + { + auto event = rpc.get_payload(api_id::IP_EVENT, header); + // Now bypass network layers with EPPP interface + ESP_RETURN_ON_ERROR(esp_netif_set_dns_info(netif, ESP_NETIF_DNS_MAIN, &event.dns), TAG, "Failed to set DNS info"); + ESP_RETURN_ON_ERROR(esp_netif_set_default_netif(netif), TAG, "Failed to set default netif to EPPP"); + ip_event_got_ip_t evt = { + .esp_netif = netif, + .ip_info = {}, + .ip_changed = true, + }; + esp_netif_get_ip_info(netif, &evt.ip_info); + ESP_RETURN_ON_ERROR(esp_event_post(IP_EVENT, IP_EVENT_STA_GOT_IP, &evt, sizeof(evt), 0), TAG, "Failed to post IP event"); + ESP_LOGI(TAG, "Main DNS:" IPSTR, IP2STR(&event.dns.ip.u_addr.ip4)); + ESP_LOGI(TAG, "EPPP IP:" IPSTR, IP2STR(&event.ppp_ip.ip)); + ESP_LOGI(TAG, "WIFI IP:" IPSTR, IP2STR(&event.wifi_ip.ip)); + ESP_LOGI(TAG, "WIFI GW:" IPSTR, IP2STR(&event.wifi_ip.gw)); + ESP_LOGI(TAG, "WIFI mask:" IPSTR, IP2STR(&event.wifi_ip.netmask)); + return ESP_OK; + } + esp_err_t process_wifi_event(RpcHeader &header) + { + auto event_id = rpc.get_payload(api_id::WIFI_EVENT, header); + ESP_RETURN_ON_ERROR(esp_event_post(WIFI_EVENT, event_id, nullptr, 0, 0), TAG, "Failed to post WiFi event"); + return ESP_OK; + } + esp_err_t perform() + { + auto header = rpc.get_header(); + if (api_id(header.id) == api_id::ERROR) { // network error + return ESP_FAIL; + } + if (api_id(header.id) == api_id::UNDEF) { // network timeout + return ESP_OK; + } + + if (api_id(header.id) == api_id::IP_EVENT) { + return process_ip_event(header); + } + if (api_id(header.id) == api_id::WIFI_EVENT) { + return process_wifi_event(header); + } + if (sync.wait_for(sync.request, 0) == ESP_OK && api_id(header.id) == pending_resp) { + pending_header = header; + pending_resp = api_id::UNDEF; + sync.notify(sync.resp_header); + sync.wait_for(sync.resp_payload); + return ESP_OK; + } + ESP_LOGE(TAG, "Unexpected header %" PRIi32, static_cast(header.id)); + return ESP_FAIL; + + } + static void task(void *ctx) + { + auto instance = static_cast(ctx); + while (instance->perform() == ESP_OK) {} + vTaskDelete(nullptr); + } + esp_netif_t *netif{nullptr}; +}; + + +namespace client { +RpcInstance instance; +} // namespace client + +RpcInstance *RpcEngine::init_client() +{ + char host[4 * 4 + 1] = {}; // IPv4: 4 x (3 numbers + '.') + \0 + esp_ip4_addr_t ip = { .addr = EPPP_DEFAULT_SERVER_IP() }; + if (esp_ip4addr_ntoa(&ip, host, sizeof(host)) == nullptr) { + return nullptr; + } + + esp_tls_cfg_t cfg = {}; + cfg.cacert_buf = client::ca_crt; + cfg.cacert_bytes = sizeof(client::ca_crt); + cfg.clientcert_buf = client::crt; + cfg.clientcert_bytes = sizeof(client::crt); + cfg.clientkey_buf = client::key; + cfg.clientkey_bytes = sizeof(client::key); + cfg.common_name = "espressif.local"; + + tls_ = esp_tls_init(); + if (!tls_) { + ESP_LOGE(TAG, "Failed to allocate esp_tls handle!"); + goto exit; + } + if (esp_tls_conn_new_sync(host, strlen(host), rpc_port, &cfg, tls_) <= 0) { + ESP_LOGE(TAG, "Failed to open a new connection %s", host); + goto exit; + } + return &client::instance; +exit: + esp_tls_conn_destroy(tls_); + tls_ = nullptr; + return nullptr; +} +} // namespace eppp_rpc + +// +// esp_wifi_remote API implementation +// +using namespace eppp_rpc; +using namespace client; + +extern "C" esp_err_t esp_wifi_remote_init(const wifi_init_config_t *config) +{ + // Here we initialize this client's RPC + ESP_RETURN_ON_ERROR(instance.init(), TAG, "Failed to initialize eppp-rpc"); + + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::INIT, config), TAG, "Failed to send request"); + return instance.get_resp(api_id::INIT); +} + +extern "C" esp_err_t esp_wifi_remote_set_config(wifi_interface_t interface, wifi_config_t *conf) +{ + esp_wifi_remote_config params = { .interface = interface, .conf = {} }; + memcpy(¶ms.conf, conf, sizeof(wifi_config_t)); + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::SET_CONFIG, ¶ms), TAG, "Failed to send request"); + return instance.get_resp(api_id::SET_CONFIG); +} + +extern "C" esp_err_t esp_wifi_remote_start(void) +{ + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::START), TAG, "Failed to send request"); + return instance.get_resp(api_id::START); +} + +extern "C" esp_err_t esp_wifi_remote_stop(void) +{ + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::STOP), TAG, "Failed to send request"); + return instance.get_resp(api_id::STOP); +} + +extern "C" esp_err_t esp_wifi_remote_connect(void) +{ + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::CONNECT), TAG, "Failed to send request"); + return instance.get_resp(api_id::CONNECT); +} + +extern "C" esp_err_t esp_wifi_remote_get_mac(wifi_interface_t ifx, uint8_t mac[6]) +{ + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::GET_MAC, &ifx), TAG, "Failed to send request"); + auto ret = instance.get_resp(api_id::GET_MAC); + ESP_LOG_BUFFER_HEXDUMP("MAC", ret.mac, 6, ESP_LOG_DEBUG); + memcpy(mac, ret.mac, 6); + return ret.err; +} + +extern "C" esp_err_t esp_wifi_remote_set_mode(wifi_mode_t mode) +{ + std::lock_guard lock(instance.sync); + ESP_RETURN_ON_ERROR(instance.send(api_id::SET_MODE, &mode), TAG, "Failed to send request"); + return instance.get_resp(api_id::SET_MODE); +} diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp b/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp new file mode 100644 index 000000000..beb87d407 --- /dev/null +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_impl.hpp @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include +#include + +namespace eppp_rpc { + +const int rpc_port = 3333; + +enum class api_id : uint32_t { + ERROR, + UNDEF, + INIT, + SET_MODE, + SET_CONFIG, + START, + STOP, + CONNECT, + GET_MAC, + WIFI_EVENT, + IP_EVENT, +}; + +enum class role { + SERVER, + CLIENT, +}; + +struct RpcHeader { + api_id id; + uint32_t size; +} __attribute((__packed__)); + +template +struct RpcData { + RpcHeader head; + T value_{}; + explicit RpcData(api_id id) : head{id, sizeof(T)} {} + + uint8_t *value() + { + return (uint8_t *) &value_; + } + + uint8_t *marshall(T *t, size_t &size) + { + size = head.size + sizeof(RpcHeader); + memcpy(value(), t, sizeof(T)); + return (uint8_t *) this; + } +} __attribute((__packed__)); + +class RpcInstance; + +class RpcEngine { +public: + explicit RpcEngine(role r) : tls_(nullptr), role_(r) {} + + esp_err_t init() + { + if (tls_ != nullptr) { + return ESP_OK; + } + if (role_ == role::CLIENT) { + instance = init_client(); + } + if (role_ == role::SERVER) { + instance = init_server(); + } + return instance == nullptr ? ESP_FAIL : ESP_OK; + } + + template + esp_err_t send(api_id id, T *t) + { + RpcData req(id); + size_t size; + auto buf = req.marshall(t, size); + ESP_LOGD("rpc", "Sending API id:%d", (int) id); + ESP_LOG_BUFFER_HEXDUMP("rpc", buf, size, ESP_LOG_VERBOSE); + int len = esp_tls_conn_write(tls_, buf, size); + if (len <= 0) { + ESP_LOGE("rpc", "Failed to write data to the connection"); + return ESP_FAIL; + } + return ESP_OK; + } + + esp_err_t send(api_id id) // specialization for (void) + { + RpcHeader head = {.id = id, .size = 0}; + int len = esp_tls_conn_write(tls_, &head, sizeof(head)); + if (len <= 0) { + ESP_LOGE("rpc", "Failed to write data to the connection"); + return ESP_FAIL; + } + return ESP_OK; + } + + RpcHeader get_header() + { + RpcHeader header{}; + int len = esp_tls_conn_read(tls_, (char *) &header, sizeof(header)); + if (len <= 0) { + if (len < 0 && errno != EAGAIN) { + ESP_LOGE("rpc", "Failed to read header data from the connection %d %s", errno, strerror(errno)); + return {.id = api_id::ERROR, .size = 0}; + } + return {.id = api_id::UNDEF, .size = 0}; + } + return header; + } + + template + T get_payload(api_id id, RpcHeader &head) + { + RpcData resp(id); + if (head.id != id || head.size != resp.head.size) { + ESP_LOGE("rpc", "unexpected header %d %d or sizes %" PRIu32 " %" PRIu32, (int)head.id, (int)id, head.size, resp.head.size); + return {}; + } + int len = esp_tls_conn_read(tls_, (char *) resp.value(), resp.head.size); + if (len <= 0) { + ESP_LOGE("rpc", "Failed to read data from the connection"); + return {}; + } + return resp.value_; + } + +private: + RpcInstance *init_server(); + RpcInstance *init_client(); + esp_tls_t *tls_; + role role_; + RpcInstance *instance{nullptr}; +}; + +}; diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_params.h b/components/esp_wifi_remote/eppp/wifi_remote_rpc_params.h new file mode 100644 index 000000000..402308fab --- /dev/null +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_params.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +struct esp_wifi_remote_config { + wifi_interface_t interface; + wifi_config_t conf; +}; + +struct esp_wifi_remote_mac_t { + esp_err_t err; + uint8_t mac[6]; +}; + +struct esp_wifi_remote_eppp_ip_event { + uint32_t id; + esp_netif_ip_info_t wifi_ip; + esp_netif_ip_info_t ppp_ip; + esp_netif_dns_info_t dns; +}; diff --git a/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp b/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp new file mode 100644 index 000000000..aed9faa54 --- /dev/null +++ b/components/esp_wifi_remote/eppp/wifi_remote_rpc_server.cpp @@ -0,0 +1,209 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include "esp_log.h" +#include "esp_check.h" +#include "esp_tls.h" +#include "esp_wifi.h" +#include "wifi_remote_rpc_impl.hpp" +#include "eppp_link.h" +#include "wifi_remote_rpc_params.h" +#include "lwip/apps/snmp.h" + +extern "C" esp_netif_t *wifi_remote_eppp_init(eppp_type_t role); + +namespace eppp_rpc { + +namespace server { +const char *TAG = "rpc_server"; + +const unsigned char ca_crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CA "\n-----END CERTIFICATE-----"; +const unsigned char crt[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CRT "\n-----END CERTIFICATE-----"; +const unsigned char key[] = "-----BEGIN RSA PRIVATE KEY-----\n" CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_KEY "\n-----END RSA PRIVATE KEY-----"; + +} + +using namespace server; + +class RpcInstance { +public: + RpcEngine rpc{role::SERVER}; + int sock{-1}; + + esp_err_t init() + { + ESP_RETURN_ON_FALSE(netif = wifi_remote_eppp_init(EPPP_SERVER), ESP_FAIL, TAG, "Failed to init EPPP connection"); + ESP_RETURN_ON_ERROR(start_server(), TAG, "Failed to start RPC server"); + ESP_RETURN_ON_ERROR(rpc.init(), TAG, "Failed to init RPC engine"); + ESP_RETURN_ON_ERROR(esp_netif_napt_enable(netif), TAG, "Failed to enable NAPT"); + ESP_RETURN_ON_ERROR(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, handler, this), TAG, "Failed to register event"); + ESP_RETURN_ON_ERROR(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, handler, this), TAG, "Failed to register event"); + return xTaskCreate(task, "server", 8192, this, 5, nullptr) == pdTRUE ? ESP_OK : ESP_FAIL; + } + +private: + esp_netif_t *netif{nullptr}; + static void task(void *ctx) + { + auto instance = static_cast(ctx); + while (instance->perform() == ESP_OK) {} + vTaskDelete(nullptr); + } + esp_err_t start_server() + { + struct sockaddr_in dest_addr = {}; + int ret; + int opt = 1; + dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(rpc_port); + int listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + ESP_RETURN_ON_FALSE(listen_sock >= 0, ESP_FAIL, TAG, "Failed to create listening socket"); + setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + ret = bind(listen_sock, (struct sockaddr *) &dest_addr, sizeof(dest_addr)); + ESP_RETURN_ON_FALSE(ret == 0, ESP_FAIL, TAG, "Failed to bind the listening socket"); + ret = listen(listen_sock, 1); + ESP_RETURN_ON_FALSE(ret == 0, ESP_FAIL, TAG, "Failed to start listening"); + struct sockaddr_storage source_addr {}; + socklen_t addr_len = sizeof(source_addr); + sock = accept(listen_sock, (struct sockaddr *) &source_addr, &addr_len); + ESP_RETURN_ON_FALSE(sock >= 0, ESP_FAIL, TAG, "Failed to accept connections: errno %d", errno); + ESP_LOGI(TAG, "Socket accepted on: %s", inet_ntoa(((struct sockaddr_in *) &source_addr)->sin_addr)); + return ESP_OK; + } + esp_err_t wifi_event(int32_t id) + { + ESP_LOGI(TAG, "Received WIFI event %" PRIi32, id); + ESP_RETURN_ON_ERROR(rpc.send(api_id::WIFI_EVENT, &id), TAG, "Failed to marshall WiFi event"); + return ESP_OK; + } + esp_err_t ip_event(int32_t id, ip_event_got_ip_t *ip_data) + { + ESP_LOGI(TAG, "Received IP event %" PRIi32, id); + esp_wifi_remote_eppp_ip_event ip_event{}; + ip_event.id = id; + if (ip_data->esp_netif) { + // marshall additional data, only if netif available + ESP_RETURN_ON_ERROR(esp_netif_get_dns_info(ip_data->esp_netif, ESP_NETIF_DNS_MAIN, &ip_event.dns), TAG, "Failed to get DNS info"); + ESP_LOGI(TAG, "Main DNS:" IPSTR, IP2STR(&ip_event.dns.ip.u_addr.ip4)); + memcpy(&ip_event.wifi_ip, &ip_data->ip_info, sizeof(ip_event.wifi_ip)); + ESP_RETURN_ON_ERROR(esp_netif_get_ip_info(netif, &ip_event.ppp_ip), TAG, "Failed to get IP info"); + ESP_LOGI(TAG, "IP address:" IPSTR, IP2STR(&ip_data->ip_info.ip)); + } + ESP_RETURN_ON_ERROR(rpc.send(api_id::IP_EVENT, &ip_event), TAG, "Failed to marshal IP event"); + return ESP_OK; + } + static void handler(void *ctx, esp_event_base_t base, int32_t id, void *data) + { + auto instance = static_cast(ctx); + if (base == WIFI_EVENT) { + instance->wifi_event(id); + } else if (base == IP_EVENT) { + auto *ip_data = (ip_event_got_ip_t *)data; + instance->ip_event(id, ip_data); + } + } + esp_err_t perform() + { + auto header = rpc.get_header(); + ESP_LOGI(TAG, "Received header id %d", (int) header.id); + + switch (header.id) { + case api_id::SET_MODE: { + auto req = rpc.get_payload(api_id::SET_MODE, header); + auto ret = esp_wifi_set_mode(req); + if (rpc.send(api_id::SET_MODE, &ret) != ESP_OK) { + return ESP_FAIL; + } + break; + } + case api_id::INIT: { + auto req = rpc.get_payload(api_id::INIT, header); + req.osi_funcs = &g_wifi_osi_funcs; + req.wpa_crypto_funcs = g_wifi_default_wpa_crypto_funcs; + auto ret = esp_wifi_init(&req); + if (rpc.send(api_id::INIT, &ret) != ESP_OK) { + return ESP_FAIL; + } + break; + } + case api_id::SET_CONFIG: { + auto req = rpc.get_payload(api_id::SET_CONFIG, header); + auto ret = esp_wifi_set_config(req.interface, &req.conf); + if (rpc.send(api_id::SET_CONFIG, &ret) != ESP_OK) { + return ESP_FAIL; + } + break; + } + case api_id::START: { + if (header.size != 0) { + return ESP_FAIL; + } + + auto ret = esp_wifi_start(); + if (rpc.send(api_id::START, &ret) != ESP_OK) { + return ESP_FAIL; + } + break; + } + case api_id::CONNECT: { + if (header.size != 0) { + return ESP_FAIL; + } + + auto ret = esp_wifi_connect(); + if (rpc.send(api_id::CONNECT, &ret) != ESP_OK) { + return ESP_FAIL; + } + break; + } + case api_id::GET_MAC: { + auto req = rpc.get_payload(api_id::GET_MAC, header); + esp_wifi_remote_mac_t resp = {}; + resp.err = esp_wifi_get_mac(req, resp.mac); + if (rpc.send(api_id::GET_MAC, &resp) != ESP_OK) { + return ESP_FAIL; + } + break; + } + default: + return ESP_FAIL; + } + return ESP_OK; + } +}; + + +namespace server { +RpcInstance instance; +} + +RpcInstance *RpcEngine::init_server() +{ + esp_tls_cfg_server_t cfg = {}; + cfg.cacert_buf = server::ca_crt; + cfg.cacert_bytes = sizeof(server::ca_crt); + cfg.servercert_buf = server::crt; + cfg.servercert_bytes = sizeof(server::crt); + cfg.serverkey_buf = server::key; + cfg.serverkey_bytes = sizeof(server::key); + + ESP_RETURN_ON_FALSE(tls_ = esp_tls_init(), nullptr, TAG, "Failed to create ESP-TLS instance"); + ESP_RETURN_ON_FALSE(esp_tls_server_session_create(&cfg, server::instance.sock, tls_) == ESP_OK, nullptr, TAG, "Failed to create TLS session"); + return &server::instance; +} + +} // namespace eppp_rpc + +using namespace eppp_rpc; + +extern "C" esp_err_t server_init(void) +{ + return server::instance.init(); +} diff --git a/components/esp_wifi_remote/esp_wifi_remote_weak.c b/components/esp_wifi_remote/esp_wifi_remote_weak.c index 3bee295c0..e78732119 100644 --- a/components/esp_wifi_remote/esp_wifi_remote_weak.c +++ b/components/esp_wifi_remote/esp_wifi_remote_weak.c @@ -271,26 +271,6 @@ WEAK esp_err_t esp_wifi_remote_set_csi(_Bool en) LOG_UNSUPPORTED_AND_RETURN(ESP_ERR_NOT_SUPPORTED); } -WEAK esp_err_t esp_wifi_remote_set_ant_gpio(const wifi_ant_gpio_config_t *config) -{ - LOG_UNSUPPORTED_AND_RETURN(ESP_ERR_NOT_SUPPORTED); -} - -WEAK esp_err_t esp_wifi_remote_get_ant_gpio(wifi_ant_gpio_config_t *config) -{ - LOG_UNSUPPORTED_AND_RETURN(ESP_ERR_NOT_SUPPORTED); -} - -WEAK esp_err_t esp_wifi_remote_set_ant(const wifi_ant_config_t *config) -{ - LOG_UNSUPPORTED_AND_RETURN(ESP_ERR_NOT_SUPPORTED); -} - -WEAK esp_err_t esp_wifi_remote_get_ant(wifi_ant_config_t *config) -{ - LOG_UNSUPPORTED_AND_RETURN(ESP_ERR_NOT_SUPPORTED); -} - WEAK int64_t esp_wifi_remote_get_tsf_time(wifi_interface_t interface) { LOG_UNSUPPORTED_AND_RETURN(-1); diff --git a/components/esp_wifi_remote/esp_wifi_with_remote.c b/components/esp_wifi_remote/esp_wifi_with_remote.c index 66b202fc9..c78aaf966 100644 --- a/components/esp_wifi_remote/esp_wifi_with_remote.c +++ b/components/esp_wifi_remote/esp_wifi_with_remote.c @@ -267,26 +267,6 @@ esp_err_t esp_wifi_set_csi(_Bool en) return esp_wifi_remote_set_csi(en); } -esp_err_t esp_wifi_set_ant_gpio(const wifi_ant_gpio_config_t *config) -{ - return esp_wifi_remote_set_ant_gpio(config); -} - -esp_err_t esp_wifi_get_ant_gpio(wifi_ant_gpio_config_t *config) -{ - return esp_wifi_remote_get_ant_gpio(config); -} - -esp_err_t esp_wifi_set_ant(const wifi_ant_config_t *config) -{ - return esp_wifi_remote_set_ant(config); -} - -esp_err_t esp_wifi_get_ant(wifi_ant_config_t *config) -{ - return esp_wifi_remote_get_ant(config); -} - int64_t esp_wifi_get_tsf_time(wifi_interface_t interface) { return esp_wifi_remote_get_tsf_time(interface); diff --git a/components/esp_wifi_remote/examples/mqtt/CMakeLists.txt b/components/esp_wifi_remote/examples/mqtt/CMakeLists.txt new file mode 100644 index 000000000..b07caaa52 --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/CMakeLists.txt @@ -0,0 +1,23 @@ +# This project serves as a demo to enable using esp-mqtt on ESP platform targets as well as on linux +cmake_minimum_required(VERSION 3.16) + +if("${IDF_TARGET}" STREQUAL "linux") +# For linux-target we have two options: +# - With lwIP (must be defined on command line, e.g. idf.py -DWITH_LWIP=1) +# access networking from linux `tap` interface (TAP networking mode) +# - Without lwIP (must be defined on command line, e.g. idf.py -DWITH_LWIP=0) +# no designated interface, accesses user network via linux/socket sys calls + if(WITH_LWIP STREQUAL 1) + set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_tapif_io + "../../common_components/linux_compat/esp_timer") + set(COMPONENTS main esp_netif lwip protocol_examples_tapif_io startup esp_hw_support esp_system nvs_flash mqtt esp_timer) + else() + list(APPEND EXTRA_COMPONENT_DIRS + "../../common_components/linux_compat/esp_timer" + "$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs") + set(COMPONENTS main nvs_flash esp-tls esp_stubs mqtt protocol_examples_common esp_timer) + endif() +endif() + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(esp_mqtt_demo) diff --git a/components/esp_wifi_remote/examples/mqtt/README.md b/components/esp_wifi_remote/examples/mqtt/README.md new file mode 100644 index 000000000..acf680b75 --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/README.md @@ -0,0 +1,41 @@ +# MQTT demo application that runs on linux + +## Overview + +This is a simple example demonstrating connecting to an MQTT broker, subscribing and publishing some data. +This example uses IDF build system and could be configured to be build and executed: +* for any ESP32 family chip +* for linux target + +## How to use example + +### Hardware Required + +To run this example, you need any ESP32 development board or just PC/virtual machine/container running linux operating system. + +### Host build modes + +Linux build is supported in these two modes: +* `WITH_LWIP=0`: Without lwIP component. The project uses linux BSD socket interface to interact with TCP/IP stack. There's no connection phase, we use the host network as users. This mode is often referred to as user-side networking. +* `WITH_LWIP=1`: Including lwIP component, which is added to the list of required components and compiled on host. In this mode, we have to map the host network (linux TCP/IP stack) to the target network (lwip). We use IDF's [`tapif_io`](https://github.com/espressif/esp-idf/tree/master/examples/common_components/protocol_examples_tapif_io) component to create a network interface, which will be used to pass packets to and from the simulated target. Please refer to the [README](https://github.com/espressif/esp-idf/tree/master/examples/common_components/protocol_examples_tapif_io#readme) for more details about the host side networking. + +### Building on linux + +1) Configure linux target +```bash +idf.py --preview set-target linux +``` + +2) Build the project with preferred components (with or without lwip) +```bash +idf.py -DWITH_LWIP=0 build # Building without lwip (user networking) +idf.py -DWITH_LWIP=1 build # Building with lwip (TAP networking) +``` + +3) Run the project + +It is possible to run the project elf file directly, or using `idf.py` monitor target (no need to flash): +```bash +idf.py monitor +``` +idf.py -DWITH_LWIP=0 build # Building without lwip (user networking) diff --git a/components/esp_wifi_remote/examples/mqtt/main/CMakeLists.txt b/components/esp_wifi_remote/examples/mqtt/main/CMakeLists.txt new file mode 100644 index 000000000..d6e9824b8 --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "app_main.c" + INCLUDE_DIRS ".") + +target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_wifi_remote/examples/mqtt/main/Kconfig.projbuild b/components/esp_wifi_remote/examples/mqtt/main/Kconfig.projbuild new file mode 100644 index 000000000..7ad4dc25e --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/main/Kconfig.projbuild @@ -0,0 +1,21 @@ +menu "Example Configuration" + + config BROKER_URL + string "Broker URL" + default "mqtt://mqtt.eclipseprojects.io" + help + URL of the broker to connect to + + config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + +endmenu diff --git a/components/esp_wifi_remote/examples/mqtt/main/app_main.c b/components/esp_wifi_remote/examples/mqtt/main/app_main.c new file mode 100644 index 000000000..07b60abdf --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/main/app_main.c @@ -0,0 +1,204 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include +#include +#include "esp_system.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_netif.h" +#include "esp_netif.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" + +#include "esp_log.h" +#include "mqtt_client.h" + +static const char *TAG = "esp_mqtt_demo"; +static EventGroupHandle_t s_wifi_event_group; +static int s_retry_num = 0; + +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define EXAMPLE_ESP_MAXIMUM_RETRY 5 + +static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) +{ + ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id); + esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data; + esp_mqtt_client_handle_t client = event->client; + int msg_id; + switch ((esp_mqtt_event_id_t)event_id) { + case MQTT_EVENT_CONNECTED: + ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); + msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0); + ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); + + msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0); + ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); + + msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1); + ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); + + msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1"); + ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id); + break; + case MQTT_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); + break; + + case MQTT_EVENT_SUBSCRIBED: + ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); + msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0); + ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); + break; + case MQTT_EVENT_UNSUBSCRIBED: + ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); + break; + case MQTT_EVENT_PUBLISHED: + ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); + break; + case MQTT_EVENT_DATA: + ESP_LOGI(TAG, "MQTT_EVENT_DATA"); + printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); + printf("DATA=%.*s\r\n", event->data_len, event->data); + break; + case MQTT_EVENT_ERROR: + ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); + break; + default: + ESP_LOGI(TAG, "Other event id:%d", event->event_id); + break; + } +} + +static void mqtt_app_start(void) +{ + esp_mqtt_client_config_t mqtt_cfg = {}; + mqtt_cfg.broker.address.uri = CONFIG_BROKER_URL; + mqtt_cfg.credentials.client_id = "idf_on_linux_client"; + + esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); + /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */ + esp_mqtt_client_register_event(client, (esp_mqtt_event_id_t)ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); + esp_mqtt_client_start(client); +} + +static void event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "EVENT type %s id %d", event_base, (int)event_id); + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(TAG, "connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data; + ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +static void wifi_init_sta() +{ + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_ESP_WIFI_SSID, + .password = EXAMPLE_ESP_WIFI_PASS, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start() ); + + ESP_LOGI(TAG, "wifi_init_sta finished."); + + /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum + * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_CONNECTED_BIT) { + ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } +} + +void app_main(void) +{ + ESP_LOGI(TAG, "[APP] Startup.."); + ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); + ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); + + esp_log_level_set("*", ESP_LOG_INFO); + esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE); + esp_log_level_set("esp_mqtt_demo", ESP_LOG_VERBOSE); + esp_log_level_set("transport_base", ESP_LOG_VERBOSE); + esp_log_level_set("esp-tls", ESP_LOG_VERBOSE); + esp_log_level_set("transport", ESP_LOG_VERBOSE); + esp_log_level_set("outbox", ESP_LOG_VERBOSE); + + //Initialize NVS + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); + wifi_init_sta(); + + mqtt_app_start(); +} diff --git a/components/esp_wifi_remote/examples/mqtt/main/idf_component.yml b/components/esp_wifi_remote/examples/mqtt/main/idf_component.yml new file mode 100644 index 000000000..22d411780 --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/main/idf_component.yml @@ -0,0 +1,5 @@ +dependencies: + espressif/eppp_link: "^0.0.1" + esp_wifi_remote: + version: "*" + override_path: ../../.. diff --git a/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults b/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults new file mode 100644 index 000000000..68c4ddef0 --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults @@ -0,0 +1,9 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.3.0 Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32p4" +CONFIG_LWIP_PPP_SUPPORT=y +CONFIG_LWIP_PPP_SERVER_SUPPORT=y +CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n +CONFIG_ESP_WIFI_REMOTE_EPPP_UART_TX_PIN=17 +CONFIG_ESP_WIFI_REMOTE_EPPP_UART_RX_PIN=16 diff --git a/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults.esp32h2 b/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults.esp32h2 new file mode 100644 index 000000000..26ce34bdd --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults.esp32h2 @@ -0,0 +1,3 @@ +CONFIG_IDF_TARGET="esp32h2" +CONFIG_EXAMPLE_CONNECT_WIFI=n +CONFIG_EXAMPLE_CONNECT_ETHERNET=y diff --git a/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults.linux b/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults.linux new file mode 100644 index 000000000..75186ee56 --- /dev/null +++ b/components/esp_wifi_remote/examples/mqtt/sdkconfig.defaults.linux @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="linux" +# CONFIG_ESP_EVENT_POST_FROM_ISR is not set diff --git a/components/esp_wifi_remote/examples/server/CMakeLists.txt b/components/esp_wifi_remote/examples/server/CMakeLists.txt new file mode 100644 index 000000000..144b9e1a2 --- /dev/null +++ b/components/esp_wifi_remote/examples/server/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(pppos_slave) diff --git a/components/esp_wifi_remote/examples/server/README.md b/components/esp_wifi_remote/examples/server/README.md new file mode 100644 index 000000000..a8ff85f9f --- /dev/null +++ b/components/esp_wifi_remote/examples/server/README.md @@ -0,0 +1,7 @@ + +# Wi-Fi station to PPPoS server + +This example demonstrate using NAPT to bring connectivity from WiFi station to PPPoS server. + +This example expect a PPPoS client to connect to the server and use the connectivity. +The client could be a Linux computer with `pppd` service or another microcontroller with PPP client (or another ESP32 with not WiFi interface) diff --git a/components/esp_wifi_remote/examples/server/main/CMakeLists.txt b/components/esp_wifi_remote/examples/server/main/CMakeLists.txt new file mode 100644 index 000000000..2ba044442 --- /dev/null +++ b/components/esp_wifi_remote/examples/server/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "station_example_main.c" + INCLUDE_DIRS ".") diff --git a/components/esp_wifi_remote/examples/server/main/idf_component.yml b/components/esp_wifi_remote/examples/server/main/idf_component.yml new file mode 100644 index 000000000..22d411780 --- /dev/null +++ b/components/esp_wifi_remote/examples/server/main/idf_component.yml @@ -0,0 +1,5 @@ +dependencies: + espressif/eppp_link: "^0.0.1" + esp_wifi_remote: + version: "*" + override_path: ../../.. diff --git a/components/esp_wifi_remote/examples/server/main/station_example_main.c b/components/esp_wifi_remote/examples/server/main/station_example_main.c new file mode 100644 index 000000000..93516d3ca --- /dev/null +++ b/components/esp_wifi_remote/examples/server/main/station_example_main.c @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "eppp_link.h" +#include "esp_wifi_remote.h" + +esp_err_t server_init(void); + +void app_main(void) +{ + //Initialize NVS + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + server_init(); +} diff --git a/components/esp_wifi_remote/examples/server/sdkconfig.defaults b/components/esp_wifi_remote/examples/server/sdkconfig.defaults new file mode 100644 index 000000000..5aafc155a --- /dev/null +++ b/components/esp_wifi_remote/examples/server/sdkconfig.defaults @@ -0,0 +1,15 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.3.0 Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32c6" +CONFIG_LWIP_IP_FORWARD=y +CONFIG_LWIP_IPV4_NAPT=y +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096 +CONFIG_LWIP_PPP_SUPPORT=y +CONFIG_LWIP_PPP_SERVER_SUPPORT=y +CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION=n +CONFIG_ESP_WIFI_REMOTE_EPPP_UART_TX_PIN=22 +CONFIG_ESP_WIFI_REMOTE_EPPP_UART_RX_PIN=23 +CONFIG_ESP_WIFI_REMOTE_EPPP_CLIENT_CA="MIIDIzCCAgugAwIBAgIUTWOEAhITHAm2ixn5i2XlSeL01mowDQYJKoZIhvcNAQELBQAwITELMAkGA1UEBhMCQ1oxEjAQBgNVBAMMCUVzcHJlc3NpZjAeFw0yNDA0MTAxNTEzNTdaFw0yNTA0MTAxNTEzNTdaMCExCzAJBgNVBAYTAkNaMRIwEAYDVQQDDAlFc3ByZXNzaWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCSewupiSiyZNfLdVW0/smQB0yJ0Ua0KNU423ZZ7HMSrBPhfHtnQQ6SJqTdfqGCl1lvSsJZN9aT4iaEtyAm6N9trmSbSWVlkn0D8MQuBHwHCT7jRsLnyRYURRPUs11TkQdqvxtsIFqFVFB/8nJqy4IuU6JFTobCbUappQMdHKCyidXJUVHZ5y+KK2kEYFiv26rHlry+D0O/VO5/xl97uFIzP0JVdnGNu5sy9uoRYp+ua0moD3tx12tYe83XIuHKbKHMpIayjPIoaZzhCwomZMh0NETEQ5t7RXYneRGZvXXyIb/O8jPCmbfSqJ6umhPhf757xBXHaC0iG/xlND0dnRIvAgMBAAGjUzBRMB0GA1UdDgQWBBTgqejeFi/5UAgNhNv4aH7UniqmQjAfBgNVHSMEGDAWgBTgqejeFi/5UAgNhNv4aH7UniqmQjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQnqIue6KLXkjOXGtO5Bl4TkZpYAPkQuGiM6RgaBhdt3P5J1mF4T6aav8qGXSHShy1E3XkMR5OC3hkhG+FKBVKSaQLsRipuo+CeHp5RfOCNEzNI0RZwKJI92RcdWlhOA+pOTruXSoYuZvj0xnaePEghTrr7PLdgirpzIffLjvgh8BcQAz5QzP0U1XHkAVzbQjUBChiEiXVAlKChk7kKB/wEzwX3cvYKlTc89RB6I3+a+KhYJt3LIAOIDeyVp+Bhmb1JSo3H7zMpJAksG2RMnZCwlHeR6cMbb/OtJYeUKpNUxj0SaeNyHo3y8Q21G8TXcc9suU6sYJi780ArulC3cbQ" +CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_CRT="MIICvzCCAacCFCanehvaDq0bhjZA/3W/h4b0p1VHMA0GCSqGSIb3DQEBCwUAMCExCzAJBgNVBAYTAkNaMRIwEAYDVQQDDAlFc3ByZXNzaWYwHhcNMjQwNDEwMTUxMzU3WhcNMjUwNDEwMTUxMzU3WjAXMRUwEwYDVQQDDAwxOTIuMTY4LjExLjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsyR1FqBhBT3mr9AH/6iYoo1VCHbzB+V/StfCokv6LnMm6t7yiu1GgzqVk1aiHrUJGor5tBfpXywLnfVjFByZSBhhEkI26xQVdK5pZUsU1hMCJ6CWd105CD+0e5tTbGzF0PNH2KzFdg2YUqOSWBsfmgSNtnp3az8XmZN5i4958Sxe1kMN3f6EQwvkxZHGVgXCrUsdsHAEyV5NVfYq7P2nBxz3HJSGkTScFd+PRp3nfVFbBbCQDmqwoPZ7E/gUXjoLIFf7zjIMzCXTsZd/dKgXWWEFHq8SPWmLtAEvPCProT5QUaZ3gJSHup9Wmh+ok9W8wrwMj1sHlfiZWo3tatFmvAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAeWiWyTTyNbZRHq8X9qbr7oG6SYWOqDR3lPfs8wB8B+1Hez/JCrI/8quNqVAjhoTtebtp/2mcEseQDj5BOx8NBCDAmUOwB+ZKPzUoGiALy5XFGqUXzTv9tBMotC6dAMTIbT2Ql1mPJgtg2+Qv7vg6hsk4rlPMoICqN3lW6zXo2GOuJ56Tj5NkvVxv6MOVN2e3p67c92rRBysAxP6MaV8S9s2+VvnENuxpU5cq8sfzaxFkTn4UD9PoQSYGPNL9kv7Y/h7H5wlKiFY24KowPTHjulaH/DC9Fk4F1gNWjnkFcOgepzhiw/ibLrivMptUFtplFFbxGuwY5PaA26yhliBv8=" +CONFIG_ESP_WIFI_REMOTE_EPPP_SERVER_KEY="MIIEowIBAAKCAQEArMkdRagYQU95q/QB/+omKKNVQh28wflf0rXwqJL+i5zJure8ortRoM6lZNWoh61CRqK+bQX6V8sC531YxQcmUgYYRJCNusUFXSuaWVLFNYTAieglnddOQg/tHubU2xsxdDzR9isxXYNmFKjklgbH5oEjbZ6d2s/F5mTeYuPefEsXtZDDd3+hEML5MWRxlYFwq1LHbBwBMleTVX2Kuz9pwcc9xyUhpE0nBXfj0ad531RWwWwkA5qsKD2exP4FF46CyBX+84yDMwl07GXf3SoF1lhBR6vEj1pi7QBLzwj66E+UFGmd4CUh7qfVpofqJPVvMK8DI9bB5X4mVqN7WrRZrwIDAQABAoIBAHDh833OlAoXIiZ1A9lt4AAstUa8ptUTVscSlmeLoUEU7bZO0659MpccanG2JKR/TQ1YxY/0l9lDiGI0Qgp24VI1KSWiSvX6Qcbc9bnlmXGdiSyPvgOg5j/Cp+fIZse+vFB0a7eoAFhXwBk/PhfF1lOBiuPS/M43b9NVkvSIapJIaS4pvmkBvKSzHEvSArDHcr+1vFuFssZyHTnXmVgB4WiYPX4ACE8S18cnjXIQDfx8zpBbF/itnqeHDC5echnto63UDB7qHZa+DVvakhEtv50rzAuhq3/uspBClucuQUhlAAimd4OeKuwB1UC0K9AamDZRCnsf0O/Bo8/W4SWYAgECgYEA5LpRmcQ9ghW8V6bzwYvK8XGWyeNy94qOpZysFeOjxqe2sUTHVY2Ty1s44RbDd/bm0n3xcxMtLof/6Oz4TX+JseskQWBQlRiwuqc46CcHHjUQ8qokfWtASwWYgb6AzLa4B/D+H91wP/AzRfYNdRB9xhSCr7AOk9Vo5KmEPRLN/VMCgYEAwWM3oDaCkMicoMgngz/9dZ2/1yohfYdrupC0pGPhtBFNKghP+9S+e6cwWKzwQJbbRjGgt1OA3e4UEuTHJjp1tw+BRkNQ/1FI0psJGwmOtveAE7yiHf7Tw7mNDk+j32vpAPWnL7I3222Kv4G8xi2vSbn3IaI2sl7M0RHLJc/JCrUCgYBh4dI16aMg3khhglLiSv6oYKHU9/8lLChreyaxn19hDjjCl9puJE5RQlKPEPzJg+G3xqnjQxucxBqiBXclQyUb/LLhP2R8ybonxpQ11S3YoYEFOAaxnYpAEL75Fxtrf+41h85YuJzm39YxZGDR7iLE99YNdVxnq3ZeFKVAtaFtfQKBgEalPRvc7eOANZ+SnsSWqru9regnLubRgqw70pG/HyONsnepY7amaBN55vJt8rJVqbLBzGlMKuZn45NnWc0ATCJcmqgVTVCH3Cd7lV74Jdd3IKWVIk/82FVGwl25AC9NF2hPVQzaeQdCxA3jkhd/dupi8gGqZXrRoNa7PlAI0POFAoGBAJDlvddpEYcKhT3pncXIorVfYR67TlXVcKZHvL9XljwgDuf1j52ZhAs8UuoWW+NSgOdWVxocAshrLbu5fjSIN92oDAq6YVeXvxis6e8l79xd6A5iFH9Po+dEuQSaOR8XgW56n39oVR2hfaFwqijawIEzDNlYpiXAD3qNyW5e0MKA" diff --git a/components/esp_wifi_remote/idf_component.yml b/components/esp_wifi_remote/idf_component.yml index 8ef35fc4a..9acde64a7 100644 --- a/components/esp_wifi_remote/idf_component.yml +++ b/components/esp_wifi_remote/idf_component.yml @@ -2,6 +2,8 @@ version: 0.1.12 url: https://github.com/espressif/esp-protocols/tree/master/components/esp_wifi_remote description: Utility wrapper for esp_wifi functionality on remote targets dependencies: + espressif/eppp_link: + version: '0.0.1' idf: version: '5.3' # espressif/esp_hosted: diff --git a/components/esp_wifi_remote/include/esp_wifi_remote_api.h b/components/esp_wifi_remote/include/esp_wifi_remote_api.h index 420aa5e7e..2ddcd7ee2 100644 --- a/components/esp_wifi_remote/include/esp_wifi_remote_api.h +++ b/components/esp_wifi_remote/include/esp_wifi_remote_api.h @@ -57,10 +57,6 @@ esp_err_t esp_wifi_remote_80211_tx(wifi_interface_t ifx, const void *buffer, int esp_err_t esp_wifi_remote_set_csi_rx_cb(wifi_csi_cb_t cb, void *ctx); esp_err_t esp_wifi_remote_set_csi_config(const wifi_csi_config_t *config); esp_err_t esp_wifi_remote_set_csi(_Bool en); -esp_err_t esp_wifi_remote_set_ant_gpio(const wifi_ant_gpio_config_t *config); -esp_err_t esp_wifi_remote_get_ant_gpio(wifi_ant_gpio_config_t *config); -esp_err_t esp_wifi_remote_set_ant(const wifi_ant_config_t *config); -esp_err_t esp_wifi_remote_get_ant(wifi_ant_config_t *config); int64_t esp_wifi_remote_get_tsf_time(wifi_interface_t interface); esp_err_t esp_wifi_remote_set_inactive_time(wifi_interface_t ifx, uint16_t sec); esp_err_t esp_wifi_remote_get_inactive_time(wifi_interface_t ifx, uint16_t *sec); diff --git a/components/esp_wifi_remote/scripts/generate_and_check.py b/components/esp_wifi_remote/scripts/generate_and_check.py index c8df5b31a..37ac30762 100644 --- a/components/esp_wifi_remote/scripts/generate_and_check.py +++ b/components/esp_wifi_remote/scripts/generate_and_check.py @@ -15,6 +15,7 @@ Param = namedtuple('Param', ['ptr', 'array', 'qual', 'type', 'name']) AUTO_GENERATED = 'This file is auto-generated' COPYRIGHT_HEADER = open('copyright_header.h', 'r').read() NAMESPACE = re.compile(r'^esp_wifi') +DEPRECATED_API = ['esp_wifi_set_ant_gpio', 'esp_wifi_get_ant', 'esp_wifi_get_ant_gpio', 'esp_wifi_set_ant'] class FunctionVisitor(c_ast.NodeVisitor): @@ -51,6 +52,8 @@ class FunctionVisitor(c_ast.NodeVisitor): if isinstance(node.type, c_ast.TypeDecl): func_name = node.type.declname if func_name.startswith('esp_wifi') and func_name in self.content: + if func_name in DEPRECATED_API: + return ret = node.type.type.names[0] args = [] for param in node.args.params: @@ -309,6 +312,7 @@ def generate_kconfig(idf_path, component_path): f.write(' bool\n') f.write(' default y\n\n') f.write(' orsource "./Kconfig.soc_wifi_caps.in"\n') + f.write(' orsource "./Kconfig.rpc.in"\n') for line1 in lines: line = line1.strip() if re.match(r'^if\s+[A-Z_0-9]+\s*$', line): @@ -322,7 +326,7 @@ def generate_kconfig(idf_path, component_path): line1 = re.compile(config).sub('SLAVE_' + config, line1) f.write(line1) - if line.startswith('if ESP_WIFI_ENABLED'): + if re.match(r'^if\s+\(?ESP_WIFI_ENABLED', line): copy = nested_if f.write('endmenu # Wi-Fi Remote\n') return [remote_kconfig] diff --git a/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/Kconfig b/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/Kconfig index 48b4ed62e..e3e075afd 100644 --- a/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/Kconfig +++ b/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/Kconfig @@ -17,5 +17,7 @@ menu "ESP Hosted Mock" bool "esp32c6" config SLAVE_IDF_TARGET_ESP32H2 bool "esp32h2" + config SLAVE_IDF_TARGET_ESP32P4 + bool "esp32p4" endchoice endmenu diff --git a/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/esp_hosted_mock.c b/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/esp_hosted_mock.c index 6ae190a66..117d4a0da 100644 --- a/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/esp_hosted_mock.c +++ b/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/esp_hosted_mock.c @@ -267,26 +267,6 @@ esp_err_t esp_wifi_remote_set_csi(_Bool en) return ESP_OK; } -esp_err_t esp_wifi_remote_set_ant_gpio(const wifi_ant_gpio_config_t *config) -{ - return ESP_OK; -} - -esp_err_t esp_wifi_remote_get_ant_gpio(wifi_ant_gpio_config_t *config) -{ - return ESP_OK; -} - -esp_err_t esp_wifi_remote_set_ant(const wifi_ant_config_t *config) -{ - return ESP_OK; -} - -esp_err_t esp_wifi_remote_get_ant(wifi_ant_config_t *config) -{ - return ESP_OK; -} - int64_t esp_wifi_remote_get_tsf_time(wifi_interface_t interface) { return 0; diff --git a/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/include/esp_hosted_mock.h b/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/include/esp_hosted_mock.h index 420aa5e7e..2ddcd7ee2 100644 --- a/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/include/esp_hosted_mock.h +++ b/components/esp_wifi_remote/test/smoke_test/components/esp_hosted/include/esp_hosted_mock.h @@ -57,10 +57,6 @@ esp_err_t esp_wifi_remote_80211_tx(wifi_interface_t ifx, const void *buffer, int esp_err_t esp_wifi_remote_set_csi_rx_cb(wifi_csi_cb_t cb, void *ctx); esp_err_t esp_wifi_remote_set_csi_config(const wifi_csi_config_t *config); esp_err_t esp_wifi_remote_set_csi(_Bool en); -esp_err_t esp_wifi_remote_set_ant_gpio(const wifi_ant_gpio_config_t *config); -esp_err_t esp_wifi_remote_get_ant_gpio(wifi_ant_gpio_config_t *config); -esp_err_t esp_wifi_remote_set_ant(const wifi_ant_config_t *config); -esp_err_t esp_wifi_remote_get_ant(wifi_ant_config_t *config); int64_t esp_wifi_remote_get_tsf_time(wifi_interface_t interface); esp_err_t esp_wifi_remote_set_inactive_time(wifi_interface_t ifx, uint16_t sec); esp_err_t esp_wifi_remote_get_inactive_time(wifi_interface_t ifx, uint16_t *sec); diff --git a/components/esp_wifi_remote/test/smoke_test/main/all_wifi_calls.c b/components/esp_wifi_remote/test/smoke_test/main/all_wifi_calls.c index 196c4df3e..78ce3f592 100644 --- a/components/esp_wifi_remote/test/smoke_test/main/all_wifi_calls.c +++ b/components/esp_wifi_remote/test/smoke_test/main/all_wifi_calls.c @@ -280,26 +280,6 @@ void run_all_wifi_apis(void) esp_wifi_set_csi(en); } - { - const wifi_ant_gpio_config_t *config = NULL; - esp_wifi_set_ant_gpio(config); - } - - { - wifi_ant_gpio_config_t *config = NULL; - esp_wifi_get_ant_gpio(config); - } - - { - const wifi_ant_config_t *config = NULL; - esp_wifi_set_ant(config); - } - - { - wifi_ant_config_t *config = NULL; - esp_wifi_get_ant(config); - } - { wifi_interface_t interface = 0; esp_wifi_get_tsf_time(interface); diff --git a/components/esp_wifi_remote/test/smoke_test/main/all_wifi_remote_calls.c b/components/esp_wifi_remote/test/smoke_test/main/all_wifi_remote_calls.c index 9b49393da..fd2bea18f 100644 --- a/components/esp_wifi_remote/test/smoke_test/main/all_wifi_remote_calls.c +++ b/components/esp_wifi_remote/test/smoke_test/main/all_wifi_remote_calls.c @@ -280,26 +280,6 @@ void run_all_wifi_remote_apis(void) esp_wifi_remote_set_csi(en); } - { - const wifi_ant_gpio_config_t *config = NULL; - esp_wifi_remote_set_ant_gpio(config); - } - - { - wifi_ant_gpio_config_t *config = NULL; - esp_wifi_remote_get_ant_gpio(config); - } - - { - const wifi_ant_config_t *config = NULL; - esp_wifi_remote_set_ant(config); - } - - { - wifi_ant_config_t *config = NULL; - esp_wifi_remote_get_ant(config); - } - { wifi_interface_t interface = 0; esp_wifi_remote_get_tsf_time(interface); diff --git a/components/esp_wifi_remote/test/smoke_test/sdkconfig.defaults b/components/esp_wifi_remote/test/smoke_test/sdkconfig.defaults new file mode 100644 index 000000000..1f717cf36 --- /dev/null +++ b/components/esp_wifi_remote/test/smoke_test/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_LWIP_PPP_SUPPORT=y +CONFIG_LWIP_PPP_SERVER_SUPPORT=y diff --git a/components/esp_wifi_remote/wifi_apps/roaming_app/src/Kconfig.roaming b/components/esp_wifi_remote/wifi_apps/roaming_app/src/Kconfig.roaming new file mode 100644 index 000000000..e69de29bb