Просмотр исходного кода

Merge wifi commit '87977b92f3e12cfca74cf2e4dea87dc8d60b26fc' into feature/wifi-stage-two

Angus Gratton 9 лет назад
Родитель
Сommit
cb6bd109f2

+ 9 - 1
components/esp32/event.c

@@ -54,6 +54,7 @@ static esp_err_t system_event_sta_start_handle_default(system_event_t *event);
 static esp_err_t system_event_sta_stop_handle_default(system_event_t *event);
 static esp_err_t system_event_sta_connected_handle_default(system_event_t *event);
 static esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event);
+static esp_err_t system_event_sta_gotip_default(system_event_t *event);
 
 static system_event_handle_t g_system_event_handle_table[] = {
     {SYSTEM_EVENT_WIFI_READY,          NULL},
@@ -63,7 +64,7 @@ static system_event_handle_t g_system_event_handle_table[] = {
     {SYSTEM_EVENT_STA_CONNECTED,       system_event_sta_connected_handle_default},
     {SYSTEM_EVENT_STA_DISCONNECTED,    system_event_sta_disconnected_handle_default},
     {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, NULL},
-    {SYSTEM_EVENT_STA_GOTIP,           NULL},
+    {SYSTEM_EVENT_STA_GOTIP,           system_event_sta_gotip_default},
     {SYSTEM_EVENT_AP_START,            system_event_ap_start_handle_default},
     {SYSTEM_EVENT_AP_STOP,             system_event_ap_stop_handle_default},
     {SYSTEM_EVENT_AP_STACONNECTED,     NULL},
@@ -72,6 +73,13 @@ static system_event_handle_t g_system_event_handle_table[] = {
     {SYSTEM_EVENT_MAX,                 NULL},
 };
 
+static esp_err_t system_event_sta_gotip_default(system_event_t *event)
+{
+    extern esp_err_t esp_wifi_set_sta_ip(void);
+    WIFI_API_CALL_CHECK("esp_wifi_set_sta_ip", esp_wifi_set_sta_ip(), ESP_OK);
+    return ESP_OK;
+}
+
 esp_err_t system_event_ap_start_handle_default(system_event_t *event)
 {
     struct ip_info ap_ip;

+ 1 - 0
components/esp32/include/esp_event.h

@@ -48,6 +48,7 @@ typedef struct {
 typedef struct {
     uint32_t status;          /**< status of scanning APs*/
     uint8_t  number;
+    uint8_t  scan_id;
 } system_event_sta_scan_done_t;
 
 typedef struct {

+ 18 - 3
components/esp32/include/esp_wifi.h

@@ -122,6 +122,10 @@ esp_err_t esp_wifi_connect(void);
 
 esp_err_t esp_wifi_disconnect(void);
 
+esp_err_t esp_wifi_clear_fast_connect(void);
+
+esp_err_t esp_wifi_kick_station(uint16_t aid);
+
 typedef struct {
     char *ssid;          /**< SSID of AP */
     uint8_t *bssid;      /**< MAC address of AP */
@@ -129,7 +133,7 @@ typedef struct {
     bool show_hidden;   /**< enable to scan AP whose SSID is hidden */
 } wifi_scan_config_t;
 
-esp_err_t esp_wifi_scan_start(wifi_scan_config_t *conf);
+esp_err_t esp_wifi_scan_start(wifi_scan_config_t *conf, bool block);
 
 esp_err_t esp_wifi_scan_stop(void);
 
@@ -140,7 +144,7 @@ typedef struct {
     uint8_t ssid[32];                     /**< SSID of AP */
     uint8_t primary;                      /**< channel of AP */
     wifi_second_chan_t second;            /**< second channel of AP */
-    char    rssi;                         /**< single strength of AP */
+    signed char rssi;                         /**< single strength of AP */
     wifi_auth_mode_t authmode;            /**< authmode of AP */
 }wifi_ap_list_t;
 
@@ -188,7 +192,7 @@ esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]);
 
 typedef void (* wifi_promiscuous_cb_t)(void *buf, uint16_t len);
 
-wifi_promiscuous_cb_t wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
+esp_err_t esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
 
 esp_err_t esp_wifi_set_promiscuous(uint8_t enable);
 
@@ -230,10 +234,21 @@ esp_err_t esp_wifi_get_station_list(struct station_info **station);
 
 esp_err_t esp_wifi_free_station_list(void);
 
+typedef enum {
+    WIFI_STORAGE_RAM,
+    WIFI_STORAGE_FLASH,
+} wifi_storage_t;
+
+esp_err_t esp_wifi_set_storage(wifi_storage_t storage);
+
 typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void* eb);
 
 esp_err_t esp_wifi_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);
 
+esp_err_t esp_wifi_set_auto_connect(bool en);
+
+esp_err_t esp_wifi_get_auto_connect(bool *en);
+
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
components/esp32/lib

@@ -1 +1 @@
-Subproject commit 468c510da96fd7176788fec75fa9ac37bf37ef34
+Subproject commit fbb084dacc51f9c02889acb9bd3b4a0a68144fc4

+ 3 - 1
components/esp32/wifi.c

@@ -69,12 +69,14 @@ static void esp_wifi_task(void *pvParameters)
 
 #if CONFIG_WIFI_AUTO_CONNECT
         wifi_mode_t mode;
+        bool auto_connect;
         err = esp_wifi_get_mode(&mode);
         if (err != ESP_OK){
             WIFI_DEBUG("esp_wifi_get_mode fail, ret=%d\n", err);
         }
 
-        if (mode == WIFI_MODE_STA || mode == WIFI_MODE_APSTA) {
+        err = esp_wifi_get_auto_connect(&auto_connect);
+        if ((mode == WIFI_MODE_STA || mode == WIFI_MODE_APSTA) && auto_connect) {
             err = esp_wifi_connect();
             if (err != ESP_OK) {
                 WIFI_DEBUG("esp_wifi_connect fail, ret=%d\n", err);

+ 1 - 1
components/lwip/api/tcpip.c

@@ -62,7 +62,7 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
 
 /* global variables */
 #ifdef PERF
-uint32 g_rx_post_mbox_fail_cnt = 0;
+uint32_t g_rx_post_mbox_fail_cnt = 0;
 #endif
 static tcpip_init_done_fn tcpip_init_done;
 static void *tcpip_init_done_arg;

+ 854 - 2164
components/lwip/apps/dhcpserver.c

@@ -20,19 +20,12 @@
 #include "lwip/udp.h"
 #include "lwip/mem.h"
 #include "lwip/ip_addr.h"
-#include "apps/dhcpserver.h"
-
 #include "tcpip_adapter.h"
 
-#ifdef LWIP_ESP8266
+#include "apps/dhcpserver.h"
 
-enum dyc_dhcps_flags{
-	DHCPS_STARTED = 0x00,
-	DHCPS_STOP = 0x01,
-	_END
-} DhcpsFlags = DHCPS_STOP;
+#ifdef LWIP_ESP8266
 
-#define DHCPS_MAX_LEASE 0x64
 #define BOOTP_BROADCAST 0x8000
 
 #define DHCP_REQUEST        1
@@ -69,9 +62,6 @@ enum dyc_dhcps_flags{
 #define DHCPS_DEBUG          0
 #define DHCPS_LOG printf
 
-#define DYC_DHCP_CRASH //printf
-
-
 #define MAX_STATION_NUM      8
 
 #define DHCPS_STATE_OFFER 1
@@ -81,27 +71,13 @@ enum dyc_dhcps_flags{
 #define DHCPS_STATE_IDLE 5
 #define DHCPS_STATE_RELEASE 6
 
-
-
 #ifdef MEMLEAK_DEBUG
 static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__;
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////////
-//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 const u32_t magic_cookie = 0x63538263;
-//static const char magic_cookie[] = {0x63,0x82,0x53,0x63};
-//static const u32_t magic_cookie = 0x63538263;
-//static const u32_t magic_cookie_temp  = 0x63538263;
-
-/*
-ip_2_ip4(ipaddr)
-IP_IS_V6(dest)
-IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4)    
-*/
 
+static const u32_t magic_cookie  = 0x63538263;
 
 static struct udp_pcb *pcb_dhcps = NULL;
 static ip4_addr_t  broadcast_dhcps;
@@ -109,2397 +85,1111 @@ static ip4_addr_t server_address;
 static ip4_addr_t client_address;        //added
 static ip4_addr_t 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 bool renew = false;
-#define DHCPS_LEASE_TIME_DEF	(120)
-u32_t dhcps_lease_time = DHCPS_LEASE_TIME_DEF;  //minute
 
+static dhcps_lease_t dhcps_poll;
+static dhcps_offer_t dhcps_offer = 0xFF;
+static dhcps_time_t dhcps_lease_time = DHCPS_LEASE_TIME_DEF;  //minute
 
-
-static enum dyc_dhcps_flags get_dhcps_status(void )
+/******************************************************************************
+ * 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)
 {
-    return DhcpsFlags;
+    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;
+
+        default:
+            break;
+    }
+
+    return option_arg;
 }
+
 /******************************************************************************
  * 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)
+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;
-	if (*phead == NULL)
-		*phead = pinsert;
-	else {
-		plist = *phead;
-		pdhcps_node = pinsert->pnode;
-		pdhcps_pool = plist->pnode;
-
-		if(pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
-		    pinsert->pnext = plist;
-		    *phead = pinsert;
-		} else {
+    list_node *plist = NULL;
+    struct dhcps_pool *pdhcps_pool = NULL;
+    struct dhcps_pool *pdhcps_node = NULL;
+
+    if (*phead == NULL) {
+        *phead = pinsert;
+    } else {
+        plist = *phead;
+        pdhcps_node = pinsert->pnode;
+        pdhcps_pool = plist->pnode;
+
+        if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
+            pinsert->pnext = plist;
+            *phead = pinsert;
+        } else {
             while (plist->pnext != NULL) {
                 pdhcps_pool = plist->pnext->pnode;
+
                 if (pdhcps_node->ip.addr < pdhcps_pool->ip.addr) {
                     pinsert->pnext = plist->pnext;
                     plist->pnext = pinsert;
                     break;
                 }
+
                 plist = plist->pnext;
             }
 
-            if(plist->pnext == NULL) {
+            if (plist->pnext == NULL) {
                 plist->pnext = pinsert;
             }
-		}
-	}
+        }
+    }
+
 //	pinsert->pnext = NULL;
 }
 
 /******************************************************************************
  * 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)
-{
-	list_node *plist = NULL;
-
-	plist = *phead;
-	if (plist == NULL){
-		*phead = NULL;
-	} else {
-		if (plist == pdelete){
-			*phead = plist->pnext;
-			pdelete->pnext = NULL;
-		} else {
-			while (plist != NULL) {
-				if (plist->pnext == pdelete){
-					plist->pnext = pdelete->pnext;
-					pdelete->pnext = NULL;
-				}
-				plist = plist->pnext;
-			}
-		}
-	}
+void node_remove_from_list(list_node **phead, list_node *pdelete)
+{
+    list_node *plist = NULL;
+
+    plist = *phead;
+
+    if (plist == NULL) {
+        *phead = NULL;
+    } else {
+        if (plist == pdelete) {
+            *phead = plist->pnext;
+            pdelete->pnext = NULL;
+        } else {
+            while (plist != NULL) {
+                if (plist->pnext == pdelete) {
+                    plist->pnext = pdelete->pnext;
+                    pdelete->pnext = NULL;
+                }
+
+                plist = plist->pnext;
+            }
+        }
+    }
 }
-///////////////////////////////////////////////////////////////////////////////////
-/*
- * ��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;
+    *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)
+
+/******************************************************************************
+ * 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;
+    ip4_addr_t ipadd;
 
-        ipadd.addr = *( (u32_t *) &server_address);
+    ipadd.addr = *((u32_t *) &server_address);
 
 #ifdef USE_CLASS_B_NET
-        *optptr++ = DHCP_OPTION_SUBNET_MASK;
-        *optptr++ = 4;  //length
-        *optptr++ = 255;
-        *optptr++ = 240;	
-        *optptr++ = 0;
-        *optptr++ = 0;
+    *optptr++ = DHCP_OPTION_SUBNET_MASK;
+    *optptr++ = 4;  //length
+    *optptr++ = 255;
+    *optptr++ = 240;
+    *optptr++ = 0;
+    *optptr++ = 0;
 #else
-        *optptr++ = DHCP_OPTION_SUBNET_MASK;
-        *optptr++ = 4;  
-        *optptr++ = 255;
-        *optptr++ = 255;	
-        *optptr++ = 255;
-        *optptr++ = 0;
+    *optptr++ = DHCP_OPTION_SUBNET_MASK;
+    *optptr++ = 4;
+    *optptr++ = 255;
+    *optptr++ = 255;
+    *optptr++ = 255;
+    *optptr++ = 0;
 #endif
 
-        *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++ = DHCP_OPTION_SERVER_ID;
-        *optptr++ = 4;  
-        *optptr++ = ip4_addr1( &ipadd);
-        *optptr++ = ip4_addr2( &ipadd);
-        *optptr++ = ip4_addr3( &ipadd);
-        *optptr++ = ip4_addr4( &ipadd);
-
-        if (dhcps_router_enabled(offer)){
-        	struct ip_info if_ip;
-		//bzero(&if_ip, sizeof(struct ip_info));
-              memset(&if_ip ,0x00, sizeof(struct ip_info));
-        
-		tcpip_adapter_get_ip_info(WIFI_IF_AP, &if_ip);
-
-		*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);
-        }
+    *optptr++ = DHCP_OPTION_LEASE_TIME;
+    *optptr++ = 4;
+    *optptr++ = ((dhcps_lease_time * 60) >> 24) & 0xFF;
+    *optptr++ = ((dhcps_lease_time * 60) >> 16) & 0xFF;
+    *optptr++ = ((dhcps_lease_time * 60) >> 8) & 0xFF;
+    *optptr++ = ((dhcps_lease_time * 60) >> 0) & 0xFF;
+
+    *optptr++ = DHCP_OPTION_SERVER_ID;
+    *optptr++ = 4;
+    *optptr++ = ip4_addr1(&ipadd);
+    *optptr++ = ip4_addr2(&ipadd);
+    *optptr++ = ip4_addr3(&ipadd);
+    *optptr++ = ip4_addr4(&ipadd);
+
+    if (dhcps_router_enabled(dhcps_offer)) {
+        struct ip_info if_ip;
+        //bzero(&if_ip, sizeof(struct ip_info));
+        memset(&if_ip , 0x00, sizeof(struct ip_info));
+
+        tcpip_adapter_get_ip_info(WIFI_IF_AP, &if_ip);
+
+        *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);
+    *optptr++ = DHCP_OPTION_DNS_SERVER;
+    *optptr++ = 4;
+    *optptr++ = ip4_addr1(&ipadd);
+    *optptr++ = ip4_addr2(&ipadd);
+    *optptr++ = ip4_addr3(&ipadd);
+    *optptr++ = ip4_addr4(&ipadd);
 #endif
 
 #ifdef CLASS_B_NET
-        *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
-        *optptr++ = 4;  
-        *optptr++ = ip4_addr1( &ipadd);
-        *optptr++ = 255;
-        *optptr++ = 255;
-        *optptr++ = 255;
+    *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
+    *optptr++ = 4;
+    *optptr++ = ip4_addr1(&ipadd);
+    *optptr++ = 255;
+    *optptr++ = 255;
+    *optptr++ = 255;
 #else
-        *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
-        *optptr++ = 4;  
-        *optptr++ = ip4_addr1( &ipadd);
-        *optptr++ = ip4_addr2( &ipadd);
-        *optptr++ = ip4_addr3( &ipadd);
-        *optptr++ = 255;
+    *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS;
+    *optptr++ = 4;
+    *optptr++ = ip4_addr1(&ipadd);
+    *optptr++ = ip4_addr2(&ipadd);
+    *optptr++ = ip4_addr3(&ipadd);
+    *optptr++ = 255;
 #endif
 
-        *optptr++ = DHCP_OPTION_INTERFACE_MTU;
-        *optptr++ = 2;  
+    *optptr++ = DHCP_OPTION_INTERFACE_MTU;
+    *optptr++ = 2;
 #ifdef CLASS_B_NET
-        *optptr++ = 0x05;	
-        *optptr++ = 0xdc;
+    *optptr++ = 0x05;
+    *optptr++ = 0xdc;
 #else
-        *optptr++ = 0x02;	
-        *optptr++ = 0x40;
+    *optptr++ = 0x02;
+    *optptr++ = 0x40;
 #endif
 
-        *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY;
-        *optptr++ = 1;  
-        *optptr++ = 0x00; 
+    *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY;
+    *optptr++ = 1;
+    *optptr++ = 0x00;
 
-        *optptr++ = 43;	
-        *optptr++ = 6;	
+    *optptr++ = 43;
+    *optptr++ = 6;
 
-        *optptr++ = 0x01;	
-        *optptr++ = 4;  
-        *optptr++ = 0x00;
-        *optptr++ = 0x00;
-        *optptr++ = 0x00;
-        *optptr++ = 0x02; 	
+    *optptr++ = 0x01;
+    *optptr++ = 4;
+    *optptr++ = 0x00;
+    *optptr++ = 0x00;
+    *optptr++ = 0x00;
+    *optptr++ = 0x02;
 
-        return optptr;
+    return optptr;
 }
-///////////////////////////////////////////////////////////////////////////////////
-/*
- * ��DHCP msg�ṹ����ӽ����־����
- *
- * @param optptr -- DHCP msg��Ϣλ��
- *
- * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ
- */
-///////////////////////////////////////////////////////////////////////////////////
-static u8_t* add_end(u8_t *optptr)
-{
 
-        *optptr++ = DHCP_OPTION_END;
-        return 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;
 }
-///////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////
+
+/******************************************************************************
+ * 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;
+    ip4_addr_t client;
 
 
-        client.addr = *( (uint32_t *) &client_address);
+    client.addr = *((uint32_t *) &client_address);
 
-        m->op = DHCP_REPLY;
+    m->op = DHCP_REPLY;
 
-        m->htype = DHCP_HTYPE_ETHERNET;
+    m->htype = DHCP_HTYPE_ETHERNET;
 
-        m->hlen = 6;  
+    m->hlen = 6;
 
-        m->hops = 0;
+    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));
+    m->secs = 0;
+    m->flags = htons(BOOTP_BROADCAST);
 
-        memset((char *) m->ciaddr, 0, sizeof(m->ciaddr));
+    memcpy((char *) m->yiaddr, (char *) &client.addr, sizeof(m->yiaddr));
 
-        memset((char *) m->siaddr, 0, sizeof(m->siaddr));
+    memset((char *) m->ciaddr, 0, sizeof(m->ciaddr));
 
-        memset((char *) m->giaddr, 0, sizeof(m->giaddr));
+    memset((char *) m->siaddr, 0, sizeof(m->siaddr));
 
-        memset((char *) m->sname, 0, sizeof(m->sname));
+    memset((char *) m->giaddr, 0, sizeof(m->giaddr));
 
-        memset((char *) m->file, 0, sizeof(m->file));
+    memset((char *) m->sname, 0, sizeof(m->sname));
 
-        memset((char *) m->options, 0, sizeof(m->options));
-        
-//        u32_t temp  = 0x63538263;
- //       u8 *log_temp = (u8 *)&temp;
-//DYC_DHCP_CRASH("l:%0x,%0x,%0x,%0x,",log_temp[0],log_temp[1],log_temp[2],log_temp[3]);
+    memset((char *) m->file, 0, sizeof(m->file));
 
-u32_t magic_cookie_temp = magic_cookie;
+    memset((char *) m->options, 0, sizeof(m->options));
 
-//extern bool system_get_string_from_flash(void *flash_str, void* ram_str,uint8 ram_str_len);
-//system_get_string_from_flash((void *)(&magic_cookie), (void *)(&magic_cookie_temp),4);
-//printf("ck_tmp3:%08X\n",magic_cookie_temp);
+    u32_t magic_cookie_temp = magic_cookie;
 
-        //memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie));
-        memcpy((char *) m->options, &magic_cookie_temp, sizeof(magic_cookie_temp));
-//        DYC_DHCP_CRASH("m,");
+    memcpy((char *) m->options, &magic_cookie_temp, sizeof(magic_cookie_temp));
 }
-///////////////////////////////////////////////////////////////////////////////////
-/*
- * ����һ��OFFER
- *
- * @param -- m ָ����Ҫ���͵�DHCP msg����
- */
-///////////////////////////////////////////////////////////////////////////////////
+
+/******************************************************************************
+ * FunctionName : send_offer
+ * Description  : DHCP message OFFER Response
+ * Parameters   : m -- DHCP message info
+ * Returns      : none
+*******************************************************************************/
 static void send_offer(struct dhcps_msg *m)
 {
-        u8_t *end;
-	    struct pbuf *p, *q;
-	    u8_t *data;
-	    u16_t cnt=0;
-	    u16_t i;
-		err_t SendOffer_err_t;
-        create_msg(m);
-
-        end = add_msg_type(&m->options[4], DHCPOFFER);
-        end = add_offer_options(end);
-        end = add_end(end);
-
-	    p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM);
+    u8_t *end;
+    struct pbuf *p, *q;
+    u8_t *data;
+    u16_t cnt = 0;
+    u16_t i;
+    err_t SendOffer_err_t;
+    create_msg(m);
+
+    end = add_msg_type(&m->options[4], DHCPOFFER);
+    end = add_offer_options(end);
+    end = add_end(end);
+
+    p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM);
 #if DHCPS_DEBUG
-		DHCPS_LOG("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 (p != NULL) {
+
 #if DHCPS_DEBUG
-	        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);
+        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;
-	            for(i=0; i<q->len; i++)
-	            {
-	                data[i] = ((u8_t *) m)[cnt++];
+        q = p;
+
+        while (q != NULL) {
+            data = (u8_t *)q->payload;
+
+            for (i = 0; i < q->len; i++) {
+                data[i] = ((u8_t *) m)[cnt++];
 #if DHCPS_DEBUG
-					DHCPS_LOG("%02x ",data[i]);
-					if((i+1)%16 == 0){
-						DHCPS_LOG("\n");
-					}
+                DHCPS_LOG("%02x ", data[i]);
+
+                if ((i + 1) % 16 == 0) {
+                    DHCPS_LOG("\n");
+                }
+
 #endif
-	            }
+            }
+
+            q = q->next;
+        }
+    } else {
 
-	            q = q->next;
-	        }
-	    }else{
-	        
 #if DHCPS_DEBUG
-	        DHCPS_LOG("dhcps: send_offer>>pbuf_alloc failed\n");
+        DHCPS_LOG("dhcps: send_offer>>pbuf_alloc failed\n");
 #endif
-	        return;
-	    }
-        
-        ip_addr_t ip_temp = IPADDR4_INIT(0x0);
-        ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
-                SendOffer_err_t = udp_sendto( pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT );
+        return;
+    }
+
+    ip_addr_t ip_temp = IPADDR4_INIT(0x0);
+    ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
+    SendOffer_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
 #if DHCPS_DEBUG
-	        DHCPS_LOG("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t);
+    DHCPS_LOG("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t);
 #endif
-	    if(p->ref != 0){	
+
+    if (p->ref != 0) {
 #if DHCPS_DEBUG
-	        DHCPS_LOG("udhcp: send_offer>>free pbuf\n");
+        DHCPS_LOG("udhcp: send_offer>>free pbuf\n");
 #endif
-	        pbuf_free(p);
-	    }
+        pbuf_free(p);
+    }
 }
-///////////////////////////////////////////////////////////////////////////////////
-/*
- * ����һ��NAK��Ϣ
- *
- * @param m ָ����Ҫ���͵�DHCP msg����
- */
-///////////////////////////////////////////////////////////////////////////////////
+
+/******************************************************************************
+ * FunctionName : send_nak
+ * Description  : DHCP message NACK Response
+ * Parameters   : m -- DHCP message info
+ * Returns      : none
+*******************************************************************************/
 static void send_nak(struct dhcps_msg *m)
 {
-        u8_t *end;
-        struct pbuf *p, *q;
-        u8_t *data;
-        u16_t cnt=0;
-        u16_t i;
-        err_t SendNak_err_t;
-        create_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);
+    u8_t *end;
+    struct pbuf *p, *q;
+    u8_t *data;
+    u16_t cnt = 0;
+    u16_t i;
+    err_t SendNak_err_t;
+    create_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);
 #if DHCPS_DEBUG
-		DHCPS_LOG("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 (p != NULL) {
+
 #if DHCPS_DEBUG
-	        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);
+        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;
-	            for(i=0; i<q->len; i++)
-	            {
-	                data[i] = ((u8_t *) m)[cnt++];
-#if DHCPS_DEBUG					
-					DHCPS_LOG("%02x ",data[i]);
-					if((i+1)%16 == 0){
-						DHCPS_LOG("\n");
-					}
+        q = p;
+
+        while (q != NULL) {
+            data = (u8_t *)q->payload;
+
+            for (i = 0; i < q->len; i++) {
+                data[i] = ((u8_t *) m)[cnt++];
+#if DHCPS_DEBUG
+                DHCPS_LOG("%02x ", data[i]);
+
+                if ((i + 1) % 16 == 0) {
+                    DHCPS_LOG("\n");
+                }
+
 #endif
-	            }
+            }
+
+            q = q->next;
+        }
+    } else {
 
-	            q = q->next;
-	        }
-	    }else{
-	        
 #if DHCPS_DEBUG
-	        DHCPS_LOG("dhcps: send_nak>>pbuf_alloc failed\n");
+        DHCPS_LOG("dhcps: send_nak>>pbuf_alloc failed\n");
 #endif
-	        return;
-    	}
+        return;
+    }
 
-        ip_addr_t ip_temp = IPADDR4_INIT(0x0);
-        ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);       
-        SendNak_err_t = udp_sendto( pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT );
+    ip_addr_t ip_temp = IPADDR4_INIT(0x0);
+    ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
+    SendNak_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
 #if DHCPS_DEBUG
-	        DHCPS_LOG("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t);
+    DHCPS_LOG("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t);
 #endif
- 	    if(p->ref != 0){
-#if DHCPS_DEBUG			
-	        DHCPS_LOG("udhcp: send_nak>>free pbuf\n");
+
+    if (p->ref != 0) {
+#if DHCPS_DEBUG
+        DHCPS_LOG("udhcp: send_nak>>free pbuf\n");
 #endif
-	        pbuf_free(p);
-	    }
+        pbuf_free(p);
+    }
 }
-///////////////////////////////////////////////////////////////////////////////////
-/*
- * ����һ��ACK��DHCP�ͻ���
- *
- * @param m ָ����Ҫ���͵�DHCP msg����
- */
-///////////////////////////////////////////////////////////////////////////////////
+
+/******************************************************************************
+ * FunctionName : send_ack
+ * Description  : DHCP message ACK Response
+ * Parameters   : m -- DHCP message info
+ * Returns      : none
+*******************************************************************************/
 static void send_ack(struct dhcps_msg *m)
 {
-        u8_t *end;
-        struct pbuf *p, *q;
-        u8_t *data;
-        u16_t cnt=0;
-        u16_t i;
-        err_t SendAck_err_t;
-        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);
+    u8_t *end;
+    struct pbuf *p, *q;
+    u8_t *data;
+    u16_t cnt = 0;
+    u16_t i;
+    err_t SendAck_err_t;
+    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);
 #if DHCPS_DEBUG
-		DHCPS_LOG("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 (p != NULL) {
+
 #if DHCPS_DEBUG
-	        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);
+        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;
-	            for(i=0; i<q->len; i++)
-	            {
-	                data[i] = ((u8_t *) m)[cnt++];
-#if DHCPS_DEBUG					
-					DHCPS_LOG("%02x ",data[i]);
-					if((i+1)%16 == 0){
-						DHCPS_LOG("\n");
-					}
+        q = p;
+
+        while (q != NULL) {
+            data = (u8_t *)q->payload;
+
+            for (i = 0; i < q->len; i++) {
+                data[i] = ((u8_t *) m)[cnt++];
+#if DHCPS_DEBUG
+                DHCPS_LOG("%02x ", data[i]);
+
+                if ((i + 1) % 16 == 0) {
+                    DHCPS_LOG("\n");
+                }
+
 #endif
-	            }
+            }
+
+            q = q->next;
+        }
+    } else {
 
-	            q = q->next;
-	        }
-	    }else{
-	    
 #if DHCPS_DEBUG
-	        DHCPS_LOG("dhcps: send_ack>>pbuf_alloc failed\n");
+        DHCPS_LOG("dhcps: send_ack>>pbuf_alloc failed\n");
 #endif
-	        return;
-	    }
+        return;
+    }
 
-        ip_addr_t ip_temp = IPADDR4_INIT(0x0);
-        ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);   
-        SendAck_err_t = udp_sendto( pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT );
+    ip_addr_t ip_temp = IPADDR4_INIT(0x0);
+    ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
+    SendAck_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
 #if DHCPS_DEBUG
-	        DHCPS_LOG("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t);
+    DHCPS_LOG("dhcps: send_ack>>udp_sendto result %x\n", SendAck_err_t);
 #endif
-	    
-	    if(p->ref != 0){
+
+    if (p->ref != 0) {
 #if DHCPS_DEBUG
-	        DHCPS_LOG("udhcp: send_ack>>free pbuf\n");
+        DHCPS_LOG("udhcp: send_ack>>free pbuf\n");
 #endif
-	        pbuf_free(p);
-	    }
+        pbuf_free(p);
+    }
 }
-///////////////////////////////////////////////////////////////////////////////////
-/*
- * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ��
- *
- * @param optptr DHCP msg���������
- * @param len ��������Ĵ��?(byte)
- *
- * @return uint8_t ���ش�����DHCP Server״ֵ̬
- */
-///////////////////////////////////////////////////////////////////////////////////
+
+/******************************************************************************
+ * 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)
 {
-       ip4_addr_t client;
-    	bool is_dhcp_parse_end = false;
-    	struct dhcps_state s;
+    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;
-        u16_t type = 0;
+    u8_t *end = optptr + len;
+    u16_t type = 0;
 
-        s.state = DHCPS_STATE_IDLE;
+    s.state = DHCPS_STATE_IDLE;
 
-        while (optptr < end) {
+    while (optptr < end) {
 #if DHCPS_DEBUG
-        	DHCPS_LOG("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) {
 
-                case DHCP_OPTION_MSG_TYPE:	//53
-                        type = *(optptr + 2);
-                        break;
+        switch ((s16_t) *optptr) {
+
+            case DHCP_OPTION_MSG_TYPE:	//53
+                type = *(optptr + 2);
+                break;
 
-                case DHCP_OPTION_REQ_IPADDR://50
-                        if( memcmp( (char *) &client.addr, (char *) optptr+2,4)==0 ) {
+            case DHCP_OPTION_REQ_IPADDR://50
+                if (memcmp((char *) &client.addr, (char *) optptr + 2, 4) == 0) {
 #if DHCPS_DEBUG
-                    		DHCPS_LOG("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 {
+                    s.state = DHCPS_STATE_ACK;
+                } else {
 #if DHCPS_DEBUG
-                    		DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n");
+                    DHCPS_LOG("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n");
 #endif
-                            s.state = DHCPS_STATE_NAK;
-                        }
-                        break;
-                case DHCP_OPTION_END:
-			            {
-			                is_dhcp_parse_end = true;
-			            }
-                        break;
-            }
+                    s.state = DHCPS_STATE_NAK;
+                }
+
+                break;
 
-		    if(is_dhcp_parse_end){
-		            break;
-		    }
+            case DHCP_OPTION_END: {
+                is_dhcp_parse_end = true;
+            }
+            break;
+        }
 
-            optptr += optptr[1] + 2;
+        if (is_dhcp_parse_end) {
+            break;
         }
 
-        switch (type){
-        
-        	case DHCPDISCOVER://1
-                s.state = DHCPS_STATE_OFFER;
+        optptr += optptr[1] + 2;
+    }
+
+    switch (type) {
+
+        case DHCPDISCOVER://1
+            s.state = DHCPS_STATE_OFFER;
 #if DHCPS_DEBUG
-            	DHCPS_LOG("dhcps: DHCPD_STATE_OFFER\n");
+            DHCPS_LOG("dhcps: DHCPD_STATE_OFFER\n");
 #endif
-                break;
+            break;
+
+        case DHCPREQUEST://3
+            if (!(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK)) {
+                if (renew == true) {
+                    s.state = DHCPS_STATE_ACK;
+                } else {
+                    s.state = DHCPS_STATE_NAK;
+                }
 
-        	case DHCPREQUEST://3
-                if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) {
-                    if(renew == true) {
-                        s.state = DHCPS_STATE_ACK;
-                    } else {
-                        s.state = DHCPS_STATE_NAK;
-                    }
 #if DHCPS_DEBUG
-                		DHCPS_LOG("dhcps: DHCPD_STATE_NAK\n");
+                DHCPS_LOG("dhcps: DHCPD_STATE_NAK\n");
 #endif
-                }
-                break;
+            }
+
+            break;
 
-			case DHCPDECLINE://4
-                s.state = DHCPS_STATE_IDLE;
+        case DHCPDECLINE://4
+            s.state = DHCPS_STATE_IDLE;
 #if DHCPS_DEBUG
-            	DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
+            DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
 #endif
-                break;
+            break;
 
-        	case DHCPRELEASE://7
-                s.state = DHCPS_STATE_RELEASE;
+        case DHCPRELEASE://7
+            s.state = DHCPS_STATE_RELEASE;
 #if DHCPS_DEBUG
-            	DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
+            DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
 #endif
-                break;
-        }
+            break;
+    }
+
 #if DHCPS_DEBUG
-    	DHCPS_LOG("dhcps: return s.state = %d\n", s.state);
+    DHCPS_LOG("dhcps: return s.state = %d\n", s.state);
 #endif
-        return s.state;
+    return s.state;
 }
-///////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////
+
+/******************************************************************************
+ * 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 magic_cookie_temp = magic_cookie;
-//extern bool system_get_string_from_flash(void *flash_str, void* ram_str,uint8 ram_str_len);
-//system_get_string_from_flash((void *)(&magic_cookie), (void *)(&magic_cookie_temp),4);
-//printf("ck_tmp4:%08X\n",magic_cookie_temp);
-
-		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
-        	        DHCPS_LOG("dhcps: len = %d\n", len);
+        DHCPS_LOG("dhcps: len = %d\n", len);
 #endif
+        ip4_addr_t addr_tmp;
+
+        struct dhcps_pool *pdhcps_pool = NULL;
+        list_node *pnode = NULL;
+        list_node *pback_node = NULL;
+        ip4_addr_t first_address;
+        bool flag = false;
+
+        first_address.addr = dhcps_poll.start_ip.addr;
+        client_address.addr = client_address_plus.addr;
+        renew = false;
+
+        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) {
+                    if (memcmp(&pdhcps_pool->ip.addr, m->ciaddr, sizeof(pdhcps_pool->ip.addr)) == 0) {
+                        renew = true;
+                    }
+
+                    client_address.addr = pdhcps_pool->ip.addr;
+                    pdhcps_pool->lease_timer = dhcps_lease_time;
+                    pnode = pback_node;
+                    goto POOL_CHECK;
+                } else if (pdhcps_pool->ip.addr == client_address_plus.addr) {
+                    addr_tmp.addr = htonl(client_address_plus.addr);
+                    addr_tmp.addr++;
+                    client_address_plus.addr = htonl(addr_tmp.addr);
+                    client_address.addr = client_address_plus.addr;
+                }
+
+                if (flag == false) { // search the fisrt unused ip
+                    if (first_address.addr < pdhcps_pool->ip.addr) {
+                        flag = true;
+                    } else {
+                        addr_tmp.addr = htonl(first_address.addr);
+                        addr_tmp.addr++;
+                        first_address.addr = htonl(addr_tmp.addr);
+                    }
+                }
+            }
+        } else {
+            client_address.addr = dhcps_poll.start_ip.addr;
+        }
+
+        if (client_address_plus.addr > dhcps_poll.end_ip.addr) {
+            client_address.addr = first_address.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 *)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 = dhcps_lease_time;
+            pnode = (list_node *)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_poll.end_ip.addr) {
+                client_address_plus.addr = dhcps_poll.start_ip.addr;
+            } else {
+                addr_tmp.addr = htonl(client_address.addr);
+                addr_tmp.addr++;
+                client_address_plus.addr = htonl(addr_tmp.addr);
+            }
+        }
+
+POOL_CHECK:
+
+        if ((client_address.addr > dhcps_poll.end_ip.addr) || (ip4_addr_isany(&client_address))) {
+            if (pnode != NULL) {
+                node_remove_from_list(&plist, pnode);
+                free(pnode);
+                pnode = NULL;
+            }
+
+            if (pdhcps_pool != NULL) {
+                free(pdhcps_pool);
+                pdhcps_pool = NULL;
+            }
+
+            return 4;
+        }
+
+        s16_t ret = parse_options(&m->options[4], len);;
+
+        if (ret == DHCPS_STATE_RELEASE) {
+            if (pnode != NULL) {
+                node_remove_from_list(&plist, pnode);
+                free(pnode);
+                pnode = NULL;
+            }
+
+            if (pdhcps_pool != NULL) {
+                free(pdhcps_pool);
+                pdhcps_pool = NULL;
+            }
 
-	              ip4_addr_t addr_tmp;    
-//	                memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid));
-
-			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;
-			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);
-			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;
-					}
-					client_address.addr = pdhcps_pool->ip.addr;
-					pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER;
-					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);
-					client_address.addr = client_address_plus.addr;
-				}
-
-				if(flag == false) { // search the fisrt unused ip
-                                    if(first_address.addr < pdhcps_pool->ip.addr) {
-                                        flag = true;
-                                    } else {
-                                        addr_tmp.addr = htonl(first_address.addr);
-                                        addr_tmp.addr++;
-                                        first_address.addr = htonl(addr_tmp.addr);
-                                    }
-				}
-			}
-			if (client_address_plus.addr > dhcps_lease.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;
-			    pdhcps_pool = NULL;
-			    pnode = NULL;
-			} else {
-        			pdhcps_pool = (struct dhcps_pool *)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 = DHCPS_LEASE_TIMER;
-        			pnode = (list_node *)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;
-                            } else {
-                                    addr_tmp.addr = htonl(client_address.addr);
-                                    addr_tmp.addr++;
-                                    client_address_plus.addr = htonl(addr_tmp.addr);
-                            }
-			}
-
-			POOL_CHECK:
-			if ((client_address.addr > dhcps_lease.end_ip.addr) || (ip4_addr_isany(&client_address))){
-			    if(pnode != NULL) {
-			        node_remove_from_list(&plist,pnode);
-			        free(pnode);
-			        pnode = NULL;
-			    }
-
-			    if (pdhcps_pool != NULL) {
-			        free(pdhcps_pool);
-			        pdhcps_pool = NULL;
-			    }
-// client_address_plus.addr = dhcps_lease.start_ip.addr;
-				return 4;
-			}
-
-			s16_t ret = parse_options(&m->options[4], len);;
-
-			if(ret == DHCPS_STATE_RELEASE) {
-			    if(pnode != NULL) {
-			        node_remove_from_list(&plist,pnode);
-			        free(pnode);
-			        pnode = NULL;
-			    }
-
-			    if (pdhcps_pool != NULL) {
-			        free(pdhcps_pool);
-			        pdhcps_pool = NULL;
-			    }
-			    memset(&client_address,0x0,sizeof(client_address));
-			}
-
-//TO_DO ,  set (ap-> sta)   ip_addr   no use.
-//if ( tcpip_dep_set_ip_info(STATION_IF, struct ip_info *if_ip) == false )
-    //return 0;
-//if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) {
-   // return 0;
+            memset(&client_address, 0x0, sizeof(client_address));
+        }
 
 #if DHCPS_DEBUG
-	                DHCPS_LOG("dhcps: xid changed\n");
-	                DHCPS_LOG("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;
-}
+        return ret;
+    }
 
+    return 0;
+}
 
+/******************************************************************************
+ * 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;
-        u16_t i;
-        u16_t dhcps_msg_cnt=0;
-        u8_t *p_dhcps_msg = NULL;
-        u8_t *data;
+                        struct udp_pcb *pcb,
+                        struct pbuf *p,
+                        const ip_addr_t *addr,
+                        u16_t port)
+{
+    struct dhcps_msg *pmsg_dhcps = NULL;
+    s16_t tlen;
+    u16_t i;
+    u16_t dhcps_msg_cnt = 0;
+    u8_t *p_dhcps_msg = NULL;
+    u8_t *data;
 
 #if DHCPS_DEBUG
-    	DHCPS_LOG("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 *)malloc(sizeof(struct dhcps_msg));
-           memset(pmsg_dhcps ,0x00 ,sizeof(struct dhcps_msg));
-        
-	    if (NULL == pmsg_dhcps){
-	    	pbuf_free(p);
-	    	return;
-	    }
-	    p_dhcps_msg = (u8_t *)pmsg_dhcps;
-		tlen = p->tot_len;
-	    data = p->payload;
+
+    if (p == NULL) {
+        return;
+    }
+
+    pmsg_dhcps = (struct dhcps_msg *)malloc(sizeof(struct dhcps_msg));
+    memset(pmsg_dhcps , 0x00 , sizeof(struct dhcps_msg));
+
+    if (NULL == pmsg_dhcps) {
+        pbuf_free(p);
+        return;
+    }
+
+    p_dhcps_msg = (u8_t *)pmsg_dhcps;
+    tlen = p->tot_len;
+    data = p->payload;
 
 #if DHCPS_DEBUG
-	    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					
-			DHCPS_LOG("%02x ",data[i]);
-			if((i+1)%16 == 0){
-				DHCPS_LOG("\n");
-			}
+    DHCPS_LOG("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen);
+    DHCPS_LOG("dhcps: handle_dhcp-> p->len = %d\n", p->len);
 #endif
-	    }
-		
-		if(p->next != NULL) {
+
+    for (i = 0; i < p->len; i++) {
+        p_dhcps_msg[dhcps_msg_cnt++] = data[i];
 #if DHCPS_DEBUG
-	        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;
-	        for(i=0; i<p->next->len; i++){
-	            p_dhcps_msg[dhcps_msg_cnt++] = data[i];
-#if DHCPS_DEBUG					
-				DHCPS_LOG("%02x ",data[i]);
-				if((i+1)%16 == 0){
-					DHCPS_LOG("\n");
-				}
+        DHCPS_LOG("%02x ", data[i]);
+
+        if ((i + 1) % 16 == 0) {
+            DHCPS_LOG("\n");
+        }
+
 #endif
-			}
-		}
+    }
 
-		/*
-	     * DHCP �ͻ���������Ϣ����
-	    */
+    if (p->next != NULL) {
 #if DHCPS_DEBUG
-    	DHCPS_LOG("dhcps: handle_dhcp-> parse_msg(p)\n");
+        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
-		
-        switch(parse_msg(pmsg_dhcps, tlen - 240)) {
-	        case DHCPS_STATE_OFFER://1 
-#if DHCPS_DEBUG            
-            	 DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n");
-#endif			
-	             send_offer(pmsg_dhcps);
-	             break;
-	        case DHCPS_STATE_ACK://3
+
+        data = p->next->payload;
+
+        for (i = 0; i < p->next->len; i++) {
+            p_dhcps_msg[dhcps_msg_cnt++] = data[i];
 #if DHCPS_DEBUG
-            	 DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
-#endif			
-	             send_ack(pmsg_dhcps);
-	             break;
-	        case DHCPS_STATE_NAK://4
-#if DHCPS_DEBUG            
-            	 DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
+            DHCPS_LOG("%02x ", data[i]);
+
+            if ((i + 1) % 16 == 0) {
+                DHCPS_LOG("\n");
+            }
+
 #endif
-	             send_nak(pmsg_dhcps);
-	             break;
-		default :
-				 break;
         }
+    }
+
 #if DHCPS_DEBUG
-    	DHCPS_LOG("dhcps: handle_dhcp-> pbuf_free(p)\n");
+    DHCPS_LOG("dhcps: handle_dhcp-> parse_msg(p)\n");
 #endif
-        pbuf_free(p);
-        free(pmsg_dhcps);
-        pmsg_dhcps = NULL;
-}
-///////////////////////////////////////////////////////////////////////////////////
-static void wifi_softap_init_dhcps_lease(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) {
-		softap_ip = htonl(ip);
-		start_ip = htonl(dhcps_lease.start_ip.addr);
-		end_ip = htonl(dhcps_lease.end_ip.addr);
-		/*config ip information can't contain local ip*/
-		if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
-			dhcps_lease.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;
-			}
-		}
-	}
-
-	if (dhcps_lease.enable == false) {
-		local_ip = softap_ip = htonl(ip);
-		softap_ip &= 0xFFFFFF00;
-		local_ip &= 0xFF;
-		if (local_ip >= 0x80)
-			local_ip -= DHCPS_MAX_LEASE;
-		else
-			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);
-	}
-//	printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip);
-}
 
+    switch (parse_msg(pmsg_dhcps, tlen - 240)) {
+        case DHCPS_STATE_OFFER://1
+#if DHCPS_DEBUG
+            DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n");
+#endif
+            send_offer(pmsg_dhcps);
+            break;
 
-///////////////////////////////////////////////////////////////////////////////////
-void dhcps_start(struct netif *netif)
-{
-	struct netif * apnetif =netif;
-
-
-	if(apnetif->dhcps_pcb != NULL) {
-            udp_remove(apnetif->dhcps_pcb);
-       }
-	pcb_dhcps = udp_new();
-	if (pcb_dhcps == NULL) {
-		printf("dhcps_start(): could not obtain pcb\n");
-	}
-	apnetif->dhcps_pcb = pcb_dhcps;
-
-	IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255);
-
-	server_address = netif->ip_addr.u_addr.ip4;
-	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);
-	udp_recv(pcb_dhcps, handle_dhcp, NULL);
+        case DHCPS_STATE_ACK://3
 #if DHCPS_DEBUG
-	DHCPS_LOG("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n");
+            DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n");
 #endif
-        DhcpsFlags = DHCPS_STARTED;
+            send_ack(pmsg_dhcps);
+            break;
 
-}
+        case DHCPS_STATE_NAK://4
+#if DHCPS_DEBUG
+            DHCPS_LOG("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n");
+#endif
+            send_nak(pmsg_dhcps);
+            break;
 
-void dhcps_stop(struct netif *netif )
-{
-    struct netif * apnetif = netif;
-    if(apnetif == NULL)
-    {
-        printf("dhcps_stop: apnetif == NULL\n");
-        return;
-    }
-    udp_disconnect(pcb_dhcps);
-//	dhcps_lease_flag = true;
-    if(apnetif->dhcps_pcb != NULL) {
-        udp_remove(apnetif->dhcps_pcb);
-        apnetif->dhcps_pcb = NULL;
-    }
-
-    list_node *pnode = NULL;
-    list_node *pback_node = NULL;
-    pnode = plist;
-    while (pnode != NULL) {
-        pback_node = pnode;
-        pnode = pback_node->pnext;
-        node_remove_from_list(&plist, pback_node);
-        free(pback_node->pnode);
-        pback_node->pnode = NULL;
-        free(pback_node);
-        pback_node = NULL;
+        default :
+            break;
     }
-    DhcpsFlags = DHCPS_STOP;
-}
-
-bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please)
-{
 
-//  NOT USE
-	struct ip_info info;
-	u32_t softap_ip = 0;
-	u32_t start_ip = 0;
-	u32_t end_ip = 0;
-    
-	//uint8 opmode = wifi_get_opmode();
-       //uint8 opmode = 0;
-	//if (opmode == STATION_MODE || opmode == NULL_MODE) {
-		//return false;
-	//}
- 	if (please == NULL || get_dhcps_status() == DHCPS_STARTED)
-		return false;
-
-	if(please->enable) {
-              struct ip_info ip_info;
-        	memset(&ip_info, 0x00, sizeof(struct ip_info));
-              tcpip_adapter_get_ip_info(WIFI_IF_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;
-
-    	       memset(&dhcps_lease, 0x00, 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;
+#if DHCPS_DEBUG
+    DHCPS_LOG("dhcps: handle_dhcp-> pbuf_free(p)\n");
+#endif
+    pbuf_free(p);
+    free(pmsg_dhcps);
+    pmsg_dhcps = NULL;
 }
 
 /******************************************************************************
- * 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 : dhcps_poll_set
+ * Description  : set ip poll from start to end for station
+ * Parameters   : ip -- The current ip addr
+ * Returns      : none
 *******************************************************************************/
-bool wifi_softap_get_dhcps_lease(struct dhcps_lease *please)
-{
-
-	if (NULL == please)
-		return false;
-	if (dhcps_lease.enable == false){
-		if (get_dhcps_status() == DHCPS_STOP)
-			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;
-	pre = plist;
-	p = pre->pnext;
-	minpre = pre;
-	minp = p;
-	while (p != NULL){
-		pdhcps_pool = p->pnode;
-		pmin_pool = minp->pnode;
-		if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){
-			minp = p;
-			minpre = pre;
-		}
-		pre = p;
-		p = p->pnext;
-	}
-	minpre->pnext = minp->pnext;
-	free(minp->pnode);
-	minp->pnode = NULL;
-	free(minp);
-	minp = NULL;
-}
-
-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;
-	pnode = plist;
-	while (pnode != NULL) {
-		pdhcps_pool = pnode->pnode;
-		pdhcps_pool->lease_timer --;
-		if (pdhcps_pool->lease_timer == 0){
-			pback_node = pnode;
-			pnode = pback_node->pnext;
-			node_remove_from_list(&plist,pback_node);
-			free(pback_node->pnode);
-			pback_node->pnode = NULL;
-			free(pback_node);
-			pback_node = NULL;
-		} else {
-			pnode = pnode ->pnext;
-			num_dhcps_pool ++;
-		}
-	}
-
-	if (num_dhcps_pool >= MAX_STATION_NUM)
-		kill_oldest_dhcps_pool();
-}
-
-bool wifi_softap_set_dhcps_offer_option(u8_t level, void* optarg)
-{
-	bool offer_flag = true;
-	u8_t option = 0;
-
-	if (optarg == NULL && get_dhcps_status() == false)
-		return false;
-
-	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;
-			break;
-	}
-	return offer_flag;
-}
-
-bool wifi_softap_set_dhcps_lease_time(u32_t minute)
-{
-
-    if (get_dhcps_status() == DHCPS_STARTED) {
-        return false;
-    }
-
-    if(minute == 0) {
-        return false;
-    }
-    dhcps_lease_time = minute;
-    return true;
-}
-
-bool wifi_softap_reset_dhcps_lease_time(void)
-{
-
-    if (get_dhcps_status() == DHCPS_STARTED) {
-        return false;
-    }
-    dhcps_lease_time = DHCPS_LEASE_TIME_DEF;
-    return true;
-}
-
-u32_t wifi_softap_get_dhcps_lease_time(void) // minute
-{
-    return dhcps_lease_time;
-}
-
-/* Search ip address based on mac address */
-bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip)
-{
-    struct dhcps_pool *pdhcps_pool = NULL;
-    list_node *pback_node = NULL;
-    bool ret = false;
-    
-    for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) {
-        pdhcps_pool = pback_node->pnode;
-        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 ret;
-}
-#else
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include "lwip/sys.h"
-#include <netdb.h>
-#include <errno.h>
-static os_timer_t micros_overflow_timer;
-static uint32_t micros_at_last_overflow_tick = 0;
-static uint32_t micros_overflow_count = 0;
-
-void micros_overflow_tick(void* arg)
-{
-    uint32_t m = system_get_time();
-    if(m < micros_at_last_overflow_tick)
-        ++micros_overflow_count;
-    micros_at_last_overflow_tick = m;
-}
-
-unsigned long  millis()
-{
-    uint32_t m = system_get_time();
-    uint32_t c = micros_overflow_count + ((m < micros_at_last_overflow_tick) ? 1 : 0);
-    return c * 4294967 + m / 1000;
-}
-
-unsigned long  micros()
-{
-    return system_get_time();
-}
-
-void dhcps_set_default_time(void)
-{
-	os_timer_disarm(&micros_overflow_timer);
-    os_timer_setfn(&micros_overflow_timer, (os_timer_func_t*) &micros_overflow_tick, 0);
-    os_timer_arm(&micros_overflow_timer, 60000, 1);
-}
-
-time_t time(time_t * t)
-{
-    time_t seconds = millis();
-    if (t)
-    {
-        *t = seconds;
-    }
-    return seconds;
-}
-
-/*
- * Initialize the binding list.
- */
-
-void
-dhcp_binding_list_init (binding_list *list)
-{
-    STAILQ_INIT(list);
-}
-
-/*
- * Create a new binding
- *
- * The binding is added to the binding list,
- * and a pointer to the binding is returned for further manipulations.
- */
-
-address_binding *
-dhcp_binding_add (binding_list *list, uint32_t address, uint8_t *cident, uint8_t cident_len, int is_static)
-{
-    // fill binding
-    address_binding *binding = calloc(1, sizeof(*binding));
-
-    binding->address = address;
-    binding->cident_len = cident_len;
-    memcpy(binding->cident, cident, cident_len);
-
-    binding->is_static = is_static;
-
-    // add to binding list
-    STAILQ_INSERT_HEAD(list, binding, pointers);
-
-    return binding;
-}
-
-/*
- * Updated bindings status, i.e. set to EXPIRED the status of the
- * expired bindings.
- */
-
-void
-dhcp_binding_statuses_update (binding_list *list)
-{
-    address_binding *binding, *binding_temp;
-
-    STAILQ_FOREACH_SAFE(binding, list, pointers, binding_temp)
-    {
-        if(binding->binding_time + binding->lease_time < time(NULL))
-        {
-            binding->status = EXPIRED;
-        }
-    }
-}
-
-/*
- * Search a static or dynamic binding having the given client identifier.
- *
- * If the is_static option is true a static binding will be searched,
- * otherwise a dynamic one. If status is not zero, an binding with that
- * status will be searched.
- */
-
-address_binding *
-dhcp_binding_search (binding_list *list, uint8_t *cident, uint8_t cident_len, int is_static, int status)
-{
-    address_binding *binding, *binding_temp;
-
-    STAILQ_FOREACH_SAFE(binding, list, pointers, binding_temp)
-    {
-        if((binding->is_static == is_static || is_static == STATIC_OR_DYNAMIC) &&
-           binding->cident_len == cident_len &&
-           memcmp(binding->cident, cident, cident_len) == 0)
-        {
-            if(status == 0)
-                return binding;
-            else if(status == binding->status)
-                return binding;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Get an available free address
- *
- * If a zero address is returned, no more address are available.
- */
-
-static uint32_t
-dhcp_binding_take_free_address (pool_indexes *indexes)
-{
-    if(indexes->current <= indexes->last)
-    {
-        uint32_t address = indexes->current;
-        indexes->current = htonl(ntohl(indexes->current) + 1);
-        return address;
-
-    }
-    else
-        return 0;
-}
-
-/*
- * Create a new dynamic binding or reuse an expired one.
- *
- * An attemp will be made to assign to the client the requested IP address
- * contained in the address option. An address equals to zero means that no
- * specific address has been requested.
- *
- * If the dynamic pool of addresses is full a NULL pointer will be returned.
- */
-
-address_binding *
-dhcp_binding_new_dynamic (binding_list *list, pool_indexes *indexes, uint32_t address, uint8_t *cident, uint8_t cident_len)
-{
-    address_binding *binding, *binding_temp;
-    address_binding *found_binding = NULL;
-
-    if (address != 0)
-    {
-
-        STAILQ_FOREACH_SAFE(binding, list, pointers, binding_temp)
-        {
-            // search a previous binding using the requested IP address
-
-            if(binding->address == address)
-            {
-                found_binding = binding;
-                break;
+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_poll.enable == true) {
+        softap_ip = htonl(ip);
+        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_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_poll.enable = false;
             }
         }
     }
 
-    if(found_binding != NULL &&
-       !found_binding->is_static &&
-       found_binding->status != PENDING &&
-       found_binding->status != ASSOCIATED)
-    {
-
-        // the requested IP address is available (reuse an expired association)
-        return found_binding;
-
-    }
-    else
-    {
-
-        /* the requested IP address is already in use, or no address has been
-               requested, or the address requested has never been allocated
-               (we do not support this last case and just return the next
-               available address!). */
-
-        uint32_t address = dhcp_binding_take_free_address(indexes);
-
-        if(address != 0)
-            return dhcp_binding_add(list, address, cident, cident_len, 0);
-
-        else   // search any previously assigned address which is expired
-        {
+    if (dhcps_poll.enable == false) {
+        local_ip = softap_ip = htonl(ip);
+        softap_ip &= 0xFFFFFF00;
+        local_ip &= 0xFF;
 
-            STAILQ_FOREACH_SAFE(binding, list, pointers, binding_temp)
-            {
-                if(!binding->is_static &&
-                   found_binding->status != PENDING &&
-                   found_binding->status != ASSOCIATED)
-                    return binding;
-            }
-
-            // if executions reach here no more addresses are available
-            return NULL;
+        if (local_ip >= 0x80) {
+            local_ip -= DHCPS_MAX_LEASE;
+        } else {
+            local_ip ++;
         }
-    }
-}
-
-/*
- * Delete an binding list and deallocate its memory.
- * Deallocate even the list elements.
- */
-
-static void
-dhcp_binding_list_delete (binding_list *list)
-{
-    address_binding *opt = STAILQ_FIRST(list);
-    address_binding *tmp;
-
-    while (opt != NULL)
-    {
-        tmp = STAILQ_NEXT(opt, pointers);
-        free(opt);
-        opt = tmp;
-    }
-
-    STAILQ_INIT(list);
-}
-
-/* Value parsing functions:
- *
- * Parse the string pointed by s, and allocate the
- * pointer p to contain the parsed data.
- *
- * On success return the size of the parsed data,
- * on error return zero.
- */
-
-static  int dhcp_option_byte (char *s, void **p);
-static  int dhcp_option_byte_list (char *s, void **p);
-static  int dhcp_option_short (char *s, void **p);
-static  int dhcp_option_short_list (char *s, void **p);
-static  int dhcp_option_long (char *s, void **p);
-static  int dhcp_option_string (char *s, void **p);
-static  int dhcp_option_ip (char *s, void **p);
-static  int dhcp_option_ip_list (char *s, void **p);
-
-/* Global pool */
-static  const uint8_t dhcp_option_magic[4] = {0x63, 0x82, 0x53, 0x63};
-static address_pool dhcp_address_pool = {0};
-
-/*
- * Mapping table between DHCP options and
- * functions that parse their value.
- */
-static struct
-{
-    char *name;
-    int (*f) (char *, void **);
-} dhcp_option_info [256] =
-{
-    [PAD] { "PAD", NULL },
-    [END] { "END", NULL },
-    [SUBNET_MASK] { "SUBNET_MASK", dhcp_option_ip },
-    [TIME_OFFSET] { "TIME_OFFSET", dhcp_option_long },
-    [ROUTER] { "ROUTER", dhcp_option_ip_list },
-    [TIME_SERVER] { "TIME_SERVER", dhcp_option_ip_list },
-    [NAME_SERVER] { "NAME_SERVER", dhcp_option_ip_list },
-    [DOMAIN_NAME_SERVER] { "DOMAIN_NAME_SERVER", dhcp_option_ip_list },
-    [LOG_SERVER] { "LOG_SERVER", dhcp_option_ip_list },
-    [COOKIE_SERVER] { "COOKIE_SERVER", dhcp_option_ip_list },
-    [LPR_SERVER] { "LPR_SERVER", dhcp_option_ip_list },
-    [IMPRESS_SERVER] { "IMPRESS_SERVER", dhcp_option_ip_list },
-    [RESOURCE_LOCATION_SERVER] { "RESOURCE_LOCATION_SERVER", dhcp_option_ip_list },
-    [HOST_NAME] { "HOST_NAME", dhcp_option_string },
-    [BOOT_FILE_SIZE] { "BOOT_FILE_SIZE", dhcp_option_short },
-    [MERIT_DUMP_FILE] { "MERIT_DUMP_FILE", dhcp_option_string },
-    [DOMAIN_NAME] { "DOMAIN_NAME", dhcp_option_string },
-    [SWAP_SERVER] { "SWAP_SERVER", dhcp_option_ip },
-    [ROOT_PATH] { "ROOT_PATH", dhcp_option_string },
-    [EXTENSIONS_PATH] { "EXTENSIONS_PATH", dhcp_option_string },
-    [IP_FORWARDING] { "IP_FORWARDING", dhcp_option_byte },
-    [NON_LOCAL_SOURCE_ROUTING] { "NON_LOCAL_SOURCE_ROUTING", dhcp_option_byte },
-    [POLICY_FILTER] { "POLICY_FILTER", dhcp_option_ip_list },
-    [MAXIMUM_DATAGRAM_REASSEMBLY_SIZE] { "MAXIMUM_DATAGRAM_REASSEMBLY_SIZE", dhcp_option_short },
-    [DEFAULT_IP_TIME_TO_LIVE] { "DEFAULT_IP_TIME_TO_LIVE", dhcp_option_byte },
-    [PATH_MTU_AGING_TIMEOUT] { "PATH_MTU_AGING_TIMEOUT", dhcp_option_long },
-    [PATH_MTU_PLATEAU_TABLE] { "PATH_MTU_PLATEAU_TABLE", dhcp_option_short_list },
-    [INTERFACE_MTU] { "INTERFACE_MTU", dhcp_option_short },
-    [ALL_SUBNETS_ARE_LOCAL] { "ALL_SUBNETS_ARE_LOCAL", dhcp_option_byte },
-    [BROADCAST_ADDRESS] { "BROADCAST_ADDRESS", dhcp_option_ip },
-    [PERFORM_MASK_DISCOVERY] { "PERFORM_MASK_DISCOVERY", dhcp_option_byte },
-    [MASK_SUPPLIER] { "MASK_SUPPLIER", dhcp_option_byte },
-    [PERFORM_ROUTER_DISCOVERY] { "PERFORM_ROUTER_DISCOVERY", dhcp_option_byte },
-    [ROUTER_SOLICITATION_ADDRESS] { "ROUTER_SOLICITATION_ADDRESS", dhcp_option_ip },
-    [STATIC_ROUTE] { "STATIC_ROUTE", dhcp_option_ip_list },
-    [TRAILER_ENCAPSULATION] { "TRAILER_ENCAPSULATION", dhcp_option_byte },
-    [ARP_CACHE_TIMEOUT] { "ARP_CACHE_TIMEOUT", dhcp_option_long },
-    [ETHERNET_ENCAPSULATION] { "ETHERNET_ENCAPSULATION", dhcp_option_byte },
-    [TCP_DEFAULT_TTL] { "TCP_DEFAULT_TTL", dhcp_option_byte },
-    [TCP_KEEPALIVE_INTERVAL] { "TCP_KEEPALIVE_INTERVAL", dhcp_option_long },
-    [TCP_KEEPALIVE_GARBAGE] { "TCP_KEEPALIVE_GARBAGE", dhcp_option_byte },
-    [NETWORK_INFORMATION_SERVICE_DOMAIN] { "NETWORK_INFORMATION_SERVICE_DOMAIN", dhcp_option_string },
-    [NETWORK_INFORMATION_SERVERS] { "NETWORK_INFORMATION_SERVERS", dhcp_option_ip_list },
-    [NETWORK_TIME_PROTOCOL_SERVERS] { "NETWORK_TIME_PROTOCOL_SERVERS", dhcp_option_ip_list },
-    [VENDOR_SPECIFIC_INFORMATION] { "VENDOR_SPECIFIC_INFORMATION", dhcp_option_byte_list },
-    [NETBIOS_OVER_TCP_IP_NAME_SERVER] { "NETBIOS_OVER_TCP_IP_NAME_SERVER", dhcp_option_ip_list },
-    [NETBIOS_OVER_TCP_IP_DATAGRAM_DISTRIBUTION_SERVER] { "NETBIOS_OVER_TCP_IP_DATAGRAM_DISTRIBUTION_SERVER", dhcp_option_ip_list },
-    [NETBIOS_OVER_TCP_IP_NODE_TYPE] { "NETBIOS_OVER_TCP_IP_NODE_TYPE", dhcp_option_byte },
-    [NETBIOS_OVER_TCP_IP_SCOPE] { "NETBIOS_OVER_TCP_IP_SCOPE", dhcp_option_string },
-    [X_WINDOW_SYSTEM_FONT_SERVER] { "X_WINDOW_SYSTEM_FONT_SERVER", dhcp_option_ip_list },
-    [X_WINDOW_SYSTEM_DISPLAY_MANAGER] { "X_WINDOW_SYSTEM_DISPLAY_MANAGER", dhcp_option_ip_list },
-    [NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN] { "NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN", dhcp_option_string },
-    [NETWORK_INFORMATION_SERVICE_PLUS_SERVERS] { "NETWORK_INFORMATION_SERVICE_PLUS_SERVERS", dhcp_option_ip_list },
-    [MOBILE_IP_HOME_AGENT] { "MOBILE_IP_HOME_AGENT", dhcp_option_ip_list },
-    [SMTP_SERVER] { "SMTP_SERVER", dhcp_option_ip_list },
-    [POP3_SERVER] { "POP3_SERVER", dhcp_option_ip_list },
-    [NNTP_SERVER] { "NNTP_SERVER", dhcp_option_ip_list },
-    [DEFAULT_WWW_SERVER] { "DEFAULT_WWW_SERVER", dhcp_option_ip_list },
-    [DEFAULT_FINGER_SERVER] { "DEFAULT_FINGER_SERVER", dhcp_option_ip_list },
-    [DEFAULT_IRC_SERVER] { "DEFAULT_IRC_SERVER", dhcp_option_ip_list },
-    [STREETTALK_SERVER] { "STREETTALK_SERVER", dhcp_option_ip_list },
-    [STREETTALK_DIRECTORY_ASSISTANCE_SERVER] { "STREETTALK_DIRECTORY_ASSISTANCE_SERVER",  dhcp_option_ip_list },
-    [REQUESTED_IP_ADDRESS] { "REQUESTED_IP_ADDRESS", NULL },
-    [IP_ADDRESS_LEASE_TIME] { "IP_ADDRESS_LEASE_TIME", dhcp_option_long },
-    [OPTION_OVERLOAD] { "OPTION_OVERLOAD", dhcp_option_byte },
-    [TFTP_SERVER_NAME] { "TFTP_SERVER_NAME", dhcp_option_string },
-    [BOOTFILE_NAME] { "BOOTFILE_NAME", dhcp_option_string },
-    [DHCP_MESSAGE_TYPE] { "DHCP_MESSAGE_TYPE", NULL },
-    [SERVER_IDENTIFIER] { "SERVER_IDENTIFIER", dhcp_option_ip },
-    [PARAMETER_REQUEST_LIST] { "PARAMETER_REQUEST_LIST", NULL },
-    [MESSAGE] { "MESSAGE", NULL },
-    [MAXIMUM_DHCP_MESSAGE_SIZE] { "MAXIMUM_DHCP_MESSAGE_SIZE", NULL },
-    [RENEWAL_T1_TIME_VALUE] { "RENEWAL_T1_TIME_VALUE", dhcp_option_long },
-    [REBINDING_T2_TIME_VALUE] { "REBINDING_T2_TIME_VALUE", dhcp_option_long },
-    [VENDOR_CLASS_IDENTIFIER] { "VENDOR_CLASS_IDENTIFIER", NULL },
-    [CLIENT_IDENTIFIER] { "CLIENT_IDENTIFIER", NULL },
-
-    [USER_CLASS] { "USER_CLASS", NULL },
-    [FQDN] { "FQDN", NULL },
-    [DHCP_AGENT_OPTIONS] { "DHCP_AGENT_OPTIONS", NULL },
-    [NDS_SERVERS] { "NDS_SERVERS", NULL },
-    [NDS_TREE_NAME] { "NDS_TREE_NAME", NULL },
-    [NDS_CONTEXT] { "NDS_CONTEXT", NULL },
-    [CLIENT_LAST_TRANSACTION_TIME] { "CLIENT_LAST_TRANSACTION_TIME", NULL },
-    [ASSOCIATED_IP] { "ASSOCIATED_IP", NULL },
-    [USER_AUTHENTICATION_PROTOCOL] { "USER_AUTHENTICATION_PROTOCOL", NULL },
-    [AUTO_CONFIGURE] { "AUTO_CONFIGURE", NULL },
-    [NAME_SERVICE_SEARCH] { "NAME_SERVICE_SEARCH", dhcp_option_string },
-    [SUBNET_SELECTION] { "SUBNET_SELECTION", NULL },
-    [DOMAIN_SEARCH] { "DOMAIN_SEARCH", dhcp_option_string },
-    [CLASSLESS_ROUTE] { "CLASSLESS_ROUTE", dhcp_option_string },
-};
-
-/* Value parsing functions */
-
-static int
-dhcp_option_byte (char *s, void **p)
-{
-    *p = malloc(sizeof(uint8_t));
-    uint8_t n = ((uint8_t) strtol(s, NULL, 0));
-    memcpy(*p, &n, sizeof(n));
-
-    return sizeof(uint8_t);
-}
-
-static int
-dhcp_option_byte_list (char *s, void **p)
-{
-    *p = malloc(strlen(s) * sizeof(uint8_t)); // slightly over the strictly requested size
-
-    int count = 0;
-
-    char *s2 = strdup(s);
-    char *s3 = strtok(s2, ", ");
-
-    while(s3 != NULL)
-    {
-
-        uint8_t n = ((uint8_t) strtol(s3, NULL, 0));
-
-        memcpy(((uint8_t *) *p) + count, &n, sizeof(uint8_t));
-
-        count += sizeof(uint8_t);
-        s3 = strtok(NULL, " ");
-    }
-
-    free(s2);
-
-    return count;
-}
-
-static int
-dhcp_option_short (char *s, void **p)
-{
-    *p = malloc(sizeof(uint16_t));
-    uint16_t n = ((uint16_t) strtol(s, NULL, 0));
-    memcpy(*p, &n, sizeof(n));
-
-    return sizeof(uint16_t);
-}
-
-static int
-dhcp_option_short_list (char *s, void **p)
-{
-    *p = malloc(strlen(s) * sizeof(uint16_t)); // slightly over the strictly requested size
-
-    int count = 0;
-
-    char *s2 = strdup(s);
-    char *s3 = strtok(s2, ", ");
-
-    while(s3 != NULL)
-    {
-
-        uint16_t n = ((uint16_t) strtol(s3, NULL, 0));
-
-        memcpy(((uint8_t *) *p) + count, &n, sizeof(uint16_t));
-
-        count += sizeof(uint16_t);
-        s3 = strtok(NULL, " ");
-    }
-
-    free(s2);
-
-    return count;
-}
-
-static int
-dhcp_option_long (char *s, void **p)
-{
-    *p = malloc(sizeof(uint32_t));
-    uint32_t n = strtol(s, NULL, 0);
-    memcpy(*p, &n, sizeof(n));
-
-    return sizeof(uint32_t);
-}
-
-static int
-dhcp_option_string (char *s, void **p)
-{
-    *p = strdup(s);
-
-    return strlen(s);
-}
-
-static int
-dhcp_option_ip (char *s, void **p)
-{
-    struct sockaddr_in ip;
-
-    *p = malloc(sizeof(uint32_t));
-
-    if (inet_aton(s, &ip.sin_addr) == 0)   // error: invalid IP address
-    {
-        free(*p);
-        return 0;
-    }
-
-    memcpy(*p, &ip.sin_addr, sizeof(uint32_t));
-
-    return sizeof(uint32_t);
-}
-
-static int
-dhcp_option_ip_list (char *s, void **p)
-{
-    *p = malloc(strlen(s) * sizeof(uint32_t) / 4); // slightly over the strictly required size
-
-    int count = 0;
-
-    char *s2 = strdup(s);
-    char *s3 = strtok(s2, ", ");
-
-    while(s3 != NULL)
-    {
-        struct sockaddr_in ip;
-
-        if (inet_aton(s3, &ip.sin_addr) == 0)   // error: invalid IP address
-        {
-            free(*p);
-            return 0;
-        }
-
-        memcpy(((uint8_t *) *p) + count, &ip.sin_addr, sizeof(uint32_t));
-
-        count += sizeof(uint32_t);
-        s3 = strtok(NULL, " ");
-    }
-
-    free(s2);
-
-    return count;
-}
-
-/* Option-related functions */
-
-/*
- * Given the name of the option and its value as strings,
- * fill the dhcp_option structure pointed by opt.
- *
- * On success return the parsed option id,
- * otherwise return zero.
- */
-static uint8_t
-dhcp_option_parse (dhcp_option *opt, char *name, char *value)
-{
-    int (*f) (char *, void **);
-    int id;
-
-    uint8_t len;
-    uint8_t *p;
-
-    for (id = 0; id < 256; id++)   // search the option by name
-    {
-        if (dhcp_option_info[id].name &&
-            strcmp(dhcp_option_info[id].name, name) == 0) break;
-    }
-
-    if (id == 256)   // not found
-    {
-        log_info("Unsupported DHCP option '%s'", name);
-        return 0;
-    }
-
-    f = dhcp_option_info[id].f;
-
-    if (f == NULL)   // no parsing function available
-    {
-        log_info("Unsupported DHCP option '%s'", name);
-        return 0;
-    }
-
-    len = f(value, (void **)&p); // parse the value
-
-    if(len == 0) // error parsing the value
-        return 0;
-
-    // structure filling
-    opt->id = id;
-    opt->len = len;
-    memcpy(opt->data, p, len);
-
-    free(p);
-
-    return opt->id;
-}
-
-/*
- * Initialize an option list.
- */
-
-static void
-dhcp_option_list_init (dhcp_option_list *list)
-{
-    STAILQ_INIT(list);
-}
-
-/*
- * Given a list of options search an option having
- * the passed option id, and returns a pointer to it.
- *
- * If the option is not present the function returns NULL.
- */
-
-static dhcp_option *
-dhcp_option_search (dhcp_option_list *list, uint8_t id)
-{
-    dhcp_option *opt, *opt_temp;
-
-    STAILQ_FOREACH_SAFE(opt, list, pointers, opt_temp)
-    {
-
-        if(opt->id == id)
-            return opt;
-
-    }
-
-    return NULL;
-}
 
-/*
- * Print options in list.
- */
-
-static void
-dhcp_option_print (dhcp_option_list *list)
-{
-    dhcp_option *opt, *opt_temp;
-    int i=0;
-
-    STAILQ_FOREACH_SAFE(opt, list, pointers, opt_temp)
-    {
-
-        printf("options[%d]=%d (%s)\n", i++, opt->id,
-               dhcp_option_info[opt->id].name);
-
-    }
-}
-
-
-/*
- * Append the provided option to the list.
- *
- * Always allocate new memory, that must be freed later...
- */
-
-static void
-dhcp_option_append (dhcp_option_list *list, dhcp_option *opt)
-{
-    dhcp_option *nopt = calloc(1, sizeof(*nopt));
-    memcpy(nopt, opt, 2 + opt->len);
-
-    STAILQ_INSERT_TAIL(list, nopt, pointers);
-}
-
-/*
- * Parse the options contained in a DHCP message into a list.
- *
- * Return 1 on success, 0 if the options are malformed.
- */
-
-static int
-dhcp_option_parse_to_list (dhcp_option_list *list, dhcp_option *opts, size_t len)
-{
-    dhcp_option *opt, *end;
-
-    opt = opts;
-    end = (dhcp_option *)(((uint8_t *)opts) + len);
-
-    if (len < 4 ||
-        memcmp(opt, dhcp_option_magic, sizeof(dhcp_option_magic)) != 0)
-        return 0;
-
-    opt = (dhcp_option *)(((uint8_t *) opt) + 4);
-
-    while (opt < end  &&
-           opt->id != END)   // TODO: check also valid option sizes
-    {
-
-        if ((dhcp_option *)(((uint8_t *) opt) + 2 + opt->len) >= end)
-            return 0; // the len field is too long
-
-        dhcp_option_append(list, opt);
-
-        opt = (dhcp_option *)(((uint8_t *) opt) + 2 + opt->len);
+        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);
     }
 
-    if (opt < end && opt->id == END)
-        return 1;
-
-    return 0;
 }
 
-/*
- * Serialize a list of options, to be inserted directly inside
- * the options section of a DHCP message.
- *
- * Return 0 on error, the total serialized len on success.
- */
-
-static size_t
-dhcp_option_list_serialize (dhcp_option_list *list, uint8_t *buf, size_t len)
-{
-    uint8_t *p = buf;
-
-    if (len < 4)
-        return 0;
-
-    memcpy(p, dhcp_option_magic, sizeof(dhcp_option_magic));
-    p += 4;
-    len -= 4;
-
-    dhcp_option *opt, *opt_temp;
-
-    STAILQ_FOREACH_SAFE(opt, list, pointers, opt_temp)
-    {
-
-        if (len <= 2 + opt->len)
-            return 0;
-
-        memcpy(p, opt, 2 + opt->len);
-        p   += 2 + opt->len;
-        len -= 2 + opt->len;
-
-    }
-
-    if (len < 1)
-        return 0;
-
-    *p = END;
-
-    p++;
-    len--;
-
-    return p - buf;
-}
-
-/*
- * Delete an option list and deallocate its memory.
- * Deallocate even the list elements.
- */
-
-static void
-dhcp_option_list_delete (dhcp_option_list *list)
-{
-    dhcp_option *opt = STAILQ_FIRST(list);
-    dhcp_option *tmp;
-
-    while (opt != NULL)
-    {
-        tmp = STAILQ_NEXT(opt, pointers);
-        free(opt);
-        opt = tmp;
-    }
-
-    STAILQ_INIT(list);
-}
-
-static void dhcp_options_default_fill(dhcp_option_list *list, dhcp_option_list *reply_opts)
+/******************************************************************************
+ * 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, struct ip_info *info)
 {
-    dhcp_option *opt, *opt_temp;
-    int i = 0;
+    struct netif *apnetif = netif;
 
-    STAILQ_FOREACH_SAFE(opt, list, pointers, opt_temp)
-    {
-        log_info("options[%d]=%d (%s)\n", i++, opt->id, dhcp_option_info[opt->id].name);
 
-        if (opt != NULL)
-            dhcp_option_append(reply_opts, opt);
+    if (apnetif->dhcps_pcb != NULL) {
+        udp_remove(apnetif->dhcps_pcb);
     }
-}
 
-static void
-dhcp_options_requested_fill (dhcp_option *requested_opts, dhcp_option_list *reply_opts)
-{
-    uint8_t len = requested_opts->len;
-    uint8_t *id = requested_opts->data;
-
-    int i = 0;
-    for (i = 0; i < len; i++)
-    {
-        if(id[i] != 0)
-        {
-            dhcp_option *opt = dhcp_option_search(&dhcp_address_pool.options, id[i]);
-
-            if(opt != NULL)
-                dhcp_option_append(reply_opts, opt);
-        }
-    }
-    dhcp_option_print(reply_opts);
-}
+    pcb_dhcps = udp_new();
 
-static bool dhcp_options_add(char* name, char* value)
-{
-    uint8_t id = 0;
-    bool flags = true;
-    REQUIRE_ACTION(name, add_error, flags = false);
-    REQUIRE_ACTION(value, add_error, flags = false);
-    dhcp_option *option = calloc(1, sizeof(*option));
-    REQUIRE_ACTION(option, add_error, flags = false);
-    id = dhcp_option_parse(option, name, value);
-    if (id == 0)
-    {
-        log_info( "error: invalid dhcp option specified: %s,%s",name, value);
-        REQUIRE_ACTION(option, add_error, flags = false);
+    if (pcb_dhcps == NULL || info == NULL) {
+        printf("dhcps_start(): could not obtain pcb\n");
     }
 
-    dhcp_option_append(&dhcp_address_pool.options, option);
+    apnetif->dhcps_pcb = pcb_dhcps;
 
-    if(option->id == IP_ADDRESS_LEASE_TIME)
-        dhcp_address_pool.lease_time = ntohl(*((uint32_t *)option->data));
+    IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255);
 
-add_error:
-    free(option);
-    return flags;
-}
+    server_address = info->ip;
+    dhcps_poll_set(server_address.addr);
 
-/*
- * Message handling routines.
- */
+    client_address_plus.addr = dhcps_poll.start_ip.addr;
 
-static uint8_t dhcp_request_expand (dhcps_msg *request, size_t len)
-{
-    dhcp_option_list_init(&request->opts);
-
-    if (request->hdr.hlen < 1 || request->hdr.hlen > 16)
-        return 0;
-
-    if (dhcp_option_parse_to_list(&request->opts, (dhcp_option *)request->hdr.options, len - DHCP_HEADER_SIZE) == 0)
-        return 0;
-
-    dhcp_option *type_opt = dhcp_option_search(&request->opts, DHCP_MESSAGE_TYPE);
-
-    if (type_opt == NULL)
-        return 0;
-
-    uint8_t type = type_opt->data[0];
-
-    return type;
-}
-
-static int
-dhcp_reply_init (dhcps_msg *request, dhcps_msg *reply)
-{
-    memset(&reply->hdr, 0, sizeof(reply->hdr));
-
-    dhcp_option_list_init(&reply->opts);
-
-    reply->hdr.op = BOOTREPLY;
-
-    reply->hdr.htype = request->hdr.htype;
-    reply->hdr.hlen  = request->hdr.hlen;
-
-    reply->hdr.xid   = request->hdr.xid;
-    reply->hdr.flags = request->hdr.flags;
-
-    reply->hdr.giaddr = request->hdr.giaddr;
-
-    memcpy(reply->hdr.chaddr, request->hdr.chaddr, request->hdr.hlen);
+    udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT);
+    udp_recv(pcb_dhcps, handle_dhcp, NULL);
+#if DHCPS_DEBUG
+    DHCPS_LOG("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n");
+#endif
 
-    return 1;
 }
 
-static int dhcp_reply_send(struct udp_pcb *pcb, ip_addr_t *addr, dhcps_msg *reply)
+/******************************************************************************
+ * FunctionName : dhcps_stop
+ * Description  : stop dhcp server function
+ * Parameters   : netif -- The current netif addr
+ * Returns      : none
+*******************************************************************************/
+void dhcps_stop(struct netif *netif)
 {
-    size_t len = 0, ret = 0;
-    struct pbuf *p = NULL, *q = NULL;
-    u8_t *data = NULL;
-    u16_t cnt = 0;
-    u16_t i = 0;
-
-    len = dhcp_option_list_serialize(&reply->opts, reply->hdr.options, sizeof(reply->hdr) - DHCP_HEADER_SIZE);
-    len += DHCP_HEADER_SIZE;
-
-    dhcp_option *type_opt = dhcp_option_search(&reply->opts, DHCP_MESSAGE_TYPE);
-    if (type_opt == NULL)
-        return -1;
-
-//    if (type_opt->data[0] == DHCP_OFFER)
-    addr->u_addr.ip4.addr = INADDR_BROADCAST;
-//    else
-//        ip4_addr_set(ip_2_ip4(addr), &reply->hdr.yiaddr); // use the address assigned by us
-
-    if (reply->hdr.yiaddr.addr != 0)
-    {
-        log_info("send_dhcp_reply %s\n", inet_ntoa(*addr));
-    }
-
-    p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
-
-    if (p != NULL)
-    {
-        q = p;
-        while (q != NULL)
-        {
-            data = (u8_t *)q->payload;
-            for (i = 0; i< q->len; i++)
-            {
-                data[i] = ((u8_t *) reply)[cnt++];
-            }
-
-            q = q->next;
-        }
-    }
-    else
-    {
-        return 0;
-    }
+    struct netif *apnetif = netif;
 
-    ret = udp_sendto(pcb, p, addr, BOOTPC);
-    log_info("dhcp_send %d %d\n", ret, p->ref);
-    if(p->ref != 0)
-    {
-        pbuf_free(p);
+    if (apnetif == NULL) {
+        printf("dhcps_stop: apnetif == NULL\n");
+        return;
     }
 
-    return ret;
-}
-
-static int
-dhcp_reply_fill (dhcps_msg *request, dhcps_msg *reply,
-                 address_binding *binding, uint8_t type)
-{
-    static dhcp_option type_opt, server_id_opt;
-
-    type_opt.id = DHCP_MESSAGE_TYPE;
-    type_opt.len = 1;
-    type_opt.data[0] = type;
-    dhcp_option_append(&reply->opts, &type_opt);
-
-    server_id_opt.id = SERVER_IDENTIFIER;
-    server_id_opt.len = 4;
-    memcpy(server_id_opt.data, &dhcp_address_pool.server_id, sizeof(dhcp_address_pool.server_id));
-    dhcp_option_append(&reply->opts, &server_id_opt);
+    udp_disconnect(pcb_dhcps);
 
-    if(binding != NULL)
-    {
-        reply->hdr.yiaddr.addr = binding->address;
+    if (apnetif->dhcps_pcb != NULL) {
+        udp_remove(apnetif->dhcps_pcb);
+        apnetif->dhcps_pcb = NULL;
     }
 
-    if (type != DHCPS_NAK)
-    {
-        dhcp_option *requested_opts = dhcp_option_search(&request->opts, PARAMETER_REQUEST_LIST);
+    list_node *pnode = NULL;
+    list_node *pback_node = NULL;
+    pnode = plist;
 
-        if (requested_opts)
-            dhcp_options_default_fill(&dhcp_address_pool.options, &reply->opts);
+    while (pnode != NULL) {
+        pback_node = pnode;
+        pnode = pback_node->pnext;
+        node_remove_from_list(&plist, pback_node);
+        free(pback_node->pnode);
+        pback_node->pnode = NULL;
+        free(pback_node);
+        pback_node = NULL;
     }
-
-    return type;
 }
 
-static int
-dhcp_discover (dhcps_msg *request, dhcps_msg *reply)
+/******************************************************************************
+ * FunctionName : kill_oldest_dhcps_pool
+ * Description  : remove the oldest node from list
+ * Parameters   : none
+ * Returns      : none
+*******************************************************************************/
+static void kill_oldest_dhcps_pool(void)
 {
-    address_binding *binding = NULL;
-    binding = dhcp_binding_search(&dhcp_address_pool.bindings, request->hdr.chaddr, request->hdr.hlen, STATIC, EMPTY);
-
-    if (binding)
-    {
-        /* a static binding has been configured for this client */
-        log_info("%s %d %p",__FILE__, __LINE__, binding);
-    }
-    else
-    {
-        /* use dynamic pool */
-        /* If an address is available, the new address SHOULD be chosen as follows: */
-        binding = dhcp_binding_search(&dhcp_address_pool.bindings, request->hdr.chaddr,request->hdr.hlen, DYNAMIC, EMPTY);
-
-        if (binding)
-        {
-            /* The client's current address as recorded in the client's current
-               binding, ELSE */
-
-            /* The client's previous address as recorded in the client's (now
-               expired or released) binding, if that address is in the server's
-               pool of available addresses and not already allocated, ELSE */
-            log_info("%s %d %p",__FILE__, __LINE__, binding);
-        }
-        else
-        {
-            /* The address requested in the 'Requested IP Address' option, if that
-               address is valid and not already allocated, ELSE */
-
-            /* A new address allocated from the server's pool of available
-               addresses; the address is selected based on the subnet from which
-               the message was received (if 'giaddr' is 0) or on the address of
-               the relay agent that forwarded the message ('giaddr' when not 0). */
-
-            /* extract requested IP address */
-            uint32_t address = 0;
-            dhcp_option *address_opt = dhcp_option_search(&request->opts, REQUESTED_IP_ADDRESS);
-
-            if (address_opt != NULL)
-                memcpy(&address, address_opt->data, sizeof(address));
-
-            binding = dhcp_binding_new_dynamic(&dhcp_address_pool.bindings, &dhcp_address_pool.indexes, address, request->hdr.chaddr, request->hdr.hlen);
-
-            if (binding == NULL)
-            {
-                log_info("Can not offer an address, no address available.");
-                return 0;
-            }
+    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;
+    minp = p;
+
+    while (p != NULL) {
+        pdhcps_pool = p->pnode;
+        pmin_pool = minp->pnode;
+
+        if (pdhcps_pool->lease_timer < pmin_pool->lease_timer) {
+            minp = p;
+            minpre = pre;
         }
-    }
 
-    if (binding->binding_time + binding->lease_time < time(NULL))
-    {
-        log_info("%s %d %p",__FILE__, __LINE__, binding);
-        binding->status = PENDING;
-        binding->binding_time = time(NULL);
-        binding->lease_time = dhcp_address_pool.pending_time;
+        pre = p;
+        p = p->pnext;
     }
 
-    return dhcp_reply_fill(request, reply, binding, DHCPS_OFFER);
+    minpre->pnext = minp->pnext;
+    free(minp->pnode);
+    minp->pnode = NULL;
+    free(minp);
+    minp = NULL;
 }
 
-static int
-dhcp_request (dhcps_msg *request, dhcps_msg *reply)
+/******************************************************************************
+ * FunctionName : dhcps_coarse_tmr
+ * Description  : the lease time count
+ * Parameters   : none
+ * Returns      : none
+*******************************************************************************/
+void dhcps_coarse_tmr(void)
 {
-    address_binding *binding = dhcp_binding_search(&dhcp_address_pool.bindings, request->hdr.chaddr, request->hdr.hlen, STATIC_OR_DYNAMIC, PENDING);
-
-    uint32_t server_id = 0;
-    dhcp_option *server_id_opt = dhcp_option_search(&request->opts, SERVER_IDENTIFIER);
-
-    if (server_id_opt != NULL)
-        memcpy(&server_id, server_id_opt->data, sizeof(server_id));
-
-    if (server_id == dhcp_address_pool.server_id)
-    {
-        /* this request is an answer to our offer */
-        if (binding != NULL)
-        {
-            log_info("Ack, associated");
-
-            binding->status = ASSOCIATED;
-            binding->lease_time = dhcp_address_pool.lease_time;
-
-            return dhcp_reply_fill(request, reply, binding, DHCPS_ACK);
-        }
-        else
-        {
-            log_info("Nak, not associated");
+    u8_t num_dhcps_pool = 0;
+    list_node *pback_node = NULL;
+    list_node *pnode = NULL;
+    struct dhcps_pool *pdhcps_pool = NULL;
+    pnode = plist;
 
-            return dhcp_reply_fill(request, reply, NULL, DHCPS_NAK);
+    while (pnode != NULL) {
+        pdhcps_pool = pnode->pnode;
+        pdhcps_pool->lease_timer --;
+
+        if (pdhcps_pool->lease_timer == 0) {
+            pback_node = pnode;
+            pnode = pback_node->pnext;
+            node_remove_from_list(&plist, pback_node);
+            free(pback_node->pnode);
+            pback_node->pnode = NULL;
+            free(pback_node);
+            pback_node = NULL;
+        } else {
+            pnode = pnode ->pnext;
+            num_dhcps_pool ++;
         }
-
     }
-    else if (server_id != 0)
-    {
-        /* this request is an answer to another offer */
-        
-        binding->status = EMPTY;
-        binding->lease_time = 0;
-
-        return 0;
-    }
-
-    return 0;
-}
 
-static int
-dhcp_decline (dhcps_msg *request, dhcps_msg *reply)
-{
-    address_binding *binding = NULL;
-    binding = dhcp_binding_search(&dhcp_address_pool.bindings, request->hdr.chaddr, request->hdr.hlen, STATIC_OR_DYNAMIC, PENDING);
-    if(binding != NULL)
-    {
-        binding->status = EMPTY;
+    if (num_dhcps_pool >= MAX_STATION_NUM) {
+        kill_oldest_dhcps_pool();
     }
-
-    return 0;
-}
-
-static int
-dhcp_release (dhcps_msg *request, dhcps_msg *reply)
-{
-    address_binding *binding = NULL;
-    binding = dhcp_binding_search(&dhcp_address_pool.bindings, request->hdr.chaddr, request->hdr.hlen, STATIC_OR_DYNAMIC, ASSOCIATED);
-    if(binding != NULL)
-    {
-        binding->status = RELEASED;
-    }
-
-    return 0;
 }
 
-static int
-dhcp_inform (dhcps_msg *request, dhcps_msg *reply)
-{
-    return dhcp_reply_fill(request, reply, NULL, DHCPS_ACK);
-}
-
-/**
- * If an incoming DHCP message is in response to us, then trigger the state machine.
- *
- * Dispatch client DHCP messages to the correct handling routines
- *
- */
-static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
+/******************************************************************************
+ * 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)
 {
-    struct netif *netif = ip_current_input_netif();
-
-    struct pbuf *pthis = NULL;
-
-    LWIP_UNUSED_ARG(arg);
-    LWIP_ASSERT("invalid server address type", !IP_IS_V6(addr));
-    /* prevent warnings about unused arguments */
-    LWIP_UNUSED_ARG(pcb);
-    LWIP_UNUSED_ARG(addr);
-    LWIP_UNUSED_ARG(port);
-    uint8_t type = 0;
-    dhcps_msg *request = calloc(1, sizeof(dhcps_msg));
-    REQUIRE_ACTION(request, free_pbuf_and_return, 0);
-    dhcps_msg *reply = calloc(1, sizeof(dhcps_msg));
-    REQUIRE_ACTION(reply, free_pbuf_and_return, 0);
-    size_t len = 0;
-    len = pbuf_copy_partial(p, &request->hdr, p->tot_len, 0);
-    if (len < DHCP_HEADER_SIZE + 5)
-    {
-        goto free_pbuf_and_return;
-    }
-    else
-    {
-        if (request->hdr.op != BOOTREQUEST)
-        {
-            goto free_pbuf_and_return;
-        }
-        else
-        {
-            type = dhcp_request_expand(request, len);
-            dhcp_reply_init(request, reply);
-            switch (type)
-            {
-                case DHCPS_DISCOVER:
-                    type = dhcp_discover(request, reply);
-                    break;
-
-                case DHCPS_REQUEST:
-                    type = dhcp_request(request, reply);
-                    break;
-
-                case DHCPS_DECLINE:
-                    type = dhcp_decline(request, reply);
-                    break;
-
-                case DHCPS_RELEASE:
-                    type = dhcp_release(request, reply);
-                    break;
-
-                case DHCPS_INFORM:
-                    type = dhcp_inform(request, reply);
-                    break;
-
-                default:
-                    log_info("%s.%u: request with invalid DHCP message type option",inet_ntoa(addr), port);
-                    break;
-            }
+    struct dhcps_pool *pdhcps_pool = NULL;
+    list_node *pback_node = NULL;
+    bool ret = false;
 
-            if (type != DHCP_NONE)
-                dhcp_reply_send(pcb, (ip_addr_t *)addr, reply);
+    for (pback_node = plist; pback_node != NULL; pback_node = pback_node->pnext) {
+        pdhcps_pool = pback_node->pnode;
 
-            dhcp_option_list_delete(&request->opts);
-            dhcp_option_list_delete(&reply->opts);
+        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;
         }
     }
 
-free_pbuf_and_return:
-    if (request != NULL)
-        free(request);
-
-    if (reply != NULL)
-        free(reply);
-    pbuf_free(p);
-}
-
-void dhcps_set_default_option(struct dhcps_lease *pool_addr)
-{
-    ip4_addr_t server_ip, broadcast, dns;
-    REQUIRE_ASSERT(pool_addr);
-	address_pool *dhcps_addr_pool = &dhcp_address_pool; 
-
-	if (dhcps_addr_pool->flags){
-	
-	} else{
-		dhcp_option_list_init(&dhcps_addr_pool->options);
-		dhcps_addr_pool->flags = true;
-	}
-
-	/* Load configuration */
-    dhcps_option_set(IP_ADDRESS_LEASE_TIME, "36000");
-    dhcps_option_set(SUBNET_MASK, inet_ntoa(pool_addr->net_mask));
-
-    server_ip.addr = dhcps_addr_pool->server_id;
-    dhcps_option_set(ROUTER, inet_ntoa(server_ip));
-
-    broadcast.addr = server_ip.addr | ~(pool_addr->net_mask.addr);
-    dhcps_option_set(BROADCAST_ADDRESS,inet_ntoa(broadcast));
-
-    dns.addr = DHCP_SERVER_OPENDNS;
-    dhcps_option_set(DOMAIN_NAME_SERVER, inet_ntoa(dns));
-}
-
-static void dhcps_set_default_binding(address_pool *pool_addr)
-{
-	REQUIRE_ASSERT(pool_addr);
-	dhcp_binding_list_init(&pool_addr->bindings);
-}
-
-static address_pool* dhcps_try_open_socket(address_pool *pool_addr)
-{
-    REQUIRE_ASSERT(pool_addr);
-    pool_addr->socket = udp_new();
-    REQUIRE_ASSERT(pool_addr->socket);
-    udp_bind(pool_addr->socket, IP_ADDR_ANY, BOOTPS);
-    udp_recv(pool_addr->socket, dhcp_recv, pool_addr);
-    return pool_addr;
-}
-
-void dhcps_start(struct netif *netif, struct dhcps_lease *lease_pool)
-{
-    REQUIRE_ASSERT(netif);
-    REQUIRE_ASSERT(lease_pool);
-	
-	dhcp_address_pool.server_id = netif->ip_addr.u_addr.ip4.addr;    	
-    dhcps_set_default_time();
-	dhcps_set_default_binding(&dhcp_address_pool);
-    dhcps_set_default_option(lease_pool);    
-    dhcps_try_open_socket(&dhcp_address_pool);
-}
-
-void dhcps_stop(struct netif *netif )
-{
-    dhcp_binding_list_delete(&dhcp_address_pool.bindings);
-    dhcp_option_list_delete(&dhcp_address_pool.options);
-    udp_remove(dhcp_address_pool.socket);
-	dhcp_address_pool.flags = false;
-//	memset(&dhcp_address_pool, 0, sizeof(address_pool));
-}
-
-bool dhcps_lease_set(struct dhcps_lease *please)
-{    
-	REQUIRE_ASSERT(please);
-	    	
-    dhcp_address_pool.indexes.first   = please->start_ip.addr;
-    dhcp_address_pool.indexes.last    = please->end_ip.addr;
-    dhcp_address_pool.indexes.current = please->start_ip.addr;
-    
-    return true;
-}
-
-bool dhcps_lease_get(struct dhcps_lease *please)
-{
-	REQUIRE_ASSERT(please);
-	please->start_ip.addr = dhcp_address_pool.indexes.first;
-    please->end_ip.addr = dhcp_address_pool.indexes.last;
-    please->net_mask.addr = inet_addr("255.255.255.0");
-	return true;
-}
-
-bool dhcps_option_set(u8_t opt_id, void* optarg)
-{
-	if (dhcp_address_pool.flags){
-		dhcp_option *opt = dhcp_option_search(&dhcp_address_pool.options, opt_id);
-	    if (opt)
-	    {
-	        opt->len = strlen(optarg);
-	        memset(opt->data, 0, sizeof(opt->data));
-	        memcpy(opt->data, optarg, opt->len);
-	        return true;
-	    }
-	    else
-	    {
-	        return dhcp_options_add(dhcp_option_info[opt_id].name, optarg);
-	    }
-	} else{
-		dhcp_option_list_init(&dhcp_address_pool.options);
-		dhcp_address_pool.flags = true;
-		return dhcp_options_add(dhcp_option_info[opt_id].name, optarg);
-	}   
-}
-
-bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please)
-{
-    return false;
-}
-
-bool wifi_softap_set_dhcps_lease_time(u32_t minute)
-{
-    return false;
+    return ret;
 }
-
-
-#endif   /*ifdef  LWIP_ESP8266*/
-
-
-
-
+#endif
 

+ 35 - 316
components/lwip/include/lwip/apps/dhcpserver.h

@@ -47,221 +47,6 @@ typedef struct dhcps_msg {
         u8_t options[312];
 }dhcps_msg;
 
-struct dhcps_lease {
-	bool enable;
-	ip4_addr_t start_ip;
-	ip4_addr_t end_ip;
-};
-
-enum dhcps_offer_option{
-	OFFER_START = 0x00,
-	OFFER_ROUTER = 0x01,
-	OFFER_END
-};
-
-struct dhcps_pool{
-	ip4_addr_t ip;
-	u8_t mac[6];
-	u32_t lease_timer;
-};
-
-typedef struct _list_node{
-	void *pnode;
-	struct _list_node *pnext;
-}list_node;
-
-extern u32_t dhcps_lease_time;
-#define DHCPS_LEASE_TIMER  dhcps_lease_time  //0x05A0
-
-#define   dhcps_router_enabled(offer)	((offer & OFFER_ROUTER) != 0)
-void dhcps_start(struct netif *netif);
-void dhcps_stop(struct netif *netif);
-
-bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip);
-#else
-#include "lwip/opt.h"
-
-#include "lwip/netif.h"
-#include "lwip/udp.h"
-
-/** DHCP DEBUG INFO **/
-#define DHCPS_DEBUG 1
-#if DHCPS_DEBUG    	
-#define log_info(message, ...)   do { \
-		printf((message), ##__VA_ARGS__);   \
-		printf("\n");		  \
-	  } while(0);
-	
-#else
-#define log_info(message, ...)
-#endif
-
-#if (!defined(unlikely))
-#define unlikely(Expression)	!!(Expression)
-#endif
-
-#define REQUIRE_ASSERT(Expression) do{if (!(Expression)) log_info("%d\n", __LINE__);}while(0)
-
-#define REQUIRE_ACTION(Expression,Label,Action) \
-	do{\
-		if (unlikely(!(Expression))) \
-		{\
-			log_info("%d\n", __LINE__);\
-			{Action;}\
-			goto Label;\
-		}\
-	}while(0)
-
-#define REQUIRE_NOERROR(Expression,Label) \
-	do{\
-		int LocalError;\
-		LocalError = (int)Expression;\
-		if (unlikely(LocalError != 0)) \
-		{\
-			log_info("%d 0x%x\n", __LINE__, LocalError);\
-			goto Label;\
-		}\
-	}while(0)
-
-#define REQUIRE_NOERROR_ACTION(Expression,Label,Action) \
-	do{\
-		int LocalError;\
-		LocalError = (int)Expression;\
-		if (unlikely(LocalError != 0)) \
-		{\
-			log_info("%d\n", __LINE__);\
-			{Action;}\
-			goto Label;\
-		}\
-	}while(0)
-
-#define DHCP_OK	0
-#define DHCP_FAIL -1
-#define DHCP_SERVER_OPENDNS    0xd043dede /* OpenDNS DNS server 208.67.222.222 */
-
-/* DHCP message */
-/*
- * Code ID of DHCP and BOOTP options
- * as defined in RFC 2132
- */
-typedef enum
-{
-	DHCP_NONE	= 0,
-    DHCPS_DISCOVER = 1,
-    DHCPS_OFFER    = 2,
-    DHCPS_REQUEST  = 3,
-    DHCPS_DECLINE  = 4,
-    DHCPS_ACK      = 5,
-    DHCPS_NAK      = 6,
-    DHCPS_RELEASE  = 7,
-    DHCPS_INFORM   = 8,
-    DHCP_FORCE_RENEW = 9,
-    DHCP_LEASE_QUERY = 10,
-    DHCP_LEASE_UNASSIGNED = 11,
-    DHCP_LEASE_UNKNOWN = 12,
-    DHCP_LEASE_ACTIVE =  13,
-} dhcp_msg_type;
-
-typedef enum
-{
-    BOOTPS = 67,
-    BOOTPC = 68
-} ports;
-
-typedef enum
-{
-    BOOTREQUEST = 1,
-    BOOTREPLY   = 2,
-} op_types;
-
-typedef enum
-{
-    ETHERNET     = 0x01,
-    ETHERNET_LAN = 0x06,
-    ETHEFDDI = 0x08,
-    ETHEIEEE1394 = 0x18
-} hardware_types;
-
-typedef enum
-{
-    DHCPS_CHADDR_LEN = 16U,
-    DHCPS_SNAME_LEN = 64U,
-    DHCPS_FILE_LEN = 128U,
-    DHCP_HEADER_SIZE = 236U // without size of options
-} head_size;
-
-typedef struct dhcps
-{
-    /** transaction identifier of last sent request */
-    u32_t xid;
-    /** incoming msg */
-    struct dhcps_msg *msg_in;
-    /** track PCB allocation state */
-    u8_t pcb_allocated;
-    /** current DHCP state machine state */
-    u8_t state;
-    /** retries of current request */
-    u8_t tries;
-#if LWIP_DHCP_AUTOIP_COOP
-    u8_t autoip_coop_state;
-#endif
-    u8_t subnet_mask_given;
-
-    struct pbuf *p_out; /* pbuf of outcoming msg */
-    struct dhcp_msg *msg_out; /* outgoing msg */
-    u16_t options_out_len; /* outgoing msg options length */
-    u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
-    u16_t t1_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
-    u16_t t2_timeout;  /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
-    u16_t t1_renew_time;  /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */
-    u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */
-    u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */
-    u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */
-    ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */
-    ip4_addr_t offered_ip_addr;
-    ip4_addr_t offered_sn_mask;
-    ip4_addr_t offered_gw_addr;
-
-    u32_t offered_t0_lease; /* lease period (in seconds) */
-    u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
-    u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period)  */
-#if LWIP_DHCP_BOOTP_FILE
-    ip_addr_t offered_si_addr;
-    char boot_file_name[DHCP_FILE_LEN];
-#endif /* LWIP_DHCP_BOOTPFILE */
-
-} dhcps;
-
-typedef struct dhcp_message
-{
-    PACK_STRUCT_FLD_8(u8_t op);
-    PACK_STRUCT_FLD_8(u8_t htype);
-    PACK_STRUCT_FLD_8(u8_t hlen);
-    PACK_STRUCT_FLD_8(u8_t hops);
-    PACK_STRUCT_FIELD(u32_t xid);
-    PACK_STRUCT_FIELD(u16_t secs);
-    PACK_STRUCT_FIELD(u16_t flags);
-    PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr);
-    PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr);
-    PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr);
-    PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr);
-    PACK_STRUCT_FLD_8(u8_t chaddr[DHCPS_CHADDR_LEN]);
-    PACK_STRUCT_FLD_8(u8_t sname[DHCPS_SNAME_LEN]);
-    PACK_STRUCT_FLD_8(u8_t file[DHCPS_FILE_LEN]);
-//    PACK_STRUCT_FIELD(u32_t cookie);
-#define DHCPS_MIN_OPTIONS_LEN 312U
-    /** make sure user does not configure this too small */
-#if ((defined(DHCPS_OPTIONS_LEN)) && (DHCPS_OPTIONS_LEN < DHCPS_MIN_OPTIONS_LEN))
-#undef DHCPS_OPTIONS_LEN
-#endif
-    /** allow this to be configured in lwipopts.h, but not too small */
-#if (!defined(DHCPS_OPTIONS_LEN))
-    /** set this to be sufficient for your options in outgoing DHCP msgs */
-#define DHCPS_OPTIONS_LEN DHCPS_MIN_OPTIONS_LEN
-#endif
-    PACK_STRUCT_FLD_8(u8_t options[DHCPS_OPTIONS_LEN]);
-} dhcp_message;
-
 /** DHCP OPTIONS CODE **/
 typedef enum
 {
@@ -379,117 +164,51 @@ typedef enum
     CLASSLESS_ROUTE = 121,
 } dhcp_msg_option;
 
-typedef struct dhcp_option
-{
-    uint8_t id;        // option id
-    uint8_t len;       // option length
-    uint8_t data[256]; // option data
-
-    STAILQ_ENTRY(dhcp_option) pointers; // pointers, see queue(3)
-} dhcp_option;
-
-typedef STAILQ_HEAD(dhcp_option_list_, dhcp_option) DHCP_OPTION_LIST;
-typedef struct dhcp_option_list_ dhcp_option_list;
 
-/*
- * Header to manage the database of address bindings.
- */
+/*   Defined in esp_misc.h */
+//struct dhcps_lease {
+//	bool enable;
+//	ip4_addr_t start_ip;
+//	ip4_addr_t end_ip;
+//};
 
-// static association or dynamic
-enum
-{
-    DYNAMIC = 0,
-    STATIC  = 1,
-    STATIC_OR_DYNAMIC = 2
-};
-
-// binding status
-enum
-{
-    EMPTY = 0,
-    ASSOCIATED,
-    PENDINGD,
-    EXPIRED,
-    RELEASED
+enum dhcps_offer_option{
+	OFFER_START = 0x00,
+	OFFER_ROUTER = 0x01,
+	OFFER_END
 };
 
-/*
- * IP address used to delimitate an address pool.
- */
-typedef struct pool_indexes
-{
-    uint32_t first;    // first address of the pool
-    uint32_t last;     // last address of the pool
-    uint32_t current;  // current available address
-}pool_indexes;
-
-/*
- * The bindings are organized as a double linked list
- * using the standard queue(3) library
- */
-typedef struct address_binding
-{
-    uint32_t address;     // address
-    uint8_t cident_len;   // client identifier len
-    uint8_t cident[256];  // client identifier
-
-    time_t binding_time;  // time of binding
-    time_t lease_time;    // duration of lease
-
-    int status;           // binding status
-    int is_static;        // check if it is a static binding
+#define DHCPS_MAX_LEASE 0x64
+#define DHCPS_LEASE_TIME_DEF	(120)
 
-    STAILQ_ENTRY(address_binding) pointers; // list pointers, see queue(3)
-}address_binding;
-
-typedef STAILQ_HEAD(binding_list_, address_binding) BINDING_LIST_HEAD;
-typedef struct binding_list_ binding_list;
-
-/*
- * Global association pool.
- *
- * The (static or dynamic) associations tables of the DHCP server,
- * are maintained in this global structure.
- *
- * Note: all the IP addresses are in host order,
- *       to allow an easy manipulation.
- */
-
-typedef struct address_pool
-{
-    uint32_t server_id; // this server id (IP address)
-    uint32_t netmask;   // network mask
-    uint32_t gateway;   // network gateway
-
-    char device[16];    // network device to use
-
-    pool_indexes indexes;  // used to delimitate a pool of available addresses
-
-    time_t lease_time;   // default lease time
-    time_t pending_time; // duration of a binding in the pending state
-    struct udp_pcb *socket;	   // 
-    bool   flags;
+struct dhcps_pool{
+	ip4_addr_t ip;
+	u8_t mac[6];
+	u32_t lease_timer;
+};
 
-    dhcp_option_list options; // options for this pool, see queue
+typedef struct _list_node{
+	void *pnode;
+	struct _list_node *pnext;
+}list_node;
 
-    binding_list bindings; // associated addresses, see queue(3)
-}address_pool;
+typedef u32_t dhcps_time_t;
+typedef u8_t dhcps_offer_t;
+typedef struct dhcps_lease dhcps_lease_t;
 
-/*
- * Internal representation of a DHCP message,
- * with options parsed into a list...
- */
-typedef struct dhcps_msg
-{
-    dhcp_message     hdr;
-    dhcp_option_list opts;
-} dhcps_msg;
+typedef struct _dhcps_options{
+	dhcps_offer_t dhcps_offer;
+	dhcps_time_t  dhcps_time;
+	dhcps_lease_t dhcps_poll;
+}dhcps_options_t;
 
-bool dhcps_option_set(u8_t opt_id, void* optarg);
-void dhcps_start(struct netif *netif, struct dhcps_lease *lease_pool);
+#define   dhcps_router_enabled(offer)	((offer & OFFER_ROUTER) != 0)
+void dhcps_start(struct netif *netif, struct ip_info *info);
 void dhcps_stop(struct netif *netif);
-bool dhcps_lease_set(struct dhcps_lease *please);
-bool dhcps_lease_get(struct dhcps_lease *please);
+void *dhcps_option_info(u8_t op_id, u32_t opt_len);
+bool dhcp_search_ip_on_mac(u8_t *mac, ip4_addr_t *ip);
 
 #endif
+
 #endif
+

+ 1 - 2
components/lwip/include/lwip/port/arch/cc.h

@@ -35,6 +35,7 @@
 #define __ARCH_CC_H__
 
 #include <stdint.h>
+#include <errno.h>
 
 #include "arch/sys_arch.h"
 
@@ -72,6 +73,4 @@ typedef int sys_prot_t;
 #define LWIP_NOASSERT
 //#define LWIP_ERROR
 
-#define LWIP_PROVIDE_ERRNO
-
 #endif /* __ARCH_CC_H__ */

+ 6 - 5
components/lwip/include/lwip/port/lwipopts.h

@@ -221,6 +221,7 @@ extern unsigned long os_random(void);
  * TCP_WND: The size of a TCP window.  This must be at least
  * (2 * TCP_MSS) for things to work well
  */
+#define PERF 1
 #ifdef PERF
 extern unsigned char misc_prof_get_tcpw(void);
 extern unsigned char misc_prof_get_tcp_snd_buf(void);
@@ -469,7 +470,7 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void);
 /**
  * SOCKETS_DEBUG: Enable debugging in sockets.c.
  */
-#define SOCKETS_DEBUG                   LWIP_DBG_ON
+#define SOCKETS_DEBUG                   LWIP_DBG_OFF
 
 /**
  * ICMP_DEBUG: Enable debugging in icmp.c.
@@ -505,15 +506,15 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void);
  * DHCP_DEBUG: Enable debugging in dhcp.c.
  */
 #define DHCP_DEBUG                      LWIP_DBG_OFF
-#define LWIP_DEBUG                      1
-#define TCP_DEBUG                       LWIP_DBG_ON
-#define THREAD_SAFE_DEBUG               LWIP_DBG_ON
+#define LWIP_DEBUG                      0
+#define TCP_DEBUG                       LWIP_DBG_OFF
+#define THREAD_SAFE_DEBUG               LWIP_DBG_OFF
 #define LWIP_THREAD_SAFE                1
 
 #define CHECKSUM_CHECK_UDP              0
 #define CHECKSUM_CHECK_IP               0
 
-#define HEAP_HIGHWAT                    6*1024
+#define HEAP_HIGHWAT                    20*1024
 
 #define LWIP_NETCONN_FULLDUPLEX         1
 #define LWIP_NETCONN_SEM_PER_THREAD     1

+ 0 - 2
components/lwip/port/freertos/sys_arch.c

@@ -501,13 +501,11 @@ static void sys_thread_tls_free(int index, void* data)
 
   if (sem && *sem){
     LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem del, i=%d sem=%p\n", index, *sem));
-    ets_printf("sem del:%p\n", *sem);
     vSemaphoreDelete(*sem);
   }
 
   if (sem){
     LWIP_DEBUGF(THREAD_SAFE_DEBUG, ("sem pointer del, i=%d sem_p=%p\n", index, sem));
-    ets_printf("sem pointer del:%p\n", sem);
     free(sem);
   }
 }

+ 1 - 1
components/lwip/port/netif/wlanif.c

@@ -66,7 +66,7 @@ static char hostname[16];
 static char hostname[16];
 #endif
 #ifdef PERF
-uint32 g_rx_alloc_pbuf_fail_cnt = 0;
+uint32_t g_rx_alloc_pbuf_fail_cnt = 0;
 #endif
 
 /**

+ 27 - 4
components/tcpip_adapter/include/tcpip_adapter.h

@@ -32,6 +32,15 @@ struct ip_info {
     ip4_addr_t gw;
 };
 
+/*   Defined in esp_misc.h */
+struct dhcps_lease {
+	bool enable;
+	ip4_addr_t start_ip;
+	ip4_addr_t end_ip;
+};
+
+typedef struct dhcps_lease tcpip_adapter_dhcps_lease;
+
 #endif
 
 #if CONFIG_DHCP_STA_LIST 
@@ -50,6 +59,7 @@ struct station_list {
 #define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED  ESP_ERR_TCPIP_ADAPTER_BASE + 0x03
 #define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED  ESP_ERR_TCPIP_ADAPTER_BASE + 0x04
 #define ESP_ERR_TCPIP_ADAPTER_NO_MEM                ESP_ERR_TCPIP_ADAPTER_BASE + 0x05
+#define ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED      ESP_ERR_TCPIP_ADAPTER_BASE + 0x06
 
 /* will add ethernet interface */
 typedef enum {
@@ -65,6 +75,21 @@ typedef enum {
     TCPIP_ADAPTER_DHCP_STATUS_MAX
 } tcpip_adapter_dhcp_status_t;
 
+/*op*/
+typedef enum{
+    TCPIP_ADAPTER_OP_START = 0,
+    TCPIP_ADAPTER_OP_SET,
+    TCPIP_ADAPTER_OP_GET,
+    TCPIP_ADAPTER_OP_MAX
+} tcpip_adapter_option_mode;
+
+typedef enum{
+    TCPIP_ADAPTER_ROUTER_SOLICITATION_ADDRESS = 32,
+    TCPIP_ADAPTER_REQUESTED_IP_ADDRESS = 50,
+    TCPIP_ADAPTER_IP_ADDRESS_LEASE_TIME = 51,
+    TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52,
+} tcpip_adapter_option_id;
+
 void tcpip_adapter_init(void);
 
 esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, struct ip_info *info);
@@ -86,15 +111,13 @@ esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac);
 #endif
 
 esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status);
-
+esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_option_mode opt_op, tcpip_adapter_option_id opt_id, void *opt_val, uint32_t opt_len);
 esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if);
-
 esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if);
 
 esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status);
-
+esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode opt_op, tcpip_adapter_option_id opt_id, void *opt_val, uint32_t opt_len);
 esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if);
-
 esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if);
 
 esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void* eb);

+ 160 - 38
components/tcpip_adapter/tcpip_adapter_lwip.c

@@ -38,7 +38,7 @@ static tcpip_adapter_dhcp_status_t dhcpc_status = TCPIP_ADAPTER_DHCP_INIT;
 
 static esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif);
 
-#define TCPIP_ADAPTER_DEBUG  printf
+#define TCPIP_ADAPTER_DEBUG(...)
 
 void tcpip_adapter_init(void)
 {
@@ -76,8 +76,12 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, struct
         netif_set_up(esp_netif[tcpip_if]);
 
         if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) {
-            dhcps_start(esp_netif[tcpip_if]);
-            printf("dhcp server start:(ip: %s, mask: %s, gw: %s)\n", inet_ntoa(info->ip), inet_ntoa(info->netmask), inet_ntoa(info->gw));
+            dhcps_start(esp_netif[tcpip_if], info);
+
+            printf("dhcp server start:(ip: %s, ", inet_ntoa(info->ip));
+            printf("mask: %s, ", inet_ntoa(info->netmask));
+            printf("gw: %s)\n", inet_ntoa(info->gw));
+
             dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
         }
     }
@@ -130,6 +134,8 @@ esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
             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]);
     }
 
@@ -151,44 +157,14 @@ esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
             if (dhcpc_status != TCPIP_ADAPTER_DHCP_STOPPED) {
                 dhcpc_status = TCPIP_ADAPTER_DHCP_INIT;
             }
-        } else {
-            netif_set_down(esp_netif[tcpip_if]);
-            netif_set_addr(esp_netif[tcpip_if], IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
         }
-
-        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);
+        
+        netif_set_down(esp_netif[tcpip_if]);
     }
 
     return ESP_OK;
 }
 
-esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, struct ip_info *if_ip)
-{
-    struct netif *p_netif;
-
-    if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip == 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(&if_ip->ip, ip_2_ip4(&p_netif->ip_addr));
-        ip4_addr_set(&if_ip->netmask, ip_2_ip4(&p_netif->netmask));
-        ip4_addr_set(&if_ip->gw, ip_2_ip4(&p_netif->gw));
-
-        return ESP_OK;
-    }
-
-    ip4_addr_copy(if_ip->ip, esp_ip[tcpip_if].ip);
-    ip4_addr_copy(if_ip->gw, esp_ip[tcpip_if].gw);
-    ip4_addr_copy(if_ip->netmask, esp_ip[tcpip_if].netmask);
-
-    return ESP_OK;
-}
-
 esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif)
 {
     tcpip_adapter_if_t tcpip_if;
@@ -223,6 +199,7 @@ esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif)
             memcpy(&evt.event_info.got_ip.ip, &esp_ip[tcpip_if].ip, sizeof(evt.event_info.got_ip.ip));
             memcpy(&evt.event_info.got_ip.netmask, &esp_ip[tcpip_if].netmask, sizeof(evt.event_info.got_ip.netmask));
             memcpy(&evt.event_info.got_ip.gw, &esp_ip[tcpip_if].gw, sizeof(evt.event_info.got_ip.gw));
+
             esp_event_send(&evt);
 
             printf("ip: %s, ", inet_ntoa(esp_ip[tcpip_if].ip));
@@ -236,14 +213,54 @@ esp_err_t tcpip_adapter_addr_change_cb(struct netif *netif)
     return ESP_OK;
 }
 
+esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, struct ip_info *if_ip)
+{
+    struct netif *p_netif;
+
+    if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip == 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(&if_ip->ip, ip_2_ip4(&p_netif->ip_addr));
+        ip4_addr_set(&if_ip->netmask, ip_2_ip4(&p_netif->netmask));
+        ip4_addr_set(&if_ip->gw, ip_2_ip4(&p_netif->gw));
+
+        return ESP_OK;
+    }
+
+    ip4_addr_copy(if_ip->ip, esp_ip[tcpip_if].ip);
+    ip4_addr_copy(if_ip->gw, esp_ip[tcpip_if].gw);
+    ip4_addr_copy(if_ip->netmask, esp_ip[tcpip_if].netmask);
+
+    return ESP_OK;
+}
+
 esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, struct ip_info *if_ip)
 {
     struct netif *p_netif;
+    tcpip_adapter_dhcp_status_t status;
 
     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip == 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;
+        }
+    }
+
     ip4_addr_copy(esp_ip[tcpip_if].ip, if_ip->ip);
     ip4_addr_copy(esp_ip[tcpip_if].gw, if_ip->gw);
     ip4_addr_copy(esp_ip[tcpip_if].netmask, if_ip->netmask);
@@ -297,6 +314,99 @@ esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
 }
 #endif
 
+esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_option_mode opt_op, tcpip_adapter_option_id 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:
+            {
+                *(uint8_t *)opt_val = (*(uint8_t *)opt_info) & OFFER_ROUTER;
+                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:
+            {
+                struct ip_info info;
+                uint32_t softap_ip = 0;
+                uint32_t start_ip = 0;
+                uint32_t end_ip = 0;
+                struct dhcps_lease *poll = opt_val;
+
+                memset(&info, 0x00, sizeof(struct ip_info));
+                tcpip_adapter_get_ip_info(WIFI_IF_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:
+            {
+                *(uint8_t *)opt_info = (*(uint8_t *)opt_val) & OFFER_ROUTER;
+                break;
+            }
+            default:
+                break;
+        }
+    } else {
+        return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
+    }
+
+    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;
@@ -316,7 +426,9 @@ esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
         struct netif *p_netif = esp_netif[tcpip_if];
 
         if (p_netif != NULL && netif_is_up(p_netif)) {
-            dhcps_start(p_netif);
+            struct ip_info default_ip;
+            tcpip_adapter_get_ip_info(WIFI_IF_AP, &default_ip);
+            dhcps_start(p_netif, &default_ip);
             dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
             TCPIP_ADAPTER_DEBUG("dhcp server start successfully\n");
             return ESP_OK;
@@ -358,6 +470,12 @@ esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
     return ESP_OK;
 }
 
+esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode opt_op, tcpip_adapter_option_id opt_id, void *opt_val, uint32_t opt_len)
+{
+    // TODO: when dhcp request timeout,change the retry count
+    return ESP_OK;
+}
+
 esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
 {
     *status = dhcpc_status;
@@ -379,9 +497,13 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
         if (p_netif != NULL) {
             if (netif_is_up(p_netif)) {
                 TCPIP_ADAPTER_DEBUG("dhcp client init ip/mask/gw to all-0\n");
-                ip_addr_set_zero(&p_netif->ip_addr);;
+                ip_addr_set_zero(&p_netif->ip_addr);
                 ip_addr_set_zero(&p_netif->netmask);
                 ip_addr_set_zero(&p_netif->gw);
+            } else {
+                TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
+                dhcpc_status = TCPIP_ADAPTER_DHCP_INIT;
+                return ESP_OK;
             }
 
             if (dhcp_start(p_netif) != ERR_OK) {
@@ -420,7 +542,7 @@ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
             TCPIP_ADAPTER_DEBUG("dhcp client if not ready\n");
             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
         }
-    } else if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
+    } else if (dhcpc_status == TCPIP_ADAPTER_DHCP_STOPPED) {
         TCPIP_ADAPTER_DEBUG("dhcp client already stoped\n");
         return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
     }