From 52ca3a917d7bbf52381e0441e28aaac534edf099 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 21 Nov 2019 13:23:58 +0100 Subject: [PATCH 1/3] esp_netif: Support for PPPoS in esp_netif using lwip ppp client --- components/esp_common/src/esp_err_to_name.c | 6 + components/esp_netif/CMakeLists.txt | 1 + components/esp_netif/esp_netif_defaults.c | 9 + components/esp_netif/include/esp_netif.h | 22 ++- .../esp_netif/include/esp_netif_defaults.h | 20 ++ .../esp_netif/include/esp_netif_net_stack.h | 5 +- .../esp_netif/include/esp_netif_types.h | 17 +- components/esp_netif/lwip/esp_netif_lwip.c | 177 +++++++++++------- .../esp_netif/lwip/esp_netif_lwip_defaults.c | 33 +++- .../esp_netif/lwip/esp_netif_lwip_internal.h | 58 +++++- .../port/esp32/include/netif/ethernetif.h | 2 +- .../lwip/port/esp32/include/netif/wlanif.h | 2 +- components/lwip/port/esp32/netif/ethernetif.c | 3 +- components/lwip/port/esp32/netif/wlanif.c | 3 +- 14 files changed, 264 insertions(+), 94 deletions(-) diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index 24971ca490..ec97c0804e 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -488,6 +488,12 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED ERR_TBL_IT(ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED), /* 20488 0x5008 */ +# endif +# ifdef ESP_ERR_ESP_NETIF_INIT_FAILED + ERR_TBL_IT(ESP_ERR_ESP_NETIF_INIT_FAILED), /* 20489 0x5009 */ +# endif +# ifdef ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED + ERR_TBL_IT(ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED), /* 20490 0x500a */ # endif // components/esp_common/include/esp_err.h # ifdef ESP_ERR_FLASH_BASE diff --git a/components/esp_netif/CMakeLists.txt b/components/esp_netif/CMakeLists.txt index 6155f95795..b775ba3b17 100644 --- a/components/esp_netif/CMakeLists.txt +++ b/components/esp_netif/CMakeLists.txt @@ -2,6 +2,7 @@ idf_component_register(SRCS "esp_netif_handlers.c" "esp_netif_objects.c" "esp_netif_defaults.c" "lwip/esp_netif_lwip.c" + "lwip/esp_netif_lwip_ppp.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_defaults.c b/components/esp_netif/esp_netif_defaults.c index 5fc037f1db..39278857fb 100644 --- a/components/esp_netif/esp_netif_defaults.c +++ b/components/esp_netif/esp_netif_defaults.c @@ -67,3 +67,12 @@ const esp_netif_inherent_config_t _g_esp_netif_inherent_eth_config = { .if_desc = "eth", .route_prio = 50 }; + +const esp_netif_inherent_config_t _g_esp_netif_inherent_ppp_config = { + .flags = ESP_NETIF_FLAG_IS_PPP, + .lost_ip_event = IP_EVENT_PPP_LOST_IP, + .get_ip_event = IP_EVENT_PPP_GOT_IP, + .if_key = "PPP_DEF", + .if_desc = "ppp", + .route_prio = 128 +}; diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index 2f44160371..fc0cc2740c 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -26,10 +26,6 @@ #include "esp_eth_netif_glue.h" #endif -#ifdef __cplusplus -extern "C" { -#endif - // // Note: tcpip_adapter legacy API has to be included by default to provide full compatibility // for applications that used tcpip_adapter API without explicit inclusion of tcpip_adapter.h @@ -40,6 +36,10 @@ extern "C" { #undef _ESP_NETIF_SUPPRESS_LEGACY_WARNING_ #endif // CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup ESP_NETIF_INIT_API ESP-NETIF Initialization API * @brief Initialization and deinitialization of underlying TCP/IP stack and esp-netif instances @@ -101,7 +101,7 @@ void esp_netif_destroy(esp_netif_t *esp_netif); * */ esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif, - const esp_netif_driver_ifconfig_t *driver_config); + const esp_netif_driver_ifconfig_t *driver_config); /** * @brief Attaches esp_netif instance to the io driver handle @@ -411,7 +411,9 @@ int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif); * - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED * - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED */ -esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len); +esp_err_t +esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, + void *opt_val, uint32_t opt_len); /** * @brief Set or Get DHCP client option @@ -428,7 +430,9 @@ esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m * - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED * - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED */ -esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len); +esp_err_t +esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, + void *opt_val, uint32_t opt_len); /** * @brief Start DHCP client (only if enabled in interface object) @@ -630,7 +634,7 @@ void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t * @return either pointer to buf which now holds the ASCII * representation of addr or NULL if buf was too small */ -char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen); +char *esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen); /** * @brief Ascii internet address interpretation routine @@ -731,7 +735,7 @@ int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t * * @return First netif from the list if supplied parameter is NULL, next one otherwise */ -esp_netif_t* esp_netif_next(esp_netif_t* esp_netif); +esp_netif_t *esp_netif_next(esp_netif_t *esp_netif); /** * @brief Returns number of registered esp_netif objects diff --git a/components/esp_netif/include/esp_netif_defaults.h b/components/esp_netif/include/esp_netif_defaults.h index f2eea9d6ef..caa5a8a008 100644 --- a/components/esp_netif/include/esp_netif_defaults.h +++ b/components/esp_netif/include/esp_netif_defaults.h @@ -52,6 +52,16 @@ extern "C" { .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, \ .driver = NULL, \ } + +/** +* @brief Default configuration reference of PPP client +*/ +#define ESP_NETIF_DEFAULT_PPP() \ + { \ + .base = ESP_NETIF_BASE_DEFAULT_PPP, \ + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP, \ + .driver = NULL, \ + } /** * @brief Default base config (esp-netif inherent) of WIFI STA */ @@ -67,9 +77,17 @@ extern "C" { */ #define ESP_NETIF_BASE_DEFAULT_ETH &_g_esp_netif_inherent_eth_config +/** + * @brief Default base config (esp-netif inherent) of ppp interface + */ +#define ESP_NETIF_BASE_DEFAULT_PPP &_g_esp_netif_inherent_ppp_config + + #define ESP_NETIF_NETSTACK_DEFAULT_ETH _g_esp_netif_netstack_default_eth #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 + // // Include default network stacks configs // - Network stack configurations are provided in a specific network stack @@ -79,6 +97,7 @@ extern "C" { extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_eth; extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta; extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap; +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_ppp; // // Include default common configs inherent to esp-netif @@ -88,6 +107,7 @@ extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap; extern const esp_netif_inherent_config_t _g_esp_netif_inherent_sta_config; extern const esp_netif_inherent_config_t _g_esp_netif_inherent_ap_config; extern const esp_netif_inherent_config_t _g_esp_netif_inherent_eth_config; +extern const esp_netif_inherent_config_t _g_esp_netif_inherent_ppp_config; #ifdef __cplusplus } diff --git a/components/esp_netif/include/esp_netif_net_stack.h b/components/esp_netif/include/esp_netif_net_stack.h index 8b1b2eaef7..334183a119 100644 --- a/components/esp_netif/include/esp_netif_net_stack.h +++ b/components/esp_netif/include/esp_netif_net_stack.h @@ -37,7 +37,10 @@ extern "C" { esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev); /** - * @brief Returns network stack specific implementation handle + * @brief Returns network stack specific implementation handle (if supported) + * + * Note that it is not supported to acquire PPP netif impl pointer and + * this function will return NULL for esp_netif instances configured to PPP mode * * @param[in] esp_netif Handle to esp-netif instance * diff --git a/components/esp_netif/include/esp_netif_types.h b/components/esp_netif/include/esp_netif_types.h index 05373ba5b0..9c785ad883 100644 --- a/components/esp_netif/include/esp_netif_types.h +++ b/components/esp_netif/include/esp_netif_types.h @@ -31,6 +31,8 @@ extern "C" { #define ESP_ERR_ESP_NETIF_NO_MEM ESP_ERR_ESP_NETIF_BASE + 0x06 #define ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED ESP_ERR_ESP_NETIF_BASE + 0x07 #define ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED ESP_ERR_ESP_NETIF_BASE + 0x08 +#define ESP_ERR_ESP_NETIF_INIT_FAILED ESP_ERR_ESP_NETIF_BASE + 0x09 +#define ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED ESP_ERR_ESP_NETIF_BASE + 0x0A /** @brief Type of esp_netif_object server */ @@ -80,11 +82,13 @@ typedef enum{ /** IP event declarations */ typedef enum { - IP_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */ - IP_EVENT_STA_LOST_IP, /*!< ESP32 station lost IP and the IP is reset to 0 */ - IP_EVENT_AP_STAIPASSIGNED, /*!< ESP32 soft-AP assign an IP to a connected station */ - IP_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */ - IP_EVENT_ETH_GOT_IP, /*!< ESP32 ethernet got IP from connected AP */ + IP_EVENT_STA_GOT_IP, /*!< station got IP from connected AP */ + IP_EVENT_STA_LOST_IP, /*!< station lost IP and the IP is reset to 0 */ + IP_EVENT_AP_STAIPASSIGNED, /*!< soft-AP assign an IP to a connected station */ + IP_EVENT_GOT_IP6, /*!< station or ap or ethernet interface v6IP addr is preferred */ + IP_EVENT_ETH_GOT_IP, /*!< ethernet got IP from connected AP */ + IP_EVENT_PPP_GOT_IP, /*!< PPP interface got IP */ + IP_EVENT_PPP_LOST_IP, /*!< PPP interface lost IP */ } ip_event_t; /** @brief IP event base declaration */ @@ -131,7 +135,8 @@ typedef enum esp_netif_flags { ESP_NETIF_DHCP_SERVER = 1 << 1, ESP_NETIF_FLAG_AUTOUP = 1 << 2, ESP_NETIF_FLAG_GARP = 1 << 3, - ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 << 4 + ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 << 4, + ESP_NETIF_FLAG_IS_PPP = 1 << 5 } esp_netif_flags_t; typedef enum esp_netif_ip_event_type { diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index c736577451..91e7b13fd3 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include "esp_netif_lwip_internal.h" @@ -32,6 +33,7 @@ #include "lwip/dns.h" #endif +#include "esp_netif_lwip_ppp.h" #include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver_options.h" @@ -45,10 +47,13 @@ #define ESP_NETIF_HOSTNAME_MAX_SIZE 32 /** - * @brief thread safe tcpip function utility macro + * @brief lwip thread safe tcpip function utility macro */ -#define _LWIP_TASK_IPC_CALL(function, netif, param) \ -{ \ +#define _RUN_IN_LWIP_TASK_IF_SUPPORTED(function, netif, param) \ +{ \ + if (netif->is_ppp_netif) { \ + return ESP_ERR_NOT_SUPPORTED; \ + } \ return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); \ } @@ -61,42 +66,6 @@ typedef enum esp_netif_action { ESP_NETIF_STOPPED, } esp_netif_action_t; -/** - * @brief Main esp-netif container with interface related information - */ -struct esp_netif_obj { - // default interface addresses - uint8_t mac[NETIF_MAX_HWADDR_LEN]; - esp_netif_ip_info_t* ip_info; - esp_netif_ip_info_t* ip_info_old; - - // lwip netif related - struct netif* lwip_netif; - err_t (*lwip_init_fn)(struct netif*); - void (*lwip_input_fn)(struct netif *netif, void *buffer, size_t len, void *eb); - - // io driver related - void* driver_handle; - esp_err_t (*driver_transmit)(void *h, void *buffer, size_t len); - void (*driver_free_rx_buffer)(void *h, void* buffer); - - // dhcp related - esp_netif_dhcp_status_t dhcpc_status; - esp_netif_dhcp_status_t dhcps_status; - bool timer_running; - - // event translation - ip_event_t get_ip_event; - ip_event_t lost_ip_event; - - // misc flags, types, keys, priority - esp_netif_flags_t flags; - char * hostname; - char * if_key; - char * if_desc; - int route_prio; -}; - // // Internal variables for this module // @@ -167,6 +136,20 @@ static esp_netif_t* esp_netif_is_active(esp_netif_t *arg) return NULL; } +/** + * @brief This function sets default netif no matter which implementation used + * + * @param esp_netif handle to network interface + */ +static void esp_netif_set_default_netif(esp_netif_t *esp_netif) +{ + if (esp_netif->is_ppp_netif) { + esp_netif_ppp_set_default_netif(esp_netif->netif_handle); + } else { + netif_set_default(esp_netif->netif_handle); + } +} + /** * @brief This function sets default routing netif based on priorities of all interfaces which are up * @param esp_netif current interface which just updated state @@ -183,10 +166,10 @@ static void esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_act s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif); if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif) && (s_last_default_esp_netif->route_prio > esp_netif->route_prio)) { - netif_set_default(s_last_default_esp_netif->lwip_netif); + esp_netif_set_default_netif(s_last_default_esp_netif); } else if (esp_netif_is_netif_up(esp_netif)) { s_last_default_esp_netif = esp_netif; - netif_set_default(s_last_default_esp_netif->lwip_netif); + esp_netif_set_default_netif(s_last_default_esp_netif); } } break; @@ -212,7 +195,7 @@ static void esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_act } esp_netif_list_unlock(); if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) { - netif_set_default(s_last_default_esp_netif->lwip_netif); + esp_netif_set_default_netif(s_last_default_esp_netif); } } break; @@ -243,13 +226,15 @@ esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif) esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev) { + // ppp_pcb ptr would never get to app code, so this function only works with vanilla lwip impl struct netif *lwip_netif = dev; return lwip_netif->state; } void* esp_netif_get_netif_impl(esp_netif_t *esp_netif) { - if (esp_netif) { + // get impl ptr only for vanilla lwip impl (ppp_pcb not supported) + if (esp_netif && !esp_netif->is_ppp_netif) { return esp_netif->lwip_netif; } return NULL; @@ -333,11 +318,25 @@ 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 (esp_netif_stack_config->init_fn) { - esp_netif->lwip_init_fn = esp_netif_stack_config->init_fn; - } - if (esp_netif_stack_config->input_fn) { - esp_netif->lwip_input_fn = esp_netif_stack_config->input_fn; + 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) { + 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; + } else { + 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 lwip_netif itself + esp_netif->netif_handle = esp_netif->lwip_netif; + } // Install IO functions only if provided -- connects driver and netif @@ -442,6 +441,14 @@ static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif) return ESP_ERR_NO_MEM; } } + if (esp_netif->flags & ESP_NETIF_FLAG_IS_PPP) { + err_t err = esp_netif->lwip_init_fn(NULL); + if (err != ERR_OK) { + ESP_LOGE(TAG, "Init netif failed with %d", err); + return ESP_ERR_ESP_NETIF_INIT_FAILED; + } + } + if (NULL == netif_add(esp_netif->lwip_netif, (struct ip4_addr*)&esp_netif->ip_info->ip, (struct ip4_addr*)&esp_netif->ip_info->netmask, (struct ip4_addr*)&esp_netif->ip_info->gw, esp_netif, esp_netif->lwip_init_fn, tcpip_input)) { @@ -460,6 +467,9 @@ 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); + } free(esp_netif->lwip_netif); free(esp_netif->hostname); if (s_last_default_esp_netif == esp_netif) { @@ -510,6 +520,9 @@ 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) { + return ESP_ERR_NOT_SUPPORTED; + } memcpy(esp_netif->mac, mac, NETIF_MAX_HWADDR_LEN); memcpy(esp_netif->lwip_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN); return ESP_OK; @@ -601,7 +614,18 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_start(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_start_api, esp_netif, NULL) +esp_err_t esp_netif_start(esp_netif_t *esp_netif) +{ + if (esp_netif->is_ppp_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; + } + return esp_netif_lwip_ipc_call(esp_netif_start_api, esp_netif, NULL); +} static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) { @@ -639,7 +663,18 @@ static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_stop(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_stop_api, esp_netif, NULL) +esp_err_t esp_netif_stop(esp_netif_t *esp_netif) +{ + if (esp_netif->is_ppp_netif) { + // No need to stop PPP interface in lwip thread + esp_err_t ret = esp_netif_stop_ppp(esp_netif->lwip_ppp_ctx); + if (ret == ESP_OK) { + esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);; + } + return ret; + } + return esp_netif_lwip_ipc_call(esp_netif_stop_api, esp_netif, NULL); +} // // IO translate functions @@ -657,7 +692,7 @@ esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len) esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb) { - esp_netif->lwip_input_fn(esp_netif->lwip_netif, buffer, len, eb); + esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb); return ESP_OK; } @@ -817,7 +852,7 @@ static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_dhcpc_stop_api, esp_netif, NULL) +esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_stop_api, esp_netif, NULL) static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg) { @@ -866,11 +901,11 @@ static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg) } } -esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_dhcpc_start_api, esp_netif, NULL) +esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_start_api, esp_netif, NULL) 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)) { + if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) || esp_netif->is_ppp_netif) { return ESP_ERR_INVALID_ARG; } @@ -880,7 +915,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)) { + if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_SERVER) || esp_netif->is_ppp_netif) { return ESP_ERR_INVALID_ARG; } @@ -915,7 +950,7 @@ static esp_err_t esp_netif_dhcps_start_api(esp_netif_api_msg_t *msg) } } -esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_dhcps_start_api, esp_netif, NULL) +esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_start_api, esp_netif, NULL) static esp_err_t esp_netif_dhcps_stop_api(esp_netif_api_msg_t *msg) { @@ -945,7 +980,7 @@ static esp_err_t esp_netif_dhcps_stop_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_dhcps_stop_api, esp_netif, NULL) +esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_stop_api, esp_netif, NULL) static esp_err_t esp_netif_set_hostname_api(esp_netif_api_msg_t *msg) { @@ -984,13 +1019,13 @@ static esp_err_t esp_netif_set_hostname_api(esp_netif_api_msg_t *msg) #endif } -esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname) _LWIP_TASK_IPC_CALL(esp_netif_set_hostname_api, esp_netif, hostname) +esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_hostname_api, esp_netif, hostname) 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) { + if (!esp_netif || esp_netif->is_ppp_netif) { return ESP_ERR_INVALID_ARG; } @@ -1029,7 +1064,7 @@ static esp_err_t esp_netif_up_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_up(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_up_api, esp_netif, NULL) +esp_err_t esp_netif_up(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_up_api, esp_netif, NULL) static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg) { @@ -1063,7 +1098,7 @@ static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_down(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_down_api, esp_netif, NULL) +esp_err_t esp_netif_down(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_down_api, esp_netif, NULL) bool esp_netif_is_netif_up(esp_netif_t *esp_netif) { @@ -1135,7 +1170,7 @@ static esp_err_t esp_netif_set_ip_old_info_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _LWIP_TASK_IPC_CALL(esp_netif_set_ip_old_info_api, esp_netif, ip_info) +esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_old_info_api, esp_netif, ip_info) static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg) { @@ -1195,7 +1230,7 @@ static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg) return ESP_OK; } -esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _LWIP_TASK_IPC_CALL(esp_netif_set_ip_info_api, esp_netif, ip_info) +esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_info_api, esp_netif, ip_info) static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) { @@ -1242,6 +1277,9 @@ 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) { + return ESP_ERR_NOT_SUPPORTED; + } esp_netif_dns_param_t dns_param = { .dns_type = type, .dns_info = dns @@ -1279,6 +1317,15 @@ 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) { + const ip_addr_t *dns_ip = dns_getserver(type); + if (dns_ip == IP_ADDR_ANY) { + return ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED; + } + memcpy(&dns->ip.u_addr.ip4, &dns_ip->u_addr.ip4, sizeof(ip4_addr_t)); + return ESP_OK; + } + esp_netif_dns_param_t dns_param = { .dns_type = type, .dns_info = dns @@ -1330,13 +1377,13 @@ static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg) } } -esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif) _LWIP_TASK_IPC_CALL(esp_netif_create_ip6_linklocal_api, esp_netif, NULL) +esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_create_ip6_linklocal_api, esp_netif, NULL) esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6) { ESP_LOGD(TAG, "%s esp-netif:%p", __func__, esp_netif); - if (esp_netif == NULL || if_ip6 == NULL) { + if (esp_netif == NULL || if_ip6 == NULL || esp_netif->is_ppp_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 6fc61088ac..955285024b 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_defaults.c +++ b/components/esp_netif/lwip/esp_netif_lwip_defaults.c @@ -14,6 +14,7 @@ #include "esp_netif.h" #include "esp_netif_lwip_internal.h" +#include "esp_netif_lwip_ppp.h" #include "netif/wlanif.h" #include "netif/ethernetif.h" @@ -24,18 +25,36 @@ // static const struct esp_netif_netstack_config s_eth_netif_config = { - .init_fn = ethernetif_init, - .input_fn = ethernetif_input + .lwip = { + .init_fn = ethernetif_init, + .input_fn = ethernetif_input + } }; static const struct esp_netif_netstack_config s_wifi_netif_config_ap = { - .init_fn = wlanif_init_ap, - .input_fn = wlanif_input + .lwip = { + .init_fn = wlanif_init_ap, + .input_fn = wlanif_input + } + }; static const struct esp_netif_netstack_config s_wifi_netif_config_sta = { - .init_fn = wlanif_init_sta, - .input_fn = wlanif_input + .lwip = { + .init_fn = wlanif_init_sta, + .input_fn = wlanif_input + } +}; + +static const struct esp_netif_netstack_config s_netif_config_ppp = { + .lwip_ppp = { + .input_fn = esp_netif_lwip_ppp_input, + .ppp_events = { + .ppp_error_event_enabled = true, + .ppp_phase_event_enabled = false + } + } }; 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; \ No newline at end of file +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; \ No newline at end of file diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 56ac90d68b..853b0629e8 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -15,12 +15,25 @@ #pragma once #include "esp_netif.h" +#include "esp_netif_ppp.h" #include "lwip/netif.h" +struct esp_netif_netstack_lwip_vanilla_config { + err_t (*init_fn)(struct netif*); + void (*input_fn)(void *netif, void *buffer, size_t len, void *eb); +}; + +struct esp_netif_netstack_lwip_ppp_config { + void (*input_fn)(void *netif, void *buffer, size_t len, void *eb); + esp_netif_ppp_config_t ppp_events; +}; + // LWIP netif specific network stack configuration struct esp_netif_netstack_config { - err_t (*init_fn)(struct netif*); - void (*input_fn)(struct netif *netif, void *buffer, size_t len, void *eb); + union { + struct esp_netif_netstack_lwip_vanilla_config lwip; + struct esp_netif_netstack_lwip_ppp_config lwip_ppp; + }; }; struct esp_netif_api_msg_s; @@ -45,3 +58,44 @@ typedef struct esp_netif_ip_lost_timer_s { bool timer_running; } esp_netif_ip_lost_timer_t; +// Forward declare the ppp context +typedef struct lwip_ppp_ctx lwip_ppp_ctx_t; + +/** + * @brief Main esp-netif container with interface related information + */ +struct esp_netif_obj { + // default interface addresses + uint8_t mac[NETIF_MAX_HWADDR_LEN]; + esp_netif_ip_info_t* ip_info; + esp_netif_ip_info_t* ip_info_old; + + // lwip netif related + struct netif *lwip_netif; + lwip_ppp_ctx_t *lwip_ppp_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; + + // io driver related + void* driver_handle; + esp_err_t (*driver_transmit)(void *h, void *buffer, size_t len); + void (*driver_free_rx_buffer)(void *h, void* buffer); + + // dhcp related + esp_netif_dhcp_status_t dhcpc_status; + esp_netif_dhcp_status_t dhcps_status; + bool timer_running; + + // event translation + ip_event_t get_ip_event; + ip_event_t lost_ip_event; + + // misc flags, types, keys, priority + esp_netif_flags_t flags; + char * hostname; + char * if_key; + char * if_desc; + int route_prio; +}; diff --git a/components/lwip/port/esp32/include/netif/ethernetif.h b/components/lwip/port/esp32/include/netif/ethernetif.h index 9abd1e4ee9..d5d23b3d39 100644 --- a/components/lwip/port/esp32/include/netif/ethernetif.h +++ b/components/lwip/port/esp32/include/netif/ethernetif.h @@ -24,7 +24,7 @@ extern "C" { err_t ethernetif_init(struct netif *netif); -void ethernetif_input(struct netif *netif, void *buffer, size_t len, void *eb); +void ethernetif_input(void *h, void *buffer, size_t len, void *eb); void netif_reg_addr_change_cb(void* cb); diff --git a/components/lwip/port/esp32/include/netif/wlanif.h b/components/lwip/port/esp32/include/netif/wlanif.h index d3e39e2ab2..4535b6cb51 100644 --- a/components/lwip/port/esp32/include/netif/wlanif.h +++ b/components/lwip/port/esp32/include/netif/wlanif.h @@ -27,7 +27,7 @@ extern "C" { err_t wlanif_init_ap(struct netif *netif); err_t wlanif_init_sta(struct netif *netif); -void wlanif_input(struct netif *netif, void *buffer, size_t len, void* eb); +void wlanif_input(void *netif, void *buffer, size_t len, void* eb); err_t wlanif_init(struct netif *netif); wifi_interface_t wifi_get_interface(void *dev); diff --git a/components/lwip/port/esp32/netif/ethernetif.c b/components/lwip/port/esp32/netif/ethernetif.c index eac9823809..3c75bd1ebe 100644 --- a/components/lwip/port/esp32/netif/ethernetif.c +++ b/components/lwip/port/esp32/netif/ethernetif.c @@ -151,8 +151,9 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p) * @param buffer ethernet buffer * @param len length of buffer */ -void ethernetif_input(struct netif *netif, void *buffer, size_t len, void *eb) +void ethernetif_input(void *h, void *buffer, size_t len, void *eb) { + struct netif *netif = h; struct pbuf *p; if (buffer == NULL || !netif_is_up(netif)) { diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index 4b5c839d1c..e1d0bed6b9 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -154,8 +154,9 @@ low_level_output(struct netif *netif, struct pbuf *p) * @param netif the lwip network interface structure for this ethernetif */ void ESP_IRAM_ATTR -wlanif_input(struct netif *netif, void *buffer, size_t len, void* eb) +wlanif_input(void *h, void *buffer, size_t len, void* eb) { + struct netif * netif = h; esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); struct pbuf *p; From 25913af2cc12cfa4667e23d931f45915a22532fe Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 11 Nov 2019 16:38:43 +0100 Subject: [PATCH 2/3] pppos_client: udated example code to use esp-netif in PPP configuration --- components/esp_netif/include/esp_netif_ppp.h | 109 ++++++ .../esp_netif/lwip/esp_netif_lwip_ppp.c | 327 ++++++++++++++++++ .../esp_netif/lwip/esp_netif_lwip_ppp.h | 76 ++++ .../port/esp32/include/netif/ethernetif.h | 2 +- .../components/modem/CMakeLists.txt | 1 + .../components/modem/include/esp_modem.h | 38 +- .../modem/include/esp_modem_netif.h | 53 +++ .../components/modem/src/esp_modem.c | 191 ++-------- .../components/modem/src/esp_modem_netif.c | 155 +++++++++ .../pppos_client/main/pppos_client_main.c | 90 ++++- 10 files changed, 838 insertions(+), 204 deletions(-) create mode 100644 components/esp_netif/include/esp_netif_ppp.h create mode 100644 components/esp_netif/lwip/esp_netif_lwip_ppp.c create mode 100644 components/esp_netif/lwip/esp_netif_lwip_ppp.h create mode 100644 examples/protocols/pppos_client/components/modem/include/esp_modem_netif.h create mode 100644 examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c diff --git a/components/esp_netif/include/esp_netif_ppp.h b/components/esp_netif/include/esp_netif_ppp.h new file mode 100644 index 0000000000..b6df9fdfdb --- /dev/null +++ b/components/esp_netif/include/esp_netif_ppp.h @@ -0,0 +1,109 @@ +// 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. +// + +#ifndef _ESP_NETIF_PPP_H_ +#define _ESP_NETIF_PPP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief PPP event base */ +ESP_EVENT_DECLARE_BASE(NETIF_PPP_STATUS); + +/** @brief Configuration structure for PPP network interface + * + */ +typedef struct esp_netif_ppp_config { + bool ppp_phase_event_enabled; /**< Enables events coming from PPP PHASE change */ + bool ppp_error_event_enabled; /**< Enables events from main PPP state machine producing errors */ +} esp_netif_ppp_config_t; + +/** @brief event id offset for PHASE related events + * + * All PPP related events are produced from esp-netif under `NETIF_PPP_STATUS`, this offset defines + * helps distinguish between error and phase events + */ +#define NETIF_PP_PHASE_OFFSET (0x100) + +/** @brief event ids for different PPP related events + * + */ +typedef enum { + NETIF_PPP_ERRORNONE = 0, /* No error. */ + NETIF_PPP_ERRORPARAM = 1, /* Invalid parameter. */ + NETIF_PPP_ERROROPEN = 2, /* Unable to open PPP session. */ + NETIF_PPP_ERRORDEVICE = 3, /* Invalid I/O device for PPP. */ + NETIF_PPP_ERRORALLOC = 4, /* Unable to allocate resources. */ + NETIF_PPP_ERRORUSER = 5, /* User interrupt. */ + NETIF_PPP_ERRORCONNECT = 6, /* Connection lost. */ + NETIF_PPP_ERRORAUTHFAIL = 7, /* Failed authentication challenge. */ + NETIF_PPP_ERRORPROTOCOL = 8, /* Failed to meet protocol. */ + NETIF_PPP_ERRORPEERDEAD = 9, /* Connection timeout */ + NETIF_PPP_ERRORIDLETIMEOUT = 10, /* Idle Timeout */ + NETIF_PPP_ERRORCONNECTTIME = 11, /* Max connect time reached */ + NETIF_PPP_ERRORLOOPBACK = 12, /* Loopback detected */ + NETIF_PPP_PHASE_DEAD = NETIF_PP_PHASE_OFFSET + 0, + NETIF_PPP_PHASE_MASTER = NETIF_PP_PHASE_OFFSET + 1, + NETIF_PPP_PHASE_HOLDOFF = NETIF_PP_PHASE_OFFSET + 2, + NETIF_PPP_PHASE_INITIALIZE = NETIF_PP_PHASE_OFFSET + 3, + NETIF_PPP_PHASE_SERIALCONN = NETIF_PP_PHASE_OFFSET + 4, + NETIF_PPP_PHASE_DORMANT = NETIF_PP_PHASE_OFFSET + 5, + NETIF_PPP_PHASE_ESTABLISH = NETIF_PP_PHASE_OFFSET + 6, + NETIF_PPP_PHASE_AUTHENTICATE = NETIF_PP_PHASE_OFFSET + 7, + NETIF_PPP_PHASE_CALLBACK = NETIF_PP_PHASE_OFFSET + 8, + NETIF_PPP_PHASE_NETWORK = NETIF_PP_PHASE_OFFSET + 9, + NETIF_PPP_PHASE_RUNNING = NETIF_PP_PHASE_OFFSET + 10, + NETIF_PPP_PHASE_TERMINATE = NETIF_PP_PHASE_OFFSET + 11, + NETIF_PPP_PHASE_DISCONNECT = NETIF_PP_PHASE_OFFSET + 12, +} esp_netif_ppp_status_event_t; + +/** @brief definitions of different authorisation types + * + */ +typedef enum { + NETIF_PPP_AUTHTYPE_PAP = 0x01, + NETIF_PPP_AUTHTYPE_CHAP = 0x02, + NETIF_PPP_AUTHTYPE_MSCHAP = 0x04, + NETIF_PPP_AUTHTYPE_MSCHAP_V2 = 0x08, + NETIF_PPP_AUTHTYPE_EAP = 0x10, +} esp_netif_auth_type_t; + +/** @brief Sets the auth parameters for the supplied esp-netif. + * + * @param[in] esp_netif Handle to esp-netif instance + * @param[in] authtype Authorisation type + * @param[in] user User name + * @param[in] passwd Password + * + * @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not PPP + */ +esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd); + +/** @brief Sets common parameters for the supplied esp-netif. + * + * @param[in] esp_netif Handle to esp-netif instance + * @param[in] config Pointer to PPP netif configuration structure + * + * @return ESP_OK on success, ESP_ERR_ESP_NETIF_INVALID_PARAMS if netif null or not PPP + */ +esp_err_t esp_netif_ppp_set_params(esp_netif_t *netif, const esp_netif_ppp_config_t *config); + + +#ifdef __cplusplus +} +#endif + +#endif //_ESP_NETIF_PPP_H_ diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c new file mode 100644 index 0000000000..9a5cc9b015 --- /dev/null +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -0,0 +1,327 @@ +// 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 "lwip/dns.h" +#include "esp_netif.h" +#include "netif/ppp/pppapi.h" +#include "netif/ppp/pppos.h" +#include "esp_log.h" +#include "esp_netif_net_stack.h" +#include "esp_event.h" +#include "esp_netif_ppp.h" +#include "esp_netif_lwip_internal.h" + +ESP_EVENT_DEFINE_BASE(NETIF_PPP_STATUS); + +static const char *TAG = "esp-netif_lwip-ppp"; + +#if PPPOS_SUPPORT + +/** + * @brief internal lwip_ppp context struct, used to hold PPP netif related parameters + */ +struct lwip_ppp_ctx { + bool ppp_phase_event_enabled; + bool ppp_error_event_enabled; + ppp_pcb *ppp; +}; + +/** + * @brief lwip callback from PPP client used here to produce PPP error related events, + * as well as some IP events + */ +static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx) +{ + struct netif *pppif = ppp_netif(pcb); + const ip_addr_t *dest_ip = NULL; + ip_event_ap_staipassigned_t evt = { 0 }; + esp_err_t err; + esp_netif_t *netif = ctx; + struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; + esp_netif_ip_info_t ipinfo = { {0}, {0}, {0} }; + esp_ip4_addr_t ns1; + esp_ip4_addr_t ns2; + switch (err_code) { + case PPPERR_NONE: /* Connected */ + ESP_LOGI(TAG, "Connected"); + + ipinfo.ip.addr = pppif->ip_addr.u_addr.ip4.addr; + ipinfo.gw.addr = pppif->gw.u_addr.ip4.addr; + ipinfo.netmask.addr = pppif->netmask.u_addr.ip4.addr; + dest_ip = dns_getserver(0); + if(dest_ip != NULL){ + ns1.addr = (*dest_ip).u_addr.ip4.addr; + } + dest_ip = dns_getserver(1); + if(dest_ip != NULL){ + ns2.addr = (*dest_ip).u_addr.ip4.addr; + } + ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&ns1)); + ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&ns2)); + + evt.ip.addr = ipinfo.ip.addr; + + err = esp_event_post(IP_EVENT, netif->get_ip_event, &evt, sizeof(evt), 0); + if (ESP_OK != err) { + ESP_LOGE(TAG, "esp_event_send_internal failed with code %d", err); + } + return; + + case PPPERR_PARAM: + ESP_LOGE(TAG, "Invalid parameter"); + break; + case PPPERR_OPEN: + ESP_LOGE(TAG, "Unable to open PPP session"); + break; + case PPPERR_DEVICE: + ESP_LOGE(TAG, "Invalid I/O device for PPP"); + break; + case PPPERR_ALLOC: + ESP_LOGE(TAG, "Unable to allocate resources"); + break; + case PPPERR_USER: /* User interrupt */ + ESP_LOGI(TAG, "User interrupt"); + break; + case PPPERR_CONNECT: /* Connection lost */ + ESP_LOGI(TAG, "Connection lost"); + err = esp_event_post(IP_EVENT, netif->lost_ip_event, &evt, sizeof(evt), 0); + + if (ESP_OK != err) { + ESP_LOGE(TAG, "esp_event_send_internal failed with code %d", err); + } + return; + + case PPPERR_AUTHFAIL: + ESP_LOGE(TAG, "Failed authentication challenge"); + break; + case PPPERR_PROTOCOL: + ESP_LOGE(TAG, "Failed to meet protocol"); + break; + case PPPERR_PEERDEAD: + ESP_LOGE(TAG, "Connection timeout"); + break; + case PPPERR_IDLETIMEOUT: + ESP_LOGE(TAG, "Idle Timeout"); + break; + case PPPERR_CONNECTTIME: + ESP_LOGE(TAG, "Max connect time reached"); + break; + case PPPERR_LOOPBACK: + ESP_LOGE(TAG, "Loopback detected"); + break; + default: + ESP_LOGE(TAG, "Unknown error code %d", err_code); + break; + } + if (obj->ppp_error_event_enabled) { + err = esp_event_post(NETIF_PPP_STATUS, err_code, netif, sizeof(netif), 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_event_post failed with code %d", err); + } + + } +} + +#if PPP_NOTIFY_PHASE +/** + * @brief Notify phase callback which is called on each PPP internal state change + * + * @param pcb PPP control block + * @param phase Phase ID + * @param ctx Context of callback + */ +static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx) +{ + switch (phase) { + case PPP_PHASE_DEAD: + ESP_LOGD(TAG, "Phase Dead"); + break; + case PPP_PHASE_INITIALIZE: + ESP_LOGD(TAG, "Phase Start"); + break; + case PPP_PHASE_ESTABLISH: + ESP_LOGD(TAG, "Phase Establish"); + break; + case PPP_PHASE_AUTHENTICATE: + ESP_LOGD(TAG, "Phase Authenticate"); + break; + case PPP_PHASE_NETWORK: + ESP_LOGD(TAG, "Phase Network"); + break; + case PPP_PHASE_RUNNING: + ESP_LOGD(TAG, "Phase Running"); + break; + case PPP_PHASE_TERMINATE: + ESP_LOGD(TAG, "Phase Terminate"); + break; + case PPP_PHASE_DISCONNECT: + ESP_LOGD(TAG, "Phase Disconnect"); + break; + default: + ESP_LOGW(TAG, "Phase Unknown: %d", phase); + break; + } + esp_netif_t *netif = ctx; + struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; + 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) { + ESP_LOGE(TAG, "esp_event_post failed with code %d", err); + } + } +} +#endif // PPP_NOTIFY_PHASE + +/** + * @brief PPP low level output callback used to transmit data using standard esp-netif interafce + * + * @param pcb PPP control block + * @param data Buffer to write to serial port + * @param len Length of the data buffer + * @param ctx Context of callback + * + * @return uint32_t Length of data successfully sent + */ +static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *netif) +{ + esp_err_t ret = esp_netif_transmit(netif, data, len); + if (ret == ESP_OK) { + return len; + } + return 0; +} + +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) { + return ESP_ERR_ESP_NETIF_INVALID_PARAMS; + } + struct lwip_ppp_ctx *obj = netif->lwip_ppp_ctx; +#if PAP_SUPPORT + pppapi_set_auth(obj->ppp, authtype, user, passwd); +#elif CHAP_SUPPORT + pppapi_set_auth(obj->ppp, authtype, user, passwd); +#else +#error "Unsupported AUTH Negotiation" +#endif + return ESP_OK; +} + +void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx) +{ + pppapi_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) +{ + struct netif * netif_impl = esp_netif->lwip_netif; + struct lwip_ppp_ctx * ppp_obj = calloc(1, sizeof(struct lwip_ppp_ctx)); + if (ppp_obj == NULL) { + ESP_LOGE(TAG, "%s: cannot allocate lwip_ppp_ctx", __func__); + return NULL; + } + + 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__); + } +#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; +} + +esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp_ctx) +{ + 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) { + ESP_LOGE(TAG, "%s: PPP connection cannot be started", __func__); + return ESP_FAIL; + } + return ESP_OK; +} + +void esp_netif_lwip_ppp_input(void *ppp_ctx, void *buffer, size_t len, void *eb) +{ + struct lwip_ppp_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_LOGD(TAG, "%s: Stopped PPP connection: %p", __func__, ppp_ctx->ppp); + err_t ret = pppapi_close(ppp_ctx->ppp, 0); + if (ret != ERR_OK) { + ESP_LOGE(TAG, "pppapi_close failed with %d", ret); + return ESP_FAIL; + } + return ESP_OK; +} + +void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp_ctx) +{ + pppapi_free(ppp_ctx->ppp); + free(ppp_ctx); +} + +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; + 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 */ + +/** + * @brief If PPP not enabled in menuconfig, log the error and return appropriate code indicating failure +*/ +#define LOG_PPP_DISABLED_AND_DO(action) \ + { \ + ESP_LOGE(TAG, "%s not supported, please enable PPP in lwIP component configuration", __func__); \ + action; \ + } + +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) + 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) + LOG_PPP_DISABLED_AND_DO(return NULL) + +esp_err_t esp_netif_start_ppp(lwip_ppp_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) + LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED) + +void esp_netif_destroy_ppp(lwip_ppp_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) + LOG_PPP_DISABLED_AND_DO(return ESP_ERR_NOT_SUPPORTED) + +#endif /* PPPOS_SUPPORT */ diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.h b/components/esp_netif/lwip/esp_netif_lwip_ppp.h new file mode 100644 index 0000000000..25047f795e --- /dev/null +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.h @@ -0,0 +1,76 @@ +// 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. + +#ifndef _ESP_NETIF_LWIP_PPP_H_ +#define _ESP_NETIF_LWIP_PPP_H_ + +/** + * @brief Creates new PPP related structure + * + * @param[in] esp_netif pointer esp-netif instance + * @param[in] stack_config TCP/IP stack configuration structure + * + * @return + * - 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); + +/** + * @brief Creates new PPP related structure + * + * @param[in] ppp pointer to internal ppp context instance + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_netif_start_ppp(lwip_ppp_ctx_t *ppp); + +/** + * @brief Data path API to input incoming packets to PPP + * + * @param[in] ppp pointer to internal ppp context instance + * @param[in] buffer pointer to the incoming data + * @param[in] len length of the data + * @param[in] eb external buffer ptr not used here (to be inline with input function prototypes) + * + * @return + * - ESP_OK on success + */ +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 + */ +void esp_netif_destroy_ppp(lwip_ppp_ctx_t *ppp); + +/** + * @brief Stops the PPP interface + * + * @param[in] ppp pointer to internal ppp context instance + * + * @return + * - ESP_OK on success + */ +esp_err_t esp_netif_stop_ppp(lwip_ppp_ctx_t *ppp); + +/** + * @brief Sets default netif for routing priority config + * + */ +void esp_netif_ppp_set_default_netif(lwip_ppp_ctx_t* ppp_ctx); + +#endif // _ESP_NETIF_LWIP_PPP_H_ \ No newline at end of file diff --git a/components/lwip/port/esp32/include/netif/ethernetif.h b/components/lwip/port/esp32/include/netif/ethernetif.h index d5d23b3d39..406674c48e 100644 --- a/components/lwip/port/esp32/include/netif/ethernetif.h +++ b/components/lwip/port/esp32/include/netif/ethernetif.h @@ -24,7 +24,7 @@ extern "C" { err_t ethernetif_init(struct netif *netif); -void ethernetif_input(void *h, void *buffer, size_t len, void *eb); +void ethernetif_input(void *netif, void *buffer, size_t len, void *eb); void netif_reg_addr_change_cb(void* cb); diff --git a/examples/protocols/pppos_client/components/modem/CMakeLists.txt b/examples/protocols/pppos_client/components/modem/CMakeLists.txt index e1bc2c0a97..a0a4343169 100644 --- a/examples/protocols/pppos_client/components/modem/CMakeLists.txt +++ b/examples/protocols/pppos_client/components/modem/CMakeLists.txt @@ -1,5 +1,6 @@ set(srcs "src/esp_modem.c" "src/esp_modem_dce_service" + "src/esp_modem_netif.c" "src/sim800.c" "src/bg96.c") diff --git a/examples/protocols/pppos_client/components/modem/include/esp_modem.h b/examples/protocols/pppos_client/components/modem/include/esp_modem.h index f2da7aeb08..461c0527d1 100644 --- a/examples/protocols/pppos_client/components/modem/include/esp_modem.h +++ b/examples/protocols/pppos_client/components/modem/include/esp_modem.h @@ -21,7 +21,6 @@ extern "C" { #include "esp_modem_dte.h" #include "esp_event.h" #include "driver/uart.h" -#include "lwip/ip_addr.h" /** * @brief Declare Event Base for ESP Modem @@ -35,8 +34,6 @@ ESP_EVENT_DECLARE_BASE(ESP_MODEM_EVENT); */ typedef enum { MODEM_EVENT_PPP_START, /*!< ESP Modem Start PPP Session */ - MODEM_EVENT_PPP_CONNECT, /*!< ESP Modem Connect to PPP Server */ - MODEM_EVENT_PPP_DISCONNECT, /*!< ESP Modem Disconnect from PPP Server */ MODEM_EVENT_PPP_STOP, /*!< ESP Modem Stop PPP Session*/ MODEM_EVENT_UNKNOWN /*!< ESP Modem Unknown Response */ } esp_modem_event_t; @@ -54,6 +51,12 @@ typedef struct { uint32_t baud_rate; /*!< Communication baud rate */ } esp_modem_dte_config_t; +/** + * @brief Type used for reception callback + * + */ +typedef esp_err_t (*esp_modem_on_receive)(void *buffer, size_t len, void *context); + /** * @brief ESP Modem DTE Default Configuration * @@ -88,7 +91,7 @@ modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config); * - ESP_ERR_NO_MEM on allocating memory for the handler failed * - ESP_ERR_INVALID_ARG on invalid combination of event base and event id */ -esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, void *handler_args); +esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args); /** * @brief Unregister event handler for ESP Modem event loop @@ -101,18 +104,6 @@ esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t hand */ esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t handler); -/** - * @brief PPPoS Client IP Information - * - */ -typedef struct { - ip4_addr_t ip; /*!< IP Address */ - ip4_addr_t netmask; /*!< Net Mask */ - ip4_addr_t gw; /*!< Gateway */ - ip4_addr_t ns1; /*!< Name Server1 */ - ip4_addr_t ns2; /*!< Name Server2 */ -} ppp_client_ip_info_t; - /** * @brief Setup PPP Session * @@ -121,7 +112,7 @@ typedef struct { * - ESP_OK on success * - ESP_FAIL on error */ -esp_err_t esp_modem_setup_ppp(modem_dte_t *dte); +esp_err_t esp_modem_start_ppp(modem_dte_t *dte); /** * @brief Exit PPP Session @@ -131,7 +122,18 @@ esp_err_t esp_modem_setup_ppp(modem_dte_t *dte); * - ESP_OK on success * - ESP_FAIL on error */ -esp_err_t esp_modem_exit_ppp(modem_dte_t *dte); +esp_err_t esp_modem_stop_ppp(modem_dte_t *dte); + +/** + * @brief Setup on reception callback + * + * @param dte ESP Modem DTE object + * @param receive_cb Function pointer to the reception callback + * @param receive_cb_ctx Contextual pointer to be passed to the reception callback + * + * @return ESP_OK on success + */ +esp_err_t esp_modem_set_rx_cb(modem_dte_t *dte, esp_modem_on_receive receive_cb, void *receive_cb_ctx); #ifdef __cplusplus } diff --git a/examples/protocols/pppos_client/components/modem/include/esp_modem_netif.h b/examples/protocols/pppos_client/components/modem/include/esp_modem_netif.h new file mode 100644 index 0000000000..1eac1b497a --- /dev/null +++ b/examples/protocols/pppos_client/components/modem/include/esp_modem_netif.h @@ -0,0 +1,53 @@ +// Copyright 2015-2018 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 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates handle to esp_modem used as an esp-netif driver + * + * @param dte ESP Modem DTE object + * + * @return opaque pointer to esp-modem IO driver used to attach to esp-netif + */ +void *esp_modem_netif_setup(modem_dte_t *dte); + +/** + * @brief Destroys the esp-netif driver handle + * + * @param h pointer to the esp-netif adapter for esp-modem + */ +void esp_modem_netif_teardown(void *h); + +/** + * @brief Clears default handlers for esp-modem lifecycle + * + * @param h pointer to the esp-netif adapter for esp-modem + */ +esp_err_t esp_modem_netif_clear_default_handlers(void *h); + +/** + * @brief Setups default handlers for esp-modem lifecycle + * + * @param h pointer to the esp-netif adapter for esp-modem + * @param esp_netif pointer corresponding esp-netif instance + */ +esp_err_t esp_modem_netif_set_default_handlers(void *h, esp_netif_t * esp_netif); + +#ifdef __cplusplus +} +#endif diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem.c b/examples/protocols/pppos_client/components/modem/src/esp_modem.c index cf604b2b6a..b171be27cd 100644 --- a/examples/protocols/pppos_client/components/modem/src/esp_modem.c +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem.c @@ -17,10 +17,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" -#include "netif/ppp/pppapi.h" -#include "netif/ppp/pppos.h" -#include "lwip/dns.h" -#include "esp_netif.h" #include "esp_modem.h" #include "esp_log.h" #include "sdkconfig.h" @@ -60,11 +56,21 @@ typedef struct { esp_event_loop_handle_t event_loop_hdl; /*!< Event loop handle */ TaskHandle_t uart_event_task_hdl; /*!< UART event task handle */ SemaphoreHandle_t process_sem; /*!< Semaphore used for indicating processing status */ - struct netif pppif; /*!< PPP network interface */ - ppp_pcb *ppp; /*!< PPP control block */ modem_dte_t parent; /*!< DTE interface that should extend */ + esp_modem_on_receive receive_cb; /*!< ptr to data reception */ + void *receive_cb_ctx; /*!< ptr to rx fn context data */ } esp_modem_dte_t; + +esp_err_t esp_modem_set_rx_cb(modem_dte_t *dte, esp_modem_on_receive receive_cb, void *receive_cb_ctx) +{ + esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent); + esp_dte->receive_cb_ctx = receive_cb_ctx; + esp_dte->receive_cb = receive_cb; + return ESP_OK; +} + + /** * @brief Handle one line in DTE * @@ -135,9 +141,9 @@ static void esp_handle_uart_data(esp_modem_dte_t *esp_dte) uart_get_buffered_data_len(esp_dte->uart_port, &length); length = MIN(ESP_MODEM_LINE_BUFFER_SIZE, length); length = uart_read_bytes(esp_dte->uart_port, esp_dte->buffer, length, portMAX_DELAY); - /* pass input data to the lwIP core thread */ + /* pass the input data to configured callback */ if (length) { - pppos_input_tcpip(esp_dte->ppp, esp_dte->buffer, length); + esp_dte->receive_cb(esp_dte->buffer, length, esp_dte->receive_cb_ctx); } } @@ -236,6 +242,8 @@ err: return -1; } + + /** * @brief Send data and wait for prompt from DCE * @@ -344,6 +352,8 @@ static esp_err_t esp_modem_dte_deinit(modem_dte_t *dte) return ESP_OK; } + + modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config) { esp_err_t res; @@ -363,6 +373,7 @@ modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config) esp_dte->parent.change_mode = esp_modem_dte_change_mode; esp_dte->parent.process_cmd_done = esp_modem_dte_process_cmd_done; esp_dte->parent.deinit = esp_modem_dte_deinit; + /* Config UART */ uart_config_t uart_config = { .baud_rate = config->baud_rate, @@ -434,10 +445,10 @@ err_dte_mem: return NULL; } -esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, void *handler_args) +esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args) { esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent); - return esp_event_handler_register_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_EVENT_ANY_ID, handler, handler_args); + return esp_event_handler_register_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, event_id, handler, handler_args); } esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t handler) @@ -446,137 +457,7 @@ esp_err_t esp_modem_remove_event_handler(modem_dte_t *dte, esp_event_handler_t h return esp_event_handler_unregister_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_EVENT_ANY_ID, handler); } -/** - * @brief PPP status callback which is called on PPP status change (up, down, …) by lwIP core thread - * - * @param pcb PPP control block - * @param err_code Error code - * @param ctx Context of callback - */ -static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx) -{ - struct netif *pppif = ppp_netif(pcb); - const ip_addr_t *dest_ip = NULL; - modem_dte_t *dte = (modem_dte_t *)(ctx); - esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent); - ppp_client_ip_info_t ipinfo = {0}; - switch (err_code) { - case PPPERR_NONE: /* Connected */ - ipinfo.ip = pppif->ip_addr.u_addr.ip4; - ipinfo.gw = pppif->gw.u_addr.ip4; - ipinfo.netmask = pppif->netmask.u_addr.ip4; - dest_ip = dns_getserver(0); - if(dest_ip != NULL){ - ipinfo.ns1 = (*dest_ip).u_addr.ip4; - } - dest_ip = dns_getserver(1); - if(dest_ip != NULL){ - ipinfo.ns2 = (*dest_ip).u_addr.ip4; - } - esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_CONNECT, &ipinfo, sizeof(ipinfo), 0); - break; - case PPPERR_PARAM: - ESP_LOGE(MODEM_TAG, "Invalid parameter"); - break; - case PPPERR_OPEN: - ESP_LOGE(MODEM_TAG, "Unable to open PPP session"); - break; - case PPPERR_DEVICE: - ESP_LOGE(MODEM_TAG, "Invalid I/O device for PPP"); - break; - case PPPERR_ALLOC: - ESP_LOGE(MODEM_TAG, "Unable to allocate resources"); - break; - case PPPERR_USER: /* User interrupt */ - esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_STOP, NULL, 0, 0); - /* Free the PPP control block */ - pppapi_free(esp_dte->ppp); - break; - case PPPERR_CONNECT: /* Connection lost */ - esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_DISCONNECT, NULL, 0, 0); - break; - case PPPERR_AUTHFAIL: - ESP_LOGE(MODEM_TAG, "Failed authentication challenge"); - break; - case PPPERR_PROTOCOL: - ESP_LOGE(MODEM_TAG, "Failed to meet protocol"); - break; - case PPPERR_PEERDEAD: - ESP_LOGE(MODEM_TAG, "Connection timeout"); - break; - case PPPERR_IDLETIMEOUT: - ESP_LOGE(MODEM_TAG, "Idle Timeout"); - break; - case PPPERR_CONNECTTIME: - ESP_LOGE(MODEM_TAG, "Max connect time reached"); - break; - case PPPERR_LOOPBACK: - ESP_LOGE(MODEM_TAG, "Loopback detected"); - break; - default: - ESP_LOGE(MODEM_TAG, "Unknown error code %d", err_code); - break; - } -} - -#if PPP_NOTIFY_PHASE -/** - * @brief Notify phase callback which is called on each PPP internal state change - * - * @param pcb PPP control block - * @param phase Phase ID - * @param ctx Context of callback - */ -static void on_ppp_notify_phase(ppp_pcb *pcb, u8_t phase, void *ctx) -{ - switch (phase) { - case PPP_PHASE_DEAD: - ESP_LOGD(MODEM_TAG, "Phase Dead"); - break; - case PPP_PHASE_INITIALIZE: - ESP_LOGD(MODEM_TAG, "Phase Start"); - break; - case PPP_PHASE_ESTABLISH: - ESP_LOGD(MODEM_TAG, "Phase Establish"); - break; - case PPP_PHASE_AUTHENTICATE: - ESP_LOGD(MODEM_TAG, "Phase Authenticate"); - break; - case PPP_PHASE_NETWORK: - ESP_LOGD(MODEM_TAG, "Phase Network"); - break; - case PPP_PHASE_RUNNING: - ESP_LOGD(MODEM_TAG, "Phase Running"); - break; - case PPP_PHASE_TERMINATE: - ESP_LOGD(MODEM_TAG, "Phase Terminate"); - break; - case PPP_PHASE_DISCONNECT: - ESP_LOGD(MODEM_TAG, "Phase Disconnect"); - break; - default: - ESP_LOGW(MODEM_TAG, "Phase Unknown: %d", phase); - break; - } -} -#endif - -/** - * @brief PPPoS serial output callback - * - * @param pcb PPP control block - * @param data Buffer to write to serial port - * @param len Length of the data buffer - * @param ctx Context of callback - * @return uint32_t Length of data successfully sent - */ -static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len, void *ctx) -{ - modem_dte_t *dte = (modem_dte_t *)ctx; - return dte->send_data(dte, (const char *)data, len); -} - -esp_err_t esp_modem_setup_ppp(modem_dte_t *dte) +esp_err_t esp_modem_start_ppp(modem_dte_t *dte) { modem_dce_t *dce = dte->dce; MODEM_CHECK(dce, "DTE has not yet bind with DCE", err); @@ -585,40 +466,18 @@ esp_err_t esp_modem_setup_ppp(modem_dte_t *dte) MODEM_CHECK(dce->define_pdp_context(dce, 1, "IP", CONFIG_EXAMPLE_MODEM_APN) == ESP_OK, "set MODEM APN failed", err); /* Enter PPP mode */ MODEM_CHECK(dte->change_mode(dte, MODEM_PPP_MODE) == ESP_OK, "enter ppp mode failed", err); - /* Create PPPoS interface */ - esp_dte->ppp = pppapi_pppos_create(&(esp_dte->pppif), pppos_low_level_output, on_ppp_status_changed, dte); - MODEM_CHECK(esp_dte->ppp, "create pppos interface failed", err); -#if PPP_NOTIFY_PHASE - ppp_set_notify_phase_callback(esp_dte->ppp, on_ppp_notify_phase); -#endif - /* Initiate PPP client connection */ - /* Set default route */ - MODEM_CHECK(pppapi_set_default(esp_dte->ppp) == ERR_OK, "set default route failed", err); - /* Ask the peer for up to 2 DNS server addresses */ - ppp_set_usepeerdns(esp_dte->ppp, 1); - /* Auth configuration */ -#if PAP_SUPPORT - pppapi_set_auth(esp_dte->ppp, PPPAUTHTYPE_PAP, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD); -#elif CHAP_SUPPORT - pppapi_set_auth(esp_dte->ppp, PPPAUTHTYPE_CHAP, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD); -#else -#error "Unsupported AUTH Negotiation" -#endif - /* Initiate PPP negotiation, without waiting */ - MODEM_CHECK(pppapi_connect(esp_dte->ppp, 0) == ERR_OK, "initiate ppp negotiation failed", err); + + /* post PPP mode started event */ esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_START, NULL, 0, 0); return ESP_OK; err: return ESP_FAIL; } -esp_err_t esp_modem_exit_ppp(modem_dte_t *dte) +esp_err_t esp_modem_stop_ppp(modem_dte_t *dte) { modem_dce_t *dce = dte->dce; MODEM_CHECK(dce, "DTE has not yet bind with DCE", err); - esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent); - /* Shutdown of PPP protocols */ - MODEM_CHECK(pppapi_close(esp_dte->ppp, 0) == ERR_OK, "close ppp connection failed", err); /* Enter command mode */ MODEM_CHECK(dte->change_mode(dte, MODEM_COMMAND_MODE) == ESP_OK, "enter command mode failed", err); /* Hang up */ diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c b/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c new file mode 100644 index 0000000000..c5a5a5ab27 --- /dev/null +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c @@ -0,0 +1,155 @@ +// Copyright 2015-2018 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 "esp_netif.h" +#include "esp_modem.h" +#include "esp_log.h" + +static const char *TAG = "esp-modem-netif"; + +/** + * @brief ESP32 Modem handle to be used as netif IO object + */ +typedef struct esp_modem_netif_driver_s { + esp_netif_driver_base_t base; /*!< base structure reserved as esp-netif driver */ + modem_dte_t *dte; /*!< ptr to the esp_modem objects (DTE) */ +} esp_modem_netif_driver_t; + +/** + * @brief Transmit function called from esp_netif to output network stack data + * + * Note: This API has to conform to esp-netif transmit prototype + * + * @param h Opaque pointer representing esp-netif driver, esp_dte in this case of esp_modem + * @param data data buffer + * @param length length of data to send + * + * @return ESP_OK on success + */ +static esp_err_t esp_modem_dte_transmit(void *h, void *buffer, size_t len) +{ + modem_dte_t *dte = h; + if (dte->send_data(dte, (const char *)buffer, len) > 0) { + return ESP_OK; + } + return ESP_FAIL; +} + +/** + * @brief Post attach adapter for esp-modem + * + * Used to exchange internal callbacks, context between esp-netif nad modem-netif + * + * @param esp_netif handle to esp-netif object + * @param args pointer to modem-netif driver + * + * @return ESP_OK on success + */ +static esp_err_t esp_modem_post_attach_start(esp_netif_t * esp_netif, void * args) +{ + esp_modem_netif_driver_t *driver = args; + modem_dte_t *dte = driver->dte; + const esp_netif_driver_ifconfig_t driver_ifconfig = { + .driver_free_rx_buffer = NULL, + .transmit = esp_modem_dte_transmit, + .handle = dte + }; + driver->base.netif = esp_netif; + ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig)); + esp_modem_start_ppp(dte); + return ESP_OK; +} + +/** + * @brief Data path callback from esp-modem to pass data to esp-netif + * + * @param buffer data pointer + * @param len data length + * @param context context data used for esp-modem-netif handle + * + * @return ESP_OK on success + */ +static esp_err_t modem_netif_receive_cb(void *buffer, size_t len, void *context) +{ + esp_modem_netif_driver_t *driver = context; + esp_netif_receive(driver->base.netif, buffer, len, NULL); + return ESP_OK; +} + +void *esp_modem_netif_setup(modem_dte_t *dte) +{ + esp_modem_netif_driver_t *driver = calloc(1, sizeof(esp_modem_netif_driver_t)); + if (driver == NULL) { + ESP_LOGE(TAG, "Cannot allocate esp_modem_netif_driver_t"); + goto drv_create_failed; + } + esp_err_t err = esp_modem_set_rx_cb(dte, modem_netif_receive_cb, driver); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_modem_set_rx_cb failed with: %d", err); + goto drv_create_failed; + } + + driver->base.post_attach = esp_modem_post_attach_start; + driver->dte = dte; + return driver; + +drv_create_failed: + return NULL; +} + +void esp_modem_netif_teardown(void *h) +{ + esp_modem_netif_driver_t *driver = h; + esp_netif_destroy(driver->base.netif); + free(driver); +} + +esp_err_t esp_modem_netif_clear_default_handlers(void *h) +{ + esp_modem_netif_driver_t *driver = h; + esp_err_t ret; + ret = esp_modem_remove_event_handler(driver->dte, esp_netif_action_start); + if (ret != ESP_OK) { + goto clear_event_failed; + } + ret = esp_modem_remove_event_handler(driver->dte, esp_netif_action_stop); + if (ret != ESP_OK) { + goto clear_event_failed; + } + return ESP_OK; + +clear_event_failed: + ESP_LOGE(TAG, "Failed to unregister event handlers"); + return ESP_FAIL; + +} + +esp_err_t esp_modem_netif_set_default_handlers(void *h, esp_netif_t * esp_netif) +{ + esp_modem_netif_driver_t *driver = h; + esp_err_t ret; + ret = esp_modem_add_event_handler(driver->dte, esp_netif_action_start, MODEM_EVENT_PPP_START, esp_netif); + if (ret != ESP_OK) { + goto set_event_failed; + } + ret = esp_modem_add_event_handler(driver->dte, esp_netif_action_stop, MODEM_EVENT_PPP_STOP, esp_netif); + if (ret != ESP_OK) { + goto set_event_failed; + } + return ESP_OK; + +set_event_failed: + ESP_LOGE(TAG, "Failed to register event handlers"); + esp_modem_netif_clear_default_handlers(driver); + return ESP_FAIL; +} diff --git a/examples/protocols/pppos_client/main/pppos_client_main.c b/examples/protocols/pppos_client/main/pppos_client_main.c index 7df7c49388..d31c8197e4 100644 --- a/examples/protocols/pppos_client/main/pppos_client_main.c +++ b/examples/protocols/pppos_client/main/pppos_client_main.c @@ -10,8 +10,10 @@ #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "esp_netif.h" +#include "esp_netif_ppp.h" #include "mqtt_client.h" #include "esp_modem.h" +#include "esp_modem_netif.h" #include "esp_log.h" #include "sim800.h" #include "bg96.h" @@ -112,21 +114,6 @@ static void modem_event_handler(void *event_handler_arg, esp_event_base_t event_ case MODEM_EVENT_PPP_START: ESP_LOGI(TAG, "Modem PPP Started"); break; - case MODEM_EVENT_PPP_CONNECT: - ESP_LOGI(TAG, "Modem Connect to PPP Server"); - ppp_client_ip_info_t *ipinfo = (ppp_client_ip_info_t *)(event_data); - ESP_LOGI(TAG, "~~~~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP : " IPSTR, IP2STR(&ipinfo->ip)); - ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&ipinfo->netmask)); - ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&ipinfo->gw)); - ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&ipinfo->ns1)); - ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&ipinfo->ns2)); - ESP_LOGI(TAG, "~~~~~~~~~~~~~~"); - xEventGroupSetBits(event_group, CONNECT_BIT); - break; - case MODEM_EVENT_PPP_DISCONNECT: - ESP_LOGI(TAG, "Modem Disconnect from PPP Server"); - break; case MODEM_EVENT_PPP_STOP: ESP_LOGI(TAG, "Modem PPP Stopped"); xEventGroupSetBits(event_group, STOP_BIT); @@ -179,15 +166,72 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) return ESP_OK; } +static void on_ppp_changed(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "PPP state changed event %d", event_id); + if (event_id == NETIF_PPP_ERRORUSER) { + /* User interrupted event from esp-netif */ + esp_netif_t *netif = event_data; + ESP_LOGI(TAG, "User interrupted event from netif:%p", netif); + } +} + + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "IP event! %d", event_id); + if (event_id == IP_EVENT_PPP_GOT_IP) { + esp_netif_dns_info_t dns_info; + + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + esp_netif_t *netif = event->esp_netif; + + ESP_LOGI(TAG, "Modem Connect to PPP Server"); + ESP_LOGI(TAG, "~~~~~~~~~~~~~~"); + ESP_LOGI(TAG, "IP : " IPSTR, IP2STR(&event->ip_info.ip)); + ESP_LOGI(TAG, "Netmask : " IPSTR, IP2STR(&event->ip_info.netmask)); + ESP_LOGI(TAG, "Gateway : " IPSTR, IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, 0, &dns_info); + ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + esp_netif_get_dns_info(netif, 1, &dns_info); + ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + ESP_LOGI(TAG, "~~~~~~~~~~~~~~"); + xEventGroupSetBits(event_group, CONNECT_BIT); + + ESP_LOGI(TAG, "GOT ip event!!!"); + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Modem Disconnect from PPP Server"); + } +} + void app_main(void) { +#if CONFIG_LWIP_PPP_PAP_SUPPORT + esp_netif_auth_type_t auth_type = NETIF_PPP_AUTHTYPE_PAP; +#elif CONFIG_LWIP_PPP_CHAP_SUPPORT + esp_netif_auth_type_t auth_type = NETIF_PPP_AUTHTYPE_CHAP; +#else +#error "Unsupported AUTH Negotiation" +#endif esp_netif_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &on_ip_event, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed, NULL)); + event_group = xEventGroupCreate(); + + // Init netif object + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP(); + esp_netif_t *esp_netif = esp_netif_new(&cfg); + assert(esp_netif); + /* create dte object */ esp_modem_dte_config_t config = ESP_MODEM_DTE_DEFAULT_CONFIG(); modem_dte_t *dte = esp_modem_dte_init(&config); /* Register event handler */ - ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, NULL)); + ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, ESP_EVENT_ANY_ID, NULL)); /* create dce object */ #if CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 modem_dce_t *dce = sim800_init(dte); @@ -211,10 +255,15 @@ void app_main(void) uint32_t voltage = 0, bcs = 0, bcl = 0; ESP_ERROR_CHECK(dce->get_battery_status(dce, &bcs, &bcl, &voltage)); ESP_LOGI(TAG, "Battery voltage: %d mV", voltage); - /* Setup PPP environment */ - esp_modem_setup_ppp(dte); + /* setup PPPoS network parameters */ + esp_netif_ppp_set_auth(esp_netif, auth_type, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD); + void *modem_netif_adapter = esp_modem_netif_setup(dte); + esp_modem_netif_set_default_handlers(modem_netif_adapter, esp_netif); + /* attach the modem to the network interface */ + esp_netif_attach(esp_netif, modem_netif_adapter); /* Wait for IP address */ xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY); + ESP_ERROR_CHECK(dce->power_down(dce)); /* Config MQTT */ esp_mqtt_client_config_t mqtt_config = { .uri = BROKER_URL, @@ -225,7 +274,10 @@ void app_main(void) xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, portMAX_DELAY); esp_mqtt_client_destroy(mqtt_client); /* Exit PPP mode */ - ESP_ERROR_CHECK(esp_modem_exit_ppp(dte)); + ESP_ERROR_CHECK(esp_modem_stop_ppp(dte)); + /* Destroy the netif adapter withe events, which internally frees also the esp-netif instance */ + esp_modem_netif_clear_default_handlers(modem_netif_adapter); + esp_modem_netif_teardown(modem_netif_adapter); xEventGroupWaitBits(event_group, STOP_BIT, pdTRUE, pdTRUE, portMAX_DELAY); #if CONFIG_EXAMPLE_SEND_MSG const char *message = "Welcome to ESP32!"; From 04a25394aa323c9e842a4cff8834b4d3d85e3ca6 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 21 Nov 2019 13:20:13 +0100 Subject: [PATCH 3/3] esp_modem: add simple compatibility layer for new esp_modem connecting over esp-netif --- .../components/modem/CMakeLists.txt | 1 + .../components/modem/include/esp_modem.h | 9 +- .../modem/include/esp_modem_compat.h | 62 +++++++++++ .../components/modem/src/esp_modem.c | 8 +- .../components/modem/src/esp_modem_compat.c | 102 ++++++++++++++++++ .../components/modem/src/esp_modem_netif.c | 4 +- .../pppos_client/main/pppos_client_main.c | 8 +- 7 files changed, 180 insertions(+), 14 deletions(-) create mode 100644 examples/protocols/pppos_client/components/modem/include/esp_modem_compat.h create mode 100644 examples/protocols/pppos_client/components/modem/src/esp_modem_compat.c diff --git a/examples/protocols/pppos_client/components/modem/CMakeLists.txt b/examples/protocols/pppos_client/components/modem/CMakeLists.txt index a0a4343169..33cc955dea 100644 --- a/examples/protocols/pppos_client/components/modem/CMakeLists.txt +++ b/examples/protocols/pppos_client/components/modem/CMakeLists.txt @@ -1,6 +1,7 @@ set(srcs "src/esp_modem.c" "src/esp_modem_dce_service" "src/esp_modem_netif.c" + "src/esp_modem_compat.c" "src/sim800.c" "src/bg96.c") diff --git a/examples/protocols/pppos_client/components/modem/include/esp_modem.h b/examples/protocols/pppos_client/components/modem/include/esp_modem.h index 461c0527d1..689fe32b52 100644 --- a/examples/protocols/pppos_client/components/modem/include/esp_modem.h +++ b/examples/protocols/pppos_client/components/modem/include/esp_modem.h @@ -21,6 +21,7 @@ extern "C" { #include "esp_modem_dte.h" #include "esp_event.h" #include "driver/uart.h" +#include "esp_modem_compat.h" /** * @brief Declare Event Base for ESP Modem @@ -33,9 +34,9 @@ ESP_EVENT_DECLARE_BASE(ESP_MODEM_EVENT); * */ typedef enum { - MODEM_EVENT_PPP_START, /*!< ESP Modem Start PPP Session */ - MODEM_EVENT_PPP_STOP, /*!< ESP Modem Stop PPP Session*/ - MODEM_EVENT_UNKNOWN /*!< ESP Modem Unknown Response */ + ESP_MODEM_EVENT_PPP_START = 0, /*!< ESP Modem Start PPP Session */ + ESP_MODEM_EVENT_PPP_STOP = 3, /*!< ESP Modem Stop PPP Session*/ + ESP_MODEM_EVENT_UNKNOWN = 4 /*!< ESP Modem Unknown Response */ } esp_modem_event_t; /** @@ -91,7 +92,7 @@ modem_dte_t *esp_modem_dte_init(const esp_modem_dte_config_t *config); * - ESP_ERR_NO_MEM on allocating memory for the handler failed * - ESP_ERR_INVALID_ARG on invalid combination of event base and event id */ -esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args); +esp_err_t esp_modem_set_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args); /** * @brief Unregister event handler for ESP Modem event loop diff --git a/examples/protocols/pppos_client/components/modem/include/esp_modem_compat.h b/examples/protocols/pppos_client/components/modem/include/esp_modem_compat.h new file mode 100644 index 0000000000..5075dd2211 --- /dev/null +++ b/examples/protocols/pppos_client/components/modem/include/esp_modem_compat.h @@ -0,0 +1,62 @@ +// 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. +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwip/ip.h" + +/** +* @brief ESP Modem Event backward compatible version +*/ +typedef enum { + MODEM_EVENT_PPP_START = 0x100, + MODEM_EVENT_PPP_CONNECT = 0x101, + MODEM_EVENT_PPP_DISCONNECT = 0x102, + MODEM_EVENT_PPP_STOP = 0x103, + MODEM_EVENT_UNKNOWN = 0x104, +} esp_modem_compat_event_t; + +/** + * @brief PPPoS Client IP Information backward compatible version + * + */ +typedef struct { + ip4_addr_t ip; /*!< IP Address */ + ip4_addr_t netmask; /*!< Net Mask */ + ip4_addr_t gw; /*!< Gateway */ + ip4_addr_t ns1; /*!< Name Server1 */ + ip4_addr_t ns2; /*!< Name Server2 */ + } ppp_client_ip_info_t; + +/** + * @brief Backward compatible version of esp_modem_set_event_handler() + */ +esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, void *handler_args) __attribute__ ((deprecated)); + +/** + * @brief Backward compatible version of creating esp-netif(PPP) and attaching to esp_modem_start_ppp() + */ +esp_err_t esp_modem_setup_ppp(modem_dte_t *dte) __attribute__ ((deprecated)); + +/** + * @brief Backward compatible version of deleting esp-netif and esp_modem_stop_ppp() + */ +esp_err_t esp_modem_exit_ppp(modem_dte_t *dte) __attribute__ ((deprecated)); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem.c b/examples/protocols/pppos_client/components/modem/src/esp_modem.c index b171be27cd..988b95f1e7 100644 --- a/examples/protocols/pppos_client/components/modem/src/esp_modem.c +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem.c @@ -91,8 +91,8 @@ static esp_err_t esp_dte_handle_line(esp_modem_dte_t *esp_dte) } return ESP_OK; err_handle: - /* Send MODEM_EVENT_UNKNOWN signal to event loop */ - esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_UNKNOWN, + /* Send ESP_MODEM_EVENT_UNKNOWN signal to event loop */ + esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_MODEM_EVENT_UNKNOWN, (void *)line, strlen(line) + 1, pdMS_TO_TICKS(100)); err: return ESP_FAIL; @@ -445,7 +445,7 @@ err_dte_mem: return NULL; } -esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args) +esp_err_t esp_modem_set_event_handler(modem_dte_t *dte, esp_event_handler_t handler, int32_t event_id, void *handler_args) { esp_modem_dte_t *esp_dte = __containerof(dte, esp_modem_dte_t, parent); return esp_event_handler_register_with(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, event_id, handler, handler_args); @@ -468,7 +468,7 @@ esp_err_t esp_modem_start_ppp(modem_dte_t *dte) MODEM_CHECK(dte->change_mode(dte, MODEM_PPP_MODE) == ESP_OK, "enter ppp mode failed", err); /* post PPP mode started event */ - esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, MODEM_EVENT_PPP_START, NULL, 0, 0); + esp_event_post_to(esp_dte->event_loop_hdl, ESP_MODEM_EVENT, ESP_MODEM_EVENT_PPP_START, NULL, 0, 0); return ESP_OK; err: return ESP_FAIL; diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem_compat.c b/examples/protocols/pppos_client/components/modem/src/esp_modem_compat.c new file mode 100644 index 0000000000..20497bc7b2 --- /dev/null +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem_compat.c @@ -0,0 +1,102 @@ +// 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_netif.h" +#include "esp_netif_ppp.h" +#include "esp_modem.h" +#include "esp_modem_netif.h" +#include "esp_log.h" + +static const char *TAG = "esp-modem-compat"; + +static void on_modem_compat_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + int32_t compat_event_id = MODEM_EVENT_UNKNOWN; + switch (event_id) { + case ESP_MODEM_EVENT_PPP_START: + compat_event_id = MODEM_EVENT_PPP_START; + break; + case ESP_MODEM_EVENT_PPP_STOP: + compat_event_id = MODEM_EVENT_PPP_STOP; + break; + default: + break; + } + esp_event_post(ESP_MODEM_EVENT, compat_event_id, NULL, 0, 0); +} + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "IP event! %d", event_id); + if (event_id == IP_EVENT_PPP_GOT_IP) { + esp_netif_dns_info_t dns_info; + ppp_client_ip_info_t ipinfo = {0}; + ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data; + esp_netif_t *netif = event->esp_netif; + ipinfo.ip.addr = event->ip_info.ip.addr; + ipinfo.gw.addr = event->ip_info.gw.addr; + ipinfo.netmask.addr = event->ip_info.netmask.addr; + esp_netif_get_dns_info(netif, 0, &dns_info); + ipinfo.ns1.addr = dns_info.ip.u_addr.ip4.addr; + ipinfo.ns2.addr = dns_info.ip.u_addr.ip4.addr; + esp_event_post(ESP_MODEM_EVENT, MODEM_EVENT_PPP_CONNECT, &ipinfo, sizeof(ipinfo), 0); + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Modem Disconnect from PPP Server"); + esp_event_post(ESP_MODEM_EVENT, MODEM_EVENT_PPP_DISCONNECT, NULL, 0, 0); + } +} + +esp_err_t esp_modem_add_event_handler(modem_dte_t *dte, esp_event_handler_t handler, void *handler_args) +{ + // event loop has to be created when using this API -- create and ignore failure if already created + esp_event_loop_create_default(); + ESP_ERROR_CHECK(esp_event_handler_register(ESP_MODEM_EVENT, MODEM_EVENT_PPP_START, handler, handler_args)); + ESP_ERROR_CHECK(esp_event_handler_register(ESP_MODEM_EVENT, MODEM_EVENT_PPP_CONNECT, handler, handler_args)); + ESP_ERROR_CHECK(esp_event_handler_register(ESP_MODEM_EVENT, MODEM_EVENT_PPP_DISCONNECT, handler, handler_args)); + ESP_ERROR_CHECK(esp_event_handler_register(ESP_MODEM_EVENT, MODEM_EVENT_PPP_STOP, handler, handler_args)); + return esp_modem_set_event_handler(dte, on_modem_compat_handler, ESP_EVENT_ANY_ID, handler_args); +} + +esp_err_t esp_modem_setup_ppp(modem_dte_t *dte) +{ +#if CONFIG_LWIP_PPP_PAP_SUPPORT + esp_netif_auth_type_t auth_type = NETIF_PPP_AUTHTYPE_PAP; +#elif CONFIG_LWIP_PPP_CHAP_SUPPORT + esp_netif_auth_type_t auth_type = NETIF_PPP_AUTHTYPE_CHAP; +#else +#error "Unsupported AUTH Negotiation" +#endif + // Init netif object + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP(); + esp_netif_t *esp_netif = esp_netif_new(&cfg); + assert(esp_netif); + + // event loop has to be created when using this API -- create and ignore failure if already created + esp_event_loop_create_default(); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &on_ip_event, NULL)); + esp_netif_ppp_set_auth(esp_netif, auth_type, CONFIG_EXAMPLE_MODEM_PPP_AUTH_USERNAME, CONFIG_EXAMPLE_MODEM_PPP_AUTH_PASSWORD); + void *modem_netif_adapter = esp_modem_netif_setup(dte); + esp_modem_netif_set_default_handlers(modem_netif_adapter, esp_netif); + /* attach the modem to the network interface */ + return esp_netif_attach(esp_netif, modem_netif_adapter); +} + +esp_err_t esp_modem_exit_ppp(modem_dte_t *dte) +{ + // Note: A minor memory leak is expected when using esp-modem-compat + return esp_modem_stop_ppp(dte); +} diff --git a/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c b/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c index c5a5a5ab27..341291f8e9 100644 --- a/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c +++ b/examples/protocols/pppos_client/components/modem/src/esp_modem_netif.c @@ -138,11 +138,11 @@ esp_err_t esp_modem_netif_set_default_handlers(void *h, esp_netif_t * esp_netif) { esp_modem_netif_driver_t *driver = h; esp_err_t ret; - ret = esp_modem_add_event_handler(driver->dte, esp_netif_action_start, MODEM_EVENT_PPP_START, esp_netif); + ret = esp_modem_set_event_handler(driver->dte, esp_netif_action_start, ESP_MODEM_EVENT_PPP_START, esp_netif); if (ret != ESP_OK) { goto set_event_failed; } - ret = esp_modem_add_event_handler(driver->dte, esp_netif_action_stop, MODEM_EVENT_PPP_STOP, esp_netif); + ret = esp_modem_set_event_handler(driver->dte, esp_netif_action_stop, ESP_MODEM_EVENT_PPP_STOP, esp_netif); if (ret != ESP_OK) { goto set_event_failed; } diff --git a/examples/protocols/pppos_client/main/pppos_client_main.c b/examples/protocols/pppos_client/main/pppos_client_main.c index d31c8197e4..655809856b 100644 --- a/examples/protocols/pppos_client/main/pppos_client_main.c +++ b/examples/protocols/pppos_client/main/pppos_client_main.c @@ -111,14 +111,14 @@ err: static void modem_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { switch (event_id) { - case MODEM_EVENT_PPP_START: + case ESP_MODEM_EVENT_PPP_START: ESP_LOGI(TAG, "Modem PPP Started"); break; - case MODEM_EVENT_PPP_STOP: + case ESP_MODEM_EVENT_PPP_STOP: ESP_LOGI(TAG, "Modem PPP Stopped"); xEventGroupSetBits(event_group, STOP_BIT); break; - case MODEM_EVENT_UNKNOWN: + case ESP_MODEM_EVENT_UNKNOWN: ESP_LOGW(TAG, "Unknow line received: %s", (char *)event_data); break; default: @@ -231,7 +231,7 @@ void app_main(void) esp_modem_dte_config_t config = ESP_MODEM_DTE_DEFAULT_CONFIG(); modem_dte_t *dte = esp_modem_dte_init(&config); /* Register event handler */ - ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, ESP_EVENT_ANY_ID, NULL)); + ESP_ERROR_CHECK(esp_modem_set_event_handler(dte, modem_event_handler, ESP_EVENT_ANY_ID, NULL)); /* create dce object */ #if CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 modem_dce_t *dce = sim800_init(dte);