diff --git a/components/esp8266/include/esp_event.h b/components/esp8266/include/esp_event.h index cc130bd8..e31da16a 100644 --- a/components/esp8266/include/esp_event.h +++ b/components/esp8266/include/esp_event.h @@ -45,6 +45,7 @@ typedef enum { SYSTEM_EVENT_AP_STOP, /**< ESP8266 soft-AP stop */ SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP8266 soft-AP */ SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP8266 soft-AP */ + SYSTEM_EVENT_AP_STAIPASSIGNED, /**< ESP8266 soft-AP assign an IP to a connected station */ SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ SYSTEM_EVENT_GOT_IP6, /**< ESP8266 station or ap or ethernet interface v6IP addr is preferred */ SYSTEM_EVENT_ETH_START, /**< ESP8266 ethernet start */ diff --git a/components/esp8266/include/esp_misc.h b/components/esp8266/include/esp_misc.h index d7625305..990f5617 100644 --- a/components/esp8266/include/esp_misc.h +++ b/components/esp8266/include/esp_misc.h @@ -82,23 +82,6 @@ void os_install_putc1(void (*p)(char c)); */ void os_putc(char c); -enum dhcp_status { - DHCP_STOPPED, /**< disable DHCP */ - DHCP_STARTED /**< enable DHCP */ -}; - -struct dhcps_lease { - bool enable; /**< enable DHCP lease or not */ - struct ip4_addr start_ip; /**< start IP of IP range */ - struct ip4_addr end_ip; /**< end IP of IP range */ -}; - -enum dhcps_offer_option { - OFFER_START = 0x00, /**< DHCP offer option start */ - OFFER_ROUTER = 0x01, /**< DHCP offer router, only support this option now */ - OFFER_END /**< DHCP offer option start */ -}; - /** * @} */ 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/lib/VERSION b/components/esp8266/lib/VERSION index 80e383ab..72dbffdb 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,10 +1,10 @@ gwen: crypto: 137694e espnow: 137694e - core: 137694e - net80211: 137694e + core: 68ec0eb + net80211: 68ec0eb pp: 137694e pwm: 0181338 smartconfig:9ec59b5 - wpa: 137694e + wpa: 68ec0eb wps: 137694e \ No newline at end of file diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index 0df8c48d..080f50d4 100644 Binary files a/components/esp8266/lib/libcore.a and b/components/esp8266/lib/libcore.a differ diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index 3e5dbbb6..5117c589 100644 Binary files a/components/esp8266/lib/libnet80211.a and b/components/esp8266/lib/libnet80211.a differ diff --git a/components/esp8266/lib/libwpa.a b/components/esp8266/lib/libwpa.a index d74f7fe9..37e96efa 100644 Binary files a/components/esp8266/lib/libwpa.a and b/components/esp8266/lib/libwpa.a differ 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/esp8266/source/event_default_handlers.c b/components/esp8266/source/event_default_handlers.c index 5fca64bd..aa22abaf 100644 --- a/components/esp8266/source/event_default_handlers.c +++ b/components/esp8266/source/event_default_handlers.c @@ -18,6 +18,7 @@ #include "esp_err.h" #include "esp_wifi.h" +#include "esp_misc.h" #include "esp_event.h" #include "esp_event_loop.h" #include "esp_system.h" @@ -32,6 +33,15 @@ static const char* TAG = "event"; +#define WIFI_API_CALL_CHECK(info, api_call, ret) \ +do{\ + esp_err_t __err = (api_call);\ + if ((ret) != __err) {\ + ESP_LOGE(TAG, "%s %d %s ret=0x%X", __FUNCTION__, __LINE__, (info), __err);\ + return __err;\ + }\ +} while(0) + typedef esp_err_t (*system_event_handler_t)(system_event_t *e); static esp_err_t system_event_ap_start_handle_default(system_event_t *event); @@ -51,58 +61,241 @@ static system_event_handler_t default_event_handlers[SYSTEM_EVENT_MAX] = { 0 }; static esp_err_t system_event_sta_got_ip_default(system_event_t *event) { + ESP_LOGI(TAG, "sta ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, + IP2STR(&event->event_info.got_ip.ip_info.ip), + IP2STR(&event->event_info.got_ip.ip_info.netmask), + IP2STR(&event->event_info.got_ip.ip_info.gw)); + return ESP_OK; } static esp_err_t system_event_sta_lost_ip_default(system_event_t *event) { + ESP_LOGI(TAG, "station ip lost"); return ESP_OK; } esp_err_t system_event_ap_start_handle_default(system_event_t *event) { + tcpip_adapter_ip_info_t ap_ip; + uint8_t ap_mac[6]; + + WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_AP, ap_mac), ESP_OK); + + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip); + tcpip_adapter_start(TCPIP_ADAPTER_IF_AP, ap_mac, &ap_ip); + return ESP_OK; } esp_err_t system_event_ap_stop_handle_default(system_event_t *event) { + tcpip_adapter_stop(TCPIP_ADAPTER_IF_AP); + return ESP_OK; } esp_err_t system_event_sta_start_handle_default(system_event_t *event) { + tcpip_adapter_ip_info_t sta_ip; + uint8_t sta_mac[6]; + + WIFI_API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac), ESP_OK); + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + tcpip_adapter_start(TCPIP_ADAPTER_IF_STA, sta_mac, &sta_ip); + return ESP_OK; } esp_err_t system_event_sta_stop_handle_default(system_event_t *event) { + tcpip_adapter_stop(TCPIP_ADAPTER_IF_STA); return ESP_OK; } esp_err_t system_event_sta_connected_handle_default(system_event_t *event) { + tcpip_adapter_dhcp_status_t status; + + tcpip_adapter_up(TCPIP_ADAPTER_IF_STA); + tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &status); + + if (status == TCPIP_ADAPTER_DHCP_INIT) { + tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA); + } else if (status == TCPIP_ADAPTER_DHCP_STOPPED) { + tcpip_adapter_ip_info_t sta_ip; + tcpip_adapter_ip_info_t sta_old_ip; + + tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + tcpip_adapter_get_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_old_ip); + + if (!(ip4_addr_isany_val(sta_ip.ip) || ip4_addr_isany_val(sta_ip.netmask) || ip4_addr_isany_val(sta_ip.gw))) { + system_event_t evt; + + evt.event_id = SYSTEM_EVENT_STA_GOT_IP; + evt.event_info.got_ip.ip_changed = false; + + if (memcmp(&sta_ip, &sta_old_ip, sizeof(sta_ip))) { + evt.event_info.got_ip.ip_changed = true; + } + + memcpy(&evt.event_info.got_ip.ip_info, &sta_ip, sizeof(tcpip_adapter_ip_info_t)); + tcpip_adapter_set_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); + + esp_event_send(&evt); + ESP_LOGD(TAG, "static ip: ip changed=%d", evt.event_info.got_ip.ip_changed); + } else { + ESP_LOGE(TAG, "invalid static ip"); + } + } + return ESP_OK; } esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event) { + tcpip_adapter_down(TCPIP_ADAPTER_IF_STA); return ESP_OK; } +static esp_err_t esp_system_event_debug(system_event_t *event) +{ + if (event == NULL) { + ESP_LOGE(TAG, "event is null!"); + printf("event is null!"); + return ESP_FAIL; + } + switch (event->event_id) { + case SYSTEM_EVENT_WIFI_READY: { + ESP_LOGD(TAG, "SYSTEM_EVENT_WIFI_READY"); + break; + } + case SYSTEM_EVENT_SCAN_DONE: { + system_event_sta_scan_done_t *scan_done = &event->event_info.scan_done; + ESP_LOGD(TAG, "SYSTEM_EVENT_SCAN_DONE, status:%d, number:%d", scan_done->status, scan_done->number); + break; + } + case SYSTEM_EVENT_STA_START: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_START"); + break; + } + case SYSTEM_EVENT_STA_STOP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_STOP"); + break; + } + case SYSTEM_EVENT_STA_CONNECTED: { + system_event_sta_connected_t *connected = &event->event_info.connected; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_CONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", channel:%d, authmode:%d", \ + connected->ssid, connected->ssid_len, MAC2STR(connected->bssid), connected->channel, connected->authmode); + break; + } + case SYSTEM_EVENT_STA_DISCONNECTED: { + system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:" MACSTR ", reason:%d", \ + disconnected->ssid, disconnected->ssid_len, MAC2STR(disconnected->bssid), disconnected->reason); + break; + } + case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: { + system_event_sta_authmode_change_t *auth_change = &event->event_info.auth_change; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_AUTHMODE_CHNAGE, old_mode:%d, new_mode:%d", auth_change->old_mode, auth_change->new_mode); + break; + } + case SYSTEM_EVENT_STA_GOT_IP: { + system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip; + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOT_IP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR, + IP2STR(&got_ip->ip_info.ip), + IP2STR(&got_ip->ip_info.netmask), + IP2STR(&got_ip->ip_info.gw)); + break; + } + case SYSTEM_EVENT_STA_LOST_IP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_LOST_IP"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_SUCCESS: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_SUCCESS"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_FAILED: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_FAILED"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_TIMEOUT"); + break; + } + case SYSTEM_EVENT_STA_WPS_ER_PIN: { + ESP_LOGD(TAG, "SYSTEM_EVENT_STA_WPS_ER_PIN"); + break; + } + case SYSTEM_EVENT_AP_START: { + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_START"); + break; + } + case SYSTEM_EVENT_AP_STOP: { + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STOP"); + break; + } + case SYSTEM_EVENT_AP_STACONNECTED: { + system_event_ap_staconnected_t *staconnected = &event->event_info.sta_connected; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STACONNECTED, mac:" MACSTR ", aid:%d", \ + MAC2STR(staconnected->mac), staconnected->aid); + break; + } + case SYSTEM_EVENT_AP_STADISCONNECTED: { + system_event_ap_stadisconnected_t *stadisconnected = &event->event_info.sta_disconnected; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STADISCONNECTED, mac:" MACSTR ", aid:%d", \ + MAC2STR(stadisconnected->mac), stadisconnected->aid); + break; + } + case SYSTEM_EVENT_AP_PROBEREQRECVED: { + system_event_ap_probe_req_rx_t *ap_probereqrecved = &event->event_info.ap_probereqrecved; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_PROBEREQRECVED, rssi:%d, mac:" MACSTR, \ + ap_probereqrecved->rssi, \ + MAC2STR(ap_probereqrecved->mac)); + break; + } + case SYSTEM_EVENT_GOT_IP6: { + ip6_addr_t *addr = &event->event_info.got_ip6.ip6_info.ip; + ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STA_GOT_IP6 address %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", + IP6_ADDR_BLOCK1(addr), + IP6_ADDR_BLOCK2(addr), + IP6_ADDR_BLOCK3(addr), + IP6_ADDR_BLOCK4(addr), + IP6_ADDR_BLOCK5(addr), + IP6_ADDR_BLOCK6(addr), + IP6_ADDR_BLOCK7(addr), + IP6_ADDR_BLOCK8(addr)); + break; + } + + default: { + ESP_LOGW(TAG, "unexpected system event %d!", event->event_id); + break; + } + } + + return ESP_OK; +} esp_err_t esp_event_process_default(system_event_t *event) { if (event == NULL) { + ESP_LOGE(TAG, "Error: event is null!"); return ESP_FAIL; } + esp_system_event_debug(event); if ((event->event_id < SYSTEM_EVENT_MAX)) { if (default_event_handlers[event->event_id] != NULL) { + ESP_LOGV(TAG, "enter default callback"); default_event_handlers[event->event_id](event); + ESP_LOGV(TAG, "exit default callback"); } } else { + ESP_LOGE(TAG, "mismatch or invalid event, id=%d", event->event_id); return ESP_FAIL; } return ESP_OK; @@ -118,4 +311,6 @@ void esp_event_set_default_wifi_handlers() default_event_handlers[SYSTEM_EVENT_STA_LOST_IP] = system_event_sta_lost_ip_default; default_event_handlers[SYSTEM_EVENT_AP_START] = system_event_ap_start_handle_default; default_event_handlers[SYSTEM_EVENT_AP_STOP] = system_event_ap_stop_handle_default; + + //esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop); } \ No newline at end of file diff --git a/components/esp8266/source/event_loop.c b/components/esp8266/source/event_loop.c index 3b8162d7..335e4685 100644 --- a/components/esp8266/source/event_loop.c +++ b/components/esp8266/source/event_loop.c @@ -27,10 +27,9 @@ static const char* TAG = "event"; static bool s_event_init_flag = false; +static void *s_event_queue = NULL; static system_event_cb_t s_event_handler_cb = NULL; static void *s_event_ctx = NULL; -static void *s_event_queue = NULL; - static esp_err_t esp_event_post_to_user(system_event_t *event) { @@ -40,33 +39,6 @@ static esp_err_t esp_event_post_to_user(system_event_t *event) return ESP_OK; } -system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx) -{ - system_event_cb_t old_cb = s_event_handler_cb; - s_event_handler_cb = cb; - s_event_ctx = ctx; - return old_cb; -} - -esp_err_t esp_event_send(system_event_t *event) -{ - if (s_event_queue == NULL) { - ESP_LOGE(TAG, "Event loop not initialized via esp_event_loop_init, but esp_event_send called"); - return ESP_ERR_INVALID_STATE; - } - - portBASE_TYPE ret = wifi_queue_send(s_event_queue, event, 0, 1); - if (ret != pdPASS) { - if (event) { - ESP_LOGE(TAG, "e=%d f", event->event_id); - } else { - ESP_LOGE(TAG, "e null"); - } - return ESP_FAIL; - } - return ESP_OK; -} - static void esp_event_loop_task(void *pvParameters) { while (1) { @@ -80,12 +52,37 @@ static void esp_event_loop_task(void *pvParameters) if (ret != ESP_OK) { ESP_LOGE(TAG, "post event to user fail!"); } - } else { - ESP_LOGE(TAG, "esp_event_loop_task end"); } } } +system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx) +{ + system_event_cb_t old_cb = s_event_handler_cb; + s_event_handler_cb = cb; + s_event_ctx = ctx; + return old_cb; +} + +esp_err_t esp_event_send(system_event_t *event) +{ + if (s_event_queue == NULL) { + ESP_LOGE(TAG, "Event loop not initialized via esp_event_loop_init, but esp_event_send called"); + return ESP_ERR_INVALID_STATE; + } + + int ret = wifi_queue_send(s_event_queue, event, 0, 1); + if (ret != true) { + if (event) { + ESP_LOGE(TAG, "e=%d f", event->event_id); + } else { + ESP_LOGE(TAG, "e null"); + } + return ESP_FAIL; + } + return ESP_OK; +} + QueueHandle_t esp_event_loop_get_queue(void) { return s_event_queue; diff --git a/components/lwip/apps/dhcpserver/dhcpserver.c b/components/lwip/apps/dhcpserver/dhcpserver.c index 690f315b..85e9ad20 100644 --- a/components/lwip/apps/dhcpserver/dhcpserver.c +++ b/components/lwip/apps/dhcpserver/dhcpserver.c @@ -27,38 +27,186 @@ #include "lwip/udp.h" #include "lwip/mem.h" #include "dhcpserver/dhcpserver.h" +#include "dhcpserver/dhcpserver_options.h" #include "FreeRTOS.h" -extern struct netif *esp_netif[2]; +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPS_SERVER_PORT 67 +#define DHCPS_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_INTERFACE_MTU 26 +#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +//#define USE_CLASS_B_NET 1 +#define DHCPS_DEBUG 0 +#define DHCPS_LOG printf + +#define MAX_STATION_NUM CONFIG_LWIP_DHCPS_MAX_STATION_NUM + +#define DHCPS_STATE_OFFER 1 +#define DHCPS_STATE_DECLINE 2 +#define DHCPS_STATE_ACK 3 +#define DHCPS_STATE_NAK 4 +#define DHCPS_STATE_IDLE 5 +#define DHCPS_STATE_RELEASE 6 + +typedef struct _list_node { + void *pnode; + struct _list_node *pnext; +} list_node; //////////////////////////////////////////////////////////////////////////////////// -//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; -//static u8_t old_xid[4] = {0}; -static const u32_t magic_cookie = 0x63538263; -static struct udp_pcb* pcb_dhcps = NULL; -static struct ip4_addr server_address; -static struct ip4_addr client_address;//added -static struct ip4_addr client_address_plus; -static struct dhcps_lease dhcps_lease; -//static bool dhcps_lease_flag = true; -static list_node* plist = NULL; -static u8_t offer = 0xFF; +static const u32_t magic_cookie = 0x63538263; + +static struct udp_pcb *pcb_dhcps = NULL; +static ip4_addr_t broadcast_dhcps; +static ip4_addr_t server_address; +static ip4_addr_t dns_server = {0}; +static ip4_addr_t client_address; //added +static ip4_addr_t client_address_plus; + +static list_node *plist = NULL; static bool renew = false; -#define DHCPS_LEASE_TIME_DEF CONFIG_LWIP_DHCPS_LEASE_UNIT -u32_t dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute + +static dhcps_lease_t dhcps_poll; +static dhcps_time_t dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute +static dhcps_offer_t dhcps_offer = 0xFF; +static dhcps_offer_t dhcps_dns = 0x00; +static dhcps_cb_t dhcps_cb; + +/****************************************************************************** + * FunctionName : dhcps_option_info + * Description : get the DHCP message option info + * Parameters : op_id -- DHCP message option id + * opt_len -- DHCP message option length + * Returns : DHCP message option addr +*******************************************************************************/ +void *dhcps_option_info(u8_t op_id, u32_t opt_len) +{ + void *option_arg = NULL; + + switch (op_id) { + case IP_ADDRESS_LEASE_TIME: + if (opt_len == sizeof(dhcps_time_t)) { + option_arg = &dhcps_lease_time; + } + + break; + + case REQUESTED_IP_ADDRESS: + if (opt_len == sizeof(dhcps_lease_t)) { + option_arg = &dhcps_poll; + } + + break; + + case ROUTER_SOLICITATION_ADDRESS: + if (opt_len == sizeof(dhcps_offer_t)) { + option_arg = &dhcps_offer; + } + + break; + + case DOMAIN_NAME_SERVER: + if (opt_len == sizeof(dhcps_offer_t)) { + option_arg = &dhcps_dns; + } + + break; + + default: + break; + } + + return option_arg; +} + +/****************************************************************************** + * FunctionName : dhcps_set_option_info + * Description : set the DHCP message option info + * Parameters : op_id -- DHCP message option id + * opt_info -- DHCP message option info + * opt_len -- DHCP message option length + * Returns : none +*******************************************************************************/ +void dhcps_set_option_info(u8_t op_id, void *opt_info, u32_t opt_len) +{ + if (opt_info == NULL) { + return; + } + switch (op_id) { + case IP_ADDRESS_LEASE_TIME: + if (opt_len == sizeof(dhcps_time_t)) { + dhcps_lease_time = *(dhcps_time_t *)opt_info; + } + + break; + + case REQUESTED_IP_ADDRESS: + if (opt_len == sizeof(dhcps_lease_t)) { + dhcps_poll = *(dhcps_lease_t *)opt_info; + } + + break; + + case ROUTER_SOLICITATION_ADDRESS: + if (opt_len == sizeof(dhcps_offer_t)) { + dhcps_offer = *(dhcps_offer_t *)opt_info; + } + + break; + + case DOMAIN_NAME_SERVER: + if (opt_len == sizeof(dhcps_offer_t)) { + dhcps_dns = *(dhcps_offer_t *)opt_info; + } + break; + + default: + break; + } + return; +} + /****************************************************************************** * FunctionName : node_insert_to_list * Description : insert the node to the list - * Parameters : arg -- Additional argument to pass to the callback function + * Parameters : phead -- the head node of the list + * pinsert -- the insert node of the list * Returns : none *******************************************************************************/ -void node_insert_to_list(list_node** phead, list_node* pinsert) +static void node_insert_to_list(list_node **phead, list_node *pinsert) { - list_node* plist = NULL; - struct dhcps_pool* pdhcps_pool = NULL; - struct dhcps_pool* pdhcps_node = NULL; + list_node *plist = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + struct dhcps_pool *pdhcps_node = NULL; if (*phead == NULL) { *phead = pinsert; @@ -95,12 +243,13 @@ void node_insert_to_list(list_node** phead, list_node* pinsert) /****************************************************************************** * FunctionName : node_delete_from_list * Description : remove the node from list - * Parameters : arg -- Additional argument to pass to the callback function + * Parameters : phead -- the head node of the list + * pdelete -- the remove node of the list * Returns : none *******************************************************************************/ -void node_remove_from_list(list_node** phead, list_node* pdelete) +void node_remove_from_list(list_node **phead, list_node *pdelete) { - list_node* plist = NULL; + list_node *plist = NULL; plist = *phead; @@ -122,38 +271,32 @@ void node_remove_from_list(list_node** phead, list_node* pdelete) } } } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg��Ϣ�ṹ���������� - * - * @param optptr -- DHCP msg��Ϣλ�� - * @param type -- Ҫ��ӵ�����option - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static u8_t* add_msg_type(u8_t* optptr, u8_t type) -{ +/****************************************************************************** + * FunctionName : add_msg_type + * Description : add TYPE option of DHCP message + * Parameters : optptr -- the addr of DHCP message option + * Returns : the addr of DHCP message option +*******************************************************************************/ +static u8_t *add_msg_type(u8_t *optptr, u8_t type) +{ *optptr++ = DHCP_OPTION_MSG_TYPE; *optptr++ = 1; *optptr++ = type; return optptr; } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg�ṹ������offerӦ������ - * - * @param optptr -- DHCP msg��Ϣλ�� - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static u8_t* add_offer_options(u8_t* optptr) -{ - struct ip4_addr ipadd; - ipadd.addr = *((u32_t*) &server_address); +/****************************************************************************** + * FunctionName : add_offer_options + * Description : add OFFER option of DHCP message + * Parameters : optptr -- the addr of DHCP message option + * Returns : the addr of DHCP message option +*******************************************************************************/ +static u8_t *add_offer_options(u8_t *optptr) +{ + ip4_addr_t ipadd; + + ipadd.addr = *((u32_t *) &server_address); #ifdef USE_CLASS_B_NET *optptr++ = DHCP_OPTION_SUBNET_MASK; @@ -173,10 +316,10 @@ static u8_t* add_offer_options(u8_t* optptr) *optptr++ = DHCP_OPTION_LEASE_TIME; *optptr++ = 4; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; + *optptr++ = ((dhcps_lease_time * DHCPS_LEASE_UNIT) >> 24) & 0xFF; + *optptr++ = ((dhcps_lease_time * DHCPS_LEASE_UNIT) >> 16) & 0xFF; + *optptr++ = ((dhcps_lease_time * DHCPS_LEASE_UNIT) >> 8) & 0xFF; + *optptr++ = ((dhcps_lease_time * DHCPS_LEASE_UNIT) >> 0) & 0xFF; *optptr++ = DHCP_OPTION_SERVER_ID; *optptr++ = 4; @@ -185,27 +328,36 @@ static u8_t* add_offer_options(u8_t* optptr) *optptr++ = ip4_addr3(&ipadd); *optptr++ = ip4_addr4(&ipadd); - if (dhcps_router_enabled(offer)) { + if (dhcps_router_enabled(dhcps_offer)) { tcpip_adapter_ip_info_t if_ip; - bzero(&if_ip, sizeof(tcpip_adapter_ip_info_t)); - wifi_get_ip_info(ESP_IF_WIFI_AP, &if_ip); + //bzero(&if_ip, sizeof(struct ip_info)); + memset(&if_ip , 0x00, sizeof(tcpip_adapter_ip_info_t)); - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = 4; - *optptr++ = ip4_addr1(&if_ip.gw); - *optptr++ = ip4_addr2(&if_ip.gw); - *optptr++ = ip4_addr3(&if_ip.gw); - *optptr++ = ip4_addr4(&if_ip.gw); + tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &if_ip); + + if (!ip4_addr_isany_val(if_ip.gw)) { + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = 4; + *optptr++ = ip4_addr1(&if_ip.gw); + *optptr++ = ip4_addr2(&if_ip.gw); + *optptr++ = ip4_addr3(&if_ip.gw); + *optptr++ = ip4_addr4(&if_ip.gw); + } } -#ifdef USE_DNS *optptr++ = DHCP_OPTION_DNS_SERVER; *optptr++ = 4; - *optptr++ = ip4_addr1(&ipadd); - *optptr++ = ip4_addr2(&ipadd); - *optptr++ = ip4_addr3(&ipadd); - *optptr++ = ip4_addr4(&ipadd); -#endif + if (dhcps_dns_enabled(dhcps_dns)) { + *optptr++ = ip4_addr1(&dns_server); + *optptr++ = ip4_addr2(&dns_server); + *optptr++ = ip4_addr3(&dns_server); + *optptr++ = ip4_addr4(&dns_server); + }else { + *optptr++ = ip4_addr1(&ipadd); + *optptr++ = ip4_addr2(&ipadd); + *optptr++ = ip4_addr3(&ipadd); + *optptr++ = ip4_addr4(&ipadd); + } #ifdef CLASS_B_NET *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; @@ -225,13 +377,8 @@ static u8_t* add_offer_options(u8_t* optptr) *optptr++ = DHCP_OPTION_INTERFACE_MTU; *optptr++ = 2; -#ifdef CLASS_B_NET *optptr++ = 0x05; *optptr++ = 0xdc; -#else - *optptr++ = 0x02; - *optptr++ = 0x40; -#endif *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; *optptr++ = 1; @@ -249,62 +396,87 @@ static u8_t* add_offer_options(u8_t* optptr) return optptr; } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg�ṹ����ӽ����־���� - * - * @param optptr -- DHCP msg��Ϣλ�� - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static u8_t* add_end(u8_t* optptr) -{ +/****************************************************************************** + * FunctionName : add_end + * Description : add end option of DHCP message + * Parameters : optptr -- the addr of DHCP message option + * Returns : the addr of DHCP message option +*******************************************************************************/ +static u8_t *add_end(u8_t *optptr) +{ *optptr++ = DHCP_OPTION_END; return optptr; } -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -static void create_msg(struct dhcps_msg* m) -{ - struct ip4_addr client; - client.addr = *((uint32_t*) &client_address); +/****************************************************************************** + * FunctionName : create_msg + * Description : create response message + * Parameters : m -- DHCP message info + * Returns : none +*******************************************************************************/ +static void create_msg(struct dhcps_msg *m) +{ + ip4_addr_t client; + + + client.addr = *((uint32_t *) &client_address); m->op = DHCP_REPLY; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = 6; + m->hops = 0; // os_memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); m->secs = 0; m->flags = htons(BOOTP_BROADCAST); - memcpy((char*) m->yiaddr, (char*) &client.addr, sizeof(m->yiaddr)); + memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr)); - memset((char*) m->ciaddr, 0, sizeof(m->ciaddr)); - memset((char*) m->siaddr, 0, sizeof(m->siaddr)); - memset((char*) m->giaddr, 0, sizeof(m->giaddr)); - memset((char*) m->sname, 0, sizeof(m->sname)); - memset((char*) m->file, 0, sizeof(m->file)); + memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); - memset((char*) m->options, 0, sizeof(m->options)); + memset((char *) m->siaddr, 0, sizeof(m->siaddr)); - u32_t magic_cookie1 = magic_cookie; - memcpy((char*) m->options, &magic_cookie1, sizeof(magic_cookie1)); + memset((char *) m->giaddr, 0, sizeof(m->giaddr)); + + memset((char *) m->sname, 0, sizeof(m->sname)); + + memset((char *) m->file, 0, sizeof(m->file)); + + memset((char *) m->options, 0, sizeof(m->options)); + + u32_t magic_cookie_temp = magic_cookie; + + memcpy((char *) m->options, &magic_cookie_temp, sizeof(magic_cookie_temp)); } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��OFFER - * - * @param -- m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void send_offer(struct dhcps_msg* m) + +struct pbuf * dhcps_pbuf_alloc(u16_t len) { - u8_t* end; - struct pbuf* p, *q; - u8_t* data; + u16_t mlen = sizeof(struct dhcps_msg); + + if (len > mlen) { +#if DHCPS_DEBUG + DHCPS_LOG("dhcps: len=%d mlen=%d", len, mlen); +#endif + mlen = len; + } + + return pbuf_alloc(PBUF_TRANSPORT, mlen, PBUF_RAM); +} + +/****************************************************************************** + * FunctionName : send_offer + * Description : DHCP message OFFER Response + * Parameters : m -- DHCP message info + * Returns : none +*******************************************************************************/ +static void send_offer(struct dhcps_msg *m, u16_t len) +{ + u8_t *end; + struct pbuf *p, *q; + u8_t *data; u16_t cnt = 0; u16_t i; #if DHCPS_DEBUG @@ -316,30 +488,30 @@ static void send_offer(struct dhcps_msg* m) end = add_offer_options(end); end = add_end(end); - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); + p = dhcps_pbuf_alloc(len); #if DHCPS_DEBUG - printf("udhcp: send_offer>>p->ref = %d\n", p->ref); + DHCPS_LOG("udhcp: send_offer>>p->ref = %d\n", p->ref); #endif if (p != NULL) { #if DHCPS_DEBUG - printf("dhcps: send_offer>>pbuf_alloc succeed\n"); - printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_offer>>p->len = %d\n", p->len); + DHCPS_LOG("dhcps: send_offer>>pbuf_alloc succeed\n"); + DHCPS_LOG("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); + DHCPS_LOG("dhcps: send_offer>>p->len = %d\n", p->len); #endif q = p; while (q != NULL) { - data = (u8_t*)q->payload; + data = (u8_t *)q->payload; for (i = 0; i < q->len; i++) { - data[i] = ((u8_t*) m)[cnt++]; + data[i] = ((u8_t *) m)[cnt++]; #if DHCPS_DEBUG - printf("%02x ", data[i]); + DHCPS_LOG("%02x ", data[i]); if ((i + 1) % 16 == 0) { - printf("\n"); + DHCPS_LOG("\n"); } #endif @@ -350,38 +522,37 @@ static void send_offer(struct dhcps_msg* m) } else { #if DHCPS_DEBUG - printf("dhcps: send_offer>>pbuf_alloc failed\n"); + DHCPS_LOG("dhcps: send_offer>>pbuf_alloc failed\n"); #endif return; } #if DHCPS_DEBUG SendOffer_err_t = udp_sendto(pcb_dhcps, p, IP_ADDR_BROADCAST, DHCPS_CLIENT_PORT); - printf("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t); + DHCPS_LOG("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t); #else udp_sendto(pcb_dhcps, p, IP_ADDR_BROADCAST, DHCPS_CLIENT_PORT); #endif if (p->ref != 0) { #if DHCPS_DEBUG - printf("udhcp: send_offer>>free pbuf\n"); + DHCPS_LOG("udhcp: send_offer>>free pbuf\n"); #endif pbuf_free(p); } } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��NAK��Ϣ - * - * @param m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void send_nak(struct dhcps_msg* m) -{ - u8_t* end; - struct pbuf* p, *q; - u8_t* data; +/****************************************************************************** + * FunctionName : send_nak + * Description : DHCP message NACK Response + * Parameters : m -- DHCP message info + * Returns : none +*******************************************************************************/ +static void send_nak(struct dhcps_msg *m, u16_t len) +{ + u8_t *end; + struct pbuf *p, *q; + u8_t *data; u16_t cnt = 0; u16_t i; #if DHCPS_DEBUG @@ -392,30 +563,30 @@ static void send_nak(struct dhcps_msg* m) end = add_msg_type(&m->options[4], DHCPNAK); end = add_end(end); - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); + p = dhcps_pbuf_alloc(len); #if DHCPS_DEBUG - printf("udhcp: send_nak>>p->ref = %d\n", p->ref); + DHCPS_LOG("udhcp: send_nak>>p->ref = %d\n", p->ref); #endif if (p != NULL) { #if DHCPS_DEBUG - printf("dhcps: send_nak>>pbuf_alloc succeed\n"); - printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_nak>>p->len = %d\n", p->len); + DHCPS_LOG("dhcps: send_nak>>pbuf_alloc succeed\n"); + DHCPS_LOG("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); + DHCPS_LOG("dhcps: send_nak>>p->len = %d\n", p->len); #endif q = p; while (q != NULL) { - data = (u8_t*)q->payload; + data = (u8_t *)q->payload; for (i = 0; i < q->len; i++) { - data[i] = ((u8_t*) m)[cnt++]; + data[i] = ((u8_t *) m)[cnt++]; #if DHCPS_DEBUG - printf("%02x ", data[i]); + DHCPS_LOG("%02x ", data[i]); if ((i + 1) % 16 == 0) { - printf("\n"); + DHCPS_LOG("\n"); } #endif @@ -426,73 +597,70 @@ static void send_nak(struct dhcps_msg* m) } else { #if DHCPS_DEBUG - printf("dhcps: send_nak>>pbuf_alloc failed\n"); + DHCPS_LOG("dhcps: send_nak>>pbuf_alloc failed\n"); #endif return; } #if DHCPS_DEBUG SendNak_err_t = udp_sendto(pcb_dhcps, p, IP_ADDR_BROADCAST, DHCPS_CLIENT_PORT); - printf("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t); + DHCPS_LOG("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t); #else udp_sendto(pcb_dhcps, p, IP_ADDR_BROADCAST, DHCPS_CLIENT_PORT); #endif if (p->ref != 0) { #if DHCPS_DEBUG - printf("udhcp: send_nak>>free pbuf\n"); + DHCPS_LOG("udhcp: send_nak>>free pbuf\n"); #endif pbuf_free(p); } } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��ACK��DHCP�ͻ��� - * - * @param m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void send_ack(struct dhcps_msg* m) -{ - u8_t* end; - struct pbuf* p, *q; - u8_t* data; +/****************************************************************************** + * FunctionName : send_ack + * Description : DHCP message ACK Response + * Parameters : m -- DHCP message info + * Returns : none +*******************************************************************************/ +static void send_ack(struct dhcps_msg *m, u16_t len) +{ + u8_t *end; + struct pbuf *p, *q; + u8_t *data; u16_t cnt = 0; u16_t i; -#if DHCPS_DEBUG err_t SendAck_err_t; -#endif create_msg(m); end = add_msg_type(&m->options[4], DHCPACK); end = add_offer_options(end); end = add_end(end); - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); + p = dhcps_pbuf_alloc(len); #if DHCPS_DEBUG - printf("udhcp: send_ack>>p->ref = %d\n", p->ref); + DHCPS_LOG("udhcp: send_ack>>p->ref = %d\n", p->ref); #endif if (p != NULL) { #if DHCPS_DEBUG - printf("dhcps: send_ack>>pbuf_alloc succeed\n"); - printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_ack>>p->len = %d\n", p->len); + DHCPS_LOG("dhcps: send_ack>>pbuf_alloc succeed\n"); + DHCPS_LOG("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); + DHCPS_LOG("dhcps: send_ack>>p->len = %d\n", p->len); #endif q = p; while (q != NULL) { - data = (u8_t*)q->payload; + data = (u8_t *)q->payload; for (i = 0; i < q->len; i++) { - data[i] = ((u8_t*) m)[cnt++]; + data[i] = ((u8_t *) m)[cnt++]; #if DHCPS_DEBUG - printf("%02x ", data[i]); + DHCPS_LOG("%02x ", data[i]); if ((i + 1) % 16 == 0) { - printf("\n"); + DHCPS_LOG("\n"); } #endif @@ -503,51 +671,52 @@ static void send_ack(struct dhcps_msg* m) } else { #if DHCPS_DEBUG - printf("dhcps: send_ack>>pbuf_alloc failed\n"); + DHCPS_LOG("dhcps: send_ack>>pbuf_alloc failed\n"); #endif return; } -#if DHCPS_DEBUG SendAck_err_t = udp_sendto(pcb_dhcps, p, IP_ADDR_BROADCAST, DHCPS_CLIENT_PORT); - printf("dhcps: send_ack>>udp_sendto result %x\n", SendAck_err_t); -#else + DHCPS_LOG("dhcps: send_ack>>udp_sendto result %x\n", SendAck_err_t); +#if DHCPS_DEBUG udp_sendto(pcb_dhcps, p, IP_ADDR_BROADCAST, DHCPS_CLIENT_PORT); #endif + if (SendAck_err_t == ERR_OK) { + dhcps_cb(m->yiaddr); + } + if (p->ref != 0) { #if DHCPS_DEBUG - printf("udhcp: send_ack>>free pbuf\n"); + DHCPS_LOG("udhcp: send_ack>>free pbuf\n"); #endif pbuf_free(p); } } -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ�� - * - * @param optptr DHCP msg�е��������� - * @param len ��������Ĵ��?(byte) - * - * @return uint8_t ���ش�����DHCP Server״ֵ̬ - */ -/////////////////////////////////////////////////////////////////////////////////// -static u8_t parse_options(u8_t* optptr, s16_t len) + +/****************************************************************************** + * FunctionName : parse_options + * Description : parse DHCP message options + * Parameters : optptr -- DHCP message option info + * len -- DHCP message option length + * Returns : none +*******************************************************************************/ +static u8_t parse_options(u8_t *optptr, s16_t len) { - struct ip4_addr client; + ip4_addr_t client; bool is_dhcp_parse_end = false; struct dhcps_state s; - client.addr = *((uint32_t*) &client_address); // Ҫ�����DHCP�ͻ��˵�IP + client.addr = *((uint32_t *) &client_address); - u8_t* end = optptr + len; + u8_t *end = optptr + len; u16_t type = 0; s.state = DHCPS_STATE_IDLE; while (optptr < end) { #if DHCPS_DEBUG - printf("dhcps: (s16_t)*optptr = %d\n", (s16_t)*optptr); + DHCPS_LOG("dhcps: (s16_t)*optptr = %d\n", (s16_t)*optptr); #endif switch ((s16_t) *optptr) { @@ -557,14 +726,14 @@ static u8_t parse_options(u8_t* optptr, s16_t len) break; case DHCP_OPTION_REQ_IPADDR://50 - if (memcmp((char*) &client.addr, (char*) optptr + 2, 4) == 0) { + if (memcmp((char *) &client.addr, (char *) optptr + 2, 4) == 0) { #if DHCPS_DEBUG - printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); + DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); #endif s.state = DHCPS_STATE_ACK; } else { #if DHCPS_DEBUG - printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); + DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); #endif s.state = DHCPS_STATE_NAK; } @@ -589,7 +758,7 @@ static u8_t parse_options(u8_t* optptr, s16_t len) case DHCPDISCOVER://1 s.state = DHCPS_STATE_OFFER; #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_OFFER\n"); + DHCPS_LOG("dhcps: DHCPD_STATE_OFFER\n"); #endif break; @@ -602,7 +771,7 @@ static u8_t parse_options(u8_t* optptr, s16_t len) } #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_NAK\n"); + DHCPS_LOG("dhcps: DHCPD_STATE_NAK\n"); #endif } @@ -611,83 +780,56 @@ static u8_t parse_options(u8_t* optptr, s16_t len) case DHCPDECLINE://4 s.state = DHCPS_STATE_IDLE; #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_IDLE\n"); + DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n"); #endif break; case DHCPRELEASE://7 s.state = DHCPS_STATE_RELEASE; #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_IDLE\n"); + DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n"); #endif break; } #if DHCPS_DEBUG - printf("dhcps: return s.state = %d\n", s.state); + DHCPS_LOG("dhcps: return s.state = %d\n", s.state); #endif return s.state; } -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -static s16_t parse_msg(struct dhcps_msg* m, u16_t len) + +/****************************************************************************** + * FunctionName : parse_msg + * Description : parse DHCP message from netif + * Parameters : m -- DHCP message info + * len -- DHCP message length + * Returns : DHCP message type +*******************************************************************************/ +static s16_t parse_msg(struct dhcps_msg *m, u16_t len) { - u32_t lease_timer = (dhcps_lease_time * 60) / DHCPS_COARSE_TIMER_SECS; + u32_t lease_timer = (dhcps_lease_time * DHCPS_LEASE_UNIT)/DHCPS_COARSE_TIMER_SECS; - if (memcmp((char*)m->options, - &magic_cookie, - sizeof(magic_cookie)) == 0) { + if (memcmp((char *)m->options, &magic_cookie, sizeof(magic_cookie)) == 0) { #if DHCPS_DEBUG - printf("dhcps: len = %d\n", len); + DHCPS_LOG("dhcps: len = %d\n", len); #endif - /* - * ��¼��ǰ��xid���ﴦ���? - * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� - */ -// if((old_xid[0] == 0) && -// (old_xid[1] == 0) && -// (old_xid[2] == 0) && -// (old_xid[3] == 0)){ -// /* -// * old_xidδ��¼�κ����? -// * �϶��ǵ�һ��ʹ�� -// */ -// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); -// }else{ -// /* -// * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� -// * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP -// * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) -// * -// */ -// if(memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ - /* - * ��¼���ε�xid�ţ�ͬʱ�����IP���� - */ - struct ip4_addr addr_tmp; -// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); + ip4_addr_t addr_tmp; -// { - struct dhcps_pool* pdhcps_pool = NULL; - list_node* pnode = NULL; - list_node* pback_node = NULL; - struct ip4_addr first_address; + struct dhcps_pool *pdhcps_pool = NULL; + list_node *pnode = NULL; + list_node *pback_node = NULL; + ip4_addr_t first_address; bool flag = false; -// POOL_START: - first_address.addr = dhcps_lease.start_ip.addr; + first_address.addr = dhcps_poll.start_ip.addr; client_address.addr = client_address_plus.addr; renew = false; -// addr_tmp.addr = htonl(client_address_plus.addr); -// addr_tmp.addr++; -// client_address_plus.addr = htonl(addr_tmp.addr); if (plist != NULL) { for (pback_node = plist; pback_node != NULL; pback_node = pback_node->pnext) { pdhcps_pool = pback_node->pnode; if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0) { -// printf("the same device request ip\n"); if (memcmp(&pdhcps_pool->ip.addr, m->ciaddr, sizeof(pdhcps_pool->ip.addr)) == 0) { renew = true; } @@ -697,8 +839,6 @@ static s16_t parse_msg(struct dhcps_msg* m, u16_t len) pnode = pback_node; goto POOL_CHECK; } else if (pdhcps_pool->ip.addr == client_address_plus.addr) { -// client_address.addr = client_address_plus.addr; -// printf("the ip addr has been request\n"); addr_tmp.addr = htonl(client_address_plus.addr); addr_tmp.addr++; client_address_plus.addr = htonl(addr_tmp.addr); @@ -716,29 +856,33 @@ static s16_t parse_msg(struct dhcps_msg* m, u16_t len) } } } else { - client_address.addr = dhcps_lease.start_ip.addr; + client_address.addr = dhcps_poll.start_ip.addr; } - if (client_address_plus.addr > dhcps_lease.end_ip.addr) { + if (client_address_plus.addr > dhcps_poll.end_ip.addr) { client_address.addr = first_address.addr; } - if (client_address.addr > dhcps_lease.end_ip.addr) { - client_address_plus.addr = dhcps_lease.start_ip.addr; + if (client_address.addr > dhcps_poll.end_ip.addr) { + client_address_plus.addr = dhcps_poll.start_ip.addr; pdhcps_pool = NULL; pnode = NULL; } else { - pdhcps_pool = (struct dhcps_pool*)os_zalloc(sizeof(struct dhcps_pool)); + pdhcps_pool = (struct dhcps_pool *)mem_malloc(sizeof(struct dhcps_pool)); + memset(pdhcps_pool , 0x00 , sizeof(struct dhcps_pool)); + pdhcps_pool->ip.addr = client_address.addr; memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); pdhcps_pool->lease_timer = lease_timer; - pnode = (list_node*)os_zalloc(sizeof(list_node)); + pnode = (list_node *)mem_malloc(sizeof(list_node)); + memset(pnode , 0x00 , sizeof(list_node)); + pnode->pnode = pdhcps_pool; pnode->pnext = NULL; node_insert_to_list(&plist, pnode); - if (client_address.addr == dhcps_lease.end_ip.addr) { - client_address_plus.addr = dhcps_lease.start_ip.addr; + if (client_address.addr == dhcps_poll.end_ip.addr) { + client_address_plus.addr = dhcps_poll.start_ip.addr; } else { addr_tmp.addr = htonl(client_address.addr); addr_tmp.addr++; @@ -748,7 +892,7 @@ static s16_t parse_msg(struct dhcps_msg* m, u16_t len) POOL_CHECK: - if ((client_address.addr > dhcps_lease.end_ip.addr) || (ip4_addr_isany(&client_address))) { + if ((client_address.addr > dhcps_poll.end_ip.addr) || (ip4_addr_isany(&client_address))) { if (pnode != NULL) { node_remove_from_list(&plist, pnode); os_free(pnode); @@ -760,7 +904,6 @@ POOL_CHECK: pdhcps_pool = NULL; } -// client_address_plus.addr = dhcps_lease.start_ip.addr; return 4; } @@ -780,82 +923,79 @@ POOL_CHECK: memset(&client_address, 0x0, sizeof(client_address)); } - extern bool wifi_softap_set_station_info(uint8_t*,ip4_addr_t*); - if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { - return 0; - } - -// } #if DHCPS_DEBUG - printf("dhcps: xid changed\n"); - printf("dhcps: client_address.addr = %x\n", client_address.addr); + DHCPS_LOG("dhcps: xid changed\n"); + DHCPS_LOG("dhcps: client_address.addr = %x\n", client_address.addr); #endif - -// } - -// } return ret; } return 0; } -/////////////////////////////////////////////////////////////////////////////////// -/* - * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������ - * ��Ҫ����udp_recv()������LWIP����ע��. - * - * @param arg - * @param pcb ���յ�UDP��Ŀ��ƿ�? - * @param p ���յ���UDP�е��������? - * @param addr ���ʹ�UDP���Դ�����IP��ַ - * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void handle_dhcp(void* arg, - struct udp_pcb* pcb, - struct pbuf* p, - const ip_addr_t* addr, + +/****************************************************************************** + * FunctionName : handle_dhcp + * Description : If an incoming DHCP message is in response to us, then trigger the state machine + * Parameters : arg -- arg user supplied argument (udp_pcb.recv_arg) + * pcb -- the udp_pcb which received data + * p -- the packet buffer that was received + * addr -- the remote IP address from which the packet was received + * port -- the remote port from which the packet was received + * Returns : none +*******************************************************************************/ +static void handle_dhcp(void *arg, + struct udp_pcb *pcb, + struct pbuf *p, + const ip_addr_t *addr, u16_t port) { - struct dhcps_msg* pmsg_dhcps = NULL; - s16_t tlen; + struct dhcps_msg *pmsg_dhcps = NULL; + s16_t tlen, malloc_len; u16_t i; u16_t dhcps_msg_cnt = 0; - u8_t* p_dhcps_msg = NULL; - u8_t* data; + u8_t *p_dhcps_msg = NULL; + u8_t *data; #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> receive a packet\n"); + DHCPS_LOG("dhcps: handle_dhcp-> receive a packet\n"); #endif if (p == NULL) { return; } - pmsg_dhcps = (struct dhcps_msg*)os_zalloc(sizeof(struct dhcps_msg)); + malloc_len = sizeof(struct dhcps_msg); +#if DHCPS_DEBUG + DHCPS_LOG("dhcps: handle_dhcp malloc_len=%d rx_len=%d", malloc_len, p->tot_len); +#endif + if (malloc_len < p->tot_len) { + malloc_len = p->tot_len; + } + pmsg_dhcps = (struct dhcps_msg *)mem_malloc(malloc_len); if (NULL == pmsg_dhcps) { pbuf_free(p); return; } - p_dhcps_msg = (u8_t*)pmsg_dhcps; + memset(pmsg_dhcps , 0x00 , malloc_len); + p_dhcps_msg = (u8_t *)pmsg_dhcps; tlen = p->tot_len; data = p->payload; #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); - printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); + DHCPS_LOG("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); + DHCPS_LOG("dhcps: handle_dhcp-> p->len = %d\n", p->len); #endif for (i = 0; i < p->len; i++) { p_dhcps_msg[dhcps_msg_cnt++] = data[i]; #if DHCPS_DEBUG - printf("%02x ", data[i]); + DHCPS_LOG("%02x ", data[i]); if ((i + 1) % 16 == 0) { - printf("\n"); + DHCPS_LOG("\n"); } #endif @@ -863,9 +1003,9 @@ static void handle_dhcp(void* arg, if (p->next != NULL) { #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> p->next != NULL\n"); - printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n", p->next->tot_len); - printf("dhcps: handle_dhcp-> p->next->len = %d\n", p->next->len); + DHCPS_LOG("dhcps: handle_dhcp-> p->next != NULL\n"); + DHCPS_LOG("dhcps: handle_dhcp-> p->next->tot_len = %d\n", p->next->tot_len); + DHCPS_LOG("dhcps: handle_dhcp-> p->next->len = %d\n", p->next->len); #endif data = p->next->payload; @@ -873,44 +1013,40 @@ static void handle_dhcp(void* arg, for (i = 0; i < p->next->len; i++) { p_dhcps_msg[dhcps_msg_cnt++] = data[i]; #if DHCPS_DEBUG - printf("%02x ", data[i]); + DHCPS_LOG("%02x ", data[i]); if ((i + 1) % 16 == 0) { - printf("\n"); + DHCPS_LOG("\n"); } #endif } } - /* - * DHCP �ͻ���������Ϣ���� - */ #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> parse_msg(p)\n"); + DHCPS_LOG("dhcps: handle_dhcp-> parse_msg(p)\n"); #endif switch (parse_msg(pmsg_dhcps, tlen - 240)) { - case DHCPS_STATE_OFFER://1 #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); + DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); #endif - send_offer(pmsg_dhcps); + send_offer(pmsg_dhcps, malloc_len); break; case DHCPS_STATE_ACK://3 #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); + DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); #endif - send_ack(pmsg_dhcps); + send_ack(pmsg_dhcps, malloc_len); break; case DHCPS_STATE_NAK://4 #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); + DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); #endif - send_nak(pmsg_dhcps); + send_nak(pmsg_dhcps, malloc_len); break; default : @@ -918,39 +1054,45 @@ static void handle_dhcp(void* arg, } #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); + DHCPS_LOG("dhcps: handle_dhcp-> pbuf_free(p)\n"); #endif pbuf_free(p); os_free(pmsg_dhcps); pmsg_dhcps = NULL; } -/////////////////////////////////////////////////////////////////////////////////// -static void wifi_softap_init_dhcps_lease(u32_t ip) + +/****************************************************************************** + * FunctionName : dhcps_poll_set + * Description : set ip poll from start to end for station + * Parameters : ip -- The current ip addr + * Returns : none +*******************************************************************************/ +static void dhcps_poll_set(u32_t ip) { u32_t softap_ip = 0, local_ip = 0; u32_t start_ip = 0; u32_t end_ip = 0; - if (dhcps_lease.enable == true) { + if (dhcps_poll.enable == true) { softap_ip = htonl(ip); - start_ip = htonl(dhcps_lease.start_ip.addr); - end_ip = htonl(dhcps_lease.end_ip.addr); + start_ip = htonl(dhcps_poll.start_ip.addr); + end_ip = htonl(dhcps_poll.end_ip.addr); /*config ip information can't contain local ip*/ if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { - dhcps_lease.enable = false; + dhcps_poll.enable = false; } else { /*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)) || (end_ip - start_ip > DHCPS_MAX_LEASE)) { - dhcps_lease.enable = false; + dhcps_poll.enable = false; } } } - if (dhcps_lease.enable == false) { + if (dhcps_poll.enable == false) { local_ip = softap_ip = htonl(ip); softap_ip &= 0xFFFFFF00; local_ip &= 0xFF; @@ -961,17 +1103,36 @@ static void wifi_softap_init_dhcps_lease(u32_t ip) local_ip ++; } - bzero(&dhcps_lease, sizeof(dhcps_lease)); - dhcps_lease.start_ip.addr = softap_ip | local_ip; - dhcps_lease.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); - dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); - dhcps_lease.end_ip.addr = htonl(dhcps_lease.end_ip.addr); + bzero(&dhcps_poll, sizeof(dhcps_poll)); + dhcps_poll.start_ip.addr = softap_ip | local_ip; + dhcps_poll.end_ip.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); + dhcps_poll.start_ip.addr = htonl(dhcps_poll.start_ip.addr); + dhcps_poll.end_ip.addr = htonl(dhcps_poll.end_ip.addr); } -// printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); } -/////////////////////////////////////////////////////////////////////////////////// -void dhcps_start(tcpip_adapter_ip_info_t* info) + + +/****************************************************************************** + * FunctionName : dhcps_set_new_lease_cb + * Description : set callback for dhcp server when it assign an IP + * to the connected dhcp client + * Parameters : cb -- callback for dhcp server + * Returns : none +*******************************************************************************/ +void dhcps_set_new_lease_cb(dhcps_cb_t cb) +{ + dhcps_cb = cb; +} + +/****************************************************************************** + * FunctionName : dhcps_start + * Description : start dhcp server function + * Parameters : netif -- The current netif addr + * : info -- The current ip info + * Returns : none +*******************************************************************************/ +void dhcps_start(struct netif *netif, ip4_addr_t ip) { if (pcb_dhcps != NULL) { udp_remove(pcb_dhcps); @@ -979,34 +1140,48 @@ void dhcps_start(tcpip_adapter_ip_info_t* info) pcb_dhcps = udp_new(); - if (pcb_dhcps == NULL || info == NULL) { + if (pcb_dhcps == NULL || ip4_addr_isany_val(ip)) { printf("dhcps_start(): could not obtain pcb\n"); } - server_address = info->ip; - wifi_softap_init_dhcps_lease(server_address.addr); - client_address_plus.addr = dhcps_lease.start_ip.addr; - udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); + IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255); + + server_address.addr = ip.addr; + dhcps_poll_set(server_address.addr); + + client_address_plus.addr = dhcps_poll.start_ip.addr; + + udp_bind(pcb_dhcps, &netif->ip_addr, DHCPS_SERVER_PORT); udp_recv(pcb_dhcps, handle_dhcp, NULL); #if DHCPS_DEBUG - printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); + DHCPS_LOG("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); #endif } -void dhcps_stop(void) +/****************************************************************************** + * FunctionName : dhcps_stop + * Description : stop dhcp server function + * Parameters : netif -- The current netif addr + * Returns : none +*******************************************************************************/ +void dhcps_stop(struct netif *netif) { + struct netif *apnetif = netif; - udp_disconnect(pcb_dhcps); + if (apnetif == NULL) { + printf("dhcps_stop: apnetif == NULL\n"); + return; + } if (pcb_dhcps != NULL) { + udp_disconnect(pcb_dhcps); udp_remove(pcb_dhcps); pcb_dhcps = NULL; } - //udp_remove(pcb_dhcps); - list_node* pnode = NULL; - list_node* pback_node = NULL; + list_node *pnode = NULL; + list_node *pback_node = NULL; pnode = plist; while (pnode != NULL) { @@ -1020,97 +1195,17 @@ void dhcps_stop(void) } } -bool wifi_softap_set_dhcps_lease(struct dhcps_lease* please) -{ - tcpip_adapter_ip_info_t info; - u32_t softap_ip = 0; - u32_t start_ip = 0; - u32_t end_ip = 0; - - wifi_mode_t opmode; - esp_wifi_get_mode(&opmode); - - if (opmode == WIFI_MODE_STA || opmode == WIFI_MODE_NULL) { - return false; - } - - if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) { - return false; - } - - if (please->enable) { - bzero(&info, sizeof(tcpip_adapter_ip_info_t)); - wifi_get_ip_info(ESP_IF_WIFI_AP, &info); - softap_ip = htonl(info.ip.addr); - start_ip = htonl(please->start_ip.addr); - end_ip = htonl(please->end_ip.addr); - - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { - return false; - } - - /*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 false; - } - - if (end_ip - start_ip > DHCPS_MAX_LEASE) { - return false; - } - - bzero(&dhcps_lease, sizeof(dhcps_lease)); -// dhcps_lease.start_ip.addr = start_ip; -// dhcps_lease.end_ip.addr = end_ip; - dhcps_lease.start_ip.addr = please->start_ip.addr; - dhcps_lease.end_ip.addr = please->end_ip.addr; - } - - dhcps_lease.enable = please->enable; -// dhcps_lease_flag = false; - return true; -} - /****************************************************************************** - * FunctionName : wifi_softap_get_dhcps_lease - * Description : get the lease information of DHCP server - * Parameters : please -- Additional argument to get the lease information, - * Little-Endian. - * Returns : true or false + * FunctionName : kill_oldest_dhcps_pool + * Description : remove the oldest node from list + * Parameters : none + * Returns : none *******************************************************************************/ -bool wifi_softap_get_dhcps_lease(struct dhcps_lease* please) -{ - wifi_mode_t opmode; - esp_wifi_get_mode(&opmode); - - if (opmode == WIFI_MODE_STA || opmode == WIFI_MODE_NULL) { - return false; - } - - if (NULL == please) { - return false; - } - - if (dhcps_lease.enable == false) { - if (wifi_softap_dhcps_status() == DHCP_STOPPED) { - return false; - } - } else { - } - - please->start_ip.addr = dhcps_lease.start_ip.addr; - please->end_ip.addr = dhcps_lease.end_ip.addr; - return true; -} - static void kill_oldest_dhcps_pool(void) { - list_node* pre = NULL, *p = NULL; - list_node* minpre = NULL, *minp = NULL; - struct dhcps_pool* pdhcps_pool = NULL, *pmin_pool = NULL; + list_node *pre = NULL, *p = NULL; + list_node *minpre = NULL, *minp = NULL; + struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; pre = plist; p = pre->pnext; minpre = pre; @@ -1136,12 +1231,18 @@ static void kill_oldest_dhcps_pool(void) minp = NULL; } +/****************************************************************************** + * FunctionName : dhcps_coarse_tmr + * Description : the lease time count + * Parameters : none + * Returns : none +*******************************************************************************/ void dhcps_coarse_tmr(void) { u8_t num_dhcps_pool = 0; - list_node* pback_node = NULL; - list_node* pnode = NULL; - struct dhcps_pool* pdhcps_pool = NULL; + list_node *pback_node = NULL; + list_node *pnode = NULL; + struct dhcps_pool *pdhcps_pool = NULL; pnode = plist; while (pnode != NULL) { @@ -1162,76 +1263,62 @@ void dhcps_coarse_tmr(void) } } - if (num_dhcps_pool >= MAX_STATION_NUM) { + if (num_dhcps_pool > MAX_STATION_NUM) { kill_oldest_dhcps_pool(); } } -bool wifi_softap_set_dhcps_offer_option(u8_t level, void* optarg) +/****************************************************************************** + * FunctionName : dhcp_search_ip_on_mac + * Description : Search ip address based on mac address + * Parameters : mac -- The MAC addr + * ip -- The IP info + * Returns : true or false +*******************************************************************************/ +bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip) { - bool offer_flag = true; + struct dhcps_pool *pdhcps_pool = NULL; + list_node *pback_node = NULL; + bool ret = false; - if (optarg == NULL && wifi_softap_dhcps_status() == false) { - return false; - } + for (pback_node = plist; pback_node != NULL; pback_node = pback_node->pnext) { + pdhcps_pool = pback_node->pnode; - if (level <= OFFER_START || level >= OFFER_END) { - return false; - } - - switch (level) { - case OFFER_ROUTER: - offer = (*(u8_t*)optarg) & 0x01; - offer_flag = true; - break; - - default : - offer_flag = false; + if (memcmp(pdhcps_pool->mac, mac, sizeof(pdhcps_pool->mac)) == 0) { + memcpy(&ip->addr, &pdhcps_pool->ip.addr, sizeof(pdhcps_pool->ip.addr)); + ret = true; break; + } } - return offer_flag; + return ret; } -bool wifi_softap_set_dhcps_lease_time(u32_t minute) +/****************************************************************************** + * FunctionName : dhcps_dns_setserver + * Description : set DNS server address for dhcpserver + * Parameters : dnsserver -- The DNS server address + * Returns : none +*******************************************************************************/ +void +dhcps_dns_setserver(const ip_addr_t *dnsserver) { - wifi_mode_t opmode; - esp_wifi_get_mode(&opmode); - - if (opmode == WIFI_MODE_STA || opmode == WIFI_MODE_NULL) { - return false; - } - - if (wifi_softap_dhcps_status() == DHCP_STARTED) { - return false; - } - - if (minute == 0) { - return false; - } - - dhcps_lease_time = minute; - return true; + if (dnsserver != NULL) { + dns_server = *(ip_2_ip4(dnsserver)); + } else { + dns_server = *(ip_2_ip4(IP_ADDR_ANY)); + } } -bool wifi_softap_reset_dhcps_lease_time(void) +/****************************************************************************** + * FunctionName : dhcps_dns_getserver + * Description : get DNS server address for dhcpserver + * Parameters : none + * Returns : ip4_addr_t +*******************************************************************************/ +ip4_addr_t +dhcps_dns_getserver() { - wifi_mode_t opmode; - esp_wifi_get_mode(&opmode); - - if (opmode == WIFI_MODE_STA || opmode == WIFI_MODE_NULL) { - return false; - } - - if (wifi_softap_dhcps_status() == DHCP_STARTED) { - return false; - } - - dhcps_lease_time = DHCPS_LEASE_TIME_DEF; - return true; + return dns_server; } -u32_t wifi_softap_get_dhcps_lease_time(void) // minute -{ - return dhcps_lease_time; -} diff --git a/components/lwip/include/lwip/apps/dhcpserver/dhcpserver.h b/components/lwip/include/lwip/apps/dhcpserver/dhcpserver.h index 22ea7238..258791f6 100644 --- a/components/lwip/include/lwip/apps/dhcpserver/dhcpserver.h +++ b/components/lwip/include/lwip/apps/dhcpserver/dhcpserver.h @@ -1,90 +1,95 @@ +// 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. #ifndef __DHCPS_H__ #define __DHCPS_H__ -#define USE_DNS - #include "sdkconfig.h" -#include "esp_wifi.h" +#include "lwip/ip_addr.h" -typedef struct dhcps_state { - s16_t state; +typedef struct dhcps_state{ + s16_t state; } dhcps_state; -// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� typedef struct dhcps_msg { - u8_t op, htype, hlen, hops; - u8_t xid[4]; - u16_t secs, flags; - u8_t ciaddr[4]; - u8_t yiaddr[4]; - u8_t siaddr[4]; - u8_t giaddr[4]; - u8_t chaddr[16]; - u8_t sname[64]; - u8_t file[128]; - u8_t options[312]; -} dhcps_msg; + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; + u8_t sname[64]; + u8_t file[128]; + u8_t options[312]; +}dhcps_msg; -struct dhcps_pool { - struct ip4_addr ip; - u8_t mac[6]; - u32_t lease_timer; +/* Defined in esp_misc.h */ +typedef struct { + bool enable; + ip4_addr_t start_ip; + ip4_addr_t end_ip; +} dhcps_lease_t; + +enum dhcps_offer_option{ + OFFER_START = 0x00, + OFFER_ROUTER = 0x01, + OFFER_DNS = 0x02, + OFFER_END }; -typedef struct _list_node { - void* pnode; - struct _list_node* pnext; -} list_node; - -extern u32_t dhcps_lease_time; #define DHCPS_COARSE_TIMER_SECS 1 -#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 #define DHCPS_MAX_LEASE 0x64 -#define BOOTP_BROADCAST 0x8000 +#define DHCPS_LEASE_TIME_DEF (120) +#define DHCPS_LEASE_UNIT CONFIG_LWIP_DHCPS_LEASE_UNIT -#define DHCP_REPLY 2 -#define DHCP_HTYPE_ETHERNET 1 -#define DHCP_HLEN_ETHERNET 6 +struct dhcps_pool{ + ip4_addr_t ip; + u8_t mac[6]; + u32_t lease_timer; +}; -#define DHCPS_SERVER_PORT 67 -#define DHCPS_CLIENT_PORT 68 +typedef u32_t dhcps_time_t; +typedef u8_t dhcps_offer_t; -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 +typedef struct { + dhcps_offer_t dhcps_offer; + dhcps_offer_t dhcps_dns; + dhcps_time_t dhcps_time; + dhcps_lease_t dhcps_poll; +} dhcps_options_t; -#define DHCP_OPTION_SUBNET_MASK 1 -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_REQ_IPADDR 50 -#define DHCP_OPTION_LEASE_TIME 51 -#define DHCP_OPTION_MSG_TYPE 53 -#define DHCP_OPTION_SERVER_ID 54 -#define DHCP_OPTION_INTERFACE_MTU 26 -#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 -#define DHCP_OPTION_BROADCAST_ADDRESS 28 -#define DHCP_OPTION_REQ_LIST 55 -#define DHCP_OPTION_END 255 +typedef void (*dhcps_cb_t)(u8_t client_ip[4]); -//#define USE_CLASS_B_NET 1 -#define DHCPS_DEBUG CONFIG_LWIP_DHCP_SERVER_DEBUG -#define MAX_STATION_NUM CONFIG_LWIP_DHCPS_MAX_STATION_NUM +static inline bool dhcps_router_enabled (dhcps_offer_t offer) +{ + return (offer & OFFER_ROUTER) != 0; +} -#define DHCPS_STATE_OFFER 1 -#define DHCPS_STATE_DECLINE 2 -#define DHCPS_STATE_ACK 3 -#define DHCPS_STATE_NAK 4 -#define DHCPS_STATE_IDLE 5 -#define DHCPS_STATE_RELEASE 6 +static inline bool dhcps_dns_enabled (dhcps_offer_t offer) +{ + return (offer & OFFER_DNS) != 0; +} -#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) - -void dhcps_start(tcpip_adapter_ip_info_t* info); -void dhcps_stop(void); +void dhcps_start(struct netif *netif, ip4_addr_t ip); +void dhcps_stop(struct netif *netif); +void *dhcps_option_info(u8_t op_id, u32_t opt_len); +void dhcps_set_option_info(u8_t op_id, void *opt_info, u32_t opt_len); +bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip); +void dhcps_dns_setserver(const ip_addr_t *dnsserver); +ip4_addr_t dhcps_dns_getserver(); +void dhcps_set_new_lease_cb(dhcps_cb_t cb); #endif diff --git a/components/lwip/include/lwip/apps/dhcpserver/dhcpserver_options.h b/components/lwip/include/lwip/apps/dhcpserver/dhcpserver_options.h new file mode 100644 index 00000000..8a6f1845 --- /dev/null +++ b/components/lwip/include/lwip/apps/dhcpserver/dhcpserver_options.h @@ -0,0 +1,134 @@ +// 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. +#pragma once + +/** DHCP Options + + This macros are not part of the public dhcpserver.h interface. + **/ +typedef enum +{ + /* RFC 1497 Vendor Extensions */ + + PAD = 0, + END = 255, + + SUBNET_MASK = 1, + TIME_OFFSET = 2, + ROUTER = 3, + TIME_SERVER = 4, + NAME_SERVER = 5, + DOMAIN_NAME_SERVER = 6, + LOG_SERVER = 7, + COOKIE_SERVER = 8, + LPR_SERVER = 9, + IMPRESS_SERVER = 10, + RESOURCE_LOCATION_SERVER = 11, + HOST_NAME = 12, + BOOT_FILE_SIZE = 13, + MERIT_DUMP_FILE = 14, + DOMAIN_NAME = 15, + SWAP_SERVER = 16, + ROOT_PATH = 17, + EXTENSIONS_PATH = 18, + + /* IP Layer Parameters per Host */ + + IP_FORWARDING = 19, + NON_LOCAL_SOURCE_ROUTING = 20, + POLICY_FILTER = 21, + MAXIMUM_DATAGRAM_REASSEMBLY_SIZE = 22, + DEFAULT_IP_TIME_TO_LIVE = 23, + PATH_MTU_AGING_TIMEOUT = 24, + PATH_MTU_PLATEAU_TABLE = 25, + + /* IP Layer Parameters per Interface */ + + INTERFACE_MTU = 26, + ALL_SUBNETS_ARE_LOCAL = 27, + BROADCAST_ADDRESS = 28, + PERFORM_MASK_DISCOVERY = 29, + MASK_SUPPLIER = 30, + PERFORM_ROUTER_DISCOVERY = 31, + ROUTER_SOLICITATION_ADDRESS = 32, + STATIC_ROUTE = 33, + + /* Link Layer Parameters per Interface */ + + TRAILER_ENCAPSULATION = 34, + ARP_CACHE_TIMEOUT = 35, + ETHERNET_ENCAPSULATION = 36, + + /* TCP Parameters */ + + TCP_DEFAULT_TTL = 37, + TCP_KEEPALIVE_INTERVAL = 38, + TCP_KEEPALIVE_GARBAGE = 39, + + /* Application and Service Parameters */ + + NETWORK_INFORMATION_SERVICE_DOMAIN = 40, + NETWORK_INFORMATION_SERVERS = 41, + NETWORK_TIME_PROTOCOL_SERVERS = 42, + VENDOR_SPECIFIC_INFORMATION = 43, + NETBIOS_OVER_TCP_IP_NAME_SERVER = 44, + NETBIOS_OVER_TCP_IP_DATAGRAM_DISTRIBUTION_SERVER = 45, + NETBIOS_OVER_TCP_IP_NODE_TYPE = 46, + NETBIOS_OVER_TCP_IP_SCOPE = 47, + X_WINDOW_SYSTEM_FONT_SERVER = 48, + X_WINDOW_SYSTEM_DISPLAY_MANAGER = 49, + NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN = 64, + NETWORK_INFORMATION_SERVICE_PLUS_SERVERS = 65, + MOBILE_IP_HOME_AGENT = 68, + SMTP_SERVER = 69, + POP3_SERVER = 70, + NNTP_SERVER = 71, + DEFAULT_WWW_SERVER = 72, + DEFAULT_FINGER_SERVER = 73, + DEFAULT_IRC_SERVER = 74, + STREETTALK_SERVER = 75, + STREETTALK_DIRECTORY_ASSISTANCE_SERVER = 76, + + /* DHCP Extensions */ + + REQUESTED_IP_ADDRESS = 50, + IP_ADDRESS_LEASE_TIME = 51, + OPTION_OVERLOAD = 52, + TFTP_SERVER_NAME = 66, + BOOTFILE_NAME = 67, + DHCP_MESSAGE_TYPE = 53, + SERVER_IDENTIFIER = 54, + PARAMETER_REQUEST_LIST = 55, + MESSAGE = 56, + MAXIMUM_DHCP_MESSAGE_SIZE = 57, + RENEWAL_T1_TIME_VALUE = 58, + REBINDING_T2_TIME_VALUE = 59, + VENDOR_CLASS_IDENTIFIER = 60, + CLIENT_IDENTIFIER = 61, + + USER_CLASS = 77, + FQDN = 81, + DHCP_AGENT_OPTIONS = 82, + NDS_SERVERS = 85, + NDS_TREE_NAME = 86, + NDS_CONTEXT = 87, + CLIENT_LAST_TRANSACTION_TIME = 91, + ASSOCIATED_IP = 92, + USER_AUTHENTICATION_PROTOCOL = 98, + AUTO_CONFIGURE = 116, + NAME_SERVICE_SEARCH = 117, + SUBNET_SELECTION = 118, + DOMAIN_SEARCH = 119, + CLASSLESS_ROUTE = 121, +} dhcp_msg_option; 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; - } -}