]> granicus.if.org Git - esp-idf/blob - components/tcpip_adapter/tcpip_adapter_lwip.c
tcpip_adapter/lwip: make dhcp domain name server option configurable
[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 #include "lwip/priv/tcpip_priv.h"
29 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
30 #include "lwip/dns.h"
31 #endif
32 #include "netif/wlanif.h"
33 #include "netif/ethernetif.h"
34
35 #include "apps/dhcpserver.h"
36 #include "apps/dhcpserver_options.h"
37
38 #include "esp_event.h"
39 #include "esp_log.h"
40
41 static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];
42 static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX];
43 static tcpip_adapter_ip_info_t esp_ip_old[TCPIP_ADAPTER_IF_MAX];
44 static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX];
45 static netif_init_fn esp_netif_init_fn[TCPIP_ADAPTER_IF_MAX];
46 static tcpip_adapter_ip_lost_timer_t esp_ip_lost_timer[TCPIP_ADAPTER_IF_MAX];
47
48 static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
49 static tcpip_adapter_dhcp_status_t dhcpc_status[TCPIP_ADAPTER_IF_MAX] = {TCPIP_ADAPTER_DHCP_INIT};
50 static esp_err_t tcpip_adapter_start_api(tcpip_adapter_api_msg_t * msg);
51 static esp_err_t tcpip_adapter_stop_api(tcpip_adapter_api_msg_t * msg);
52 static esp_err_t tcpip_adapter_up_api(tcpip_adapter_api_msg_t * msg);
53 static esp_err_t tcpip_adapter_down_api(tcpip_adapter_api_msg_t * msg);
54 static esp_err_t tcpip_adapter_set_ip_info_api(tcpip_adapter_api_msg_t * msg);
55 static esp_err_t tcpip_adapter_set_dns_info_api(tcpip_adapter_api_msg_t * msg);
56 static esp_err_t tcpip_adapter_get_dns_info_api(tcpip_adapter_api_msg_t * msg);
57 static esp_err_t tcpip_adapter_create_ip6_linklocal_api(tcpip_adapter_api_msg_t * msg);
58 static esp_err_t tcpip_adapter_dhcps_start_api(tcpip_adapter_api_msg_t * msg);
59 static esp_err_t tcpip_adapter_dhcps_stop_api(tcpip_adapter_api_msg_t * msg);
60 static esp_err_t tcpip_adapter_dhcpc_start_api(tcpip_adapter_api_msg_t * msg);
61 static esp_err_t tcpip_adapter_dhcpc_stop_api(tcpip_adapter_api_msg_t * msg);
62 static esp_err_t tcpip_adapter_set_hostname_api(tcpip_adapter_api_msg_t * msg);
63 static esp_err_t tcpip_adapter_reset_ip_info(tcpip_adapter_if_t tcpip_if);
64 static esp_err_t tcpip_adapter_start_ip_lost_timer(tcpip_adapter_if_t tcpip_if);
65 static void tcpip_adapter_ip_lost_timer(void *arg);
66 static sys_sem_t api_sync_sem = NULL;
67 static bool tcpip_inited = false;
68 static sys_sem_t api_lock_sem = NULL;
69 extern sys_thread_t g_lwip_task;
70 #define TAG "tcpip_adapter"
71
72 static void tcpip_adapter_api_cb(void* api_msg)
73 {
74     tcpip_adapter_api_msg_t *msg = (tcpip_adapter_api_msg_t*)api_msg;
75
76     if (!msg || !msg->api_fn) {
77         ESP_LOGD(TAG, "null msg/api_fn");
78         return;
79     }
80
81     msg->ret = msg->api_fn(msg);
82     ESP_LOGD(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret);
83     sys_sem_signal(&api_sync_sem);
84
85     return;
86 }
87
88 void tcpip_adapter_init(void)
89 {
90     int ret;
91
92     if (tcpip_inited == false) {
93         tcpip_inited = true;
94
95         tcpip_init(NULL, NULL);
96
97         memset(esp_ip, 0, sizeof(tcpip_adapter_ip_info_t)*TCPIP_ADAPTER_IF_MAX);
98         memset(esp_ip_old, 0, sizeof(tcpip_adapter_ip_info_t)*TCPIP_ADAPTER_IF_MAX);
99
100         IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1);
101         IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1);
102         IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0);
103         ret = sys_sem_new(&api_sync_sem, 0);
104         if (ERR_OK != ret) {
105             ESP_LOGE(TAG, "tcpip adatper api sync sem init fail");
106         }
107
108         ret = sys_sem_new(&api_lock_sem, 1);
109         if (ERR_OK != ret) {
110             ESP_LOGE(TAG, "tcpip adatper api lock sem init fail");
111         }
112     }
113 }
114
115 static inline netif_init_fn tcpip_if_to_netif_init_fn(tcpip_adapter_if_t tcpip_if)
116 {
117      if (tcpip_if < TCPIP_ADAPTER_IF_MAX)
118           return esp_netif_init_fn[tcpip_if];
119      else
120           return NULL;
121 }
122
123 static int tcpip_adapter_ipc_check(tcpip_adapter_api_msg_t *msg)
124 {
125 #if TCPIP_ADAPTER_TRHEAD_SAFE
126     xTaskHandle local_task = xTaskGetCurrentTaskHandle();
127
128     if (local_task == g_lwip_task) {
129         return TCPIP_ADAPTER_IPC_LOCAL;
130     }
131
132     sys_arch_sem_wait(&api_lock_sem, 0);
133     tcpip_send_api_msg((tcpip_callback_fn)tcpip_adapter_api_cb, msg, &api_sync_sem);
134     sys_sem_signal(&api_lock_sem);
135
136     return TCPIP_ADAPTER_IPC_REMOTE;
137 #else
138     return TCPIP_ADAPTER_IPC_LOCAL;
139 #endif
140 }
141
142 static esp_err_t tcpip_adapter_update_default_netif(void)
143 {
144     if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_STA])) {
145         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_STA]);
146     } else if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_ETH])) {
147         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_ETH]);
148     } else if (netif_is_up(esp_netif[TCPIP_ADAPTER_IF_AP])) {
149         netif_set_default(esp_netif[TCPIP_ADAPTER_IF_AP]);
150     }
151
152     return ESP_OK;
153 }
154
155 esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
156 {
157     netif_init_fn netif_init;
158
159     TCPIP_ADAPTER_IPC_CALL(tcpip_if, mac, ip_info, 0, tcpip_adapter_start_api);
160
161     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL || ip_info == NULL) {
162         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
163     }
164
165     if (esp_netif[tcpip_if] == NULL || !netif_is_up(esp_netif[tcpip_if])) {
166         if (esp_netif[tcpip_if] == NULL) {
167             esp_netif[tcpip_if] = calloc(1, sizeof(*esp_netif[tcpip_if]));
168         }
169
170         if (esp_netif[tcpip_if] == NULL) {
171             return ESP_ERR_NO_MEM;
172         }
173         memcpy(esp_netif[tcpip_if]->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
174
175         netif_init = tcpip_if_to_netif_init_fn(tcpip_if);
176         assert(netif_init != NULL);
177         netif_add(esp_netif[tcpip_if], &ip_info->ip, &ip_info->netmask, &ip_info->gw, NULL, netif_init, tcpip_input);
178     }
179
180     if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
181         netif_set_up(esp_netif[tcpip_if]);
182
183         if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) {
184             dhcps_start(esp_netif[tcpip_if], ip_info->ip);
185
186             ESP_LOGD(TAG, "dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")",
187                    IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw));
188
189             dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
190         }
191     }
192
193     tcpip_adapter_update_default_netif();
194
195     return ESP_OK;
196 }
197
198 esp_err_t tcpip_adapter_eth_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
199 {
200      esp_netif_init_fn[TCPIP_ADAPTER_IF_ETH] = ethernetif_init;
201      return tcpip_adapter_start(TCPIP_ADAPTER_IF_ETH, mac, ip_info);
202 }
203
204 esp_err_t tcpip_adapter_sta_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
205 {
206      esp_netif_init_fn[TCPIP_ADAPTER_IF_STA] = wlanif_init_sta;
207      return tcpip_adapter_start(TCPIP_ADAPTER_IF_STA, mac, ip_info);
208 }
209
210 esp_err_t tcpip_adapter_ap_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
211 {
212      esp_netif_init_fn[TCPIP_ADAPTER_IF_AP] = wlanif_init_ap;
213      return tcpip_adapter_start(TCPIP_ADAPTER_IF_AP, mac, ip_info);
214 }
215
216 static esp_err_t tcpip_adapter_start_api(tcpip_adapter_api_msg_t * msg)
217 {
218     return tcpip_adapter_start(msg->tcpip_if, msg->mac, msg->ip_info);
219 }
220
221 esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
222 {
223     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_stop_api);
224
225     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
226         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
227     }
228
229     if (esp_netif[tcpip_if] == NULL) {
230         return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
231     }
232
233     if (!netif_is_up(esp_netif[tcpip_if])) {
234         netif_remove(esp_netif[tcpip_if]);
235         return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
236     }
237
238     if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
239         dhcps_stop(esp_netif[tcpip_if]);    // TODO: dhcps checks status by its self
240         if (TCPIP_ADAPTER_DHCP_STOPPED != dhcps_status) {
241             dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
242         }
243     } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) {
244         dhcp_release(esp_netif[tcpip_if]);
245         dhcp_stop(esp_netif[tcpip_if]);
246         dhcp_cleanup(esp_netif[tcpip_if]);
247
248         dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
249
250         tcpip_adapter_reset_ip_info(tcpip_if);
251     }
252
253     netif_set_down(esp_netif[tcpip_if]);
254     netif_remove(esp_netif[tcpip_if]);
255     tcpip_adapter_update_default_netif();
256
257     return ESP_OK;
258 }
259
260 static esp_err_t tcpip_adapter_stop_api(tcpip_adapter_api_msg_t * msg)
261 {
262     msg->ret = tcpip_adapter_stop(msg->tcpip_if);
263     return msg->ret;
264 }
265
266 esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
267 {
268     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_up_api);
269
270     if (tcpip_if == TCPIP_ADAPTER_IF_STA ||  tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
271         if (esp_netif[tcpip_if] == NULL) {
272             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
273         }
274
275         /* use last obtained ip, or static ip */
276         netif_set_addr(esp_netif[tcpip_if], &esp_ip[tcpip_if].ip, &esp_ip[tcpip_if].netmask, &esp_ip[tcpip_if].gw);
277         netif_set_up(esp_netif[tcpip_if]);
278     }
279
280     tcpip_adapter_update_default_netif();
281
282     return ESP_OK;
283 }
284
285 static esp_err_t tcpip_adapter_up_api(tcpip_adapter_api_msg_t * msg)
286 {
287     msg->ret = tcpip_adapter_up(msg->tcpip_if);
288     return msg->ret;
289 }
290
291 esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
292 {
293     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_down_api);
294
295     if (tcpip_if == TCPIP_ADAPTER_IF_STA ||  tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
296         if (esp_netif[tcpip_if] == NULL) {
297             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
298         }
299
300         if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) {
301             dhcp_stop(esp_netif[tcpip_if]);
302
303             dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
304
305             tcpip_adapter_reset_ip_info(tcpip_if);
306         }
307
308         netif_set_addr(esp_netif[tcpip_if], IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY);
309         netif_set_down(esp_netif[tcpip_if]);
310         tcpip_adapter_start_ip_lost_timer(tcpip_if);
311     }
312
313     tcpip_adapter_update_default_netif();
314
315     return ESP_OK;
316 }
317
318 static esp_err_t tcpip_adapter_down_api(tcpip_adapter_api_msg_t * msg)
319 {
320     return tcpip_adapter_down(msg->tcpip_if);
321 }
322
323 esp_err_t tcpip_adapter_set_old_ip_info_api(tcpip_adapter_api_msg_t * msg)
324 {
325     memcpy(&esp_ip_old[msg->tcpip_if], msg->ip_info, sizeof(tcpip_adapter_ip_info_t));
326     return ESP_OK;
327 }
328
329 esp_err_t tcpip_adapter_set_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
330 {
331     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) {
332         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
333     }
334
335     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, ip_info, 0, tcpip_adapter_set_old_ip_info_api);
336
337     return ESP_OK;
338 }
339
340 esp_err_t tcpip_adapter_get_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
341 {
342     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) {
343         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
344     }
345
346     memcpy(ip_info, &esp_ip_old[tcpip_if], sizeof(tcpip_adapter_ip_info_t));
347     return ESP_OK;
348 }
349
350 esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
351 {
352     struct netif *p_netif;
353
354     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) {
355         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
356     }
357
358     p_netif = esp_netif[tcpip_if];
359
360     if (p_netif != NULL && netif_is_up(p_netif)) {
361         ip4_addr_set(&ip_info->ip, ip_2_ip4(&p_netif->ip_addr));
362         ip4_addr_set(&ip_info->netmask, ip_2_ip4(&p_netif->netmask));
363         ip4_addr_set(&ip_info->gw, ip_2_ip4(&p_netif->gw));
364
365         return ESP_OK;
366     }
367
368     ip4_addr_copy(ip_info->ip, esp_ip[tcpip_if].ip);
369     ip4_addr_copy(ip_info->gw, esp_ip[tcpip_if].gw);
370     ip4_addr_copy(ip_info->netmask, esp_ip[tcpip_if].netmask);
371
372     return ESP_OK;
373 }
374
375 esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
376 {
377     struct netif *p_netif;
378     tcpip_adapter_dhcp_status_t status;
379
380     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, ip_info, 0, tcpip_adapter_set_ip_info_api);
381
382     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) {
383         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
384     }
385
386     if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
387         tcpip_adapter_dhcps_get_status(tcpip_if, &status);
388
389         if (status != TCPIP_ADAPTER_DHCP_STOPPED) {
390             return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED;
391         }
392     } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
393         tcpip_adapter_dhcpc_get_status(tcpip_if, &status);
394
395         if (status != TCPIP_ADAPTER_DHCP_STOPPED) {
396             return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED;
397         }
398 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
399         dns_clear_servers(true);
400 #endif
401     }
402
403     ip4_addr_copy(esp_ip[tcpip_if].ip, ip_info->ip);
404     ip4_addr_copy(esp_ip[tcpip_if].gw, ip_info->gw);
405     ip4_addr_copy(esp_ip[tcpip_if].netmask, ip_info->netmask);
406
407     p_netif = esp_netif[tcpip_if];
408
409     if (p_netif != NULL && netif_is_up(p_netif)) {
410         netif_set_addr(p_netif, &ip_info->ip, &ip_info->netmask, &ip_info->gw);
411         if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->ip))) {
412             system_event_t evt;
413             evt.event_id = SYSTEM_EVENT_STA_GOT_IP;
414             evt.event_info.got_ip.ip_changed = false;
415
416             if (memcmp(ip_info, &esp_ip_old[tcpip_if], sizeof(tcpip_adapter_ip_info_t))) {
417                 evt.event_info.got_ip.ip_changed = true;
418             }
419
420             memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t));
421             memcpy(&esp_ip_old[tcpip_if], ip_info, sizeof(tcpip_adapter_ip_info_t));
422             esp_event_send(&evt);
423             ESP_LOGD(TAG, "if%d tcpip adapter set static ip: ip changed=%d", tcpip_if, evt.event_info.got_ip.ip_changed);
424         }
425     }
426
427     return ESP_OK;
428 }
429
430 static esp_err_t tcpip_adapter_set_ip_info_api(tcpip_adapter_api_msg_t * msg)
431 {
432     return tcpip_adapter_set_ip_info(msg->tcpip_if, msg->ip_info);
433 }
434
435 static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex)
436 {
437     tcpip_adapter_ip6_info_t *ip6_info;
438
439     if (!p_netif) {
440         ESP_LOGD(TAG, "null p_netif=%p", p_netif);
441         return;
442     }
443
444     if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
445         ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_STA];
446     } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) {
447         ip6_info = &esp_ip6[TCPIP_ADAPTER_IF_AP];
448     } else {
449         return;
450     }
451
452     system_event_t evt;
453
454     ip6_addr_set(&ip6_info->ip, ip_2_ip6(&p_netif->ip6_addr[ip_idex]));
455
456     //notify event
457     evt.event_id = SYSTEM_EVENT_AP_STA_GOT_IP6;
458     memcpy(&evt.event_info.got_ip6.ip6_info, ip6_info, sizeof(tcpip_adapter_ip6_info_t));
459     esp_event_send(&evt);
460 }
461
462 esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
463 {
464     struct netif *p_netif;
465
466     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_create_ip6_linklocal_api);
467
468     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
469         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
470     }
471
472     p_netif = esp_netif[tcpip_if];
473     if (p_netif != NULL && netif_is_up(p_netif)) {
474         netif_create_ip6_linklocal_address(p_netif, 1);
475         nd6_set_cb(p_netif, tcpip_adapter_nd6_cb);
476
477         return ESP_OK;
478     } else {
479         return ESP_FAIL;
480     }
481 }
482
483 static esp_err_t tcpip_adapter_create_ip6_linklocal_api(tcpip_adapter_api_msg_t * msg)
484 {
485     return tcpip_adapter_create_ip6_linklocal(msg->tcpip_if);
486 }
487
488 esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
489 {
490     struct netif *p_netif;
491
492     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) {
493         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
494     }
495
496     p_netif = esp_netif[tcpip_if];
497     if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) {
498         memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t));
499     } else {
500         return ESP_FAIL;
501     }
502     return ESP_OK;
503 }
504
505 #if 0
506 esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
507 {
508     struct netif *p_netif;
509
510     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) {
511         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
512     }
513
514     p_netif = esp_netif[tcpip_if];
515
516     if (p_netif != NULL) {
517         memcpy(mac, p_netif->hwaddr, NETIF_MAX_HWADDR_LEN);
518
519         return ESP_OK;
520     }
521
522     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
523 }
524
525 esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
526 {
527     struct netif *p_netif;
528
529     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) {
530         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
531     }
532
533     p_netif = esp_netif[tcpip_if];
534
535     if (p_netif != NULL) {
536         memcpy(p_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
537
538         return ESP_OK;
539     }
540
541     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
542 }
543 #endif
544
545 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)
546 {
547     void *opt_info = dhcps_option_info(opt_id, opt_len);
548
549     if (opt_info == NULL || opt_val == NULL) {
550         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
551     }
552
553     if (opt_op == TCPIP_ADAPTER_OP_GET) {
554         if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
555             return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
556         }
557
558         switch (opt_id) {
559         case IP_ADDRESS_LEASE_TIME: {
560             *(uint32_t *)opt_val = *(uint32_t *)opt_info;
561             break;
562         }
563         case REQUESTED_IP_ADDRESS: {
564             memcpy(opt_val, opt_info, opt_len);
565             break;
566         }
567         case ROUTER_SOLICITATION_ADDRESS: {
568             if ((*(uint8_t *)opt_info) & OFFER_ROUTER) {
569                 *(uint8_t *)opt_val = 1;
570             } else {
571                 *(uint8_t *)opt_val = 0;
572             }
573             break;
574         }
575         case DOMAIN_NAME_SERVER: {
576             if ((*(uint8_t *)opt_info) & OFFER_DNS) {
577                 *(uint8_t *)opt_val = 1;
578             } else {
579                 *(uint8_t *)opt_val = 0;
580             }
581             break;
582         }
583         default:
584             break;
585         }
586     } else if (opt_op == TCPIP_ADAPTER_OP_SET) {
587         if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) {
588             return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
589         }
590
591         switch (opt_id) {
592         case IP_ADDRESS_LEASE_TIME: {
593             if (*(uint32_t *)opt_val != 0) {
594                 *(uint32_t *)opt_info = *(uint32_t *)opt_val;
595             } else {
596                 *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF;
597             }
598             break;
599         }
600         case REQUESTED_IP_ADDRESS: {
601             tcpip_adapter_ip_info_t info;
602             uint32_t softap_ip = 0;
603             uint32_t start_ip = 0;
604             uint32_t end_ip = 0;
605             dhcps_lease_t *poll = opt_val;
606
607             if (poll->enable) {
608                 memset(&info, 0x00, sizeof(tcpip_adapter_ip_info_t));
609                 tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &info);
610                 softap_ip = htonl(info.ip.addr);
611                 start_ip = htonl(poll->start_ip.addr);
612                 end_ip = htonl(poll->end_ip.addr);
613
614                 /*config ip information can't contain local ip*/
615                 if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
616                     return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
617                 }
618
619                 /*config ip information must be in the same segment as the local ip*/
620                 softap_ip >>= 8;
621                 if ((start_ip >> 8 != softap_ip)
622                         || (end_ip >> 8 != softap_ip)) {
623                     return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
624                 }
625
626                 if (end_ip - start_ip > DHCPS_MAX_LEASE) {
627                     return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
628                 }
629             }
630
631             memcpy(opt_info, opt_val, opt_len);
632             break;
633         }
634         case ROUTER_SOLICITATION_ADDRESS: {
635             if (*(uint8_t *)opt_val) {
636                 *(uint8_t *)opt_info |= OFFER_ROUTER;
637             } else {
638                 *(uint8_t *)opt_info &= ((~OFFER_ROUTER)&0xFF);
639             }
640             break;
641         }
642         case DOMAIN_NAME_SERVER: {
643             if (*(uint8_t *)opt_val) {
644                 *(uint8_t *)opt_info |= OFFER_DNS;
645             } else {
646                 *(uint8_t *)opt_info &= ((~OFFER_DNS)&0xFF);
647             }
648             break;
649         }
650        
651         default:
652             break;
653         }
654         dhcps_set_option_info(opt_id, opt_info,opt_len);
655     } else {
656         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
657     }
658
659     return ESP_OK;
660 }
661
662 esp_err_t tcpip_adapter_set_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns)
663 {
664     tcpip_adapter_dns_param_t dns_param;
665
666     dns_param.dns_type =  type;
667     dns_param.dns_info =  dns;
668
669     TCPIP_ADAPTER_IPC_CALL(tcpip_if, type,  0, &dns_param, tcpip_adapter_set_dns_info_api);
670
671     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
672         ESP_LOGD(TAG, "set dns invalid if=%d", tcpip_if);
673         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
674     }
675  
676     if (!dns) {
677         ESP_LOGD(TAG, "set dns null dns");
678         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
679     }
680
681     if (type >= TCPIP_ADAPTER_DNS_MAX) {
682         ESP_LOGD(TAG, "set dns invalid type=%d", type);
683         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
684     }
685     
686     if (ip4_addr_isany_val(dns->ip.u_addr.ip4)) {
687         ESP_LOGD(TAG, "set dns invalid dns");
688         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
689     }
690
691     ESP_LOGD(TAG, "set dns if=%d type=%d dns=%x", tcpip_if, type, dns->ip.u_addr.ip4.addr);
692     dns->ip.type = IPADDR_TYPE_V4;
693
694     if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) {
695         dns_setserver(type, &(dns->ip));
696     } else {
697         if (type != TCPIP_ADAPTER_DNS_MAIN) {
698             ESP_LOGD(TAG, "set dns invalid type");
699             return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
700         } else {
701             dhcps_dns_setserver(&(dns->ip));
702         }
703     }
704
705     return ESP_OK;
706 }
707
708 static esp_err_t tcpip_adapter_set_dns_info_api(tcpip_adapter_api_msg_t * msg)
709 {
710     tcpip_adapter_dns_param_t *dns_param = (tcpip_adapter_dns_param_t*)msg->data;
711
712     return tcpip_adapter_set_dns_info(msg->tcpip_if, dns_param->dns_type, dns_param->dns_info);
713 }
714
715 esp_err_t tcpip_adapter_get_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns)
716
717     tcpip_adapter_dns_param_t dns_param;
718
719     dns_param.dns_type =  type;
720     dns_param.dns_info =  dns;
721     
722     TCPIP_ADAPTER_IPC_CALL(tcpip_if, type,  0, &dns_param, tcpip_adapter_get_dns_info_api);
723     if (!dns) {
724         ESP_LOGD(TAG, "get dns null dns");
725         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
726     }
727
728     if (type >= TCPIP_ADAPTER_DNS_MAX) {
729         ESP_LOGD(TAG, "get dns invalid type=%d", type);
730         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
731     }
732     
733     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
734         ESP_LOGD(TAG, "get dns invalid tcpip_if=%d",tcpip_if);
735         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
736     }
737
738     if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH) {
739         dns->ip = dns_getserver(type);
740     } else {
741         dns->ip.u_addr.ip4 = dhcps_dns_getserver();
742     }
743
744     return ESP_OK;
745 }
746
747 static esp_err_t tcpip_adapter_get_dns_info_api(tcpip_adapter_api_msg_t * msg)
748 {
749     tcpip_adapter_dns_param_t *dns_param = (tcpip_adapter_dns_param_t*)msg->data;
750
751     return tcpip_adapter_get_dns_info(msg->tcpip_if, dns_param->dns_type, dns_param->dns_info);
752 }
753
754 esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
755 {
756     *status = dhcps_status;
757
758     return ESP_OK;
759 }
760
761 esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
762 {
763     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcps_start_api);
764
765     /* only support ap now */
766     if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
767         ESP_LOGD(TAG, "dhcp server invalid if=%d", tcpip_if);
768         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
769     }
770
771     if (dhcps_status != TCPIP_ADAPTER_DHCP_STARTED) {
772         struct netif *p_netif = esp_netif[tcpip_if];
773
774         if (p_netif != NULL && netif_is_up(p_netif)) {
775             tcpip_adapter_ip_info_t default_ip;
776             tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &default_ip);
777             dhcps_start(p_netif, default_ip.ip);
778             dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
779             ESP_LOGD(TAG, "dhcp server start successfully");
780             return ESP_OK;
781         } else {
782             ESP_LOGD(TAG, "dhcp server re init");
783             dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
784             return ESP_OK;
785         }
786     }
787
788     ESP_LOGD(TAG, "dhcp server already start");
789     return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
790 }
791
792 static esp_err_t tcpip_adapter_dhcps_start_api(tcpip_adapter_api_msg_t * msg)
793 {
794     return tcpip_adapter_dhcps_start(msg->tcpip_if);
795 }
796
797
798 esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
799 {
800     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcps_stop_api);
801
802     /* only support ap now */
803     if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
804         ESP_LOGD(TAG, "dhcp server invalid if=%d", tcpip_if);
805         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
806     }
807
808     if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) {
809         struct netif *p_netif = esp_netif[tcpip_if];
810
811         if (p_netif != NULL) {
812             dhcps_stop(p_netif);
813         } else {
814             ESP_LOGD(TAG, "dhcp server if not ready");
815             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
816         }
817     } else if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
818         ESP_LOGD(TAG, "dhcp server already stoped");
819         return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
820     }
821
822     ESP_LOGD(TAG, "dhcp server stop successfully");
823     dhcps_status = TCPIP_ADAPTER_DHCP_STOPPED;
824     return ESP_OK;
825 }
826
827 static esp_err_t tcpip_adapter_dhcps_stop_api(tcpip_adapter_api_msg_t * msg)
828 {
829     return tcpip_adapter_dhcps_stop(msg->tcpip_if);
830 }
831
832 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)
833 {
834     // TODO: when dhcp request timeout,change the retry count
835     return ESP_OK;
836 }
837
838 static void tcpip_adapter_dhcpc_cb(struct netif *netif)
839 {
840     tcpip_adapter_ip_info_t *ip_info_old = NULL;
841     tcpip_adapter_ip_info_t *ip_info = NULL;
842     tcpip_adapter_if_t tcpip_if;
843
844     if (!netif) {
845         ESP_LOGD(TAG, "null netif=%p", netif);
846         return;
847     }
848
849     if( netif == esp_netif[TCPIP_ADAPTER_IF_STA] ) {
850         tcpip_if = TCPIP_ADAPTER_IF_STA;
851     } else if(netif == esp_netif[TCPIP_ADAPTER_IF_ETH] ) {
852         tcpip_if = TCPIP_ADAPTER_IF_ETH;
853     } else { 
854         ESP_LOGD(TAG, "err netif=%p", netif);
855         return;
856     }
857
858     ESP_LOGD(TAG, "if%d dhcpc cb", tcpip_if);
859     ip_info = &esp_ip[tcpip_if];
860     ip_info_old = &esp_ip_old[tcpip_if];
861
862     if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY) ) {
863         
864         //check whether IP is changed
865         if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), &ip_info->ip) ||
866                 !ip4_addr_cmp(ip_2_ip4(&netif->netmask), &ip_info->netmask) ||
867                 !ip4_addr_cmp(ip_2_ip4(&netif->gw), &ip_info->gw) ) {
868             system_event_t evt;
869
870             ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr));
871             ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask));
872             ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
873
874             //notify event
875             if (tcpip_if == TCPIP_ADAPTER_IF_ETH) {
876                 evt.event_id = SYSTEM_EVENT_ETH_GOT_IP;
877                 evt.event_info.got_ip.ip_changed = true;
878             } else {
879                 evt.event_id = SYSTEM_EVENT_STA_GOT_IP;
880                 evt.event_info.got_ip.ip_changed = false;
881             }
882
883             if (memcmp(ip_info, ip_info_old, sizeof(tcpip_adapter_ip_info_t))) {
884                 evt.event_info.got_ip.ip_changed = true;
885             }
886
887             memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t));
888             memcpy(ip_info_old, ip_info, sizeof(tcpip_adapter_ip_info_t));
889             ESP_LOGD(TAG, "if%d ip changed=%d", tcpip_if, evt.event_info.got_ip.ip_changed);
890             esp_event_send(&evt);
891         } else {
892             ESP_LOGD(TAG, "if%d ip unchanged", tcpip_if);
893         }
894     } else {
895         if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY)) {
896             tcpip_adapter_start_ip_lost_timer(tcpip_if);
897         }
898     }
899
900     return;
901 }
902
903 static esp_err_t tcpip_adapter_start_ip_lost_timer(tcpip_adapter_if_t tcpip_if)
904 {
905     tcpip_adapter_ip_info_t *ip_info_old = &esp_ip_old[tcpip_if];
906     struct netif *netif = esp_netif[tcpip_if];
907
908     ESP_LOGD(TAG, "if%d start ip lost tmr: enter", tcpip_if);
909     if (tcpip_if != TCPIP_ADAPTER_IF_STA) {
910         ESP_LOGD(TAG, "if%d start ip lost tmr: only sta support ip lost timer", tcpip_if);
911         return ESP_OK;
912     }
913
914     if (esp_ip_lost_timer[tcpip_if].timer_running) {
915         ESP_LOGD(TAG, "if%d start ip lost tmr: already started", tcpip_if);
916         return ESP_OK;
917     }
918
919     if ( netif && (CONFIG_IP_LOST_TIMER_INTERVAL > 0) && !ip4_addr_isany_val(ip_info_old->ip)) {
920         esp_ip_lost_timer[tcpip_if].timer_running = true;
921         sys_timeout(CONFIG_IP_LOST_TIMER_INTERVAL*1000, tcpip_adapter_ip_lost_timer, (void*)tcpip_if);
922         ESP_LOGD(TAG, "if%d start ip lost tmr: interval=%d", tcpip_if, CONFIG_IP_LOST_TIMER_INTERVAL);
923         return ESP_OK;
924     }
925
926     ESP_LOGD(TAG, "if%d start ip lost tmr: no need start because netif=%p interval=%d ip=%x", 
927                   tcpip_if, netif, CONFIG_IP_LOST_TIMER_INTERVAL, ip_info_old->ip.addr);
928
929     return ESP_OK;
930 }
931
932 static void tcpip_adapter_ip_lost_timer(void *arg)
933 {
934     tcpip_adapter_if_t tcpip_if = (tcpip_adapter_if_t)arg;
935
936     ESP_LOGD(TAG, "if%d ip lost tmr: enter", tcpip_if);
937     esp_ip_lost_timer[tcpip_if].timer_running = false;
938
939     if (tcpip_if == TCPIP_ADAPTER_IF_STA) {
940         struct netif *netif = esp_netif[tcpip_if];
941
942         if ( (!netif) || (netif && ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY))){
943             system_event_t evt;
944
945             ESP_LOGD(TAG, "if%d ip lost tmr: raise ip lost event", tcpip_if);
946             memset(&esp_ip_old[tcpip_if], 0, sizeof(tcpip_adapter_ip_info_t));
947             evt.event_id = SYSTEM_EVENT_STA_LOST_IP;
948             esp_event_send(&evt);
949         } else {
950             ESP_LOGD(TAG, "if%d ip lost tmr: no need raise ip lost event", tcpip_if);
951         }
952     } else {
953         ESP_LOGD(TAG, "if%d ip lost tmr: not station", tcpip_if);
954     }
955 }
956
957 esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
958 {
959     *status = dhcpc_status[tcpip_if];
960
961     return ESP_OK;
962 }
963
964 esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
965 {
966     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcpc_start_api);
967
968     if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH)  || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
969         ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if);
970         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
971     }
972
973     if (dhcpc_status[tcpip_if] != TCPIP_ADAPTER_DHCP_STARTED) {
974         struct netif *p_netif = esp_netif[tcpip_if];
975
976         tcpip_adapter_reset_ip_info(tcpip_if);
977 #if LWIP_DNS
978         dns_clear_servers(true);
979 #endif
980
981         if (p_netif != NULL) {
982             if (netif_is_up(p_netif)) {
983                 ESP_LOGD(TAG, "dhcp client init ip/mask/gw to all-0");
984                 ip_addr_set_zero(&p_netif->ip_addr);
985                 ip_addr_set_zero(&p_netif->netmask);
986                 ip_addr_set_zero(&p_netif->gw);
987                 tcpip_adapter_start_ip_lost_timer(tcpip_if);
988             } else {
989                 ESP_LOGD(TAG, "dhcp client re init");
990                 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
991                 return ESP_OK;
992             }
993
994             if (dhcp_start(p_netif) != ERR_OK) {
995                 ESP_LOGD(TAG, "dhcp client start failed");
996                 return ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED;
997             }
998
999             dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb);
1000
1001             ESP_LOGD(TAG, "dhcp client start successfully");
1002             dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED;
1003             return ESP_OK;
1004         } else {
1005             ESP_LOGD(TAG, "dhcp client re init");
1006             dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
1007             return ESP_OK;
1008         }
1009     }
1010
1011     ESP_LOGD(TAG, "dhcp client already started");
1012     return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
1013 }
1014
1015 static esp_err_t tcpip_adapter_dhcpc_start_api(tcpip_adapter_api_msg_t * msg)
1016 {
1017     return tcpip_adapter_dhcpc_start(msg->tcpip_if);
1018 }
1019
1020 esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
1021 {
1022     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcpc_stop_api);
1023
1024     if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH)  || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
1025         ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if);
1026         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
1027     }
1028
1029     if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) {
1030         struct netif *p_netif = esp_netif[tcpip_if];
1031
1032         if (p_netif != NULL) {
1033             dhcp_stop(p_netif);
1034             tcpip_adapter_reset_ip_info(tcpip_if);
1035             tcpip_adapter_start_ip_lost_timer(tcpip_if);
1036         } else {
1037             ESP_LOGD(TAG, "dhcp client if not ready");
1038             return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
1039         }
1040     } else if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STOPPED) {
1041         ESP_LOGD(TAG, "dhcp client already stoped");
1042         return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
1043     }
1044
1045     ESP_LOGD(TAG, "dhcp client stop successfully");
1046     dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
1047     return ESP_OK;
1048 }
1049
1050 static esp_err_t tcpip_adapter_dhcpc_stop_api(tcpip_adapter_api_msg_t * msg)
1051 {
1052     return tcpip_adapter_dhcpc_stop(msg->tcpip_if);
1053 }
1054
1055 esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
1056 {
1057     ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len);
1058     return ESP_OK;
1059 }
1060
1061 esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb)
1062 {
1063     wlanif_input(esp_netif[TCPIP_ADAPTER_IF_STA], buffer, len, eb);
1064     return ESP_OK;
1065 }
1066
1067 esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb)
1068 {
1069     wlanif_input(esp_netif[TCPIP_ADAPTER_IF_AP], buffer, len, eb);
1070     return ESP_OK;
1071 }
1072
1073 #if 0
1074 bool tcpip_dep_output(wifi_interface_t wifi_if, void *buffer, uint16_t len)
1075 {
1076
1077     return true;
1078 }
1079 #endif
1080
1081 esp_interface_t tcpip_adapter_get_esp_if(void *dev)
1082 {
1083     struct netif *p_netif = (struct netif *)dev;
1084
1085     if (p_netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
1086         return ESP_IF_WIFI_STA;
1087     } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_AP]) {
1088         return ESP_IF_WIFI_AP;
1089     } else if (p_netif == esp_netif[TCPIP_ADAPTER_IF_ETH]) {
1090         return ESP_IF_ETH;
1091     }
1092
1093     return ESP_IF_MAX;
1094 }
1095
1096 esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list)
1097 {
1098     int i;
1099
1100     if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) {
1101         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
1102     }
1103
1104     memset(tcpip_sta_list, 0, sizeof(tcpip_adapter_sta_list_t));
1105     tcpip_sta_list->num = wifi_sta_list->num;
1106     for (i = 0; i < wifi_sta_list->num; i++) {
1107         memcpy(tcpip_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
1108         dhcp_search_ip_on_mac(tcpip_sta_list->sta[i].mac, &tcpip_sta_list->sta[i].ip);
1109     }
1110
1111     return ESP_OK;
1112 }
1113
1114 esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
1115 {
1116 #if LWIP_NETIF_HOSTNAME
1117     TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, hostname, tcpip_adapter_set_hostname_api);
1118     struct netif *p_netif;
1119     static char hostinfo[TCPIP_ADAPTER_IF_MAX][TCPIP_HOSTNAME_MAX_SIZE + 1];
1120
1121     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) {
1122         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
1123     }
1124
1125     if (strlen(hostname) > TCPIP_HOSTNAME_MAX_SIZE) {
1126         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
1127     }
1128
1129     p_netif = esp_netif[tcpip_if];
1130     if (p_netif != NULL) {
1131         memset(hostinfo[tcpip_if], 0, sizeof(hostinfo[tcpip_if]));
1132         strlcpy(hostinfo[tcpip_if], hostname, sizeof(hostinfo[tcpip_if]));
1133         p_netif->hostname = hostinfo[tcpip_if];
1134         return ESP_OK;
1135     } else {
1136         return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
1137     }
1138 #else
1139     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
1140 #endif
1141 }
1142
1143 static esp_err_t tcpip_adapter_set_hostname_api(tcpip_adapter_api_msg_t * msg)
1144 {
1145     const char *hostname = (char*) msg->data;
1146
1147     return tcpip_adapter_set_hostname(msg->tcpip_if, hostname);
1148 }
1149
1150 esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname)
1151 {
1152 #if LWIP_NETIF_HOSTNAME
1153     struct netif *p_netif = NULL;
1154     if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) {
1155         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
1156     }
1157
1158     p_netif = esp_netif[tcpip_if];
1159     if (p_netif != NULL) {
1160         *hostname = p_netif->hostname;
1161         return ESP_OK;
1162     } else {
1163         return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
1164     }
1165 #else
1166     return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
1167 #endif
1168 }
1169
1170 static esp_err_t tcpip_adapter_reset_ip_info(tcpip_adapter_if_t tcpip_if)
1171 {
1172     ip4_addr_set_zero(&esp_ip[tcpip_if].ip);
1173     ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
1174     ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
1175     return ESP_OK;
1176 }
1177
1178 #endif /* CONFIG_TCPIP_LWIP */