]> granicus.if.org Git - esp-idf/blob - components/tcpip_adapter/tcpip_adapter_lwip.c
deep sleep: fix regression due to moving ets_update_cpu_frequency into IRAM
[esp-idf] / components / tcpip_adapter / tcpip_adapter_lwip.c
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stdio.h>
16 #include <string.h>
17
18 #include "tcpip_adapter.h"
19
20 #if CONFIG_TCPIP_LWIP
21
22 #include "lwip/inet.h"
23 #include "lwip/tcpip.h"
24 #include "lwip/dhcp.h"
25 #include "lwip/ip_addr.h"
26 #include "lwip/ip6_addr.h"
27 #include "lwip/nd6.h"
28 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
29 #include "lwip/dns.h"
30 #endif
31 #include "netif/wlanif.h"
32 #include "netif/ethernetif.h"
33
34 #include "apps/dhcpserver.h"
35
36 #include "esp_event.h"
37
38 static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];
39 static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX];
40 static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX];
41
42 static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
43 static tcpip_adapter_dhcp_status_t dhcpc_status[TCPIP_ADAPTER_IF_MAX] = {TCPIP_ADAPTER_DHCP_INIT};
44
45 #define TCPIP_ADAPTER_DEBUG(...)
46 //#define TCPIP_ADAPTER_DEBUG printf
47
48 void tcpip_adapter_init(void)
49 {
50     static bool tcpip_inited = false;
51
52     if (tcpip_inited == false) {
53         tcpip_inited = true;
54
55         tcpip_init(NULL, NULL);
56
57         IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1);
58         IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1);
59         IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0);
60     }
61 }
62
63 esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
64 {
65     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL || ip_info == NULL) {
66         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
67     }
68
69     if (esp_netif[tcpip_if] == NULL) {
70         esp_netif[tcpip_if] = calloc(1, sizeof(*esp_netif[tcpip_if]));
71         if (esp_netif[tcpip_if] == NULL) {
72             return ESP_ERR_NO_MEM;
73         }
74         memcpy(esp_netif[tcpip_if]->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
75         if (tcpip_if == TCPIP_ADAPTER_IF_AP || tcpip_if == TCPIP_ADAPTER_IF_STA) {
76             netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, wlanif_init, tcpip_input);
77         } else if (tcpip_if == TCPIP_ADAPTER_IF_ETH) {
78             netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, ethernetif_init, tcpip_input);
79         }
80     }
81
82     if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
83         netif_set_up(esp_netif[tcpip_if]);
84
85         if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) {
86             dhcps_start(esp_netif[tcpip_if], ip_info->ip);
87
88             printf("dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n",
89                    IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw));
90
91             dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
92         }
93     }
94
95     /* if ap is on, choose ap as default if */
96     if (esp_netif[TCPIP_ADAPTER_IF_AP]) {
97         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_AP]);
98     } else if (esp_netif[TCPIP_ADAPTER_IF_STA]) {
99         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_STA]);
100     } else if (esp_netif[TCPIP_ADAPTER_IF_ETH] ) {
101         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_ETH]);
102     }
103
104     return ESP_OK;
105 }
106
107 esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
108 {
109     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
110         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
111     }
112
113     if (esp_netif[tcpip_if] == NULL) {
114         return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
115     }
116
117     if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
118         dhcps_stop(esp_netif[tcpip_if]);    // TODO: dhcps checks status by its self
119         if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status) {
120             dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
121         }
122     } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) {
123         dhcp_release(esp_netif[tcpip_if]);
124         dhcp_stop(esp_netif[tcpip_if]);
125         dhcp_cleanup(esp_netif[tcpip_if]);
126
127         dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
128
129         ip4_addr_set_zero(&esp_ip[tcpip_if].ip);
130         ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
131         ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
132     }
133
134     netif_remove(esp_netif[tcpip_if]);
135
136     free(esp_netif[tcpip_if]);
137     esp_netif[tcpip_if] = NULL;
138
139     /* in ap + sta mode, if stop ap, choose sta as default if */
140     if (esp_netif[TCPIP_ADAPTER_IF_STA] && tcpip_if == TCPIP_ADAPTER_IF_AP) {
141         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_STA]);
142     }
143
144     return ESP_OK;
145 }
146
147 esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
148 {
149     if (tcpip_if == TCPIP_ADAPTER_IF_STA ||  tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
150         if (esp_netif[tcpip_if] == NULL) {
151             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
152         }
153
154         /* use last obtained ip, or static ip */
155         netif_set_addr(esp_netif[tcpip_if], &esp_ip[tcpip_if].ip, &esp_ip[tcpip_if].netmask, &esp_ip[tcpip_if].gw);
156         netif_set_up(esp_netif[tcpip_if]);
157     }
158
159     return ESP_OK;
160 }
161
162 esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
163 {
164     if (tcpip_if == TCPIP_ADAPTER_IF_STA ||  tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
165         if (esp_netif[tcpip_if] == NULL) {
166             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
167         }
168
169         if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) {
170             dhcp_stop(esp_netif[tcpip_if]);
171
172             dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
173
174             ip4_addr_set_zero(&esp_ip[tcpip_if].ip);
175             ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
176             ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
177         }
178
179         /* Modify ip address to trigger tcp/udp pcb cleanup */
180         netif_set_addr(esp_netif[tcpip_if], IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
181
182         netif_set_down(esp_netif[tcpip_if]);
183     }
184
185     return ESP_OK;
186 }
187
188 esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
189 {
190     struct netif *p_netif;
191
192     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) {
193         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
194     }
195
196     p_netif = esp_netif[tcpip_if];
197
198     if (p_netif != NULL && netif_is_up(p_netif)) {
199         ip4_addr_set(&ip_info->ip, ip_2_ip4(&p_netif->ip_addr));
200         ip4_addr_set(&ip_info->netmask, ip_2_ip4(&p_netif->netmask));
201         ip4_addr_set(&ip_info->gw, ip_2_ip4(&p_netif->gw));
202
203         return ESP_OK;
204     }
205
206     ip4_addr_copy(ip_info->ip, esp_ip[tcpip_if].ip);
207     ip4_addr_copy(ip_info->gw, esp_ip[tcpip_if].gw);
208     ip4_addr_copy(ip_info->netmask, esp_ip[tcpip_if].netmask);
209
210     return ESP_OK;
211 }
212
213 esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
214 {
215     struct netif *p_netif;
216     tcpip_adapter_dhcp_status_t status;
217
218     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL ||
219             ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask)) {
220         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
221     }
222
223     if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
224         tcpip_adapter_dhcps_get_status(tcpip_if, &status);
225
226         if (status != TCPIP_ADAPTER_DHCP_STOPPED) {
227             return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED;
228         }
229     } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
230         tcpip_adapter_dhcpc_get_status(tcpip_if, &status);
231
232         if (status != TCPIP_ADAPTER_DHCP_STOPPED) {
233             return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED;
234         }
235 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
236         u8_t numdns = 0;
237         for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) {
238             dns_setserver(numdns, NULL);
239         }
240 #endif
241     }
242
243     ip4_addr_copy(esp_ip[tcpip_if].ip, ip_info->ip);
244     ip4_addr_copy(esp_ip[tcpip_if].gw, ip_info->gw);
245     ip4_addr_copy(esp_ip[tcpip_if].netmask, ip_info->netmask);
246
247     p_netif = esp_netif[tcpip_if];
248
249     if (p_netif != NULL && netif_is_up(p_netif)) {
250         netif_set_addr(p_netif, &ip_info->ip, &ip_info->netmask, &ip_info->gw);
251     }
252
253     return ESP_OK;
254 }
255
256 static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex)
257 {
258     tcpip_adapter_ip6_info_t *ip6_info;
259
260     if (!p_netif) {
261         TCPIP_ADAPTER_DEBUG("null p_netif=%p\n", p_netif);
262         return;
263     }
264
265     if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
266         ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_STA];
267     } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) {
268         ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP];
269     } else {
270         return;
271     }
272
273     system_event_t evt;
274
275     ip6_addr_set(&ip6_info->ip, ip_2_ip6(&p_netif->ip6_addr[ip_idex]));
276
277     //notify event
278     evt.event_id = SYSTEM_EVENT_AP_STA_GOT_IP6;
279     memcpy(&evt.event_info.got_ip6.ip6_info, ip6_info, sizeof(tcpip_adapter_ip6_info_t));
280     esp_event_send(&evt);
281 }
282
283 esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
284 {
285     struct netif *p_netif;
286
287     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
288         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
289     }
290
291     p_netif = esp_netif[tcpip_if];
292     if (p_netif != NULL && netif_is_up(p_netif)) {
293         netif_create_ip6_linklocal_address(p_netif, 1);
294         nd6_set_cb(p_netif, tcpip_adapter_nd6_cb);
295
296         return ESP_OK;
297     } else {
298         return ESP_FAIL;
299     }
300 }
301
302 esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
303 {
304     struct netif *p_netif;
305
306     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) {
307         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
308     }
309
310     p_netif = esp_netif[tcpip_if];
311     if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) {
312         memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t));
313     } else {
314         return ESP_FAIL;
315     }
316     return ESP_OK;
317 }
318
319 #if 0
320 esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
321 {
322     struct netif *p_netif;
323
324     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) {
325         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
326     }
327
328     p_netif = esp_netif[tcpip_if];
329
330     if (p_netif != NULL) {
331         memcpy(mac, p_netif->hwaddr, NETIF_MAX_HWADDR_LEN);
332
333         return ESP_OK;
334     }
335
336     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
337 }
338
339 esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
340 {
341     struct netif *p_netif;
342
343     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) {
344         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
345     }
346
347     p_netif = esp_netif[tcpip_if];
348
349     if (p_netif != NULL) {
350         memcpy(p_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
351
352         return ESP_OK;
353     }
354
355     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
356 }
357 #endif
358
359 esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len)
360 {
361     void *opt_info = dhcps_option_info(opt_id, opt_len);
362
363     if (opt_info == NULL || opt_val == NULL) {
364         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
365     }
366
367     if (opt_op == TCPIP_ADAPTER_OP_GET) {
368         if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
369             return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
370         }
371
372         switch (opt_id) {
373         case IP_ADDRESS_LEASE_TIME: {
374             *(uint32_t *)opt_val = *(uint32_t *)opt_info;
375             break;
376         }
377         case REQUESTED_IP_ADDRESS: {
378             memcpy(opt_val, opt_info, opt_len);
379             break;
380         }
381         case ROUTER_SOLICITATION_ADDRESS: {
382             *(uint8_t *)opt_val = (*(uint8_t *)opt_info) & OFFER_ROUTER;
383             break;
384         }
385         default:
386             break;
387         }
388     } else if (opt_op == TCPIP_ADAPTER_OP_SET) {
389         if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) {
390             return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
391         }
392
393         switch (opt_id) {
394         case IP_ADDRESS_LEASE_TIME: {
395             if (*(uint32_t *)opt_val != 0) {
396                 *(uint32_t *)opt_info = *(uint32_t *)opt_val;
397             } else {
398                 *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF;
399             }
400             break;
401         }
402         case REQUESTED_IP_ADDRESS: {
403             tcpip_adapter_ip_info_t info;
404             uint32_t softap_ip = 0;
405             uint32_t start_ip = 0;
406             uint32_t end_ip = 0;
407             dhcps_lease_t *poll = opt_val;
408
409             if (poll->enable) {
410                 memset(&info, 0x00, sizeof(tcpip_adapter_ip_info_t));
411                 tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &info);
412                 softap_ip = htonl(info.ip.addr);
413                 start_ip = htonl(poll->start_ip.addr);
414                 end_ip = htonl(poll->end_ip.addr);
415
416                 /*config ip information can't contain local ip*/
417                 if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
418                     return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
419                 }
420
421                 /*config ip information must be in the same segment as the local ip*/
422                 softap_ip >>= 8;
423                 if ((start_ip >> 8 != softap_ip)
424                         || (end_ip >> 8 != softap_ip)) {
425                     return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
426                 }
427
428                 if (end_ip - start_ip > DHCPS_MAX_LEASE) {
429                     return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
430                 }
431             }
432
433             memcpy(opt_info, opt_val, opt_len);
434             break;
435         }
436         case ROUTER_SOLICITATION_ADDRESS: {
437             *(uint8_t *)opt_info = (*(uint8_t *)opt_val) & OFFER_ROUTER;
438             break;
439         }
440         default:
441             break;
442         }
443     } else {
444         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
445     }
446
447     return ESP_OK;
448 }
449
450 esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
451 {
452     *status = dhcps_status;
453
454     return ESP_OK;
455 }
456
457 esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
458 {
459     /* only support ap now */
460     if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
461         TCPIP_ADAPTER_DEBUG("dhcp server invalid if=%d\n", tcpip_if);
462         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
463     }
464
465     if (dhcps_status != TCPIP_ADAPTER_DHCP_STARTED) {
466         struct netif *p_netif = esp_netif[tcpip_if];
467
468         if (p_netif != NULL && netif_is_up(p_netif)) {
469             tcpip_adapter_ip_info_t default_ip;
470             tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &default_ip);
471             dhcps_start(p_netif, default_ip.ip);
472             dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
473             TCPIP_ADAPTER_DEBUG("dhcp server start successfully\n");
474             return ESP_OK;
475         } else {
476             TCPIP_ADAPTER_DEBUG("dhcp server re init\n");
477             dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
478             return ESP_OK;
479         }
480     }
481
482     TCPIP_ADAPTER_DEBUG("dhcp server already start\n");
483     return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
484 }
485
486 esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
487 {
488     /* only support ap now */
489     if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
490         TCPIP_ADAPTER_DEBUG("dhcp server invalid if=%d\n", tcpip_if);
491         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
492     }
493
494     if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) {
495         struct netif *p_netif = esp_netif[tcpip_if];
496
497         if (p_netif != NULL) {
498             dhcps_stop(p_netif);
499         } else {
500             TCPIP_ADAPTER_DEBUG("dhcp server if not ready\n");
501             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
502         }
503     } else if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
504         TCPIP_ADAPTER_DEBUG("dhcp server already stoped\n");
505         return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
506     }
507
508     TCPIP_ADAPTER_DEBUG("dhcp server stop successfully\n");
509     dhcps_status = TCPIP_ADAPTER_DHCP_STOPPED;
510     return ESP_OK;
511 }
512
513 esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len)
514 {
515     // TODO: when dhcp request timeout,change the retry count
516     return ESP_OK;
517 }
518
519 static void tcpip_adapter_dhcpc_cb(struct netif *netif)
520 {
521     if (!netif) {
522         TCPIP_ADAPTER_DEBUG("null netif=%p\n", netif);
523         return;
524     }
525
526     if (netif != esp_netif[TCPIP_ADAPTER_IF_STA] && netif != esp_netif[TCPIP_ADAPTER_IF_ETH]) {
527         TCPIP_ADAPTER_DEBUG("err netif=%p\n", netif);
528         return;
529     }
530
531     if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY) ) {
532         tcpip_adapter_ip_info_t *ip_info = NULL;
533         if( netif == esp_netif[TCPIP_ADAPTER_IF_STA] ) {
534             ip_info = &esp_ip[TCPIP_ADAPTER_IF_STA];
535         } else if(netif == esp_netif[TCPIP_ADAPTER_IF_ETH] ) {
536             ip_info = &esp_ip[TCPIP_ADAPTER_IF_ETH];
537         } 
538
539         //check whether IP is changed
540         if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), &ip_info->ip) ||
541                 !ip4_addr_cmp(ip_2_ip4(&netif->netmask), &ip_info->netmask) ||
542                 !ip4_addr_cmp(ip_2_ip4(&netif->gw), &ip_info->gw) ) {
543             system_event_t evt;
544
545             ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr));
546             ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask));
547             ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
548
549             //notify event
550             if (netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
551                 evt.event_id = SYSTEM_EVENT_STA_GOT_IP;
552             } else if (netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) {
553                 evt.event_id = SYSTEM_EVENT_ETH_GOT_IP;
554             }
555
556             memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t));
557
558             esp_event_send(&evt);
559         } else {
560             TCPIP_ADAPTER_DEBUG("ip unchanged\n");
561         }
562     }
563
564     return;
565 }
566
567 esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
568 {
569     *status = dhcpc_status[tcpip_if];
570
571     return ESP_OK;
572 }
573
574 esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
575 {
576     /* only support sta now, need to support ethernet */
577     if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH)  || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
578         TCPIP_ADAPTER_DEBUG("dhcp client invalid if=%d\n", tcpip_if);
579         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
580     }
581
582     if (dhcpc_status[tcpip_if] != TCPIP_ADAPTER_DHCP_STARTED) {
583         struct netif *p_netif = esp_netif[tcpip_if];
584
585         ip4_addr_set_zero(&esp_ip[tcpip_if].ip);
586         ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
587         ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
588
589         if (p_netif != NULL) {
590             if (netif_is_up(p_netif)) {
591                 TCPIP_ADAPTER_DEBUG("dhcp client init ip/mask/gw to all-0\n");
592                 ip_addr_set_zero(&p_netif->ip_addr);
593                 ip_addr_set_zero(&p_netif->netmask);
594                 ip_addr_set_zero(&p_netif->gw);
595             } else {
596                 TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
597                 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
598                 return ESP_OK;
599             }
600
601             if (dhcp_start(p_netif) != ERR_OK) {
602                 TCPIP_ADAPTER_DEBUG("dhcp client start failed\n");
603                 return ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED;
604             }
605
606             dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb);
607
608             TCPIP_ADAPTER_DEBUG("dhcp client start successfully\n");
609             dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED;
610             return ESP_OK;
611         } else {
612             TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
613             dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
614             return ESP_OK;
615         }
616     }
617
618     TCPIP_ADAPTER_DEBUG("dhcp client already started\n");
619     return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
620 }
621
622 esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
623 {
624     /* only support sta now, need to support ethernet */
625     if (tcpip_if != TCPIP_ADAPTER_IF_STA || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
626         TCPIP_ADAPTER_DEBUG("dhcp client invalid if=%d\n", tcpip_if);
627         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
628     }
629
630     if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) {
631         struct netif *p_netif = esp_netif[tcpip_if];
632
633         if (p_netif != NULL) {
634             dhcp_stop(p_netif);
635
636             ip4_addr_set_zero(&esp_ip[tcpip_if].ip);
637             ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
638             ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
639         } else {
640             TCPIP_ADAPTER_DEBUG("dhcp client if not ready\n");
641             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
642         }
643     } else if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STOPPED) {
644         TCPIP_ADAPTER_DEBUG("dhcp client already stoped\n");
645         return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
646     }
647
648     TCPIP_ADAPTER_DEBUG("dhcp client stop successfully\n");
649     dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
650     return ESP_OK;
651 }
652
653 esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
654 {
655     ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len);
656     return ESP_OK;
657 }
658
659 esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb)
660 {
661     wlanif_input(esp_netif[TCPIP_ADAPTER_IF_STA], buffer, len, eb);
662     return ESP_OK;
663 }
664
665 esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb)
666 {
667     wlanif_input(esp_netif[TCPIP_ADAPTER_IF_AP], buffer, len, eb);
668     return ESP_OK;
669 }
670
671 #if 0
672 bool tcpip_dep_output(wifi_interface_t wifi_if, void *buffer, uint16_t len)
673 {
674
675     return true;
676 }
677 #endif
678
679 esp_interface_t tcpip_adapter_get_esp_if(void *dev)
680 {
681     struct netif *p_netif = (struct netif *)dev;
682
683     if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
684         return ESP_IF_WIFI_STA;
685     } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) {
686         return ESP_IF_WIFI_AP;
687     } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) {
688         return ESP_IF_ETH;
689     }
690
691     return ESP_IF_MAX;
692 }
693
694 esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list)
695 {
696     int i;
697
698     if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) {
699         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
700     }
701
702     memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t));
703     tcpip_sta_list->num = wifi_sta_list->num;
704     for (i = 0; i < wifi_sta_list->num; i++) {
705         memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
706         dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip);
707     }
708
709     return ESP_OK;
710 }
711
712 esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
713 {
714 #if LWIP_NETIF_HOSTNAME
715     struct netif *p_netif;
716     static char hostinfo[TCPIP_HOSTNAME_MAX_SIZE + 1][TCPIP_ADAPTER_IF_MAX];
717
718     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) {
719         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
720     }
721
722     if (strlen(hostname) > TCPIP_HOSTNAME_MAX_SIZE) {
723         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
724     }
725
726     p_netif = esp_netif[tcpip_if];
727     if (p_netif != NULL) {
728         memset(hostinfo[tcpip_if], 0, sizeof(hostinfo[tcpip_if]));
729         memcpy(hostinfo[tcpip_if], hostname, strlen(hostname));
730         p_netif->hostname = hostinfo[tcpip_if];
731         return ESP_OK;
732     } else {
733         return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
734     }
735 #else
736     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
737 #endif
738 }
739
740 esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname)
741 {
742 #if LWIP_NETIF_HOSTNAME
743     struct netif *p_netif = NULL;
744     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) {
745         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
746     }
747
748     p_netif = esp_netif[tcpip_if];
749     if (p_netif != NULL) {
750         *hostname = p_netif->hostname;
751         return ESP_OK;
752     } else {
753         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
754     }
755 #else
756     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
757 #endif
758 }
759
760 #endif