From b3954c198d40d8680403822a7272271580d38b52 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 3 Oct 2023 16:28:30 +0200 Subject: [PATCH] feat(esp_netif): Added new API to search in netif list --- components/esp_netif/include/esp_netif.h | 18 ++++++++- .../esp_netif/loopback/esp_netif_loopback.c | 4 +- components/esp_netif/lwip/esp_netif_lwip.c | 38 ++++++++++++++++++ .../esp_netif/lwip/esp_netif_lwip_internal.h | 9 +++-- .../esp_netif/test_apps/main/esp_netif_test.c | 39 +++++++++++++++++++ 5 files changed, 101 insertions(+), 7 deletions(-) diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index aeb5ffdd6a..2b1664ce7e 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -945,6 +945,22 @@ int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t */ esp_netif_t *esp_netif_next(esp_netif_t *esp_netif); +/** + * @brief Predicate callback for esp_netif_find_if() used to find interface + * which meets defined criteria + */ +typedef bool (*esp_netif_find_predicate_t)(esp_netif_t *netif, void *ctx); + +/** + * @brief Return a netif pointer for the interface that meets criteria defined + * by the callback + * + * @param fn Predicate function returning true for the desired interface + * @param ctx Context pointer passed to the predicate, typically a descriptor to compare with + * @return valid netif pointer if found, NULL if not + */ +esp_netif_t *esp_netif_find_if(esp_netif_find_predicate_t fn, void *ctx); + /** * @brief Returns number of registered esp_netif objects * diff --git a/components/esp_netif/loopback/esp_netif_loopback.c b/components/esp_netif/loopback/esp_netif_loopback.c index e3fbb71921..0721fcce58 100644 --- a/components/esp_netif/loopback/esp_netif_loopback.c +++ b/components/esp_netif/loopback/esp_netif_loopback.c @@ -187,7 +187,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) } esp_netif->ip_info_old = ip_info; - esp_netif_add_to_list(esp_netif); + esp_netif_add_to_list_unsafe(esp_netif); // Configure the created object with provided configuration esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config); @@ -203,7 +203,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) void esp_netif_destroy(esp_netif_t *esp_netif) { if (esp_netif) { - esp_netif_remove_from_list(esp_netif); + esp_netif_remove_from_list_unsafe(esp_netif); free(esp_netif->ip_info); free(esp_netif->ip_info_old); free(esp_netif->if_key); diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index ed06d4dfd1..37c4f5a648 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -251,6 +251,16 @@ static inline esp_err_t esp_netif_lwip_ipc_call_fn(esp_netif_api_fn fn, esp_neti return esp_netif_lwip_ipc_call_msg(&msg); } +static inline esp_err_t esp_netif_lwip_ipc_call_get_netif(esp_netif_api_fn fn, esp_netif_t **netif, void *ctx) +{ + esp_netif_api_msg_t msg = { + .p_esp_netif = netif, + .data = ctx, + .api_fn = fn + }; + return esp_netif_lwip_ipc_call_msg(&msg); +} + static inline esp_err_t esp_netif_lwip_ipc_no_args(esp_netif_api_fn fn) { esp_netif_api_msg_t msg = { @@ -768,6 +778,34 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) return esp_netif; } +typedef struct find_if_api { + esp_netif_find_predicate_t fn; + void *ctx; +} find_if_api_t; + +static esp_err_t esp_netif_find_if_api(esp_netif_api_msg_t *msg) +{ + find_if_api_t *find_if_api = msg->data; + esp_netif_t *esp_netif = NULL; + while ((esp_netif = esp_netif_next(esp_netif)) != NULL) { + if (find_if_api->fn(esp_netif, find_if_api->ctx)) { + *msg->p_esp_netif = esp_netif; + return ESP_OK; + } + } + return ESP_FAIL; +} + +esp_netif_t *esp_netif_find_if(esp_netif_find_predicate_t fn, void *ctx) +{ + esp_netif_t *netif = NULL; + find_if_api_t find_if_api = { .fn = fn, .ctx = ctx }; + if (esp_netif_lwip_ipc_call_get_netif(esp_netif_find_if_api, &netif, &find_if_api) == ESP_OK) { + return netif; + } + return NULL; +} + static void esp_netif_lwip_remove(esp_netif_t *esp_netif) { if (esp_netif->lwip_netif) { diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 5b154d4c8d..715005ba60 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,9 +22,10 @@ typedef struct esp_netif_api_msg_s { int ret; esp_netif_api_fn api_fn; union { - esp_netif_t *esp_netif; - esp_netif_callback_fn user_fn; - }; + esp_netif_t *esp_netif; /* esp_netif as input param */ + esp_netif_t **p_esp_netif; /* esp_netif as output */ + esp_netif_callback_fn user_fn; /* user callback */ + }; /* Commonly used parameters what calling api_fn */ void *data; } esp_netif_api_msg_t; diff --git a/components/esp_netif/test_apps/main/esp_netif_test.c b/components/esp_netif/test_apps/main/esp_netif_test.c index 12bef72e57..2eeece32fb 100644 --- a/components/esp_netif/test_apps/main/esp_netif_test.c +++ b/components/esp_netif/test_apps/main/esp_netif_test.c @@ -77,6 +77,44 @@ TEST(esp_netif, create_delete_multiple_netifs) } +static bool desc_matches_with(esp_netif_t *netif, void *ctx) +{ + return strcmp(ctx, esp_netif_get_desc(netif)) == 0; +} + +TEST(esp_netif, find_netifs) +{ + // Create some interfaces + const char* if_keys[] = { "if1", "if2", "if3", "if4", "if5"}; + const int nr_of_netifs = sizeof(if_keys)/sizeof(char*); + esp_netif_t *netifs[nr_of_netifs]; + + for (int i=0; i