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