net: conn_mgr: Bulk convenience functions
To further reduce the need for networking boilerplate in applications, provide bulk versions of net_if_up, net_if_down, conn_mgr_if_connect, and conn_mgr_if_disconnect that affect all available / eligible ifaces at once. Since it is not intuitive whether these functions should affect ifaces which conn_mgr is ignoring, these functions take an argument that allows this to be specified by the application. Signed-off-by: Georges Oates_Larsen <georges.larsen@nordicsemi.no>
This commit is contained in:
parent
b65613e79c
commit
ad6fdaf2c2
4 changed files with 638 additions and 1 deletions
|
|
@ -423,6 +423,57 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout);
|
|||
*/
|
||||
void conn_mgr_conn_init(void);
|
||||
|
||||
/**
|
||||
* @brief Convenience function that takes all available ifaces into the admin-up state.
|
||||
*
|
||||
* Essentially a wrapper for net_if_up.
|
||||
*
|
||||
* @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
|
||||
* Otherwise, affect all ifaces.
|
||||
* @return 0 if all net_if_up calls returned 0, otherwise the first nonzero value
|
||||
* returned by a net_if_up call.
|
||||
*/
|
||||
int conn_mgr_all_if_up(bool skip_ignored);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience function that takes all available ifaces into the admin-down state.
|
||||
*
|
||||
* Essentially a wrapper for net_if_down.
|
||||
*
|
||||
* @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
|
||||
* Otherwise, affect all ifaces.
|
||||
* @return 0 if all net_if_down calls returned 0, otherwise the first nonzero value
|
||||
* returned by a net_if_down call.
|
||||
*/
|
||||
int conn_mgr_all_if_down(bool skip_ignored);
|
||||
|
||||
/**
|
||||
* @brief Convenience function that takes all available ifaces into the admin-up state, and
|
||||
* connects those that support connectivity.
|
||||
*
|
||||
* Essentially a wrapper for net_if_up and conn_mgr_if_connect.
|
||||
*
|
||||
* @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
|
||||
* Otherwise, affect all ifaces.
|
||||
* @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero
|
||||
* value returned by either net_if_up or conn_mgr_if_connect.
|
||||
*/
|
||||
int conn_mgr_all_if_connect(bool skip_ignored);
|
||||
|
||||
/**
|
||||
* @brief Convenience function that disconnects all available ifaces that support connectivity
|
||||
* without putting them into admin-down state (unless auto-down is enabled for the iface).
|
||||
*
|
||||
* Essentially a wrapper for net_if_down.
|
||||
*
|
||||
* @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr.
|
||||
* Otherwise, affect all ifaces.
|
||||
* @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero
|
||||
* value returned by either net_if_up or conn_mgr_if_connect.
|
||||
*/
|
||||
int conn_mgr_all_if_disconnect(bool skip_ignored);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@
|
|||
LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL);
|
||||
|
||||
#include <zephyr/net/net_if.h>
|
||||
#include <zephyr/net/conn_mgr_connectivity.h>
|
||||
#include <zephyr/sys/iterable_sections.h>
|
||||
#include <zephyr/net/conn_mgr.h>
|
||||
|
||||
#include <zephyr/net/conn_mgr_connectivity.h>
|
||||
|
||||
#include "conn_mgr_private.h"
|
||||
|
||||
|
|
@ -422,3 +424,144 @@ void conn_mgr_conn_init(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum conn_mgr_conn_all_if_oper {
|
||||
ALL_IF_UP,
|
||||
ALL_IF_DOWN,
|
||||
ALL_IF_CONNECT,
|
||||
ALL_IF_DISCONNECT
|
||||
};
|
||||
|
||||
struct conn_mgr_conn_all_if_ctx {
|
||||
bool skip_ignored;
|
||||
enum conn_mgr_conn_all_if_oper operation;
|
||||
int status;
|
||||
};
|
||||
|
||||
/* Per-iface callback for conn_mgr_conn_all_if_up */
|
||||
static void conn_mgr_conn_all_if_cb(struct net_if *iface, void *user_data)
|
||||
{
|
||||
int status = 0;
|
||||
struct conn_mgr_conn_all_if_ctx *context = (struct conn_mgr_conn_all_if_ctx *)user_data;
|
||||
|
||||
/* Skip ignored ifaces if so desired */
|
||||
if (context->skip_ignored && conn_mgr_is_iface_ignored(iface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform the requested operation */
|
||||
switch (context->operation) {
|
||||
case ALL_IF_UP:
|
||||
/* Do not take iface admin up if it already is. */
|
||||
if (net_if_is_admin_up(iface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = net_if_up(iface);
|
||||
break;
|
||||
case ALL_IF_DOWN:
|
||||
/* Do not take iface admin down if it already is. */
|
||||
if (!net_if_is_admin_up(iface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = net_if_down(iface);
|
||||
break;
|
||||
case ALL_IF_CONNECT:
|
||||
/* Connect operation only supported if iface is bound */
|
||||
if (!conn_mgr_if_is_bound(iface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = conn_mgr_if_connect(iface);
|
||||
break;
|
||||
case ALL_IF_DISCONNECT:
|
||||
/* Disconnect operation only supported if iface is bound */
|
||||
if (!conn_mgr_if_is_bound(iface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = conn_mgr_if_disconnect(iface);
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->status == 0) {
|
||||
context->status = status;
|
||||
}
|
||||
|
||||
NET_ERR("%s failed for iface %d (%p). Error: %d",
|
||||
context->operation == ALL_IF_UP ? "net_if_up" :
|
||||
context->operation == ALL_IF_DOWN ? "net_if_down" :
|
||||
context->operation == ALL_IF_CONNECT ? "conn_mgr_if_connect" :
|
||||
context->operation == ALL_IF_DISCONNECT ? "conn_mgr_if_disconnect" :
|
||||
"invalid",
|
||||
net_if_get_by_iface(iface), iface, status
|
||||
);
|
||||
}
|
||||
|
||||
int conn_mgr_all_if_up(bool skip_ignored)
|
||||
{
|
||||
struct conn_mgr_conn_all_if_ctx context = {
|
||||
.operation = ALL_IF_UP,
|
||||
.skip_ignored = skip_ignored,
|
||||
.status = 0
|
||||
};
|
||||
|
||||
net_if_foreach(conn_mgr_conn_all_if_cb, &context);
|
||||
|
||||
return context.status;
|
||||
}
|
||||
|
||||
int conn_mgr_all_if_down(bool skip_ignored)
|
||||
{
|
||||
struct conn_mgr_conn_all_if_ctx context = {
|
||||
.operation = ALL_IF_DOWN,
|
||||
.skip_ignored = skip_ignored,
|
||||
.status = 0
|
||||
};
|
||||
|
||||
net_if_foreach(conn_mgr_conn_all_if_cb, &context);
|
||||
|
||||
return context.status;
|
||||
}
|
||||
|
||||
int conn_mgr_all_if_connect(bool skip_ignored)
|
||||
{
|
||||
/* First, take all ifaces up.
|
||||
* All bound ifaces will do this automatically when connect is called, but non-bound ifaces
|
||||
* won't, so we must request it explicitly.
|
||||
*/
|
||||
struct conn_mgr_conn_all_if_ctx context = {
|
||||
.operation = ALL_IF_UP,
|
||||
.skip_ignored = skip_ignored,
|
||||
.status = 0
|
||||
};
|
||||
|
||||
net_if_foreach(conn_mgr_conn_all_if_cb, &context);
|
||||
|
||||
/* Now connect all ifaces.
|
||||
* We are delibarately not resetting context.status between these two calls so that
|
||||
* the first nonzero status code encountered between the two of them is what is returned.
|
||||
*/
|
||||
context.operation = ALL_IF_CONNECT;
|
||||
net_if_foreach(conn_mgr_conn_all_if_cb, &context);
|
||||
|
||||
return context.status;
|
||||
}
|
||||
|
||||
int conn_mgr_all_if_disconnect(bool skip_ignored)
|
||||
{
|
||||
struct conn_mgr_conn_all_if_ctx context = {
|
||||
.operation = ALL_IF_DISCONNECT,
|
||||
.skip_ignored = skip_ignored,
|
||||
.status = 0
|
||||
};
|
||||
|
||||
net_if_foreach(conn_mgr_conn_all_if_cb, &context);
|
||||
|
||||
return context.status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,3 +24,7 @@ CONFIG_ZTEST_NEW_API=y
|
|||
CONFIG_NET_IF_MAX_IPV4_COUNT=6
|
||||
CONFIG_NET_IF_MAX_IPV6_COUNT=6
|
||||
CONFIG_TEST_USERSPACE=y
|
||||
|
||||
# Increased net event queue size needed since this test performs simultaneous events on a
|
||||
# large number of ifaces.
|
||||
CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <zephyr/ztest.h>
|
||||
#include <zephyr/net/net_if.h>
|
||||
#include <zephyr/net/conn_mgr_connectivity.h>
|
||||
#include <zephyr/net/conn_mgr.h>
|
||||
#include "conn_mgr_private.h"
|
||||
#include "test_conn_impl.h"
|
||||
#include "test_ifaces.h"
|
||||
|
|
@ -54,6 +55,9 @@ static void reset_test_iface_state(struct net_if *iface)
|
|||
struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface);
|
||||
struct test_conn_data *iface_data = conn_mgr_if_get_data(iface);
|
||||
|
||||
/* Some tests mark ifaces as ignored, this must be reset between each test. */
|
||||
conn_mgr_watch_iface(iface);
|
||||
|
||||
if (iface_binding) {
|
||||
/* Reset all flags and settings for the binding */
|
||||
iface_binding->flags = 0;
|
||||
|
|
@ -1139,5 +1143,440 @@ ZTEST(conn_mgr_conn, test_auto_down_fatal)
|
|||
"Auto-down should not trigger on fatal error if it is disabled.");
|
||||
}
|
||||
|
||||
/* Verify that all_if_up brings all ifaces up, but only if they are not ignored or
|
||||
* skip_ignored is false
|
||||
*/
|
||||
ZTEST(conn_mgr_conn, test_all_if_up)
|
||||
{
|
||||
/* Ignore an iface */
|
||||
conn_mgr_ignore_iface(ifa1);
|
||||
|
||||
/* Take all ifaces up (do not skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_up(false), 0, "conn_mgr_all_if_up should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all ifaces are up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
|
||||
|
||||
/* Manually take all ifaces down */
|
||||
zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Take all ifaces up (skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_up(true), 0, "conn_mgr_all_if_up should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all except ignored are up */
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-up.");
|
||||
|
||||
zassert_false(net_if_is_admin_up(ifa1), "Ignored iface should not be admin-up.");
|
||||
}
|
||||
|
||||
/* Verify that all_if_connect brings all ifaces up, and connects all bound ifaces, but only those
|
||||
* that are not ignored, or all of them if skip_ignored is false
|
||||
*/
|
||||
ZTEST(conn_mgr_conn, test_all_if_connect)
|
||||
{
|
||||
/* Ignore a bound and an unbound iface */
|
||||
conn_mgr_ignore_iface(ifa1);
|
||||
conn_mgr_ignore_iface(ifnone);
|
||||
|
||||
/* Connect all ifaces (do not skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_connect(false), 0, "conn_mgr_all_if_connect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all ifaces are up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
|
||||
/* Verify bound ifaces are connected */
|
||||
zassert_true(net_if_is_up(ifa1), "All bound ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifa2), "All bound ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifb), "All bound ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifni), "All bound ifaces should be connected.");
|
||||
|
||||
/* Manually take all ifaces down */
|
||||
zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "net_if_disconnect should succeed.");
|
||||
zassert_equal(conn_mgr_if_disconnect(ifa2), 0, "net_if_disconnect should succeed.");
|
||||
zassert_equal(conn_mgr_if_disconnect(ifb), 0, "net_if_disconnect should succeed.");
|
||||
zassert_equal(conn_mgr_if_disconnect(ifni), 0, "net_if_disconnect should succeed.");
|
||||
|
||||
zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces.");
|
||||
zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Connect all ifaces (skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_connect(true), 0, "conn_mgr_all_if_connect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all except ignored are up */
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up.");
|
||||
|
||||
zassert_false(net_if_is_admin_up(ifa1), "All ignored ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnone), "All ignored ifaces should be admin-down.");
|
||||
|
||||
/* Verify bound ifaces are connected, except for ignored */
|
||||
zassert_true(net_if_is_up(ifa2), "All non-ignored bound ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifb), "All non-ignored bound ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifni), "All non-ignored bound ifaces should be connected.");
|
||||
|
||||
zassert_false(net_if_is_up(ifa1), "Ignored iface should not be connected.");
|
||||
}
|
||||
|
||||
/* Verify that all_if_down takes all ifaces down, but only if they are not ignored,
|
||||
* or skip_ignored is false
|
||||
*/
|
||||
ZTEST(conn_mgr_conn, test_all_if_down)
|
||||
{
|
||||
/* Ignore an iface */
|
||||
conn_mgr_ignore_iface(ifa1);
|
||||
|
||||
/* Manually take all ifaces up */
|
||||
zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Take all ifaces down (do not skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_down(false), 0, "conn_mgr_all_if_down should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all ifaces are down */
|
||||
zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down.");
|
||||
|
||||
/* Manually take all ifaces up */
|
||||
zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Take all ifaces down (skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_down(true), 0, "conn_mgr_all_if_down should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify that all except the ignored iface is down */
|
||||
zassert_false(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-down.");
|
||||
|
||||
zassert_true(net_if_is_admin_up(ifa1), "Ignored iface should be admin-up.");
|
||||
}
|
||||
|
||||
/* Verify that all_if_disconnect disconnects all bound ifaces, but only if they are not ignored,
|
||||
* or skip_ignored is false
|
||||
*/
|
||||
ZTEST(conn_mgr_conn, test_all_if_disconnect)
|
||||
{
|
||||
/* Ignore a bound iface */
|
||||
conn_mgr_ignore_iface(ifa1);
|
||||
|
||||
/* Manually take all ifaces up */
|
||||
zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Manually connect all bound ifaces */
|
||||
zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Disconnect all ifaces (do not skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_disconnect(false), 0,
|
||||
"conn_mgr_all_if_disconnect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify that all bound ifaces are disconnected */
|
||||
zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected.");
|
||||
|
||||
/* Verify that all ifaces are still up, even if disconnected */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
|
||||
/* Manually reconnect bound ifaces */
|
||||
zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Disconnect all ifaces (skip ignored) */
|
||||
zassert_equal(conn_mgr_all_if_disconnect(true), 0,
|
||||
"conn_mgr_all_if_disconnect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify that all bound ifaces are disconnected, except the ignored iface */
|
||||
zassert_false(net_if_is_up(ifa2), "All non-ignored bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifb), "All non-ignored bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifni), "All non-ignored bound ifaces should be disconnected.");
|
||||
|
||||
zassert_true(net_if_is_up(ifa1), "Ignored iface should still be connected");
|
||||
}
|
||||
|
||||
|
||||
/* Verify that double calls to all_if_up do not raise errors */
|
||||
ZTEST(conn_mgr_conn, test_all_if_up_double)
|
||||
{
|
||||
/* Take all ifaces up twice in a row */
|
||||
zassert_equal(conn_mgr_all_if_up(false), 0,
|
||||
"conn_mgr_all_if_up should succeed.");
|
||||
zassert_equal(conn_mgr_all_if_up(false), 0,
|
||||
"conn_mgr_all_if_up should succeed twice in a row.");
|
||||
|
||||
/* One more time, after a delay, to be sure */
|
||||
k_sleep(K_MSEC(1));
|
||||
zassert_equal(conn_mgr_all_if_up(false), 0,
|
||||
"conn_mgr_all_if_up should succeed twice in a row.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all ifaces are up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
}
|
||||
|
||||
/* Verify that double calls to all_if_down do not raise errors */
|
||||
ZTEST(conn_mgr_conn, test_all_if_down_double)
|
||||
{
|
||||
/* Manually take all ifaces up */
|
||||
zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Take all ifaces down twice in a row */
|
||||
zassert_equal(conn_mgr_all_if_down(false), 0,
|
||||
"conn_mgr_all_if_down should succeed.");
|
||||
zassert_equal(conn_mgr_all_if_down(false), 0,
|
||||
"conn_mgr_all_if_down should succeed twice in a row.");
|
||||
|
||||
/* One more time, after a delay, to be sure */
|
||||
k_sleep(K_MSEC(1));
|
||||
zassert_equal(conn_mgr_all_if_down(false), 0,
|
||||
"conn_mgr_all_if_down should succeed twice in a row.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all ifaces are down */
|
||||
zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down.");
|
||||
zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down.");
|
||||
}
|
||||
|
||||
/* Verify that double calls to all_if_connect do not raise errors */
|
||||
ZTEST(conn_mgr_conn, test_all_if_connect_double)
|
||||
{
|
||||
/* Connect all ifaces twice in a row */
|
||||
zassert_equal(conn_mgr_all_if_connect(false), 0,
|
||||
"conn_mgr_all_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_all_if_connect(false), 0,
|
||||
"conn_mgr_all_if_connect should succeed twice in a row.");
|
||||
|
||||
/* One more time, after a delay, to be sure */
|
||||
k_sleep(K_MSEC(1));
|
||||
zassert_equal(conn_mgr_all_if_connect(false), 0,
|
||||
"conn_mgr_all_if_connect should succeed twice in a row.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all ifaces are up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
|
||||
/* Verify all bound ifaces are connected */
|
||||
}
|
||||
|
||||
/* Verify that double calls to all_if_disconnect do not raise errors */
|
||||
ZTEST(conn_mgr_conn, test_all_if_disconnect_double)
|
||||
{
|
||||
/* Manually take all ifaces up */
|
||||
zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Manually connect all bound ifaces */
|
||||
zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Connect all ifaces twice in a row */
|
||||
zassert_equal(conn_mgr_all_if_disconnect(false), 0,
|
||||
"conn_mgr_all_if_disconnect should succeed.");
|
||||
zassert_equal(conn_mgr_all_if_disconnect(false), 0,
|
||||
"conn_mgr_all_if_disconnect should succeed twice in a row.");
|
||||
|
||||
/* One more time, after a delay, to be sure */
|
||||
k_sleep(K_MSEC(1));
|
||||
zassert_equal(conn_mgr_all_if_disconnect(false), 0,
|
||||
"conn_mgr_all_if_disconnect should succeed twice in a row.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify all bound ifaces are disconnected */
|
||||
zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected.");
|
||||
|
||||
/* Verify all ifaces are up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Testing error passing for all_if_up/all_if_down is not possible without using an L2 other than
|
||||
* Dummy, since the dummy L2 is not capable of erroring in response to either of these.
|
||||
*
|
||||
* However, since all bulk convenience functions share a single implementation, testing
|
||||
* connect and disconnect is sufficient to gain acceptable coverage of this behavior for all of
|
||||
* them.
|
||||
*/
|
||||
|
||||
/* Verify that all_if_connect successfully forwards errors encountered on individual ifaces */
|
||||
ZTEST(conn_mgr_conn, test_all_if_connect_err)
|
||||
{
|
||||
struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1);
|
||||
|
||||
/* Schedule a connect error on one of the ifaces */
|
||||
ifa1_data->api_err = -ECHILD;
|
||||
|
||||
/* Verify that this error is passed to all_if_connect */
|
||||
zassert_equal(conn_mgr_all_if_connect(false), -ECHILD,
|
||||
"conn_mgr_all_if_connect should fail with the requested error.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Verify that all ifaces went admin-up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
|
||||
/* Verify that all the non-error ifaces are connected */
|
||||
zassert_true(net_if_is_up(ifa2), "All non-failing ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifb), "All non-failing ifaces should be connected.");
|
||||
zassert_true(net_if_is_up(ifni), "All non-failing ifaces should be connected.");
|
||||
|
||||
/* Verify that the error iface is not connected */
|
||||
zassert_false(net_if_is_up(ifa1), "The failing iface should not be connected.");
|
||||
}
|
||||
|
||||
/* Verify that all_if_disconnect successfully forwards errors encountered on individual ifaces */
|
||||
ZTEST(conn_mgr_conn, test_all_if_disconnect_err)
|
||||
{
|
||||
struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1);
|
||||
|
||||
/* Manually take all ifaces up */
|
||||
zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces.");
|
||||
zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Manually connect all bound ifaces */
|
||||
zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed.");
|
||||
zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed.");
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Schedule a disconnect error on one of the ifaces */
|
||||
ifa1_data->api_err = -ECHILD;
|
||||
|
||||
/* Verify that this error is passed to all_if_disconnect */
|
||||
zassert_equal(conn_mgr_all_if_disconnect(false), -ECHILD,
|
||||
"conn_mgr_all_if_disconnect should fail with the requested error.");
|
||||
|
||||
/* Verify that all ifaces are still admin-up */
|
||||
zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up.");
|
||||
zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up.");
|
||||
|
||||
/* Verify that all the non-error ifaces are disconnected */
|
||||
zassert_false(net_if_is_up(ifa2), "All non-failing ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifb), "All non-failing ifaces should be disconnected.");
|
||||
zassert_false(net_if_is_up(ifni), "All non-failing ifaces should be disconnected.");
|
||||
|
||||
/* Verify that the error iface is not connected */
|
||||
zassert_true(net_if_is_up(ifa1), "The failing iface should not be disconnected.");
|
||||
}
|
||||
|
||||
ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL);
|
||||
|
|
|
|||
Loading…
Reference in a new issue