zephyr/samples/net/sockets/echo_server/src/echo-server.c
Jukka Rissanen cf720f9882 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>
2020-03-17 17:17:20 +02:00

225 lines
4.2 KiB
C

/* echo-server.c - Networking echo server */
/*
* Copyright (c) 2016 Intel Corporation.
* Copyright (c) 2018 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <logging/log.h>
LOG_MODULE_REGISTER(net_echo_server_sample, LOG_LEVEL_DBG);
#include <zephyr.h>
#include <linker/sections.h>
#include <errno.h>
#include <shell/shell.h>
#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 = {
.proto = "IPv4",
},
.ipv6 = {
.proto = "IPv6",
},
};
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) || \
defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
int err;
#endif
k_sem_init(&quit_lock, 0, UINT_MAX);
LOG_INF(APP_BANNER);
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
#if defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC)
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate,
sizeof(ca_certificate));
if (err < 0) {
LOG_ERR("Failed to register CA certificate: %d", err);
}
#endif
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_SERVER_CERTIFICATE,
server_certificate,
sizeof(server_certificate));
if (err < 0) {
LOG_ERR("Failed to register public certificate: %d", err);
}
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_PRIVATE_KEY,
private_key, sizeof(private_key));
if (err < 0) {
LOG_ERR("Failed to register private key: %d", err);
}
#endif
#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
err = tls_credential_add(PSK_TAG,
TLS_CREDENTIAL_PSK,
psk,
sizeof(psk));
if (err < 0) {
LOG_ERR("Failed to register PSK: %d", err);
}
err = tls_credential_add(PSK_TAG,
TLS_CREDENTIAL_PSK_ID,
psk_id,
sizeof(psk_id) - 1);
if (err < 0) {
LOG_ERR("Failed to register PSK ID: %d", err);
}
#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;
}
SHELL_STATIC_SUBCMD_SET_CREATE(sample_commands,
SHELL_CMD(quit, NULL,
"Quit the sample application\n",
cmd_sample_quit),
SHELL_SUBCMD_SET_END
);
SHELL_CMD_REGISTER(sample, &sample_commands,
"Sample application commands", NULL);
void main(void)
{
init_app();
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);
}
/* Wait for the connection. */
k_sem_take(&run_app, K_FOREVER);
start_udp_and_tcp();
k_sem_take(&quit_lock, K_FOREVER);
if (connected) {
stop_udp_and_tcp();
}
}