1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <lwip/ip_addr.h>
9 #include <lwip/sockets.h>
10
11 #include "esp_check.h"
12 #include "esp_netif_lwip_internal.h"
13
14 #include "esp_netif.h"
15 #include "esp_netif_private.h"
16
17 #if CONFIG_ESP_NETIF_TCPIP_LWIP
18
19 #include "lwip/tcpip.h"
20 #include "lwip/dhcp.h"
21 #include "lwip/ip_addr.h"
22 #include "lwip/ip6_addr.h"
23 #include "lwip/mld6.h"
24 #include "lwip/nd6.h"
25 #include "lwip/priv/tcpip_priv.h"
26 #include "lwip/netif.h"
27 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
28 #include "lwip/dns.h"
29 #endif
30
31 #if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
32 #include "lwip_default_hooks.h"
33 #endif
34
35 #include "esp_netif_lwip_ppp.h"
36 #include "esp_netif_lwip_slip.h"
37 #include "dhcpserver/dhcpserver.h"
38 #include "dhcpserver/dhcpserver_options.h"
39
40 #include "esp_event.h"
41 #include "esp_log.h"
42
43 //
44 // This is the main module implementing lwip interaction with esp-netif
45 //
46
47 #define ESP_NETIF_HOSTNAME_MAX_SIZE 32
48
49 /**
50 * @brief lwip thread safe tcpip function utility macros
51 */
52 #define _RUN_IN_LWIP_TASK(function, netif, param) { return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); }
53
54 /**
55 * @brief macros to check netif related data to evaluate interface type
56 */
57 #if CONFIG_PPP_SUPPORT || CONFIG_LWIP_SLIP_SUPPORT
58 #define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) (netif->related_data && netif->related_data->is_point2point)
59 #else
60 #define _IS_NETIF_ANY_POINT2POINT_TYPE(netif) false
61 #endif
62 #define _RUN_IN_LWIP_TASK_IF_SUPPORTED(function, netif, param) \
63 { \
64 if (_IS_NETIF_ANY_POINT2POINT_TYPE(netif)) { \
65 return ESP_ERR_NOT_SUPPORTED; \
66 } \
67 return esp_netif_lwip_ipc_call(function, netif, (void *)(param)); \
68 }
69
70 /**
71 * @brief If netif protocol not enabled in menuconfig, log the error and return appropriate code indicating failure
72 */
73
74 #define LOG_NETIF_DISABLED_AND_DO(proto, action) \
75 do { \
76 ESP_LOGE(TAG, "%s not supported, please enable it in lwIP component configuration", proto); \
77 action; \
78 } while(0)
79
80 //
81 // Internal types
82 //
83 typedef enum esp_netif_action {
84 ESP_NETIF_UNDEF,
85 ESP_NETIF_STARTED,
86 ESP_NETIF_STOPPED,
87 } esp_netif_action_t;
88
89 //
90 // Internal variables for this module
91 //
92 extern sys_thread_t g_lwip_task;
93
94 static const char *TAG = "esp_netif_lwip";
95
96 static bool tcpip_initialized = false;
97 static esp_netif_t *s_last_default_esp_netif = NULL;
98
99 #if !LWIP_TCPIP_CORE_LOCKING
100 static sys_sem_t api_sync_sem = NULL;
101 static sys_sem_t api_lock_sem = NULL;
102
103 /**
104 * @brief Api callback from tcpip thread used to call esp-netif
105 * function in lwip task context
106 */
esp_netif_api_cb(void * api_msg)107 static void esp_netif_api_cb(void *api_msg)
108 {
109 esp_netif_api_msg_t *msg = (esp_netif_api_msg_t *)api_msg;
110
111 if (!msg || !msg->api_fn) {
112 ESP_LOGD(TAG, "null msg/api_fn");
113 return;
114 }
115
116 msg->ret = msg->api_fn(msg);
117 ESP_LOGD(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret);
118 sys_sem_signal(&api_sync_sem);
119
120 }
121 #endif
122
123 /**
124 * @brief Initiates a tcpip remote call if called from another task
125 * or calls the function directly if executed from lwip task
126 */
esp_netif_lwip_ipc_call(esp_netif_api_fn fn,esp_netif_t * netif,void * data)127 static inline esp_err_t esp_netif_lwip_ipc_call(esp_netif_api_fn fn, esp_netif_t *netif, void *data)
128 {
129 esp_netif_api_msg_t msg = {
130 .esp_netif = netif,
131 .data = data,
132 .api_fn = fn
133 };
134 #if !LWIP_TCPIP_CORE_LOCKING
135 if (g_lwip_task != xTaskGetCurrentTaskHandle()) {
136 ESP_LOGD(TAG, "check: remote, if=%p fn=%p\n", netif, fn);
137 sys_arch_sem_wait(&api_lock_sem, 0);
138 tcpip_send_msg_wait_sem((tcpip_callback_fn)esp_netif_api_cb, &msg, &api_sync_sem);
139 sys_sem_signal(&api_lock_sem);
140 return msg.ret;
141 }
142 #endif /* !LWIP_TCPIP_CORE_LOCKING */
143 ESP_LOGD(TAG, "check: local, if=%p fn=%p\n", netif, fn);
144 return fn(&msg);
145 }
146
147 /**
148 * @brief Check if supplied esp_netif handle is active, i.e. available within registered interfaces
149 * as it might have already been destroyed. Returns the supplied handle if active, nullptr otherwise
150 *
151 * @param esp_netif handle to check if available in the list of registered interfaces
152 * @return esp_netif handle if available, or NULL if it wasn't found
153 */
esp_netif_is_active(esp_netif_t * arg)154 static esp_netif_t* esp_netif_is_active(esp_netif_t *arg)
155 {
156 // looking for the netif in the list of registered interfaces
157 // as it might have already been destroyed
158 if (esp_netif_is_netif_listed(arg)) {
159 return arg;
160 }
161 return NULL;
162 }
163
164 /**
165 * @brief This function sets default netif no matter which implementation used
166 *
167 * @param esp_netif handle to network interface
168 *
169 * @note: This function must be called from lwip thread
170 */
esp_netif_set_default_netif(esp_netif_t * esp_netif)171 static void esp_netif_set_default_netif(esp_netif_t *esp_netif)
172 {
173 if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
174 #if CONFIG_PPP_SUPPORT
175 esp_netif_ppp_set_default_netif(esp_netif->netif_handle);
176 #endif
177 } else {
178 netif_set_default(esp_netif->lwip_netif);
179 }
180 }
181
182 /**
183 * @brief tcpip thread version of esp_netif_update_default_netif
184 *
185 * @note This function and all functions called from this must be called from lwip task context
186 */
esp_netif_update_default_netif_lwip(esp_netif_api_msg_t * msg)187 static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg)
188 {
189 esp_netif_t *esp_netif = msg->esp_netif;
190 esp_netif_action_t action = (esp_netif_action_t)msg->data;
191
192 ESP_LOGD(TAG, "%s %p", __func__, esp_netif);
193
194 switch (action) {
195 case ESP_NETIF_STARTED:
196 {
197 // check if previously default interface hasn't been destroyed in the meantime
198 s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif);
199 if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)
200 && (s_last_default_esp_netif->route_prio > esp_netif->route_prio)) {
201 esp_netif_set_default_netif(s_last_default_esp_netif);
202 } else if (esp_netif_is_netif_up(esp_netif)) {
203 s_last_default_esp_netif = esp_netif;
204 esp_netif_set_default_netif(s_last_default_esp_netif);
205 }
206 }
207 break;
208
209 default:
210 case ESP_NETIF_STOPPED:
211 {
212 s_last_default_esp_netif = NULL;
213 esp_netif_list_lock();
214 esp_netif_t *netif = esp_netif_next_unsafe(NULL);
215 while (netif) {
216 if (esp_netif_is_netif_up(netif)) {
217 if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) {
218 if (netif->route_prio > s_last_default_esp_netif->route_prio) {
219 s_last_default_esp_netif = netif;
220 } // else not needed, as the s_last_default_esp_netif is correct
221 } else {
222 // s_last_default is either not set or down, current netif is up
223 s_last_default_esp_netif = netif;
224 }
225 }
226 netif = esp_netif_next_unsafe(netif);
227 }
228 esp_netif_list_unlock();
229 if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) {
230 esp_netif_set_default_netif(s_last_default_esp_netif);
231 }
232 }
233 break;
234 }
235 return ESP_OK;
236 }
237
238 /**
239 * @brief This function sets default routing netif based on priorities of all interfaces which are up
240 *
241 * @param esp_netif current interface which just updated state
242 * @param action updating action (on-off)
243 */
esp_netif_update_default_netif(esp_netif_t * esp_netif,esp_netif_action_t action)244 static esp_err_t esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_action_t action)
245 {
246 return esp_netif_lwip_ipc_call(esp_netif_update_default_netif_lwip, esp_netif, (void*)action);
247 }
248
esp_netif_set_ip4_addr(esp_ip4_addr_t * addr,uint8_t a,uint8_t b,uint8_t c,uint8_t d)249 void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
250 {
251 ip4_addr_t *address = (ip4_addr_t*)addr;
252 IP4_ADDR(address, a, b, c, d);
253 }
254
esp_ip4addr_ntoa(const esp_ip4_addr_t * addr,char * buf,int buflen)255 char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen)
256 {
257 return ip4addr_ntoa_r((ip4_addr_t *)addr, buf, buflen);
258 }
259
esp_ip4addr_aton(const char * addr)260 uint32_t esp_ip4addr_aton(const char *addr)
261 {
262 return ipaddr_addr(addr);
263 }
264
esp_netif_str_to_ip4(const char * src,esp_ip4_addr_t * dst)265 esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst)
266 {
267 if (src == NULL || dst == NULL) {
268 return ESP_ERR_INVALID_ARG;
269 }
270 int err = inet_pton(AF_INET, src, dst);
271 return err == 1 ? ESP_OK : ESP_FAIL;
272 }
273
esp_netif_str_to_ip6(const char * src,esp_ip6_addr_t * dst)274 esp_err_t esp_netif_str_to_ip6(const char *src, esp_ip6_addr_t *dst)
275 {
276 if (src == NULL || dst == NULL) {
277 return ESP_ERR_INVALID_ARG;
278 }
279 int err = inet_pton(AF_INET6, src, dst);
280 return err == 1 ? ESP_OK : ESP_FAIL;
281 }
282
esp_netif_get_io_driver(esp_netif_t * esp_netif)283 esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif)
284 {
285 return esp_netif->driver_handle;
286 }
287
esp_netif_get_handle_from_netif_impl(void * dev)288 esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev)
289 {
290 // ppp_pcb ptr would never get to app code, so this function only works with vanilla lwip impl
291 struct netif *lwip_netif = dev;
292 return lwip_netif->state;
293 }
294
esp_netif_get_netif_impl(esp_netif_t * esp_netif)295 void* esp_netif_get_netif_impl(esp_netif_t *esp_netif)
296 {
297 // get impl ptr only for vanilla lwip impl (ppp_pcb not supported)
298 if (esp_netif && !_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
299 return esp_netif->lwip_netif;
300 }
301 return NULL;
302 }
303
esp_netif_init(void)304 esp_err_t esp_netif_init(void)
305 {
306 if (tcpip_initialized == false) {
307 tcpip_initialized = true;
308 #if CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT
309 uint8_t rand_buf[16];
310 /*
311 * This is early startup code where WiFi/BT is yet to be enabled and hence
312 * relevant entropy source is not available. However, bootloader enables
313 * SAR ADC based entropy source at its initialization, and our requirement
314 * of random bytes is pretty small (16), so we can assume that following
315 * API will provide sufficiently random data.
316 */
317 esp_fill_random(rand_buf, sizeof(rand_buf));
318 lwip_init_tcp_isn(esp_log_timestamp(), rand_buf);
319 #endif
320 tcpip_init(NULL, NULL);
321 ESP_LOGD(TAG, "LwIP stack has been initialized");
322 }
323
324 #if !LWIP_TCPIP_CORE_LOCKING
325 if (!api_sync_sem) {
326 if (ERR_OK != sys_sem_new(&api_sync_sem, 0)) {
327 ESP_LOGE(TAG, "esp netif api sync sem init fail");
328 return ESP_FAIL;
329 }
330 }
331
332 if (!api_lock_sem) {
333 if (ERR_OK != sys_sem_new(&api_lock_sem, 1)) {
334 ESP_LOGE(TAG, "esp netif api lock sem init fail");
335 return ESP_FAIL;
336 }
337 }
338 #endif
339
340 ESP_LOGD(TAG, "esp-netif has been successfully initialized");
341 return ESP_OK;
342 }
343
esp_netif_deinit(void)344 esp_err_t esp_netif_deinit(void)
345 {
346 if (tcpip_initialized == true) {
347 /* deinit of LwIP not supported:
348 * do not deinit semaphores and states,
349 * so init could be called multiple times
350 *
351 tcpip_initialized = false;
352 sys_sem_free(&api_sync_sem);
353 sys_sem_free(&api_lock_sem);
354 */
355 return ESP_ERR_NOT_SUPPORTED;
356
357 }
358 return ESP_ERR_INVALID_STATE;
359 }
360
esp_netif_init_configuration(esp_netif_t * esp_netif,const esp_netif_config_t * cfg)361 static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_netif_config_t *cfg)
362 {
363 // Basic esp_netif and lwip is a mandatory configuration and cannot be updated after esp_netif_new()
364 if (cfg == NULL || cfg->base == NULL || cfg->stack == NULL) {
365 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
366 }
367
368 // Configure general esp-netif properties
369 memcpy(esp_netif->mac, cfg->base->mac, NETIF_MAX_HWADDR_LEN);
370 if (cfg->base->ip_info == NULL) {
371 ip4_addr_set_zero(&esp_netif->ip_info->ip);
372 ip4_addr_set_zero(&esp_netif->ip_info->gw);
373 ip4_addr_set_zero(&esp_netif->ip_info->netmask);
374 } else {
375 memcpy(esp_netif->ip_info, cfg->base->ip_info, sizeof(esp_netif_ip_info_t));
376 }
377 memcpy(esp_netif->ip_info_old, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
378
379 // Setup main config parameters
380 esp_netif->lost_ip_event = cfg->base->lost_ip_event;
381 esp_netif->get_ip_event = cfg->base->get_ip_event;
382 esp_netif->flags = cfg->base->flags;
383
384 if (cfg->base->if_key) {
385 esp_netif->if_key = strdup(cfg->base->if_key);
386 }
387 if (cfg->base->if_desc) {
388 esp_netif->if_desc = strdup(cfg->base->if_desc);
389 }
390 if (cfg->base->route_prio) {
391 esp_netif->route_prio = cfg->base->route_prio;
392 }
393
394 // Install network stack functions -- connects netif and L3 stack
395 const esp_netif_netstack_config_t *esp_netif_stack_config = cfg->stack;
396 if (cfg->base->flags & ESP_NETIF_FLAG_IS_PPP) {
397 #if CONFIG_PPP_SUPPORT
398 esp_netif->related_data = esp_netif_new_ppp(esp_netif, esp_netif_stack_config);
399 if (esp_netif->related_data == NULL) {
400 return ESP_ERR_ESP_NETIF_INIT_FAILED;
401 }
402 esp_netif->lwip_input_fn = esp_netif_stack_config->lwip_ppp.input_fn;
403 // Make the netif handle (used for tcpip input function) the ppp_netif
404 esp_netif->netif_handle = esp_netif->related_data;
405 #else
406 LOG_NETIF_DISABLED_AND_DO("PPP", return ESP_ERR_NOT_SUPPORTED);
407 #endif
408 } else if (cfg->base->flags & ESP_NETIF_FLAG_IS_SLIP) {
409 #if CONFIG_LWIP_SLIP_SUPPORT
410 esp_netif->related_data = esp_netif_new_slip(esp_netif, esp_netif_stack_config);
411 if (esp_netif->related_data == NULL) {
412 return ESP_ERR_ESP_NETIF_INIT_FAILED;
413 }
414 if (esp_netif_stack_config->lwip.init_fn) {
415 esp_netif->lwip_init_fn = esp_netif_stack_config->lwip.init_fn;
416 }
417 if (esp_netif_stack_config->lwip.input_fn) {
418 esp_netif->lwip_input_fn = esp_netif_stack_config->lwip.input_fn;
419 }
420 // Make the netif handle (used for tcpip input function) the esp_netif itself
421 esp_netif->netif_handle = esp_netif;
422 #else
423 LOG_NETIF_DISABLED_AND_DO("SLIP", return ESP_ERR_NOT_SUPPORTED);
424 #endif
425 } else {
426 if (esp_netif_stack_config-> lwip.init_fn) {
427 esp_netif->lwip_init_fn = esp_netif_stack_config->lwip.init_fn;
428 }
429 if (esp_netif_stack_config->lwip.input_fn) {
430 esp_netif->lwip_input_fn = esp_netif_stack_config->lwip.input_fn;
431 }
432 // Make the netif handle (used for tcpip input function) the lwip_netif itself
433 esp_netif->netif_handle = esp_netif->lwip_netif;
434
435 }
436
437 // Install IO functions only if provided -- connects driver and netif
438 // this configuration could be updated after esp_netif_new(), typically in post_attach callback
439 if (cfg->driver) {
440 const esp_netif_driver_ifconfig_t *esp_netif_driver_config = cfg->driver;
441 if (esp_netif_driver_config->handle) {
442 esp_netif->driver_handle = esp_netif_driver_config->handle;
443 }
444 if (esp_netif_driver_config->transmit) {
445 esp_netif->driver_transmit = esp_netif_driver_config->transmit;
446 }
447 if (esp_netif_driver_config->transmit_wrap) {
448 esp_netif->driver_transmit_wrap = esp_netif_driver_config->transmit_wrap;
449 }
450 if (esp_netif_driver_config->driver_free_rx_buffer) {
451 esp_netif->driver_free_rx_buffer = esp_netif_driver_config->driver_free_rx_buffer;
452 }
453 }
454 return ESP_OK;
455 }
456
esp_netif_new(const esp_netif_config_t * esp_netif_config)457 esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
458 {
459 // mandatory configuration must be provided when creating esp_netif object
460 if (esp_netif_config == NULL ||
461 esp_netif_config->base->if_key == NULL ||
462 NULL != esp_netif_get_handle_from_ifkey(esp_netif_config->base->if_key)) {
463 ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (config or if_key is NULL or duplicate key)",
464 __func__, esp_netif_config);
465 return NULL;
466 }
467
468 // Create parent esp-netif object
469 esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj));
470 if (!esp_netif) {
471 ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(struct esp_netif_obj),
472 esp_get_free_heap_size());
473 return NULL;
474 }
475
476 // Create ip info
477 esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
478 if (!ip_info) {
479 ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(esp_netif_ip_info_t),
480 esp_get_free_heap_size());
481 free(esp_netif);
482 return NULL;
483 }
484 esp_netif->ip_info = ip_info;
485
486 // creating another ip info (to store old ip)
487 ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
488 if (!ip_info) {
489 ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(esp_netif_ip_info_t),
490 esp_get_free_heap_size());
491 free(esp_netif->ip_info);
492 free(esp_netif);
493 return NULL;
494 }
495 esp_netif->ip_info_old = ip_info;
496
497 // Create underlying lwip netif
498 struct netif * lwip_netif = calloc(1, sizeof(struct netif));
499 if (!lwip_netif) {
500 ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(struct netif),
501 esp_get_free_heap_size());
502 free(esp_netif->ip_info_old);
503 free(esp_netif->ip_info);
504 free(esp_netif);
505 return NULL;
506 }
507
508 lwip_netif->state = esp_netif;
509 esp_netif->lwip_netif = lwip_netif;
510
511 esp_netif_add_to_list(esp_netif);
512
513 // Configure the created object with provided configuration
514 esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config);
515 if (ret != ESP_OK) {
516 ESP_LOGE(TAG, "Initial configuration of esp_netif failed with %d", ret);
517 esp_netif_destroy(esp_netif);
518 return NULL;
519 }
520
521 return esp_netif;
522 }
523
esp_netif_lwip_remove(esp_netif_t * esp_netif)524 static void esp_netif_lwip_remove(esp_netif_t *esp_netif)
525 {
526 if (esp_netif->lwip_netif) {
527 if (netif_is_up(esp_netif->lwip_netif)) {
528 netif_set_down(esp_netif->lwip_netif);
529 }
530 netif_remove(esp_netif->lwip_netif);
531 }
532 }
533
esp_netif_lwip_add(esp_netif_t * esp_netif)534 static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif)
535 {
536 if (esp_netif->lwip_netif == NULL) {
537 esp_netif->lwip_netif = calloc(1, sizeof(struct netif));
538 if (esp_netif->lwip_netif == NULL) {
539 return ESP_ERR_NO_MEM;
540 }
541 }
542 if (esp_netif->flags & ESP_NETIF_FLAG_IS_PPP) {
543 #if CONFIG_PPP_SUPPORT
544 err_t err = esp_netif->lwip_init_fn(NULL);
545 if (err != ERR_OK) {
546 ESP_LOGE(TAG, "Init netif failed with %d", err);
547 return ESP_ERR_ESP_NETIF_INIT_FAILED;
548 }
549 #else
550 LOG_NETIF_DISABLED_AND_DO("PPP", return ESP_ERR_NOT_SUPPORTED);
551 #endif
552 }
553
554 if (NULL == netif_add(esp_netif->lwip_netif, (struct ip4_addr*)&esp_netif->ip_info->ip,
555 (struct ip4_addr*)&esp_netif->ip_info->netmask, (struct ip4_addr*)&esp_netif->ip_info->gw,
556 esp_netif, esp_netif->lwip_init_fn, tcpip_input)) {
557 esp_netif_lwip_remove(esp_netif);
558 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
559 }
560 return ESP_OK;
561 }
562
esp_netif_destroy_related(esp_netif_t * esp_netif)563 static void esp_netif_destroy_related(esp_netif_t *esp_netif)
564 {
565 if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
566 #if CONFIG_PPP_SUPPORT
567 esp_netif_destroy_ppp(esp_netif->related_data);
568 #endif
569 } else if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, SLIP_LWIP_NETIF)) {
570 #if CONFIG_LWIP_SLIP_SUPPORT
571 esp_netif_destroy_slip(esp_netif->related_data);
572 #endif
573 }
574 }
575
esp_netif_destroy(esp_netif_t * esp_netif)576 void esp_netif_destroy(esp_netif_t *esp_netif)
577 {
578 if (esp_netif) {
579 esp_netif_remove_from_list(esp_netif);
580 free(esp_netif->ip_info);
581 free(esp_netif->ip_info_old);
582 free(esp_netif->if_key);
583 free(esp_netif->if_desc);
584 esp_netif_lwip_remove(esp_netif);
585 esp_netif_destroy_related(esp_netif);
586 free(esp_netif->lwip_netif);
587 free(esp_netif->hostname);
588 if (s_last_default_esp_netif == esp_netif) {
589 // clear last default netif if it happens to be this just destroyed interface
590 s_last_default_esp_netif = NULL;
591 }
592 free(esp_netif);
593 }
594 }
595
esp_netif_attach(esp_netif_t * esp_netif,esp_netif_iodriver_handle driver_handle)596 esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle)
597 {
598 esp_netif_driver_base_t *base_driver = driver_handle;
599
600 esp_netif->driver_handle = driver_handle;
601 if (base_driver->post_attach) {
602 esp_err_t ret = base_driver->post_attach(esp_netif, driver_handle);
603 if (ret != ESP_OK) {
604 ESP_LOGE(TAG, "Post-attach callback of driver(%p) failed with %d", driver_handle, ret);
605 return ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED;
606 }
607 }
608 return ESP_OK;
609 }
610
esp_netif_set_driver_config(esp_netif_t * esp_netif,const esp_netif_driver_ifconfig_t * driver_config)611 esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif,
612 const esp_netif_driver_ifconfig_t *driver_config)
613 {
614 if (esp_netif == NULL || driver_config == NULL) {
615 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
616 }
617 esp_netif->driver_handle = driver_config->handle;
618 esp_netif->driver_transmit = driver_config->transmit;
619 esp_netif->driver_transmit_wrap = driver_config->transmit_wrap;
620 esp_netif->driver_free_rx_buffer = driver_config->driver_free_rx_buffer;
621 return ESP_OK;
622 }
623
esp_netif_reset_ip_info(esp_netif_t * esp_netif)624 static esp_err_t esp_netif_reset_ip_info(esp_netif_t *esp_netif)
625 {
626 ip4_addr_set_zero(&(esp_netif->ip_info->ip));
627 ip4_addr_set_zero(&(esp_netif->ip_info->gw));
628 ip4_addr_set_zero(&(esp_netif->ip_info->netmask));
629 return ESP_OK;
630 }
631
esp_netif_set_mac(esp_netif_t * esp_netif,uint8_t mac[])632 esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[])
633 {
634 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
635 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
636 }
637 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
638 return ESP_ERR_NOT_SUPPORTED;
639 }
640 memcpy(esp_netif->mac, mac, NETIF_MAX_HWADDR_LEN);
641 memcpy(esp_netif->lwip_netif->hwaddr, mac, NETIF_MAX_HWADDR_LEN);
642 return ESP_OK;
643 }
644
esp_netif_get_mac(esp_netif_t * esp_netif,uint8_t mac[])645 esp_err_t esp_netif_get_mac(esp_netif_t *esp_netif, uint8_t mac[])
646 {
647 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
648 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
649 }
650 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
651 return ESP_ERR_NOT_SUPPORTED;
652 }
653 if (esp_netif_is_netif_up(esp_netif)) {
654 memcpy(mac, esp_netif->lwip_netif->hwaddr, NETIF_MAX_HWADDR_LEN);
655 return ESP_OK;
656 }
657 memcpy(mac, esp_netif->mac, NETIF_MAX_HWADDR_LEN);
658 return ESP_OK;
659 }
660
661 #if ESP_DHCPS
esp_netif_dhcps_cb(u8_t client_ip[4])662 static void esp_netif_dhcps_cb(u8_t client_ip[4])
663 {
664 ESP_LOGI(TAG, "DHCP server assigned IP to a station, IP is: %d.%d.%d.%d",
665 client_ip[0], client_ip[1], client_ip[2], client_ip[3]);
666 ip_event_ap_staipassigned_t evt;
667
668 memset(&evt, 0, sizeof(ip_event_ap_staipassigned_t));
669 memcpy((char *)&evt.ip.addr, (char *)client_ip, sizeof(evt.ip.addr));
670 int ret = esp_event_send_internal(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, &evt, sizeof(evt), 0);
671 if (ESP_OK != ret) {
672 ESP_LOGE(TAG, "dhcps cb: failed to post IP_EVENT_AP_STAIPASSIGNED (%x)", ret);
673 }
674 }
675 #endif
676
esp_netif_config_sanity_check(const esp_netif_t * esp_netif)677 static esp_err_t esp_netif_config_sanity_check(const esp_netif_t * esp_netif)
678 {
679 if (esp_netif == NULL) {
680 ESP_LOGE(TAG, "Cannot start esp_netif: esp_netif must not be null");
681 return ESP_ERR_INVALID_STATE;
682 }
683
684 if (esp_netif->driver_transmit == NULL ||
685 esp_netif->driver_handle == NULL ||
686 esp_netif->lwip_input_fn == NULL ||
687 esp_netif->lwip_init_fn == NULL) {
688 ESP_LOGE(TAG, "Cannot start esp_netif: Missing mandatory configuration:\n"
689 "esp_netif->driver_transmit: %p, esp_netif->driver_handle:%p, "
690 "esp_netif->lwip_input_fn: %p, esp_netif->lwip_init_fn:%p",
691 esp_netif->driver_transmit, esp_netif->driver_handle,
692 esp_netif->lwip_input_fn, esp_netif->lwip_init_fn);
693
694 return ESP_ERR_INVALID_STATE;
695 }
696 return ESP_OK;
697 }
698
esp_netif_start_api(esp_netif_api_msg_t * msg)699 static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg)
700 {
701 esp_netif_t * esp_netif = msg->esp_netif;
702
703 ESP_LOGD(TAG, "%s %p", __func__, esp_netif);
704
705 ESP_ERROR_CHECK(esp_netif_config_sanity_check(esp_netif));
706
707 ESP_ERROR_CHECK(esp_netif_lwip_add(esp_netif));
708
709 if (esp_netif->flags&ESP_NETIF_FLAG_GARP) {
710 #if ESP_GRATUITOUS_ARP
711 netif_set_garp_flag(esp_netif->lwip_netif);
712 #else
713 ESP_LOGW(TAG,"CONFIG_LWIP_ESP_GRATUITOUS_ARP not enabled, but esp-netif configured with ESP_NETIF_FLAG_GARP");
714 #endif
715 }
716 struct netif *p_netif = esp_netif->lwip_netif;
717 if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, SLIP_LWIP_NETIF)) {
718 #if CONFIG_LWIP_SLIP_SUPPORT
719 esp_netif_start_slip(esp_netif);
720 #endif
721 }
722 if (esp_netif->flags&ESP_NETIF_FLAG_AUTOUP) {
723 ESP_LOGD(TAG, "%s Setting the lwip netif%p UP", __func__, p_netif);
724 netif_set_up(p_netif);
725 }
726 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
727 #if ESP_DHCPS
728 if (esp_netif->dhcps_status == ESP_NETIF_DHCP_INIT) {
729 if (p_netif != NULL && netif_is_up(p_netif)) {
730 esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
731 ip4_addr_t lwip_ip;
732 ip4_addr_t lwip_netmask;
733 memcpy(&lwip_ip, &default_ip->ip, sizeof(struct ip4_addr));
734 memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
735 dhcps_set_new_lease_cb(esp_netif_dhcps_cb);
736 dhcps_set_option_info(SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
737 dhcps_start(p_netif, lwip_ip);
738 esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
739 ESP_LOGD(TAG, "DHCP server started successfully");
740 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
741 return ESP_OK;
742 } else {
743 ESP_LOGD(TAG, "DHCP server re init");
744 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
745 return ESP_OK;
746 }
747 } else if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
748 ESP_LOGD(TAG, "DHCP server already started");
749 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
750 }
751 return ESP_OK;
752 #else
753 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
754 #endif
755 } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
756 if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STARTED) {
757 if (p_netif != NULL) {
758 struct dhcp *dhcp_data = NULL;
759 dhcp_data = netif_dhcp_data(p_netif);
760 if (dhcp_data == NULL) {
761 dhcp_data = (struct dhcp *)malloc(sizeof(struct dhcp));
762 if (dhcp_data == NULL) {
763 return ESP_ERR_NO_MEM;
764 }
765 dhcp_set_struct(p_netif, dhcp_data);
766 }
767 }
768 }
769 }
770
771 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
772
773 return ESP_OK;
774 }
775
esp_netif_start(esp_netif_t * esp_netif)776 esp_err_t esp_netif_start(esp_netif_t *esp_netif)
777 {
778 if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
779 #if CONFIG_PPP_SUPPORT
780 // No need to start PPP interface in lwip thread
781 esp_err_t ret = esp_netif_start_ppp(esp_netif);
782 if (ret == ESP_OK) {
783 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
784 }
785 return ret;
786 #endif
787 }
788 return esp_netif_lwip_ipc_call(esp_netif_start_api, esp_netif, NULL);
789 }
790
esp_netif_stop_api(esp_netif_api_msg_t * msg)791 static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg)
792 {
793 esp_netif_t *esp_netif = msg->esp_netif;
794
795 struct netif *lwip_netif = esp_netif->lwip_netif;
796 if (lwip_netif == NULL) {
797 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
798 }
799
800 if (!netif_is_up(lwip_netif)) {
801 esp_netif_lwip_remove(esp_netif);
802 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
803 }
804
805 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
806 #if ESP_DHCPS
807 dhcps_stop(lwip_netif); // TODO(IDF-1099): dhcps checks status by its self
808 if (ESP_NETIF_DHCP_STOPPED != esp_netif->dhcps_status) {
809 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
810 }
811 #else
812 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
813 #endif
814 } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
815 dhcp_release(lwip_netif);
816 dhcp_stop(lwip_netif);
817 dhcp_cleanup(lwip_netif);
818
819 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
820
821 esp_netif_reset_ip_info(esp_netif);
822 }
823
824 netif_set_down(lwip_netif);
825 esp_netif_lwip_remove(esp_netif);
826 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);;
827
828 return ESP_OK;
829 }
830
esp_netif_stop(esp_netif_t * esp_netif)831 esp_err_t esp_netif_stop(esp_netif_t *esp_netif)
832 {
833 if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) {
834 #if CONFIG_PPP_SUPPORT
835 // No need to stop PPP interface in lwip thread
836 esp_err_t ret = esp_netif_stop_ppp(esp_netif->related_data);
837 if (ret == ESP_OK) {
838 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);;
839 }
840 return ret;
841 #endif
842 } else if (_IS_NETIF_POINT2POINT_TYPE(esp_netif, SLIP_LWIP_NETIF)) {
843 #if CONFIG_LWIP_SLIP_SUPPORT
844 // No need to stop SLIP interface in lwip thread
845 esp_err_t ret = esp_netif_stop_slip(esp_netif);
846 if (ret == ESP_OK) {
847 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);;
848 }
849 return ret;
850 #endif
851 }
852 return esp_netif_lwip_ipc_call(esp_netif_stop_api, esp_netif, NULL);
853 }
854
esp_netif_netstack_buf_ref(void * pbuf)855 void esp_netif_netstack_buf_ref(void *pbuf)
856 {
857 pbuf_ref(pbuf);
858 }
859
esp_netif_netstack_buf_free(void * pbuf)860 void esp_netif_netstack_buf_free(void *pbuf)
861 {
862 pbuf_free(pbuf);
863 }
864
865 //
866 // IO translate functions
867 //
esp_netif_free_rx_buffer(void * h,void * buffer)868 void esp_netif_free_rx_buffer(void *h, void* buffer)
869 {
870 esp_netif_t *esp_netif = h;
871 esp_netif->driver_free_rx_buffer(esp_netif->driver_handle, buffer);
872 }
873
esp_netif_transmit(esp_netif_t * esp_netif,void * data,size_t len)874 esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len)
875 {
876 return (esp_netif->driver_transmit)(esp_netif->driver_handle, data, len);
877 }
878
esp_netif_transmit_wrap(esp_netif_t * esp_netif,void * data,size_t len,void * pbuf)879 esp_err_t esp_netif_transmit_wrap(esp_netif_t *esp_netif, void *data, size_t len, void *pbuf)
880 {
881 return (esp_netif->driver_transmit_wrap)(esp_netif->driver_handle, data, len, pbuf);
882 }
883
esp_netif_receive(esp_netif_t * esp_netif,void * buffer,size_t len,void * eb)884 esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
885 {
886 esp_netif->lwip_input_fn(esp_netif->netif_handle, buffer, len, eb);
887 return ESP_OK;
888 }
889
890 //
891 // DHCP:
892 //
893 static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif);
894
esp_netif_dhcpc_cb(struct netif * netif)895 static void esp_netif_dhcpc_cb(struct netif *netif)
896 {
897 if (!netif) {
898 ESP_LOGD(TAG, "null netif=%p", netif);
899 return;
900 }
901 ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, netif);
902
903 esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
904
905 esp_netif_ip_info_t *ip_info = esp_netif->ip_info;
906 esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info_old;
907
908
909 if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4) ) {
910
911 //check whether IP is changed
912 if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), (&ip_info->ip)) ||
913 !ip4_addr_cmp(ip_2_ip4(&netif->netmask), (&ip_info->netmask)) ||
914 !ip4_addr_cmp(ip_2_ip4(&netif->gw), (&ip_info->gw)) ) {
915 ip_event_got_ip_t evt = {
916 .esp_netif = esp_netif,
917 .if_index = -1, // invalid index, handle used
918 .ip_changed = false,
919 };
920 ip_event_t evt_id = esp_netif_get_event_id(esp_netif, ESP_NETIF_IP_EVENT_GOT_IP);
921 int ret;
922
923 ip4_addr_set(&ip_info->ip, ip_2_ip4(&netif->ip_addr));
924 ip4_addr_set(&ip_info->netmask, ip_2_ip4(&netif->netmask));
925 ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
926
927 //notify event
928 if (memcmp(ip_info, ip_info_old, sizeof(esp_netif_ip_info_t))) {
929 evt.ip_changed = true;
930 }
931
932 memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t));
933 memcpy(ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
934 ESP_LOGD(TAG, "if%p ip changed=%d", esp_netif, evt.ip_changed);
935 ret = esp_event_send_internal(IP_EVENT, evt_id, &evt, sizeof(evt), 0);
936 if (ESP_OK != ret) {
937 ESP_LOGE(TAG, "dhcpc cb: failed to post got ip event (%x)", ret);
938 }
939 } else {
940 ESP_LOGD(TAG, "if%p ip unchanged", esp_netif);
941 }
942 } else {
943 if (!ip4_addr_cmp(&ip_info->ip, IP4_ADDR_ANY4)) {
944 esp_netif_start_ip_lost_timer(esp_netif);
945 }
946 }
947 }
948
esp_netif_ip_lost_timer(void * arg)949 static void esp_netif_ip_lost_timer(void *arg)
950 {
951 esp_netif_t *esp_netif = esp_netif_is_active(arg);
952
953 if (esp_netif == NULL) {
954 ESP_LOGD(TAG, "%s esp_netif=%p not active any more", __func__, arg);
955 return;
956 }
957
958 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
959
960 esp_netif->timer_running = false;
961
962 struct netif *netif = esp_netif->lwip_netif;
963
964 if ( (!netif) || (netif && ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4))) {
965 ip_event_got_ip_t evt = {
966 .esp_netif = esp_netif,
967 .if_index = -1,
968 };
969 int ret;
970
971 ESP_LOGD(TAG, "if%p ip lost tmr: raise ip lost event", esp_netif);
972 memset(esp_netif->ip_info_old, 0, sizeof(esp_netif_ip_info_t));
973 if (esp_netif->lost_ip_event) {
974 ret = esp_event_send_internal(IP_EVENT, esp_netif->lost_ip_event,
975 &evt, sizeof(evt), 0);
976 if (ESP_OK != ret) {
977 ESP_LOGE(TAG, "ip lost timer: failed to post lost ip event (%x)", ret);
978 }
979 }
980 } else {
981 ESP_LOGD(TAG, "if%p ip lost tmr: no need raise ip lost event", esp_netif);
982 }
983 }
984
985
esp_netif_start_ip_lost_timer(esp_netif_t * esp_netif)986 static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif)
987 {
988 esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info;
989 struct netif *netif = esp_netif->lwip_netif;
990
991 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
992
993 if (esp_netif->timer_running) {
994 ESP_LOGD(TAG, "if%p start ip lost tmr: already started", esp_netif);
995 return ESP_OK;
996 }
997
998 if ( netif && (CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL > 0) && !ip4_addr_isany_val(ip_info_old->ip)) {
999 esp_netif->timer_running = true;
1000 sys_timeout(CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL * 1000, esp_netif_ip_lost_timer, (void *)esp_netif);
1001 ESP_LOGD(TAG, "if%p start ip lost tmr: interval=%d", esp_netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL);
1002 return ESP_OK;
1003 }
1004
1005 ESP_LOGD(TAG, "if%p start ip lost tmr: no need start because netif=%p interval=%d ip=%x",
1006 esp_netif, netif, CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL, ip_info_old->ip.addr);
1007
1008 return ESP_OK;
1009 }
1010
esp_netif_dhcpc_stop_api(esp_netif_api_msg_t * msg)1011 static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg)
1012 {
1013 esp_netif_t *esp_netif = msg->esp_netif;
1014
1015 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1016
1017 if (esp_netif == NULL) {
1018 ESP_LOGE(TAG, "dhcp client stop called with NULL api");
1019 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1020 }
1021
1022 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1023 struct netif *p_netif = esp_netif->lwip_netif;
1024
1025 if (p_netif != NULL) {
1026 dhcp_stop(p_netif);
1027 esp_netif_reset_ip_info(esp_netif);
1028 esp_netif_start_ip_lost_timer(esp_netif);
1029 } else {
1030 ESP_LOGD(TAG, "dhcp client if not ready");
1031 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1032 }
1033 } else if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) {
1034 ESP_LOGD(TAG, "dhcp client already stoped");
1035 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
1036 }
1037
1038 ESP_LOGD(TAG, "dhcp client stop successfully");
1039 esp_netif->dhcpc_status = ESP_NETIF_DHCP_STOPPED;
1040
1041 LWIP_DHCP_IP_ADDR_ERASE(esp_netif);
1042
1043 return ESP_OK;
1044 }
1045
esp_netif_dhcpc_stop(esp_netif_t * esp_netif)1046 esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_stop_api, esp_netif, NULL)
1047
1048 static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg)
1049 {
1050 esp_netif_t *esp_netif = msg->esp_netif;
1051
1052 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1053
1054 if (!esp_netif) {
1055 return ESP_ERR_INVALID_ARG;
1056 }
1057
1058 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1059 ESP_LOGD(TAG, "dhcp client already started");
1060 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1061 }
1062
1063 struct netif *p_netif = esp_netif->lwip_netif;
1064
1065 esp_netif_reset_ip_info(esp_netif);
1066
1067 #if LWIP_DNS
1068 dns_clear_servers(true);
1069 #endif
1070
1071 if (p_netif != NULL) {
1072 if (netif_is_up(p_netif)) {
1073 ip_addr_set_zero(&p_netif->ip_addr);
1074 ip_addr_set_zero(&p_netif->netmask);
1075 ip_addr_set_zero(&p_netif->gw);
1076 esp_netif_start_ip_lost_timer(esp_netif);
1077 } else {
1078 ESP_LOGD(TAG, "dhcp client re init");
1079 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1080 return ESP_OK;
1081 }
1082 ESP_LOGD(TAG, "starting dhcp client");
1083
1084 if (dhcp_start(p_netif) != ERR_OK) {
1085 ESP_LOGE(TAG, "dhcp client start failed");
1086 return ESP_ERR_ESP_NETIF_DHCPC_START_FAILED;
1087 }
1088
1089 dhcp_set_cb(p_netif, esp_netif_dhcpc_cb);
1090
1091 esp_netif->dhcpc_status = ESP_NETIF_DHCP_STARTED;
1092 return ESP_OK;
1093 } else {
1094 ESP_LOGD(TAG, "dhcp client re init");
1095 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1096 return ESP_OK;
1097 }
1098 }
1099
esp_netif_dhcpc_start(esp_netif_t * esp_netif)1100 esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcpc_start_api, esp_netif, NULL)
1101
1102 #if ESP_DHCPS
1103 esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
1104 {
1105 if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1106 return ESP_ERR_INVALID_ARG;
1107 }
1108
1109 *status = esp_netif->dhcps_status;
1110 return ESP_OK;
1111 }
1112 #endif
1113
esp_netif_dhcpc_get_status(esp_netif_t * esp_netif,esp_netif_dhcp_status_t * status)1114 esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
1115 {
1116 if (!esp_netif || (esp_netif->flags & ESP_NETIF_DHCP_SERVER) || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1117 return ESP_ERR_INVALID_ARG;
1118 }
1119
1120 *status = esp_netif->dhcpc_status;
1121 return ESP_OK;
1122 }
1123
1124 #if ESP_DHCPS
esp_netif_dhcps_start_api(esp_netif_api_msg_t * msg)1125 static esp_err_t esp_netif_dhcps_start_api(esp_netif_api_msg_t *msg)
1126 {
1127 esp_netif_t *esp_netif = msg->esp_netif;
1128
1129 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1130
1131 if (!esp_netif) {
1132 return ESP_ERR_INVALID_ARG;
1133 }
1134
1135 if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
1136 ESP_LOGD(TAG, "dhcp server already started");
1137 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1138 }
1139
1140 struct netif *p_netif = esp_netif->lwip_netif;
1141 if (p_netif != NULL && netif_is_up(p_netif)) {
1142 esp_netif_ip_info_t *default_ip = esp_netif->ip_info;
1143 ip4_addr_t lwip_ip;
1144 ip4_addr_t lwip_netmask;
1145 memcpy(&lwip_ip, &default_ip->ip, sizeof(struct ip4_addr));
1146 memcpy(&lwip_netmask, &default_ip->netmask, sizeof(struct ip4_addr));
1147 dhcps_set_new_lease_cb(esp_netif_dhcps_cb);
1148 dhcps_set_option_info(SUBNET_MASK, (void*)&lwip_netmask, sizeof(lwip_netmask));
1149 dhcps_start(p_netif, lwip_ip);
1150 esp_netif->dhcps_status = ESP_NETIF_DHCP_STARTED;
1151 ESP_LOGD(TAG, "DHCP server started successfully");
1152 return ESP_OK;
1153 } else {
1154 ESP_LOGD(TAG, "dhcp server re init");
1155 esp_netif->dhcps_status = ESP_NETIF_DHCP_INIT;
1156 return ESP_OK;
1157 }
1158 }
1159
esp_netif_dhcps_start(esp_netif_t * esp_netif)1160 esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_start_api, esp_netif, NULL)
1161
1162 static esp_err_t esp_netif_dhcps_stop_api(esp_netif_api_msg_t *msg)
1163 {
1164 esp_netif_t *esp_netif = msg->esp_netif;
1165
1166 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1167
1168 if (!esp_netif) {
1169 return ESP_ERR_INVALID_ARG;
1170 }
1171
1172 struct netif *p_netif = esp_netif->lwip_netif;
1173 if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STARTED) {
1174 if (p_netif != NULL) {
1175 dhcps_stop(p_netif);
1176 } else {
1177 ESP_LOGD(TAG, "dhcp server if not ready");
1178 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1179 }
1180 } else if (esp_netif->dhcps_status == ESP_NETIF_DHCP_STOPPED) {
1181 ESP_LOGD(TAG, "dhcp server already stoped");
1182 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
1183 }
1184
1185 ESP_LOGD(TAG, "dhcp server stop successfully");
1186 esp_netif->dhcps_status = ESP_NETIF_DHCP_STOPPED;
1187 return ESP_OK;
1188 }
1189
esp_netif_dhcps_stop(esp_netif_t * esp_netif)1190 esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_dhcps_stop_api, esp_netif, NULL)
1191 #endif
1192
1193 static esp_err_t esp_netif_set_hostname_api(esp_netif_api_msg_t *msg)
1194 {
1195 esp_netif_t *esp_netif = msg->esp_netif;
1196 const char *hostname = msg->data;
1197
1198 ESP_LOGD(TAG, "%s esp_netif:%p hostname %s", __func__, esp_netif, hostname);
1199
1200 if (!esp_netif) {
1201 return ESP_ERR_INVALID_ARG;
1202 }
1203
1204 #if LWIP_NETIF_HOSTNAME
1205
1206 struct netif *p_netif = esp_netif->lwip_netif;
1207
1208 if (strlen(hostname) > ESP_NETIF_HOSTNAME_MAX_SIZE) {
1209 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1210 }
1211
1212 if (p_netif != NULL) {
1213 if (esp_netif->hostname) {
1214 free(esp_netif->hostname);
1215 }
1216 esp_netif->hostname = strdup(hostname);
1217 if (esp_netif->hostname == NULL) {
1218 p_netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
1219 return ESP_ERR_NO_MEM;
1220 }
1221 p_netif->hostname = esp_netif->hostname;
1222 return ESP_OK;
1223 } else {
1224 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1225 }
1226 #else
1227 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1228 #endif
1229 }
1230
esp_netif_set_hostname(esp_netif_t * esp_netif,const char * hostname)1231 esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_hostname_api, esp_netif, hostname)
1232
1233 esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname)
1234 {
1235 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1236
1237 if (!esp_netif || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1238 return ESP_ERR_INVALID_ARG;
1239 }
1240
1241 #if LWIP_NETIF_HOSTNAME
1242 struct netif *p_netif = esp_netif->lwip_netif;
1243
1244 if (p_netif != NULL && p_netif->hostname != NULL) {
1245 *hostname = p_netif->hostname;
1246 return ESP_OK;
1247 } else {
1248 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1249 }
1250 #else
1251 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1252 #endif
1253 }
1254
esp_netif_up_api(esp_netif_api_msg_t * msg)1255 static esp_err_t esp_netif_up_api(esp_netif_api_msg_t *msg)
1256 {
1257 esp_netif_t *esp_netif = msg->esp_netif;
1258
1259 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1260
1261 if (!esp_netif) {
1262 return ESP_ERR_INVALID_STATE;
1263 }
1264
1265 struct netif *lwip_netif = esp_netif->lwip_netif;
1266
1267 /* use last obtained ip, or static ip */
1268 netif_set_addr(lwip_netif, (ip4_addr_t*)&esp_netif->ip_info->ip, (ip4_addr_t*)&esp_netif->ip_info->netmask, (ip4_addr_t*)&esp_netif->ip_info->gw);
1269 netif_set_up(lwip_netif);
1270
1271 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED);
1272
1273 return ESP_OK;
1274 }
1275
esp_netif_up(esp_netif_t * esp_netif)1276 esp_err_t esp_netif_up(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK(esp_netif_up_api, esp_netif, NULL)
1277
1278 static esp_err_t esp_netif_down_api(esp_netif_api_msg_t *msg)
1279 {
1280 esp_netif_t *esp_netif = msg->esp_netif;
1281
1282 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1283
1284 if (!esp_netif) {
1285 return ESP_ERR_INVALID_STATE;
1286 }
1287
1288 struct netif *lwip_netif = esp_netif->lwip_netif;
1289
1290 if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT && esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1291 dhcp_stop(esp_netif->lwip_netif);
1292
1293 esp_netif->dhcpc_status = ESP_NETIF_DHCP_INIT;
1294
1295 esp_netif_reset_ip_info(esp_netif);
1296 }
1297 #if CONFIG_LWIP_IPV6
1298 for(int8_t i = 0 ;i < LWIP_IPV6_NUM_ADDRESSES ;i++) {
1299 netif_ip6_addr_set(lwip_netif, i, IP6_ADDR_ANY6);
1300 netif_ip6_addr_set_valid_life(lwip_netif, i, 0);
1301 netif_ip6_addr_set_pref_life(lwip_netif, i, 0);
1302 netif_ip6_addr_set_state(lwip_netif, i, IP6_ADDR_INVALID);
1303 }
1304 #endif
1305 netif_set_addr(lwip_netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
1306 netif_set_down(lwip_netif);
1307
1308 if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
1309 esp_netif_start_ip_lost_timer(esp_netif);
1310 }
1311
1312 esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED);
1313
1314 return ESP_OK;
1315 }
1316
esp_netif_down(esp_netif_t * esp_netif)1317 esp_err_t esp_netif_down(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK(esp_netif_down_api, esp_netif, NULL)
1318
1319 bool esp_netif_is_netif_up(esp_netif_t *esp_netif)
1320 {
1321 ESP_LOGV(TAG, "%s esp_netif:%p", __func__, esp_netif);
1322
1323 if (esp_netif != NULL && esp_netif->lwip_netif != NULL) {
1324 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1325 // ppp implementation uses netif_set_link_up/down to update link state
1326 return netif_is_link_up(esp_netif->lwip_netif);
1327 }
1328 // esp-netif handlers and drivers take care to set_netif_up/down on link state update
1329 return netif_is_up(esp_netif->lwip_netif);
1330 } else {
1331 return false;
1332 }
1333 }
1334
esp_netif_get_old_ip_info(esp_netif_t * esp_netif,esp_netif_ip_info_t * ip_info)1335 esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
1336 {
1337 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1338
1339 if (esp_netif == NULL || ip_info == NULL) {
1340 return ESP_ERR_INVALID_ARG;
1341 }
1342 memcpy(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t));
1343 return ESP_OK;
1344 }
1345
esp_netif_get_ip_info(esp_netif_t * esp_netif,esp_netif_ip_info_t * ip_info)1346 esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
1347 {
1348 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1349
1350 if (esp_netif == NULL || ip_info == NULL) {
1351 return ESP_ERR_INVALID_ARG;
1352 }
1353
1354 struct netif *p_netif = esp_netif->lwip_netif;
1355
1356 if (p_netif != NULL && netif_is_up(p_netif)) {
1357 ip4_addr_set(&ip_info->ip, ip_2_ip4(&p_netif->ip_addr));
1358 ip4_addr_set(&ip_info->netmask, ip_2_ip4(&p_netif->netmask));
1359 ip4_addr_set(&ip_info->gw, ip_2_ip4(&p_netif->gw));
1360
1361 return ESP_OK;
1362 }
1363
1364 memcpy(ip_info, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
1365
1366 return ESP_OK;
1367 }
1368
1369
esp_netif_is_valid_static_ip(esp_netif_ip_info_t * ip_info)1370 bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info)
1371 {
1372 if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask))) {
1373 // let's assume valid ip_info is when none of ip and netmask is 'any' address (zeros)
1374 return true;
1375 }
1376 return false;
1377 }
1378
esp_netif_set_ip_old_info_api(esp_netif_api_msg_t * msg)1379 static esp_err_t esp_netif_set_ip_old_info_api(esp_netif_api_msg_t *msg)
1380 {
1381 esp_netif_t *esp_netif = msg->esp_netif;
1382 const esp_netif_ip_info_t *ip_info = msg->data;
1383
1384 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1385
1386 if (esp_netif == NULL || ip_info == NULL) {
1387 return ESP_ERR_INVALID_STATE;
1388 }
1389
1390 memcpy(msg->esp_netif->ip_info_old, msg->data, sizeof(esp_netif_ip_info_t));
1391 return ESP_OK;
1392 }
1393
esp_netif_set_old_ip_info(esp_netif_t * esp_netif,const esp_netif_ip_info_t * ip_info)1394 esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_old_info_api, esp_netif, ip_info)
1395
1396 static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg)
1397 {
1398 esp_netif_t *esp_netif = msg->esp_netif;
1399 const esp_netif_ip_info_t *ip_info = msg->data;
1400
1401 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1402
1403 if (esp_netif == NULL || ip_info == NULL) {
1404 return ESP_ERR_INVALID_STATE;
1405 }
1406
1407 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1408 if (esp_netif->dhcps_status != ESP_NETIF_DHCP_STOPPED) {
1409 return ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED;
1410 }
1411 } else if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
1412 if (esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED) {
1413 return ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED;
1414 }
1415 #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
1416 dns_clear_servers(true);
1417 #endif
1418 }
1419
1420 ip4_addr_copy(esp_netif->ip_info->ip, ip_info->ip);
1421 ip4_addr_copy(esp_netif->ip_info->gw, ip_info->gw);
1422 ip4_addr_copy(esp_netif->ip_info->netmask, ip_info->netmask);
1423
1424 struct netif *p_netif = esp_netif->lwip_netif;
1425
1426 if (p_netif != NULL && netif_is_up(p_netif)) {
1427 netif_set_addr(p_netif, (ip4_addr_t*)&ip_info->ip, (ip4_addr_t*)&ip_info->netmask, (ip4_addr_t*)&ip_info->gw);
1428 if (ESP_NETIF_FLAG_EVENT_IP_MODIFIED & esp_netif->flags) {
1429 if (!(ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask) || ip4_addr_isany_val(ip_info->gw))) {
1430
1431 ip_event_t evt_id = esp_netif->get_ip_event;
1432 ip_event_got_ip_t evt = { .esp_netif = esp_netif, .if_index = -1, .ip_changed = false};
1433 int ret;
1434 if (memcmp(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t))) {
1435 evt.ip_changed = true;
1436 }
1437
1438 memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t));
1439 memcpy(esp_netif->ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
1440 ret = esp_event_send_internal(IP_EVENT, evt_id, &evt, sizeof(evt), 0);
1441 if (ESP_OK != ret) {
1442 ESP_LOGE(TAG, "set ip info: failed to post got ip event (%x)", ret);
1443 }
1444
1445 ESP_LOGD(TAG, "if%p netif set static ip: ip changed=%d", esp_netif, evt.ip_changed);
1446
1447 }
1448 }
1449 }
1450
1451 return ESP_OK;
1452 }
1453
esp_netif_set_ip_info(esp_netif_t * esp_netif,const esp_netif_ip_info_t * ip_info)1454 esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_set_ip_info_api, esp_netif, ip_info)
1455
1456 static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg)
1457 {
1458 esp_netif_t *esp_netif = msg->esp_netif;
1459 esp_netif_dns_param_t *dns_param = msg->data;
1460 esp_netif_dns_type_t type = dns_param->dns_type;
1461 esp_netif_dns_info_t *dns = dns_param->dns_info;
1462
1463 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1464
1465 if (esp_netif == NULL) {
1466 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1467 }
1468
1469 if (!dns) {
1470 ESP_LOGD(TAG, "set dns null dns");
1471 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1472 }
1473
1474 if (ip4_addr_isany_val(dns->ip.u_addr.ip4)) {
1475 ESP_LOGD(TAG, "set dns invalid dns");
1476 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1477 }
1478
1479 ESP_LOGD(TAG, "set dns if=%p type=%d dns=%x", esp_netif, type, dns->ip.u_addr.ip4.addr);
1480
1481 ip_addr_t *lwip_ip = (ip_addr_t*)&dns->ip;
1482 #if CONFIG_LWIP_IPV6 && LWIP_IPV4
1483 lwip_ip->type = IPADDR_TYPE_V4;
1484 #endif
1485 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1486 #if ESP_DHCPS
1487 // if DHCP server configured to set DNS in dhcps API
1488 if (type != ESP_NETIF_DNS_MAIN) {
1489 ESP_LOGD(TAG, "set dns invalid type");
1490 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1491 } else {
1492 dhcps_dns_setserver(lwip_ip);
1493 }
1494 #else
1495 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
1496 #endif
1497 } else {
1498 dns_setserver(type, lwip_ip);
1499 }
1500
1501 return ESP_OK;
1502 }
1503
esp_netif_set_dns_info(esp_netif_t * esp_netif,esp_netif_dns_type_t type,esp_netif_dns_info_t * dns)1504 esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
1505 {
1506 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1507 return ESP_ERR_NOT_SUPPORTED;
1508 }
1509 esp_netif_dns_param_t dns_param = {
1510 .dns_type = type,
1511 .dns_info = dns
1512 };
1513 return esp_netif_lwip_ipc_call(esp_netif_set_dns_info_api, esp_netif, (void *)&dns_param);
1514 }
1515
esp_netif_get_dns_info_api(esp_netif_api_msg_t * msg)1516 static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg)
1517 {
1518 esp_netif_t *esp_netif = msg->esp_netif;
1519 esp_netif_dns_param_t *dns_param = msg->data;
1520 esp_netif_dns_type_t type = dns_param->dns_type;
1521 esp_netif_dns_info_t *dns = dns_param->dns_info;
1522
1523 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1524
1525 if (!dns) {
1526 ESP_LOGE(TAG, "%s: dns_info cannot be NULL", __func__);
1527 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1528 }
1529
1530 if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) {
1531 #if ESP_DHCPS
1532 ip4_addr_t dns_ip = dhcps_dns_getserver();
1533 memcpy(&dns->ip.u_addr.ip4, &dns_ip, sizeof(ip4_addr_t));
1534 #else
1535 LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED);
1536 #endif
1537 } else {
1538 const ip_addr_t* dns_ip = NULL;
1539 dns_ip = dns_getserver(type);
1540 if(dns_ip != NULL) {
1541 memcpy(&dns->ip, dns_ip, sizeof(ip_addr_t));
1542 }
1543 }
1544
1545 return ESP_OK;
1546 }
1547
esp_netif_get_dns_info(esp_netif_t * esp_netif,esp_netif_dns_type_t type,esp_netif_dns_info_t * dns)1548 esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
1549 {
1550 if (_IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1551 const ip_addr_t *dns_ip = dns_getserver(type);
1552 if (dns_ip == IP_ADDR_ANY) {
1553 return ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED;
1554 }
1555 #if CONFIG_LWIP_IPV6
1556 memcpy(&dns->ip.u_addr.ip4, &dns_ip->u_addr.ip4, sizeof(ip4_addr_t));
1557 #else
1558 memcpy(&dns->ip.u_addr.ip4, &dns_ip->addr, sizeof(ip4_addr_t));
1559 #endif
1560 return ESP_OK;
1561 }
1562
1563 esp_netif_dns_param_t dns_param = {
1564 .dns_type = type,
1565 .dns_info = dns
1566 };
1567 return esp_netif_lwip_ipc_call(esp_netif_get_dns_info_api, esp_netif, (void *)&dns_param);
1568 }
1569
1570 #if CONFIG_LWIP_IPV6
esp_netif_ip6_get_addr_type(esp_ip6_addr_t * ip6_addr)1571 esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr)
1572 {
1573 ip6_addr_t* lwip_ip6_info = (ip6_addr_t*)ip6_addr;
1574
1575 if (ip6_addr_isglobal(lwip_ip6_info)) {
1576 return ESP_IP6_ADDR_IS_GLOBAL;
1577 } else if (ip6_addr_islinklocal(lwip_ip6_info)) {
1578 return ESP_IP6_ADDR_IS_LINK_LOCAL;
1579 } else if (ip6_addr_issitelocal(lwip_ip6_info)) {
1580 return ESP_IP6_ADDR_IS_SITE_LOCAL;
1581 } else if (ip6_addr_isuniquelocal(lwip_ip6_info)) {
1582 return ESP_IP6_ADDR_IS_UNIQUE_LOCAL;
1583 } else if (ip6_addr_isipv4mappedipv6(lwip_ip6_info)) {
1584 return ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6;
1585 }
1586 return ESP_IP6_ADDR_IS_UNKNOWN;
1587
1588 }
1589
esp_netif_nd6_cb(struct netif * p_netif,uint8_t ip_index)1590 static void esp_netif_nd6_cb(struct netif *p_netif, uint8_t ip_index)
1591 {
1592 ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, p_netif);
1593 if (!p_netif) {
1594 ESP_LOGD(TAG, "esp_netif_nd6_cb called with null p_netif");
1595 return;
1596 }
1597
1598 esp_netif_ip6_info_t ip6_info;
1599 ip6_addr_t lwip_ip6_info;
1600 //notify event
1601 ip_event_got_ip6_t evt = { .esp_netif = p_netif->state, .if_index = -1, .ip_index = ip_index };
1602
1603 ip6_addr_set(&lwip_ip6_info, ip_2_ip6(&p_netif->ip6_addr[ip_index]));
1604 #if LWIP_IPV6_SCOPES
1605 memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(esp_ip6_addr_t));
1606 #else
1607 memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(ip6_addr_t));
1608 ip6_info.ip.zone = 0; // zero out zone, as not used in lwip
1609 #endif /* LWIP_IPV6_SCOPES */
1610
1611 memcpy(&evt.ip6_info, &ip6_info, sizeof(esp_netif_ip6_info_t));
1612 int ret = esp_event_send_internal(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0);
1613 if (ESP_OK != ret) {
1614 ESP_LOGE(TAG, "nd6 cb: failed to post IP_EVENT_GOT_IP6 (%x)", ret);
1615 }
1616 }
1617
esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t * msg)1618 static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg)
1619 {
1620 esp_netif_t *esp_netif = msg->esp_netif;
1621
1622 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
1623
1624 struct netif *p_netif = esp_netif->lwip_netif;
1625 if (p_netif != NULL && netif_is_up(p_netif)) {
1626 netif_create_ip6_linklocal_address(p_netif, 1);
1627 nd6_set_cb(p_netif, esp_netif_nd6_cb);
1628 return ESP_OK;
1629 } else {
1630 return ESP_FAIL;
1631 }
1632 }
1633
esp_netif_create_ip6_linklocal(esp_netif_t * esp_netif)1634 esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif) _RUN_IN_LWIP_TASK_IF_SUPPORTED(esp_netif_create_ip6_linklocal_api, esp_netif, NULL)
1635
1636 esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
1637 {
1638 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
1639
1640 if (esp_netif == NULL || if_ip6 == NULL || _IS_NETIF_ANY_POINT2POINT_TYPE(esp_netif)) {
1641 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1642 }
1643 struct netif *p_netif = esp_netif->lwip_netif;
1644
1645 if (p_netif != NULL && netif_is_up(p_netif) && ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, 0))) {
1646 memcpy(if_ip6, &p_netif->ip6_addr[0], sizeof(ip6_addr_t));
1647 } else {
1648 return ESP_FAIL;
1649 }
1650 return ESP_OK;
1651 }
1652
esp_netif_get_ip6_global(esp_netif_t * esp_netif,esp_ip6_addr_t * if_ip6)1653 esp_err_t esp_netif_get_ip6_global(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
1654 {
1655 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
1656
1657 if (esp_netif == NULL || if_ip6 == NULL) {
1658 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1659 }
1660
1661 int i;
1662 struct netif *p_netif = esp_netif->lwip_netif;
1663
1664 if (p_netif != NULL && netif_is_up(p_netif)) {
1665 for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1666 if (ip6_addr_ispreferred(netif_ip6_addr_state(p_netif, i)) &&
1667 ip6_addr_isglobal(netif_ip6_addr(p_netif, i))) {
1668 memcpy(if_ip6, &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
1669 return ESP_OK;
1670 }
1671 }
1672 }
1673
1674 return ESP_FAIL;
1675 }
1676
esp_netif_get_all_ip6(esp_netif_t * esp_netif,esp_ip6_addr_t if_ip6[])1677 int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[])
1678 {
1679 ESP_LOGV(TAG, "%s esp-netif:%p", __func__, esp_netif);
1680
1681 if (esp_netif == NULL || if_ip6 == NULL) {
1682 return 0;
1683 }
1684
1685 int addr_count = 0;
1686 struct netif *p_netif = esp_netif->lwip_netif;
1687
1688 if (p_netif != NULL && netif_is_up(p_netif)) {
1689 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
1690 if (!ip_addr_cmp(&p_netif->ip6_addr[i], IP6_ADDR_ANY)) {
1691 memcpy(&if_ip6[addr_count++], &p_netif->ip6_addr[i], sizeof(ip6_addr_t));
1692 }
1693 }
1694 }
1695 return addr_count;
1696 }
1697 #endif
1698
esp_netif_get_flags(esp_netif_t * esp_netif)1699 esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif)
1700 {
1701 return esp_netif->flags;
1702 }
1703
esp_netif_get_ifkey(esp_netif_t * esp_netif)1704 const char *esp_netif_get_ifkey(esp_netif_t *esp_netif)
1705 {
1706 return esp_netif->if_key;
1707 }
1708
esp_netif_get_desc(esp_netif_t * esp_netif)1709 const char *esp_netif_get_desc(esp_netif_t *esp_netif)
1710 {
1711 return esp_netif->if_desc;
1712 }
1713
esp_netif_get_route_prio(esp_netif_t * esp_netif)1714 int esp_netif_get_route_prio(esp_netif_t *esp_netif)
1715 {
1716 if (esp_netif == NULL) {
1717 return -1;
1718 }
1719 return esp_netif->route_prio;
1720 }
1721
esp_netif_get_event_id(esp_netif_t * esp_netif,esp_netif_ip_event_type_t event_type)1722 int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type)
1723 {
1724 switch(event_type) {
1725 case ESP_NETIF_IP_EVENT_GOT_IP:
1726 return esp_netif->get_ip_event;
1727 case ESP_NETIF_IP_EVENT_LOST_IP:
1728 return esp_netif->lost_ip_event;
1729 default:
1730 return -1;
1731 }
1732 }
1733
1734 #if ESP_DHCPS
esp_netif_dhcps_option(esp_netif_t * esp_netif,esp_netif_dhcp_option_mode_t opt_op,esp_netif_dhcp_option_id_t opt_id,void * opt_val,uint32_t opt_len)1735 esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
1736 uint32_t opt_len)
1737 {
1738 void *opt_info = dhcps_option_info(opt_id, opt_len);
1739 if (esp_netif == NULL) {
1740 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1741 }
1742
1743 esp_netif_dhcp_status_t dhcps_status = esp_netif->dhcps_status;
1744 if (opt_info == NULL || opt_val == NULL) {
1745 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1746 }
1747
1748 if (opt_op == ESP_NETIF_OP_GET) {
1749 if (dhcps_status == ESP_NETIF_DHCP_STOPPED) {
1750 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
1751 }
1752
1753 switch (opt_id) {
1754 case IP_ADDRESS_LEASE_TIME: {
1755 *(uint32_t *)opt_val = *(uint32_t *)opt_info;
1756 break;
1757 }
1758 case ESP_NETIF_SUBNET_MASK:
1759 case REQUESTED_IP_ADDRESS: {
1760 memcpy(opt_val, opt_info, opt_len);
1761 break;
1762 }
1763 case ROUTER_SOLICITATION_ADDRESS: {
1764 if ((*(uint8_t *)opt_info) & OFFER_ROUTER) {
1765 *(uint8_t *)opt_val = 1;
1766 } else {
1767 *(uint8_t *)opt_val = 0;
1768 }
1769 break;
1770 }
1771 case DOMAIN_NAME_SERVER: {
1772 if ((*(uint8_t *)opt_info) & OFFER_DNS) {
1773 *(uint8_t *)opt_val = 1;
1774 } else {
1775 *(uint8_t *)opt_val = 0;
1776 }
1777 break;
1778 }
1779 default:
1780 break;
1781 }
1782 } else if (opt_op == ESP_NETIF_OP_SET) {
1783 if (dhcps_status == ESP_NETIF_DHCP_STARTED) {
1784 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1785 }
1786
1787 switch (opt_id) {
1788 case IP_ADDRESS_LEASE_TIME: {
1789 if (*(uint32_t *)opt_val != 0) {
1790 *(uint32_t *)opt_info = *(uint32_t *)opt_val;
1791 } else {
1792 *(uint32_t *)opt_info = DHCPS_LEASE_TIME_DEF;
1793 }
1794 break;
1795 }
1796 case ESP_NETIF_SUBNET_MASK: {
1797 memcpy(opt_info, opt_val, opt_len);
1798 break;
1799 }
1800 case REQUESTED_IP_ADDRESS: {
1801 esp_netif_ip_info_t info;
1802 uint32_t softap_ip = 0;
1803 uint32_t start_ip = 0;
1804 uint32_t end_ip = 0;
1805 dhcps_lease_t *poll = opt_val;
1806
1807 if (poll->enable) {
1808 memset(&info, 0x00, sizeof(esp_netif_ip_info_t));
1809 esp_netif_get_ip_info(esp_netif, &info);
1810
1811 softap_ip = htonl(info.ip.addr);
1812 start_ip = htonl(poll->start_ip.addr);
1813 end_ip = htonl(poll->end_ip.addr);
1814
1815 /*config ip information can't contain local ip*/
1816 if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) {
1817 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1818 }
1819
1820 /*config ip information must be in the same segment as the local ip*/
1821 softap_ip >>= 8;
1822 if ((start_ip >> 8 != softap_ip)
1823 || (end_ip >> 8 != softap_ip)) {
1824 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1825 }
1826
1827 if (end_ip - start_ip > DHCPS_MAX_LEASE) {
1828 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1829 }
1830 }
1831
1832 memcpy(opt_info, opt_val, opt_len);
1833 break;
1834 }
1835 case ROUTER_SOLICITATION_ADDRESS: {
1836 if (*(uint8_t *)opt_val) {
1837 *(uint8_t *)opt_info |= OFFER_ROUTER;
1838 } else {
1839 *(uint8_t *)opt_info &= ((~OFFER_ROUTER) & 0xFF);
1840 }
1841 break;
1842 }
1843 case DOMAIN_NAME_SERVER: {
1844 if (*(uint8_t *)opt_val) {
1845 *(uint8_t *)opt_info |= OFFER_DNS;
1846 } else {
1847 *(uint8_t *)opt_info &= ((~OFFER_DNS) & 0xFF);
1848 }
1849 break;
1850 }
1851
1852 default:
1853 break;
1854 }
1855 dhcps_set_option_info(opt_id, opt_info, opt_len);
1856 } else {
1857 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1858 }
1859
1860 return ESP_OK;
1861 }
1862 #endif
1863
esp_netif_dhcpc_option(esp_netif_t * esp_netif,esp_netif_dhcp_option_mode_t opt_op,esp_netif_dhcp_option_id_t opt_id,void * opt_val,uint32_t opt_len)1864 esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
1865 uint32_t opt_len)
1866 {
1867 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
1868 return ESP_ERR_ESP_NETIF_IF_NOT_READY;
1869 }
1870 struct dhcp *dhcp = netif_dhcp_data(esp_netif->lwip_netif);
1871 if (dhcp == NULL || opt_val == NULL) {
1872 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1873 }
1874 if (opt_op == ESP_NETIF_OP_GET) {
1875 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STOPPED) {
1876 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED;
1877 }
1878 switch (opt_id) {
1879 case ESP_NETIF_IP_REQUEST_RETRY_TIME:
1880 if (opt_len == sizeof(dhcp->tries)) {
1881 *(uint8_t *)opt_val = dhcp->tries;
1882 }
1883 break;
1884 #if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
1885 case ESP_NETIF_VENDOR_SPECIFIC_INFO:
1886 return dhcp_get_vendor_specific_information(opt_len, opt_val);
1887 #endif
1888 default:
1889 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1890 }
1891 } else if (opt_op == ESP_NETIF_OP_SET) {
1892 if (esp_netif->dhcpc_status == ESP_NETIF_DHCP_STARTED) {
1893 return ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED;
1894 }
1895 switch (opt_id) {
1896 case ESP_NETIF_IP_REQUEST_RETRY_TIME:
1897 if (opt_len == sizeof(dhcp->tries)) {
1898 dhcp->tries = *(uint8_t *)opt_val;
1899 }
1900 break;
1901 #if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
1902 case ESP_NETIF_VENDOR_CLASS_IDENTIFIER:
1903 return dhcp_set_vendor_class_identifier(opt_len, opt_val);
1904 #endif
1905 default:
1906 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1907 }
1908 } else {
1909 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1910 }
1911 return ESP_OK;
1912 }
1913
esp_netif_get_netif_impl_index(esp_netif_t * esp_netif)1914 int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
1915 {
1916 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
1917 return -1;
1918 }
1919 return netif_get_index(esp_netif->lwip_netif);
1920 }
1921
esp_netif_get_netif_impl_name(esp_netif_t * esp_netif,char * name)1922 esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name)
1923 {
1924 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
1925
1926 if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
1927 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
1928 }
1929 netif_index_to_name(netif_get_index(esp_netif->lwip_netif), name);
1930 return ESP_OK;
1931 }
1932
1933 #if CONFIG_LWIP_IPV6
1934
esp_netif_join_ip6_multicast_group_api(esp_netif_api_msg_t * msg)1935 static esp_err_t esp_netif_join_ip6_multicast_group_api(esp_netif_api_msg_t *msg)
1936 {
1937 esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
1938 esp_err_t error = ESP_OK;
1939 ip6_addr_t ip6addr;
1940
1941 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
1942 memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
1943 #if LWIP_IPV6_SCOPES
1944 ip6addr.zone = 0;
1945 #endif
1946 if (mld6_joingroup_netif(msg->esp_netif->lwip_netif, &ip6addr) != ERR_OK) {
1947 error = ESP_ERR_ESP_NETIF_MLD6_FAILED;
1948 ESP_LOGE(TAG, "failed to join ip6 multicast group");
1949 }
1950 return error;
1951 }
1952
esp_netif_join_ip6_multicast_group(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)1953 esp_err_t esp_netif_join_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
1954 _RUN_IN_LWIP_TASK(esp_netif_join_ip6_multicast_group_api, esp_netif, addr)
1955
1956 static esp_err_t esp_netif_leave_ip6_multicast_group_api(esp_netif_api_msg_t *msg)
1957 {
1958 esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
1959 ip6_addr_t ip6addr;
1960
1961 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
1962 memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
1963 #if LWIP_IPV6_SCOPES
1964 ip6addr.zone = 0;
1965 #endif
1966 ESP_RETURN_ON_FALSE(mld6_leavegroup_netif(msg->esp_netif->lwip_netif, &ip6addr) != ERR_OK,
1967 ESP_ERR_ESP_NETIF_MLD6_FAILED, TAG, "Failed to leave ip6 multicast group");
1968 return ESP_OK;
1969 }
1970
esp_netif_leave_ip6_multicast_group(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)1971 esp_err_t esp_netif_leave_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
1972 _RUN_IN_LWIP_TASK(esp_netif_leave_ip6_multicast_group_api, esp_netif, addr)
1973
1974 static esp_err_t esp_netif_add_ip6_address_api(esp_netif_api_msg_t *msg)
1975 {
1976 ip_event_add_ip6_t *addr = (ip_event_add_ip6_t *)msg->data;
1977 ip6_addr_t ip6addr;
1978 esp_err_t error = ESP_OK;
1979 int8_t index = -1;
1980
1981 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
1982 memcpy(ip6addr.addr, addr->addr.addr, sizeof(ip6addr.addr));
1983 #if LWIP_IPV6_SCOPES
1984 ip6addr.zone = 0;
1985 #endif
1986 err_t err = netif_add_ip6_address(msg->esp_netif->lwip_netif, &ip6addr, &index);
1987 ESP_RETURN_ON_FALSE(err == ERR_OK && index >= 0, ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED, TAG,
1988 "Failed to add ip6 address");
1989
1990 netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index,
1991 addr->preferred ? IP6_ADDR_PREFERRED : IP6_ADDR_DEPRECATED);
1992 ip_event_got_ip6_t evt = {.esp_netif = msg->esp_netif, .if_index = -1, .ip_index = index};
1993 evt.ip6_info.ip = addr->addr;
1994 ESP_RETURN_ON_ERROR(esp_event_send_internal(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0), TAG,
1995 "Failed to post IP_EVENT_GOT_IP6");
1996 return error;
1997 }
1998
esp_netif_add_ip6_address(esp_netif_t * esp_netif,const ip_event_add_ip6_t * addr)1999 esp_err_t esp_netif_add_ip6_address(esp_netif_t *esp_netif, const ip_event_add_ip6_t *addr)
2000 _RUN_IN_LWIP_TASK(esp_netif_add_ip6_address_api, esp_netif, addr)
2001
2002 static esp_err_t esp_netif_remove_ip6_address_api(esp_netif_api_msg_t *msg)
2003 {
2004 esp_ip6_addr_t *addr = (esp_ip6_addr_t *)msg->data;
2005 ip6_addr_t ip6addr;
2006
2007 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, msg->esp_netif);
2008 memcpy(ip6addr.addr, addr->addr, sizeof(ip6addr.addr));
2009 #if LWIP_IPV6_SCOPES
2010 ip6addr.zone = 0;
2011 #endif
2012 int8_t index = netif_get_ip6_addr_match(msg->esp_netif->lwip_netif, &ip6addr);
2013 if (index != -1) {
2014 netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index, IP6_ADDR_INVALID);
2015 }
2016 return ESP_OK;
2017 }
2018
2019 esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
2020 _RUN_IN_LWIP_TASK(esp_netif_remove_ip6_address_api, esp_netif, addr)
2021
2022 #endif // CONFIG_LWIP_IPV6
2023
2024 #endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */
2025