Fork fix: the SDIO wedge is FIXED (esp-hosted-mcu #167)
Test, Build and Push / test-gateway (push) Successful in 12s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped

Root cause (verified against our exact IDF tree, not the community guess):
the "258" in "sdio_write_task: Failed to send data: 258" is NOT a timeout
(that is 263). 258 = 0x102 = ESP_ERR_INVALID_ARG. On the ESP32-P4, block-
mode CMD53 writes require the SOURCE buffer to be 64-byte (cache-line)
aligned; the IDF sdmmc driver rejects a misaligned source with INVALID_ARG
BEFORE any bus activity. esp_hosts write loop then declares "Unrecoverable
host sdio state" and reboots the whole P4. The audio TX payload is not
64-aligned, so streaming mic audio wedged on the very FIRST frame (which is
exactly what we saw: listening -> instant Failed to send -> reboot).

This also explains why buffer/queue/clock/retry tuning all did nothing: the
write never reached the bus. And why our symptom was instant, not after
~100 writes (the community block-mode-desync theory) — it is the first
misaligned buffer, every time.

Fix: vendored esp_hosted 2.12.11 as an editable local component (overrides
the registry copy) and bounce a misaligned TX payload through one aligned
DMA scratch buffer in hosted_sdio_write_block (port_esp_hosted_host_sdio.c).
TX is serialized by the bus lock so a single static bounce buffer is safe;
freed in hosted_sdio_deinit. Host-only change — no C6 reflash.

VERIFIED ON HARDWARE (autonomous self-test): 40s of continuous mic-audio
upstream streaming — the traffic that previously wedged on the first frame
— ran clean, zero timeouts, zero reboots. A guarded SDIO_TX_SELFTEST harness
is kept (compiled out) for future SDIO stress testing.

Credit: root cause + patch designed via multi-agent investigation; the
precise 258=INVALID_ARG decode (correcting the upstream community timeout
assumption) came from checking our actual esp_err.h.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 09:50:27 +02:00
co-authored by Claude Fable 5
parent ac9d24e0f9
commit cb5826e02b
666 changed files with 216925 additions and 0 deletions
@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/** prevent recursive inclusion **/
#ifndef __ESP_HOSTED_API_TYPES_H__
#define __ESP_HOSTED_API_TYPES_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t major1;
uint32_t minor1;
uint32_t patch1;
int32_t revision;
int32_t prerelease;
int32_t build;
} esp_hosted_coprocessor_fwver_t;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,105 @@
/*
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file esp_hosted_cp_ext_coex.h
* @brief External Coexistence API for ESP-Hosted Co-Processor
*
* Platform-agnostic APIs to configure external coexistence GPIO pins on
* the ESP-Hosted co-processor from the host MCU. Also compatible with non-ESP
* hosts (e.g. STM32, nRF) that do not use ESP-IDF.
*/
#ifndef __ESP_HOSTED_CP_EXT_COEX_H__
#define __ESP_HOSTED_CP_EXT_COEX_H__
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_HOSTED_EXT_COEX_WIRE_1 0
#define ESP_HOSTED_EXT_COEX_WIRE_2 1
#define ESP_HOSTED_EXT_COEX_WIRE_3 2
#define ESP_HOSTED_EXT_COEX_WIRE_4 3
typedef enum {
ESP_HOSTED_EXT_COEX_LEADER_ROLE = 0,
ESP_HOSTED_EXT_COEX_FOLLOWER_ROLE = 2,
ESP_HOSTED_EXT_COEX_UNKNOWN_ROLE,
} esp_hosted_ext_coex_work_mode_t;
typedef struct {
int32_t request;
int32_t priority;
int32_t grant;
int32_t tx_line;
} esp_hosted_ext_coex_gpio_set_t;
#if defined(CONFIG_ESP_HOSTED_CP_EXT_COEX) && CONFIG_ESP_HOSTED_CP_EXT_COEX
/**
* @brief Host-side API to set the work mode for external coexistence
* on the co-processor connected to the host.
*
* @param work_mode Work mode to be set
*
* @return ESP_OK on success, otherwise an error code
*/
esp_err_t esp_hosted_cp_ext_coex_set_work_mode(esp_hosted_ext_coex_work_mode_t work_mode);
/**
* @brief Host-side API to configure GPIO pins for external coexistence
* on the co-processor connected to the host.
*
* @param wire_type Wire type for which the GPIO pins are configured
* @param gpio_pins GPIO pin configuration to be set
*
* @return ESP_OK on success, otherwise an error code
*/
esp_err_t esp_hosted_cp_ext_coex_set_gpio_pin(uint32_t wire_type,
const esp_hosted_ext_coex_gpio_set_t *gpio_pins);
#if defined(CONFIG_ESP_HOSTED_CP_EXT_COEX_ADVANCE) && CONFIG_ESP_HOSTED_CP_EXT_COEX_ADVANCE
/**
* @brief Host-side API to set the grant delay for external coexistence
* on the co-processor connected to the host.
*
* @param delay_us Grant delay to be set
*
* @return ESP_OK on success, otherwise an error code
*/
esp_err_t esp_hosted_cp_ext_coex_set_grant_delay(uint8_t delay_us);
/**
* @brief Host-side API to set the validate high for external coexistence
* on the co-processor connected to the host.
*
* @param is_high_valid Validate high to be set
*
* @return ESP_OK on success, otherwise an error code
*/
esp_err_t esp_hosted_cp_ext_coex_set_validate_high(bool is_high_valid);
#endif
/**
* @brief Host-side API to disable external coexistence
* on the co-processor connected to the host.
*
* @return ESP_OK on success, otherwise an error code
*/
esp_err_t esp_hosted_cp_ext_coex_disable(void);
#endif /* CONFIG_ESP_HOSTED_CP_EXT_COEX */
#ifdef __cplusplus
}
#endif
#endif /* __ESP_HOSTED_CP_EXT_COEX_H__ */
@@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_HOSTED_CP_GPIO_H__
#define __ESP_HOSTED_CP_GPIO_H__
#include "esp_err.h"
typedef struct
{
uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
uint32_t mode; /*!< GPIO mode: set input/output mode */
uint32_t pull_up_en; /*!< GPIO pull-up */
uint32_t pull_down_en; /*!< GPIO pull-down */
uint32_t intr_type; /*!< GPIO interrupt type */
} esp_hosted_cp_gpio_config_t;
#define H_BIT0 (1ULL << 0)
#define H_BIT1 (1ULL << 1)
#define H_BIT2 (1ULL << 2)
#define H_CP_GPIO_MODE_DEF_DISABLE (0)
#define H_CP_GPIO_MODE_DEF_INPUT (H_BIT0) ///< bit mask for input
#define H_CP_GPIO_MODE_DEF_OUTPUT (H_BIT1) ///< bit mask for output
#define H_CP_GPIO_MODE_DEF_OD (H_BIT2) ///< bit mask for OD mode
enum {
H_CP_GPIO_MODE_DISABLE = H_CP_GPIO_MODE_DEF_DISABLE, /*!< GPIO mode : disable input and output */
H_CP_GPIO_MODE_INPUT = H_CP_GPIO_MODE_DEF_INPUT, /*!< GPIO mode : input only */
H_CP_GPIO_MODE_OUTPUT = H_CP_GPIO_MODE_DEF_OUTPUT, /*!< GPIO mode : output only mode */
H_CP_GPIO_MODE_OUTPUT_OD = ((H_CP_GPIO_MODE_DEF_OUTPUT) | (H_CP_GPIO_MODE_DEF_OD)), /*!< GPIO mode : output only with open-drain mode */
H_CP_GPIO_MODE_INPUT_OUTPUT_OD = ((H_CP_GPIO_MODE_DEF_INPUT) | (H_CP_GPIO_MODE_DEF_OUTPUT) | (H_CP_GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/
H_CP_GPIO_MODE_INPUT_OUTPUT = ((H_CP_GPIO_MODE_DEF_INPUT) | (H_CP_GPIO_MODE_DEF_OUTPUT)), /*!< GPIO mode : output and input mode */
};
#define H_CP_GPIO_PULL_UP (1)
#define H_CP_GPIO_PULL_DOWN (0)
esp_err_t esp_hosted_cp_gpio_config(const esp_hosted_cp_gpio_config_t *pGPIOConfig);
esp_err_t esp_hosted_cp_gpio_reset_pin(uint32_t gpio_num);
esp_err_t esp_hosted_cp_gpio_set_level(uint32_t gpio_num, uint32_t level);
esp_err_t esp_hosted_cp_gpio_get_level(uint32_t gpio_num, int *level);
esp_err_t esp_hosted_cp_gpio_set_direction(uint32_t gpio_num, uint32_t mode);
esp_err_t esp_hosted_cp_gpio_input_enable(uint32_t gpio_num);
esp_err_t esp_hosted_cp_gpio_set_pull_mode(uint32_t gpio_num, uint32_t pull_mode);
#endif /*__ESP_HOSTED_CP_GPIO_H__*/
@@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_HOSTED_OPENTHREAD_H__
#define __ESP_HOSTED_OPENTHREAD_H__
typedef enum {
HOSTED_OPENTHREAD_TRANSPORT_UART,
HOSTED_OPENTHREAD_TRANSPORT_MAX,
} esp_hosted_openthread_radio_transport_t;
typedef enum {
HOSTED_OPENTHREAD_QUERY_CONFIGURED,
HOSTED_OPENTHREAD_QUERY_INITED,
HOSTED_OPENTHREAD_QUERY_ENABLED,
HOSTED_OPENTHREAD_QUERY_READY,
} esp_hosted_openthread_query_t;
typedef struct {
int port;
int baud_rate;
int data_bits;
int parity;
int stop_bits;
int flow_ctrl;
int rx_flow_ctrl_thresh;
int source_clk;
int rx_pin;
int tx_pin;
} esp_hosted_openthread_uart_config_t;
typedef struct {
esp_hosted_openthread_radio_transport_t type;
union {
esp_hosted_openthread_uart_config_t radio_uart_config;
};
} esp_hosted_openthread_radio_config_t;
/**
* @brief Gets the current Hosted OpenThread Radio Config
*
* Caller responsible for filling OT implementation dependent radio configuration
* from the returned info
*
* @param config ESP-Hosted Radio Config
*
* @return 0 on success
*/
int esp_hosted_openthread_get_radio_config(esp_hosted_openthread_radio_config_t *config);
int esp_hosted_openthread_rcp_init(void);
int esp_hosted_openthread_rcp_deinit(void);
int esp_hosted_openthread_rcp_start(void);
int esp_hosted_openthread_rcp_stop(void);
// query the RCP on its state: configured, inited, enabled or ready
int esp_hosted_openthread_rcp_query(esp_hosted_openthread_query_t query);
#endif
@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* APIs to do OTA updates of the co-processor
*
* Note: This API is platform dependent
*
* Add additional APIs as required based on how the OTA binary is to
* be fetched.
*
* Source for the API should be in host/port/<platform>/...
*
* Procedure used by APIs to do OTA update:
* 1. Fetch and prepare OTA binary
* 2. Call rpc_ota_begin() to start OTA
* 3. Repeatedly call rpc_ota_write() with a continuous chunk of OTA data
* 4. Call rpc_ota_end()
*
* @deprecated This API is deprecated. Use the new OTA examples in examples/host_slave_ota/
* and examples/host_self_ota/ which provide more flexible OTA implementations.
* These examples demonstrate how to use the low-level esp_hosted_ota_begin(),
* esp_hosted_ota_write(), and esp_hosted_ota_end() APIs directly.
*/
#ifndef __ESP_HOSTED_OTA_H__
#define __ESP_HOSTED_OTA_H__
#include "esp_err.h"
enum {
ESP_HOSTED_SLAVE_OTA_ACTIVATED,
ESP_HOSTED_SLAVE_OTA_COMPLETED,
ESP_HOSTED_SLAVE_OTA_NOT_REQUIRED,
ESP_HOSTED_SLAVE_OTA_NOT_STARTED,
ESP_HOSTED_SLAVE_OTA_IN_PROGRESS,
ESP_HOSTED_SLAVE_OTA_FAILED,
};
/**
* @brief Fetch OTA image from a web server (image_url)
* @deprecated Use the examples in examples/host_slave_ota/ for new implementations
* @param image_url URL of the OTA image
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t esp_hosted_slave_ota(const char* image_url) __attribute__((deprecated("Use examples/host_slave_ota/ for new OTA implementations")));
/* --------- OTA APIs --------- */
/**
* @brief Begin OTA update on the remote coprocessor device
*
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t esp_hosted_slave_ota_begin(void);
/**
* @brief Write OTA data chunk to the remote coprocessor device
*
* @param ota_data Pointer to OTA data chunk
* @param ota_data_len Length of OTA data chunk
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t esp_hosted_slave_ota_write(uint8_t* ota_data, uint32_t ota_data_len);
/**
* @brief End OTA update on the remote coprocessor device
*
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t esp_hosted_slave_ota_end(void);
/**
* @brief Activate OTA update on the remote coprocessor device. This would also reboot the remote coprocessor.
*
* @return esp_err_t ESP_OK on success, error code on failure
*/
esp_err_t esp_hosted_slave_ota_activate(void);
#endif /*__ESP_HOSTED_OTA_H__*/
@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_HOSTED_POWER_SAVE_API_H
#define ESP_HOSTED_POWER_SAVE_API_H
typedef enum {
HOSTED_WAKEUP_UNDEFINED = 0,
HOSTED_WAKEUP_NORMAL_REBOOT,
HOSTED_WAKEUP_DEEP_SLEEP,
} esp_hosted_wakeup_reason_t;
typedef enum {
HOSTED_POWER_SAVE_TYPE_NONE = 0,
HOSTED_POWER_SAVE_TYPE_LIGHT_SLEEP,
HOSTED_POWER_SAVE_TYPE_DEEP_SLEEP,
} esp_hosted_power_save_type_t;
/*
* @brief Initializes the power save driver.
* This function is typically called automatically during esp_hosted_init().
*/
int esp_hosted_power_save_init(void);
/*
* @brief Deinitializes the power save driver.
* This function is typically called automatically during esp_hosted_deinit().
*/
int esp_hosted_power_save_deinit(void);
/**
* @brief Checks if the host power save feature is enabled in Kconfig.
*
* @return int Returns 1 if the feature is enabled, 0 otherwise.
*/
int esp_hosted_power_save_enabled(void);
/**
* @brief Determines if the host rebooted due to deep sleep.
*
* @return int Returns 1 if the host rebooted due to deep sleep, 0 otherwise.
*/
int esp_hosted_woke_from_power_save(void);
/**
* @brief Checks if the host is currently in power saving mode.
*
* @return int Returns 1 if the host is in power saving mode, 0 otherwise.
*/
int esp_hosted_power_saving(void);
/**
* @brief Initiates the host power save mode (deep sleep).
* @note This function does not return. The host will enter deep sleep
* and reboot upon wake-up.
*
* @param power_save_type The type of power save mode to enter.
* Currently, only HOSTED_POWER_SAVE_TYPE_DEEP_SLEEP is supported.
* @return int Returns 0 on success, or a nonzero value on failure (e.g., if the feature is disabled).
*/
int esp_hosted_power_save_start(esp_hosted_power_save_type_t power_save_type);
/**
* @brief Starts a timer that will place the host into deep sleep upon expiration.
*
* @param time_ms The duration in milliseconds after which the host will enter deep sleep.
* @return int Returns 0 on success or a nonzero value on failure.
*/
int esp_hosted_power_save_timer_start(uint32_t time_ms);
/**
* @brief Stops the host power save timer.
*
* @return int Returns 0 on success or a nonzero value on failure.
*/
int esp_hosted_power_save_timer_stop(void);
#endif
@@ -0,0 +1,171 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_HOSTED_TRANSPORT_CONFIG_H__
#define __ESP_HOSTED_TRANSPORT_CONFIG_H__
#include <stdbool.h>
#include "esp_err.h"
typedef enum {
ESP_TRANSPORT_OK = ESP_OK,
ESP_TRANSPORT_ERR_INVALID_ARG = ESP_ERR_INVALID_ARG,
ESP_TRANSPORT_ERR_ALREADY_SET = ESP_ERR_NOT_ALLOWED,
ESP_TRANSPORT_ERR_INVALID_STATE = ESP_ERR_INVALID_STATE,
} esp_hosted_transport_err_t;
/* GPIO pin configuration structure */
typedef struct {
void *port;
int pin;
} gpio_pin_t;
/* New Configuration Structures */
struct esp_hosted_sdio_config {
uint32_t clock_freq_khz;
uint8_t bus_width;
uint8_t slot;
gpio_pin_t pin_clk;
gpio_pin_t pin_cmd;
gpio_pin_t pin_d0;
gpio_pin_t pin_d1;
gpio_pin_t pin_d2;
gpio_pin_t pin_d3;
gpio_pin_t pin_reset;
uint8_t rx_mode;
bool block_mode;
bool iomux_enable;
uint16_t tx_queue_size;
uint16_t rx_queue_size;
};
struct esp_hosted_spi_hd_config {
/* Number of lines used */
uint8_t num_data_lines;
/* SPI HD pins */
gpio_pin_t pin_cs;
gpio_pin_t pin_clk;
gpio_pin_t pin_data_ready;
gpio_pin_t pin_d0;
gpio_pin_t pin_d1;
gpio_pin_t pin_d2;
gpio_pin_t pin_d3;
gpio_pin_t pin_reset;
/* SPI HD configuration */
uint32_t clk_mhz;
uint8_t mode;
uint16_t tx_queue_size;
uint16_t rx_queue_size;
bool checksum_enable;
uint8_t num_command_bits;
uint8_t num_address_bits;
uint8_t num_dummy_bits;
};
struct esp_hosted_spi_config {
/* SPI Full Duplex pins */
gpio_pin_t pin_mosi;
gpio_pin_t pin_miso;
gpio_pin_t pin_sclk;
gpio_pin_t pin_cs;
gpio_pin_t pin_handshake;
gpio_pin_t pin_data_ready;
gpio_pin_t pin_reset;
/* SPI Full Duplex configuration */
uint16_t tx_queue_size;
uint16_t rx_queue_size;
uint8_t mode;
uint32_t clk_mhz;
};
struct esp_hosted_uart_config {
/* UART bus number */
uint8_t port;
/* UART pins */
gpio_pin_t pin_tx;
gpio_pin_t pin_rx;
gpio_pin_t pin_reset;
/* UART configuration */
uint8_t num_data_bits;
uint8_t parity;
uint8_t stop_bits;
uint8_t flow_ctrl;
uint8_t clk_src;
bool checksum_enable;
uint32_t baud_rate;
uint16_t tx_queue_size;
uint16_t rx_queue_size;
};
struct esp_hosted_transport_config {
uint8_t transport_in_use;
union {
struct esp_hosted_sdio_config sdio;
struct esp_hosted_spi_hd_config spi_hd;
struct esp_hosted_spi_config spi;
struct esp_hosted_uart_config uart;
} u;
};
/* Default configuration functions - implemented by port layer */
struct esp_hosted_sdio_config esp_hosted_get_default_sdio_config(void);
struct esp_hosted_sdio_config esp_hosted_get_default_sdio_iomux_config(void);
struct esp_hosted_spi_hd_config esp_hosted_get_default_spi_hd_config(void);
struct esp_hosted_spi_config esp_hosted_get_default_spi_config(void);
struct esp_hosted_uart_config esp_hosted_get_default_uart_config(void);
/* Convenience macros for backward compatibility and ease of use */
#define INIT_DEFAULT_HOST_SDIO_CONFIG() esp_hosted_get_default_sdio_config()
#define INIT_DEFAULT_HOST_SDIO_IOMUX_CONFIG() esp_hosted_get_default_sdio_iomux_config()
#define INIT_DEFAULT_HOST_SPI_HD_CONFIG() esp_hosted_get_default_spi_hd_config()
#define INIT_DEFAULT_HOST_SPI_CONFIG() esp_hosted_get_default_spi_config()
#define INIT_DEFAULT_HOST_UART_CONFIG() esp_hosted_get_default_uart_config()
/***
* Generic Transport APIs
***/
esp_err_t esp_hosted_set_default_config(void);
bool esp_hosted_is_config_valid(void);
/* Configuration get/set functions */
esp_hosted_transport_err_t esp_hosted_transport_set_default_config(void);
esp_hosted_transport_err_t esp_hosted_transport_get_config(struct esp_hosted_transport_config **config);
esp_hosted_transport_err_t esp_hosted_transport_get_reset_config(gpio_pin_t *pin_config);
bool esp_hosted_transport_is_config_valid(void);
/***
* Transport dependent APIs.
* Can only be used with the configured host transport
***/
/* SDIO functions */
esp_hosted_transport_err_t esp_hosted_sdio_get_config(struct esp_hosted_sdio_config **config);
esp_hosted_transport_err_t esp_hosted_sdio_set_config(struct esp_hosted_sdio_config *config) __attribute__((warn_unused_result));
esp_hosted_transport_err_t esp_hosted_sdio_iomux_set_config(struct esp_hosted_sdio_config *config) __attribute__((warn_unused_result));
/* SPI Half Duplex functions */
esp_hosted_transport_err_t esp_hosted_spi_hd_get_config(struct esp_hosted_spi_hd_config **config);
esp_hosted_transport_err_t esp_hosted_spi_hd_set_config(struct esp_hosted_spi_hd_config *config) __attribute__((warn_unused_result));
esp_hosted_transport_err_t esp_hosted_spi_hd_2lines_get_config(struct esp_hosted_spi_hd_config **config);
esp_hosted_transport_err_t esp_hosted_spi_hd_2lines_set_config(struct esp_hosted_spi_hd_config *config) __attribute__((warn_unused_result));
/* SPI Full Duplex functions */
esp_hosted_transport_err_t esp_hosted_spi_get_config(struct esp_hosted_spi_config **config);
esp_hosted_transport_err_t esp_hosted_spi_set_config(struct esp_hosted_spi_config *config) __attribute__((warn_unused_result));
/* UART functions */
esp_hosted_transport_err_t esp_hosted_uart_get_config(struct esp_hosted_uart_config **config);
esp_hosted_transport_err_t esp_hosted_uart_set_config(struct esp_hosted_uart_config *config) __attribute__((warn_unused_result));
#endif /* __ESP_HOSTED_TRANSPORT_CONFIG_H__ */
@@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_HOSTED_WIFI_REMOTE_GLUE_H__
#define __ESP_HOSTED_WIFI_REMOTE_GLUE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_hosted_interface.h"
#include "esp_wifi_remote.h"
#include "esp_wifi.h"
struct esp_remote_channel_config {
esp_hosted_if_type_t if_type;
bool secure;
};
typedef struct esp_remote_channel_config * esp_remote_channel_config_t;
/* Transport/Channel related data structures and macros */
#define ESP_HOSTED_CHANNEL_CONFIG_DEFAULT() { \
.secure = true, \
}
/* Function pointer types for channel callbacks */
typedef esp_err_t (*esp_remote_channel_rx_fn_t)(void *h, void *buffer,
void *buff_to_free, size_t len);
typedef esp_err_t (*esp_remote_channel_tx_fn_t)(void *h, void *buffer, size_t len);
/* Transport/Channel Management API Functions - use managed component typedef */
esp_remote_channel_t esp_hosted_add_channel(esp_remote_channel_config_t config,
esp_remote_channel_tx_fn_t *tx, const esp_remote_channel_rx_fn_t rx);
esp_err_t esp_hosted_remove_channel(esp_remote_channel_t channel);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_HOSTED_WIFI_REMOTE_GLUE_H__ */