1 /*
2 * Copyright (c) 2023 Basalte bv
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_coap_service_sample, LOG_LEVEL_DBG);
9
10 #include <zephyr/net/coap_service.h>
11
12 #include "net_sample_common.h"
13
14 #ifdef CONFIG_NET_IPV6
15 #include <zephyr/net/mld.h>
16
17 #include "net_private.h"
18 #include "ipv6.h"
19 #endif
20
21 static uint16_t coap_port = CONFIG_NET_SAMPLE_COAP_SERVER_SERVICE_PORT;
22
23 #ifndef CONFIG_NET_SAMPLE_COAPS_SERVICE
24
25 COAP_SERVICE_DEFINE(coap_server, NULL, &coap_port, COAP_SERVICE_AUTOSTART);
26
27 #else /* CONFIG_NET_SAMPLE_COAPS_SERVICE */
28
29 #include "certificate.h"
30
31 static const sec_tag_t sec_tag_list_verify_none[] = {
32 SERVER_CERTIFICATE_TAG,
33 #if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
34 PSK_TAG,
35 #endif
36 };
37
38 COAPS_SERVICE_DEFINE(coap_server, NULL, &coap_port, 0,
39 sec_tag_list_verify_none, sizeof(sec_tag_list_verify_none));
40
41 #endif /* CONFIG_NET_SAMPLE_COAPS_SERVICE */
42
setup_dtls(void)43 static int setup_dtls(void)
44 {
45 #if defined(CONFIG_NET_SAMPLE_COAPS_SERVICE)
46 #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS)
47 int err;
48
49 #if defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC)
50 err = tls_credential_add(SERVER_CERTIFICATE_TAG,
51 TLS_CREDENTIAL_CA_CERTIFICATE,
52 ca_certificate,
53 sizeof(ca_certificate));
54 if (err < 0) {
55 LOG_ERR("Failed to register CA certificate: %d", err);
56 return err;
57 }
58 #endif /* defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) */
59
60 err = tls_credential_add(SERVER_CERTIFICATE_TAG,
61 TLS_CREDENTIAL_SERVER_CERTIFICATE,
62 server_certificate,
63 sizeof(server_certificate));
64 if (err < 0) {
65 LOG_ERR("Failed to register public certificate: %d", err);
66 return err;
67 }
68
69 err = tls_credential_add(SERVER_CERTIFICATE_TAG,
70 TLS_CREDENTIAL_PRIVATE_KEY,
71 private_key, sizeof(private_key));
72 if (err < 0) {
73 LOG_ERR("Failed to register private key: %d", err);
74 return err;
75 }
76
77 #if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
78 err = tls_credential_add(PSK_TAG,
79 TLS_CREDENTIAL_PSK,
80 psk,
81 sizeof(psk));
82 if (err < 0) {
83 LOG_ERR("Failed to register PSK: %d", err);
84 return err;
85 }
86
87 err = tls_credential_add(PSK_TAG,
88 TLS_CREDENTIAL_PSK_ID,
89 psk_id,
90 sizeof(psk_id) - 1);
91 if (err < 0) {
92 LOG_ERR("Failed to register PSK ID: %d", err);
93 return err;
94 }
95
96 #endif /* defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) */
97 #endif /* defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) */
98 #endif /* defined(CONFIG_NET_SAMPLE_COAPS_SERVICE) */
99 return 0;
100 }
101
102 #if !defined(CONFIG_NET_SAMPLE_COAPS_SERVICE) && defined(CONFIG_NET_IPV6)
103
104 #define ALL_NODES_LOCAL_COAP_MCAST \
105 { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfd } } }
106
107 #define MY_IP6ADDR \
108 { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }
109
join_coap_multicast_group(uint16_t port)110 static int join_coap_multicast_group(uint16_t port)
111 {
112 static struct in6_addr my_addr = MY_IP6ADDR;
113 struct sockaddr_in6 mcast_addr = {
114 .sin6_family = AF_INET6,
115 .sin6_addr = ALL_NODES_LOCAL_COAP_MCAST,
116 .sin6_port = htons(port) };
117 struct net_if_addr *ifaddr;
118 struct net_if *iface;
119 int ret;
120
121 iface = net_if_get_default();
122 if (!iface) {
123 LOG_ERR("Could not get the default interface");
124 return -ENOENT;
125 }
126
127 #if defined(CONFIG_NET_CONFIG_SETTINGS)
128 if (net_addr_pton(AF_INET6,
129 CONFIG_NET_CONFIG_MY_IPV6_ADDR,
130 &my_addr) < 0) {
131 LOG_ERR("Invalid IPv6 address %s",
132 CONFIG_NET_CONFIG_MY_IPV6_ADDR);
133 }
134 #endif
135
136 ifaddr = net_if_ipv6_addr_add(iface, &my_addr, NET_ADDR_MANUAL, 0);
137 if (!ifaddr) {
138 LOG_ERR("Could not add unicast address to interface");
139 return -EINVAL;
140 }
141
142 ifaddr->addr_state = NET_ADDR_PREFERRED;
143
144 ret = net_ipv6_mld_join(iface, &mcast_addr.sin6_addr);
145 if (ret < 0) {
146 LOG_ERR("Cannot join %s IPv6 multicast group (%d)",
147 net_sprint_ipv6_addr(&mcast_addr.sin6_addr), ret);
148 return ret;
149 }
150
151 return 0;
152 }
153
154 #endif /* CONFIG_NET_IPV6 */
155
main(void)156 int main(void)
157 {
158 int ret;
159
160 wait_for_network();
161
162 ret = setup_dtls();
163 if (ret < 0) {
164 LOG_ERR("Failed to setup DTLS (%d)", ret);
165 return ret;
166 }
167
168 #if !defined(CONFIG_NET_SAMPLE_COAPS_SERVICE) && defined(CONFIG_NET_IPV6)
169 ret = join_coap_multicast_group(coap_port);
170 if (ret < 0) {
171 LOG_ERR("Failed to join CoAP all-nodes multicast (%d)", ret);
172 return ret;
173 }
174 #endif
175
176 #ifdef CONFIG_NET_SAMPLE_COAPS_SERVICE
177 /* CoAP secure server has to be started manually after DTLS setup */
178 ret = coap_service_start(&coap_server);
179 if (ret < 0) {
180 LOG_ERR("Failed to start CoAP secure server (%d)", ret);
181 return ret;
182 }
183 #endif
184
185 return ret;
186 }
187