diff --git a/esp_wifi_remote/CMakeLists.txt b/esp_wifi_remote/CMakeLists.txt new file mode 100644 index 000000000..7d94483db --- /dev/null +++ b/esp_wifi_remote/CMakeLists.txt @@ -0,0 +1,8 @@ +if(NOT CONFIG_ESP_WIFI_ENABLED) + set(src_wifi_is_remote esp_wifi_remote.c) +endif() + +idf_component_register(INCLUDE_DIRS include + SRCS wifi_remote_rpc.c wifi_remote_net.c wifi_remote_init.c ${src_wifi_is_remote} + REQUIRES esp_event esp_netif + PRIV_REQUIRES esp_wifi esp_hosted) diff --git a/esp_wifi_remote/esp_wifi_remote.c b/esp_wifi_remote/esp_wifi_remote.c new file mode 100644 index 000000000..9de43153f --- /dev/null +++ b/esp_wifi_remote/esp_wifi_remote.c @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_wifi.h" +#include "esp_log.h" +#include "esp_wifi_remote.h" + +#define WEAK __attribute__((weak)) + +WEAK ESP_EVENT_DEFINE_BASE(WIFI_EVENT); + +WEAK wifi_osi_funcs_t g_wifi_osi_funcs; +WEAK const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; +WEAK uint64_t g_wifi_feature_caps; + +WEAK esp_err_t esp_wifi_connect(void) +{ + return remote_esp_wifi_connect(); +} + +WEAK esp_err_t esp_wifi_init(const wifi_init_config_t *config) +{ + return remote_esp_wifi_init(config); +} + +WEAK esp_err_t esp_wifi_set_mode(wifi_mode_t mode) +{ + return remote_esp_wifi_set_mode(mode); +} + +WEAK esp_err_t esp_wifi_set_config(wifi_interface_t interface, wifi_config_t *conf) +{ + return remote_esp_wifi_set_config(interface, conf); +} + +WEAK esp_err_t esp_wifi_start(void) +{ + return remote_esp_wifi_start(); +} + +WEAK esp_err_t esp_wifi_stop(void) +{ + return remote_esp_wifi_stop(); +} + +WEAK esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]) +{ + return remote_esp_wifi_get_mac(ifx, mac); +} diff --git a/esp_wifi_remote/idf_component.yml b/esp_wifi_remote/idf_component.yml new file mode 100644 index 000000000..71e3fd181 --- /dev/null +++ b/esp_wifi_remote/idf_component.yml @@ -0,0 +1 @@ +version: "1.0.0" diff --git a/esp_wifi_remote/include/esp_wifi_remote.h b/esp_wifi_remote/include/esp_wifi_remote.h new file mode 100644 index 000000000..d32499610 --- /dev/null +++ b/esp_wifi_remote/include/esp_wifi_remote.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include "esp_wifi.h" + +// Public API +esp_err_t remote_esp_wifi_connect(void); +esp_err_t remote_esp_wifi_init(const wifi_init_config_t *config); +esp_err_t remote_esp_wifi_set_mode(wifi_mode_t mode); +esp_err_t remote_esp_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf); +esp_err_t remote_esp_wifi_start(void); +esp_err_t remote_esp_wifi_stop(void); +esp_err_t remote_esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]); + + +// TODO: Move this to private include +// Private API +esp_err_t remote_esp_wifi_init_slave(void); + +// handling channels +esp_err_t esp_wifi_remote_channel_rx(void *h, void *buffer, size_t len); +esp_err_t esp_wifi_remote_channel_set(wifi_interface_t ifx, void *h, esp_err_t (*tx_cb)(void *, void *, size_t)); +esp_err_t esp_wifi_remote_rpc_channel_rx(void *h, void *buffer, size_t len); +esp_err_t esp_wifi_remote_rpc_channel_set(void *h, esp_err_t (*tx_cb)(void *, void *, size_t)); diff --git a/esp_wifi_remote/wifi_remote_init.c b/esp_wifi_remote/wifi_remote_init.c new file mode 100644 index 000000000..b0ec6ba50 --- /dev/null +++ b/esp_wifi_remote/wifi_remote_init.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_err.h" +#include +#include "esp_wifi_remote.h" + +esp_err_t remote_esp_wifi_init_slave(void) +{ + if (esp_hosted_setup() != ESP_OK) { + return ESP_FAIL; + } + esp_hosted_channel_fn_t tx_cb; + esp_hosted_channel_t * ch; + + // Add an RPC channel with default config (i.e. secure=true) + esp_hosted_channel_config_t config = ESP_HOSTED_CHANNEL_CONFIG_DEFAULT(); + ch = esp_hosted_add_channel(&config, &tx_cb, esp_wifi_remote_rpc_channel_rx); + esp_wifi_remote_rpc_channel_set(ch, tx_cb); + + // Add two other channels for the two WiFi interfaces (STA, softAP) in plain text + config.secure = false; + ch = esp_hosted_add_channel(&config, &tx_cb, esp_wifi_remote_channel_rx); // TODO: add checks for `ch` and `tx_cb` + esp_wifi_remote_channel_set(WIFI_IF_STA, ch, tx_cb); + ch = esp_hosted_add_channel(&config, &tx_cb, esp_wifi_remote_channel_rx); + esp_wifi_remote_channel_set(WIFI_IF_AP, ch, tx_cb); + + return ESP_OK; +} diff --git a/esp_wifi_remote/wifi_remote_net.c b/esp_wifi_remote/wifi_remote_net.c new file mode 100644 index 000000000..8b21d8418 --- /dev/null +++ b/esp_wifi_remote/wifi_remote_net.c @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_err.h" +#include + +#define CHANNELS 2 + +static esp_hosted_channel_fn_t s_tx_cb[CHANNELS]; +static esp_hosted_channel_t *s_channel[CHANNELS]; +static wifi_rxcb_t s_rx_fn[CHANNELS]; + +esp_err_t esp_wifi_remote_channel_rx(void *h, void *buffer, size_t len) +{ + if (h == s_channel[0]) { + return s_rx_fn[0](buffer, len, buffer); + } + if (h == s_channel[1]) { + return s_rx_fn[1](buffer, len, buffer); + } + return ESP_FAIL; +} + +esp_err_t esp_wifi_remote_channel_set(wifi_interface_t ifx, void *h, esp_err_t (*tx_cb)(void *, void *, size_t)) +{ + if (ifx == WIFI_IF_STA) { + s_channel[0] = h; + s_tx_cb[0] = tx_cb; + return ESP_OK; + } + if (ifx == WIFI_IF_AP) { + s_channel[1] = h; + s_tx_cb[1] = tx_cb; + return ESP_OK; + } + return ESP_FAIL; +} + + +esp_err_t esp_wifi_internal_set_sta_ip(void) +{ + return ESP_OK; +} + +esp_err_t esp_wifi_internal_reg_netstack_buf_cb(wifi_netstack_buf_ref_cb_t ref, wifi_netstack_buf_free_cb_t free) +{ + return ESP_OK; +} + +void esp_wifi_internal_free_rx_buffer(void* buffer) +{ +// free(buffer); +} + +int esp_wifi_internal_tx(wifi_interface_t ifx, void *buffer, uint16_t len) +{ + if (ifx == WIFI_IF_STA) { + return s_tx_cb[0](s_channel[0], buffer, len); + } + if (ifx == WIFI_IF_AP) { + return s_tx_cb[1](s_channel[1], buffer, len); + } + + return -1; +} + +esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn) +{ + if (ifx == WIFI_IF_STA) { + s_rx_fn[0] = fn; + return ESP_OK; + } + if (ifx == WIFI_IF_AP) { + s_rx_fn[1] = fn; + return ESP_OK; + } + + return ESP_FAIL; +} diff --git a/esp_wifi_remote/wifi_remote_rpc.c b/esp_wifi_remote/wifi_remote_rpc.c new file mode 100644 index 000000000..eaee8acee --- /dev/null +++ b/esp_wifi_remote/wifi_remote_rpc.c @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_log.h" +#include "esp_err.h" +#include "esp_wifi.h" +#include "esp_wifi_remote.h" +#include "esp_hosted_api.h" + +static esp_hosted_channel_t *s_params_channel; +static esp_hosted_channel_fn_t s_params_tx; +static wifi_config_t s_last_wifi_conf; + +esp_err_t esp_wifi_remote_rpc_channel_rx(void *h, void *buffer, size_t len) +{ + if (h == s_params_channel && len == sizeof(s_last_wifi_conf)) { + memcpy(&s_last_wifi_conf, buffer, len); // TODO: use queue + return ESP_OK; + } + return ESP_FAIL; +} + +esp_err_t esp_wifi_remote_rpc_channel_set(void *h, esp_err_t (*tx_cb)(void *, void *, size_t)) +{ + s_params_channel =h; + s_params_tx = tx_cb; + return ESP_OK; +} + +esp_err_t remote_esp_wifi_connect(void) +{ + return test_wifi_connect(); +} + +esp_err_t remote_esp_wifi_init(const wifi_init_config_t *config) +{ + if (remote_esp_wifi_init_slave() != ESP_OK) { + return ESP_FAIL; + } + return test_wifi_init(config); +} + +esp_err_t remote_esp_wifi_set_mode(wifi_mode_t mode) +{ + return test_wifi_set_mode(mode); +} + +esp_err_t remote_esp_wifi_set_config(wifi_interface_t interface, wifi_config_t *conf) +{ + uint8_t *param = (uint8_t*)conf; + uint32_t checksum = 0; // TODO: generate a random number and add it to both + for (int i=0; i