From 606363897c1b6f11ba4dd442c80daf00b8fe33ee 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 | 16 ++++++++ .../esp_netif/loopback/esp_netif_loopback.c | 4 +- components/esp_netif/lwip/esp_netif_lwip.c | 28 +++++++++++++ .../test_app_esp_netif/main/esp_netif_test.c | 39 +++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index a1b3368990..7a698175c4 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -985,6 +985,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 0d7d7f47c5..0b41dda795 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -803,6 +803,34 @@ esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) return 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/test_apps/test_app_esp_netif/main/esp_netif_test.c b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c index 18b4ee92e5..472a8de7ad 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c @@ -129,6 +129,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