TLS_CREDENTIAL_SERVER_CERTIFICATE credential type is misleading, as in fact it just represents a public certificate, it does not matter if the certificate belongs to a server or a client. And actually, it was already used in-tree for clients as well, for example in LwM2M. Therefore rename the credential type to a more generic TLS_CREDENTIAL_PUBLIC_CERTIFICATE and deprecate the old one. Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
249 lines
4.8 KiB
C
249 lines
4.8 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 <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(net_echo_server_sample, LOG_LEVEL_DBG);
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/linker/sections.h>
|
|
#include <errno.h>
|
|
#include <zephyr/shell/shell.h>
|
|
|
|
#include <zephyr/net/net_core.h>
|
|
#include <zephyr/net/tls_credentials.h>
|
|
|
|
#include <zephyr/net/net_mgmt.h>
|
|
#include <zephyr/net/net_event.h>
|
|
#include <zephyr/net/conn_mgr_monitor.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;
|
|
|
|
#if defined(CONFIG_USERSPACE)
|
|
K_APPMEM_PARTITION_DEFINE(app_partition);
|
|
struct k_mem_domain app_domain;
|
|
#endif
|
|
|
|
#define EVENT_MASK (NET_EVENT_L4_CONNECTED | \
|
|
NET_EVENT_L4_DISCONNECTED)
|
|
|
|
APP_DMEM 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,
|
|
uint32_t mgmt_event, struct net_if *iface)
|
|
{
|
|
ARG_UNUSED(iface);
|
|
ARG_UNUSED(cb);
|
|
|
|
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_USERSPACE)
|
|
struct k_mem_partition *parts[] = {
|
|
#if Z_LIBC_PARTITION_EXISTS
|
|
&z_libc_partition,
|
|
#endif
|
|
&app_partition
|
|
};
|
|
|
|
int ret = k_mem_domain_init(&app_domain, ARRAY_SIZE(parts), parts);
|
|
|
|
__ASSERT(ret == 0, "k_mem_domain_init() failed %d", ret);
|
|
ARG_UNUSED(ret);
|
|
#endif
|
|
|
|
k_sem_init(&quit_lock, 0, K_SEM_MAX_LIMIT);
|
|
|
|
LOG_INF(APP_BANNER);
|
|
|
|
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
|
|
int err;
|
|
|
|
#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 /* defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) */
|
|
|
|
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
|
|
TLS_CREDENTIAL_PUBLIC_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);
|
|
}
|
|
|
|
#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 /* defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) */
|
|
#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */
|
|
|
|
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);
|
|
|
|
conn_mgr_mon_resend_status();
|
|
}
|
|
|
|
init_vlan();
|
|
init_tunnel();
|
|
init_ws();
|
|
init_usb();
|
|
}
|
|
|
|
static int cmd_sample_quit(const struct shell *sh,
|
|
size_t argc, char *argv[])
|
|
{
|
|
want_to_quit = true;
|
|
|
|
conn_mgr_mon_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);
|
|
|
|
int 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();
|
|
}
|
|
return 0;
|
|
}
|