mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp_netif/lwip: Fix core-locking config (v5.0)
* Fix thread safety issues in non-core locking * Add option to verify thread safety issues in lwip (core-lock assertion) * Make esp_sntp.h thread safe API * Fix sntp examples Closes https://github.com/espressif/esp-idf/issues/9908 Closes https://github.com/espressif/esp-idf/issues/10502 Closes https://github.com/espressif/esp-idf/issues/10466
This commit is contained in:
parent
f9f4a23159
commit
5b75693522
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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"
|
||||
|
@ -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 <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#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 */
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
---------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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`。
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user