| 
									
										
										
										
											2022-02-08 17:39:38 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: Apache-2.0 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "esp_netif.h"
 | 
					
						
							|  |  |  | #include "sys/queue.h"
 | 
					
						
							|  |  |  | #include "esp_log.h"
 | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "freertos/semphr.h"
 | 
					
						
							|  |  |  | #include "esp_netif_private.h"
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Purpose of this module is to provide list of esp-netif structures
 | 
					
						
							|  |  |  | //  - this module has no dependency on a specific network stack (lwip)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char *TAG = "esp_netif_objects"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct slist_netifs_s slist_netifs_t; | 
					
						
							|  |  |  | struct slist_netifs_s { | 
					
						
							|  |  |  |     esp_netif_t *netif; | 
					
						
							|  |  |  |     SLIST_ENTRY(slist_netifs_s) next; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SLIST_HEAD(slisthead, slist_netifs_s) s_head = { .slh_first = NULL, }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static size_t s_esp_netif_counter = 0; | 
					
						
							| 
									
										
										
										
											2022-02-08 17:39:38 +08:00
										 |  |  | static SemaphoreHandle_t  s_list_lock = NULL; | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ESP_EVENT_DEFINE_BASE(IP_EVENT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  | esp_err_t esp_netif_list_lock(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (s_list_lock == NULL) { | 
					
						
							|  |  |  |         s_list_lock = xSemaphoreCreateMutex(); | 
					
						
							|  |  |  |         if (s_list_lock == NULL) { | 
					
						
							|  |  |  |             return ESP_ERR_NO_MEM; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     xSemaphoreTake(s_list_lock, portMAX_DELAY); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void esp_netif_list_unlock(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(s_list_lock); | 
					
						
							|  |  |  |     xSemaphoreGive(s_list_lock); | 
					
						
							|  |  |  |     if (s_esp_netif_counter == 0) { | 
					
						
							|  |  |  |         vQueueDelete(s_list_lock); | 
					
						
							|  |  |  |         s_list_lock = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // List manipulation functions
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | esp_err_t esp_netif_add_to_list(esp_netif_t *netif) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_err_t ret; | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     struct slist_netifs_s *item = calloc(1, sizeof(struct slist_netifs_s)); | 
					
						
							|  |  |  |     ESP_LOGD(TAG, "%s %p", __func__, netif); | 
					
						
							|  |  |  |     if (item == NULL) { | 
					
						
							|  |  |  |         return ESP_ERR_NO_MEM; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     item->netif = netif; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     if ((ret = esp_netif_list_lock()) != ESP_OK) { | 
					
						
							| 
									
										
										
										
											2020-05-11 21:37:00 +02:00
										 |  |  |         free(item); | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     SLIST_INSERT_HEAD(&s_head, item, next); | 
					
						
							|  |  |  |     ++s_esp_netif_counter; | 
					
						
							| 
									
										
										
										
											2023-02-02 16:27:29 +01:00
										 |  |  |     ESP_LOGD(TAG, "%s netif added successfully (total netifs: %" PRIu32 ")", __func__, (uint32_t)s_esp_netif_counter); | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_netif_list_unlock(); | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t esp_netif_remove_from_list(esp_netif_t *netif) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct slist_netifs_s *item; | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_err_t ret; | 
					
						
							|  |  |  |     if ((ret = esp_netif_list_lock()) != ESP_OK) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     ESP_LOGV(TAG, "%s %p", __func__, netif); | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     SLIST_FOREACH(item, &s_head, next) { | 
					
						
							|  |  |  |         if (item->netif == netif) { | 
					
						
							|  |  |  |             SLIST_REMOVE(&s_head, item, slist_netifs_s, next); | 
					
						
							|  |  |  |             assert(s_esp_netif_counter > 0); | 
					
						
							|  |  |  |             --s_esp_netif_counter; | 
					
						
							| 
									
										
										
										
											2023-02-02 16:27:29 +01:00
										 |  |  |             ESP_LOGD(TAG, "%s netif successfully removed (total netifs: %" PRIu32 ")", __func__, (uint32_t)s_esp_netif_counter); | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |             free(item); | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |             esp_netif_list_unlock(); | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |             return ESP_OK; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_netif_list_unlock(); | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     return ESP_ERR_NOT_FOUND; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t esp_netif_get_nr_of_ifs(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s_esp_netif_counter; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_netif_t* esp_netif_next(esp_netif_t* netif) | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     esp_err_t ret; | 
					
						
							|  |  |  |     esp_netif_t* result; | 
					
						
							|  |  |  |     if ((ret = esp_netif_list_lock()) != ESP_OK) { | 
					
						
							|  |  |  |         ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     result = esp_netif_next_unsafe(netif); | 
					
						
							|  |  |  |     esp_netif_list_unlock(); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif) | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     ESP_LOGV(TAG, "%s %p", __func__, netif); | 
					
						
							|  |  |  |     struct slist_netifs_s *item; | 
					
						
							| 
									
										
										
										
											2019-10-23 15:17:18 +02:00
										 |  |  |     // Getting the first netif if argument is NULL
 | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |     if (netif == NULL) { | 
					
						
							|  |  |  |         item = SLIST_FIRST(&s_head); | 
					
						
							|  |  |  |         return (item == NULL) ? NULL : item->netif; | 
					
						
							| 
									
										
										
										
											2019-10-23 15:17:18 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     // otherwise the next one (after the supplied netif)
 | 
					
						
							|  |  |  |     SLIST_FOREACH(item, &s_head, next) { | 
					
						
							|  |  |  |         if (item->netif == netif) { | 
					
						
							|  |  |  |             item = SLIST_NEXT(item, next); | 
					
						
							|  |  |  |             return (item == NULL) ? NULL : item->netif; | 
					
						
							| 
									
										
										
										
											2019-06-28 16:47:34 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool esp_netif_is_netif_listed(esp_netif_t *esp_netif) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |     struct slist_netifs_s *item; | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_err_t ret; | 
					
						
							|  |  |  |     if ((ret = esp_netif_list_lock()) != ESP_OK) { | 
					
						
							|  |  |  |         ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret); | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |     SLIST_FOREACH(item, &s_head, next) { | 
					
						
							|  |  |  |         if (item->netif == esp_netif) { | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |             esp_netif_list_unlock(); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_netif_list_unlock(); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |     struct slist_netifs_s *item; | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_err_t ret; | 
					
						
							|  |  |  |     if ((ret = esp_netif_list_lock()) != ESP_OK) { | 
					
						
							|  |  |  |         ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |     SLIST_FOREACH(item, &s_head, next) { | 
					
						
							|  |  |  |         esp_netif_t *esp_netif = item->netif; | 
					
						
							|  |  |  |         if (strcmp(if_key, esp_netif_get_ifkey(esp_netif)) == 0) { | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |             esp_netif_list_unlock(); | 
					
						
							|  |  |  |             return esp_netif; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-20 13:41:00 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-22 09:43:20 +02:00
										 |  |  |     esp_netif_list_unlock(); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2020-06-12 16:43:34 +02:00
										 |  |  | } |