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);
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;
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");
}
}
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;
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;
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};
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"
void tcpip_adapter_init(void)
{
- static bool tcpip_inited = false;
int ret;
if (tcpip_inited == false) {
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");
}
}
}
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
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]);
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;
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;
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;
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) ||
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];
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)) {
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;
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;
#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 */