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