diff --git a/components/esp_netif/CMakeLists.txt b/components/esp_netif/CMakeLists.txt index 5ee19e4991..3ba64cd465 100644 --- a/components/esp_netif/CMakeLists.txt +++ b/components/esp_netif/CMakeLists.txt @@ -4,7 +4,6 @@ idf_component_register(SRCS "esp_netif_handlers.c" "lwip/esp_netif_lwip.c" "lwip/esp_netif_lwip_ppp.c" "lwip/esp_netif_lwip_slip.c" - "lwip/esp_netif_lwip_slip_sio.c" "loopback/esp_netif_loopback.c" "lwip/esp_netif_lwip_defaults.c" "lwip/esp_netif_sta_list.c" diff --git a/components/esp_netif/esp_netif_objects.c b/components/esp_netif/esp_netif_objects.c index 23a2c6dde7..30c645ef56 100644 --- a/components/esp_netif/esp_netif_objects.c +++ b/components/esp_netif/esp_netif_objects.c @@ -186,4 +186,4 @@ esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) } while (NULL != (esp_netif = esp_netif_next_unsafe(esp_netif))); esp_netif_list_unlock(); return NULL; -} \ No newline at end of file +} diff --git a/components/esp_netif/include/esp_netif_defaults.h b/components/esp_netif/include/esp_netif_defaults.h index 0b7541abb7..f61d7294b8 100644 --- a/components/esp_netif/include/esp_netif_defaults.h +++ b/components/esp_netif/include/esp_netif_defaults.h @@ -79,10 +79,10 @@ extern "C" { ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ .get_ip_event = 0, \ - .lost_ip_event = 0, \ - .if_key = "SLIP_DEF", \ - .if_desc = "slip", \ - .route_prio = 20 \ + .lost_ip_event = 0, \ + .if_key = "SLP_DEF", \ + .if_desc = "slip", \ + .route_prio = 16 \ }; /** @@ -129,9 +129,9 @@ extern "C" { * @brief Default configuration reference of SLIP client */ #define ESP_NETIF_DEFAULT_SLIP() \ - { \ + { \ .base = ESP_NETIF_BASE_DEFAULT_SLIP, \ - .driver = NULL, \ + .driver = NULL, \ .stack = ESP_NETIF_NETSTACK_DEFAULT_SLIP, \ } @@ -167,7 +167,7 @@ extern "C" { #define ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA _g_esp_netif_netstack_default_wifi_sta #define ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP _g_esp_netif_netstack_default_wifi_ap #define ESP_NETIF_NETSTACK_DEFAULT_PPP _g_esp_netif_netstack_default_ppp -#define ESP_NETIF_NETSTACK_DEFAULT_SLIP _g_esp_netif_netstack_default_slip +#define ESP_NETIF_NETSTACK_DEFAULT_SLIP _g_esp_netif_netstack_default_slip // // Include default network stacks configs diff --git a/components/esp_netif/include/esp_netif_slip.h b/components/esp_netif/include/esp_netif_slip.h index 088cca1751..bb0aa08303 100644 --- a/components/esp_netif/include/esp_netif_slip.h +++ b/components/esp_netif/include/esp_netif_slip.h @@ -16,12 +16,12 @@ #ifndef _ESP_NETIF_SLIP_H_ #define _ESP_NETIF_SLIP_H_ +#include "esp_netif.h" + #ifdef __cplusplus extern "C" { #endif -#include "driver/uart.h" - /** @brief SLIP event base */ ESP_EVENT_DECLARE_BASE(SLIP_EVENT); @@ -31,16 +31,11 @@ typedef enum esp_netif_slip_event { } esp_netif_slip_event_e; -/** @brief Forward declaration of lwip_slip_ctx for external use */ -typedef struct lwip_slip_ctx lwip_slip_ctx_t; - /** @brief Configuration structure for SLIP network interface * */ typedef struct esp_netif_slip_config { - ip6_addr_t addr; /* Local IP6 address */ - - uart_port_t uart_dev; /* UART device for reading and writing SLIP information, this must be initialised externally */ + esp_ip6_addr_t ip6_addr; /* Local IP6 address */ } esp_netif_slip_config_t; @@ -54,21 +49,20 @@ typedef struct esp_netif_slip_config { */ esp_err_t esp_netif_slip_set_params(esp_netif_t *netif, const esp_netif_slip_config_t *config); -/** - * @brief Data path API to input incoming packets to SLIP +/** @brief Sets IPV6 address for the supplied esp-netif. * - * @param[in] esp_netif handle to slip esp-netif instance - * @param[in] buffer pointer to the incoming data - * @param[in] len length of the data + * @param[in] netif handle to slip esp-netif instance + * @param[in] ipv6 IPv6 address of the SLIP interface * - * @return - * - ESP_OK on success + * @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not SLIP */ -void esp_netif_lwip_slip_raw_input(esp_netif_t *netif, void *buffer, size_t len); +esp_err_t esp_netif_slip_set_ipv6(esp_netif_t *netif, const esp_ip6_addr_t *ipv6); /** * @brief Data path API to write raw packet ous the SLIP interface * + * This API is typically used when implementing user defined methods + * * @param[in] esp_netif handle to slip esp-netif instance * @param[in] buffer pointer to the outgoing data * @param[in] len length of the data @@ -87,37 +81,6 @@ void esp_netif_lwip_slip_raw_output(esp_netif_t *netif, void *buffer, size_t len * @return * - pointer to the internal ip6 address object */ -const ip6_addr_t *esp_slip_get_ip6(esp_netif_t *slip_netif); - -/** - * @brief Fetch lwip_slip_ctx_t for esp_netif_t object - * - * This is required to support the wiring of esp_netif objects outside - * of this component. - * - * @return - * - lwip slip context - */ -lwip_slip_ctx_t *esp_netif_lwip_slip_get_ctx(esp_netif_t *slip_netif); - -/** - * @brief Start the esp slip netif - * - * @param[in] esp_netif handle to slip esp-netif instance - * - * @return - * - ESP_OK on success - */ -esp_err_t esp_netif_start_slip(lwip_slip_ctx_t *slip_ctx); - -/** - * @brief Stop the esp slip netif - * - * @param[in] esp_netif handle to slip esp-netif instance - * - * @return - * - ESP_OK on success - */ -esp_err_t esp_netif_stop_slip(lwip_slip_ctx_t *slip_ctx); +const esp_ip6_addr_t *esp_slip_get_ip6(esp_netif_t *slip_netif); #endif diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 4ddf0f7479..f7bbc202ce 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -52,9 +52,14 @@ */ #define _RUN_IN_LWIP_TASK(function, netif, param) { return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); } +/** + * @brief macros to check netif related data to evaluate interface type + */ +#define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) (netif->related_data && netif->related_data->is_point2point) + #define _RUN_IN_LWIP_TASK_IF_SUPPORTED(function, netif, param) \ { \ - if (netif->is_ppp_netif) { \ + if (_IS_NETIF_ANY_POINT2POINT_TYPE(netif)) { \ return ESP_ERR_NOT_SUPPORTED; \ } \ return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); \ @@ -148,10 +153,8 @@ static esp_netif_t* esp_netif_is_active(esp_netif_t *arg) */ static void esp_netif_set_default_netif(esp_netif_t *esp_netif) { - if (esp_netif->is_ppp_netif) { + if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { esp_netif_ppp_set_default_netif(esp_netif->netif_handle); - } else if (esp_netif->is_slip_netif) { - esp_netif_slip_set_default_netif(esp_netif->netif_handle); } else { netif_set_default(esp_netif->netif_handle); } @@ -256,7 +259,7 @@ esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev) void* esp_netif_get_netif_impl(esp_netif_t *esp_netif) { // get impl ptr only for vanilla lwip impl (ppp_pcb not supported) - if (esp_netif && !esp_netif->is_ppp_netif) { + if (esp_netif && !_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { return esp_netif->lwip_netif; } return NULL; @@ -341,24 +344,27 @@ static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_ // Install network stack functions -- connects netif and L3 stack const esp_netif_netstack_config_t *esp_netif_stack_config = cfg->stack; if (cfg->base->flags & ESP_NETIF_FLAG_IS_PPP) { - esp_netif->lwip_ppp_ctx = esp_netif_new_ppp(esp_netif, esp_netif_stack_config); - if (esp_netif->lwip_ppp_ctx == NULL) { + esp_netif->related_data = esp_netif_new_ppp(esp_netif, esp_netif_stack_config); + if (esp_netif->related_data == NULL) { return ESP_ERR_ESP_NETIF_INIT_FAILED; } esp_netif->lwip_input_fn = esp_netif_stack_config->lwip_ppp.input_fn; - esp_netif->is_ppp_netif = true; // Make the netif handle (used for tcpip input function) the ppp_netif - esp_netif->netif_handle = esp_netif->lwip_ppp_ctx; + esp_netif->netif_handle = esp_netif->related_data; } else if (cfg->base->flags & ESP_NETIF_FLAG_IS_SLIP) { - esp_netif->lwip_slip_ctx = esp_netif_new_slip(esp_netif, esp_netif_stack_config); - if (esp_netif->lwip_slip_ctx == NULL) { + esp_netif->related_data = esp_netif_new_slip(esp_netif, esp_netif_stack_config); + if (esp_netif->related_data == NULL) { return ESP_ERR_ESP_NETIF_INIT_FAILED; } - esp_netif->lwip_input_fn = esp_netif_stack_config->lwip_slip.input_fn; - esp_netif->is_slip_netif = true; - // Make the netif handle (used for tcpip input function) the slip_netif - esp_netif->netif_handle = esp_netif->lwip_slip_ctx; + if (esp_netif_stack_config->lwip.init_fn) { + esp_netif->lwip_init_fn = esp_netif_stack_config->lwip.init_fn; + } + if (esp_netif_stack_config->lwip.input_fn) { + esp_netif->lwip_input_fn = esp_netif_stack_config->lwip.input_fn; + } + // Make the netif handle (used for tcpip input function) the esp_netif itself + esp_netif->netif_handle = esp_netif; } else { if (esp_netif_stack_config-> lwip.init_fn) { @@ -491,6 +497,15 @@ static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif) return ESP_OK; } +static void esp_netif_destroy_related(esp_netif_t *esp_netif) +{ + if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { + esp_netif_destroy_ppp(esp_netif->related_data); + } else if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, SLIP_LWIP_NETIF)) { + esp_netif_destroy_slip(esp_netif->related_data); + } +} + void esp_netif_destroy(esp_netif_t *esp_netif) { if (esp_netif) { @@ -500,11 +515,7 @@ void esp_netif_destroy(esp_netif_t *esp_netif) free(esp_netif->if_key); free(esp_netif->if_desc); esp_netif_lwip_remove(esp_netif); - if (esp_netif->is_ppp_netif) { - esp_netif_destroy_ppp(esp_netif->netif_handle); - } else if (esp_netif->is_slip_netif) { - esp_netif_destroy_slip(esp_netif->netif_handle); - } + esp_netif_destroy_related(esp_netif); free(esp_netif->lwip_netif); free(esp_netif->hostname); if (s_last_default_esp_netif == esp_netif) { @@ -555,7 +566,7 @@ esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[]) if (esp_netif == NULL || esp_netif->lwip_netif == NULL) { return ESP_ERR_ESP_NETIF_IF_NOT_READY; } - if (esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_NOT_SUPPORTED; } memcpy(esp_netif->mac, mac, NETIF_MAX_HWADDR_LEN); @@ -568,7 +579,7 @@ esp_err_t esp_netif_get_mac(esp_netif_t *esp_netif, uint8_t mac[]) if (esp_netif == NULL || esp_netif->lwip_netif == NULL) { return ESP_ERR_ESP_NETIF_IF_NOT_READY; } - if (esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_NOT_SUPPORTED; } if (esp_netif_is_netif_up(esp_netif)) { @@ -684,16 +695,9 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_start(esp_netif_t *esp_netif) { - if (esp_netif->is_ppp_netif) { + if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { // No need to start PPP interface in lwip thread - esp_err_t ret = esp_netif_start_ppp(esp_netif->lwip_ppp_ctx); - if (ret == ESP_OK) { - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); - } - return ret; - } else if (esp_netif->is_slip_netif) { - // No need to start SLIP interface in lwip thread - esp_err_t ret = esp_netif_start_slip(esp_netif->lwip_slip_ctx); + esp_err_t ret = esp_netif_start_ppp(esp_netif->related_data); if (ret == ESP_OK) { esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); } @@ -740,16 +744,16 @@ static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_stop(esp_netif_t *esp_netif) { - if (esp_netif->is_ppp_netif) { + if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { // No need to stop PPP interface in lwip thread - esp_err_t ret = esp_netif_stop_ppp(esp_netif->lwip_ppp_ctx); + esp_err_t ret = esp_netif_stop_ppp(esp_netif->related_data); if (ret == ESP_OK) { esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);; } return ret; - } else if (esp_netif->is_slip_netif) { + } else if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, SLIP_LWIP_NETIF)) { // No need to stop PPP interface in lwip thread - esp_err_t ret = esp_netif_stop_slip(esp_netif->lwip_slip_ctx); + esp_err_t ret = esp_netif_stop_slip(esp_netif); if (ret == ESP_OK) { esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);; } @@ -987,7 +991,7 @@ esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUP esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status) { - if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) || esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_INVALID_ARG; } @@ -997,7 +1001,7 @@ esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_stat esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status) { - if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_SERVER) || esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_SERVER) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_INVALID_ARG; } @@ -1110,7 +1114,7 @@ esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname) { ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif); - if (!esp_netif || esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (!esp_netif || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_INVALID_ARG; } @@ -1192,7 +1196,7 @@ bool esp_netif_is_netif_up(esp_netif_t *esp_netif) ESP_LOGV(TAG, "%s esp_netif:%p", __func__, esp_netif); if (esp_netif != NULL && esp_netif->lwip_netif != NULL) { - if (esp_netif->is_ppp_netif) { + if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { // ppp implementation uses netif_set_link_up/down to update link state return netif_is_link_up(esp_netif->lwip_netif); } @@ -1369,7 +1373,7 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns) { - if (esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_NOT_SUPPORTED; } esp_netif_dns_param_t dns_param = { @@ -1409,7 +1413,7 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns) { - if (esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { const ip_addr_t *dns_ip = dns_getserver(type); if (dns_ip == IP_ADDR_ANY) { return ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED; @@ -1494,7 +1498,7 @@ esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if { ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif); - if (esp_netif == NULL || if_ip6 == NULL || esp_netif->is_ppp_netif || esp_netif->is_slip_netif) { + if (esp_netif == NULL || if_ip6 == NULL || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } struct netif *p_netif = esp_netif->lwip_netif; diff --git a/components/esp_netif/lwip/esp_netif_lwip_defaults.c b/components/esp_netif/lwip/esp_netif_lwip_defaults.c index aa3d579058..b241b00363 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_defaults.c +++ b/components/esp_netif/lwip/esp_netif_lwip_defaults.c @@ -54,16 +54,8 @@ static const struct esp_netif_netstack_config s_netif_config_ppp = { } }; -static const struct esp_netif_netstack_config s_netif_config_slip = { - .lwip_slip = { - .slip_config = { - .uart_dev = UART_NUM_1, - } - } -}; const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_eth = &s_eth_netif_config; const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta = &s_wifi_netif_config_sta; const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap = &s_wifi_netif_config_ap; const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_ppp = &s_netif_config_ppp; -const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_slip = &s_netif_config_slip; diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index a3df2f2c7f..f383674b2d 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -30,6 +30,7 @@ struct esp_netif_netstack_lwip_ppp_config { }; struct esp_netif_netstack_lwip_slip_config { + err_t (*init_fn)(struct netif*); void (*input_fn)(void *netif, void *buffer, size_t len, void *eb); esp_netif_slip_config_t slip_config; }; @@ -39,7 +40,6 @@ struct esp_netif_netstack_config { union { struct esp_netif_netstack_lwip_vanilla_config lwip; struct esp_netif_netstack_lwip_ppp_config lwip_ppp; - struct esp_netif_netstack_lwip_slip_config lwip_slip; }; }; @@ -65,9 +65,28 @@ typedef struct esp_netif_ip_lost_timer_s { bool timer_running; } esp_netif_ip_lost_timer_t; -// Forward declare the ppp and slip context -typedef struct lwip_ppp_ctx lwip_ppp_ctx_t; -typedef struct lwip_slip_ctx lwip_slip_ctx_t; +/** + * @brief Check the netif if of a specific P2P type + */ +#define _IS_NETIF_POINT2POINT_TYPE(netif, type) (netif->related_data && netif->related_data->is_point2point && netif->related_data->netif_type == type) + +/** + * @brief Additional netif types when related data are needed + */ +enum netif_types { + COMMON_LWIP_NETIF, + PPP_LWIP_NETIF, + SLIP_LWIP_NETIF +}; + +/** + * @brief Related data to esp-netif (additional data for some special types of netif + * (typically for point-point network types, such as PPP or SLIP) + */ +typedef struct netif_related_data { + bool is_point2point; + enum netif_types netif_type; +} netif_related_data_t; /** * @brief Main esp-netif container with interface related information @@ -80,14 +99,10 @@ struct esp_netif_obj { // lwip netif related struct netif *lwip_netif; - lwip_ppp_ctx_t *lwip_ppp_ctx; - lwip_slip_ctx_t *lwip_slip_ctx; err_t (*lwip_init_fn)(struct netif*); void (*lwip_input_fn)(void *input_netif_handle, void *buffer, size_t len, void *eb); void * netif_handle; // netif impl context (either vanilla lwip-netif or ppp_pcb) - - bool is_ppp_netif; - bool is_slip_netif; + netif_related_data_t *related_data; // holds additional data for specific netifs // io driver related void* driver_handle; diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index 2a82ca404e..7500888d8a 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -31,13 +31,16 @@ static const char *TAG = "esp-netif_lwip-ppp"; #if PPPOS_SUPPORT /** - * @brief internal lwip_ppp context struct, used to hold PPP netif related parameters + * @brief internal lwip_ppp context struct extends the netif related data + * used to hold PPP netif related parameters */ -struct lwip_ppp_ctx { +typedef struct lwip_peer2peer_ctx { + netif_related_data_t base; // Generic portion of netif-related data + // PPP specific fields follow bool ppp_phase_event_enabled; bool ppp_error_event_enabled; ppp_pcb *ppp; -}; +} lwip_peer2peer_ctx_t; /** * @brief lwip callback from PPP client used here to produce PPP error related events, @@ -53,7 +56,8 @@ static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx) .if_index = -1, }; esp_err_t err; - struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; + struct lwip_peer2peer_ctx *obj = (struct lwip_peer2peer_ctx*)netif->related_data; + assert(obj->base.netif_type == PPP_LWIP_NETIF); esp_ip4_addr_t ns1; esp_ip4_addr_t ns2; switch (err_code) { @@ -208,7 +212,8 @@ static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx) break; } esp_netif_t *netif = ctx; - struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; + lwip_peer2peer_ctx_t *obj = (lwip_peer2peer_ctx_t *)netif->related_data; + assert(obj->base.netif_type == PPP_LWIP_NETIF); if (obj && obj->ppp_phase_event_enabled) { esp_err_t err = esp_event_post(NETIF_PPP_STATUS, NETIF_PP_PHASE_OFFSET + phase, netif, sizeof(netif), 0); if (err != ESP_OK) { @@ -239,12 +244,13 @@ static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd) { - if (netif == NULL || !netif->is_ppp_netif) { + if (_IS_NETIF_POINT2POINT_TYPE(netif, PPP_LWIP_NETIF)) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } #if PPP_AUTH_SUPPORT - struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; - pppapi_set_auth(obj->ppp, authtype, user, passwd); + lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif->related_data; + assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); + pppapi_set_auth(ppp_ctx->ppp, authtype, user, passwd); #else ESP_LOGE(TAG, "%s failed: No authorisation enabled in menuconfig", __func__); return ESP_ERR_ESP_NETIF_IF_NOT_READY; @@ -252,35 +258,47 @@ esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t autht return ESP_OK; } -void esp_netif_slip_set_default_netif(lwip_ppp_ctx_t* slip_ctx) +void esp_netif_ppp_set_default_netif(netif_related_data_t *netif_related) { - netif_set_default(slip_ctx->netif) + lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related; + assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); + + ppp_set_default(ppp_ctx->ppp); } -lwip_ppp_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config) +netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config) { struct netif * netif_impl = esp_netif->lwip_netif; - struct lwip_ppp_ctx * ppp_obj = calloc(1, sizeof(struct lwip_ppp_ctx)); + struct lwip_peer2peer_ctx * ppp_obj = calloc(1, sizeof(struct lwip_peer2peer_ctx)); if (ppp_obj == NULL) { ESP_LOGE(TAG, "%s: cannot allocate lwip_ppp_ctx", __func__); return NULL; } + // Setup the generic esp-netif fields + ppp_obj->base.is_point2point = true; + ppp_obj->base.netif_type = PPP_LWIP_NETIF; ppp_obj->ppp = pppapi_pppos_create(netif_impl, pppos_low_level_output, on_ppp_status_changed, esp_netif); ESP_LOGD(TAG, "%s: PPP connection created: %p", __func__, ppp_obj->ppp); if (!ppp_obj->ppp) { ESP_LOGE(TAG, "%s: lwIP PPP connection cannot be created", __func__); } + + // Set the related data here, since the phase callback could be triggered before this function exits + esp_netif->related_data = (netif_related_data_t *)ppp_obj; #if PPP_NOTIFY_PHASE ppp_set_notify_phase_callback(ppp_obj->ppp, on_ppp_notify_phase); #endif ppp_set_usepeerdns(ppp_obj->ppp, 1); - return ppp_obj; + return (netif_related_data_t *)ppp_obj; } -esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp_ctx) +esp_err_t esp_netif_start_ppp(netif_related_data_t *netif_related) { + lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related; + assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); + ESP_LOGD(TAG, "%s: Starting PPP connection: %p", __func__, ppp_ctx->ppp); esp_err_t err = pppapi_connect(ppp_ctx->ppp, 0); if (err != ESP_OK) { @@ -292,15 +310,17 @@ esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp_ctx) void esp_netif_lwip_ppp_input(void *ppp_ctx, void *buffer, size_t len, void *eb) { - struct lwip_ppp_ctx * obj = ppp_ctx; + struct lwip_peer2peer_ctx * obj = ppp_ctx; err_t ret = pppos_input_tcpip(obj->ppp, buffer, len); if (ret != ERR_OK) { ESP_LOGE(TAG, "pppos_input_tcpip failed with %d", ret); } } -esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp_ctx) +esp_err_t esp_netif_stop_ppp(netif_related_data_t *netif_related) { + lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related; + assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); ESP_LOGD(TAG, "%s: Stopped PPP connection: %p", __func__, ppp_ctx->ppp); err_t ret = pppapi_close(ppp_ctx->ppp, 0); if (ret != ERR_OK) { @@ -310,21 +330,26 @@ esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp_ctx) return ESP_OK; } -void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp_ctx) +void esp_netif_destroy_ppp(netif_related_data_t *netif_related) { + lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related; + assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); + pppapi_free(ppp_ctx->ppp); - free(ppp_ctx); + free(netif_related); } esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config) { - struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; + struct lwip_peer2peer_ctx *obj = (struct lwip_peer2peer_ctx *)netif->related_data; obj->ppp_phase_event_enabled = config->ppp_phase_event_enabled; obj->ppp_error_event_enabled = config->ppp_error_event_enabled; return ESP_OK; } #else /* PPPOS_SUPPORT */ +typedef struct lwip_peer2peer_ctx lwip_peer2peer_ctx_t; + /** * @brief If PPP not enabled in menuconfig, log the error and return appropriate code indicating failure */ @@ -337,22 +362,22 @@ esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_confi esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd) LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED) -void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx) +void esp_netif_ppp_set_default_netif(lwip_peer2peer_ctx_t* ppp_ctx) LOG_PPP_DISABLED_AND_DO() -lwip_ppp_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config) +lwip_peer2peer_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config) LOG_PPP_DISABLED_AND_DO(return NULL) -esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp_ctx) +esp_err_t esp_netif_start_ppp(lwip_peer2peer_ctx_t *ppp_ctx) LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED) void esp_netif_lwip_ppp_input(void *ppp_ctx, void *buffer, size_t len, void *eb) LOG_PPP_DISABLED_AND_DO() -esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp_ctx) +esp_err_t esp_netif_stop_ppp(lwip_peer2peer_ctx_t *ppp_ctx) LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED) -void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp_ctx) +void esp_netif_destroy_ppp(lwip_peer2peer_ctx_t *ppp_ctx) LOG_PPP_DISABLED_AND_DO() esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config) diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.h b/components/esp_netif/lwip/esp_netif_lwip_ppp.h index 8b306e3454..c9a2ef6aeb 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.h +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.h @@ -25,17 +25,17 @@ * - pointer to ppp-netif object on success * - NULL otherwise */ -lwip_ppp_ctx_t* esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config); +netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config); /** * @brief Creates new PPP related structure * - * @param[in] ppp pointer to internal ppp context instance + * @param[in] netif_related pointer to internal ppp context instance * * @return * - ESP_OK on success */ -esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp); +esp_err_t esp_netif_start_ppp(netif_related_data_t *netif_related); /** * @brief Data path API to input incoming packets to PPP @@ -53,19 +53,19 @@ void esp_netif_lwip_ppp_input(void *ppp, void *buffer, size_t len, void *eb); /** * @brief Destroys the ppp netif object * - * @param[in] ppp pointer to internal ppp context instance + * @param[in] netif_related pointer to internal ppp context instance */ -void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp); +void esp_netif_destroy_ppp(netif_related_data_t *netif_related); /** * @brief Stops the PPP interface * - * @param[in] ppp pointer to internal ppp context instance + * @param[in] netif_related pointer to internal ppp context instance * * @return * - ESP_OK on success */ -esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp); +esp_err_t esp_netif_stop_ppp(netif_related_data_t *netif_related); /** * @brief Sets default netif for routing priority config @@ -73,6 +73,6 @@ esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp); * @note: This function must be called from lwip thread * */ -void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx); +void esp_netif_ppp_set_default_netif(netif_related_data_t *netif_related); #endif // _ESP_NETIF_LWIP_PPP_H_ \ No newline at end of file diff --git a/components/esp_netif/lwip/esp_netif_lwip_slip.c b/components/esp_netif/lwip/esp_netif_lwip_slip.c index 69386869be..80cbf1b91f 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_slip.c +++ b/components/esp_netif/lwip/esp_netif_lwip_slip.c @@ -16,19 +16,14 @@ #include "lwip/dns.h" #include "esp_netif.h" #include "esp_log.h" -#include "esp_netif_net_stack.h" -#include "esp_event.h" #include "esp_netif_slip.h" - #include "esp_netif_lwip_internal.h" - +#include "esp_netif_net_stack.h" #include "lwip/opt.h" -#include "lwip/sio.h" -#include "lwip/ip.h" -#include "lwip/ip6.h" #include "lwip/ip6_addr.h" #include "lwip/netif.h" #include "netif/slipif.h" +#include "lwip/sio.h" #include @@ -38,25 +33,21 @@ ESP_EVENT_DEFINE_BASE(SLIP_EVENT); static const char *TAG = "esp-netif_lwip-slip"; /** - * @brief LWIP SLIP context object + * @brief LWIP SLIP context object extends esp-netif related data */ typedef struct lwip_slip_ctx { - //! ESP netif object - esp_netif_t *esp_netif; + //! Generic esp-netif related data + netif_related_data_t base; //! SLIP interface IP6 address - ip6_addr_t addr; - - - //! UART device for underling SIO - uart_port_t uart_dev; + esp_ip6_addr_t addr; } lwip_slip_ctx_t; /** * @brief Create a new lwip slip interface */ -lwip_slip_ctx_t *esp_netif_new_slip(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config) +netif_related_data_t * esp_netif_new_slip(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config) { ESP_LOGD(TAG, "%s", __func__); @@ -68,60 +59,29 @@ lwip_slip_ctx_t *esp_netif_new_slip(esp_netif_t *esp_netif, const esp_netif_nets ESP_LOGE(TAG, "%s: cannot allocate lwip_slip_ctx_t", __func__); return NULL; } + // Setup the generic esp-netif fields + slip_ctx->base.is_point2point = true; + slip_ctx->base.netif_type = SLIP_LWIP_NETIF; - ESP_LOGD(TAG, "%s: Initialising SLIP (esp_netif %p, lwip_netif %p, device: %d)", __func__, esp_netif, netif_impl, slip_ctx->uart_dev); - - // Load config - const esp_netif_slip_config_t *slip_config = &esp_netif_stack_config->lwip_slip.slip_config; - - // Attache network interface and uart device - slip_ctx->uart_dev = slip_config->uart_dev; - slip_ctx->esp_netif = esp_netif; + ESP_LOGD(TAG, "%s: Initialising SLIP (esp_netif %p, lwip_netif %p)", __func__, esp_netif, netif_impl); ESP_LOGI(TAG, "%s: Created SLIP interface (netif %p, slip_ctx: %p)", __func__, esp_netif, slip_ctx); - return slip_ctx; -} - -/** - * @brief Creates new SLIP related structure - */ -esp_err_t esp_netif_start_slip(lwip_slip_ctx_t *slip_ctx) -{ - ESP_LOGI(TAG, "%s: Starting SLIP connection (slip_ctx: %p, addr: %s)", __func__, slip_ctx, ip6addr_ntoa(&slip_ctx->addr)); - - struct netif *netif_impl = slip_ctx->esp_netif->lwip_netif; - - // Store serial port number in net interface for SIO open command - netif_impl->state = (void *)slip_ctx->uart_dev; - - // Attach interface - netif_add_noaddr(slip_ctx->esp_netif->lwip_netif, (void *)slip_ctx->uart_dev, &slipif_init, &ip_input); - - // Bind address - int8_t addr_index = 0; - - // Note that addr_set is used here as the address is statically configured - // rather than negotiated over the link - netif_ip6_addr_set(slip_ctx->esp_netif->lwip_netif, addr_index, &slip_ctx->addr); - netif_ip6_addr_set_state(slip_ctx->esp_netif->lwip_netif, addr_index, IP6_ADDR_VALID); - - // Setup interface - netif_set_link_up(slip_ctx->esp_netif->lwip_netif); - netif_set_up(slip_ctx->esp_netif->lwip_netif); - - return ESP_OK; + return (netif_related_data_t *)slip_ctx; } /** * @brief Stops the SLIP interface */ -esp_err_t esp_netif_stop_slip(lwip_slip_ctx_t *slip_ctx) +esp_err_t esp_netif_stop_slip(esp_netif_t *esp_netif) { + lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *)esp_netif; + assert(slip_ctx->base.netif_type == SLIP_LWIP_NETIF); + ESP_LOGI(TAG, "%s: Stopped SLIP connection: %p", __func__, slip_ctx); // Stop interface - netif_set_link_down(slip_ctx->esp_netif->lwip_netif); + netif_set_link_down(esp_netif->lwip_netif); return ESP_OK; } @@ -133,59 +93,64 @@ esp_err_t esp_netif_stop_slip(lwip_slip_ctx_t *slip_ctx) esp_err_t esp_netif_slip_set_params(esp_netif_t *netif, const esp_netif_slip_config_t *slip_config) { - lwip_slip_ctx_t *slip_ctx = netif->lwip_slip_ctx; + lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *)netif->related_data; + assert(slip_ctx->base.netif_type == SLIP_LWIP_NETIF); ESP_LOGD(TAG, "%s (slip_ctx: %p)", __func__, slip_ctx); - if (netif_is_link_up(slip_ctx->esp_netif->lwip_netif)) { + if (netif_is_link_up(netif->lwip_netif)) { ESP_LOGE(TAG, "Cannot set parameters while SLIP interface is running"); return ESP_ERR_INVALID_STATE; } - memcpy(&slip_ctx->addr, &slip_config->addr, sizeof(ip6_addr_t)); - slip_ctx->uart_dev = slip_config->uart_dev; + memcpy(&slip_ctx->addr, &slip_config->ip6_addr, sizeof(ip6_addr_t)); + return ESP_OK; } +esp_err_t esp_netif_slip_set_ipv6(esp_netif_t *netif, const esp_ip6_addr_t *ipv6) +{ + lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *)netif->related_data; + assert(slip_ctx->base.netif_type == SLIP_LWIP_NETIF); + + ESP_LOGV(TAG, "%s (slip_ctx: %p)", __func__, slip_ctx); + + if (netif_is_link_up(netif->lwip_netif)) { + ESP_LOGE(TAG, "Cannot set parameters while SLIP interface is running"); + return ESP_ERR_INVALID_STATE; + } + memcpy(&slip_ctx->addr, ipv6, sizeof(ip6_addr_t)); + int8_t addr_index = 0; + + netif_ip6_addr_set(netif->lwip_netif, addr_index, (ip6_addr_t *)&slip_ctx->addr); + netif_ip6_addr_set_state(netif->lwip_netif, addr_index, IP6_ADDR_VALID); + + return ESP_OK; +} + + /** * @brief Write incoming serial data to the SLIP interface */ -void esp_netif_lwip_slip_input(void *ctx, void *buffer, size_t len, void *eb) +void esp_netif_lwip_slip_input(void *h, void *buffer, unsigned int len, void *eb) { - lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *)ctx; +#if CONFIG_LWIP_SLIP_SUPPORT + esp_netif_t *netif = h; + lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *)netif->related_data; + assert(slip_ctx->base.netif_type == SLIP_LWIP_NETIF); ESP_LOGD(TAG, "%s", __func__); ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_DEBUG); // Update slip netif with data - slipif_received_bytes(slip_ctx->esp_netif->lwip_netif, buffer, len); + slipif_received_bytes(netif->lwip_netif, buffer, len); // Process incoming bytes for (int i = 0; i < len; i++) { - slipif_process_rxqueue(slip_ctx->esp_netif->lwip_netif); + slipif_process_rxqueue(netif->lwip_netif); } -} - -/** - * @brief Write raw data out the SLIP interface - */ -void esp_netif_lwip_slip_output(lwip_slip_ctx_t *slip_ctx, void *buffer, size_t len) -{ - struct netif *lwip_netif = slip_ctx->esp_netif->lwip_netif; - - ESP_LOGD(TAG, "%s", __func__); - ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_DEBUG); - - struct pbuf p = { - .next = NULL, - .payload = buffer, - .tot_len = len, - .len = len, - }; - - // Call slip if output function to feed data out slip interface - lwip_netif->output_ip6(lwip_netif, &p, NULL); +#endif } /** @@ -208,38 +173,111 @@ void esp_netif_lwip_slip_raw_output(esp_netif_t *slip_netif, void *buffer, size_ lwip_netif->output_ip6(lwip_netif, &p, NULL); } -/** - * @brief Fetch pointer to internal slip_lwip_context - * - * This is required to support the wiring of esp_netif objects outside - * of this component. - * - * @return - * - lwip slip context - */ -lwip_slip_ctx_t *esp_netif_lwip_slip_get_ctx(esp_netif_t *slip_netif) -{ - return slip_netif->lwip_slip_ctx; -} - /** * @brief Destroys the SLIP context object */ -void esp_netif_destroy_slip(lwip_slip_ctx_t *slip_ctx) +void esp_netif_destroy_slip(netif_related_data_t *slip) { ESP_LOGD(TAG, "%s", __func__); // Free base object - free(slip_ctx); + free(slip); } -void esp_netif_slip_set_default_netif(lwip_slip_ctx_t *slip_ctx) +const esp_ip6_addr_t *esp_slip_get_ip6(esp_netif_t *slip_netif) { - netif_set_default(slip_ctx->esp_netif->lwip_netif); + lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *)slip_netif->related_data; + assert(slip_ctx->base.netif_type == SLIP_LWIP_NETIF); + return &slip_ctx->addr; } -const ip6_addr_t *esp_slip_get_ip6(esp_netif_t *slip_netif) +/** @brief Get esp-netif object corresponding to registration index + */ +static esp_netif_t * get_netif_with_esp_index(int index) { - return &slip_netif->lwip_slip_ctx->addr; + esp_netif_t *netif = NULL; + int counter = 0; + while ((netif = esp_netif_next(netif)) != NULL) { + if (counter == index) { + return netif; + } + counter++; + } + return NULL; } +/** @brief Return list registration index of the supplied netif ptr + */ +static int get_esp_netif_index(esp_netif_t * esp_netif) +{ + esp_netif_t *netif = NULL; + int counter = 0; + while ((netif = esp_netif_next(netif)) != NULL) { + if (esp_netif == netif) { + return counter; + } + counter++; + } + return -1; +} + +err_t esp_slipif_init(struct netif *netif) +{ + esp_netif_t *esp_netif = netif->state; + int esp_index = get_esp_netif_index(esp_netif); + if (esp_index < 0) { + return ERR_IF; + } + + // Store netif index in net interface for SIO open command to abstract the dev + netif->state = (void *)esp_index; + + err_t err = slipif_init(netif); + netif_set_up(netif); + netif_set_link_up(netif); + return err; +} + +static const struct esp_netif_netstack_config s_netif_config_slip = { + .lwip = { + .init_fn = esp_slipif_init, + .input_fn = esp_netif_lwip_slip_input, + } +}; + +const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_slip = &s_netif_config_slip; + + +/*** + * @brief Open a serial device for communication + */ +sio_fd_t sio_open(uint8_t devnum) +{ + ESP_LOGD(TAG, "Opening device: %d\r\n", devnum); + + esp_netif_t *esp_netif = get_netif_with_esp_index(devnum); + if (!esp_netif) { + ESP_LOGE(TAG, "didn't find esp-netif with index=%d\n", devnum); + return NULL; + } + + // Return SIO handle + return esp_netif; +} + +/*** + * @brief Send a single character to the serial device (blocking) + */ +void sio_send(uint8_t c, sio_fd_t fd) +{ + esp_netif_t *esp_netif = fd; + + ESP_LOGD(TAG, "%s", __func__); + ESP_LOG_BUFFER_HEX_LEVEL(TAG, &c, 1, ESP_LOG_DEBUG); + + esp_err_t ret = esp_netif_transmit(esp_netif, &c, 1); + if (ret != ESP_OK) { + // Handle errors + ESP_LOGD(TAG, "%s: uart_write_bytes error %i", __func__, ret); + } +} diff --git a/components/esp_netif/lwip/esp_netif_lwip_slip.h b/components/esp_netif/lwip/esp_netif_lwip_slip.h index 0c64ee8a5b..8d6c55ad04 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_slip.h +++ b/components/esp_netif/lwip/esp_netif_lwip_slip.h @@ -15,8 +15,6 @@ #ifndef _ESP_NETIF_LWIP_SLIP_H_ #define _ESP_NETIF_LWIP_SLIP_H_ -typedef struct lwip_slip_ctx lwip_slip_ctx_t; - /** * @brief Creates new SLIP related structure * @@ -27,45 +25,24 @@ typedef struct lwip_slip_ctx lwip_slip_ctx_t; * - pointer to slip-netif object on success * - NULL otherwise */ -lwip_slip_ctx_t *esp_netif_new_slip(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config); - -/** - * @brief Creates new SLIP related structure - * - * @param[in] slip pointer to internal slip context instance - * - * @return - * - ESP_OK on success - */ -esp_err_t esp_netif_start_slip(lwip_slip_ctx_t *slip); - - +netif_related_data_t * esp_netif_new_slip(esp_netif_t *esp_netif, const esp_netif_netstack_config_t *esp_netif_stack_config); /** * @brief Destroys the slip netif object * * @param[in] slip pointer to internal slip context instance */ -void esp_netif_destroy_slip(lwip_slip_ctx_t *slip); +void esp_netif_destroy_slip(netif_related_data_t *slip); /** - * @brief Stops the SLIP interface + * @brief Stop the esp slip netif * - * @param[in] slip pointer to internal slip context instance + * @param[in] esp_netif handle to slip esp-netif instance * * @return * - ESP_OK on success */ -esp_err_t esp_netif_stop_slip(lwip_slip_ctx_t *slip); - -/** - * @brief Sets default netif for routing priority config - * - * @note: This function must be called from lwip thread - * - */ -void esp_netif_slip_set_default_netif(lwip_slip_ctx_t *slip_ctx); +esp_err_t esp_netif_stop_slip(esp_netif_t *esp_netif); - -#endif // _ESP_NETIF_LWIP_SLIP_H_ \ No newline at end of file +#endif // _ESP_NETIF_LWIP_SLIP_H_ diff --git a/components/esp_netif/lwip/esp_netif_lwip_slip_sio.c b/components/esp_netif/lwip/esp_netif_lwip_slip_sio.c deleted file mode 100644 index d68b5fe03d..0000000000 --- a/components/esp_netif/lwip/esp_netif_lwip_slip_sio.c +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#include - -#include "esp_log.h" -#include "driver/uart.h" - -#include "lwip/opt.h" -#include "lwip/sio.h" - -static const char *TAG = "esp-netif_lwip-slip_sio"; - -/*** - * @brief slip IO (SIO) uart driver - */ -typedef struct lwip_slip_sio { - uart_port_t uart_dev; - bool blocking; -} lwip_slip_sio_t; - -/*** - * @brief Open a serial device for communication - */ -sio_fd_t sio_open(uint8_t devnum) -{ - ESP_LOGD(TAG, "Opening device: %d\r\n", devnum); - - // Create SIO object - lwip_slip_sio_t *slip_sio = malloc(sizeof(lwip_slip_sio_t)); - - // Store device num etc. - slip_sio->uart_dev = devnum; - slip_sio->blocking = false; - - // Return SIO handle - return slip_sio; -} - -/*** - * @brief Send a single character to the serial device (blocking) - */ -void sio_send(uint8_t c, sio_fd_t fd) -{ - lwip_slip_sio_t *slip_sio = ( lwip_slip_sio_t *) fd; - - ESP_LOGD(TAG, "%s", __func__); - ESP_LOG_BUFFER_HEX_LEVEL(TAG, &c, 1, ESP_LOG_DEBUG); - - int res = uart_write_bytes(slip_sio->uart_dev, (const char *)&c, 1); - if (res < 0) { - // Handle errors - ESP_LOGD(TAG, "%s: uart_write_bytes error %i", __func__, res); - } -} - -/*** - * @brief Write to the serial port (blocking) - */ -uint32_t sio_write(sio_fd_t fd, uint8_t *data, uint32_t len) -{ - lwip_slip_sio_t *slip_sio = ( lwip_slip_sio_t *) fd; - - ESP_LOGD(TAG, "%s", __func__); - ESP_LOG_BUFFER_HEX_LEVEL(TAG, data, len, ESP_LOG_DEBUG); - - int32_t res = uart_write_bytes(slip_sio->uart_dev, (char *)data, len); - if (res < 0) { - // Handle errors - ESP_LOGD(TAG, "%s: uart_write_bytes error %i", __func__, res); - return 0; - } - - return (uint32_t) res; -} - -/*** - * @brief Receive a single character from the serial device (blocking) - */ -uint8_t sio_recv(sio_fd_t fd) -{ - lwip_slip_sio_t *slip_sio = ( lwip_slip_sio_t *) fd; - uint8_t b; - - slip_sio->blocking = true; - - while (slip_sio->blocking == true) { - int res = uart_read_bytes(slip_sio->uart_dev, &b, 1, portTICK_RATE_MS * 1); - if (res < 0) { - // Handle errors - ESP_LOGD(TAG, "%s: uart_read_bytes error %i", __func__, res); - return 0; - } else if (res == 1) { - break; - } - } - - return b; -} - -/*** - * @brief Read from the serial port (blocking, abort with `sio_read_abort`) - */ -uint32_t sio_read(sio_fd_t fd, uint8_t *data, uint32_t len) -{ - lwip_slip_sio_t *slip_sio = ( lwip_slip_sio_t *) fd; - int res = 0; - - slip_sio->blocking = true; - - while (slip_sio->blocking == true) { - res = uart_read_bytes(slip_sio->uart_dev, data, len, portTICK_RATE_MS * 1); - if (res < 0) { - // Handle errors - ESP_LOGD(TAG, "%s: uart_read_bytes error %i", __func__, res); - return 0; - } else if (res > 0) { - break; - } - } - - return (uint32_t) res; -} - -/*** - * @brief Read from the serial port (non-blocking) - */ -uint32_t sio_tryread(sio_fd_t fd, uint8_t *data, uint32_t len) -{ - lwip_slip_sio_t *slip_sio = ( lwip_slip_sio_t *) fd; - - int res = uart_read_bytes(slip_sio->uart_dev, data, len, portTICK_RATE_MS * 1); - if (res < 0) { - ESP_LOGD(TAG, "%s: uart_read_bytes error %i", __func__, res); - return 0; - } - - return (uint32_t)res; -} - - -/*** - * @brief Abort a pending sio_read call - */ -void sio_read_abort(sio_fd_t fd) -{ - lwip_slip_sio_t *slip_sio = ( lwip_slip_sio_t *) fd; - - slip_sio->blocking = false; -} - diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 7378667002..d04631b17d 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -655,13 +655,6 @@ menu "LWIP" SLIP over serial support is experimental and unsupported. - config LWIP_SLIP_RX_FROM_ISR - bool "Enable LWIP SLIP interrupt mode" - depends on LWIP_SLIP_SUPPORT - default y - help - Enable interrupt functions in SLIP netif/slipif.h - config LWIP_SLIP_DEBUG_ON bool "Enable SLIP debug log output" depends on LWIP_SLIP_SUPPORT diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index ea35bb89ca..c974a456f4 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -477,9 +477,16 @@ #ifdef CONFIG_LWIP_SLIP_SUPPORT /** - * Enable SLIP receive from ISR functions + * Enable SLIP receive from ISR functions and disable Rx thread + * + * This is the only supported mode of lwIP SLIP interface, so that + * - incoming packets are queued into pbufs + * - no thread is created from lwIP + * meaning it is the application responsibility to read data + * from IO driver and feed them to the slip interface */ -#define SLIP_RX_FROM_ISR CONFIG_LWIP_SLIP_RX_FROM_ISR +#define SLIP_RX_FROM_ISR 1 +#define SLIP_USE_RX_THREAD 0 /** * PPP_DEBUG: Enable debugging for PPP. diff --git a/examples/protocols/slip/slip_udp/CMakeLists.txt b/examples/protocols/slip/slip_udp/CMakeLists.txt index b9d68c60fe..5d7fdd6ce6 100644 --- a/examples/protocols/slip/slip_udp/CMakeLists.txt +++ b/examples/protocols/slip/slip_udp/CMakeLists.txt @@ -2,11 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(EXTRA_COMPONENT_DIRS - ../components/slip_modem/ -) - - include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(slip_client) - diff --git a/examples/protocols/slip/slip_udp/README.md b/examples/protocols/slip/slip_udp/README.md index 334d2d4673..d7869ff978 100644 --- a/examples/protocols/slip/slip_udp/README.md +++ b/examples/protocols/slip/slip_udp/README.md @@ -4,7 +4,7 @@ ## Overview -This provides SLIP support for connection to Contiki gateway devices, allowing the ESP32 to be used to bridge between low-power networks and IP (Wifi / Ethernet). +This provides SLIP support for connection to Contiki gateway devices, allowing the ESP platform board to be used to bridge between low-power networks and IP (Wifi / Ethernet). ## How to use example @@ -12,7 +12,33 @@ This provides SLIP support for connection to Contiki gateway devices, allowing t To run this example, you need an ESP32 dev board (e.g. ESP32-WROVER Kit) or ESP32 core board (e.g. ESP32-DevKitC). For test purpose, you also need a SLIP capable gateway device, such as anything running [Contiki](https://github.com/contiki-os/contiki) gateway firmware. -You can also try other modules as long as they implement the SLIP protocol. +You can also try other modules as long as they implement the SLIP protocol (e.g. linux device with slip module loaded) + +#### Setup a test SLIP device + +It is possible to configure any device with linux and a serial interface +(e.g. raspberry PI or a PC with USB to serial bridge) to enable SLIP interface. + +To test this example with such device, please follow these steps: + +- Configure IPv4 mode in the example configuration menu + +- Setup SLIP interface +``` +slattach -v -L -s 115200 -p slip /dev/ttyAMA0 +``` +where the `/dev/ttyAMA0` is the device's serial port + +- Configure IP addresses +``` +ifconfig sl0 10.0.0.1 dstaddr 10.0.0.2 +``` +where the `10.0.0.2` is IPv4 address of the ESP platform board + +- Send and receive back UDP packets, as the example implements UDP echo server +``` +nc -u 10.0.0.2 5678 +``` #### Pin Assignment @@ -30,7 +56,7 @@ You can also try other modules as long as they implement the SLIP protocol. Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` menu. - Choose the RX and TX pins - +- Choose port number and IP protocol for socket udp server For use in external projects `SLIP support` must be enabled under the `components/lwip` menu. diff --git a/examples/protocols/slip/components/slip_modem/CMakeLists.txt b/examples/protocols/slip/slip_udp/components/slip_modem/CMakeLists.txt similarity index 79% rename from examples/protocols/slip/components/slip_modem/CMakeLists.txt rename to examples/protocols/slip/slip_udp/components/slip_modem/CMakeLists.txt index 4a596ca727..7739fdfbc2 100644 --- a/examples/protocols/slip/components/slip_modem/CMakeLists.txt +++ b/examples/protocols/slip/slip_udp/components/slip_modem/CMakeLists.txt @@ -3,6 +3,6 @@ idf_component_register( SRCS "library/slip_modem.c" INCLUDE_DIRS "include" - REQUIRES lwip esp_netif + REQUIRES esp_netif ) diff --git a/examples/protocols/slip/slip_udp/components/slip_modem/component.mk b/examples/protocols/slip/slip_udp/components/slip_modem/component.mk new file mode 100644 index 0000000000..b9a426049f --- /dev/null +++ b/examples/protocols/slip/slip_udp/components/slip_modem/component.mk @@ -0,0 +1,3 @@ +COMPONENT_ADD_INCLUDEDIRS := include + +COMPONENT_SRCDIRS := library diff --git a/examples/protocols/slip/components/slip_modem/include/slip_modem.h b/examples/protocols/slip/slip_udp/components/slip_modem/include/slip_modem.h similarity index 71% rename from examples/protocols/slip/components/slip_modem/include/slip_modem.h rename to examples/protocols/slip/slip_udp/components/slip_modem/include/slip_modem.h index e0e04da4a6..2cbd4be519 100644 --- a/examples/protocols/slip/components/slip_modem/include/slip_modem.h +++ b/examples/protocols/slip/slip_udp/components/slip_modem/include/slip_modem.h @@ -1,3 +1,16 @@ +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #pragma once diff --git a/examples/protocols/slip/components/slip_modem/library/slip_modem.c b/examples/protocols/slip/slip_udp/components/slip_modem/library/slip_modem.c similarity index 80% rename from examples/protocols/slip/components/slip_modem/library/slip_modem.c rename to examples/protocols/slip/slip_udp/components/slip_modem/library/slip_modem.c index d7b6b4fba4..0583dc2380 100644 --- a/examples/protocols/slip/components/slip_modem/library/slip_modem.c +++ b/examples/protocols/slip/slip_udp/components/slip_modem/library/slip_modem.c @@ -1,28 +1,27 @@ - +// Copyright 2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #include "slip_modem.h" - #include "esp_netif.h" #include "esp_netif_slip.h" #include "esp_event.h" #include "esp_log.h" - -#include "lwip/opt.h" -#include "lwip/sio.h" -#include "lwip/ip.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - -#include "esp_netif_slip.h" - - #define SLIP_RX_TASK_PRIORITY 10 #define SLIP_RX_TASK_STACK_SIZE (4 * 1024) - static const char *TAG = "esp-slip_modem"; @@ -53,9 +52,6 @@ struct esp_slip_modem { // ESP base netif driver esp_netif_driver_base_t base; - // LWIP slip context - lwip_slip_ctx_t *slip_driver; - // Uart for use with slip esp_slip_uart_t uart; @@ -72,28 +68,15 @@ struct esp_slip_modem { }; -// Forward function definitions +// Forward function declaration static void esp_slip_modem_uart_rx_task(void *arg); static esp_err_t esp_slip_modem_post_attach(esp_netif_t *esp_netif, void *args); - -// TODO: netif internal functions required for driver operation -esp_err_t esp_netif_start_slip(lwip_slip_ctx_t *slip_ctx); -esp_err_t esp_netif_stop_slip(lwip_slip_ctx_t *slip_ctx); - -void esp_netif_lwip_slip_output(lwip_slip_ctx_t *slip_ctx, void *buffer, size_t len); -void esp_netif_lwip_slip_input(void *ctx, void *buffer, size_t len, void *eb); - - // Create a new slip netif void *esp_slip_modem_create(esp_netif_t *slip_netif, esp_slip_modem_config_t *modem_config) { ESP_LOGI(TAG, "%s: Creating slip modem (netif: %p)", __func__, slip_netif); - // Fetch lwip slip ctx object - // TODO: is the the best / a reasonable approach? - lwip_slip_ctx_t *slip_ctx = esp_netif_lwip_slip_get_ctx(slip_netif); - ESP_LOGD(TAG, "%s (netif: %p)", __func__, slip_netif); esp_slip_modem_t *slip_modem = calloc(1, sizeof(esp_slip_modem_t)); @@ -103,7 +86,6 @@ void *esp_slip_modem_create(esp_netif_t *slip_netif, esp_slip_modem_config_t *mo } // Attach driver and post_attach callbacks - slip_modem->slip_driver = slip_ctx; slip_modem->base.post_attach = esp_slip_modem_post_attach; // Attach config @@ -135,8 +117,6 @@ static esp_err_t esp_slip_driver_start(esp_slip_modem_t *slip_modem) return ESP_ERR_NO_MEM; } - // Then, initialise UART - // Build configuration uart_config_t uart_config = { .baud_rate = slip_modem->uart.uart_baud, @@ -160,7 +140,7 @@ static esp_err_t esp_slip_driver_start(esp_slip_modem_t *slip_modem) xTaskCreate(esp_slip_modem_uart_rx_task, "slip_modem_uart_rx_task", SLIP_RX_TASK_STACK_SIZE, slip_modem, SLIP_RX_TASK_PRIORITY, &slip_modem->uart.uart_rx_task); // Finally, initialise slip network interface - esp_netif_start_slip(slip_modem->slip_driver); + esp_netif_action_start(slip_modem->base.netif, 0, 0, 0); return ESP_OK; } @@ -169,7 +149,7 @@ static esp_err_t esp_slip_driver_start(esp_slip_modem_t *slip_modem) esp_err_t esp_slip_modem_destroy(esp_slip_modem_t *slip_modem) { // Stop slip driver - esp_netif_stop_slip(slip_modem->slip_driver); + esp_netif_action_stop(slip_modem->base.netif, 0, 0, 0); // Stop uart rx task vTaskDelete(slip_modem->uart.uart_rx_task); @@ -184,27 +164,21 @@ esp_err_t esp_slip_modem_destroy(esp_slip_modem_t *slip_modem) } // Modem transmit for glue logic -esp_err_t esp_slip_modem_transmit(void *slip_driver, void *buffer, size_t len) +static esp_err_t esp_slip_modem_transmit(void *slip_driver, void *buffer, size_t len) { ESP_LOGD(TAG, "%s", __func__); ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_DEBUG); + esp_slip_modem_t *slip_modem = (esp_slip_modem_t *) slip_driver; - lwip_slip_ctx_t *slip_ctx = (lwip_slip_ctx_t *) slip_driver; - - esp_netif_lwip_slip_output(slip_ctx, buffer, len); - + int32_t res = uart_write_bytes(slip_modem->uart.uart_dev, (char *)buffer, len); + if (res < 0) { + // Handle errors + ESP_LOGE(TAG, "%s: uart_write_bytes error %i", __func__, res); + return ESP_FAIL; + } return ESP_OK; } -// Modem receive for glue logic -void esp_slip_modem_receive(esp_netif_t *esp_netif, void *buffer, size_t len) -{ - ESP_LOGD(TAG, "%s", __func__); - ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_DEBUG); - - esp_netif_receive(esp_netif, buffer, len, NULL); -} - // Post-attach handler for netif static esp_err_t esp_slip_modem_post_attach(esp_netif_t *esp_netif, void *args) { @@ -215,7 +189,7 @@ static esp_err_t esp_slip_modem_post_attach(esp_netif_t *esp_netif, void *args) const esp_netif_driver_ifconfig_t driver_ifconfig = { .driver_free_rx_buffer = NULL, .transmit = esp_slip_modem_transmit, - .handle = slip_modem->slip_driver, + .handle = slip_modem, }; slip_modem->base.netif = esp_netif; @@ -226,8 +200,7 @@ static esp_err_t esp_slip_modem_post_attach(esp_netif_t *esp_netif, void *args) return ESP_OK; } -esp_err_t esp_slip_modem_set_default_handlers(esp_netif_t *esp_netif) -{ +esp_err_t esp_slip_modem_set_default_handlers(esp_netif_t *esp_netif) { esp_err_t ret; if (esp_netif == NULL) { @@ -248,8 +221,6 @@ esp_err_t esp_slip_modem_set_default_handlers(esp_netif_t *esp_netif) fail: esp_eth_clear_default_handlers(esp_netif); return ret; - - return ESP_OK; } esp_err_t esp_slip_modem_clear_default_handlers(void *esp_netif) @@ -265,15 +236,13 @@ esp_err_t esp_slip_modem_clear_default_handlers(void *esp_netif) } - static void esp_slip_modem_uart_rx_task(void *arg) { esp_slip_modem_t *slip_modem = (esp_slip_modem_t *) arg; - ESP_LOGD(TAG, "Start SLIP modem RX task (slip_modem %p slip_ctx %p filter: %p)", slip_modem, slip_modem->slip_driver, slip_modem->rx_filter); + ESP_LOGD(TAG, "Start SLIP modem RX task (slip_modem %p filter: %p)", slip_modem, slip_modem->rx_filter); ESP_LOGD(TAG, "Uart: %d, buffer: %p (%d bytes)", slip_modem->uart.uart_dev, slip_modem->buffer, slip_modem->buffer_len); - while (slip_modem->running == true) { // Read data from the UART int len = uart_read_bytes(slip_modem->uart.uart_dev, slip_modem->buffer, slip_modem->buffer_len, 1 / portTICK_RATE_MS); @@ -293,7 +262,7 @@ static void esp_slip_modem_uart_rx_task(void *arg) } // Pass received bytes in to slip interface - esp_netif_lwip_slip_input(slip_modem->slip_driver, slip_modem->buffer, len, NULL); + esp_netif_receive(slip_modem->base.netif, slip_modem->buffer, len, NULL); } // Yeild to allow other tasks to progress diff --git a/examples/protocols/slip/slip_udp/main/Kconfig.projbuild b/examples/protocols/slip/slip_udp/main/Kconfig.projbuild index 1709058d0f..e23abfa081 100644 --- a/examples/protocols/slip/slip_udp/main/Kconfig.projbuild +++ b/examples/protocols/slip/slip_udp/main/Kconfig.projbuild @@ -21,12 +21,18 @@ menu "Example Configuration" help Baud rate for UART communication - config EXAMPLE_UDP_PORT - int "Port for UDP echo server" - default 5678 - help - Port for UDP echo server in example - endmenu + config EXAMPLE_UDP_PORT + int "Port for UDP echo server" + default 5678 + help + Port for UDP echo server in example + + config EXAMPLE_IPV4 + bool "Test with IPv4 address" + default n + help + Test interface using IPv4 + endmenu diff --git a/examples/protocols/slip/slip_udp/main/slip_client_main.c b/examples/protocols/slip/slip_udp/main/slip_client_main.c index 682e363eb8..2fdab88007 100644 --- a/examples/protocols/slip/slip_udp/main/slip_client_main.c +++ b/examples/protocols/slip/slip_udp/main/slip_client_main.c @@ -9,8 +9,6 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" - #include "esp_system.h" #include "esp_log.h" @@ -19,8 +17,6 @@ #include "esp_netif_slip.h" #include "lwip/sockets.h" -#include "lwip/dns.h" -#include "lwip/netdb.h" #include "slip_modem.h" @@ -29,14 +25,12 @@ static const char *TAG = "SLIP_EXAMPLE"; #define STACK_SIZE (10 * 1024) #define PRIORITY 10 -TaskHandle_t udp_rx_tx_handle; - static void udp_rx_tx_task(void *arg) { char addr_str[128]; uint8_t rx_buff[1024]; - int sock = *(int *)arg; + int sock = (int)arg; struct sockaddr_in6 source_addr; socklen_t socklen = sizeof(source_addr); @@ -53,7 +47,11 @@ static void udp_rx_tx_task(void *arg) } // Parse out address to string - inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); + if (source_addr.sin6_family == PF_INET) { + inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); + } else if (source_addr.sin6_family == PF_INET6) { + inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); + } // Force null termination of received data and print rx_buff[len] = 0; @@ -70,37 +68,51 @@ static void udp_rx_tx_task(void *arg) vTaskDelete(NULL); } -esp_err_t udp_rx_tx_init() +esp_err_t udp_rx_tx_init(void) { // Setup bind address struct sockaddr_in6 dest_addr; +#if CONFIG_EXAMPLE_IPV4 + sa_family_t family = AF_INET; + int ip_protocol = IPPROTO_IP; + struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr; + dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY); + dest_addr_ip4->sin_family = AF_INET; + dest_addr_ip4->sin_port = htons(CONFIG_EXAMPLE_UDP_PORT); + ip_protocol = IPPROTO_IP; +#else + sa_family_t family = AF_INET6; + int ip_protocol = IPPROTO_IPV6; bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un)); - dest_addr.sin6_family = AF_INET6; + dest_addr.sin6_family = family; dest_addr.sin6_port = htons(CONFIG_EXAMPLE_UDP_PORT); +#endif // Create socket - int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6); + int sock = socket(family, SOCK_DGRAM, ip_protocol); if (sock < 0) { ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); - return -1; + return ESP_FAIL; } // Disable IPv4 and reuse address int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); +#if !CONFIG_EXAMPLE_IPV4 setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); +#endif // Bind socket int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (err < 0) { ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); - return -2; + return ESP_FAIL; } ESP_LOGI(TAG, "Socket bound, port %d", CONFIG_EXAMPLE_UDP_PORT); // Start UDP rx thread - xTaskCreate(udp_rx_tx_task, "udp_rx_tx", STACK_SIZE, &sock, PRIORITY, &udp_rx_tx_handle); + xTaskCreate(udp_rx_tx_task, "udp_rx_tx", STACK_SIZE, (void *)sock, PRIORITY, NULL); return ESP_OK; } @@ -111,7 +123,7 @@ static void slip_set_prefix(esp_netif_t *slip_netif) uint8_t buff[10] = {0}; // Fetch the slip interface IP - const ip6_addr_t *addr = esp_slip_get_ip6(slip_netif); + const esp_ip6_addr_t *addr = esp_slip_get_ip6(slip_netif); ESP_LOGI(TAG, "%s: prefix set (%08x:%08x)", __func__, lwip_ntohl(addr->addr[0]), lwip_ntohl(addr->addr[1])); @@ -129,7 +141,7 @@ static void slip_set_prefix(esp_netif_t *slip_netif) esp_netif_lwip_slip_raw_output(slip_netif, buff, 2 + 8); } -// slip_rx_filter filters incomming commands from the slip interface +// slip_rx_filter filters incoming commands from the slip interface // this implementation is designed for use with contiki slip devices bool slip_rx_filter(void *ctx, uint8_t *data, uint32_t len) { @@ -162,23 +174,34 @@ bool slip_rx_filter(void *ctx, uint8_t *data, uint32_t len) return false; } +#if CONFIG_EXAMPLE_IPV4 +static const esp_netif_ip_info_t s_slip_ip4 = { + .ip = { .addr = ESP_IP4TOADDR( 10, 0, 0, 2) }, +}; +#endif + // Initialise the SLIP interface -esp_netif_t *slip_if_init() +esp_netif_t *slip_if_init(void) { ESP_LOGI(TAG, "Initialising SLIP interface"); - esp_netif_config_t cfg = ESP_NETIF_DEFAULT_SLIP(); + esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_SLIP() +#if CONFIG_EXAMPLE_IPV4 + base_cfg.ip_info = &s_slip_ip4; +#endif + esp_netif_config_t cfg = { .base = &base_cfg, + .driver = NULL, + .stack = ESP_NETIF_NETSTACK_DEFAULT_SLIP }; + esp_netif_t *slip_netif = esp_netif_new(&cfg); - esp_netif_slip_config_t slip_config = { - .uart_dev = UART_NUM_2, - }; + esp_netif_slip_config_t slip_config; - IP6_ADDR(&slip_config.addr, + IP6_ADDR(&slip_config.ip6_addr, lwip_htonl(0xfd000000), lwip_htonl(0x00000000), lwip_htonl(0x00000000), - lwip_htonl(0x000000001) + lwip_htonl(0x00000001) ); esp_netif_slip_set_params(slip_netif, &slip_config); @@ -186,7 +209,7 @@ esp_netif_t *slip_if_init() ESP_LOGI(TAG, "Initialising SLIP modem"); esp_slip_modem_config_t modem_cfg = { - .uart_dev = UART_NUM_2, + .uart_dev = UART_NUM_1, .uart_tx_pin = CONFIG_EXAMPLE_UART_TX_PIN, .uart_rx_pin = CONFIG_EXAMPLE_UART_RX_PIN, @@ -209,7 +232,7 @@ esp_netif_t *slip_if_init() void app_main(void) { // Setup networking - tcpip_adapter_init(); + esp_netif_init(); esp_log_level_set("*", ESP_LOG_DEBUG); @@ -221,9 +244,4 @@ void app_main(void) // Setup UDP loopback service udp_rx_tx_init(); - - // Run - while (1) { - vTaskDelay(portTICK_PERIOD_MS * 10); - } }