1 /*
2 * Copyright (c) 2023 Basalte bv
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8
9 #include <zephyr/ztest.h>
10 #include <zephyr/net/coap_service.h>
11
coap_method1(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)12 static int coap_method1(struct coap_resource *resource, struct coap_packet *request,
13 struct sockaddr *addr, socklen_t addr_len)
14 {
15 ARG_UNUSED(resource);
16 ARG_UNUSED(request);
17 ARG_UNUSED(addr);
18 ARG_UNUSED(addr_len);
19
20 return -ENOSYS;
21 }
22
coap_method2(struct coap_resource * resource,struct coap_packet * request,struct sockaddr * addr,socklen_t addr_len)23 static int coap_method2(struct coap_resource *resource, struct coap_packet *request,
24 struct sockaddr *addr, socklen_t addr_len)
25 {
26 ARG_UNUSED(resource);
27 ARG_UNUSED(request);
28 ARG_UNUSED(addr);
29 ARG_UNUSED(addr_len);
30
31 return -ENOSYS;
32 }
33
34 static const uint16_t service_A_port = 4242;
35 COAP_SERVICE_DEFINE(service_A, "a.service.com", &service_A_port, COAP_SERVICE_AUTOSTART);
36
37 static const char * const resource_0_path[] = { "res0", NULL };
38 COAP_RESOURCE_DEFINE(resource_0, service_A, {
39 .path = resource_0_path,
40 .get = coap_method1,
41 .put = coap_method2,
42 });
43
44 static const char * const resource_1_path[] = { "res1", NULL };
45 COAP_RESOURCE_DEFINE(resource_1, service_A, {
46 .path = resource_1_path,
47 .post = coap_method1,
48 });
49
50 static uint16_t service_B_port;
51 COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, 0);
52
53 static const char * const resource_2_path[] = { "res2", "sub", NULL };
54 COAP_RESOURCE_DEFINE(resource_2, service_B, {
55 .path = resource_2_path,
56 .get = coap_method2,
57 .put = coap_method1,
58 });
59
60 static const char * const resource_3_path[] = { "res3", "+", NULL };
61 COAP_RESOURCE_DEFINE(resource_3, service_B, {
62 .path = resource_3_path,
63 .post = coap_method2,
64 });
65
66 static const uint16_t service_C_port = 5959;
67 #ifdef CONFIG_NET_SOCKETS_ENABLE_DTLS
68 static const sec_tag_t sec_tag_list[] = { 1 };
69
70 COAPS_SERVICE_DEFINE(service_C, "192.168.1.1", &service_C_port, 0, sec_tag_list,
71 sizeof(sec_tag_list));
72
73 #else
74
75 COAP_SERVICE_DEFINE(service_C, "192.168.1.1", &service_C_port, 0);
76 #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */
77
78 static const char * const resource_4_path[] = { "res4", "*", NULL };
79 COAP_RESOURCE_DEFINE(resource_4, service_C, {
80 .path = resource_4_path,
81 .get = coap_method1,
82 });
83
ZTEST(coap_service,test_COAP_SERVICE_DEFINE)84 ZTEST(coap_service, test_COAP_SERVICE_DEFINE)
85 {
86 zassert_ok(strcmp(service_A.host, "a.service.com"));
87 zassert_equal(service_A.port, &service_A_port);
88 zassert_equal(*service_A.port, 4242);
89 zassert_equal(service_A.sec_tag_list, NULL);
90 zassert_equal(service_A.sec_tag_list_size, 0);
91
92 zassert_ok(strcmp(service_B.host, "b.service.com"));
93 zassert_equal(service_B.port, &service_B_port);
94 zassert_equal(*service_B.port, 0);
95 zassert_equal(service_B.sec_tag_list, NULL);
96 zassert_equal(service_B.sec_tag_list_size, 0);
97
98 zassert_ok(strcmp(service_C.host, "192.168.1.1"));
99 zassert_equal(service_C.port, &service_C_port);
100 zassert_equal(*service_C.port, 5959);
101
102 #ifdef CONFIG_NET_SOCKETS_ENABLE_DTLS
103 zassert_equal(service_C.sec_tag_list, sec_tag_list);
104 zassert_equal(service_C.sec_tag_list_size, sizeof(sec_tag_list));
105 #else
106 zassert_equal(service_C.sec_tag_list, NULL);
107 zassert_equal(service_C.sec_tag_list_size, 0);
108 #endif
109 }
110
ZTEST(coap_service,test_COAP_SERVICE_COUNT)111 ZTEST(coap_service, test_COAP_SERVICE_COUNT)
112 {
113 size_t n_svc;
114
115 n_svc = 4273;
116 COAP_SERVICE_COUNT(&n_svc);
117 zassert_equal(n_svc, 3);
118 }
119
ZTEST(coap_service,test_COAP_SERVICE_RESOURCE_COUNT)120 ZTEST(coap_service, test_COAP_SERVICE_RESOURCE_COUNT)
121 {
122 zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_A), 2);
123 zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_B), 2);
124 zassert_equal(COAP_SERVICE_RESOURCE_COUNT(&service_C), 1);
125 }
126
ZTEST(coap_service,test_COAP_SERVICE_HAS_RESOURCE)127 ZTEST(coap_service, test_COAP_SERVICE_HAS_RESOURCE)
128 {
129 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_0));
130 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_1));
131 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_2));
132 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_A, &resource_3));
133
134 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_0));
135 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_1));
136 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_2));
137 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_B, &resource_3));
138
139 zassert_false(COAP_SERVICE_HAS_RESOURCE(&service_C, &resource_0));
140 zassert_true(COAP_SERVICE_HAS_RESOURCE(&service_C, &resource_4));
141 }
142
ZTEST(coap_service,test_COAP_SERVICE_FOREACH)143 ZTEST(coap_service, test_COAP_SERVICE_FOREACH)
144 {
145 size_t n_svc = 0;
146 size_t have_service_A = 0;
147 size_t have_service_B = 0;
148 size_t have_service_C = 0;
149
150 COAP_SERVICE_FOREACH(svc) {
151 if (svc == &service_A) {
152 have_service_A = 1;
153 zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, COAP_SERVICE_AUTOSTART);
154 } else if (svc == &service_B) {
155 have_service_B = 1;
156 zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0);
157 } else if (svc == &service_C) {
158 have_service_C = 1;
159 zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0);
160 } else {
161 zassert_unreachable("svc (%p) not equal to &service_A (%p), &service_B "
162 "(%p), or &service_C (%p)",
163 svc, &service_A, &service_B, &service_C);
164 }
165
166 n_svc++;
167 }
168
169 zassert_equal(n_svc, 3);
170 zassert_equal(have_service_A + have_service_B + have_service_C, n_svc);
171 }
172
ZTEST(coap_service,test_COAP_RESOURCE_FOREACH)173 ZTEST(coap_service, test_COAP_RESOURCE_FOREACH)
174 {
175 size_t first_res, second_res, n_res;
176
177 n_res = 0;
178 first_res = 0;
179 second_res = 0;
180 COAP_RESOURCE_FOREACH(service_A, res) {
181 if (res == &resource_0) {
182 first_res = 1;
183 } else if (res == &resource_1) {
184 second_res = 1;
185 } else {
186 zassert_unreachable(
187 "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res,
188 &resource_0, &resource_1);
189 }
190
191 n_res++;
192 }
193
194 zassert_equal(n_res, 2);
195 zassert_equal(first_res + second_res, n_res);
196
197 n_res = 0;
198 first_res = 0;
199 second_res = 0;
200 COAP_RESOURCE_FOREACH(service_B, res) {
201 if (res == &resource_2) {
202 first_res = 1;
203 } else if (res == &resource_3) {
204 second_res = 1;
205 } else {
206 zassert_unreachable(
207 "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res,
208 &resource_2, &resource_3);
209 }
210
211 n_res++;
212 }
213
214 zassert_equal(n_res, 2);
215 zassert_equal(first_res + second_res, n_res);
216
217 n_res = 0;
218 first_res = 0;
219 second_res = 0;
220 COAP_RESOURCE_FOREACH(service_C, res) {
221 if (res == &resource_4) {
222 first_res = 1;
223 } else {
224 zassert_unreachable(
225 "res (%p) not equal to &resource_4 (%p)", res, &resource_4);
226 }
227 n_res++;
228 }
229
230 zassert_equal(n_res, 1);
231 zassert_equal(first_res + second_res, n_res);
232 }
233
ZTEST(coap_service,test_COAP_SERVICE_FOREACH_RESOURCE)234 ZTEST(coap_service, test_COAP_SERVICE_FOREACH_RESOURCE)
235 {
236 size_t first_res, second_res, n_res;
237
238 n_res = 0;
239 first_res = 0;
240 second_res = 0;
241 COAP_SERVICE_FOREACH_RESOURCE(&service_A, res) {
242 if (res == &resource_0) {
243 first_res = 1;
244 } else if (res == &resource_1) {
245 second_res = 1;
246 } else {
247 zassert_unreachable(
248 "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res,
249 &resource_0, &resource_1);
250 }
251
252 n_res++;
253 }
254
255 zassert_equal(n_res, 2);
256 zassert_equal(first_res + second_res, n_res);
257
258 n_res = 0;
259 first_res = 0;
260 second_res = 0;
261 COAP_SERVICE_FOREACH_RESOURCE(&service_B, res) {
262 if (res == &resource_2) {
263 first_res = 1;
264 } else if (res == &resource_3) {
265 second_res = 1;
266 } else {
267 zassert_unreachable(
268 "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res,
269 &resource_2, &resource_3);
270 }
271
272 n_res++;
273 }
274
275 zassert_equal(n_res, 2);
276 zassert_equal(first_res + second_res, n_res);
277
278 n_res = 0;
279 first_res = 0;
280 second_res = 0;
281 COAP_SERVICE_FOREACH_RESOURCE(&service_C, res) {
282 if (res == &resource_4) {
283 first_res = 1;
284 } else {
285 zassert_unreachable(
286 "res (%p) not equal to &resource_4 (%p)", res, &resource_4);
287 }
288 n_res++;
289 }
290
291 zassert_equal(n_res, 1);
292 zassert_equal(first_res + second_res, n_res);
293 }
294
ZTEST(coap_service,test_COAP_RESOURCE_DEFINE)295 ZTEST(coap_service, test_COAP_RESOURCE_DEFINE)
296 {
297 COAP_SERVICE_FOREACH_RESOURCE(&service_A, res) {
298 if (res == &resource_0) {
299 zassert_ok(strcmp(res->path[0], "res0"));
300 zassert_equal(res->get, coap_method1);
301 zassert_equal(res->put, coap_method2);
302 } else if (res == &resource_1) {
303 zassert_ok(strcmp(res->path[0], "res1"));
304 zassert_equal(res->post, coap_method1);
305 } else {
306 zassert_unreachable(
307 "res (%p) not equal to &resource_0 (%p) or &resource_1 (%p)", res,
308 &resource_0, &resource_1);
309 }
310 }
311
312 COAP_SERVICE_FOREACH_RESOURCE(&service_B, res) {
313 if (res == &resource_2) {
314 zassert_ok(strcmp(res->path[0], "res2"));
315 zassert_ok(strcmp(res->path[1], "sub"));
316 zassert_equal(res->get, coap_method2);
317 zassert_equal(res->put, coap_method1);
318 } else if (res == &resource_3) {
319 zassert_ok(strcmp(res->path[0], "res3"));
320 zassert_ok(strcmp(res->path[1], "+"));
321 zassert_equal(res->post, coap_method2);
322 } else {
323 zassert_unreachable(
324 "res (%p) not equal to &resource_2 (%p) or &resource_3 (%p)", res,
325 &resource_2, &resource_3);
326 }
327 }
328
329 COAP_SERVICE_FOREACH_RESOURCE(&service_C, res) {
330 if (res == &resource_4) {
331 zassert_ok(strcmp(res->path[0], "res4"));
332 zassert_ok(strcmp(res->path[1], "*"));
333 zassert_equal(res->get, coap_method1);
334 zassert_equal(res->put, NULL);
335 } else {
336 zassert_unreachable(
337 "res (%p) not equal to &resource_4 (%p)", res, &resource_4);
338 }
339 }
340 }
341
342 ZTEST_SUITE(coap_service, NULL, NULL, NULL, NULL, NULL);
343