From cf720f98825c60fcc078bc4c3f722a17a89ab8ba Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Sat, 14 Mar 2020 11:54:14 +0200 Subject: [PATCH] samples: net: echo-server: Wait network interface before starting No use starting the application if the network interface is down. So start to listen connection management events and start the TCP and UDP handlers only after network is up and ready. Signed-off-by: Jukka Rissanen --- samples/net/sockets/echo_server/prj.conf | 1 + .../net/sockets/echo_server/src/echo-server.c | 109 +++++++++++++++--- 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/samples/net/sockets/echo_server/prj.conf b/samples/net/sockets/echo_server/prj.conf index 81d913e90d0..d633cf8ed6b 100644 --- a/samples/net/sockets/echo_server/prj.conf +++ b/samples/net/sockets/echo_server/prj.conf @@ -7,6 +7,7 @@ CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_POSIX_NAMES=y CONFIG_POSIX_MAX_FDS=6 +CONFIG_NET_CONNECTION_MANAGER=y # Kernel options CONFIG_MAIN_STACK_SIZE=2048 diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index 0049d0f9dda..f08181cae03 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -18,12 +18,23 @@ LOG_MODULE_REGISTER(net_echo_server_sample, LOG_LEVEL_DBG); #include #include +#include +#include +#include + #include "common.h" #include "certificate.h" #define APP_BANNER "Run echo server" static struct k_sem quit_lock; +static struct net_mgmt_event_callback mgmt_cb; +static bool connected; +K_SEM_DEFINE(run_app, 0, 1); +static bool want_to_quit; + +#define EVENT_MASK (NET_EVENT_L4_CONNECTED | \ + NET_EVENT_L4_DISCONNECTED) struct configs conf = { .ipv4 = { @@ -39,6 +50,67 @@ void quit(void) k_sem_give(&quit_lock); } +static void start_udp_and_tcp(void) +{ + LOG_INF("Starting..."); + + if (IS_ENABLED(CONFIG_NET_TCP)) { + start_tcp(); + } + + if (IS_ENABLED(CONFIG_NET_UDP)) { + start_udp(); + } +} + +static void stop_udp_and_tcp(void) +{ + LOG_INF("Stopping..."); + + if (IS_ENABLED(CONFIG_NET_UDP)) { + stop_udp(); + } + + if (IS_ENABLED(CONFIG_NET_TCP)) { + stop_tcp(); + } +} + +static void event_handler(struct net_mgmt_event_callback *cb, + u32_t mgmt_event, struct net_if *iface) +{ + if ((mgmt_event & EVENT_MASK) != mgmt_event) { + return; + } + + if (want_to_quit) { + k_sem_give(&run_app); + want_to_quit = false; + } + + if (mgmt_event == NET_EVENT_L4_CONNECTED) { + LOG_INF("Network connected"); + + connected = true; + k_sem_give(&run_app); + + return; + } + + if (mgmt_event == NET_EVENT_L4_DISCONNECTED) { + if (connected == false) { + LOG_INF("Waiting network to be connected"); + } else { + LOG_INF("Network disconnected"); + connected = false; + } + + k_sem_reset(&run_app); + + return; + } +} + static void init_app(void) { #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) || \ @@ -94,12 +166,24 @@ static void init_app(void) } #endif + if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { + net_mgmt_init_event_callback(&mgmt_cb, + event_handler, EVENT_MASK); + net_mgmt_add_event_callback(&mgmt_cb); + + net_conn_mgr_resend_status(); + } + init_vlan(); } static int cmd_sample_quit(const struct shell *shell, size_t argc, char *argv[]) { + want_to_quit = true; + + net_conn_mgr_resend_status(); + quit(); return 0; @@ -119,23 +203,22 @@ void main(void) { init_app(); - if (IS_ENABLED(CONFIG_NET_TCP)) { - start_tcp(); + if (!IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { + /* If the config library has not been configured to start the + * app only after we have a connection, then we can start + * it right away. + */ + k_sem_give(&run_app); } - if (IS_ENABLED(CONFIG_NET_UDP)) { - start_udp(); - } + /* Wait for the connection. */ + k_sem_take(&run_app, K_FOREVER); + + start_udp_and_tcp(); k_sem_take(&quit_lock, K_FOREVER); - LOG_INF("Stopping..."); - - if (IS_ENABLED(CONFIG_NET_TCP)) { - stop_tcp(); - } - - if (IS_ENABLED(CONFIG_NET_UDP)) { - stop_udp(); + if (connected) { + stop_udp_and_tcp(); } }