1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "tcpip_adapter.h"
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"
28 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
31 #include "netif/wlanif.h"
32 #include "netif/ethernetif.h"
34 #include "apps/dhcpserver.h"
36 #include "esp_event.h"
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];
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};
45 #define TCPIP_ADAPTER_DEBUG(...)
46 //#define TCPIP_ADAPTER_DEBUG printf
48 void tcpip_adapter_init(void)
50 static bool tcpip_inited = false;
52 if (tcpip_inited == false) {
55 tcpip_init(NULL, NULL);
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);
63 esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
65 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL || ip_info == NULL) {
66 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
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;
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);
82 if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
83 netif_set_up(esp_netif[tcpip_if]);
85 if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) {
86 dhcps_start(esp_netif[tcpip_if], ip_info->ip);
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));
91 dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
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]);
107 esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
109 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
110 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
113 if (esp_netif[tcpip_if] == NULL) {
114 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
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;
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]);
127 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
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);
134 netif_remove(esp_netif[tcpip_if]);
136 free(esp_netif[tcpip_if]);
137 esp_netif[tcpip_if] = NULL;
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]);
147 esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
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;
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]);
162 esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
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;
169 if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) {
170 dhcp_stop(esp_netif[tcpip_if]);
172 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
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);
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);
182 netif_set_down(esp_netif[tcpip_if]);
188 esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
190 struct netif *p_netif;
192 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL) {
193 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
196 p_netif = esp_netif[tcpip_if];
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));
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);
213 esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
215 struct netif *p_netif;
216 tcpip_adapter_dhcp_status_t status;
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;
223 if (tcpip_if == TCPIP_ADAPTER_IF_AP) {
224 tcpip_adapter_dhcps_get_status(tcpip_if, &status);
226 if (status != TCPIP_ADAPTER_DHCP_STOPPED) {
227 return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED;
229 } else if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
230 tcpip_adapter_dhcpc_get_status(tcpip_if, &status);
232 if (status != TCPIP_ADAPTER_DHCP_STOPPED) {
233 return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED;
235 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
237 for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) {
238 dns_setserver(numdns, NULL);
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);
247 p_netif = esp_netif[tcpip_if];
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);
256 static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex)
258 tcpip_adapter_ip6_info_t *ip6_info;
261 TCPIP_ADAPTER_DEBUG("null p_netif=%p\n", p_netif);
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];
275 ip6_addr_set(&ip6_info->ip, ip_2_ip6(&p_netif->ip6_addr[ip_idex]));
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);
283 esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
285 struct netif *p_netif;
287 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
288 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
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);
302 esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
304 struct netif *p_netif;
306 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || if_ip6 == NULL) {
307 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
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));
320 esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
322 struct netif *p_netif;
324 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) {
325 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
328 p_netif = esp_netif[tcpip_if];
330 if (p_netif != NULL) {
331 memcpy(mac, p_netif->hwaddr, NETIF_MAX_HWADDR_LEN);
336 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
339 esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t mac[6])
341 struct netif *p_netif;
343 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL) {
344 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
347 p_netif = esp_netif[tcpip_if];
349 if (p_netif != NULL) {
350 memcpy(p_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
355 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
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)
361 void *opt_info = dhcps_option_info(opt_id, opt_len);
363 if (opt_info == NULL || opt_val == NULL) {
364 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
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;
373 case IP_ADDRESS_LEASE_TIME: {
374 *(uint32_t *)opt_val = *(uint32_t *)opt_info;
377 case REQUESTED_IP_ADDRESS: {
378 memcpy(opt_val, opt_info, opt_len);
381 case ROUTER_SOLICITATION_ADDRESS: {
382 *(uint8_t *)opt_val = (*(uint8_t *)opt_info) & OFFER_ROUTER;
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;
394 case IP_ADDRESS_LEASE_TIME: {
395 if (*(uint32_t *)opt_val != 0) {
396 *(uint32_t *)opt_info = *(uint32_t *)opt_val;
398 *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF;
402 case REQUESTED_IP_ADDRESS: {
403 tcpip_adapter_ip_info_t info;
404 uint32_t softap_ip = 0;
405 uint32_t start_ip = 0;
407 dhcps_lease_t *poll = opt_val;
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);
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;
421 /*config ip information must be in the same segment as the local ip*/
423 if ((start_ip >> 8 != softap_ip)
424 || (end_ip >> 8 != softap_ip)) {
425 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
428 if (end_ip - start_ip > DHCPS_MAX_LEASE) {
429 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
433 memcpy(opt_info, opt_val, opt_len);
436 case ROUTER_SOLICITATION_ADDRESS: {
437 *(uint8_t *)opt_info = (*(uint8_t *)opt_val) & OFFER_ROUTER;
444 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
450 esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
452 *status = dhcps_status;
457 esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
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;
465 if (dhcps_status != TCPIP_ADAPTER_DHCP_STARTED) {
466 struct netif *p_netif = esp_netif[tcpip_if];
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");
476 TCPIP_ADAPTER_DEBUG("dhcp server re init\n");
477 dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
482 TCPIP_ADAPTER_DEBUG("dhcp server already start\n");
483 return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
486 esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
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;
494 if (dhcps_status == TCPIP_ADAPTER_DHCP_STARTED) {
495 struct netif *p_netif = esp_netif[tcpip_if];
497 if (p_netif != NULL) {
500 TCPIP_ADAPTER_DEBUG("dhcp server if not ready\n");
501 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
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;
508 TCPIP_ADAPTER_DEBUG("dhcp server stop successfully\n");
509 dhcps_status = TCPIP_ADAPTER_DHCP_STOPPED;
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)
515 // TODO: when dhcp request timeout,change the retry count
519 static void tcpip_adapter_dhcpc_cb(struct netif *netif)
522 TCPIP_ADAPTER_DEBUG("null netif=%p\n", netif);
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);
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];
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) ) {
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));
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;
556 memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t));
558 esp_event_send(&evt);
560 TCPIP_ADAPTER_DEBUG("ip unchanged\n");
567 esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
569 *status = dhcpc_status[tcpip_if];
574 esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
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;
582 if (dhcpc_status[tcpip_if] != TCPIP_ADAPTER_DHCP_STARTED) {
583 struct netif *p_netif = esp_netif[tcpip_if];
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);
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);
596 TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
597 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
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;
606 dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb);
608 TCPIP_ADAPTER_DEBUG("dhcp client start successfully\n");
609 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED;
612 TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
613 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
618 TCPIP_ADAPTER_DEBUG("dhcp client already started\n");
619 return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
622 esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
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;
630 if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STARTED) {
631 struct netif *p_netif = esp_netif[tcpip_if];
633 if (p_netif != NULL) {
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);
640 TCPIP_ADAPTER_DEBUG("dhcp client if not ready\n");
641 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
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;
648 TCPIP_ADAPTER_DEBUG("dhcp client stop successfully\n");
649 dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
653 esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
655 ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len);
659 esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb)
661 wlanif_input(esp_netif[TCPIP_ADAPTER_IF_STA], buffer, len, eb);
665 esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb)
667 wlanif_input(esp_netif[TCPIP_ADAPTER_IF_AP], buffer, len, eb);
672 bool tcpip_dep_output(wifi_interface_t wifi_if, void *buffer, uint16_t len)
679 esp_interface_t tcpip_adapter_get_esp_if(void *dev)
681 struct netif *p_netif = (struct netif *)dev;
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]) {
694 esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list)
698 if ((wifi_sta_list == NULL) || (tcpip_sta_list == NULL)) {
699 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
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);
712 esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
714 #if LWIP_NETIF_HOSTNAME
715 struct netif *p_netif;
716 static char hostinfo[TCPIP_HOSTNAME_MAX_SIZE + 1][TCPIP_ADAPTER_IF_MAX];
718 if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) {
719 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
722 if (strlen(hostname) > TCPIP_HOSTNAME_MAX_SIZE) {
723 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
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];
733 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
736 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
740 esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname)
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;
748 p_netif = esp_netif[tcpip_if];
749 if (p_netif != NULL) {
750 *hostname = p_netif->hostname;
753 return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
756 return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;