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(); } }