net: nsos_sockets: conn_mgr support

Add support for using native sockets with the connectivity API. This
allows libraries that use the connectivity API to be tested in an
application with real connectivity, without external hardware.

Signed-off-by: Jordan Yates <jordan@embeint.com>
This commit is contained in:
Jordan Yates 2025-05-20 14:22:20 +10:00 committed by Benjamin Cabé
commit 2203a571bc
2 changed files with 121 additions and 0 deletions

View file

@ -269,6 +269,20 @@ config NET_NATIVE_OFFLOADED_SOCKETS_EPOLL_WAIT_INTERVAL
Decrease that value when lower network traffic latency is expected, at the expense of more Decrease that value when lower network traffic latency is expected, at the expense of more
CPU processing overhead. CPU processing overhead.
config NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM
bool "Support for the network connectivity API"
help
Simulate an interface that transitions through the dormant state based on calls
to the network connectivity API, after some delay.
config NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM_AUTO_CONNECT
bool "Automatically connect"
depends on NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM
help
If this option is set the Connection Manager will automatically call connect after the
network interface has been brought up. This option sets the default value, the option has
a corresponding flag that can be set at run time by calling conn_mgr_if_set_flag().
endif # NET_NATIVE_OFFLOADED_SOCKETS endif # NET_NATIVE_OFFLOADED_SOCKETS
endif # NET_DRIVERS endif # NET_DRIVERS

View file

@ -18,6 +18,8 @@ LOG_MODULE_REGISTER(nsos_sockets);
#include <soc.h> #include <soc.h>
#include <string.h> #include <string.h>
#include <zephyr/net/conn_mgr_connectivity.h>
#include <zephyr/net/conn_mgr_connectivity_impl.h>
#include <zephyr/net/ethernet.h> #include <zephyr/net/ethernet.h>
#include <zephyr/net/net_ip.h> #include <zephyr/net/net_ip.h>
#include <zephyr/net/offloaded_netdev.h> #include <zephyr/net/offloaded_netdev.h>
@ -1591,3 +1593,108 @@ NET_DEVICE_OFFLOAD_INIT(nsos_socket, "nsos_socket",
NULL, NULL,
NULL, NULL, NULL, NULL,
0, &nsos_iface_offload_api, NET_ETH_MTU); 0, &nsos_iface_offload_api, NET_ETH_MTU);
#ifdef CONFIG_NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM
struct nsos_conn_data {
struct k_work_delayable work;
struct net_if *iface;
k_timeout_t connect_delay;
};
#define NSOS_NET_IF_CTX_TYPE struct nsos_conn_data
static void nsos_delayed_connect_fn(struct k_work *work)
{
struct k_work_delayable *dwork = k_work_delayable_from_work(work);
struct nsos_conn_data *data = CONTAINER_OF(dwork, struct nsos_conn_data, work);
LOG_INF("NSOS: active");
net_if_dormant_off(data->iface);
}
static void nsos_net_if_init(struct conn_mgr_conn_binding *binding)
{
struct nsos_conn_data *data = binding->ctx;
LOG_DBG("");
/* Setup connection worker */
k_work_init_delayable(&data->work, nsos_delayed_connect_fn);
data->iface = binding->iface;
/* Set default auto connect state */
if (!IS_ENABLED(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM_AUTO_CONNECT)) {
conn_mgr_binding_set_flag(binding, CONN_MGR_IF_NO_AUTO_CONNECT, true);
}
/* Default delay */
data->connect_delay = K_SECONDS(1);
/* Mark the interface as dormant */
net_if_dormant_on(binding->iface);
}
static int nsos_net_connect(struct conn_mgr_conn_binding *const binding)
{
struct nsos_conn_data *data = binding->ctx;
LOG_INF("NSOS: connecting");
k_work_reschedule(&data->work, data->connect_delay);
return 0;
}
static int nsos_net_if_disconnect(struct conn_mgr_conn_binding *const binding)
{
struct nsos_conn_data *data = binding->ctx;
LOG_INF("NSOS: dormant");
k_work_cancel_delayable(&data->work);
net_if_dormant_on(binding->iface);
return 0;
}
int nsos_net_if_get_opt(struct conn_mgr_conn_binding *const binding, int optname,
void *optval, size_t *optlen)
{
struct nsos_conn_data *data = binding->ctx;
if (optname != 0) {
return -EINVAL;
}
if (*optlen < sizeof(k_timeout_t)) {
return -EINVAL;
}
memcpy(optval, &data->connect_delay, sizeof(data->connect_delay));
*optlen = sizeof(data->connect_delay);
return 0;
}
int nsos_net_if_set_opt(struct conn_mgr_conn_binding *const binding, int optname,
const void *optval, size_t optlen)
{
struct nsos_conn_data *data = binding->ctx;
const k_timeout_t *opt = optval;
if (optname != 0) {
return -EINVAL;
}
if (optlen != sizeof(k_timeout_t)) {
return -EINVAL;
}
data->connect_delay = *opt;
return 0;
}
static struct conn_mgr_conn_api nsos_conn_mgr_api = {
.init = nsos_net_if_init,
.connect = nsos_net_connect,
.disconnect = nsos_net_if_disconnect,
.get_opt = nsos_net_if_get_opt,
.set_opt = nsos_net_if_set_opt,
};
CONN_MGR_CONN_DEFINE(NSOS_NET_IF, &nsos_conn_mgr_api);
CONN_MGR_BIND_CONN(nsos_socket, NSOS_NET_IF);
#endif /* CONFIG_NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM */