// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include "tcpip_adapter_internal.h" #if CONFIG_TCPIP_LWIP #include "lwip/inet.h" #include "lwip/tcpip.h" #include "lwip/dhcp.h" #include "lwip/ip_addr.h" #include "lwip/ip6_addr.h" #include "lwip/nd6.h" #include "lwip/priv/tcpip_priv.h" #include "lwip/netif.h" #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ #include "lwip/dns.h" #endif #include "netif/wlanif.h" #include "netif/ethernetif.h" #if CONFIG_LWIP_TCP_ISN_HOOK #include "tcp_isn.h" #endif #include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver_options.h" #include "esp_event.h" #include "esp_log.h" 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_start_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_stop_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_up_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_down_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_set_ip_info_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_set_dns_info_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_get_dns_info_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_create_ip6_linklocal_api(tcpip_adapter_api_msg_t * msg); static esp_err_t tcpip_adapter_dhcps_start_api(tcpip_adapter_api_msg_t * msg); 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; static const char* TAG = "tcpip_adapter"; static void tcpip_adapter_api_cb(void* api_msg) { tcpip_adapter_api_msg_t *msg = (tcpip_adapter_api_msg_t*)api_msg; if (!msg || !msg->api_fn) { ESP_LOGD(TAG, "null msg/api_fn"); return; } msg->ret = msg->api_fn(msg); ESP_LOGV(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret); sys_sem_signal(&api_sync_sem); return; } static void tcpip_adapter_dhcps_cb(u8_t client_ip[4]) { ESP_LOGI(TAG,"softAP assign IP to station,IP is: %d.%d.%d.%d", client_ip[0],client_ip[1],client_ip[2],client_ip[3]); system_event_t evt; memset(&evt, 0, sizeof(system_event_t)); evt.event_id = SYSTEM_EVENT_AP_STAIPASSIGNED; memcpy((char *)&evt.event_info.ap_staipassigned.ip.addr, (char *)client_ip, sizeof(evt.event_info.ap_staipassigned.ip.addr)); esp_event_send(&evt); } void tcpip_adapter_init(void) { int ret; if (tcpip_inited == false) { #if CONFIG_LWIP_TCP_ISN_HOOK uint8_t rand_buf[16]; /* * This is early startup code where WiFi/BT is yet to be enabled and hence * relevant entropy source is not available. However, bootloader enables * SAR ADC based entropy source at its initialization, and our requirement * of random bytes is pretty small (16), so we can assume that following * API will provide sufficiently random data. */ esp_fill_random(rand_buf, sizeof(rand_buf)); lwip_init_tcp_isn(esp_log_timestamp(), rand_buf); #endif tcpip_inited = true; 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_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"); } } } static inline netif_init_fn tcpip_if_to_netif_init_fn(tcpip_adapter_if_t tcpip_if) { if (tcpip_if < TCPIP_ADAPTER_IF_MAX) return esp_netif_init_fn[tcpip_if]; else return NULL; } static int tcpip_adapter_ipc_check(tcpip_adapter_api_msg_t *msg) { #if TCPIP_ADAPTER_TRHEAD_SAFE xTaskHandle local_task = xTaskGetCurrentTaskHandle(); if (local_task == g_lwip_task) { return TCPIP_ADAPTER_IPC_LOCAL; } sys_arch_sem_wait(&api_lock_sem, 0); tcpip_send_msg_wait_sem((tcpip_callback_fn)tcpip_adapter_api_cb, msg, &api_sync_sem); sys_sem_signal(&api_lock_sem); return TCPIP_ADAPTER_IPC_REMOTE; #else return TCPIP_ADAPTER_IPC_LOCAL; #endif } static esp_err_t tcpip_adapter_update_default_netif(void) { if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_STA])) { netif_set_default(esp_netif[TCPIP_ADAPTER_IF_STA]); } else if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_ETH])) { netif_set_default(esp_netif[TCPIP_ADAPTER_IF_ETH]); } else if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_AP])) { netif_set_default(esp_netif[TCPIP_ADAPTER_IF_AP]); } return ESP_OK; } static esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info) { netif_init_fn netif_init; TCPIP_ADAPTER_IPC_CALL(tcpip_if, mac, ip_info, 0, tcpip_adapter_start_api); if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL || ip_info == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (esp_netif[tcpip_if] == NULL || !netif_is_up(esp_netif[tcpip_if])) { if (esp_netif[tcpip_if] == NULL) { esp_netif[tcpip_if] = calloc(1, sizeof(*esp_netif[tcpip_if])); } if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_NO_MEM; } memcpy(esp_netif[tcpip_if]->hwaddr, mac, NETIF_MAX_HWADDR_LEN); netif_init = tcpip_if_to_netif_init_fn(tcpip_if); assert(netif_init != NULL); netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, netif_init, tcpip_input); #if ESP_GRATUITOUS_ARP if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { netif_set_garp_flag(esp_netif[tcpip_if]); } #endif } if (tcpip_if == TCPIP_ADAPTER_IF_AP) { netif_set_up(esp_netif[tcpip_if]); if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) { dhcps_set_new_lease_cb(tcpip_adapter_dhcps_cb); dhcps_start(esp_netif[tcpip_if], ip_info->ip); ESP_LOGD(TAG, "dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")", IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw)); dhcps_status = TCPIP_ADAPTER_DHCP_STARTED; } } tcpip_adapter_update_default_netif(); return ESP_OK; } esp_err_t tcpip_adapter_eth_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info) { esp_netif_init_fn[TCPIP_ADAPTER_IF_ETH] = ethernetif_init; return tcpip_adapter_start(TCPIP_ADAPTER_IF_ETH, mac, ip_info); } esp_err_t tcpip_adapter_sta_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info) { esp_netif_init_fn[TCPIP_ADAPTER_IF_STA] = wlanif_init_sta; return tcpip_adapter_start(TCPIP_ADAPTER_IF_STA, mac, ip_info); } esp_err_t tcpip_adapter_ap_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info) { esp_netif_init_fn[TCPIP_ADAPTER_IF_AP] = wlanif_init_ap; return tcpip_adapter_start(TCPIP_ADAPTER_IF_AP, mac, ip_info); } static esp_err_t tcpip_adapter_start_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_start(msg->tcpip_if, msg->mac, msg->ip_info); } esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_stop_api); if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } if (!netif_is_up(esp_netif[tcpip_if])) { netif_remove(esp_netif[tcpip_if]); return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } if (tcpip_if == TCPIP_ADAPTER_IF_AP) { dhcps_stop(esp_netif[tcpip_if]); // TODO: dhcps checks status by its self if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status) { dhcps_status = TCPIP_ADAPTER_DHCP_INIT; } } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { dhcp_release(esp_netif[tcpip_if]); dhcp_stop(esp_netif[tcpip_if]); dhcp_cleanup(esp_netif[tcpip_if]); dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; tcpip_adapter_reset_ip_info(tcpip_if); } netif_set_down(esp_netif[tcpip_if]); netif_remove(esp_netif[tcpip_if]); tcpip_adapter_update_default_netif(); return ESP_OK; } static esp_err_t tcpip_adapter_stop_api(tcpip_adapter_api_msg_t * msg) { msg->ret = tcpip_adapter_stop(msg->tcpip_if); return msg->ret; } esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_up_api); if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) { if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } /* use last obtained ip, or static ip */ netif_set_addr(esp_netif[tcpip_if], &esp_ip[tcpip_if].ip, &esp_ip[tcpip_if].netmask, &esp_ip[tcpip_if].gw); netif_set_up(esp_netif[tcpip_if]); } tcpip_adapter_update_default_netif(); return ESP_OK; } static esp_err_t tcpip_adapter_up_api(tcpip_adapter_api_msg_t * msg) { msg->ret = tcpip_adapter_up(msg->tcpip_if); return msg->ret; } esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_down_api); if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) { if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) { dhcp_stop(esp_netif[tcpip_if]); dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; tcpip_adapter_reset_ip_info(tcpip_if); } for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) { netif_ip6_addr_set(esp_netif[tcpip_if] ,i ,IP6_ADDR_ANY6); netif_ip6_addr_set_state(esp_netif[tcpip_if], i, IP6_ADDR_INVALID); } netif_set_addr(esp_netif[tcpip_if], IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); netif_set_down(esp_netif[tcpip_if]); tcpip_adapter_start_ip_lost_timer(tcpip_if); } tcpip_adapter_update_default_netif(); return ESP_OK; } 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, const 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 (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL && netif_is_up(p_netif)) { ip4_addr_set(&ip_info->ip, ip_2_ip4(&p_netif->ip_addr)); ip4_addr_set(&ip_info->netmask, ip_2_ip4(&p_netif->netmask)); ip4_addr_set(&ip_info->gw, ip_2_ip4(&p_netif->gw)); return ESP_OK; } ip4_addr_copy(ip_info->ip, esp_ip[tcpip_if].ip); ip4_addr_copy(ip_info->gw, esp_ip[tcpip_if].gw); ip4_addr_copy(ip_info->netmask, esp_ip[tcpip_if].netmask); return ESP_OK; } esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info) { struct netif *p_netif; tcpip_adapter_dhcp_status_t status; TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, ip_info, 0, tcpip_adapter_set_ip_info_api); if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (tcpip_if == TCPIP_ADAPTER_IF_AP) { tcpip_adapter_dhcps_get_status(tcpip_if, &status); if (status != TCPIP_ADAPTER_DHCP_STOPPED) { return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED; } } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) { tcpip_adapter_dhcpc_get_status(tcpip_if, &status); if (status != TCPIP_ADAPTER_DHCP_STOPPED) { return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED; } #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ dns_clear_servers(true); #endif } ip4_addr_copy(esp_ip[tcpip_if].ip, ip_info->ip); ip4_addr_copy(esp_ip[tcpip_if].gw, ip_info->gw); ip4_addr_copy(esp_ip[tcpip_if].netmask, ip_info->netmask); p_netif = esp_netif[tcpip_if]; if (p_netif != NULL && netif_is_up(p_netif)) { netif_set_addr(p_netif, &ip_info->ip, &ip_info->netmask, &ip_info->gw); if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask) || ip4_addr_isany_val(ip_info->gw))) { system_event_t evt; memset(&evt, 0, sizeof(system_event_t)); if (tcpip_if == TCPIP_ADAPTER_IF_STA) { evt.event_id = SYSTEM_EVENT_STA_GOT_IP; } else if (tcpip_if == TCPIP_ADAPTER_IF_ETH) { evt.event_id = SYSTEM_EVENT_ETH_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 esp_err_t tcpip_adapter_set_ip_info_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_set_ip_info(msg->tcpip_if, msg->ip_info); } static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex) { tcpip_adapter_ip6_info_t *ip6_info; system_event_t evt; memset(&evt, 0, sizeof(system_event_t)); //notify event evt.event_id = SYSTEM_EVENT_GOT_IP6; if (!p_netif) { ESP_LOGD(TAG, "null p_netif=%p", p_netif); return; } if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_STA]; evt.event_info.got_ip6.if_index = TCPIP_ADAPTER_IF_STA; } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) { ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP]; evt.event_info.got_ip6.if_index = TCPIP_ADAPTER_IF_AP; } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) { ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_ETH]; evt.event_info.got_ip6.if_index = TCPIP_ADAPTER_IF_ETH; } else { return; } ip6_addr_set(&ip6_info->ip, ip_2_ip6(&p_netif->ip6_addr[ip_idex])); memcpy(&evt.event_info.got_ip6.ip6_info, ip6_info, sizeof(tcpip_adapter_ip6_info_t)); esp_event_send(&evt); } esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if) { struct netif *p_netif; TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_create_ip6_linklocal_api); if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL && netif_is_up(p_netif)) { netif_create_ip6_linklocal_address(p_netif, 1); nd6_set_cb(p_netif, tcpip_adapter_nd6_cb); return ESP_OK; } else { return ESP_FAIL; } } static esp_err_t tcpip_adapter_create_ip6_linklocal_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_create_ip6_linklocal(msg->tcpip_if); } esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6) { struct netif *p_netif; if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) { memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t)); } else { return ESP_FAIL; } return ESP_OK; } esp_err_t tcpip_adapter_get_ip6_global(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6) { ESP_LOGD(TAG, "%s esp-netif:%p", __func__, esp_netif); if (tcpip_if >=TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } int i; struct netif *p_netif = esp_netif[tcpip_if]; if (p_netif != NULL && netif_is_up(p_netif)) { for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, i))) { memcpy(if_ip6, &p_netif->ip6_addr[i], sizeof(ip6_addr_t)); return ESP_OK; } } } return ESP_FAIL; } #if 0 esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6]) { struct netif *p_netif; if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { memcpy(mac, p_netif->hwaddr, NETIF_MAX_HWADDR_LEN); return ESP_OK; } return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6]) { struct netif *p_netif; if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { memcpy(p_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN); return ESP_OK; } return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } #endif esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len) { void *opt_info = dhcps_option_info(opt_id, opt_len); if (opt_info == NULL || opt_val == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (opt_op == TCPIP_ADAPTER_OP_GET) { if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) { return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED; } switch (opt_id) { case IP_ADDRESS_LEASE_TIME: { *(uint32_t *)opt_val = *(uint32_t *)opt_info; break; } case REQUESTED_IP_ADDRESS: { memcpy(opt_val, opt_info, opt_len); break; } case ROUTER_SOLICITATION_ADDRESS: { if ((*(uint8_t *)opt_info) & OFFER_ROUTER) { *(uint8_t *)opt_val = 1; } else { *(uint8_t *)opt_val = 0; } break; } case DOMAIN_NAME_SERVER: { if ((*(uint8_t *)opt_info) & OFFER_DNS) { *(uint8_t *)opt_val = 1; } else { *(uint8_t *)opt_val = 0; } break; } default: break; } } else if (opt_op == TCPIP_ADAPTER_OP_SET) { if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) { return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED; } switch (opt_id) { case IP_ADDRESS_LEASE_TIME: { 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 REQUESTED_IP_ADDRESS: { tcpip_adapter_ip_info_t info; uint32_t softap_ip = 0; uint32_t start_ip = 0; uint32_t end_ip = 0; dhcps_lease_t *poll = opt_val; if (poll->enable) { memset(&info, 0x00, sizeof(tcpip_adapter_ip_info_t)); tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &info); softap_ip = htonl(info.ip.addr); start_ip = htonl(poll->start_ip.addr); end_ip = htonl(poll->end_ip.addr); /*config ip information can't contain local ip*/ if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } /*config ip information must be in the same segment as the local ip*/ softap_ip >>= 8; if ((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (end_ip - start_ip > DHCPS_MAX_LEASE) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } } memcpy(opt_info, opt_val, opt_len); break; } case ROUTER_SOLICITATION_ADDRESS: { if (*(uint8_t *)opt_val) { *(uint8_t *)opt_info |= OFFER_ROUTER; } else { *(uint8_t *)opt_info &= ((~OFFER_ROUTER)&0xFF); } break; } case DOMAIN_NAME_SERVER: { if (*(uint8_t *)opt_val) { *(uint8_t *)opt_info |= OFFER_DNS; } else { *(uint8_t *)opt_info &= ((~OFFER_DNS)&0xFF); } break; } default: break; } dhcps_set_option_info(opt_id, opt_info,opt_len); } else { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } return ESP_OK; } esp_err_t tcpip_adapter_set_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns) { tcpip_adapter_dns_param_t dns_param; dns_param.dns_type = type; dns_param.dns_info = dns; TCPIP_ADAPTER_IPC_CALL(tcpip_if, type, 0, &dns_param, tcpip_adapter_set_dns_info_api); if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) { ESP_LOGD(TAG, "set dns invalid if=%d", tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (!dns) { ESP_LOGD(TAG, "set dns null dns"); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (type >= TCPIP_ADAPTER_DNS_MAX) { ESP_LOGD(TAG, "set dns invalid type=%d", type); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (ip4_addr_isany_val(dns->ip.u_addr.ip4)) { ESP_LOGD(TAG, "set dns invalid dns"); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } ESP_LOGD(TAG, "set dns if=%d type=%d dns=%x", tcpip_if, type, dns->ip.u_addr.ip4.addr); dns->ip.type = IPADDR_TYPE_V4; if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { dns_setserver(type, &(dns->ip)); } else { if (type != TCPIP_ADAPTER_DNS_MAIN) { ESP_LOGD(TAG, "set dns invalid type"); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } else { dhcps_dns_setserver(&(dns->ip)); } } return ESP_OK; } static esp_err_t tcpip_adapter_set_dns_info_api(tcpip_adapter_api_msg_t * msg) { tcpip_adapter_dns_param_t *dns_param = (tcpip_adapter_dns_param_t*)msg->data; return tcpip_adapter_set_dns_info(msg->tcpip_if, dns_param->dns_type, dns_param->dns_info); } esp_err_t tcpip_adapter_get_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns) { tcpip_adapter_dns_param_t dns_param; dns_param.dns_type = type; dns_param.dns_info = dns; const ip_addr_t* dns_ip = NULL; TCPIP_ADAPTER_IPC_CALL(tcpip_if, type, 0, &dns_param, tcpip_adapter_get_dns_info_api); if (!dns) { ESP_LOGD(TAG, "get dns null dns"); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (type >= TCPIP_ADAPTER_DNS_MAX) { ESP_LOGD(TAG, "get dns invalid type=%d", type); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) { ESP_LOGD(TAG, "get dns invalid tcpip_if=%d",tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) { dns_ip = dns_getserver(type); if (dns_ip != NULL) { dns->ip = *dns_ip; } } else { dns->ip.u_addr.ip4 = dhcps_dns_getserver(); } return ESP_OK; } static esp_err_t tcpip_adapter_get_dns_info_api(tcpip_adapter_api_msg_t * msg) { tcpip_adapter_dns_param_t *dns_param = (tcpip_adapter_dns_param_t*)msg->data; return tcpip_adapter_get_dns_info(msg->tcpip_if, dns_param->dns_type, dns_param->dns_info); } esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status) { *status = dhcps_status; return ESP_OK; } esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcps_start_api); /* only support ap now */ if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { ESP_LOGD(TAG, "dhcp server invalid if=%d", tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (dhcps_status != TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; if (p_netif != NULL && netif_is_up(p_netif)) { tcpip_adapter_ip_info_t default_ip; tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &default_ip); dhcps_set_new_lease_cb(tcpip_adapter_dhcps_cb); dhcps_start(p_netif, default_ip.ip); dhcps_status = TCPIP_ADAPTER_DHCP_STARTED; ESP_LOGD(TAG, "dhcp server start successfully"); return ESP_OK; } else { ESP_LOGD(TAG, "dhcp server re init"); dhcps_status = TCPIP_ADAPTER_DHCP_INIT; return ESP_OK; } } ESP_LOGD(TAG, "dhcp server already start"); return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED; } static esp_err_t tcpip_adapter_dhcps_start_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_dhcps_start(msg->tcpip_if); } esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcps_stop_api); /* only support ap now */ if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { ESP_LOGD(TAG, "dhcp server invalid if=%d", tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { dhcps_stop(p_netif); } else { ESP_LOGD(TAG, "dhcp server if not ready"); return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } } else if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) { ESP_LOGD(TAG, "dhcp server already stoped"); return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED; } ESP_LOGD(TAG, "dhcp server stop successfully"); dhcps_status = TCPIP_ADAPTER_DHCP_STOPPED; return ESP_OK; } static esp_err_t tcpip_adapter_dhcps_stop_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_dhcps_stop(msg->tcpip_if); } esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len) { // TODO: when dhcp request timeout,change the retry count return ESP_ERR_NOT_SUPPORTED; } 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] ) { 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; } 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_ANY4) ) { //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_cmp(ip_2_ip4(&netif->gw), (&ip_info->gw)) ) { system_event_t evt; memset(&evt, 0, sizeof(system_event_t)); ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr)); ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask)); ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw)); //notify event if (tcpip_if == TCPIP_ADAPTER_IF_ETH) { evt.event_id = SYSTEM_EVENT_ETH_GOT_IP; evt.event_info.got_ip.ip_changed = true; } else { 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, "if%d ip unchanged", tcpip_if); } } else { if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY4)) { 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_ANY4))){ system_event_t evt; memset(&evt, 0, sizeof(system_event_t)); 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]; return ESP_OK; } esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcpc_start_api); if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH) || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (dhcpc_status[tcpip_if] != TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; tcpip_adapter_reset_ip_info(tcpip_if); #if LWIP_DNS dns_clear_servers(true); #endif if (p_netif != NULL) { if (netif_is_up(p_netif)) { ESP_LOGD(TAG, "dhcp client init ip/mask/gw to all-0"); 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; return ESP_OK; } if (dhcp_start(p_netif) != ERR_OK) { ESP_LOGD(TAG, "dhcp client start failed"); return ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED; } dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb); ESP_LOGD(TAG, "dhcp client start successfully"); dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED; return ESP_OK; } else { ESP_LOGD(TAG, "dhcp client re init"); dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT; return ESP_OK; } } ESP_LOGD(TAG, "dhcp client already started"); return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED; } static esp_err_t tcpip_adapter_dhcpc_start_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_dhcpc_start(msg->tcpip_if); } esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if) { TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcpc_stop_api); if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH) || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if); return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) { struct netif *p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { dhcp_stop(p_netif); 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; } } else if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STOPPED) { ESP_LOGD(TAG, "dhcp client already stoped"); return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED; } ESP_LOGD(TAG, "dhcp client stop successfully"); dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED; LWIP_DHCP_IP_ADDR_ERASE(); return ESP_OK; } static esp_err_t tcpip_adapter_dhcpc_stop_api(tcpip_adapter_api_msg_t * msg) { return tcpip_adapter_dhcpc_stop(msg->tcpip_if); } esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb) { ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len); return ESP_OK; } esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb) { wlanif_input(esp_netif[TCPIP_ADAPTER_IF_STA], buffer, len, eb); return ESP_OK; } esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb) { wlanif_input(esp_netif[TCPIP_ADAPTER_IF_AP], buffer, len, eb); return ESP_OK; } #if 0 bool tcpip_dep_output(wifi_interface_t wifi_if, void *buffer, uint16_t len) { return true; } #endif esp_interface_t tcpip_adapter_get_esp_if(void *dev) { struct netif *p_netif = (struct netif *)dev; if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) { return ESP_IF_WIFI_STA; } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) { return ESP_IF_WIFI_AP; } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) { return ESP_IF_ETH; } return ESP_IF_MAX; } esp_err_t tcpip_adapter_get_sta_list(const wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list) { int i; if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t)); tcpip_sta_list->num = wifi_sta_list->num; for (i = 0; i < wifi_sta_list->num; i++) { memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6); dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip); } return ESP_OK; } esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname) { #if LWIP_NETIF_HOSTNAME TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, hostname, tcpip_adapter_set_hostname_api); struct netif *p_netif; static char hostinfo[TCPIP_ADAPTER_IF_MAX][TCPIP_HOSTNAME_MAX_SIZE + 1]; if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } if (strlen(hostname) > TCPIP_HOSTNAME_MAX_SIZE) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { memset(hostinfo[tcpip_if], 0, sizeof(hostinfo[tcpip_if])); strlcpy(hostinfo[tcpip_if], hostname, sizeof(hostinfo[tcpip_if])); p_netif->hostname = hostinfo[tcpip_if]; return ESP_OK; } else { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } #else return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; #endif } static esp_err_t tcpip_adapter_set_hostname_api(tcpip_adapter_api_msg_t * msg) { const char *hostname = (char*) msg->data; return tcpip_adapter_set_hostname(msg->tcpip_if, hostname); } esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname) { #if LWIP_NETIF_HOSTNAME struct netif *p_netif = NULL; if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } p_netif = esp_netif[tcpip_if]; if (p_netif != NULL) { *hostname = p_netif->hostname; return ESP_OK; } else { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } #else 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; } esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif) { if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } *netif = esp_netif[tcpip_if]; if (*netif == NULL) { return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY; } return ESP_OK; } bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if) { if (esp_netif[tcpip_if] != NULL && netif_is_up(esp_netif[tcpip_if])) { return true; } else { return false; } } #endif /* CONFIG_TCPIP_LWIP */