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 <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2020-03-14 11:54:14 +02:00
commit cf720f9882
2 changed files with 97 additions and 13 deletions

View file

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

View file

@ -18,12 +18,23 @@ LOG_MODULE_REGISTER(net_echo_server_sample, LOG_LEVEL_DBG);
#include <net/net_core.h>
#include <net/tls_credentials.h>
#include <net/net_mgmt.h>
#include <net/net_event.h>
#include <net/net_conn_mgr.h>
#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();
}
}