1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <string.h>
16
17 #include "esp_netif_lwip_internal.h"
18
19 #include "esp_netif.h"
20 #include "esp_netif_private.h"
21 #include "esp_netif_sta_list.h"
22
23 #if CONFIG_ESP_NETIF_LOOPBACK
24
25 #include "esp_log.h"
26
27 //
28 // Purpose of this module is to implement minimal loopback netif to facilitate
29 // low level driver testing
30 //
31
32 #define ESP_NETIF_HOSTNAME_MAX_SIZE 32
33
34 static const char *TAG = "esp_netif_loopback";
35
36 static bool s_netif_initialized = false;
37 static bool s_netif_started = false;
38 static bool s_netif_up = false;
39
40 /**
41 * @brief Main esp-netif container with interface related information
42 *
43 *
44 */
45 struct esp_netif_obj {
46 // default interface addresses
47 uint8_t mac[NETIF_MAX_HWADDR_LEN];
48 esp_netif_ip_info_t* ip_info;
49 esp_netif_ip_info_t* ip_info_old;
50
51 // io driver related
52 void* driver_handle;
53 esp_err_t (*driver_transmit)(void *h, void *buffer, size_t len);
54 void (*driver_free_rx_buffer)(void *h, void* buffer);
55
56 // misc flags, types, keys, priority
57 esp_netif_flags_t flags;
58 char * hostname;
59 char * if_key;
60 char * if_desc;
61 int route_prio;
62 };
63
esp_netif_set_ip4_addr(esp_ip4_addr_t * addr,uint8_t a,uint8_t b,uint8_t c,uint8_t d)64 void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
65 {
66 memset(addr, 0, sizeof(esp_ip4_addr_t));
67 addr->addr = esp_netif_htonl(esp_netif_ip4_makeu32(a,b,c,d));
68 }
69
esp_ip4addr_ntoa(const esp_ip4_addr_t * addr,char * buf,int buflen)70 char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen)
71 {
72 return NULL;
73 }
74
esp_netif_get_io_driver(esp_netif_t * esp_netif)75 esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif)
76 {
77 return esp_netif->driver_handle;
78 }
79
esp_netif_get_handle_from_netif_impl(void * dev)80 esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev)
81 {
82 return NULL;
83 }
84
esp_netif_get_netif_impl(esp_netif_t * esp_netif)85 void* esp_netif_get_netif_impl(esp_netif_t *esp_netif)
86 {
87 return NULL;
88 }
89
esp_netif_init(void)90 esp_err_t esp_netif_init(void)
91 {
92 ESP_LOGI(TAG, "loopback initialization");
93 if (s_netif_initialized) {
94 ESP_LOGE(TAG, "esp-netif has already been initialized");
95 return ESP_ERR_INVALID_SIZE;
96 }
97
98 s_netif_initialized = true;
99 ESP_LOGD(TAG, "esp-netif has been successfully initialized");
100 return ESP_OK;
101 }
102
esp_netif_deinit(void)103 esp_err_t esp_netif_deinit(void)
104 {
105 ESP_LOGI(TAG, "loopback initialization");
106 if (!s_netif_initialized) {
107 ESP_LOGE(TAG, "esp-netif has not been initialized yet");
108 return ESP_ERR_INVALID_SIZE;
109 }
110 s_netif_initialized = false;
111 ESP_LOGD(TAG, "esp-netif has been successfully deinitialized");
112 return ESP_OK;
113 }
114
esp_netif_init_configuration(esp_netif_t * esp_netif,const esp_netif_config_t * cfg)115 static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_netif_config_t *cfg)
116 {
117 // Basic esp_netif and lwip is a mandatory configuration and cannot be updated after esp_netif_new()
118 if (cfg == NULL || cfg->base == NULL || cfg->stack == NULL) {
119 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
120 }
121
122 // Configure general esp-netif properties
123 memcpy(esp_netif->mac, cfg->base->mac, NETIF_MAX_HWADDR_LEN);
124 if (cfg->base->ip_info == NULL) {
125 ip4_addr_set_zero(&esp_netif->ip_info->ip);
126 ip4_addr_set_zero(&esp_netif->ip_info->gw);
127 ip4_addr_set_zero(&esp_netif->ip_info->netmask);
128 } else {
129 memcpy(esp_netif->ip_info, cfg->base->ip_info, sizeof(esp_netif_ip_info_t));
130 }
131 memcpy(esp_netif->ip_info_old, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
132
133 // Setup main config parameters
134 esp_netif->flags = cfg->base->flags;
135
136 if (cfg->base->if_key) {
137 esp_netif->if_key = strdup(cfg->base->if_key);
138 }
139 if (cfg->base->if_desc) {
140 esp_netif->if_desc = strdup(cfg->base->if_desc);
141 }
142 if (cfg->base->route_prio) {
143 esp_netif->route_prio = cfg->base->route_prio;
144 }
145
146 // Network stack is bypassed in loopback interface
147
148 // Install IO functions only if provided -- connects driver and netif
149 // this configuration could be updated after esp_netif_new(), typically in post_attach callback
150 if (cfg->driver) {
151 const esp_netif_driver_ifconfig_t *esp_netif_driver_config = cfg->driver;
152 if (esp_netif_driver_config->handle) {
153 esp_netif->driver_handle = esp_netif_driver_config->handle;
154 }
155 if (esp_netif_driver_config->transmit) {
156 esp_netif->driver_transmit = esp_netif_driver_config->transmit;
157 }
158 if (esp_netif_driver_config->driver_free_rx_buffer) {
159 esp_netif->driver_free_rx_buffer = esp_netif_driver_config->driver_free_rx_buffer;
160 }
161 }
162 return ESP_OK;
163 }
164
esp_netif_new(const esp_netif_config_t * esp_netif_config)165 esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
166 {
167 // mandatory configuration must be provided when creating esp_netif object
168 if (esp_netif_config == NULL) {
169 return NULL;
170 }
171
172 // Create parent esp-netif object
173 esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj));
174 if (!esp_netif) {
175 return NULL;
176 }
177
178 // Create ip info
179 esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
180 if (!ip_info) {
181 free(esp_netif);
182 return NULL;
183 }
184 esp_netif->ip_info = ip_info;
185
186 // creating another ip info (to store old ip)
187 ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
188 if (!ip_info) {
189 free(esp_netif->ip_info);
190 free(esp_netif);
191 return NULL;
192 }
193 esp_netif->ip_info_old = ip_info;
194
195 esp_netif_add_to_list(esp_netif);
196
197 // Configure the created object with provided configuration
198 esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config);
199 if (ret != ESP_OK) {
200 ESP_LOGE(TAG, "Initial configuration of esp_netif failed with %d", ret);
201 esp_netif_destroy(esp_netif);
202 return NULL;
203 }
204
205 return esp_netif;
206 }
207
esp_netif_destroy(esp_netif_t * esp_netif)208 void esp_netif_destroy(esp_netif_t *esp_netif)
209 {
210 if (esp_netif) {
211 esp_netif_remove_from_list(esp_netif);
212 free(esp_netif->ip_info);
213 free(esp_netif->ip_info_old);
214 free(esp_netif->if_key);
215 free(esp_netif->if_desc);
216 free(esp_netif);
217 }
218 }
219
esp_netif_attach(esp_netif_t * esp_netif,esp_netif_iodriver_handle driver_handle)220 esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle)
221 {
222 esp_netif_driver_base_t *base_driver = driver_handle;
223
224 esp_netif->driver_handle = driver_handle;
225 if (base_driver->post_attach) {
226 esp_err_t ret = base_driver->post_attach(esp_netif, driver_handle);
227 if (ret != ESP_OK) {
228 ESP_LOGE(TAG, "Post-attach callback of driver(%p) failed with %d", driver_handle, ret);
229 return ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED;
230 }
231 }
232 return ESP_OK;
233 }
234
esp_netif_set_driver_config(esp_netif_t * esp_netif,const esp_netif_driver_ifconfig_t * driver_config)235 esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif,
236 const esp_netif_driver_ifconfig_t *driver_config)
237 {
238 if (esp_netif == NULL || driver_config == NULL) {
239 return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
240 }
241 esp_netif->driver_handle = driver_config->handle;
242 esp_netif->driver_transmit = driver_config->transmit;
243 esp_netif->driver_free_rx_buffer = driver_config->driver_free_rx_buffer;
244 return ESP_OK;
245 }
246
esp_netif_set_mac(esp_netif_t * esp_netif,uint8_t mac[])247 esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[])
248 {
249 return ESP_ERR_NOT_SUPPORTED;
250 }
251
esp_netif_start(esp_netif_t * esp_netif)252 esp_err_t esp_netif_start(esp_netif_t *esp_netif)
253 {
254 ESP_LOGI(TAG, "Netif started");
255 s_netif_started = true;
256 return ESP_OK;
257 }
258
259
esp_netif_stop(esp_netif_t * esp_netif)260 esp_err_t esp_netif_stop(esp_netif_t *esp_netif)
261 {
262 ESP_LOGI(TAG, "Netif stopped");
263 s_netif_started = false;
264 return ESP_OK;
265 }
266
267 //
268 // IO translate functions
269 //
esp_netif_free_rx_buffer(void * h,void * buffer)270 void esp_netif_free_rx_buffer(void *h, void* buffer)
271 {
272 esp_netif_t *esp_netif = h;
273 esp_netif->driver_free_rx_buffer(esp_netif->driver_handle, buffer);
274 }
275
esp_netif_transmit(esp_netif_t * esp_netif,void * data,size_t len)276 esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len)
277 {
278 ESP_LOGV(TAG, "Transmitting data: ptr:%p, size:%d", data, len);
279 return (esp_netif->driver_transmit)(esp_netif->driver_handle, data, len);
280 }
281
esp_netif_receive(esp_netif_t * esp_netif,void * buffer,size_t len,void * eb)282 esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
283 {
284 ESP_LOGV(TAG, "Received data: ptr:%p, size:%d", buffer, len);
285 esp_netif_transmit(esp_netif, buffer, len);
286 if (eb) {
287 esp_netif_free_rx_buffer(esp_netif, eb);
288 }
289 return ESP_OK;
290 }
291
esp_netif_dhcpc_stop(esp_netif_t * esp_netif)292 esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif)
293 {
294 return ESP_ERR_NOT_SUPPORTED;
295 }
296
esp_netif_dhcpc_start(esp_netif_t * esp_netif)297 esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif)
298 {
299 return ESP_ERR_NOT_SUPPORTED;
300 }
301
esp_netif_dhcps_get_status(esp_netif_t * esp_netif,esp_netif_dhcp_status_t * status)302 esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
303 {
304 return ESP_ERR_NOT_SUPPORTED;
305 }
306
esp_netif_dhcpc_get_status(esp_netif_t * esp_netif,esp_netif_dhcp_status_t * status)307 esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
308 {
309 return ESP_ERR_NOT_SUPPORTED;
310 }
311
esp_netif_dhcps_start(esp_netif_t * esp_netif)312 esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif)
313 {
314 return ESP_ERR_NOT_SUPPORTED;
315 }
316
esp_netif_dhcps_stop(esp_netif_t * esp_netif)317 esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif)
318 {
319 return ESP_ERR_NOT_SUPPORTED;
320 }
321
esp_netif_set_hostname(esp_netif_t * esp_netif,const char * hostname)322 esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname)
323 {
324 return ESP_ERR_NOT_SUPPORTED;
325 }
326
esp_netif_get_hostname(esp_netif_t * esp_netif,const char ** hostname)327 esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname)
328 {
329 return ESP_ERR_NOT_SUPPORTED;
330 }
331
esp_netif_up(esp_netif_t * esp_netif)332 esp_err_t esp_netif_up(esp_netif_t *esp_netif)
333 {
334 ESP_LOGI(TAG, "Netif going up");
335 s_netif_up = true;
336 return ESP_OK;
337 }
338
esp_netif_down(esp_netif_t * esp_netif)339 esp_err_t esp_netif_down(esp_netif_t *esp_netif)
340 {
341 ESP_LOGI(TAG, "Netif going down");
342 s_netif_up = false;
343 return ESP_OK;
344 }
345
esp_netif_is_netif_up(esp_netif_t * esp_netif)346 bool esp_netif_is_netif_up(esp_netif_t *esp_netif)
347 {
348 return s_netif_up;
349 }
350
esp_netif_get_old_ip_info(esp_netif_t * esp_netif,esp_netif_ip_info_t * ip_info)351 esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
352 {
353 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
354
355 if (esp_netif == NULL || ip_info == NULL) {
356 return ESP_ERR_INVALID_ARG;
357 }
358 memcpy(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t));
359 return ESP_OK;
360 }
361
esp_netif_get_ip_info(esp_netif_t * esp_netif,esp_netif_ip_info_t * ip_info)362 esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
363 {
364 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
365
366 if (esp_netif == NULL || ip_info == NULL) {
367 return ESP_ERR_INVALID_ARG;
368 }
369
370 memcpy(ip_info, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
371 return ESP_OK;
372 }
373
374
esp_netif_is_valid_static_ip(esp_netif_ip_info_t * ip_info)375 bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info)
376 {
377 return true;
378 }
379
esp_netif_set_old_ip_info(esp_netif_t * esp_netif,const esp_netif_ip_info_t * ip_info)380 esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info)
381 {
382 ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
383
384 if (esp_netif == NULL || ip_info == NULL) {
385 return ESP_ERR_INVALID_ARG;
386 }
387 memcpy(esp_netif->ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
388 return ESP_OK;
389 }
390
esp_netif_set_dns_info(esp_netif_t * esp_netif,esp_netif_dns_type_t type,esp_netif_dns_info_t * dns)391 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)
392 {
393 return ESP_ERR_NOT_SUPPORTED;
394 }
395
esp_netif_get_dns_info(esp_netif_t * esp_netif,esp_netif_dns_type_t type,esp_netif_dns_info_t * dns)396 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)
397 {
398 return ESP_ERR_NOT_SUPPORTED;
399 }
400
esp_netif_get_sta_list(const wifi_sta_list_t * wifi_sta_list,esp_netif_sta_list_t * netif_sta_list)401 esp_err_t esp_netif_get_sta_list(const wifi_sta_list_t *wifi_sta_list, esp_netif_sta_list_t *netif_sta_list)
402 {
403 return ESP_ERR_NOT_SUPPORTED;
404 }
405
esp_netif_create_ip6_linklocal(esp_netif_t * esp_netif)406 esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif)
407 {
408 return ESP_ERR_NOT_SUPPORTED;
409 }
410
esp_netif_get_ip6_linklocal(esp_netif_t * esp_netif,esp_ip6_addr_t * if_ip6)411 esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
412 {
413 return ESP_ERR_NOT_SUPPORTED;
414 }
415
esp_netif_get_ip6_global(esp_netif_t * esp_netif,esp_ip6_addr_t * if_ip6)416 esp_err_t esp_netif_get_ip6_global(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
417 {
418 return ESP_ERR_NOT_SUPPORTED;
419 }
420
esp_netif_get_flags(esp_netif_t * esp_netif)421 esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif)
422 {
423 return esp_netif->flags;
424 }
425
esp_netif_get_ifkey(esp_netif_t * esp_netif)426 const char *esp_netif_get_ifkey(esp_netif_t *esp_netif)
427 {
428 return esp_netif->if_key;
429 }
430
esp_netif_get_desc(esp_netif_t * esp_netif)431 const char *esp_netif_get_desc(esp_netif_t *esp_netif)
432 {
433 return esp_netif->if_desc;
434 }
435
esp_netif_get_event_id(esp_netif_t * esp_netif,esp_netif_ip_event_type_t event_type)436 int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type)
437 {
438 return 0;
439 }
440
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)441 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,
442 uint32_t opt_len)
443 {
444 return ESP_ERR_NOT_SUPPORTED;
445 }
446
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)447 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,
448 uint32_t opt_len)
449 {
450 return ESP_ERR_NOT_SUPPORTED;
451 }
452
esp_netif_get_netif_impl_index(esp_netif_t * esp_netif)453 int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
454 {
455 return 0;
456 }
457
esp_netif_join_ip6_multicast_group(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)458 esp_err_t esp_netif_join_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
459 {
460 return ESP_ERR_NOT_SUPPORTED;
461 }
462
esp_netif_leave_ip6_multicast_group(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)463 esp_err_t esp_netif_leave_ip6_multicast_group(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
464 {
465 return ESP_ERR_NOT_SUPPORTED;
466 }
467
esp_netif_add_ip6_address(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr,uint8_t preference)468 esp_err_t esp_netif_add_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr, uint8_t preference)
469 {
470 return ESP_ERR_NOT_SUPPORTED;
471 }
472
esp_netif_remove_ip6_address(esp_netif_t * esp_netif,const esp_ip6_addr_t * addr)473 esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
474 {
475 return ESP_ERR_NOT_SUPPORTED;
476 }
477
478 #endif /* CONFIG_ESP_NETIF_LOOPBACK */
479