From b45433110fb3a55b584e77e40d17af5e59f72453 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Wed, 19 Jul 2017 09:15:11 +0800 Subject: [PATCH] tcpip_adapter/lwip: optimize wifi/ip event --- components/esp32/event_default_handlers.c | 25 ++- components/esp32/include/esp_event.h | 4 +- components/esp32/lib | 2 +- components/lwip/core/ipv4/dhcp.c | 17 ++ components/tcpip_adapter/Kconfig | 16 ++ .../tcpip_adapter/include/tcpip_adapter.h | 40 +++- components/tcpip_adapter/tcpip_adapter_lwip.c | 184 +++++++++++++++--- 7 files changed, 252 insertions(+), 36 deletions(-) create mode 100644 components/tcpip_adapter/Kconfig diff --git a/components/esp32/event_default_handlers.c b/components/esp32/event_default_handlers.c index 75ef16465..8f1f2e936 100644 --- a/components/esp32/event_default_handlers.c +++ b/components/esp32/event_default_handlers.c @@ -55,6 +55,7 @@ static esp_err_t system_event_sta_stop_handle_default(system_event_t *event); static esp_err_t system_event_sta_connected_handle_default(system_event_t *event); static esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event); static esp_err_t system_event_sta_got_ip_default(system_event_t *event); +static esp_err_t system_event_sta_lost_ip_default(system_event_t *event); static esp_err_t system_event_eth_start_handle_default(system_event_t *event); static esp_err_t system_event_eth_stop_handle_default(system_event_t *event); @@ -135,6 +136,12 @@ static esp_err_t system_event_sta_got_ip_default(system_event_t *event) return ESP_OK; } +static esp_err_t system_event_sta_lost_ip_default(system_event_t *event) +{ + ESP_LOGI(TAG, "station ip lost"); + return ESP_OK; +} + esp_err_t system_event_ap_start_handle_default(system_event_t *event) { tcpip_adapter_ip_info_t ap_ip; @@ -191,17 +198,26 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event) tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA); } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { tcpip_adapter_ip_info_t sta_ip; + tcpip_adapter_ip_info_t sta_old_ip; tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + tcpip_adapter_get_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_old_ip); if (!(ip4_addr_isany_val(sta_ip.ip) || ip4_addr_isany_val(sta_ip.netmask) || ip4_addr_isany_val(sta_ip.gw))) { system_event_t evt; - //notify event evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + evt.event_info.got_ip.ip_changed = false; + + if (memcmp(&sta_ip, &sta_old_ip, sizeof(sta_ip))) { + evt.event_info.got_ip.ip_changed = true; + } + memcpy(&evt.event_info.got_ip.ip_info, &sta_ip, sizeof(tcpip_adapter_ip_info_t)); + tcpip_adapter_set_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); esp_event_send(&evt); + ESP_LOGD(TAG, "static ip: ip changed=%d", evt.event_info.got_ip.ip_changed); } else { ESP_LOGE(TAG, "invalid static ip"); } @@ -261,12 +277,16 @@ static esp_err_t esp_system_event_debug(system_event_t *event) } case SYSTEM_EVENT_STA_GOT_IP: { system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip; - ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOTIP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR, + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR, IP2STR(&got_ip->ip_info.ip), IP2STR(&got_ip->ip_info.netmask), IP2STR(&got_ip->ip_info.gw)); break; } + case SYSTEM_EVENT_STA_LOST_IP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_LOST_IP"); + break; + } case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: { ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_SUCCESS"); break; @@ -381,6 +401,7 @@ void esp_event_set_default_wifi_handlers() default_event_handlers[SYSTEM_EVENT_STA_CONNECTED] = system_event_sta_connected_handle_default; default_event_handlers[SYSTEM_EVENT_STA_DISCONNECTED] = system_event_sta_disconnected_handle_default; default_event_handlers[SYSTEM_EVENT_STA_GOT_IP] = system_event_sta_got_ip_default; + default_event_handlers[SYSTEM_EVENT_STA_LOST_IP] = system_event_sta_lost_ip_default; default_event_handlers[SYSTEM_EVENT_AP_START] = system_event_ap_start_handle_default; default_event_handlers[SYSTEM_EVENT_AP_STOP] = system_event_ap_stop_handle_default; diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 5cb60dba6..ccffdb818 100644 --- a/components/esp32/include/esp_event.h +++ b/components/esp32/include/esp_event.h @@ -35,6 +35,7 @@ typedef enum { SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */ SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */ SYSTEM_EVENT_STA_GOT_IP, /**< ESP32 station got IP from connected AP */ + SYSTEM_EVENT_STA_LOST_IP, /**< ESP32 station lost IP and the IP is reset to 0 */ SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */ SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */ SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */ @@ -86,6 +87,7 @@ typedef struct { typedef struct { tcpip_adapter_ip_info_t ip_info; + bool ip_changed; } system_event_sta_got_ip_t; typedef struct { @@ -116,7 +118,7 @@ typedef union { system_event_sta_disconnected_t disconnected; /**< ESP32 station disconnected to AP */ system_event_sta_scan_done_t scan_done; /**< ESP32 station scan (APs) done */ system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP32 station connected to changed */ - system_event_sta_got_ip_t got_ip; /**< ESP32 station got IP */ + system_event_sta_got_ip_t got_ip; /**< ESP32 station got IP, first time got IP or when IP is changed */ system_event_sta_wps_er_pin_t sta_er_pin; /**< ESP32 station WPS enrollee mode PIN code received */ system_event_sta_wps_fail_reason_t sta_er_fail_reason;/**< ESP32 station WPS enrollee mode failed reason code received */ system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */ diff --git a/components/esp32/lib b/components/esp32/lib index 6fda89666..0189f203c 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 6fda896660d001dd6d4aec5bae2a294a757d4276 +Subproject commit 0189f203c202a1bc27c3b76ab8c2575bcf3662b7 diff --git a/components/lwip/core/ipv4/dhcp.c b/components/lwip/core/ipv4/dhcp.c index 1c18494e1..74c9403dc 100755 --- a/components/lwip/core/ipv4/dhcp.c +++ b/components/lwip/core/ipv4/dhcp.c @@ -270,6 +270,15 @@ dhcp_handle_nak(struct netif *netif) (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); /* remove IP address from interface (must no longer be used, as per RFC2131) */ netif_set_addr(netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY); + + if (dhcp->cb != NULL) { +#ifdef ESP_LWIP + dhcp->cb(netif); +#else + dhcp->cb(); +#endif + } + /* Change to a defined state */ dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF); /* We can immediately restart discovery */ @@ -1413,6 +1422,14 @@ dhcp_release(struct netif *netif) /* remove IP address from interface (prevents routing from selecting this interface) */ netif_set_addr(netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY); + if (dhcp->cb != NULL) { +#ifdef ESP_LWIP + dhcp->cb(netif); +#else + dhcp->cb(); +#endif + } + return result; } diff --git a/components/tcpip_adapter/Kconfig b/components/tcpip_adapter/Kconfig new file mode 100644 index 000000000..eecf12054 --- /dev/null +++ b/components/tcpip_adapter/Kconfig @@ -0,0 +1,16 @@ +menu "tcpip adapter" + +config IP_LOST_TIMER_INTERVAL + int "IP Address lost timer interval (seconds)" + range 0 65535 + default 120 + help + The value of 0 indicates the IP lost timer is disabled, otherwise the timer is enabled. + + The IP address may be lost because of some reasons, e.g. when the station disconnects + from soft-AP, or when DHCP IP renew fails etc. If the IP lost timer is enabled, it will + be started everytime the IP is lost. Event SYSTEM_EVENT_STA_LOST_IP will be raised if + the timer expires. The IP lost timer is stopped if the station get the IP again before + the timer expires. + +endmenu diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index 6d99b4a81..2e6db6b5a 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -154,6 +154,10 @@ typedef struct tcpip_adapter_api_msg_s { #define TCPIP_ADAPTER_IPC_CALL(_if, _mac, _ip, _hostname, _fn) do {\ tcpip_adapter_api_msg_t msg;\ + if (tcpip_inited == false) {\ + ESP_LOGE(TAG, "tcpip_adapter is not initialized!");\ + abort();\ + }\ memset(&msg, 0, sizeof(msg));\ msg.tcpip_if = (_if);\ msg.mac = (_mac);\ @@ -168,6 +172,9 @@ typedef struct tcpip_adapter_api_msg_s { }\ }while(0) +typedef struct tcpip_adatper_ip_lost_timer_s { + bool timer_running; +} tcpip_adapter_ip_lost_timer_t; /** * @brief Initialize tcpip adapter @@ -278,13 +285,44 @@ esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i * This function is mainly used for setting static IP. * * @param[in] tcpip_if: the interface which we want to set IP information - * @param[in] ip_info: If successful, IP information will be returned in this argument. + * @param[in] ip_info: store the IP information which needs to be set to specified interface * * @return ESP_OK * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS */ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info); +/** + * @brief Get interface's old IP information + * + * When the interface successfully gets a valid IP from DHCP server or static configured, a copy of + * the IP information is set to the old IP information. When IP lost timer expires, the old IP + * information is reset to 0. + * + * @param[in] tcpip_if: the interface which we want to get old IP information + * @param[out] ip_info: If successful, IP information will be returned in this argument. + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_get_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info); + +/** + * @brief Set interface's old IP information + * + * When the interface successfully gets a valid IP from DHCP server or static configured, a copy of + * the IP information is set to the old IP information. When IP lost timer expires, the old IP + * information is reset to 0. + * + * @param[in] tcpip_if: the interface which we want to set old IP information + * @param[in] ip_info: store the IP information which needs to be set to specified interface + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_set_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info); + + /** * @brief create interface's linklocal IPv6 information * diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index a04c527b6..b1bb85bc2 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -39,8 +39,10 @@ static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX]; +static tcpip_adapter_ip_info_t esp_ip_old[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX]; static netif_init_fn esp_netif_init_fn[TCPIP_ADAPTER_IF_MAX]; +static tcpip_adapter_ip_lost_timer_t esp_ip_lost_timer[TCPIP_ADAPTER_IF_MAX]; static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT; static tcpip_adapter_dhcp_status_t dhcpc_status[TCPIP_ADAPTER_IF_MAX] = {TCPIP_ADAPTER_DHCP_INIT}; @@ -55,7 +57,12 @@ static esp_err_t tcpip_adapter_dhcps_stop_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_dhcpc_start_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_dhcpc_stop_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_set_hostname_api(tcpip_adapter_api_msg_t * msg); +static esp_err_t tcpip_adapter_reset_ip_info(tcpip_adapter_if_t tcpip_if); +static esp_err_t tcpip_adapter_start_ip_lost_timer(tcpip_adapter_if_t tcpip_if); +static void tcpip_adapter_ip_lost_timer(void *arg); static sys_sem_t api_sync_sem = NULL; +static bool tcpip_inited = false; +static sys_sem_t api_lock_sem = NULL; extern sys_thread_t g_lwip_task; #define TAG "tcpip_adapter" @@ -78,7 +85,6 @@ static void tcpip_adapter_api_cb(void* api_msg) void tcpip_adapter_init(void) { - static bool tcpip_inited = false; int ret; if (tcpip_inited == false) { @@ -87,12 +93,19 @@ void tcpip_adapter_init(void) tcpip_init(NULL, NULL); memset(esp_ip, 0, sizeof(tcpip_adapter_ip_info_t)*TCPIP_ADAPTER_IF_MAX); + memset(esp_ip_old, 0, sizeof(tcpip_adapter_ip_info_t)*TCPIP_ADAPTER_IF_MAX); + IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1); IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1); IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0); ret = sys_sem_new(&api_sync_sem, 0); if (ERR_OK != ret) { - ESP_LOGD(TAG, "tcpip adatper api sync sem init fail"); + ESP_LOGE(TAG, "tcpip adatper api sync sem init fail"); + } + + ret = sys_sem_new(&api_lock_sem, 1); + if (ERR_OK != ret) { + ESP_LOGE(TAG, "tcpip adatper api lock sem init fail"); } } } @@ -114,7 +127,9 @@ static int tcpip_adapter_ipc_check(tcpip_adapter_api_msg_t *msg) return TCPIP_ADAPTER_IPC_LOCAL; } + sys_arch_sem_wait(&api_lock_sem, 0); tcpip_send_api_msg((tcpip_callback_fn)tcpip_adapter_api_cb, msg, &api_sync_sem); + sys_sem_signal(&api_lock_sem); return TCPIP_ADAPTER_IPC_REMOTE; #else @@ -224,9 +239,7 @@ esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if) dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; - ip4_addr_set_zero(&esp_ip[tcpip_if].ip); - ip4_addr_set_zero(&esp_ip[tcpip_if].gw); - ip4_addr_set_zero(&esp_ip[tcpip_if].netmask); + tcpip_adapter_reset_ip_info(tcpip_if); } netif_set_down(esp_netif[tcpip_if]); @@ -295,15 +308,12 @@ esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if) dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; - ip4_addr_set_zero(&esp_ip[tcpip_if].ip); - ip4_addr_set_zero(&esp_ip[tcpip_if].gw); - ip4_addr_set_zero(&esp_ip[tcpip_if].netmask); + tcpip_adapter_reset_ip_info(tcpip_if); } - /* Modify ip address to trigger tcp/udp pcb cleanup */ netif_set_addr(esp_netif[tcpip_if], IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY); - netif_set_down(esp_netif[tcpip_if]); + tcpip_adapter_start_ip_lost_timer(tcpip_if); } return ESP_OK; @@ -314,6 +324,33 @@ static esp_err_t tcpip_adapter_down_api(tcpip_adapter_api_msg_t * msg) return tcpip_adapter_down(msg->tcpip_if); } +esp_err_t tcpip_adapter_set_old_ip_info_api(tcpip_adapter_api_msg_t * msg) +{ + memcpy(&esp_ip_old[msg->tcpip_if], msg->ip_info, sizeof(tcpip_adapter_ip_info_t)); + return ESP_OK; +} + +esp_err_t tcpip_adapter_set_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info) +{ + if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, ip_info, 0, tcpip_adapter_set_old_ip_info_api); + + return ESP_OK; +} + +esp_err_t tcpip_adapter_get_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info) +{ + if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) { + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + memcpy(ip_info, &esp_ip_old[tcpip_if], sizeof(tcpip_adapter_ip_info_t)); + return ESP_OK; +} + esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info) { struct netif *p_netif; @@ -378,6 +415,20 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i if (p_netif != NULL && netif_is_up(p_netif)) { netif_set_addr(p_netif, &ip_info->ip, &ip_info->netmask, &ip_info->gw); + if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->ip))) { + system_event_t evt; + evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + evt.event_info.got_ip.ip_changed = false; + + if (memcmp(ip_info, &esp_ip_old[tcpip_if], sizeof(tcpip_adapter_ip_info_t))) { + evt.event_info.got_ip.ip_changed = true; + } + + memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t)); + memcpy(&esp_ip_old[tcpip_if], ip_info, sizeof(tcpip_adapter_ip_info_t)); + esp_event_send(&evt); + ESP_LOGD(TAG, "if%d tcpip adapter set static ip: ip changed=%d", tcpip_if, evt.event_info.got_ip.ip_changed); + } } return ESP_OK; @@ -675,24 +726,30 @@ esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_a static void tcpip_adapter_dhcpc_cb(struct netif *netif) { + tcpip_adapter_ip_info_t *ip_info_old = NULL; + tcpip_adapter_ip_info_t *ip_info = NULL; + tcpip_adapter_if_t tcpip_if; + if (!netif) { ESP_LOGD(TAG, "null netif=%p", netif); return; } - if (netif != esp_netif[TCPIP_ADAPTER_IF_STA] && netif != esp_netif[TCPIP_ADAPTER_IF_ETH]) { + if( netif == esp_netif[TCPIP_ADAPTER_IF_STA] ) { + tcpip_if = TCPIP_ADAPTER_IF_STA; + } else if(netif == esp_netif[TCPIP_ADAPTER_IF_ETH] ) { + tcpip_if = TCPIP_ADAPTER_IF_ETH; + } else { ESP_LOGD(TAG, "err netif=%p", netif); return; } - if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY) ) { - tcpip_adapter_ip_info_t *ip_info = NULL; - if( netif == esp_netif[TCPIP_ADAPTER_IF_STA] ) { - ip_info = &esp_ip[TCPIP_ADAPTER_IF_STA]; - } else if(netif == esp_netif[TCPIP_ADAPTER_IF_ETH] ) { - ip_info = &esp_ip[TCPIP_ADAPTER_IF_ETH]; - } + ESP_LOGD(TAG, "if%d dhcpc cb", tcpip_if); + ip_info = &esp_ip[tcpip_if]; + ip_info_old = &esp_ip_old[tcpip_if]; + if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY) ) { + //check whether IP is changed if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), &ip_info->ip) || !ip4_addr_cmp(ip_2_ip4(&netif->netmask), &ip_info->netmask) || @@ -704,23 +761,83 @@ static void tcpip_adapter_dhcpc_cb(struct netif *netif) ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw)); //notify event - if (netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { - evt.event_id = SYSTEM_EVENT_STA_GOT_IP; - } else if (netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) { - evt.event_id = SYSTEM_EVENT_ETH_GOT_IP; + evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + evt.event_info.got_ip.ip_changed = false; + + if (memcmp(ip_info, ip_info_old, sizeof(tcpip_adapter_ip_info_t))) { + evt.event_info.got_ip.ip_changed = true; } memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t)); - + memcpy(ip_info_old, ip_info, sizeof(tcpip_adapter_ip_info_t)); + ESP_LOGD(TAG, "if%d ip changed=%d", tcpip_if, evt.event_info.got_ip.ip_changed); esp_event_send(&evt); } else { - ESP_LOGD(TAG, "ip unchanged"); + ESP_LOGD(TAG, "if%d ip unchanged", tcpip_if); + } + } else { + if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY)) { + tcpip_adapter_start_ip_lost_timer(tcpip_if); } } return; } +static esp_err_t tcpip_adapter_start_ip_lost_timer(tcpip_adapter_if_t tcpip_if) +{ + tcpip_adapter_ip_info_t *ip_info_old = &esp_ip_old[tcpip_if]; + struct netif *netif = esp_netif[tcpip_if]; + + ESP_LOGD(TAG, "if%d start ip lost tmr: enter", tcpip_if); + if (tcpip_if != TCPIP_ADAPTER_IF_STA) { + ESP_LOGD(TAG, "if%d start ip lost tmr: only sta support ip lost timer", tcpip_if); + return ESP_OK; + } + + if (esp_ip_lost_timer[tcpip_if].timer_running) { + ESP_LOGD(TAG, "if%d start ip lost tmr: already started", tcpip_if); + return ESP_OK; + } + + if ( netif && (CONFIG_IP_LOST_TIMER_INTERVAL > 0) && !ip4_addr_isany_val(ip_info_old->ip)) { + esp_ip_lost_timer[tcpip_if].timer_running = true; + sys_timeout(CONFIG_IP_LOST_TIMER_INTERVAL*1000, tcpip_adapter_ip_lost_timer, (void*)tcpip_if); + ESP_LOGD(TAG, "if%d start ip lost tmr: interval=%d", tcpip_if, CONFIG_IP_LOST_TIMER_INTERVAL); + return ESP_OK; + } + + ESP_LOGD(TAG, "if%d start ip lost tmr: no need start because netif=%p interval=%d ip=%x", + tcpip_if, netif, CONFIG_IP_LOST_TIMER_INTERVAL, ip_info_old->ip.addr); + + return ESP_OK; +} + +static void tcpip_adapter_ip_lost_timer(void *arg) +{ + tcpip_adapter_if_t tcpip_if = (tcpip_adapter_if_t)arg; + + ESP_LOGD(TAG, "if%d ip lost tmr: enter", tcpip_if); + esp_ip_lost_timer[tcpip_if].timer_running = false; + + if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + struct netif *netif = esp_netif[tcpip_if]; + + if ( (!netif) || (netif && ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY))){ + system_event_t evt; + + ESP_LOGD(TAG, "if%d ip lost tmr: raise ip lost event", tcpip_if); + memset(&esp_ip_old[tcpip_if], 0, sizeof(tcpip_adapter_ip_info_t)); + evt.event_id = SYSTEM_EVENT_STA_LOST_IP; + esp_event_send(&evt); + } else { + ESP_LOGD(TAG, "if%d ip lost tmr: no need raise ip lost event", tcpip_if); + } + } else { + ESP_LOGD(TAG, "if%d ip lost tmr: not station", tcpip_if); + } +} + esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status) { *status = dhcpc_status[tcpip_if]; @@ -741,9 +858,7 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) if (dhcpc_status[tcpip_if] != TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; - ip4_addr_set_zero(&esp_ip[tcpip_if].ip); - ip4_addr_set_zero(&esp_ip[tcpip_if].gw); - ip4_addr_set_zero(&esp_ip[tcpip_if].netmask); + tcpip_adapter_reset_ip_info(tcpip_if); if (p_netif != NULL) { if (netif_is_up(p_netif)) { @@ -751,6 +866,7 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) ip_addr_set_zero(&p_netif->ip_addr); ip_addr_set_zero(&p_netif->netmask); ip_addr_set_zero(&p_netif->gw); + tcpip_adapter_start_ip_lost_timer(tcpip_if); } else { ESP_LOGD(TAG, "dhcp client re init"); dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; @@ -798,10 +914,8 @@ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if) if (p_netif != NULL) { dhcp_stop(p_netif); - - ip4_addr_set_zero(&esp_ip[tcpip_if].ip); - ip4_addr_set_zero(&esp_ip[tcpip_if].gw); - ip4_addr_set_zero(&esp_ip[tcpip_if].netmask); + tcpip_adapter_reset_ip_info(tcpip_if); + tcpip_adapter_start_ip_lost_timer(tcpip_if); } else { ESP_LOGD(TAG, "dhcp client if not ready"); return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; @@ -934,4 +1048,12 @@ esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **h #endif } +static esp_err_t tcpip_adapter_reset_ip_info(tcpip_adapter_if_t tcpip_if) +{ + ip4_addr_set_zero(&esp_ip[tcpip_if].ip); + ip4_addr_set_zero(&esp_ip[tcpip_if].gw); + ip4_addr_set_zero(&esp_ip[tcpip_if].netmask); + return ESP_OK; +} + #endif /* CONFIG_TCPIP_LWIP */