feat(esp_netif): Added new API to search in netif list

This commit is contained in:
David Cermak
2023-10-03 16:28:30 +02:00
parent 104a1eeb16
commit b3954c198d
5 changed files with 101 additions and 7 deletions

View File

@ -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
*

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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<nr_of_netifs; ++i) {
// Create all interfaces, the same string is used as a key and as description
esp_netif_inherent_config_t base_netif_config = { .if_key = if_keys[i], .if_desc = if_keys[i] };
esp_netif_config_t cfg = { .base = &base_netif_config, .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA };
netifs[i] = esp_netif_new(&cfg);
TEST_ASSERT_NOT_NULL(netifs[i]);
}
// not found
esp_netif_t *found_netif = esp_netif_find_if(desc_matches_with, "not_present");
TEST_ASSERT_EQUAL(found_netif, NULL);
// should find the same netif, as returned from esp_netif_get_handle_from_ifkey(), as the key is the same as description
for (int i=0; i<nr_of_netifs; ++i) {
found_netif = esp_netif_find_if(desc_matches_with, (void*)if_keys[i]);
TEST_ASSERT_EQUAL(found_netif, esp_netif_get_handle_from_ifkey(if_keys[i]));
}
// destroy one by one and check it's cannot be find per its description
for (int i=0; i<nr_of_netifs; ++i) {
esp_netif_destroy(netifs[i]);
found_netif = esp_netif_find_if(desc_matches_with, (void*)if_keys[i]);
TEST_ASSERT_EQUAL(found_netif, NULL);
}
}
TEST(esp_netif, dhcp_client_state_transitions_wifi_sta)
{
// init default wifi netif
@ -273,6 +311,7 @@ TEST_GROUP_RUNNER(esp_netif)
RUN_TEST_CASE(esp_netif, init_and_destroy)
RUN_TEST_CASE(esp_netif, get_from_if_key)
RUN_TEST_CASE(esp_netif, create_delete_multiple_netifs)
RUN_TEST_CASE(esp_netif, find_netifs)
RUN_TEST_CASE(esp_netif, dhcp_client_state_transitions_wifi_sta)
RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_wifi_ap)
RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_mesh)