diff --git a/components/esp_netif/CMakeLists.txt b/components/esp_netif/CMakeLists.txt index 6eb4d85911..5846aa75d9 100644 --- a/components/esp_netif/CMakeLists.txt +++ b/components/esp_netif/CMakeLists.txt @@ -51,3 +51,4 @@ if(CONFIG_ESP_NETIF_L2_TAP OR CONFIG_ESP_NETIF_BRIDGE_EN) endif() target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") +target_compile_definitions(${COMPONENT_LIB} PRIVATE ESP_NETIF_COMPONENT_BUILD) diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index 3831655a4d..aeb5ffdd6a 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -306,6 +306,34 @@ esp_err_t esp_netif_bridge_fdb_add(esp_netif_t *esp_netif_br, uint8_t *addr, uin esp_err_t esp_netif_bridge_fdb_remove(esp_netif_t *esp_netif_br, uint8_t *addr); #endif // CONFIG_ESP_NETIF_BRIDGE_EN +/** + * @brief Cause the TCP/IP stack to join a IPv6 multicast group + * + * @param[in] esp_netif Handle to esp-netif instance + * @param[in] addr The multicast group to join + * + * @return + * - ESP_OK + * - ESP_ERR_ESP_NETIF_INVALID_PARAMS + * - ESP_ERR_ESP_NETIF_MLD6_FAILED + * - ESP_ERR_NO_MEM + */ +esp_err_t esp_netif_join_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr); + +/** + * @brief Cause the TCP/IP stack to leave a IPv6 multicast group + * + * @param[in] esp_netif Handle to esp-netif instance + * @param[in] addr The multicast group to leave + * + * @return + * - ESP_OK + * - ESP_ERR_ESP_NETIF_INVALID_PARAMS + * - ESP_ERR_ESP_NETIF_MLD6_FAILED + * - ESP_ERR_NO_MEM + */ +esp_err_t esp_netif_leave_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr); + /** * @} */ @@ -940,6 +968,27 @@ void esp_netif_netstack_buf_ref(void *netstack_buf); */ void esp_netif_netstack_buf_free(void *netstack_buf); +/** + * @} + */ + +/** @addtogroup ESP_NETIF_TCPIP_EXEC + * @{ + */ + +/** + * @brief TCPIP thread safe callback used with esp_netif_tcpip_exec() + */ +typedef esp_err_t (*esp_netif_callback_fn)(void *ctx); + +/** + * @brief Utility to execute the supplied callback in TCP/IP context + * @param fn Pointer to the callback + * @param ctx Parameter to the callback + * @return The error code (esp_err_t) returned by the callback + */ +esp_err_t esp_netif_tcpip_exec(esp_netif_callback_fn fn, void *ctx); + /** * @} */ diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index d6bbd733ed..c84d3217c5 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -100,12 +100,8 @@ typedef enum esp_netif_action { // // Internal variables for this module // -extern sys_thread_t g_lwip_task; - static const char *TAG = "esp_netif_lwip"; -static bool tcpip_initialized = false; - #if LWIP_ESP_NETIF_DATA static u8_t lwip_netif_client_id = 0xff; #endif @@ -136,17 +132,28 @@ static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, co #endif /* #if LWIP_IPV6 */ } -static void set_lwip_netif_callback(void) +#if LWIP_ESP_NETIF_DATA +static esp_err_t alloc_client_data_id(esp_netif_api_msg_t *msg) { - if (netif_callback.callback_fn == NULL ) { - netif_add_ext_callback(&netif_callback, netif_callback_fn); - } + uint8_t *client_data_id = msg->data; + *client_data_id = netif_alloc_client_data_id(); + return ESP_OK; +} +#endif // LWIP_ESP_NETIF_DATA + +static esp_err_t set_lwip_netif_callback(struct esp_netif_api_msg_s *msg) +{ + (void)msg; + netif_add_ext_callback(&netif_callback, netif_callback_fn); + return ESP_OK; } -static void remove_lwip_netif_callback(void) +static esp_err_t remove_lwip_netif_callback(struct esp_netif_api_msg_s *msg) { + (void)msg; netif_remove_ext_callback(&netif_callback); memset(&netif_callback, 0, sizeof(netif_callback)); + return ESP_OK; } static void dns_clear_servers(bool keep_fallback) @@ -186,6 +193,7 @@ static void netif_unset_garp_flag(struct netif *netif) #if !LWIP_TCPIP_CORE_LOCKING static sys_sem_t api_sync_sem = NULL; static sys_sem_t api_lock_sem = NULL; +#endif /** * @brief Api callback from tcpip thread used to call esp-netif @@ -202,33 +210,59 @@ static void esp_netif_api_cb(void *api_msg) msg->ret = msg->api_fn(msg); ESP_LOGD(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret); +#if !LWIP_TCPIP_CORE_LOCKING sys_sem_signal(&api_sync_sem); - -} #endif +} + /** * @brief Initiates a tcpip remote call if called from another task * or calls the function directly if executed from lwip task */ -static inline esp_err_t esp_netif_lwip_ipc_call(esp_netif_api_fn fn, esp_netif_t *netif, void *data) +static inline esp_err_t esp_netif_lwip_ipc_call_msg(esp_netif_api_msg_t *msg) +{ + if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { + ESP_LOGD(TAG, "check: remote, if=%p fn=%p\n", msg->esp_netif, msg->api_fn); +#if LWIP_TCPIP_CORE_LOCKING + tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, msg, NULL); +#else + sys_arch_sem_wait(&api_lock_sem, 0); + tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, msg, &api_sync_sem); + sys_sem_signal(&api_lock_sem); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + return msg->ret; + } + ESP_LOGD(TAG, "check: local, if=%p fn=%p\n", msg->esp_netif, msg->api_fn); + return msg->api_fn(msg); +} + +static inline esp_err_t esp_netif_lwip_ipc_call(esp_netif_api_fn fn, esp_netif_t* netif, void *data) { esp_netif_api_msg_t msg = { .esp_netif = netif, .data = data, .api_fn = fn }; -#if !LWIP_TCPIP_CORE_LOCKING - if (tcpip_initialized && g_lwip_task != xTaskGetCurrentTaskHandle()) { - ESP_LOGD(TAG, "check: remote, if=%p fn=%p\n", netif, fn); - sys_arch_sem_wait(&api_lock_sem, 0); - tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, &msg, &api_sync_sem); - sys_sem_signal(&api_lock_sem); - return msg.ret; - } -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - ESP_LOGD(TAG, "check: local, if=%p fn=%p\n", netif, fn); - return fn(&msg); + return esp_netif_lwip_ipc_call_msg(&msg); +} + +static inline esp_err_t esp_netif_lwip_ipc_call_fn(esp_netif_api_fn fn, esp_netif_callback_fn user_fn, void *ctx) +{ + esp_netif_api_msg_t msg = { + .user_fn = user_fn, + .data = ctx, + .api_fn = fn + }; + return esp_netif_lwip_ipc_call_msg(&msg); +} + +static inline esp_err_t esp_netif_lwip_ipc_no_args(esp_netif_api_fn fn) +{ + esp_netif_api_msg_t msg = { + .api_fn = fn + }; + return esp_netif_lwip_ipc_call_msg(&msg); } /** @@ -458,10 +492,15 @@ void* esp_netif_get_netif_impl(esp_netif_t *esp_netif) return NULL; } +static void tcpip_init_done(void *arg) +{ + sys_sem_t *init_sem = arg; + sys_sem_signal(init_sem); +} + esp_err_t esp_netif_init(void) { - if (tcpip_initialized == false) { - tcpip_initialized = true; + if (!sys_thread_tcpip(LWIP_CORE_IS_TCPIP_INITIALIZED)) { #if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT uint8_t rand_buf[16]; /* @@ -474,13 +513,21 @@ esp_err_t esp_netif_init(void) esp_fill_random(rand_buf, sizeof(rand_buf)); lwip_init_tcp_isn(esp_log_timestamp(), rand_buf); #endif - tcpip_init(NULL, NULL); - ESP_LOGD(TAG, "LwIP stack has been initialized"); -#if LWIP_ESP_NETIF_DATA - if (lwip_netif_client_id == 0xFF) { - lwip_netif_client_id = netif_alloc_client_data_id(); + sys_sem_t init_sem; + if (sys_sem_new(&init_sem, 0) != ERR_OK) { + ESP_LOGE(TAG, "esp netif cannot create tcpip_init semaphore"); + return ESP_FAIL; } +#if LWIP_TCPIP_CORE_LOCKING + /* TCPIP thread is not initialized yet, + * pretend that the calling thread is holder + * to correctly set up the TCPIP task */ + sys_thread_tcpip(LWIP_CORE_LOCK_MARK_HOLDER); #endif + tcpip_init(tcpip_init_done, &init_sem); + sys_sem_wait(&init_sem); + sys_sem_free(&init_sem); + ESP_LOGD(TAG, "LwIP stack has been initialized"); } #if !LWIP_TCPIP_CORE_LOCKING @@ -499,18 +546,22 @@ esp_err_t esp_netif_init(void) } #endif +#if LWIP_ESP_NETIF_DATA + if (lwip_netif_client_id == 0xFF) { + esp_netif_lwip_ipc_call(alloc_client_data_id, NULL, &lwip_netif_client_id); + } +#endif ESP_LOGD(TAG, "esp-netif has been successfully initialized"); return ESP_OK; } esp_err_t esp_netif_deinit(void) { - if (tcpip_initialized == true) { + if (sys_thread_tcpip(LWIP_CORE_IS_TCPIP_INITIALIZED)) { /* deinit of LwIP not supported: * do not deinit semaphores and states, * so init could be called multiple times * - tcpip_initialized = false; sys_sem_free(&api_sync_sem); sys_sem_free(&api_lock_sem); */ @@ -612,6 +663,16 @@ static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_ return ESP_OK; } +static esp_err_t tcpip_exec_api(esp_netif_api_msg_t *msg) +{ + return msg->user_fn(msg->data); +} + +esp_err_t esp_netif_tcpip_exec(esp_netif_callback_fn fn, void*ctx) +{ + return esp_netif_lwip_ipc_call_fn(tcpip_exec_api, fn, ctx); +} + esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) { // mandatory configuration must be provided when creating esp_netif object @@ -657,7 +718,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) // Optionally allocate netif client data for esp-netif ptr // to allow for running esp_netif_new() before esp_netif_init() if (lwip_netif_client_id == 0xFF) { - lwip_netif_client_id = netif_alloc_client_data_id(); + esp_netif_lwip_ipc_call(alloc_client_data_id, NULL, &lwip_netif_client_id); } #endif @@ -696,7 +757,9 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) } lwip_set_esp_netif(lwip_netif, esp_netif); - set_lwip_netif_callback(); + if (netif_callback.callback_fn == NULL ) { + esp_netif_lwip_ipc_no_args(set_lwip_netif_callback); + } return esp_netif; } @@ -783,18 +846,24 @@ static void esp_netif_destroy_related(esp_netif_t *esp_netif) } } +static esp_err_t esp_netif_lwip_remove_api(esp_netif_api_msg_t *msg) +{ + esp_netif_lwip_remove(msg->esp_netif); + return ESP_OK; +} + void esp_netif_destroy(esp_netif_t *esp_netif) { if (esp_netif) { esp_netif_remove_from_list(esp_netif); if (esp_netif_get_nr_of_ifs() == 0) { - remove_lwip_netif_callback(); + esp_netif_lwip_ipc_no_args(remove_lwip_netif_callback); } free(esp_netif->ip_info); free(esp_netif->ip_info_old); free(esp_netif->if_key); free(esp_netif->if_desc); - esp_netif_lwip_remove(esp_netif); + esp_netif_lwip_ipc_call(esp_netif_lwip_remove_api, esp_netif, NULL); esp_netif_destroy_related(esp_netif); free(esp_netif->lwip_netif); free(esp_netif->hostname); @@ -842,6 +911,15 @@ static esp_err_t esp_netif_reset_ip_info(esp_netif_t *esp_netif) return ESP_OK; } +esp_err_t esp_netif_set_mac_api(esp_netif_api_msg_t *msg) +{ + uint8_t *mac = msg->data; + esp_netif_t* esp_netif = msg->esp_netif; + memcpy(esp_netif->mac, mac, NETIF_MAX_HWADDR_LEN); + memcpy(esp_netif->lwip_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN); + return ESP_OK; +} + esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[]) { if (esp_netif == NULL || esp_netif->lwip_netif == NULL) { @@ -850,9 +928,7 @@ esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[]) if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_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; + return esp_netif_lwip_ipc_call(esp_netif_set_mac_api, esp_netif, mac); } esp_err_t esp_netif_get_mac(esp_netif_t *esp_netif, uint8_t mac[]) @@ -2018,70 +2094,75 @@ int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t } } +struct dhcp_params { + esp_netif_dhcp_option_mode_t op; + esp_netif_dhcp_option_id_t id; + void *val; + uint32_t len; +}; + #if ESP_DHCPS -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_api(esp_netif_api_msg_t *msg) { - if (esp_netif == NULL || esp_netif->dhcps == NULL) { - return ESP_ERR_ESP_NETIF_IF_NOT_READY; - } - void *opt_info = dhcps_option_info(esp_netif->dhcps, opt_id, opt_len); + esp_netif_t *esp_netif = msg->esp_netif; + struct dhcp_params *opt = msg->data; + void *opt_info = dhcps_option_info(esp_netif->dhcps, opt->id, opt->len); esp_netif_dhcp_status_t dhcps_status = esp_netif->dhcps_status; - if (opt_info == NULL || opt_val == NULL) { + if (opt_info == NULL || opt->val == NULL) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } - if (opt_op == ESP_NETIF_OP_GET) { + if (opt->op == ESP_NETIF_OP_GET) { if (dhcps_status == ESP_NETIF_DHCP_STOPPED) { return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED; } - switch (opt_id) { + switch (opt->id) { case IP_ADDRESS_LEASE_TIME: { - *(uint32_t *)opt_val = *(uint32_t *)opt_info; + *(uint32_t *)opt->val = *(uint32_t *)opt_info; break; } case ESP_NETIF_SUBNET_MASK: case REQUESTED_IP_ADDRESS: { - memcpy(opt_val, opt_info, opt_len); + memcpy(opt->val, opt_info, opt->len); break; } case ROUTER_SOLICITATION_ADDRESS: { if ((*(uint8_t *)opt_info) & OFFER_ROUTER) { - *(uint8_t *)opt_val = 1; + *(uint8_t *)opt->val = 1; } else { - *(uint8_t *)opt_val = 0; + *(uint8_t *)opt->val = 0; } break; } case DOMAIN_NAME_SERVER: { if ((*(uint8_t *)opt_info) & OFFER_DNS) { - *(uint8_t *)opt_val = 1; + *(uint8_t *)opt->val = 1; } else { - *(uint8_t *)opt_val = 0; + *(uint8_t *)opt->val = 0; } break; } default: break; } - } else if (opt_op == ESP_NETIF_OP_SET) { + } else if (opt->op == ESP_NETIF_OP_SET) { if (dhcps_status == ESP_NETIF_DHCP_STARTED) { return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED; } - switch (opt_id) { + switch (opt->id) { case IP_ADDRESS_LEASE_TIME: { - if (*(uint32_t *)opt_val != 0) { - *(uint32_t *)opt_info = *(uint32_t *)opt_val; + if (*(uint32_t *)opt->val != 0) { + *(uint32_t *)opt_info = *(uint32_t *)opt->val; } else { *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF; } break; } case ESP_NETIF_SUBNET_MASK: { - memcpy(opt_info, opt_val, opt_len); + memcpy(opt_info, opt->val, opt->len); break; } case REQUESTED_IP_ADDRESS: { @@ -2089,7 +2170,7 @@ esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m uint32_t softap_ip = 0; uint32_t start_ip = 0; uint32_t end_ip = 0; - dhcps_lease_t *poll = opt_val; + dhcps_lease_t *poll = opt->val; if (poll->enable) { memset(&info, 0x00, sizeof(esp_netif_ip_info_t)); @@ -2116,11 +2197,11 @@ esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m } } - memcpy(opt_info, opt_val, opt_len); + memcpy(opt_info, opt->val, opt->len); break; } case ROUTER_SOLICITATION_ADDRESS: { - if (*(uint8_t *)opt_val) { + if (*(uint8_t *)opt->val) { *(uint8_t *)opt_info |= OFFER_ROUTER; } else { *(uint8_t *)opt_info &= ((~OFFER_ROUTER) & 0xFF); @@ -2128,7 +2209,7 @@ esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m break; } case DOMAIN_NAME_SERVER: { - if (*(uint8_t *)opt_val) { + if (*(uint8_t *)opt->val) { *(uint8_t *)opt_info |= OFFER_DNS; } else { *(uint8_t *)opt_info &= ((~OFFER_DNS) & 0xFF); @@ -2139,63 +2220,82 @@ esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_m default: break; } - dhcps_set_option_info(esp_netif->dhcps, opt_id, opt_info, opt_len); + dhcps_set_option_info(esp_netif->dhcps, opt->id, opt_info, opt->len); } else { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } return ESP_OK; } + +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) +{ + if (esp_netif == NULL || esp_netif->dhcps == NULL) { + return ESP_ERR_ESP_NETIF_IF_NOT_READY; + } + struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val }; + return esp_netif_lwip_ipc_call(esp_netif_dhcps_option_api, esp_netif, &opts); +} #endif +esp_err_t esp_netif_dhcpc_option_api(esp_netif_api_msg_t *msg) +{ + esp_netif_t *esp_netif = msg->esp_netif; + struct dhcp_params *opt = msg->data; + + struct dhcp *dhcp = netif_dhcp_data(esp_netif->lwip_netif); + if (dhcp == NULL || opt->val == NULL) { + return ESP_ERR_ESP_NETIF_INVALID_PARAMS; + } + if (opt->op == ESP_NETIF_OP_GET) { + if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) { + return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED; + } + switch (opt->id) { + case ESP_NETIF_IP_REQUEST_RETRY_TIME: + if (opt->len == sizeof(dhcp->tries)) { + *(uint8_t *)opt->val = dhcp->tries; + } + break; +#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER + case ESP_NETIF_VENDOR_SPECIFIC_INFO: + return dhcp_get_vendor_specific_information(opt->len, opt->val); +#endif + default: + return ESP_ERR_ESP_NETIF_INVALID_PARAMS; + } + } else if (opt->op == ESP_NETIF_OP_SET) { + if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) { + return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED; + } + switch (opt->id) { + case ESP_NETIF_IP_REQUEST_RETRY_TIME: + if (opt->len == sizeof(dhcp->tries)) { + dhcp->tries = *(uint8_t *)opt->val; + } + break; +#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER + case ESP_NETIF_VENDOR_CLASS_IDENTIFIER: + return dhcp_set_vendor_class_identifier(opt->len, opt->val); +#endif + default: + return ESP_ERR_ESP_NETIF_INVALID_PARAMS; + } + } else { + return ESP_ERR_ESP_NETIF_INVALID_PARAMS; + } + return ESP_OK; +} + 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) { if (esp_netif == NULL || esp_netif->lwip_netif == NULL) { return ESP_ERR_ESP_NETIF_IF_NOT_READY; } - struct dhcp *dhcp = netif_dhcp_data(esp_netif->lwip_netif); - if (dhcp == NULL || opt_val == NULL) { - return ESP_ERR_ESP_NETIF_INVALID_PARAMS; - } - if (opt_op == ESP_NETIF_OP_GET) { - if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) { - return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED; - } - switch (opt_id) { - case ESP_NETIF_IP_REQUEST_RETRY_TIME: - if (opt_len == sizeof(dhcp->tries)) { - *(uint8_t *)opt_val = dhcp->tries; - } - break; -#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER - case ESP_NETIF_VENDOR_SPECIFIC_INFO: - return dhcp_get_vendor_specific_information(opt_len, opt_val); -#endif - default: - return ESP_ERR_ESP_NETIF_INVALID_PARAMS; - } - } else if (opt_op == ESP_NETIF_OP_SET) { - if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) { - return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED; - } - switch (opt_id) { - case ESP_NETIF_IP_REQUEST_RETRY_TIME: - if (opt_len == sizeof(dhcp->tries)) { - dhcp->tries = *(uint8_t *)opt_val; - } - break; -#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER - case ESP_NETIF_VENDOR_CLASS_IDENTIFIER: - return dhcp_set_vendor_class_identifier(opt_len, opt_val); -#endif - default: - return ESP_ERR_ESP_NETIF_INVALID_PARAMS; - } - } else { - return ESP_ERR_ESP_NETIF_INVALID_PARAMS; - } - return ESP_OK; + struct dhcp_params opts = { .op = opt_op, .id = opt_id, .len = opt_len, .val = opt_val }; + return esp_netif_lwip_ipc_call(esp_netif_dhcpc_option_api, esp_netif, &opts); } int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif) @@ -2206,6 +2306,13 @@ int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif) return netif_get_index(esp_netif->lwip_netif); } +esp_err_t esp_netif_get_netif_impl_name_api(esp_netif_api_msg_t *msg) +{ + struct netif* netif = msg->esp_netif->lwip_netif; + netif_index_to_name(netif_get_index(netif), msg->data); + return ESP_OK; +} + esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name) { ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif); @@ -2213,8 +2320,7 @@ esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name) if (esp_netif == NULL || esp_netif->lwip_netif == NULL) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } - netif_index_to_name(netif_get_index(esp_netif->lwip_netif), name); - return ESP_OK; + return esp_netif_lwip_ipc_call(esp_netif_get_netif_impl_name_api, esp_netif, name); } #if MIB2_STATS diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 332a4f822d..05eb7aa0dc 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -21,7 +21,10 @@ typedef struct esp_netif_api_msg_s { int type; /**< The first field MUST be int */ int ret; esp_netif_api_fn api_fn; - esp_netif_t *esp_netif; + union { + esp_netif_t *esp_netif; + esp_netif_callback_fn user_fn; + }; void *data; } esp_netif_api_msg_t; diff --git a/components/esp_netif/private_include/esp_netif_private.h b/components/esp_netif/private_include/esp_netif_private.h index f5355614c9..b7fcfa6ef1 100644 --- a/components/esp_netif/private_include/esp_netif_private.h +++ b/components/esp_netif/private_include/esp_netif_private.h @@ -1,16 +1,8 @@ -// Copyright 2015-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. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ESP_NETIF_PRIVATE_H_ #define _ESP_NETIF_PRIVATE_H_ @@ -145,34 +137,6 @@ void esp_netif_list_unlock(void); */ bool esp_netif_is_netif_listed(esp_netif_t *esp_netif); -/** - * @brief Cause the TCP/IP stack to join a multicast group - * - * @param[in] esp_netif Handle to esp-netif instance - * @param[in] addr The multicast group to join - * - * @return - * - ESP_OK - * - ESP_ERR_ESP_NETIF_INVALID_PARAMS - * - ESP_ERR_ESP_NETIF_MLD6_FAILED - * - ESP_ERR_NO_MEM - */ -esp_err_t esp_netif_join_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr); - -/** - * @brief Cause the TCP/IP stack to leave a multicast group - * - * @param[in] esp_netif Handle to esp-netif instance - * @param[in] addr The multicast group to leave - * - * @return - * - ESP_OK - * - ESP_ERR_ESP_NETIF_INVALID_PARAMS - * - ESP_ERR_ESP_NETIF_MLD6_FAILED - * - ESP_ERR_NO_MEM - */ -esp_err_t esp_netif_leave_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr); - /** * @brief Cause the TCP/IP stack to add an IPv6 address to the interface * diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index f4fe8634f1..f6a6487d6e 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -19,12 +19,21 @@ menu "LWIP" bool "Enable tcpip core locking" default n help - If Enable tcpip core locking,Creates a global mutex that is held + If Enable tcpip core locking,Creates a global mutex that is held during TCPIP thread operations.Can be locked by client code to perform lwIP operations without changing into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and UNLOCK_TCPIP_CORE(). - If disable tcpip core locking,TCP IP will perform tasks through context switching. + If disable tcpip core locking,TCP IP will perform tasks through context switching + + config LWIP_CHECK_THREAD_SAFETY + bool "Checks that lwip API runs in expected context" + default n + help + Enable to check that the project does not violate lwip thread safety. + If enabled, all lwip functions that require thread awareness run an assertion + to verify that the TCP/IP core functionality is either locked or accessed + from the correct thread. config LWIP_DNS_SUPPORT_MDNS_QUERIES bool "Enable mDNS queries in resolving host name" diff --git a/components/lwip/apps/sntp/sntp.c b/components/lwip/apps/sntp/sntp.c index 677574d200..ab30d89a62 100644 --- a/components/lwip/apps/sntp/sntp.c +++ b/components/lwip/apps/sntp/sntp.c @@ -1,27 +1,22 @@ -// Copyright 2015-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. +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include #include #include #include "esp_log.h" -#include "sntp.h" -#include "lwip/apps/sntp.h" +#include "esp_sntp.h" +#include "lwip/tcpip.h" static const char *TAG = "sntp"; +ESP_STATIC_ASSERT(SNTP_OPMODE_POLL == ESP_SNTP_OPMODE_POLL, "SNTP mode in lwip doesn't match the IDF enum. Please make sure lwIP version is correct"); +ESP_STATIC_ASSERT(SNTP_OPMODE_LISTENONLY == ESP_SNTP_OPMODE_LISTENONLY, "SNTP mode in lwip doesn't match the IDF enum. Please make sure lwIP version is correct"); + static volatile sntp_sync_mode_t sntp_sync_mode = SNTP_SYNC_MODE_IMMED; static volatile sntp_sync_status_t sntp_sync_status = SNTP_SYNC_STATUS_RESET; static sntp_sync_time_cb_t time_sync_notification_cb = NULL; @@ -108,11 +103,17 @@ uint32_t sntp_get_sync_interval(void) return s_sync_interval; } +static void sntp_do_restart(void *ctx) +{ + (void)ctx; + sntp_stop(); + sntp_init(); +} + bool sntp_restart(void) { if (sntp_enabled()) { - sntp_stop(); - sntp_init(); + tcpip_callback(sntp_do_restart, NULL); return true; } return false; @@ -132,3 +133,98 @@ void sntp_get_system_time(uint32_t *sec, uint32_t *us) *(us) = tv.tv_usec; sntp_set_sync_status(SNTP_SYNC_STATUS_RESET); } + +static void do_setoperatingmode(void *ctx) +{ + esp_sntp_operatingmode_t operating_mode = (esp_sntp_operatingmode_t)ctx; + sntp_setoperatingmode(operating_mode); +} + +void esp_sntp_setoperatingmode(esp_sntp_operatingmode_t operating_mode) +{ + tcpip_callback(do_setoperatingmode, (void*)operating_mode); +} + +static void do_init(void *ctx) +{ + sntp_init(); +} + +void esp_sntp_init(void) +{ + tcpip_callback(do_init, NULL); +} + +static void do_stop(void *ctx) +{ + sntp_stop(); +} + +void esp_sntp_stop(void) +{ + tcpip_callback(do_stop, NULL); +} + +struct do_setserver { + u8_t idx; + const ip_addr_t *addr; +}; + +static void do_setserver(void *ctx) +{ + struct do_setserver *params = ctx; + sntp_setserver(params->idx, params->addr); +} + +void esp_sntp_setserver(u8_t idx, const ip_addr_t *addr) +{ + struct do_setserver params = { + .idx = idx, + .addr = addr + }; + tcpip_callback(do_setserver, ¶ms); +} + +struct do_setservername { + u8_t idx; + const char *server; +}; + +static void do_setservername(void *ctx) +{ + struct do_setservername *params = ctx; + sntp_setservername(params->idx, params->server); +} + +void esp_sntp_setservername(u8_t idx, const char *server) +{ + struct do_setservername params = { + .idx = idx, + .server = server + }; + tcpip_callback(do_setservername, ¶ms); +} + +const char *esp_sntp_getservername(u8_t idx) +{ + return sntp_getservername(idx); +} + +const ip_addr_t* esp_sntp_getserver(u8_t idx) +{ + return sntp_getserver(idx); +} + +#if LWIP_DHCP_GET_NTP_SRV +static void do_servermode_dhcp(void* ctx) +{ + u8_t servermode = (bool)ctx ? 1 : 0; + sntp_servermode_dhcp(servermode); +} + +void esp_sntp_servermode_dhcp(bool enable) +{ + tcpip_callback(do_servermode_dhcp, (void*)enable); +} + +#endif /* LWIP_DHCP_GET_NTP_SRV */ diff --git a/components/lwip/include/apps/esp_sntp.h b/components/lwip/include/apps/esp_sntp.h index 1a4f9db37f..d968befefc 100644 --- a/components/lwip/include/apps/esp_sntp.h +++ b/components/lwip/include/apps/esp_sntp.h @@ -10,7 +10,6 @@ #include "lwip/err.h" #include "lwip/apps/sntp.h" - #ifdef __cplusplus extern "C" { #endif @@ -38,6 +37,17 @@ extern "C" { * to wait for the next sync cycle. */ +/// Aliases for esp_sntp prefixed API (inherently thread safe) +#define esp_sntp_sync_time sntp_sync_time +#define esp_sntp_set_sync_mode sntp_set_sync_mode +#define esp_sntp_get_sync_mode sntp_get_sync_mode +#define esp_sntp_get_sync_status sntp_get_sync_status +#define esp_sntp_set_sync_status sntp_set_sync_status +#define esp_sntp_set_time_sync_notification_cb sntp_set_time_sync_notification_cb +#define esp_sntp_set_sync_interval sntp_set_sync_interval +#define esp_sntp_get_sync_interval sntp_get_sync_interval +#define esp_sntp_restart sntp_restart + /// SNTP time update mode typedef enum { SNTP_SYNC_MODE_IMMED, /*!< Update system time immediately when receiving a response from the SNTP server. */ @@ -51,6 +61,12 @@ typedef enum { SNTP_SYNC_STATUS_IN_PROGRESS, // Smooth time sync in progress. } sntp_sync_status_t; +/// SNTP operating modes per lwip SNTP module +typedef enum { + ESP_SNTP_OPMODE_POLL, + ESP_SNTP_OPMODE_LISTENONLY, +} esp_sntp_operatingmode_t; + /** * @brief SNTP callback function for notifying about time sync event * @@ -143,6 +159,60 @@ uint32_t sntp_get_sync_interval(void); */ bool sntp_restart(void); +/** + * @brief Sets SNTP operating mode. The mode has to be set before init. + * + * @param operating_mode Desired operating mode + */ +void esp_sntp_setoperatingmode(esp_sntp_operatingmode_t operating_mode); + +/** + * @brief Init and start SNTP service + */ +void esp_sntp_init(void); + +/** + * @brief Stops SNTP service + */ +void esp_sntp_stop(void); + +/** + * @brief Sets SNTP server address + * + * @param idx Index of the server + * @param addr IP address of the server + */ +void esp_sntp_setserver(u8_t idx, const ip_addr_t *addr); + +/** + * @brief Sets SNTP hostname + * @param idx Index of the server + * @param server Name of the server + */ +void esp_sntp_setservername(u8_t idx, const char *server); + +/** + * @brief Gets SNTP server name + * @param idx Index of the server + * @return Name of the server + */ +const char *esp_sntp_getservername(u8_t idx); + +/** + * @brief Get SNTP server IP + * @param idx Index of the server + * @return IP address of the server + */ +const ip_addr_t* esp_sntp_getserver(u8_t idx); + +#if LWIP_DHCP_GET_NTP_SRV +/** + * @brief Enable acquiring SNTP server from DHCP + * @param enable True for enabling SNTP from DHCP + */ +void esp_sntp_servermode_dhcp(bool enable); +#endif /* LWIP_DHCP_GET_NTP_SRV */ + #ifdef __cplusplus } #endif diff --git a/components/lwip/include/apps/sntp/sntp.h b/components/lwip/include/apps/sntp/sntp.h index 616fd55460..50ba6b3843 100644 --- a/components/lwip/include/apps/sntp/sntp.h +++ b/components/lwip/include/apps/sntp/sntp.h @@ -1,27 +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 +/* + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ -// 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 __SNTP_H__ -#define __SNTP_H__ +#pragma once +#warning "sntp.h in IDF's lwip port folder is deprecated. Please include esp_sntp.h" /* * This header is provided only for compatibility reasons for existing * applications which directly include "sntp.h" from the IDF default paths. - * and will be removed in IDF v5.0. + * and will be removed in IDF v6.0. * It is recommended to use "esp_sntp.h" from IDF's lwip port folder */ - #include "esp_sntp.h" - -#endif // __SNTP_H__ diff --git a/components/lwip/port/esp32/freertos/sys_arch.c b/components/lwip/port/esp32/freertos/sys_arch.c index 28228ff505..fa9c1ef0fa 100644 --- a/components/lwip/port/esp32/freertos/sys_arch.c +++ b/components/lwip/port/esp32/freertos/sys_arch.c @@ -53,7 +53,6 @@ static sys_mutex_t g_lwip_protect_mutex = NULL; static pthread_key_t sys_thread_sem_key; static void sys_thread_sem_free(void* data); -sys_thread_t g_lwip_task; #if !LWIP_COMPAT_MUTEX @@ -428,10 +427,8 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize ret = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &rtos_task, CONFIG_LWIP_TCPIP_TASK_AFFINITY); - g_lwip_task = rtos_task; - - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n", - (u32_t)g_lwip_task,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE)); + LWIP_DEBUGF(TCPIP_DEBUG, ("new lwip task : %x, prio:%d,stack:%d\n", + (u32_t)rtos_task, prio, stacksize)); if (ret != pdTRUE) { return NULL; @@ -577,3 +574,36 @@ sys_delay_ms(uint32_t ms) { vTaskDelay(ms / portTICK_PERIOD_MS); } + +bool +sys_thread_tcpip(sys_thread_core_lock_t type) +{ + static sys_thread_t lwip_task = NULL; +#if LWIP_TCPIP_CORE_LOCKING + static sys_thread_t core_lock_holder = NULL; +#endif + switch (type) { + default: + return false; + case LWIP_CORE_IS_TCPIP_INITIALIZED: + return lwip_task != NULL; + case LWIP_CORE_MARK_TCPIP_TASK: + LWIP_ASSERT("LWIP_CORE_MARK_TCPIP_TASK: lwip_task == NULL", (lwip_task == NULL)); + lwip_task = (sys_thread_t) xTaskGetCurrentTaskHandle(); + return true; +#if LWIP_TCPIP_CORE_LOCKING + case LWIP_CORE_LOCK_QUERY_HOLDER: + return lwip_task ? core_lock_holder == (sys_thread_t) xTaskGetCurrentTaskHandle() : true; + case LWIP_CORE_LOCK_MARK_HOLDER: + core_lock_holder = (sys_thread_t) xTaskGetCurrentTaskHandle(); + return true; + case LWIP_CORE_LOCK_UNMARK_HOLDER: + core_lock_holder = NULL; + return true; +#else + case LWIP_CORE_LOCK_QUERY_HOLDER: + return lwip_task == NULL || lwip_task == (sys_thread_t) xTaskGetCurrentTaskHandle(); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + } + return true; +} diff --git a/components/lwip/port/esp32/include/arch/sys_arch.h b/components/lwip/port/esp32/include/arch/sys_arch.h index b4fb53a834..1cec1e01b7 100644 --- a/components/lwip/port/esp32/include/arch/sys_arch.h +++ b/components/lwip/port/esp32/include/arch/sys_arch.h @@ -100,6 +100,17 @@ sys_sem_t* sys_thread_sem_init(void); void sys_thread_sem_deinit(void); sys_sem_t* sys_thread_sem_get(void); +typedef enum { + LWIP_CORE_LOCK_QUERY_HOLDER, + LWIP_CORE_LOCK_MARK_HOLDER, + LWIP_CORE_LOCK_UNMARK_HOLDER, + LWIP_CORE_MARK_TCPIP_TASK, + LWIP_CORE_IS_TCPIP_INITIALIZED, +} sys_thread_core_lock_t; + +bool +sys_thread_tcpip(sys_thread_core_lock_t type); + #ifdef __cplusplus } #endif diff --git a/components/lwip/port/esp32/include/lwip_default_hooks.h b/components/lwip/port/esp32/include/lwip_default_hooks.h index 359263a207..28220ba75c 100644 --- a/components/lwip/port/esp32/include/lwip_default_hooks.h +++ b/components/lwip/port/esp32/include/lwip_default_hooks.h @@ -12,6 +12,7 @@ #include "lwip/pbuf.h" #include "netif/dhcp_state.h" + #ifdef ESP_IDF_LWIP_HOOK_FILENAME #include ESP_IDF_LWIP_HOOK_FILENAME #endif diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 3d39e38015..21c757a6f0 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -26,6 +26,7 @@ #include "sdkconfig.h" #include "sntp/sntp_get_set_time.h" #include "sockets_ext.h" +#include "arch/sys_arch.h" #ifdef __cplusplus extern "C" { @@ -46,9 +47,20 @@ extern "C" { */ #ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING #define LWIP_TCPIP_CORE_LOCKING 1 +#define LOCK_TCPIP_CORE() do { sys_mutex_lock(&lock_tcpip_core); sys_thread_tcpip(LWIP_CORE_LOCK_MARK_HOLDER); } while(0) +#define UNLOCK_TCPIP_CORE() do { sys_thread_tcpip(LWIP_CORE_LOCK_UNMARK_HOLDER); sys_mutex_unlock(&lock_tcpip_core); } while(0) +#ifdef CONFIG_LWIP_CHECK_THREAD_SAFETY +#define LWIP_ASSERT_CORE_LOCKED() do { LWIP_ASSERT("Required to lock TCPIP core functionality!", sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)); } while(0) +#endif /* CONFIG_LWIP_CHECK_THREAD_SAFETY */ + #else #define LWIP_TCPIP_CORE_LOCKING 0 -#endif +#ifdef CONFIG_LWIP_CHECK_THREAD_SAFETY +#define LWIP_ASSERT_CORE_LOCKED() do { LWIP_ASSERT("Required to run in TCPIP context!", sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)); } while(0) +#endif /* CONFIG_LWIP_CHECK_THREAD_SAFETY */ +#endif /* CONFIG_LWIP_TCPIP_CORE_LOCKING */ + +#define LWIP_MARK_TCPIP_THREAD() sys_thread_tcpip(LWIP_CORE_MARK_TCPIP_TASK) /** * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain @@ -846,11 +858,7 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). * Ports may call these for threads created with sys_thread_new(). */ -#if LWIP_TCPIP_CORE_LOCKING -#define LWIP_NETCONN_SEM_PER_THREAD 0 -#else #define LWIP_NETCONN_SEM_PER_THREAD 1 -#endif /** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread, * writing from a 2nd thread and closing from a 3rd thread at the same time. @@ -1199,11 +1207,17 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #endif #define LWIP_HOOK_FILENAME "lwip_default_hooks.h" #define LWIP_HOOK_IP4_ROUTE_SRC ip4_route_src_hook +#if LWIP_NETCONN_FULLDUPLEX +#define LWIP_DONE_SOCK(s) done_socket(sock) +#else +#define LWIP_DONE_SOCK(s) ((void)1) +#endif /* LWIP_NETCONN_FULLDUPLEX */ + #define LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err) \ - lwip_getsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), true): false + lwip_getsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(LWIP_DONE_SOCK(sock), true): false #define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) \ - lwip_setsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), true): false + lwip_setsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(LWIP_DONE_SOCK(sock), true): false /* --------------------------------------- diff --git a/components/lwip/test_afl_host/sdkconfig.defaults b/components/lwip/test_afl_host/sdkconfig.defaults index 81952aa5bb..ee235abe9f 100644 --- a/components/lwip/test_afl_host/sdkconfig.defaults +++ b/components/lwip/test_afl_host/sdkconfig.defaults @@ -1,2 +1,4 @@ +CONFIG_LWIP_TCPIP_CORE_LOCKING=n +CONFIG_LWIP_CHECK_THREAD_SAFETY=n CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=n CONFIG_FREERTOS_SMP=n diff --git a/docs/en/api-guides/lwip.rst b/docs/en/api-guides/lwip.rst index 89dcdc868f..71d86d207c 100644 --- a/docs/en/api-guides/lwip.rst +++ b/docs/en/api-guides/lwip.rst @@ -14,6 +14,11 @@ ESP-IDF supports the following lwIP TCP/IP stack functions: Adapted APIs ^^^^^^^^^^^^ + .. warning:: + + When using any lwIP API (other than `BSD Sockets API`_), please make sure that it is thread safe. To check if a given API call is safe, enable :ref:`CONFIG_LWIP_CHECK_THREAD_SAFETY` and run the application. This way lwIP asserts the TCP/IP core functionality to be correctly accessed; the execution aborts if it is not locked properly or accessed from the correct task (`lwIP FreeRTOS Task`_). + The general recommendation is to use :doc:`/api-reference/network/esp_netif` component to interact with lwIP. + Some common lwIP "app" APIs are supported indirectly by ESP-IDF: - DHCP Server & Client are supported indirectly via the :doc:`/api-reference/network/esp_netif` functionality diff --git a/docs/en/api-reference/system/system_time.rst b/docs/en/api-reference/system/system_time.rst index 3643e76dc8..d7f3e27c4e 100644 --- a/docs/en/api-reference/system/system_time.rst +++ b/docs/en/api-reference/system/system_time.rst @@ -122,9 +122,9 @@ To start synchronization via SNTP, just call the following three functions: .. code-block:: c - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_setservername(0, "pool.ntp.org"); - sntp_init(); + esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL); + esp_sntp_setservername(0, "pool.ntp.org"); + esp_sntp_init(); An application with this initialization code will periodically synchronize the time. The time synchronization period is determined by :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` (the default value is one hour). To modify the variable, set :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` in project configuration. diff --git a/docs/zh_CN/api-reference/system/system_time.rst b/docs/zh_CN/api-reference/system/system_time.rst index 1d1a8c7e17..d2ef956931 100644 --- a/docs/zh_CN/api-reference/system/system_time.rst +++ b/docs/zh_CN/api-reference/system/system_time.rst @@ -122,9 +122,9 @@ lwIP SNTP 库提供了 API 函数,用于设置某个事件的回调函数。 .. code-block:: c - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_setservername(0, "pool.ntp.org"); - sntp_init(); + esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL); + esp_sntp_setservername(0, "pool.ntp.org"); + esp_sntp_init(); 添加此初始化代码后,应用程序将定期同步时间。时间同步周期由 :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` 设置(默认为一小时)。如需修改,请在项目配置中设置 :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY`。 diff --git a/examples/protocols/http2_request/main/http2_request_example_main.c b/examples/protocols/http2_request/main/http2_request_example_main.c index b7fd45bd7d..5a250f73bf 100644 --- a/examples/protocols/http2_request/main/http2_request_example_main.c +++ b/examples/protocols/http2_request/main/http2_request_example_main.c @@ -17,7 +17,7 @@ #include "freertos/task.h" #include "esp_wifi.h" #include "esp_event.h" -#include "lwip/apps/sntp.h" +#include "esp_sntp.h" #include "esp_system.h" #include "nvs_flash.h" #include "protocol_examples_common.h" @@ -90,8 +90,8 @@ static void set_time(void) settimeofday(&tv, &tz); /* Start SNTP service */ - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_init(); + esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL); + esp_sntp_init(); } static void http2_task(void *args) diff --git a/examples/protocols/https_request/main/time_sync.c b/examples/protocols/https_request/main/time_sync.c index 653889617d..895acbc86d 100644 --- a/examples/protocols/https_request/main/time_sync.c +++ b/examples/protocols/https_request/main/time_sync.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,12 +33,12 @@ static const char *TAG = "time_sync"; void initialize_sntp(void) { ESP_LOGI(TAG, "Initializing SNTP"); - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_setservername(0, "pool.ntp.org"); + esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL); + esp_sntp_setservername(0, "pool.ntp.org"); #ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH); #endif - sntp_init(); + esp_sntp_init(); } static void obtain_time(void) @@ -47,8 +47,8 @@ static void obtain_time(void) * NTP server address could be aquired via DHCP, * see LWIP_DHCP_GET_NTP_SRV menuconfig option */ -#ifdef LWIP_DHCP_GET_NTP_SRV - sntp_servermode_dhcp(1); +#if LWIP_DHCP_GET_NTP_SRV + esp_sntp_servermode_dhcp(1); #endif // wait for time to be set @@ -89,7 +89,7 @@ void fetch_and_store_time_in_nvs(void *args) } nvs_close(my_handle); - sntp_stop(); + esp_sntp_stop(); exit: if (err != ESP_OK) { diff --git a/examples/protocols/sntp/main/sntp_example_main.c b/examples/protocols/sntp/main/sntp_example_main.c index cada529e83..9730bfb9fe 100644 --- a/examples/protocols/sntp/main/sntp_example_main.c +++ b/examples/protocols/sntp/main/sntp_example_main.c @@ -135,8 +135,8 @@ static void obtain_time(void) * NOTE: This call should be made BEFORE esp aquires IP address from DHCP, * otherwise NTP option would be rejected by default. */ -#ifdef LWIP_DHCP_GET_NTP_SRV - sntp_servermode_dhcp(1); // accept NTP offers from DHCP server, if any +#if LWIP_DHCP_GET_NTP_SRV + esp_sntp_servermode_dhcp(1); // accept NTP offers from DHCP server, if any #endif /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. @@ -165,7 +165,7 @@ static void obtain_time(void) static void initialize_sntp(void) { ESP_LOGI(TAG, "Initializing SNTP"); - sntp_setoperatingmode(SNTP_OPMODE_POLL); + esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL); /* * If 'NTP over DHCP' is enabled, we set dynamic pool address @@ -173,37 +173,37 @@ static void initialize_sntp(void) * provided via NTP over DHCP is not accessible */ #if LWIP_DHCP_GET_NTP_SRV && SNTP_MAX_SERVERS > 1 - sntp_setservername(1, "pool.ntp.org"); + esp_sntp_setservername(1, "pool.ntp.org"); #if LWIP_IPV6 && SNTP_MAX_SERVERS > 2 // statically assigned IPv6 address is also possible ip_addr_t ip6; if (ipaddr_aton("2a01:3f7::1", &ip6)) { // ipv6 ntp source "ntp.netnod.se" - sntp_setserver(2, &ip6); + esp_sntp_setserver(2, &ip6); } #endif /* LWIP_IPV6 */ #else /* LWIP_DHCP_GET_NTP_SRV && (SNTP_MAX_SERVERS > 1) */ // otherwise, use DNS address from a pool - sntp_setservername(0, CONFIG_SNTP_TIME_SERVER); + esp_sntp_setservername(0, CONFIG_SNTP_TIME_SERVER); - sntp_setservername(1, "pool.ntp.org"); // set the secondary NTP server (will be used only if SNTP_MAX_SERVERS > 1) + esp_sntp_setservername(1, "pool.ntp.org"); // set the secondary NTP server (will be used only if SNTP_MAX_SERVERS > 1) #endif sntp_set_time_sync_notification_cb(time_sync_notification_cb); #ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH); #endif - sntp_init(); + esp_sntp_init(); ESP_LOGI(TAG, "List of configured NTP servers:"); for (uint8_t i = 0; i < SNTP_MAX_SERVERS; ++i){ - if (sntp_getservername(i)){ - ESP_LOGI(TAG, "server %d: %s", i, sntp_getservername(i)); + if (esp_sntp_getservername(i)){ + ESP_LOGI(TAG, "server %d: %s", i, esp_sntp_getservername(i)); } else { // we have either IPv4 or IPv6 address, let's print it char buff[INET6_ADDRSTRLEN]; - ip_addr_t const *ip = sntp_getserver(i); + ip_addr_t const *ip = esp_sntp_getserver(i); if (ipaddr_ntoa_r(ip, buff, INET6_ADDRSTRLEN) != NULL) ESP_LOGI(TAG, "server %d: %s", i, buff); } diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 47a7d97fb7..00bcdc4fdc 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -459,7 +459,6 @@ components/esp_local_ctrl/src/esp_local_ctrl_handler.c components/esp_local_ctrl/src/esp_local_ctrl_priv.h components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c components/esp_netif/include/esp_netif_ppp.h -components/esp_netif/private_include/esp_netif_private.h components/esp_netif/test/test_esp_netif.c components/esp_netif/test_apps/component_ut_test.py components/esp_netif/test_apps/main/esp_netif_test.c @@ -796,11 +795,9 @@ components/log/esp_log_private.h components/log/host_test/log_test/main/log_test.cpp components/log/log_linux.c components/lwip/apps/ping/ping.c -components/lwip/apps/sntp/sntp.c components/lwip/include/apps/dhcpserver/dhcpserver_options.h components/lwip/include/apps/esp_ping.h components/lwip/include/apps/ping/ping.h -components/lwip/include/apps/sntp/sntp.h components/lwip/port/esp32/debug/lwip_debug.c components/lwip/port/esp32/freertos/sys_arch.c components/lwip/port/esp32/hooks/tcp_isn_default.c