From b041d65caa30b2ce6d86c364727575c78aa8f30f Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Tue, 26 Jun 2018 17:15:50 +0800 Subject: [PATCH] feat(tcpip_adapter): Refactor tcpip_adapter APIs --- components/esp8266/include/esp_wifi_types.h | 1 - components/esp8266/source/esp_wifi.c | 2 + .../lwip/port/esp8266/netif/ethernetif.c | 21 +- components/tcpip_adapter/Kconfig | 15 +- .../tcpip_adapter/include/tcpip_adapter.h | 530 +++++++- components/tcpip_adapter/tcpip_adapter_lwip.c | 1100 +++++++++++++++++ components/tcpip_adapter/tcpip_adapter_wifi.c | 600 --------- 7 files changed, 1639 insertions(+), 630 deletions(-) create mode 100644 components/tcpip_adapter/tcpip_adapter_lwip.c delete mode 100644 components/tcpip_adapter/tcpip_adapter_wifi.c diff --git a/components/esp8266/include/esp_wifi_types.h b/components/esp8266/include/esp_wifi_types.h index 20e656f0..76fdf746 100755 --- a/components/esp8266/include/esp_wifi_types.h +++ b/components/esp8266/include/esp_wifi_types.h @@ -20,7 +20,6 @@ #include #include "esp_err.h" #include "esp_interface.h" -#include "queue.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp8266/source/esp_wifi.c b/components/esp8266/source/esp_wifi.c index d2b39672..1cd489c9 100644 --- a/components/esp8266/source/esp_wifi.c +++ b/components/esp8266/source/esp_wifi.c @@ -18,6 +18,8 @@ #include "esp_socket.h" #include "net/sockio.h" +esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config); + /** * @brief Init WiFi * Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer, diff --git a/components/lwip/port/esp8266/netif/ethernetif.c b/components/lwip/port/esp8266/netif/ethernetif.c index 37ecd0d4..21b18a49 100644 --- a/components/lwip/port/esp8266/netif/ethernetif.c +++ b/components/lwip/port/esp8266/netif/ethernetif.c @@ -26,6 +26,9 @@ int8_t ieee80211_output_pbuf(uint8_t fd, uint8_t* dataptr, uint16_t datalen); int8_t wifi_get_netif(uint8_t fd); void wifi_station_set_default_hostname(uint8_t* hwaddr); +#define IFNAME0 'e' +#define IFNAME1 'n' + /** * In this function, the hardware should be initialized. * Called from ethernetif_init(). @@ -36,7 +39,7 @@ void wifi_station_set_default_hostname(uint8_t* hwaddr); static void low_level_init(struct netif* netif) { if (netif == NULL) { - TCPIP_ATAPTER_LOG("ERROR netif is NULL\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("low_level_init: netif is NULL\n")); return; } @@ -48,7 +51,7 @@ static void low_level_init(struct netif* netif) /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; #if LWIP_IGMP netif->flags |= NETIF_FLAG_IGMP; @@ -131,7 +134,7 @@ static int8_t low_level_output(struct netif* netif, struct pbuf* p) int8_t err = ERR_OK; if (netif == NULL) { - TCPIP_ATAPTER_LOG("ERROR netif is NULL\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: netif is NULL\n")); return ERR_ARG; } @@ -186,23 +189,23 @@ void ethernetif_input(struct netif* netif, struct pbuf* p) struct eth_hdr* ethhdr; if (p == NULL) { - TCPIP_ATAPTER_LOG("ERROR pbuf is NULL\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: pbuf is NULL\n")); goto _exit; } if (p->payload == NULL) { - TCPIP_ATAPTER_LOG("ERROR payload is NULL\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: payload is NULL\n")); pbuf_free(p); goto _exit; } if (netif == NULL) { - TCPIP_ATAPTER_LOG("ERROR netif is NULL\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: netif is NULL\n")); goto _exit; } if (!(netif->flags & NETIF_FLAG_LINK_UP)) { - TCPIP_ATAPTER_LOG("ERROR netif is not up\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: netif is not up\n")); pbuf_free(p); p = NULL; goto _exit; @@ -225,7 +228,7 @@ void ethernetif_input(struct netif* netif, struct pbuf* p) /* full packet send to tcpip_thread to process */ if (netif->input(p, netif) != ERR_OK) { - TCPIP_ATAPTER_LOG("ERROR IP input error\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); pbuf_free(p); p = NULL; } @@ -259,7 +262,7 @@ int8_t ethernetif_init(struct netif* netif) uint8_t mac[NETIF_MAX_HWADDR_LEN]; if (netif == NULL) { - TCPIP_ATAPTER_LOG("ERROR netif is NULL\n"); + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: netif is NULL\n")); } /* set MAC hardware address */ diff --git a/components/tcpip_adapter/Kconfig b/components/tcpip_adapter/Kconfig index 86eb7a3c..eecf1205 100644 --- a/components/tcpip_adapter/Kconfig +++ b/components/tcpip_adapter/Kconfig @@ -1,7 +1,16 @@ menu "tcpip adapter" -config TCPIP_ADAPER_DEBUG - bool "Enable tcpip adaptor debug" - default 1 +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 9270a1cf..1d48b322 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -15,7 +15,6 @@ #ifndef _TCPIP_ADAPTER_H_ #define _TCPIP_ADAPTER_H_ -#include "sdkconfig.h" /** * @brief TCPIP adapter library * @@ -33,8 +32,41 @@ * get free station list APIs in application side. Other APIs are used in ESP8266_RTOS_SDK internal, * otherwise the state maybe wrong. * + * TODO: ipv6 support will be added, use menuconfig to disable CONFIG_TCPIP_LWIP */ +#include +#include "esp_wifi_types.h" + +#define CONFIG_TCPIP_LWIP 1 +#define CONFIG_DHCP_STA_LIST 1 + +#if CONFIG_TCPIP_LWIP +#include "lwip/ip_addr.h" +#include "dhcpserver/dhcpserver.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ + ip4_addr2_16(ipaddr), \ + ip4_addr3_16(ipaddr), \ + ip4_addr4_16(ipaddr) + +#define IPSTR "%d.%d.%d.%d" + +#define IPV62STR(ipaddr) IP6_ADDR_BLOCK1(&(ipaddr)), \ + IP6_ADDR_BLOCK2(&(ipaddr)), \ + IP6_ADDR_BLOCK3(&(ipaddr)), \ + IP6_ADDR_BLOCK4(&(ipaddr)), \ + IP6_ADDR_BLOCK5(&(ipaddr)), \ + IP6_ADDR_BLOCK6(&(ipaddr)), \ + IP6_ADDR_BLOCK7(&(ipaddr)), \ + IP6_ADDR_BLOCK8(&(ipaddr)) + +#define IPV6STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" + typedef struct { ip4_addr_t ip; ip4_addr_t netmask; @@ -45,28 +77,101 @@ typedef struct { ip6_addr_t ip; } tcpip_adapter_ip6_info_t; +typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t; + +#if CONFIG_DHCP_STA_LIST +typedef struct { + uint8_t mac[6]; + ip4_addr_t ip; +} tcpip_adapter_sta_info_t; + +typedef struct { + tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; + int num; +} tcpip_adapter_sta_list_t; +#endif + +#endif + +#define ESP_ERR_TCPIP_ADAPTER_BASE 0x5000 // TODO: move base address to esp_err.h + +#define ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS ESP_ERR_TCPIP_ADAPTER_BASE + 0x01 +#define ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY ESP_ERR_TCPIP_ADAPTER_BASE + 0x02 +#define ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED ESP_ERR_TCPIP_ADAPTER_BASE + 0x03 +#define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED ESP_ERR_TCPIP_ADAPTER_BASE + 0x04 +#define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED ESP_ERR_TCPIP_ADAPTER_BASE + 0x05 +#define ESP_ERR_TCPIP_ADAPTER_NO_MEM ESP_ERR_TCPIP_ADAPTER_BASE + 0x06 +#define ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED ESP_ERR_TCPIP_ADAPTER_BASE + 0x07 + +/* TODO: add Ethernet interface */ typedef enum { - TCPIP_ADAPTER_IF_STA = 0, /**< ESP8266 station interface */ - TCPIP_ADAPTER_IF_AP, /**< ESP8266 soft-AP interface */ + TCPIP_ADAPTER_IF_STA = 0, /**< ESP32 station interface */ + TCPIP_ADAPTER_IF_AP, /**< ESP32 soft-AP interface */ + TCPIP_ADAPTER_IF_ETH, /**< ESP32 ethernet interface */ TCPIP_ADAPTER_IF_MAX } tcpip_adapter_if_t; -struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX]; -char* hostname; -bool default_hostname; +/*type of DNS server*/ +typedef enum { + TCPIP_ADAPTER_DNS_MAIN= 0, /**DNS main server address*/ + TCPIP_ADAPTER_DNS_BACKUP, /**DNS backup server address,for STA only,support soft-AP in future*/ + TCPIP_ADAPTER_DNS_FALLBACK, /**DNS fallback server address,for STA only*/ + TCPIP_ADAPTER_DNS_MAX /**Max DNS */ +} tcpip_adapter_dns_type_t; -#define TCPIP_ADAPTER_IF_VALID(fd) ((fd < TCPIP_ADAPTER_IF_MAX) ? 1 : 0) +/*info of DNS server*/ +typedef struct { + ip_addr_t ip; +} tcpip_adapter_dns_info_t; -/* Define those to better describe your network interface. */ -#define IFNAME0 'e' -#define IFNAME1 'n' +/* status of DHCP client or DHCP server */ +typedef enum { + TCPIP_ADAPTER_DHCP_INIT = 0, /**< DHCP client/server in initial state */ + TCPIP_ADAPTER_DHCP_STARTED, /**< DHCP client/server already been started */ + TCPIP_ADAPTER_DHCP_STOPPED, /**< DHCP client/server already been stopped */ + TCPIP_ADAPTER_DHCP_STATUS_MAX +} tcpip_adapter_dhcp_status_t; -#ifdef CONFIG_TCPIP_ADAPER_DEBUG -#define TAG "TCPIP_ADAPTER" -#define TCPIP_ATAPTER_LOG(str, ...) printf(TAG " line: %d " str, __LINE__, ##__VA_ARGS__) -#else -#define TCPIP_ATAPTER_LOG(str, ...) -#endif +/* set the option mode for DHCP client or DHCP server */ +typedef enum{ + TCPIP_ADAPTER_OP_START = 0, + TCPIP_ADAPTER_OP_SET, /**< set option mode */ + TCPIP_ADAPTER_OP_GET, /**< get option mode */ + TCPIP_ADAPTER_OP_MAX +} tcpip_adapter_option_mode_t; + +typedef enum{ + TCPIP_ADAPTER_DOMAIN_NAME_SERVER = 6, /**< domain name server */ + TCPIP_ADAPTER_ROUTER_SOLICITATION_ADDRESS = 32, /**< solicitation router address */ + TCPIP_ADAPTER_REQUESTED_IP_ADDRESS = 50, /**< request IP address pool */ + TCPIP_ADAPTER_IP_ADDRESS_LEASE_TIME = 51, /**< request IP address lease time */ + TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52, /**< request IP address retry counter */ +} tcpip_adapter_option_id_t; + +struct tcpip_adapter_api_msg_s; +typedef int (*tcpip_adapter_api_fn)(struct tcpip_adapter_api_msg_s *msg); +typedef struct tcpip_adapter_api_msg_s { + int type; /**< The first field MUST be int */ + int ret; + tcpip_adapter_api_fn api_fn; + tcpip_adapter_if_t tcpip_if; + tcpip_adapter_ip_info_t *ip_info; + uint8_t *mac; + void *data; +} tcpip_adapter_api_msg_t; + +typedef struct tcpip_adapter_dns_param_s { + tcpip_adapter_dns_type_t dns_type; + tcpip_adapter_dns_info_t *dns_info; +} tcpip_adapter_dns_param_t; + +#define TCPIP_ADAPTER_TRHEAD_SAFE 1 +#define TCPIP_ADAPTER_IPC_LOCAL 0 +#define TCPIP_ADAPTER_IPC_REMOTE 1 + +typedef struct tcpip_adatper_ip_lost_timer_s { + bool timer_running; +} tcpip_adapter_ip_lost_timer_t; /** * @brief Initialize tcpip adapter @@ -75,4 +180,395 @@ bool default_hostname; */ void tcpip_adapter_init(void); -#endif /* _TCPIP_ADAPTER_H_ */ \ No newline at end of file +/** + * @brief Start the Wi-Fi station/AP interface with specific MAC and IP + * + * Station/AP interface will be initialized, connect WiFi stack with TCPIP stack. + * + * @param[in] tcpip_if: Station/AP interface + * @param[in] mac: set MAC address of this interface + * @param[in] ip_info: set IP address of this interface + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_NO_MEM + */ +esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info); + +/** + * @brief Stop an interface + * + * The interface will be cleanup in this API, if DHCP server/client are started, will be stopped. + * + * @param[in] tcpip_if: the interface which will be started + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY + */ +esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Bring up an interface + * + * Only station interface need to be brought up, since station interface will be shut down when disconnect. + * + * @param[in] tcpip_if: the interface which will be up + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY + */ +esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Shut down an interface + * + * Only station interface need to be shut down, since station interface will be brought up when connect. + * + * @param[in] tcpip_if: the interface which will be down + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY + */ +esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Get interface's IP information + * + * There has an IP information copy in adapter library, if interface is up, get IP information from + * interface, otherwise get from copy. + * + * @param[in] tcpip_if: the interface which we want to get 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_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info); + +/** + * @brief Set interface's IP information + * + * There has an IP information copy in adapter library, if interface is up, also set interface's IP. + * DHCP client/server should be stopped before set new IP information. + * + * 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: 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 Set DNS Server's information + * + * There has an DNS Server information copy in adapter library, set DNS Server for appointed interface and type. + * + * 1.In station mode, if dhcp client is enabled, then only the fallback DNS server can be set(TCPIP_ADAPTER_DNS_FALLBACK). + * Fallback DNS server is only used if no DNS servers are set via DHCP. + * If dhcp client is disabled, then need to set main/backup dns server(TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP). + * + * 2.In soft-AP mode, the DNS Server's main dns server offered to the station is the IP address of soft-AP, + * if the application don't want to use the IP address of soft-AP, they can set the main dns server. + * + * This function is mainly used for setting static or Fallback DNS Server. + * + * @param[in] tcpip_if: the interface which we want to set DNS Server information + * @param[in] type: the type of DNS Server,including TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP, TCPIP_ADAPTER_DNS_FALLBACK + * @param[in] dns: the DNS Server address to be set + * + * @return + * - ESP_OK on success + * - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS invalid params + */ +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); + +/** + * @brief Get DNS Server's information + * + * When set the DNS Server information successfully, can get the DNS Server's information via the appointed tcpip_if and type + * + * This function is mainly used for getting DNS Server information. + * + * @param[in] tcpip_if: the interface which we want to get DNS Server information + * @param[in] type: the type of DNS Server,including TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP, TCPIP_ADAPTER_DNS_FALLBACK + * @param[in] dns: the DNS Server address to be get + * + * @return + * - ESP_OK on success + * - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS invalid params + */ +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); + +/** + * @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 + * + * @note this function will create a linklocal IPv6 address about input interface, + * if this address status changed to preferred, will call event call back , + * notify user linklocal IPv6 address has been verified + * + * @param[in] tcpip_if: the interface which we want to set IP information + * + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if); + +/** + * @brief get interface's linkloacl IPv6 information + * + * There has an IPv6 information copy in adapter library, if interface is up,and IPv6 info + * is preferred,it will get IPv6 linklocal IP successfully + * + * @param[in] tcpip_if: the interface which we want to set IP information + * @param[in] if_ip6: If successful, IPv6 information will be returned in this argument. + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6); + +#if 0 +esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac); + +esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac); +#endif + +/** + * @brief Get DHCP server's status + * + * @param[in] tcpip_if: the interface which we will get status of DHCP server + * @param[out] status: If successful, the status of DHCP server will be return in this argument. + * + * @return ESP_OK + */ +esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status); + +/** + * @brief Set or Get DHCP server's option + * + * @param[in] opt_op: option operate type, 1 for SET, 2 for GET. + * @param[in] opt_id: option index, 32 for ROUTER, 50 for IP POLL, 51 for LEASE TIME, 52 for REQUEST TIME + * @param[in] opt_val: option parameter + * @param[in] opt_len: option length + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED + * ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED + */ +esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len); + +/** + * @brief Start DHCP server + * + * @note Currently DHCP server is bind to softAP interface. + * + * @param[in] tcpip_if: the interface which we will start DHCP server + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED + */ +esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Stop DHCP server + * + * @note Currently DHCP server is bind to softAP interface. + * + * @param[in] tcpip_if: the interface which we will stop DHCP server + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPED + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY + */ +esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Get DHCP client status + * + * @param[in] tcpip_if: the interface which we will get status of DHCP client + * @param[out] status: If successful, the status of DHCP client will be return in this argument. + * + * @return ESP_OK + */ +esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status); + +/** + * @brief Set or Get DHCP client's option + * + * @note This function is not implement now. + * + * @param[in] opt_op: option operate type, 1 for SET, 2 for GET. + * @param[in] opt_id: option index, 32 for ROUTER, 50 for IP POLL, 51 for LEASE TIME, 52 for REQUEST TIME + * @param[in] opt_val: option parameter + * @param[in] opt_len: option length + * + * @return ESP_OK + */ +esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len); + +/** + * @brief Start DHCP client + * + * @note Currently DHCP client is bind to station interface. + * + * @param[in] tcpip_if: the interface which we will start DHCP client + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED + * ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED + */ +esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if); + +/** + * @brief Stop DHCP client + * + * @note Currently DHCP client is bind to station interface. + * + * @param[in] tcpip_if: the interface which we will stop DHCP client + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + * ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPED + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY + */ +esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if); + + + +esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb); + +/** + * @brief Get data from station interface + * + * This function should be installed by esp_wifi_reg_rxcb, so WiFi packets will be forward to TCPIP stack. + * + * @param[in] void *buffer: the received data point + * @param[in] uint16_t len: the received data length + * @param[in] void *eb: parameter + * + * @return ESP_OK + */ +esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb); + +/** + * @brief Get data from softAP interface + * + * This function should be installed by esp_wifi_reg_rxcb, so WiFi packets will be forward to TCPIP stack. + * + * @param[in] void *buffer: the received data point + * @param[in] uint16_t len: the received data length + * @param[in] void *eb: parameter + * + * @return ESP_OK + */ +esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb); + +/** + * @brief Get WiFi interface index + * + * Get WiFi interface from TCPIP interface struct pointer. + * + * @param[in] void *dev: adapter interface + * + * @return ESP_IF_WIFI_STA + * ESP_IF_WIFI_AP + ESP_IF_ETH + * ESP_IF_MAX + */ +esp_interface_t tcpip_adapter_get_esp_if(void *dev); + +/** + * @brief Get the station information list + * + * @param[in] wifi_sta_list_t *wifi_sta_list: station list info + * @param[out] tcpip_adapter_sta_list_t *tcpip_sta_list: station list info + * + * @return ESP_OK + * ESP_ERR_TCPIP_ADAPTER_NO_MEM + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS + */ +esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list); + +#define TCPIP_HOSTNAME_MAX_SIZE 32 +/** + * @brief Set the hostname to the interface + * + * @param[in] tcpip_if: the interface which we will set the hostname + * @param[in] hostname: the host name for set the interface, the max length of hostname is 32 bytes + * + * @return ESP_OK:success + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:parameter error + */ +esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname); + +/** + * @brief Get the hostname from the interface + * + * @param[in] tcpip_if: the interface which we will get the hostname + * @param[in] hostname: the host name from the interface + * + * @return ESP_OK:success + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:parameter error + */ +esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname); + +/** + * @brief Get the LwIP netif* that is assigned to the interface + * + * @param[in] tcpip_if: the interface which we will get the hostname + * @param[out] void ** netif: pointer to fill the resulting interface + * + * @return ESP_OK:success + * ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY:interface status error + * ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS:parameter error + */ +esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif); + +#ifdef __cplusplus +} +#endif + +#endif /* _TCPIP_ADAPTER_H_ */ + diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c new file mode 100644 index 00000000..634d3997 --- /dev/null +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -0,0 +1,1100 @@ +// Copyright 2018 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.h" + +#if CONFIG_TCPIP_LWIP + +#include "lwip/netif.h" +#include "lwip/tcpip.h" +#include "lwip/dhcp.h" +#include "lwip/dns.h" +#include "lwip/errno.h" +#include "lwip/prot/dhcp.h" +#include "netif/etharp.h" +#include "esp_wifi.h" +#include "esp_timer.h" +#include "esp_misc.h" +#include "dhcpserver/dhcpserver.h" +#include "dhcpserver/dhcpserver_options.h" +#include "net/sockio.h" +#include "esp_socket.h" +#include "esp_log.h" + +struct tcpip_adapter_pbuf { + struct pbuf_custom pbuf; + + void *base; + + struct netif *netif; +}; + +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]; +#if 0 +/*TODO need add ip6*/ +static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX]; +#endif +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_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_dhcpc_cb(struct netif *netif); +static void tcpip_adapter_ip_lost_timer(void *arg); +static int tcpip_adapter_bind_netcard(const char *name, struct netif *netif); +static bool tcpip_inited = false; + +static const char* TAG = "tcpip_adapter"; + +u32_t LwipTimOutLim = 0; // For light sleep. time out. limit is 3000ms + +/* Avoid warning. No header file has include these function */ +err_t ethernetif_init(struct netif* netif); +void system_station_got_ip_set(); + +static os_timer_t* get_ip_timer; +static int dhcp_fail_time; +static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX]; + +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; + evt.event_id = SYSTEM_EVENT_AP_STAIPASSIGNED; + esp_event_send(&evt); +} + +void tcpip_adapter_init(void) +{ + if (tcpip_inited == false) { + 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); + } +} + +static void tcpip_adapter_dhcpc_done() +{ + struct dhcp *clientdhcp = netif_dhcp_data(esp_netif[TCPIP_ADAPTER_IF_STA]) ; + + os_timer_disarm(get_ip_timer); + + if (clientdhcp->state == DHCP_STATE_BOUND) { + /*send event here*/ + tcpip_adapter_dhcpc_cb(esp_netif[TCPIP_ADAPTER_IF_STA]); + printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n", IP2STR(ip_2_ip4(&(esp_netif[0]->ip_addr))), + IP2STR(ip_2_ip4(&(esp_netif[0]->netmask))), IP2STR(ip_2_ip4(&(esp_netif[0]->gw)))); + } else if (dhcp_fail_time < (CONFIG_IP_LOST_TIMER_INTERVAL * 1000 / 100)) { + ESP_LOGD(TAG,"dhcpc time(ms): %d\n", dhcp_fail_time * 100); + dhcp_fail_time ++; + os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL); + os_timer_arm(get_ip_timer, 200, 1); + } else { + ESP_LOGD(TAG,"ERROR dhcp get ip error\n"); + free(get_ip_timer); + } +} + +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 esp_err_t tcpip_adapter_update_default_netif(void) +{ + if ((esp_netif[TCPIP_ADAPTER_IF_STA] != NULL) && netif_is_up(esp_netif[TCPIP_ADAPTER_IF_STA])) { + netif_set_default(esp_netif[TCPIP_ADAPTER_IF_STA]); + } else if ((esp_netif[TCPIP_ADAPTER_IF_AP] != NULL) && netif_is_up(esp_netif[TCPIP_ADAPTER_IF_AP])) { + netif_set_default(esp_netif[TCPIP_ADAPTER_IF_AP]); + } + + return ESP_OK; +} + +esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info) +{ + int s = -1; + 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] = (struct netif*)os_zalloc(sizeof(*esp_netif[tcpip_if])); + } + + if (esp_netif[tcpip_if] == NULL) { + ESP_LOGE(TAG, "TCPIP adapter has no menory\n"); + return ESP_ERR_NO_MEM; + } + memcpy(esp_netif[tcpip_if]->hwaddr, mac, NETIF_MAX_HWADDR_LEN); + if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + const char *netcard_name = "sta0"; + s = tcpip_adapter_bind_netcard(netcard_name, esp_netif[tcpip_if]); + if (s < 0) { + ESP_LOGE(TAG, "TCPIP adapter bind net card %s error\n", netcard_name); + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + } else if (tcpip_if == TCPIP_ADAPTER_IF_AP) { + const char *netcard_name = "ap0"; + + s = tcpip_adapter_bind_netcard(netcard_name, esp_netif[tcpip_if]); + if (s < 0) { + ESP_LOGE(TAG, "TCPIP adapter bind net card %s error\n", netcard_name); + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + } + netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, (void *)s, ethernetif_init, tcpip_input); + } + + 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_stop(tcpip_adapter_if_t tcpip_if) +{ + 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); + } + + esp_close((int)esp_netif[tcpip_if]->state); + netif_set_down(esp_netif[tcpip_if]); + netif_remove(esp_netif[tcpip_if]); + tcpip_adapter_update_default_netif(); + //os_free(esp_netif[tcpip_if]); + //esp_netif[netif_index] = NULL; + return ESP_OK; +} + + +/* + * @brief LWIP custom pbuf callback function, it is to free custom pbuf + * + * @param p LWIP pbuf pointer + * + * @return none + */ +static void tcpip_adapter_free_pbuf(struct pbuf *p) +{ + struct tcpip_adapter_pbuf *pa = (struct tcpip_adapter_pbuf *)p; + int s = (int)pa->netif->state; + + esp_free_pbuf(s, pa->base); + os_free(pa); +} + +/* + * @brief TCPIP adapter AI/O recieve callback function, it is to recieve input data + * and pass it to LWIP core + * + * @param aio AI/O control block pointer + * + * @return 0 if success or others if failed + */ +static int tcpip_adapter_recv_cb(struct esp_aio *aio) +{ + struct pbuf *pbuf = NULL; + struct tcpip_adapter_pbuf *p; + struct netif *netif = (struct netif *)aio->arg; + + extern void ethernetif_input(struct netif *netif, struct pbuf *p); + + p = os_malloc(sizeof(struct tcpip_adapter_pbuf)); + if (!p) + return -ENOMEM; + p->pbuf.custom_free_function = tcpip_adapter_free_pbuf; + p->base = (void *)aio->pbuf; + p->netif = netif; + + // PBUF_RAW means payload = (char *)aio->pbuf + offset(=0) + pbuf = pbuf_alloced_custom(PBUF_RAW, aio->len, PBUF_REF, &p->pbuf, (void *)aio->pbuf, aio->len); + if (!pbuf) + return -ENOMEM; + + ethernetif_input(netif, pbuf); + + return 0; +} + +/* + * @brief create a "esp_socket" and bind it to target net card + * + * @param name net card name pointer + * @param netif LWIP net interface pointer + * + * @return 0 if success or others if failed + */ +static int tcpip_adapter_bind_netcard(const char *name, struct netif *netif) +{ + int s, ret; + s = esp_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + if (s < 0) { + ESP_LOGE(TAG,"create socket of (AF_PACKET, SOCK_RAW, ETH_P_ALL) error\n"); + return -1; + } + + ret = esp_ioctl(s, SIOCGIFINDEX, name); + if (ret) { + ESP_LOGE(TAG,"bind socket %d to netcard %s error\n", s, name); + esp_close(s); + return -1; + } + + ret = esp_aio_event(s, ESP_SOCKET_RECV_EVENT, tcpip_adapter_recv_cb, netif); + if (ret) { + ESP_LOGE(TAG,"socket %d register receive callback function %p error\n", s, tcpip_adapter_recv_cb); + esp_close(s); + return -1; + } + return s; +} + +esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if) +{ + if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + 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_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_down(tcpip_adapter_if_t tcpip_if) +{ + if (tcpip_if == TCPIP_ADAPTER_IF_STA) { + 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); + } + + 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; +} + +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; + } + + memcpy(&esp_ip_old[tcpip_if], ip_info, sizeof(tcpip_adapter_ip_info_t)); + + 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, tcpip_adapter_ip_info_t *ip_info) +{ + struct netif *p_netif; + tcpip_adapter_dhcp_status_t status; + + 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_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) { + 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; + 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; +} + +#if 0 +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; + //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); +} +#endif + +esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if) +{ + struct netif *p_netif; + + 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); + /*TODO need add ipv6 address cb*/ + //nd6_set_cb(p_netif, tcpip_adapter_nd6_cb); + + return ESP_OK; + } else { + return ESP_FAIL; + } +} + +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_dhcps_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_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) +{ + 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; +} + +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) +{ + const ip_addr_t *ns; + + 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) { + ns = dns_getserver(type); + dns->ip = *ns; + } else { + dns->ip.u_addr.ip4 = dhcps_dns_getserver(); + } + + return ESP_OK; +} + +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) +{ + /* 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_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; +} + +esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if) +{ + /* 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; +} + +esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len) +{ + // TODO: when dhcp request timeout,change the retry count + 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] ) { + tcpip_if = TCPIP_ADAPTER_IF_STA; + } 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 ( !ip_addr_isany_val(netif->ip_addr) ) { + + //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; + + 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 + 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", CONFIG_IP_LOST_TIMER_INTERVAL); + } + } else { + if (!ip4_addr_isany_val(ip_info->ip)) { + 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 && ip_addr_isany_val(netif->ip_addr))){ + 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]; + + return ESP_OK; +} + +esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if) +{ + if ((tcpip_if != TCPIP_ADAPTER_IF_STA) || tcpip_if >= TCPIP_ADAPTER_IF_MAX) { + ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if); + return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; + } + + get_ip_timer = (os_timer_t*)malloc(sizeof(*get_ip_timer)); + + if (get_ip_timer == NULL) { + ESP_LOGE(TAG, "ERROR NO MEMORY\n"); + } + + 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); + os_timer_disarm(get_ip_timer); + os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL); + os_timer_arm(get_ip_timer, 100, 1); + + 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; +} + +esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if) +{ + if (tcpip_if != TCPIP_ADAPTER_IF_STA || 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; + return ESP_OK; +} + +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; + } + + return ESP_IF_MAX; +} + +esp_err_t tcpip_adapter_get_sta_list(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 + 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 +} + +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 +} + +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; +} + +#endif /* CONFIG_TCPIP_LWIP */ diff --git a/components/tcpip_adapter/tcpip_adapter_wifi.c b/components/tcpip_adapter/tcpip_adapter_wifi.c deleted file mode 100644 index fdaa0c36..00000000 --- a/components/tcpip_adapter/tcpip_adapter_wifi.c +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright 2018 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 "lwip/netif.h" -#include "lwip/tcpip.h" -#include "lwip/dhcp.h" -#include "lwip/errno.h" -#include "lwip/prot/dhcp.h" -#include "netif/etharp.h" -#include "esp_wifi.h" -#include "esp_timer.h" -#include "esp_misc.h" -#include "tcpip_adapter.h" -#include "dhcpserver/dhcpserver.h" -#include "net/sockio.h" -#include "esp_socket.h" - -struct tcpip_adapter_pbuf { - struct pbuf_custom pbuf; - - void *base; - - struct netif *netif; -}; - -u32_t LwipTimOutLim = 0; // For light sleep. time out. limit is 3000ms - -/* Avoid warning. No header file has include these function */ -err_t ethernetif_init(struct netif* netif); -void system_station_got_ip_set(); - -static os_timer_t* get_ip_timer; -static uint8_t dhcp_fail_time; -static bool dhcps_flag = true; -static bool dhcpc_flag = true; -static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX]; - -void tcpip_adapter_init(void) -{ - //TODO:add tcpip init function. -} - -void esp_wifi_station_dhcpc_event(uint8_t netif_index) -{ - if (TCPIP_ADAPTER_IF_VALID(netif_index)) { - TCPIP_ATAPTER_LOG("wifi station dhcpc start\n"); - dhcp_stop(esp_netif[netif_index]); - dhcp_cleanup(esp_netif[netif_index]); - dhcp_inform(esp_netif[netif_index]); - } else { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - } -} - -static void tcpip_adapter_dhcpc_done() -{ - struct dhcp *clientdhcp = netif_dhcp_data(esp_netif[TCPIP_ADAPTER_IF_STA]) ; - - os_timer_disarm(get_ip_timer); - - if (clientdhcp->state == DHCP_STATE_BOUND) { - /*send event here*/ - system_station_got_ip_set(); - printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR "\n", IP2STR(ip_2_ip4(&(esp_netif[0]->ip_addr))), - IP2STR(ip_2_ip4(&(esp_netif[0]->netmask))), IP2STR(ip_2_ip4(&(esp_netif[0]->gw)))); - } else if (dhcp_fail_time < 100) { - TCPIP_ATAPTER_LOG("dhcpc time(ms): %d\n", dhcp_fail_time * 200); - dhcp_fail_time ++; - os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL); - os_timer_arm(get_ip_timer, 200, 1); - } else { - TCPIP_ATAPTER_LOG("ERROR dhcp get ip error\n"); - free(get_ip_timer); - } -} - -static void tcpip_adapter_station_dhcp_start() -{ - err_t ret; - get_ip_timer = (os_timer_t*)malloc(sizeof(*get_ip_timer)); - - if (get_ip_timer == NULL) { - TCPIP_ATAPTER_LOG("ERROR NO MEMORY\n"); - } - - TCPIP_ATAPTER_LOG("dhcpc start\n"); - ret = dhcp_start(esp_netif[TCPIP_ADAPTER_IF_STA]); - dhcp_fail_time = 0; - - if (ret == 0) { - os_timer_disarm(get_ip_timer); - os_timer_setfn(get_ip_timer, tcpip_adapter_dhcpc_done, NULL); - os_timer_arm(get_ip_timer, 100, 1); - } -} - -/* - * @brief LWIP custom pbuf callback function, it is to free custom pbuf - * - * @param p LWIP pbuf pointer - * - * @return none - */ -static void tcpip_adapter_free_pbuf(struct pbuf *p) -{ - struct tcpip_adapter_pbuf *pa = (struct tcpip_adapter_pbuf *)p; - int s = (int)pa->netif->state; - - esp_free_pbuf(s, pa->base); - os_free(pa); -} - -/* - * @brief TCPIP adapter AI/O recieve callback function, it is to recieve input data - * and pass it to LWIP core - * - * @param aio AI/O control block pointer - * - * @return 0 if success or others if failed - */ -static int tcpip_adapter_recv_cb(struct esp_aio *aio) -{ - struct pbuf *pbuf = NULL; - struct tcpip_adapter_pbuf *p; - struct netif *netif = (struct netif *)aio->arg; - - extern void ethernetif_input(struct netif *netif, struct pbuf *p); - - p = os_malloc(sizeof(struct tcpip_adapter_pbuf)); - if (!p) - return -ENOMEM; - p->pbuf.custom_free_function = tcpip_adapter_free_pbuf; - p->base = (void *)aio->pbuf; - p->netif = netif; - - // PBUF_RAW means payload = (char *)aio->pbuf + offset(=0) - pbuf = pbuf_alloced_custom(PBUF_RAW, aio->len, PBUF_REF, &p->pbuf, (void *)aio->pbuf, aio->len); - if (!pbuf) - return -ENOMEM; - - ethernetif_input(netif, pbuf); - - return 0; -} - -/* - * @brief create a "esp_socket" and bind it to target net card - * - * @param name net card name pointer - * @param netif LWIP net interface pointer - * - * @return 0 if success or others if failed - */ -static int tcpip_adapter_bind_netcard(const char *name, struct netif *netif) -{ - int s, ret; - - s = esp_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); - if (s < 0) { - TCPIP_ATAPTER_LOG("create socket of (AF_PACKET, SOCK_RAW, ETH_P_ALL) error\n"); - return -1; - } - - ret = esp_ioctl(s, SIOCGIFINDEX, name); - if (ret) { - TCPIP_ATAPTER_LOG("bind socket %d to netcard %s error\n", s, name); - esp_close(s); - return -1; - } - - ret = esp_aio_event(s, ESP_SOCKET_RECV_EVENT, tcpip_adapter_recv_cb, netif); - if (ret) { - TCPIP_ATAPTER_LOG("socket %d register receive callback function %p error\n", s, tcpip_adapter_recv_cb); - esp_close(s); - return -1; - } - - return s; -} - -void tcpip_adapter_start(uint8_t netif_index, bool authed) -{ - if (!TCPIP_ADAPTER_IF_VALID(netif_index)) { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return; - } - - TCPIP_ATAPTER_LOG("start netif[%d]\n", netif_index); - - if (netif_index == TCPIP_ADAPTER_IF_STA) { - if (authed == 0) { - if (esp_netif[netif_index] == NULL) { - int s; - const char *netcard_name = "sta0"; - - esp_netif[netif_index] = (struct netif*)os_zalloc(sizeof(*esp_netif[netif_index])); - TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index); - TCPIP_ATAPTER_LOG("Add netif:%d\n", netif_index); - - s = tcpip_adapter_bind_netcard(netcard_name, esp_netif[netif_index]); - if (s < 0) { - TCPIP_ATAPTER_LOG("TCPIP adapter bind net card %s error\n", netcard_name); - return ; - } - - netif_add(esp_netif[netif_index], NULL, NULL, NULL, (void *)s, ethernetif_init, tcpip_input); - } - } else { - if (dhcpc_flag) { - printf("dhcp client start...\n"); - tcpip_adapter_station_dhcp_start(); - } else { - if (esp_ip[TCPIP_ADAPTER_IF_STA].ip.addr != 0) { - netif_set_addr(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_STA].ip, - &esp_ip[TCPIP_ADAPTER_IF_STA].netmask, &esp_ip[TCPIP_ADAPTER_IF_STA].gw); - netif_set_up(esp_netif[netif_index]); - system_station_got_ip_set(); - printf("ip: 0.0.0.0,mask: 0.0.0.0,gw: 0.0.0.0\n"); - } else { - printf("check your static ip\n"); - } - } - } - } else if (netif_index == TCPIP_ADAPTER_IF_AP) { - if (dhcps_flag) { - 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); - } - - if (esp_netif[netif_index] == NULL) { - int s; - const char *netcard_name = "ap0"; - - TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index); - esp_netif[netif_index] = (struct netif*)os_zalloc(sizeof(*esp_netif[netif_index])); - - s = tcpip_adapter_bind_netcard(netcard_name, esp_netif[netif_index]); - if (s < 0) { - TCPIP_ATAPTER_LOG("TCPIP adapter bind net card %s error\n", netcard_name); - return ; - } - - netif_add(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_AP].ip, - &esp_ip[TCPIP_ADAPTER_IF_AP].netmask, &esp_ip[TCPIP_ADAPTER_IF_AP].gw, (void *)s, ethernetif_init, tcpip_input); - } - - if (dhcps_flag) { - dhcps_start(&esp_ip[TCPIP_ADAPTER_IF_AP]); - printf("dhcp server start:("); - printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR, IP2STR((ip_2_ip4(&esp_netif[TCPIP_ADAPTER_IF_AP]->ip_addr))), - IP2STR((ip_2_ip4(&esp_netif[TCPIP_ADAPTER_IF_AP]->netmask))), IP2STR((ip_2_ip4(&esp_netif[TCPIP_ADAPTER_IF_AP]->gw)))); - printf(")\n"); - } - - netif_set_up(esp_netif[netif_index]); - netif_set_default(esp_netif[netif_index]); - } - - wifi_mode_t opmode; - esp_wifi_get_mode(&opmode); - - if (opmode == WIFI_MODE_STA) { - netif_set_default(esp_netif[netif_index]); - } -} - -void tcpip_adapter_stop(uint8_t netif_index) -{ - if (!TCPIP_ADAPTER_IF_VALID(netif_index)) { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return; - } - if (esp_netif[netif_index] == NULL) - return; - - if (netif_index == TCPIP_ADAPTER_IF_STA) { - TCPIP_ATAPTER_LOG("dhcp stop netif index:%d\n", netif_index); - dhcp_stop(esp_netif[netif_index]); - } - - if (netif_index == TCPIP_ADAPTER_IF_AP) { - if(dhcps_flag){ - TCPIP_ATAPTER_LOG("dhcp stop netif index:%d\n", netif_index); - dhcps_stop(); - } - } - - TCPIP_ATAPTER_LOG("stop netif[%d]\n", netif_index); - esp_close((int)esp_netif[netif_index]->state); - netif_remove(esp_netif[netif_index]); - os_free(esp_netif[netif_index]); - esp_netif[netif_index] = NULL; -} - -bool wifi_set_ip_info(wifi_interface_t netif_index, tcpip_adapter_ip_info_t* if_ip) -{ - if (!TCPIP_ADAPTER_IF_VALID((uint8_t)netif_index)) { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return false; - } - - TCPIP_ATAPTER_LOG("Set netif[%d] ip info\n", netif_index); - netif_set_addr(esp_netif[netif_index], &if_ip->ip, &if_ip->netmask, &if_ip->gw); - return true; -} - -bool wifi_get_ip_info(wifi_interface_t netif_index, tcpip_adapter_ip_info_t* if_ip) -{ - if (!TCPIP_ADAPTER_IF_VALID((uint8_t)netif_index)) { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return false; - } - - if(if_ip == NULL){ - TCPIP_ATAPTER_LOG("ERROR ip info is NULL\n"); - return false; - } - - TCPIP_ATAPTER_LOG("Get netif[%d] ip info\n", netif_index); - if_ip->ip.addr = ip_addr_get_ip4_u32(&esp_netif[netif_index]->ip_addr); - if_ip->netmask.addr = ip_addr_get_ip4_u32(&esp_netif[netif_index]->netmask); - if_ip->gw.addr = ip_addr_get_ip4_u32(&esp_netif[netif_index]->gw); - return true; -} - -bool wifi_create_linklocal_ip(uint8_t netif_index, bool ipv6) -{ - if (!TCPIP_ADAPTER_IF_VALID(netif_index)) { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return false; - } - - netif_create_ip6_linklocal_address(esp_netif[netif_index], ipv6); - return true; -} - -#if LWIP_IPV6 -bool wifi_get_linklocal_ip(uint8_t netif_index, ip6_addr_t* linklocal) -{ - if (TCPIP_ADAPTER_IF_VALID(netif_index)) { - memcpy(linklocal, ip_2_ip6(&esp_netif[netif_index]->ip6_addr[0]), sizeof(*linklocal)); - } else { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return false; - } - - return true; -} - -bool wifi_get_ipinfo_v6(uint8_t netif_index, uint8_t ip_index, ip6_addr_t* ipv6) -{ - - if (TCPIP_ADAPTER_IF_VALID(netif_index)) { - memcpy(ipv6, &esp_netif[netif_index]->ip6_addr[ip_index], sizeof(ip6_addr_t)); - } else { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return false; - } - - return true; -} -#endif - -bool wifi_softap_dhcps_start(void) -{ - wifi_mode_t opmode = WIFI_MODE_NULL; - TCPIP_ATAPTER_LOG("start softap dhcps\n"); - taskENTER_CRITICAL(); - esp_wifi_get_mode(&opmode); - - if ((opmode == WIFI_MODE_STA) || (opmode == WIFI_MODE_NULL)) { - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("ERROR you shoud enable wifi softap before start dhcp server\n"); - return false; - } - - if (dhcps_flag == false) { - tcpip_adapter_ip_info_t ipinfo; - wifi_get_ip_info(ESP_IF_WIFI_AP, &ipinfo); - TCPIP_ATAPTER_LOG("start softap dhcpserver\n"); - dhcps_start(&ipinfo); - } - - dhcps_flag = true; - taskEXIT_CRITICAL(); - return true; -} - -enum dhcp_status wifi_softap_dhcps_status() -{ - return dhcps_flag; -} - -void tcpip_adapter_sta_leave() -{ - TCPIP_ATAPTER_LOG("station leave\n"); - - if (esp_netif[TCPIP_ADAPTER_IF_STA] == NULL) { - return; - } - - netif_set_down(esp_netif[TCPIP_ADAPTER_IF_STA]); - - if (dhcpc_flag) { - dhcp_release(esp_netif[TCPIP_ADAPTER_IF_STA]); - dhcp_stop(esp_netif[TCPIP_ADAPTER_IF_STA]); - dhcp_cleanup(esp_netif[TCPIP_ADAPTER_IF_STA]); - } - - ip_addr_set_zero(&esp_netif[TCPIP_ADAPTER_IF_STA]->ip_addr); - ip_addr_set_zero(&esp_netif[TCPIP_ADAPTER_IF_STA]->netmask); - ip_addr_set_zero(&esp_netif[TCPIP_ADAPTER_IF_STA]->gw); -} - -bool wifi_softap_dhcps_stop() -{ - wifi_mode_t opmode = WIFI_MODE_NULL; - taskENTER_CRITICAL(); - esp_wifi_get_mode(&opmode); - - if ((opmode == WIFI_MODE_STA) || (opmode == WIFI_MODE_NULL)) { - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("ERROR you shoud enable wifi softap before start dhcp server\n"); - return false; - } - - if (dhcps_flag == true) { - TCPIP_ATAPTER_LOG("dhcps stop\n"); - dhcps_stop(); - } - - dhcps_flag = false; - taskEXIT_CRITICAL(); - return true; - -} - -bool wifi_station_dhcpc_start(void) -{ - wifi_mode_t opmode = WIFI_MODE_NULL; - err_t ret; - taskENTER_CRITICAL(); - esp_wifi_get_mode(&opmode); - - if ((opmode == WIFI_MODE_AP) || (opmode == WIFI_MODE_NULL)) { - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("ERROR you shoud enable wifi station mode before start dhcp client\n"); - return false; - } - - if (dhcpc_flag == false) { - if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_STA])) { - ip_addr_set_zero(&esp_netif[TCPIP_ADAPTER_IF_STA]->ip_addr); - ip_addr_set_zero(&esp_netif[TCPIP_ADAPTER_IF_STA]->netmask); - ip_addr_set_zero(&esp_netif[TCPIP_ADAPTER_IF_STA]->gw); - } else { - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("ERROR please init station netif\n"); - return false; - } - - ret = dhcp_start(esp_netif[TCPIP_ADAPTER_IF_STA]); - - if (ret != ERR_OK) { - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("ERROR start dhcp client failed.ret=%d\n", ret); - return false; - } - } - - dhcps_flag = true; - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("dhcp client start\n"); - return true; -} - -bool wifi_station_dhcpc_stop() -{ - wifi_mode_t opmode = WIFI_MODE_NULL; - taskENTER_CRITICAL(); - esp_wifi_get_mode(&opmode); - - if ((opmode == WIFI_MODE_AP) || (opmode == WIFI_MODE_NULL)) { - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("ERROR you shoud enable wifi station mode before stop dhcp client\n"); - return false; - } - - if (dhcpc_flag == true) { - dhcp_stop(esp_netif[TCPIP_ADAPTER_IF_STA]); - } else { - TCPIP_ATAPTER_LOG("WARING dhcp client have not start yet\n"); - } - - dhcpc_flag = false; - taskEXIT_CRITICAL(); - TCPIP_ATAPTER_LOG("stop dhcp client\n"); - return true; -} - -enum dhcp_status wifi_station_dhcpc_status() -{ - return dhcpc_flag; -} - -bool wifi_station_dhcpc_set_maxtry(uint8_t num) -{ - return true; -} - -bool tcpip_adapter_set_macaddr(uint8_t netif_index, uint8_t* macaddr) -{ - if (esp_netif[netif_index] == NULL || macaddr == NULL) { - TCPIP_ATAPTER_LOG("set macaddr fail\n"); - return false; - } - - memcpy(esp_netif[netif_index]->hwaddr, macaddr, 6); - TCPIP_ATAPTER_LOG("set macaddr ok\n"); - return true; -} - -bool tcpip_adapter_get_macaddr(uint8_t netif_index, uint8_t* macaddr) -{ - if (esp_netif[netif_index] == NULL || macaddr == NULL) { - return false; - } - - if (esp_netif[netif_index]->hwaddr[0] == 0 && esp_netif[netif_index]->hwaddr[1] == 0 - && esp_netif[netif_index]->hwaddr[2] == 0 && esp_netif[netif_index]->hwaddr[3] == 0 - && esp_netif[netif_index]->hwaddr[4] == 0 && esp_netif[netif_index]->hwaddr[5] == 0) - return false; - - memcpy(macaddr, esp_netif[netif_index]->hwaddr, 6); - return true; -} - - -bool wifi_station_set_hostname(char* name) -{ - if (name == NULL) { - return false; - } - - uint32_t len = strlen(name); - - if (len > 32) { - return false; - } - - wifi_mode_t opmode; - esp_wifi_get_mode(&opmode); - - if (opmode == WIFI_MODE_STA || opmode == WIFI_MODE_AP) { - default_hostname = 0; - - if (hostname != NULL) { - free(hostname); - hostname = NULL; - } - - hostname = (char*)malloc(len + 1); - - if (hostname != NULL) { - strcpy(hostname, name); - esp_netif[opmode - 1]->hostname = hostname; - } else { - return false; - } - } else { - return false; - } - - return true; -} - -struct netif* eagle_lwip_getif(uint8_t netif_index) -{ - if (TCPIP_ADAPTER_IF_VALID(netif_index)) { - return esp_netif[netif_index]; - } else { - TCPIP_ATAPTER_LOG("ERROR bad netif index:%d\n", netif_index); - return NULL; - } -}