1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_test, LOG_LEVEL_DBG);
9
10 #include <errno.h>
11 #include <zephyr/types.h>
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <zephyr/sys/printk.h>
17 #include <zephyr/kernel.h>
18 #include <zephyr/sys/util.h>
19 #include <zephyr/net/coap.h>
20
21 #include <zephyr/tc_util.h>
22 #include <zephyr/ztest.h>
23
24 #include "net_private.h"
25
26 #define COAP_BUF_SIZE 128
27
28 #define NUM_PENDINGS 3
29 #define NUM_OBSERVERS 3
30 #define NUM_REPLIES 3
31
32 static struct coap_pending pendings[NUM_PENDINGS];
33 static struct coap_observer observers[NUM_OBSERVERS];
34 static struct coap_reply replies[NUM_REPLIES];
35
36 /* This is exposed for this test in subsys/net/lib/coap/coap_link_format.c */
37 bool _coap_match_path_uri(const char * const *path,
38 const char *uri, uint16_t len);
39
40 /* Some forward declarations */
41 static void server_resource_1_callback(struct coap_resource *resource,
42 struct coap_observer *observer);
43
44 static void server_resource_2_callback(struct coap_resource *resource,
45 struct coap_observer *observer);
46
47 static int server_resource_1_get(struct coap_resource *resource,
48 struct coap_packet *request,
49 struct net_sockaddr *addr, net_socklen_t addr_len);
50
51 static const char * const server_resource_1_path[] = { "s", "1", NULL };
52 static const char *const server_resource_2_path[] = { "s", "2", NULL };
53 static struct coap_resource server_resources[] = {
54 { .path = server_resource_1_path,
55 .get = server_resource_1_get,
56 .notify = server_resource_1_callback },
57 { .path = server_resource_2_path,
58 .get = server_resource_1_get, /* Get can be shared with the first resource */
59 .notify = server_resource_2_callback },
60 { },
61 };
62
63 #define MY_PORT 12345
64 #define peer_addr { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, \
65 0, 0, 0, 0, 0, 0, 0, 0x2 } } }
66 static struct net_sockaddr_in6 dummy_addr = {
67 .sin6_family = NET_AF_INET6,
68 .sin6_addr = peer_addr };
69
70 static uint8_t data_buf[2][COAP_BUF_SIZE];
71
72 #define COAP_ROLLOVER_AGE (1 << 23)
73 #define COAP_MAX_AGE 0xffffff
74 #define COAP_FIRST_AGE 2
75
76 extern bool coap_age_is_newer(int v1, int v2);
77
ZTEST(coap,test_build_empty_pdu)78 ZTEST(coap, test_build_empty_pdu)
79 {
80 uint8_t result_pdu[] = { 0x40, 0x01, 0x0, 0x0 };
81 struct coap_packet cpkt;
82 uint8_t *data = data_buf[0];
83 int r;
84
85 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE,
86 COAP_VERSION_1, COAP_TYPE_CON, 0, NULL,
87 COAP_METHOD_GET, 0);
88
89 zassert_equal(r, 0, "Could not initialize packet");
90 zassert_equal(cpkt.offset, sizeof(result_pdu),
91 "Different size from the reference packet");
92 zassert_equal(cpkt.hdr_len, COAP_FIXED_HEADER_SIZE,
93 "Invalid header length");
94 zassert_equal(cpkt.opt_len, 0, "Invalid options length");
95 zassert_mem_equal(result_pdu, cpkt.data, cpkt.offset,
96 "Built packet doesn't match reference packet");
97 }
98
ZTEST(coap,test_build_simple_pdu)99 ZTEST(coap, test_build_simple_pdu)
100 {
101 uint8_t result_pdu[] = { 0x55, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e',
102 'n', 0xC0, 0xFF, 'p', 'a', 'y', 'l',
103 'o', 'a', 'd', 0x00 };
104 struct coap_packet cpkt;
105 const char token[] = "token";
106 static const char payload[] = "payload";
107 uint8_t *data = data_buf[0];
108 const uint8_t *payload_start;
109 uint16_t payload_len;
110 int r;
111
112 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE,
113 COAP_VERSION_1, COAP_TYPE_NON_CON,
114 strlen(token), token,
115 COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED,
116 0x1234);
117 zassert_equal(r, 0, "Could not initialize packet");
118
119 r = coap_append_option_int(&cpkt, COAP_OPTION_CONTENT_FORMAT,
120 COAP_CONTENT_FORMAT_TEXT_PLAIN);
121 zassert_equal(r, 0, "Could not append option");
122
123 r = coap_packet_append_payload_marker(&cpkt);
124 zassert_equal(r, 0, "Failed to set the payload marker");
125
126 r = coap_packet_append_payload(&cpkt, payload, sizeof(payload));
127 zassert_equal(r, 0, "Failed to set the payload");
128
129 zassert_equal(cpkt.offset, sizeof(result_pdu),
130 "Different size from the reference packet");
131 zassert_equal(cpkt.hdr_len, COAP_FIXED_HEADER_SIZE + strlen(token),
132 "Invalid header length");
133 zassert_equal(cpkt.opt_len, 1, "Invalid options length");
134 zassert_mem_equal(result_pdu, cpkt.data, cpkt.offset,
135 "Built packet doesn't match reference packet");
136
137 payload_start = coap_packet_get_payload(&cpkt, &payload_len);
138
139 zassert_equal(payload_len, sizeof(payload), "Invalid payload length");
140 zassert_equal_ptr(payload_start, cpkt.data + cpkt.offset - payload_len,
141 "Invalid payload pointer");
142 }
143
144 /* No options, No payload */
ZTEST(coap,test_parse_empty_pdu)145 ZTEST(coap, test_parse_empty_pdu)
146 {
147 uint8_t pdu[] = { 0x40, 0x01, 0, 0 };
148 struct coap_packet cpkt;
149 uint8_t *data = data_buf[0];
150 uint8_t ver;
151 uint8_t type;
152 uint8_t code;
153 uint16_t id;
154 int r;
155
156 memcpy(data, pdu, sizeof(pdu));
157
158 r = coap_packet_parse(&cpkt, data, sizeof(pdu), NULL, 0);
159 zassert_equal(r, 0, "Could not parse packet");
160
161 zassert_equal(cpkt.offset, sizeof(pdu),
162 "Different size from the reference packet");
163 zassert_equal(cpkt.hdr_len, COAP_FIXED_HEADER_SIZE,
164 "Invalid header length");
165 zassert_equal(cpkt.opt_len, 0, "Invalid options length");
166
167 ver = coap_header_get_version(&cpkt);
168 type = coap_header_get_type(&cpkt);
169 code = coap_header_get_code(&cpkt);
170 id = coap_header_get_id(&cpkt);
171
172 zassert_equal(ver, 1U, "Invalid version for parsed packet");
173 zassert_equal(type, COAP_TYPE_CON,
174 "Packet type doesn't match reference");
175 zassert_equal(code, COAP_METHOD_GET,
176 "Packet code doesn't match reference");
177 zassert_equal(id, 0U, "Packet id doesn't match reference");
178 }
179
180 /* 1 option, No payload (No payload marker) */
ZTEST(coap,test_parse_empty_pdu_1)181 ZTEST(coap, test_parse_empty_pdu_1)
182 {
183 uint8_t pdu[] = { 0x40, 0x01, 0, 0, 0x40};
184 struct coap_packet cpkt;
185 uint8_t *data = data_buf[0];
186 uint8_t ver;
187 uint8_t type;
188 uint8_t code;
189 uint16_t id;
190 int r;
191
192 memcpy(data, pdu, sizeof(pdu));
193
194 r = coap_packet_parse(&cpkt, data, sizeof(pdu), NULL, 0);
195 zassert_equal(r, 0, "Could not parse packet");
196
197 zassert_equal(cpkt.offset, sizeof(pdu),
198 "Different size from the reference packet");
199 zassert_equal(cpkt.hdr_len, COAP_FIXED_HEADER_SIZE,
200 "Invalid header length");
201 zassert_equal(cpkt.opt_len, 1, "Invalid options length");
202
203 ver = coap_header_get_version(&cpkt);
204 type = coap_header_get_type(&cpkt);
205 code = coap_header_get_code(&cpkt);
206 id = coap_header_get_id(&cpkt);
207
208 zassert_equal(ver, 1U, "Invalid version for parsed packet");
209 zassert_equal(type, COAP_TYPE_CON,
210 "Packet type doesn't match reference");
211 zassert_equal(code, COAP_METHOD_GET,
212 "Packet code doesn't match reference");
213 zassert_equal(id, 0U, "Packet id doesn't match reference");
214 }
215
ZTEST(coap,test_parse_simple_pdu)216 ZTEST(coap, test_parse_simple_pdu)
217 {
218 uint8_t pdu[] = { 0x55, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
219 0x00, 0xc1, 0x00, 0xff, 'p', 'a', 'y', 'l', 'o',
220 'a', 'd', 0x00 };
221 struct coap_packet cpkt;
222 struct coap_option options[16] = {};
223 const uint8_t token[8];
224 const uint8_t payload[] = "payload";
225 uint8_t *data = data_buf[0];
226 uint8_t ver;
227 uint8_t type;
228 uint8_t code;
229 uint8_t tkl;
230 uint16_t id;
231 const uint8_t *payload_start;
232 uint16_t payload_len;
233 int r, count = ARRAY_SIZE(options) - 1;
234
235 memcpy(data, pdu, sizeof(pdu));
236
237 r = coap_packet_parse(&cpkt, data, sizeof(pdu), NULL, 0);
238 zassert_equal(r, 0, "Could not parse packet");
239
240 zassert_equal(cpkt.offset, sizeof(pdu),
241 "Different size from the reference packet");
242 zassert_equal(cpkt.hdr_len, COAP_FIXED_HEADER_SIZE + strlen("token"),
243 "Invalid header length");
244 zassert_equal(cpkt.opt_len, 3, "Invalid options length");
245
246 payload_start = coap_packet_get_payload(&cpkt, &payload_len);
247
248 zassert_equal(payload_len, sizeof(payload), "Invalid payload length");
249 zassert_equal_ptr(payload_start, cpkt.data + cpkt.offset - payload_len,
250 "Invalid payload pointer");
251
252 ver = coap_header_get_version(&cpkt);
253 type = coap_header_get_type(&cpkt);
254 code = coap_header_get_code(&cpkt);
255 id = coap_header_get_id(&cpkt);
256
257 zassert_equal(ver, 1U, "Invalid version for parsed packet");
258 zassert_equal(type, COAP_TYPE_NON_CON,
259 "Packet type doesn't match reference");
260 zassert_equal(code, COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED,
261 "Packet code doesn't match reference");
262 zassert_equal(id, 0x1234, "Packet id doesn't match reference");
263
264 tkl = coap_header_get_token(&cpkt, (uint8_t *)token);
265
266 zassert_equal(tkl, 5U, "Token length doesn't match reference");
267 zassert_mem_equal(token, "token", tkl,
268 "Token value doesn't match the reference");
269
270 count = coap_find_options(&cpkt, COAP_OPTION_CONTENT_FORMAT,
271 options, count);
272
273 zassert_equal(count, 1, "Unexpected number of options in the packet");
274 zassert_equal(options[0].len, 1U,
275 "Option length doesn't match the reference");
276 zassert_equal(((uint8_t *)options[0].value)[0],
277 COAP_CONTENT_FORMAT_TEXT_PLAIN,
278 "Option value doesn't match the reference");
279
280 /* Not existent */
281 count = coap_find_options(&cpkt, COAP_OPTION_ETAG, options, count);
282
283 zassert_equal(count, 0,
284 "There shouldn't be any ETAG option in the packet");
285 }
286
ZTEST(coap,test_parse_malformed_pkt)287 ZTEST(coap, test_parse_malformed_pkt)
288 {
289 uint8_t opt[] = { 0x55, 0xA5, 0x12 };
290
291 struct coap_packet cpkt;
292 uint8_t *data = data_buf[0];
293 int r;
294
295 r = coap_packet_parse(&cpkt, NULL, sizeof(opt), NULL, 0);
296 zassert_equal(r, -EINVAL, "Should've failed to parse a packet");
297
298 r = coap_packet_parse(&cpkt, data, 0, NULL, 0);
299 zassert_equal(r, -EINVAL, "Should've failed to parse a packet");
300
301 memcpy(data, opt, sizeof(opt));
302 r = coap_packet_parse(&cpkt, data, sizeof(opt), NULL, 0);
303 zassert_equal(r, -EINVAL, "Should've failed to parse a packet");
304 }
305
ZTEST(coap,test_parse_malformed_coap_hdr)306 ZTEST(coap, test_parse_malformed_coap_hdr)
307 {
308 uint8_t opt[] = { 0x55, 0x24, 0x49, 0x55, 0xff, 0x66, 0x77, 0x99};
309
310 struct coap_packet cpkt;
311 uint8_t *data = data_buf[0];
312 int r;
313
314 memcpy(data, opt, sizeof(opt));
315 r = coap_packet_parse(&cpkt, data, sizeof(opt), NULL, 0);
316 zassert_equal(r, -EBADMSG, "Should've failed to parse a packet");
317 }
318
ZTEST(coap,test_parse_malformed_opt)319 ZTEST(coap, test_parse_malformed_opt)
320 {
321 uint8_t opt[] = { 0x55, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
322 0xD0 };
323 struct coap_packet cpkt;
324 uint8_t *data = data_buf[0];
325 int r;
326
327 memcpy(data, opt, sizeof(opt));
328
329 r = coap_packet_parse(&cpkt, data, sizeof(opt), NULL, 0);
330 zassert_equal(r, -EILSEQ, "Should've failed to parse a packet");
331 }
332
ZTEST(coap,test_parse_malformed_opt_len)333 ZTEST(coap, test_parse_malformed_opt_len)
334 {
335 uint8_t opt[] = { 0x55, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
336 0xC1 };
337 struct coap_packet cpkt;
338 uint8_t *data = data_buf[0];
339 int r;
340
341 memcpy(data, opt, sizeof(opt));
342
343 r = coap_packet_parse(&cpkt, data, sizeof(opt), NULL, 0);
344 zassert_equal(r, -EILSEQ, "Should've failed to parse a packet");
345 }
346
ZTEST(coap,test_parse_malformed_opt_ext)347 ZTEST(coap, test_parse_malformed_opt_ext)
348 {
349 uint8_t opt[] = { 0x55, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
350 0xE0, 0x01 };
351 struct coap_packet cpkt;
352 uint8_t *data = data_buf[0];
353 int r;
354
355 memcpy(data, opt, sizeof(opt));
356
357 r = coap_packet_parse(&cpkt, data, sizeof(opt), NULL, 0);
358 zassert_equal(r, -EILSEQ, "Should've failed to parse a packet");
359 }
360
ZTEST(coap,test_parse_malformed_opt_len_ext)361 ZTEST(coap, test_parse_malformed_opt_len_ext)
362 {
363 uint8_t opt[] = { 0x55, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
364 0xEE, 0x01, 0x02, 0x01};
365 struct coap_packet cpkt;
366 uint8_t *data = data_buf[0];
367 int r;
368
369 memcpy(data, opt, sizeof(opt));
370
371 r = coap_packet_parse(&cpkt, data, sizeof(opt), NULL, 0);
372 zassert_equal(r, -EILSEQ, "Should've failed to parse a packet");
373 }
374
375 /* 1 option, No payload (with payload marker) */
ZTEST(coap,test_parse_malformed_marker)376 ZTEST(coap, test_parse_malformed_marker)
377 {
378 uint8_t pdu[] = { 0x40, 0x01, 0, 0, 0x40, 0xFF};
379 struct coap_packet cpkt;
380 uint8_t *data = data_buf[0];
381 int r;
382
383 memcpy(data, pdu, sizeof(pdu));
384
385 r = coap_packet_parse(&cpkt, data, sizeof(pdu), NULL, 0);
386 zassert_not_equal(r, 0, "Should've failed to parse a packet");
387 }
388
ZTEST(coap,test_parse_req_build_ack)389 ZTEST(coap, test_parse_req_build_ack)
390 {
391 uint8_t pdu[] = { 0x45, 0xA5, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
392 0x00, 0xc1, 0x00, 0xff, 'p', 'a', 'y', 'l', 'o',
393 'a', 'd', 0x00 };
394 uint8_t ack_pdu[] = { 0x65, 0x80, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
395 struct coap_packet cpkt;
396 struct coap_packet ack_cpkt;
397 uint8_t *data = data_buf[0];
398 uint8_t *ack_data = data_buf[1];
399 int r;
400
401 memcpy(data, pdu, sizeof(pdu));
402
403 r = coap_packet_parse(&cpkt, data, sizeof(pdu), NULL, 0);
404 zassert_equal(r, 0, "Could not parse packet");
405
406 r = coap_ack_init(&ack_cpkt, &cpkt, ack_data, COAP_BUF_SIZE,
407 COAP_RESPONSE_CODE_BAD_REQUEST);
408 zassert_equal(r, 0, "Could not initialize ACK packet");
409
410 zassert_equal(ack_cpkt.offset, sizeof(ack_pdu),
411 "Different size from the reference packet");
412 zassert_mem_equal(ack_pdu, ack_cpkt.data, ack_cpkt.offset,
413 "Built packet doesn't match reference packet");
414 }
415
ZTEST(coap,test_parse_req_build_empty_ack)416 ZTEST(coap, test_parse_req_build_empty_ack)
417 {
418 uint8_t pdu[] = { 0x45, 0xA5, 0xDE, 0xAD, 't', 'o', 'k', 'e', 'n',
419 0x00, 0xc1, 0x00, 0xff, 'p', 'a', 'y', 'l', 'o',
420 'a', 'd', 0x00 };
421 uint8_t ack_pdu[] = { 0x60, 0x00, 0xDE, 0xAD };
422 struct coap_packet cpkt;
423 struct coap_packet ack_cpkt;
424 uint8_t *data = data_buf[0];
425 uint8_t *ack_data = data_buf[1];
426 int r;
427
428 memcpy(data, pdu, sizeof(pdu));
429
430 r = coap_packet_parse(&cpkt, data, sizeof(pdu), NULL, 0);
431 zassert_equal(r, 0, "Could not parse packet");
432
433 r = coap_ack_init(&ack_cpkt, &cpkt, ack_data, COAP_BUF_SIZE,
434 COAP_CODE_EMPTY);
435 zassert_equal(r, 0, "Could not initialize ACK packet");
436
437 zassert_equal(ack_cpkt.offset, sizeof(ack_pdu),
438 "Different size from the reference packet");
439 zassert_mem_equal(ack_pdu, ack_cpkt.data, ack_cpkt.offset,
440 "Built packet doesn't match reference packet");
441 }
442
ZTEST(coap,test_match_path_uri)443 ZTEST(coap, test_match_path_uri)
444 {
445 const char * const resource_path[] = {
446 "s",
447 "1",
448 "foobar",
449 "foobar3a",
450 "foobar3",
451 "devnull",
452 NULL
453 };
454 const char *uri;
455 int r;
456
457 uri = "/k";
458 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
459 zassert_false(r, "Matching %s failed", uri);
460
461 uri = "/s";
462 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
463 zassert_true(r, "Matching %s failed", uri);
464
465 uri = "/foobar";
466 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
467 zassert_true(r, "Matching %s failed", uri);
468
469 uri = "/foobar2";
470 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
471 zassert_false(r, "Matching %s failed", uri);
472
473 uri = "/foobar*";
474 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
475 zassert_true(r, "Matching %s failed", uri);
476
477 uri = "/foobar3*";
478 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
479 zassert_true(r, "Matching %s failed", uri);
480
481 uri = "/devnull*";
482 r = _coap_match_path_uri(resource_path, uri, strlen(uri));
483 zassert_false(r, "Matching %s failed", uri);
484 }
485
486 #define BLOCK_WISE_TRANSFER_SIZE_GET 150
487
prepare_block1_request(struct coap_packet * req,struct coap_block_context * req_ctx,int * more)488 static void prepare_block1_request(struct coap_packet *req,
489 struct coap_block_context *req_ctx,
490 int *more)
491 {
492 const char token[] = "token";
493 uint8_t payload[32] = { 0 };
494 uint8_t *data = data_buf[0];
495 bool first;
496 int r;
497 int block_size = coap_block_size_to_bytes(COAP_BLOCK_32);
498 int payload_len;
499
500 /* Request Context */
501 if (req_ctx->total_size == 0) {
502 first = true;
503 coap_block_transfer_init(req_ctx, COAP_BLOCK_32,
504 BLOCK_WISE_TRANSFER_SIZE_GET);
505 } else {
506 first = false;
507 }
508
509 r = coap_packet_init(req, data, COAP_BUF_SIZE, COAP_VERSION_1,
510 COAP_TYPE_CON, strlen(token),
511 token, COAP_METHOD_POST,
512 coap_next_id());
513 zassert_equal(r, 0, "Unable to initialize request");
514
515 r = coap_append_block1_option(req, req_ctx);
516 zassert_equal(r, 0, "Unable to append block1 option");
517
518 if (first) {
519 r = coap_append_size1_option(req, req_ctx);
520 zassert_equal(r, 0, "Unable to append size1 option");
521 }
522
523 r = coap_packet_append_payload_marker(req);
524 zassert_equal(r, 0, "Unable to append payload marker");
525
526 payload_len = req_ctx->total_size - req_ctx->current;
527 if (payload_len > block_size) {
528 payload_len = block_size;
529 }
530
531 r = coap_packet_append_payload(req, payload, payload_len);
532 zassert_equal(r, 0, "Unable to append payload");
533
534 *more = coap_next_block(req, req_ctx);
535 }
536
prepare_block1_response(struct coap_packet * rsp,struct coap_block_context * rsp_ctx,struct coap_packet * req)537 static void prepare_block1_response(struct coap_packet *rsp,
538 struct coap_block_context *rsp_ctx,
539 struct coap_packet *req)
540 {
541 uint8_t token[8];
542 uint8_t *data = data_buf[1];
543 uint16_t id;
544 uint8_t tkl;
545 int r;
546
547 if (rsp_ctx->total_size == 0) {
548 coap_block_transfer_init(rsp_ctx, COAP_BLOCK_32,
549 BLOCK_WISE_TRANSFER_SIZE_GET);
550 }
551
552 r = coap_update_from_block(req, rsp_ctx);
553 zassert_equal(r, 0, "Failed to read block option");
554
555 id = coap_header_get_id(req);
556 tkl = coap_header_get_token(req, token);
557
558 r = coap_packet_init(rsp, data, COAP_BUF_SIZE, COAP_VERSION_1,
559 COAP_TYPE_ACK, tkl, token,
560 COAP_RESPONSE_CODE_CREATED, id);
561 zassert_equal(r, 0, "Unable to initialize request");
562
563 r = coap_append_block1_option(rsp, rsp_ctx);
564 zassert_equal(r, 0, "Unable to append block1 option");
565 }
566
567 #define ITER_COUNT(len, block_len) DIV_ROUND_UP(len, block_len)
568
verify_block1_request(struct coap_block_context * req_ctx,uint8_t iter)569 static void verify_block1_request(struct coap_block_context *req_ctx,
570 uint8_t iter)
571 {
572 int block_size = coap_block_size_to_bytes(COAP_BLOCK_32);
573 int iter_max = ITER_COUNT(BLOCK_WISE_TRANSFER_SIZE_GET, block_size);
574
575 zassert_equal(req_ctx->block_size, COAP_BLOCK_32,
576 "req:%d,Couldn't get block size", iter);
577
578 /* In last iteration "current" must match "total_size" */
579 if (iter < iter_max) {
580 zassert_equal(
581 req_ctx->current, block_size * iter,
582 "req:%d,Couldn't get the current block position", iter);
583 } else {
584 zassert_equal(
585 req_ctx->current, req_ctx->total_size,
586 "req:%d,Couldn't get the current block position", iter);
587 }
588
589 zassert_equal(req_ctx->total_size, BLOCK_WISE_TRANSFER_SIZE_GET,
590 "req:%d,Couldn't packet total size", iter);
591 }
592
verify_block1_response(struct coap_block_context * rsp_ctx,uint8_t iter)593 static void verify_block1_response(struct coap_block_context *rsp_ctx,
594 uint8_t iter)
595 {
596 zassert_equal(rsp_ctx->block_size, COAP_BLOCK_32,
597 "rsp:%d,Couldn't get block size", iter);
598 zassert_equal(rsp_ctx->current,
599 coap_block_size_to_bytes(COAP_BLOCK_32) * (iter - 1U),
600 "rsp:%d, Couldn't get the current block position", iter);
601 zassert_equal(rsp_ctx->total_size, BLOCK_WISE_TRANSFER_SIZE_GET,
602 "rsp:%d, Couldn't packet total size", iter);
603 }
604
ZTEST(coap,test_block1_size)605 ZTEST(coap, test_block1_size)
606 {
607 struct coap_block_context req_ctx;
608 struct coap_block_context rsp_ctx;
609 struct coap_packet req;
610 struct coap_packet rsp;
611 int more;
612 uint8_t i;
613
614 i = 0U;
615 more = 1;
616 memset(&req_ctx, 0, sizeof(req_ctx));
617 memset(&rsp_ctx, 0, sizeof(rsp_ctx));
618
619 while (more) {
620 prepare_block1_request(&req, &req_ctx, &more);
621 prepare_block1_response(&rsp, &rsp_ctx, &req);
622
623 i++;
624
625 verify_block1_request(&req_ctx, i);
626 verify_block1_response(&rsp_ctx, i);
627 }
628 }
629
630 #define BLOCK2_WISE_TRANSFER_SIZE_GET 300
631
prepare_block2_request(struct coap_packet * req,struct coap_block_context * req_ctx,struct coap_packet * rsp)632 static void prepare_block2_request(struct coap_packet *req,
633 struct coap_block_context *req_ctx,
634 struct coap_packet *rsp)
635 {
636 const char token[] = "token";
637 uint8_t *data = data_buf[0];
638 int r;
639
640 /* Request Context */
641 if (req_ctx->total_size == 0) {
642 coap_block_transfer_init(req_ctx, COAP_BLOCK_64,
643 BLOCK2_WISE_TRANSFER_SIZE_GET);
644 } else {
645 coap_next_block(rsp, req_ctx);
646 }
647
648 r = coap_packet_init(req, data, COAP_BUF_SIZE, COAP_VERSION_1,
649 COAP_TYPE_CON, strlen(token),
650 token, COAP_METHOD_GET,
651 coap_next_id());
652 zassert_equal(r, 0, "Unable to initialize request");
653
654 r = coap_append_block2_option(req, req_ctx);
655 zassert_equal(r, 0, "Unable to append block2 option");
656 }
657
prepare_block2_response(struct coap_packet * rsp,struct coap_block_context * rsp_ctx,struct coap_packet * req,int * more)658 static void prepare_block2_response(struct coap_packet *rsp,
659 struct coap_block_context *rsp_ctx,
660 struct coap_packet *req,
661 int *more)
662 {
663 uint8_t payload[64];
664 uint8_t token[8];
665 uint8_t *data = data_buf[1];
666 uint16_t id;
667 uint8_t tkl;
668 bool first;
669 int r;
670 int block_size = coap_block_size_to_bytes(COAP_BLOCK_64);
671 int payload_len;
672
673 if (rsp_ctx->total_size == 0) {
674 first = true;
675 coap_block_transfer_init(rsp_ctx, COAP_BLOCK_64,
676 BLOCK2_WISE_TRANSFER_SIZE_GET);
677 } else {
678 first = false;
679 }
680
681 id = coap_header_get_id(req);
682 tkl = coap_header_get_token(req, token);
683
684 r = coap_packet_init(rsp, data, COAP_BUF_SIZE, COAP_VERSION_1,
685 COAP_TYPE_ACK, tkl, token,
686 COAP_RESPONSE_CODE_CONTENT, id);
687 zassert_equal(r, 0, "Unable to initialize request");
688
689 r = coap_append_block2_option(rsp, rsp_ctx);
690 zassert_equal(r, 0, "Unable to append block2 option");
691
692 if (first) {
693 r = coap_append_size2_option(rsp, rsp_ctx);
694 zassert_equal(r, 0, "Unable to append size2 option");
695 }
696
697 r = coap_packet_append_payload_marker(rsp);
698 zassert_equal(r, 0, "Unable to append payload marker");
699
700 payload_len = rsp_ctx->total_size - rsp_ctx->current;
701 if (payload_len > block_size) {
702 payload_len = block_size;
703 }
704
705 r = coap_packet_append_payload(rsp, payload, payload_len);
706 zassert_equal(r, 0, "Unable to append payload");
707
708 *more = coap_next_block(rsp, rsp_ctx);
709 }
710
verify_block2_request(struct coap_block_context * req_ctx,uint8_t iter)711 static void verify_block2_request(struct coap_block_context *req_ctx,
712 uint8_t iter)
713 {
714 zassert_equal(req_ctx->block_size, COAP_BLOCK_64,
715 "req:%d,Couldn't get block size", iter);
716 zassert_equal(req_ctx->current,
717 coap_block_size_to_bytes(COAP_BLOCK_64) * (iter - 1U),
718 "req:%d, Couldn't get the current block position", iter);
719 zassert_equal(req_ctx->total_size, BLOCK2_WISE_TRANSFER_SIZE_GET,
720 "req:%d,Couldn't packet total size", iter);
721 }
722
verify_block2_response(struct coap_block_context * rsp_ctx,uint8_t iter)723 static void verify_block2_response(struct coap_block_context *rsp_ctx,
724 uint8_t iter)
725 {
726 int block_size = coap_block_size_to_bytes(COAP_BLOCK_64);
727 int iter_max = ITER_COUNT(BLOCK2_WISE_TRANSFER_SIZE_GET, block_size);
728
729 zassert_equal(rsp_ctx->block_size, COAP_BLOCK_64,
730 "rsp:%d,Couldn't get block size", iter);
731
732 /* In last iteration "current" must match "total_size" */
733 if (iter < iter_max) {
734 zassert_equal(
735 rsp_ctx->current, block_size * iter,
736 "req:%d,Couldn't get the current block position", iter);
737 } else {
738 zassert_equal(
739 rsp_ctx->current, rsp_ctx->total_size,
740 "req:%d,Current block position does not match total size", iter);
741 }
742
743 zassert_equal(rsp_ctx->total_size, BLOCK2_WISE_TRANSFER_SIZE_GET,
744 "rsp:%d, Couldn't packet total size", iter);
745 }
746
ZTEST(coap,test_block2_size)747 ZTEST(coap, test_block2_size)
748 {
749 struct coap_block_context req_ctx;
750 struct coap_block_context rsp_ctx;
751 struct coap_packet req;
752 struct coap_packet rsp;
753 int more;
754 uint8_t i;
755
756 i = 0U;
757 more = 1;
758 memset(&req_ctx, 0, sizeof(req_ctx));
759 memset(&rsp_ctx, 0, sizeof(rsp_ctx));
760
761 while (more) {
762 prepare_block2_request(&req, &req_ctx, &rsp);
763 prepare_block2_response(&rsp, &rsp_ctx, &req, &more);
764
765 i++;
766
767 verify_block2_request(&req_ctx, i);
768 verify_block2_response(&rsp_ctx, i);
769 }
770 }
771
ZTEST(coap,test_retransmit_second_round)772 ZTEST(coap, test_retransmit_second_round)
773 {
774 struct coap_packet cpkt;
775 struct coap_packet rsp;
776 struct coap_pending *pending;
777 struct coap_pending *rsp_pending;
778 uint8_t *data = data_buf[0];
779 uint8_t *rsp_data = data_buf[1];
780 int r;
781 uint16_t id;
782
783 id = coap_next_id();
784
785 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1,
786 COAP_TYPE_CON, 0, coap_next_token(),
787 COAP_METHOD_GET, id);
788 zassert_equal(r, 0, "Could not initialize packet");
789
790 pending = coap_pending_next_unused(pendings, NUM_PENDINGS);
791 zassert_not_null(pending, "No free pending");
792
793 r = coap_pending_init(pending, &cpkt, (struct net_sockaddr *) &dummy_addr,
794 NULL);
795 zassert_equal(r, 0, "Could not initialize packet");
796
797 /* We "send" the packet the first time here */
798 zassert_true(coap_pending_cycle(pending), "Pending expired too early");
799
800 /* We simulate that the first transmission got lost */
801 zassert_true(coap_pending_cycle(pending), "Pending expired too early");
802
803 r = coap_packet_init(&rsp, rsp_data, COAP_BUF_SIZE,
804 COAP_VERSION_1, COAP_TYPE_ACK, 0, NULL,
805 COAP_METHOD_GET, id);
806 zassert_equal(r, 0, "Could not initialize packet");
807
808 /* Now we get the ack from the remote side */
809 rsp_pending = coap_pending_received(&rsp, pendings, NUM_PENDINGS);
810 zassert_equal_ptr(pending, rsp_pending,
811 "Invalid pending %p should be %p",
812 rsp_pending, pending);
813
814 coap_pending_clear(rsp_pending);
815
816 rsp_pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS);
817 zassert_is_null(rsp_pending, "There should be no active pendings");
818 }
819
ipaddr_cmp(const struct net_sockaddr * a,const struct net_sockaddr * b)820 static bool ipaddr_cmp(const struct net_sockaddr *a, const struct net_sockaddr *b)
821 {
822 if (a->sa_family != b->sa_family) {
823 return false;
824 }
825
826 if (a->sa_family == NET_AF_INET6) {
827 return net_ipv6_addr_cmp(&net_sin6(a)->sin6_addr,
828 &net_sin6(b)->sin6_addr);
829 } else if (a->sa_family == NET_AF_INET) {
830 return net_ipv4_addr_cmp(&net_sin(a)->sin_addr,
831 &net_sin(b)->sin_addr);
832 }
833
834 return false;
835 }
836
server_resource_1_callback(struct coap_resource * resource,struct coap_observer * observer)837 static void server_resource_1_callback(struct coap_resource *resource,
838 struct coap_observer *observer)
839 {
840 bool r;
841
842 r = ipaddr_cmp(&observer->addr, (const struct net_sockaddr *)&dummy_addr);
843 zassert_true(r, "The address of the observer doesn't match");
844
845 coap_remove_observer(resource, observer);
846 }
server_resource_2_callback(struct coap_resource * resource,struct coap_observer * observer)847 static void server_resource_2_callback(struct coap_resource *resource,
848 struct coap_observer *observer)
849 {
850 bool r;
851
852 r = ipaddr_cmp(&observer->addr, (const struct net_sockaddr *)&dummy_addr);
853 zassert_true(r, "The address of the observer doesn't match");
854 }
855
server_resource_1_get(struct coap_resource * resource,struct coap_packet * request,struct net_sockaddr * addr,net_socklen_t addr_len)856 static int server_resource_1_get(struct coap_resource *resource,
857 struct coap_packet *request,
858 struct net_sockaddr *addr, net_socklen_t addr_len)
859 {
860 struct coap_packet response;
861 struct coap_observer *observer;
862 uint8_t *data = data_buf[1];
863 char payload[] = "This is the payload";
864 uint8_t token[8];
865 uint8_t tkl;
866 uint16_t id;
867 int r;
868
869 zassert_true(coap_request_is_observe(request),
870 "The request should enable observing");
871
872 observer = coap_observer_next_unused(observers, NUM_OBSERVERS);
873 zassert_not_null(observer, "There should be an available observer");
874
875 tkl = coap_header_get_token(request, (uint8_t *) token);
876 id = coap_header_get_id(request);
877
878 coap_observer_init(observer, request, addr);
879 coap_register_observer(resource, observer);
880
881 r = coap_packet_init(&response, data, COAP_BUF_SIZE,
882 COAP_VERSION_1, COAP_TYPE_ACK, tkl, token,
883 COAP_RESPONSE_CODE_OK, id);
884 zassert_equal(r, 0, "Unable to initialize packet");
885
886 r = coap_append_option_int(&response, COAP_OPTION_OBSERVE,
887 resource->age);
888 zassert_equal(r, 0, "Failed to append observe option");
889
890 r = coap_packet_append_payload_marker(&response);
891 zassert_equal(r, 0, "Failed to set the payload marker");
892
893 r = coap_packet_append_payload(&response, (uint8_t *)payload,
894 strlen(payload));
895 zassert_equal(r, 0, "Unable to append payload");
896
897 resource->user_data = data;
898
899 return 0;
900 }
901
ZTEST(coap,test_observer_server)902 ZTEST(coap, test_observer_server)
903 {
904 uint8_t valid_request_pdu[] = {
905 0x45, 0x01, 0x12, 0x34,
906 't', 'o', 'k', 'e', 'n',
907 0x60, /* enable observe option */
908 0x51, 's', 0x01, '1', /* path */
909 };
910 uint8_t not_found_request_pdu[] = {
911 0x45, 0x01, 0x12, 0x34,
912 't', 'o', 'k', 'e', 'n',
913 0x60, /* enable observe option */
914 0x51, 's', 0x01, '3', /* path */
915 };
916 struct coap_packet req;
917 struct coap_option options[4] = {};
918 uint8_t *data = data_buf[0];
919 uint8_t opt_num = ARRAY_SIZE(options) - 1;
920 int r;
921
922 memcpy(data, valid_request_pdu, sizeof(valid_request_pdu));
923
924 r = coap_packet_parse(&req, data, sizeof(valid_request_pdu),
925 options, opt_num);
926 zassert_equal(r, 0, "Could not initialize packet");
927
928 r = coap_handle_request(&req, server_resources, options, opt_num,
929 (struct net_sockaddr *) &dummy_addr,
930 sizeof(dummy_addr));
931 zassert_equal(r, 0, "Could not handle packet");
932
933 /* Suppose some time passes */
934 r = coap_resource_notify(&server_resources[0]);
935 zassert_equal(r, 0, "Could not notify resource");
936
937 memcpy(data, not_found_request_pdu, sizeof(not_found_request_pdu));
938
939 r = coap_packet_parse(&req, data, sizeof(not_found_request_pdu),
940 options, opt_num);
941 zassert_equal(r, 0, "Could not initialize packet");
942
943 r = coap_handle_request(&req, server_resources, options, opt_num,
944 (struct net_sockaddr *) &dummy_addr,
945 sizeof(dummy_addr));
946 zassert_equal(r, -ENOENT,
947 "There should be no handler for this resource");
948 }
949
resource_reply_cb(const struct coap_packet * response,struct coap_reply * reply,const struct net_sockaddr * from)950 static int resource_reply_cb(const struct coap_packet *response,
951 struct coap_reply *reply,
952 const struct net_sockaddr *from)
953 {
954 TC_PRINT("You should see this");
955
956 return 0;
957 }
958
ZTEST(coap,test_observer_client)959 ZTEST(coap, test_observer_client)
960 {
961 struct coap_packet req;
962 struct coap_packet rsp;
963 struct coap_reply *reply;
964 struct coap_option options[4] = {};
965 const char token[] = "token";
966 const char * const *p;
967 uint8_t *data = data_buf[0];
968 uint8_t *rsp_data = data_buf[1];
969 uint8_t opt_num = ARRAY_SIZE(options) - 1;
970 int observe = 0;
971 int r;
972
973 r = coap_packet_init(&req, data, COAP_BUF_SIZE,
974 COAP_VERSION_1, COAP_TYPE_CON,
975 strlen(token), token,
976 COAP_METHOD_GET, coap_next_id());
977 zassert_equal(r, 0, "Unable to initialize request");
978
979 /* Enable observing the resource. */
980 r = coap_append_option_int(&req, COAP_OPTION_OBSERVE, observe);
981 zassert_equal(r, 0, "Unable to add option to request int");
982
983 for (p = server_resource_1_path; p && *p; p++) {
984 r = coap_packet_append_option(&req, COAP_OPTION_URI_PATH,
985 *p, strlen(*p));
986 zassert_equal(r, 0, "Unable to add option to request");
987 }
988
989 reply = coap_reply_next_unused(replies, NUM_REPLIES);
990 zassert_not_null(reply, "No resources for waiting for replies");
991
992 coap_reply_init(reply, &req);
993 reply->reply = resource_reply_cb;
994
995 /* Server side, not interesting for this test */
996 r = coap_packet_parse(&req, data, req.offset, options, opt_num);
997 zassert_equal(r, 0, "Could not parse req packet");
998
999 r = coap_handle_request(&req, server_resources, options, opt_num,
1000 (struct net_sockaddr *) &dummy_addr,
1001 sizeof(dummy_addr));
1002 zassert_equal(r, 0, "Could not handle packet");
1003
1004 /* We cheat, and communicate using the resource's user_data */
1005 rsp_data = server_resources[0].user_data;
1006
1007 /* 'rsp_pkt' contains the response now */
1008
1009 r = coap_packet_parse(&rsp, rsp_data, req.offset, options, opt_num);
1010 zassert_equal(r, 0, "Could not parse rsp packet");
1011
1012 reply = coap_response_received(&rsp,
1013 (const struct net_sockaddr *) &dummy_addr,
1014 replies, NUM_REPLIES);
1015 zassert_not_null(reply, "Couldn't find a matching waiting reply");
1016 }
1017
ZTEST(coap,test_handle_invalid_coap_req)1018 ZTEST(coap, test_handle_invalid_coap_req)
1019 {
1020 struct coap_packet pkt;
1021 uint8_t *data = data_buf[0];
1022 struct coap_option options[4] = {};
1023 uint8_t opt_num = 4;
1024 int r;
1025 const char *const *p;
1026
1027 r = coap_packet_init(&pkt, data, COAP_BUF_SIZE, COAP_VERSION_1,
1028 COAP_TYPE_CON, 0, NULL, 0xFF, coap_next_id());
1029
1030 zassert_equal(r, 0, "Unable to init req");
1031
1032 for (p = server_resource_1_path; p && *p; p++) {
1033 r = coap_packet_append_option(&pkt, COAP_OPTION_URI_PATH,
1034 *p, strlen(*p));
1035 zassert_equal(r, 0, "Unable to append option");
1036 }
1037
1038 r = coap_packet_parse(&pkt, data, pkt.offset, options, opt_num);
1039 zassert_equal(r, 0, "Could not parse req packet");
1040
1041 r = coap_handle_request(&pkt, server_resources, options, opt_num,
1042 (struct net_sockaddr *) &dummy_addr, sizeof(dummy_addr));
1043 zassert_equal(r, -ENOTSUP, "Request handling should fail with -ENOTSUP");
1044 }
1045
ZTEST(coap,test_build_options_out_of_order_0)1046 ZTEST(coap, test_build_options_out_of_order_0)
1047 {
1048 uint8_t result[] = {0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0xC0, 0xB1, 0x19,
1049 0xC5, 'p', 'r', 'o', 'x', 'y', 0x44, 'c', 'o', 'a', 'p'};
1050 struct coap_packet cpkt;
1051 static const char token[] = "token";
1052 uint8_t *data = data_buf[0];
1053 int r;
1054
1055 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1056 strlen(token), token, COAP_METHOD_POST, 0x1234);
1057 zassert_equal(r, 0, "Could not initialize packet");
1058
1059 r = coap_append_option_int(&cpkt, COAP_OPTION_CONTENT_FORMAT,
1060 COAP_CONTENT_FORMAT_TEXT_PLAIN);
1061 zassert_equal(r, 0, "Could not append option");
1062
1063 static const uint8_t expected_options_0 = 0xc0; /* content format */
1064
1065 zassert_mem_equal(&expected_options_0, &cpkt.data[cpkt.hdr_len], cpkt.opt_len);
1066
1067 const char *proxy_uri = "proxy";
1068
1069 r = coap_packet_append_option(&cpkt, COAP_OPTION_PROXY_URI, proxy_uri, strlen(proxy_uri));
1070 zassert_equal(r, 0, "Could not append option");
1071 static const uint8_t expected_options_1[] = {
1072 0xc0, /* content format */
1073 0xd5, 0x0a, 'p', 'r', 'o', 'x', 'y' /* proxy url */
1074 };
1075 zassert_mem_equal(expected_options_1, &cpkt.data[cpkt.hdr_len], cpkt.opt_len);
1076
1077 const char *proxy_scheme = "coap";
1078
1079 r = coap_packet_append_option(&cpkt, COAP_OPTION_PROXY_SCHEME, proxy_scheme,
1080 strlen(proxy_scheme));
1081 zassert_equal(r, 0, "Could not append option");
1082 static const uint8_t expected_options_2[] = {
1083 0xc0, /* content format */
1084 0xd5, 0x0a, 'p', 'r', 'o', 'x', 'y', /* proxy url */
1085 0x44, 'c', 'o', 'a', 'p' /* proxy scheme */
1086 };
1087 zassert_mem_equal(expected_options_2, &cpkt.data[cpkt.hdr_len], cpkt.opt_len);
1088
1089 /* option out of order */
1090 const uint8_t block_option = 0b11001;
1091
1092 r = coap_append_option_int(&cpkt, COAP_OPTION_BLOCK2, block_option);
1093 zassert_equal(r, 0, "Could not append option");
1094 static const uint8_t expected_options_3[] = {
1095 0xc0, /* content format */
1096 0xb1, 0x19, /* block2 */
1097 0xc5, 'p', 'r', 'o', 'x', 'y', /* proxy url */
1098 0x44, 'c', 'o', 'a', 'p' /* proxy scheme */
1099 };
1100 zassert_mem_equal(expected_options_3, &cpkt.data[cpkt.hdr_len], cpkt.opt_len);
1101
1102 /* look for options */
1103 struct coap_option opt;
1104
1105 r = coap_find_options(&cpkt, COAP_OPTION_CONTENT_FORMAT, &opt, 1);
1106 zassert_equal(r, 1, "Could not find option");
1107
1108 r = coap_find_options(&cpkt, COAP_OPTION_PROXY_URI, &opt, 1);
1109 zassert_equal(r, 1, "Could not find option");
1110 zassert_equal(opt.len, strlen(proxy_uri), "Wrong option len");
1111 zassert_mem_equal(opt.value, proxy_uri, strlen(proxy_uri), "Wrong option content");
1112
1113 r = coap_find_options(&cpkt, COAP_OPTION_PROXY_SCHEME, &opt, 1);
1114 zassert_equal(r, 1, "Could not find option");
1115 zassert_equal(opt.len, strlen(proxy_scheme), "Wrong option len");
1116 zassert_mem_equal(opt.value, proxy_scheme, strlen(proxy_scheme), "Wrong option content");
1117
1118 r = coap_find_options(&cpkt, COAP_OPTION_BLOCK2, &opt, 1);
1119 zassert_equal(r, 1, "Could not find option");
1120 zassert_equal(opt.len, 1, "Wrong option len");
1121 zassert_equal(*opt.value, block_option, "Wrong option content");
1122
1123 zassert_equal(cpkt.hdr_len, 9, "Wrong header len");
1124 zassert_equal(cpkt.opt_len, 14, "Wrong options size");
1125 zassert_equal(cpkt.delta, 39, "Wrong delta");
1126
1127 zassert_equal(cpkt.offset, 23, "Wrong data size");
1128
1129 zassert_mem_equal(result, cpkt.data, cpkt.offset,
1130 "Built packet doesn't match reference packet");
1131 }
1132
1133 #define ASSERT_OPTIONS(cpkt, expected_opt_len, expected_data, expected_data_len) \
1134 do { \
1135 static const uint8_t expected_hdr_len = 9; \
1136 zassert_equal(expected_hdr_len, cpkt.hdr_len, "Wrong header length"); \
1137 zassert_equal(expected_opt_len, cpkt.opt_len, "Wrong option length"); \
1138 zassert_equal(expected_hdr_len + expected_opt_len, cpkt.offset, "Wrong offset"); \
1139 zassert_equal(expected_data_len, cpkt.offset, "Wrong offset"); \
1140 zassert_mem_equal(expected_data, cpkt.data, expected_data_len, "Wrong data"); \
1141 } while (0)
1142
ZTEST(coap,test_build_options_out_of_order_1)1143 ZTEST(coap, test_build_options_out_of_order_1)
1144 {
1145 struct coap_packet cpkt;
1146
1147 static const char token[] = "token";
1148
1149 uint8_t *data = data_buf[0];
1150
1151 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1152
1153 int r;
1154
1155 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1156 strlen(token), token, COAP_METHOD_POST, 0x1234);
1157 zassert_equal(r, 0, "Could not initialize packet");
1158
1159 r = coap_append_option_int(&cpkt, COAP_OPTION_SIZE2,
1160 coap_block_size_to_bytes(COAP_BLOCK_128));
1161 zassert_equal(r, 0, "Could not append option");
1162 static const uint8_t expected_0[] = {0x45, 0x02, 0x12, 0x34, 't', 'o',
1163 'k', 'e', 'n', 0xd1, 0x0f, 0x80};
1164 ASSERT_OPTIONS(cpkt, 3, expected_0, 12);
1165
1166 const char *uri_path = "path";
1167
1168 r = coap_packet_append_option(&cpkt, COAP_OPTION_URI_PATH, uri_path, strlen(uri_path));
1169 zassert_equal(r, 0, "Could not append option");
1170
1171 static const uint8_t expected_1[] = {
1172 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n',
1173 0xb4, 'p', 'a', 't', 'h', 0xd1, 0x04, 0x80,
1174 };
1175
1176 ASSERT_OPTIONS(cpkt, 8, expected_1, 17);
1177
1178 r = coap_append_option_int(&cpkt, COAP_OPTION_CONTENT_FORMAT, COAP_CONTENT_FORMAT_APP_JSON);
1179 zassert_equal(r, 0, "Could not append option");
1180
1181 static const uint8_t expected_2[] = {
1182 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0xb4,
1183 'p', 'a', 't', 'h', 0x11, 0x32, 0xd1, 0x03, 0x80,
1184 };
1185
1186 ASSERT_OPTIONS(cpkt, 10, expected_2, 19);
1187
1188 const char *uri_host = "hostname";
1189
1190 r = coap_packet_append_option(&cpkt, COAP_OPTION_URI_HOST, uri_host, strlen(uri_host));
1191 zassert_equal(r, 0, "Could not append option");
1192
1193 static const uint8_t expected_3[] = {
1194 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o', 's', 't',
1195 'n', 'a', 'm', 'e', 0x84, 'p', 'a', 't', 'h', 0x11, 0x32, 0xd1, 0x03, 0x80,
1196 };
1197
1198 ASSERT_OPTIONS(cpkt, 19, expected_3, 28);
1199
1200 r = coap_append_option_int(&cpkt, COAP_OPTION_URI_PORT, 5638);
1201 zassert_equal(r, 0, "Could not append option");
1202
1203 static const uint8_t expected_4[] = {
1204 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h',
1205 'o', 's', 't', 'n', 'a', 'm', 'e', 'B', 0x16, 0x06, 'D',
1206 'p', 'a', 't', 'h', 0x11, 0x32, 0xd1, 0x03, 0x80,
1207 };
1208
1209 ASSERT_OPTIONS(cpkt, 22, expected_4, 31);
1210
1211 const char *uri_query0 = "query0";
1212
1213 r = coap_packet_append_option(&cpkt, COAP_OPTION_URI_QUERY, uri_query0, strlen(uri_query0));
1214 zassert_equal(r, 0, "Could not append option");
1215
1216 const char *uri_query1 = "query1";
1217
1218 r = coap_packet_append_option(&cpkt, COAP_OPTION_URI_QUERY, uri_query1, strlen(uri_query1));
1219 zassert_equal(r, 0, "Could not append option");
1220
1221 static const uint8_t expected_5[] = {
1222 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o',
1223 's', 't', 'n', 'a', 'm', 'e', 'B', 0x16, 0x06, 'D', 'p', 'a',
1224 't', 'h', 0x11, 0x32, 0x36, 'q', 'u', 'e', 'r', 'y', 0x30, 0x06,
1225 'q', 'u', 'e', 'r', 'y', 0x31, 0xd1, 0x00, 0x80,
1226 };
1227
1228 ASSERT_OPTIONS(cpkt, 36, expected_5, 45);
1229
1230 r = coap_append_option_int(&cpkt, COAP_OPTION_ACCEPT, COAP_CONTENT_FORMAT_APP_CBOR);
1231 zassert_equal(r, 0, "Could not append option");
1232
1233 static const uint8_t expected_6[] = {
1234 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o',
1235 's', 't', 'n', 'a', 'm', 'e', 'B', 0x16, 0x06, 'D', 'p', 'a',
1236 't', 'h', 0x11, 0x32, 0x36, 'q', 'u', 'e', 'r', 'y', 0x30, 0x06,
1237 'q', 'u', 'e', 'r', 'y', 0x31, 0x21, 0x3c, 0xb1, 0x80,
1238 };
1239
1240 ASSERT_OPTIONS(cpkt, 37, expected_6, 46);
1241
1242 r = coap_append_option_int(&cpkt, COAP_OPTION_OBSERVE, 0);
1243 zassert_equal(r, 0, "Could not append option");
1244
1245 static const uint8_t expected_7[] = {
1246 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o',
1247 's', 't', 'n', 'a', 'm', 'e', 0x30, 0x12, 0x16, 0x06, 'D', 'p',
1248 'a', 't', 'h', 0x11, 0x32, 0x36, 'q', 'u', 'e', 'r', 'y', 0x30,
1249 0x06, 'q', 'u', 'e', 'r', 'y', 0x31, 0x21, 0x3c, 0xb1, 0x80,
1250 };
1251
1252 ASSERT_OPTIONS(cpkt, 38, expected_7, 47);
1253
1254 r = coap_append_option_int(&cpkt, COAP_OPTION_MAX_AGE, 3);
1255 zassert_equal(r, 0, "Could not append option");
1256
1257 static const uint8_t expected_8[] = {
1258 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o', 's',
1259 't', 'n', 'a', 'm', 'e', 0x30, 0x12, 0x16, 0x06, 'D', 'p', 'a', 't',
1260 'h', 0x11, 0x32, 0x21, 0x03, 0x16, 'q', 'u', 'e', 'r', 'y', 0x30, 0x06,
1261 'q', 'u', 'e', 'r', 'y', 0x31, 0x21, 0x3c, 0xb1, 0x80,
1262 };
1263
1264 ASSERT_OPTIONS(cpkt, 40, expected_8, 49);
1265
1266 r = coap_append_option_int(&cpkt, COAP_OPTION_SIZE1, 64);
1267 zassert_equal(r, 0, "Could not append option");
1268
1269 static const uint8_t expected_9[] = {
1270 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o', 's',
1271 't', 'n', 'a', 'm', 'e', 0x30, 0x12, 0x16, 0x06, 'D', 'p', 'a', 't',
1272 'h', 0x11, 0x32, 0x21, 0x03, 0x16, 'q', 'u', 'e', 'r', 'y', 0x30, 0x06,
1273 'q', 'u', 'e', 'r', 'y', 0x31, 0x21, 0x3c, 0xb1, 0x80, 0xd1, 0x13, 0x40,
1274 };
1275
1276 ASSERT_OPTIONS(cpkt, 43, expected_9, 52);
1277
1278 zassert_equal(cpkt.hdr_len, 9, "Wrong header len");
1279 zassert_equal(cpkt.opt_len, 43, "Wrong options size");
1280 zassert_equal(cpkt.delta, 60, "Wrong delta");
1281 zassert_equal(cpkt.offset, 52, "Wrong data size");
1282 }
1283
1284 #define ASSERT_OPTIONS_AND_PAYLOAD(cpkt, expected_opt_len, expected_data, expected_offset, \
1285 expected_delta) \
1286 do { \
1287 size_t expected_data_l = ARRAY_SIZE(expected_data); \
1288 zassert_equal(expected_offset, expected_data_l); \
1289 static const uint8_t expected_hdr_len = 9; \
1290 zassert_equal(expected_hdr_len, cpkt.hdr_len, "Wrong header length"); \
1291 zassert_equal(expected_opt_len, cpkt.opt_len, "Wrong option length"); \
1292 zassert_equal(expected_offset, cpkt.offset, "Wrong offset"); \
1293 zassert_mem_equal(expected_data, cpkt.data, expected_offset, "Wrong data"); \
1294 zassert_equal(expected_delta, cpkt.delta, "Wrong delta"); \
1295 } while (0)
1296
init_basic_test_msg(struct coap_packet * cpkt,uint8_t * data)1297 static void init_basic_test_msg(struct coap_packet *cpkt, uint8_t *data)
1298 {
1299 static const char token[] = "token";
1300 const char *uri_path = "path";
1301 const char *uri_host = "hostname";
1302 const char *uri_query0 = "query0";
1303 const char *uri_query1 = "query1";
1304
1305 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1306
1307 int r;
1308
1309 r = coap_packet_init(cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1310 strlen(token), token, COAP_METHOD_POST, 0x1234);
1311 zassert_equal(r, 0, "Could not initialize packet");
1312
1313 r = coap_append_option_int(cpkt, COAP_OPTION_SIZE2,
1314 coap_block_size_to_bytes(COAP_BLOCK_128));
1315 zassert_equal(r, 0, "Could not append option");
1316
1317 r = coap_packet_append_option(cpkt, COAP_OPTION_URI_PATH, uri_path, strlen(uri_path));
1318 zassert_equal(r, 0, "Could not append option");
1319
1320 r = coap_append_option_int(cpkt, COAP_OPTION_CONTENT_FORMAT, COAP_CONTENT_FORMAT_APP_JSON);
1321 zassert_equal(r, 0, "Could not append option");
1322
1323 r = coap_packet_append_option(cpkt, COAP_OPTION_URI_HOST, uri_host, strlen(uri_host));
1324 zassert_equal(r, 0, "Could not append option");
1325
1326 r = coap_append_option_int(cpkt, COAP_OPTION_URI_PORT, 5638);
1327 zassert_equal(r, 0, "Could not append option");
1328
1329 r = coap_packet_append_option(cpkt, COAP_OPTION_URI_QUERY, uri_query0, strlen(uri_query0));
1330 zassert_equal(r, 0, "Could not append option");
1331
1332 r = coap_packet_append_option(cpkt, COAP_OPTION_URI_QUERY, uri_query1, strlen(uri_query1));
1333 zassert_equal(r, 0, "Could not append option");
1334
1335 r = coap_append_option_int(cpkt, COAP_OPTION_ACCEPT, COAP_CONTENT_FORMAT_APP_CBOR);
1336 zassert_equal(r, 0, "Could not append option");
1337
1338 r = coap_append_option_int(cpkt, COAP_OPTION_OBSERVE, 0);
1339 zassert_equal(r, 0, "Could not append option");
1340
1341 r = coap_append_option_int(cpkt, COAP_OPTION_MAX_AGE, 3);
1342 zassert_equal(r, 0, "Could not append option");
1343
1344 r = coap_append_option_int(cpkt, COAP_OPTION_SIZE1, 64);
1345 zassert_equal(r, 0, "Could not append option");
1346
1347 static const uint8_t expected_9[] = {
1348 0x45, 0x02, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x38, 'h', 'o', 's',
1349 't', 'n', 'a', 'm', 'e', 0x30, 0x12, 0x16, 0x06, 'D', 'p', 'a', 't',
1350 'h', 0x11, 0x32, 0x21, 0x03, 0x16, 'q', 'u', 'e', 'r', 'y', 0x30, 0x06,
1351 'q', 'u', 'e', 'r', 'y', 0x31, 0x21, 0x3c, 0xb1, 0x80, 0xd1, 0x13, 0x40,
1352 };
1353
1354 ASSERT_OPTIONS((*cpkt), 43, expected_9, 52);
1355
1356 r = coap_packet_append_payload_marker(cpkt);
1357 zassert_equal(r, 0, "Could not append payload marker");
1358
1359 static const uint8_t test_payload[] = {0xde, 0xad, 0xbe, 0xef};
1360
1361 r = coap_packet_append_payload(cpkt, test_payload, ARRAY_SIZE(test_payload));
1362 zassert_equal(r, 0, "Could not append test payload");
1363
1364 zassert_equal((*cpkt).hdr_len, 9, "Wrong header len");
1365 zassert_equal((*cpkt).opt_len, 43, "Wrong options size");
1366 zassert_equal((*cpkt).delta, 60, "Wrong delta");
1367 zassert_equal((*cpkt).offset, 57, "Wrong data size");
1368 }
1369
ZTEST(coap,test_remove_first_coap_option)1370 ZTEST(coap, test_remove_first_coap_option)
1371 {
1372 int r;
1373 struct coap_packet cpkt;
1374 uint8_t *data = data_buf[0];
1375
1376 init_basic_test_msg(&cpkt, data);
1377
1378 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_HOST);
1379 zassert_equal(r, 0, "Could not remove option");
1380
1381 static const uint8_t expected_0[] = {
1382 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x60, 0x12, 0x16,
1383 0x06, 0x44, 0x70, 0x61, 0x74, 0x68, 0x11, 0x32, 0x21, 0x03, 0x16, 0x71,
1384 0x75, 0x65, 0x72, 0x79, 0x30, 0x06, 0x71, 0x75, 0x65, 0x72, 0x79, 0x31,
1385 0x21, 0x3c, 0xb1, 0x80, 0xd1, 0x13, 0x40, 0xff, 0xde, 0xad, 0xbe, 0xef};
1386
1387 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 34, expected_0, 48, 60);
1388 }
1389
ZTEST(coap,test_remove_middle_coap_option)1390 ZTEST(coap, test_remove_middle_coap_option)
1391 {
1392 int r;
1393 struct coap_packet cpkt;
1394 uint8_t *data = data_buf[0];
1395
1396 init_basic_test_msg(&cpkt, data);
1397
1398 r = coap_packet_remove_option(&cpkt, COAP_OPTION_OBSERVE);
1399 zassert_equal(r, 0, "Could not remove option");
1400
1401 static const uint8_t expected_0[] = {
1402 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x38, 0x68, 0x6f, 0x73, 0x74,
1403 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x16, 0x06, 0x44, 0x70, 0x61, 0x74, 0x68, 0x11, 0x32,
1404 0x21, 0x03, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x30, 0x06, 0x71, 0x75, 0x65, 0x72,
1405 0x79, 0x31, 0x21, 0x3c, 0xb1, 0x80, 0xd1, 0x13, 0x40, 0xff, 0xde, 0xad, 0xbe, 0xef};
1406
1407 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 42, expected_0, 56, 60);
1408 }
1409
ZTEST(coap,test_remove_last_coap_option)1410 ZTEST(coap, test_remove_last_coap_option)
1411 {
1412 int r;
1413 struct coap_packet cpkt;
1414 uint8_t *data = data_buf[0];
1415
1416 init_basic_test_msg(&cpkt, data);
1417
1418 r = coap_packet_remove_option(&cpkt, COAP_OPTION_SIZE1);
1419 zassert_equal(r, 0, "Could not remove option");
1420
1421 static const uint8_t expected_0[] = {
1422 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x38, 0x68, 0x6f, 0x73, 0x74,
1423 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x12, 0x16, 0x06, 0x44, 0x70, 0x61, 0x74, 0x68, 0x11,
1424 0x32, 0x21, 0x03, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x30, 0x06, 0x71, 0x75, 0x65,
1425 0x72, 0x79, 0x31, 0x21, 0x3c, 0xb1, 0x80, 0xff, 0xde, 0xad, 0xbe, 0xef};
1426
1427 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 40, expected_0, 54, 28);
1428
1429 r = coap_append_option_int(&cpkt, COAP_OPTION_SIZE1, 65);
1430 zassert_equal(r, 0, "Could not add option at end");
1431
1432 static const uint8_t expected_1[] = {
1433 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x38, 0x68, 0x6f,
1434 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x12, 0x16, 0x06, 0x44, 0x70,
1435 0x61, 0x74, 0x68, 0x11, 0x32, 0x21, 0x03, 0x16, 0x71, 0x75, 0x65, 0x72,
1436 0x79, 0x30, 0x06, 0x71, 0x75, 0x65, 0x72, 0x79, 0x31, 0x21, 0x3c, 0xb1,
1437 0x80, 0xd1, 0x13, 0x41, 0xff, 0xde, 0xad, 0xbe, 0xef};
1438
1439 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 43, expected_1, 57, 60);
1440 }
1441
ZTEST(coap,test_remove_single_coap_option)1442 ZTEST(coap, test_remove_single_coap_option)
1443 {
1444 struct coap_packet cpkt;
1445 uint8_t *data = data_buf[0];
1446
1447 static const char token[] = "token";
1448 const char *uri_path = "path";
1449
1450 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1451
1452 int r1;
1453
1454 r1 = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1455 strlen(token), token, COAP_METHOD_POST, 0x1234);
1456 zassert_equal(r1, 0, "Could not initialize packet");
1457
1458 r1 = coap_packet_append_option(&cpkt, COAP_OPTION_URI_PATH, uri_path, strlen(uri_path));
1459 zassert_equal(r1, 0, "Could not append option");
1460
1461 r1 = coap_packet_append_payload_marker(&cpkt);
1462 zassert_equal(r1, 0, "Could not append payload marker");
1463
1464 static const uint8_t test_payload[] = {0xde, 0xad, 0xbe, 0xef};
1465
1466 r1 = coap_packet_append_payload(&cpkt, test_payload, ARRAY_SIZE(test_payload));
1467 zassert_equal(r1, 0, "Could not append test payload");
1468
1469 static const uint8_t expected_0[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b,
1470 0x65, 0x6e, 0xb4, 0x70, 0x61, 0x74, 0x68,
1471 0xff, 0xde, 0xad, 0xbe, 0xef};
1472
1473 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 5, expected_0, 19, 11);
1474
1475 /* remove the one and only option */
1476 r1 = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_PATH);
1477 zassert_equal(r1, 0, "Could not remove option");
1478
1479 static const uint8_t expected_1[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b,
1480 0x65, 0x6e, 0xff, 0xde, 0xad, 0xbe, 0xef};
1481
1482 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 0, expected_1, 14, 0);
1483 }
1484
ZTEST(coap,test_remove_repeatable_coap_option)1485 ZTEST(coap, test_remove_repeatable_coap_option)
1486 {
1487 int r;
1488 struct coap_packet cpkt;
1489 uint8_t *data = data_buf[0];
1490
1491 init_basic_test_msg(&cpkt, data);
1492
1493 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_QUERY);
1494 zassert_equal(r, 0, "Could not remove option");
1495
1496 static const uint8_t expected_0[] = {
1497 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x38, 0x68, 0x6f, 0x73,
1498 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x12, 0x16, 0x06, 0x44, 0x70, 0x61, 0x74,
1499 0x68, 0x11, 0x32, 0x21, 0x03, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x31, 0x21,
1500 0x3c, 0xb1, 0x80, 0xd1, 0x13, 0x40, 0xff, 0xde, 0xad, 0xbe, 0xef};
1501
1502 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 36, expected_0, 50, 60);
1503 }
1504
ZTEST(coap,test_remove_all_coap_options)1505 ZTEST(coap, test_remove_all_coap_options)
1506 {
1507 int r;
1508 struct coap_packet cpkt;
1509 uint8_t *data = data_buf[0];
1510
1511 init_basic_test_msg(&cpkt, data);
1512
1513 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_PORT);
1514 zassert_equal(r, 0, "Could not remove option");
1515
1516 r = coap_packet_remove_option(&cpkt, COAP_OPTION_OBSERVE);
1517 zassert_equal(r, 0, "Could not remove option");
1518
1519 r = coap_packet_remove_option(&cpkt, COAP_OPTION_SIZE1);
1520 zassert_equal(r, 0, "Could not remove option");
1521
1522 static const uint8_t expected_0[] = {
1523 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x38, 0x68, 0x6f, 0x73,
1524 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x84, 0x70, 0x61, 0x74, 0x68, 0x11, 0x32, 0x21,
1525 0x03, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x30, 0x06, 0x71, 0x75, 0x65, 0x72,
1526 0x79, 0x31, 0x21, 0x3c, 0xb1, 0x80, 0xff, 0xde, 0xad, 0xbe, 0xef};
1527
1528 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 36, expected_0, 50, 28);
1529
1530 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_HOST);
1531 zassert_equal(r, 0, "Could not remove option");
1532
1533 r = coap_packet_remove_option(&cpkt, COAP_OPTION_SIZE2);
1534 zassert_equal(r, 0, "Could not remove option");
1535
1536 r = coap_packet_remove_option(&cpkt, COAP_OPTION_CONTENT_FORMAT);
1537 zassert_equal(r, 0, "Could not remove option");
1538
1539 static const uint8_t expected_1[] = {
1540 0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xb4, 0x70, 0x61, 0x74,
1541 0x68, 0x31, 0x03, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x30, 0x06, 0x71, 0x75,
1542 0x65, 0x72, 0x79, 0x31, 0x21, 0x3c, 0xff, 0xde, 0xad, 0xbe, 0xef};
1543
1544 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 23, expected_1, 37, 17);
1545
1546 r = coap_packet_remove_option(&cpkt, COAP_OPTION_ACCEPT);
1547 zassert_equal(r, 0, "Could not remove option");
1548
1549 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_PATH);
1550 zassert_equal(r, 0, "Could not remove option");
1551
1552 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_QUERY);
1553 zassert_equal(r, 0, "Could not remove option");
1554
1555 static const uint8_t expected_2[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65,
1556 0x6e, 0xd1, 0x01, 0x03, 0x16, 0x71, 0x75, 0x65,
1557 0x72, 0x79, 0x31, 0xff, 0xde, 0xad, 0xbe, 0xef};
1558
1559 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 10, expected_2, 24, 15);
1560
1561 r = coap_packet_remove_option(&cpkt, COAP_OPTION_MAX_AGE);
1562 zassert_equal(r, 0, "Could not remove option");
1563
1564 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_QUERY);
1565 zassert_equal(r, 0, "Could not remove option");
1566
1567 static const uint8_t expected_3[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b,
1568 0x65, 0x6e, 0xff, 0xde, 0xad, 0xbe, 0xef};
1569
1570 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 0, expected_3, 14, 0);
1571
1572 /* remove option that is not there anymore */
1573 r = coap_packet_remove_option(&cpkt, COAP_OPTION_MAX_AGE);
1574 zassert_equal(r, 0, "Could not remove option");
1575
1576 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 0, expected_3, 14, 0);
1577 }
1578
ZTEST(coap,test_remove_non_existent_coap_option)1579 ZTEST(coap, test_remove_non_existent_coap_option)
1580 {
1581 int r;
1582 struct coap_packet cpkt;
1583 uint8_t *data = data_buf[0];
1584 static const char token[] = "token";
1585
1586 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1587
1588 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1589 strlen(token), token, COAP_METHOD_POST, 0x1234);
1590 zassert_equal(r, 0, "Could not initialize packet");
1591
1592 r = coap_append_option_int(&cpkt, COAP_OPTION_CONTENT_FORMAT, COAP_CONTENT_FORMAT_APP_CBOR);
1593 zassert_equal(r, 0, "Could not append option");
1594
1595 r = coap_append_option_int(&cpkt, COAP_OPTION_ACCEPT, COAP_CONTENT_FORMAT_APP_OCTET_STREAM);
1596 zassert_equal(r, 0, "Could not append option");
1597
1598 r = coap_packet_append_payload_marker(&cpkt);
1599 zassert_equal(r, 0, "Could not append payload marker");
1600
1601 static const uint8_t test_payload[] = {0xde, 0xad, 0xbe, 0xef};
1602
1603 r = coap_packet_append_payload(&cpkt, test_payload, ARRAY_SIZE(test_payload));
1604
1605 static const uint8_t expected_original_msg[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f,
1606 0x6b, 0x65, 0x6e, 0xc1, 0x3c, 0x51,
1607 0x2a, 0xff, 0xde, 0xad, 0xbe, 0xef};
1608
1609 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 4, expected_original_msg, 18, 17);
1610
1611 /* remove option that is not there but would be before existing options */
1612 r = coap_packet_remove_option(&cpkt, COAP_OPTION_URI_PATH);
1613 zassert_equal(r, 0, "Could not remove option");
1614
1615 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 4, expected_original_msg, 18, 17);
1616
1617 /* remove option that is not there but would be between existing options */
1618 r = coap_packet_remove_option(&cpkt, COAP_OPTION_MAX_AGE);
1619 zassert_equal(r, 0, "Could not remove option");
1620
1621 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 4, expected_original_msg, 18, 17);
1622
1623 /* remove option that is not there but would be after existing options */
1624 r = coap_packet_remove_option(&cpkt, COAP_OPTION_LOCATION_QUERY);
1625 zassert_equal(r, 0, "Could not remove option");
1626
1627 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 4, expected_original_msg, 18, 17);
1628 }
1629
ZTEST(coap,test_coap_packet_options_with_large_values)1630 ZTEST(coap, test_coap_packet_options_with_large_values)
1631 {
1632 int r;
1633 struct coap_packet cpkt;
1634 uint8_t *data = data_buf[0];
1635 static const char token[] = "token";
1636
1637 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1638
1639 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1640 strlen(token), token, COAP_METHOD_POST, 0x1234);
1641 zassert_equal(r, 0, "Could not initialize packet");
1642
1643 r = coap_append_option_int(&cpkt, COAP_OPTION_MAX_AGE, 3600);
1644 zassert_equal(r, 0, "Could not append option");
1645
1646 r = coap_append_option_int(&cpkt, COAP_OPTION_SIZE1, 1048576);
1647 zassert_equal(r, 0, "Could not append option");
1648
1649 static const uint8_t expected_0[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
1650 0xd2, 0x01, 0x0e, 0x10, 0xd3, 0x21, 0x10, 0x00, 0x00};
1651 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 9, expected_0, 18, 60);
1652 }
1653
ZTEST(coap,test_coap_packet_options_with_large_delta)1654 ZTEST(coap, test_coap_packet_options_with_large_delta)
1655 {
1656 int r;
1657 struct coap_packet cpkt;
1658 uint8_t *data = data_buf[0];
1659 static const char token[] = "token";
1660 static const uint8_t payload[] = {0xde, 0xad, 0xbe, 0xef};
1661
1662 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1663
1664 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1665 strlen(token), token, COAP_METHOD_POST, 0x1234);
1666 zassert_equal(r, 0, "Could not initialize packet");
1667
1668 r = coap_append_option_int(&cpkt, 65100, 0x5678);
1669 zassert_equal(r, 0, "Could not append option");
1670
1671 r = coap_packet_append_payload_marker(&cpkt);
1672 zassert_equal(r, 0, "Could not append payload marker");
1673
1674 r = coap_packet_append_payload(&cpkt, payload, ARRAY_SIZE(payload));
1675 zassert_equal(r, 0, "Could not append payload");
1676
1677 static const uint8_t expected_0[] = {0x45, 0x02, 0x12, 0x34, 0x74, 0x6f, 0x6b,
1678 0x65, 0x6e, 0xe2, 0xfd, 0x3f, 0x56, 0x78,
1679 0xff, 0xde, 0xad, 0xbe, 0xef};
1680
1681 ASSERT_OPTIONS_AND_PAYLOAD(cpkt, 5, expected_0, 19, 65100);
1682 }
1683
assert_coap_packet_set_path_query_options(const char * path,const char * const * expected,size_t expected_len,uint16_t code)1684 static void assert_coap_packet_set_path_query_options(const char *path,
1685 const char * const *expected,
1686 size_t expected_len, uint16_t code)
1687 {
1688 struct coap_packet cpkt;
1689 uint8_t *data = data_buf[0];
1690 struct coap_option options[16] = {0};
1691 int res;
1692
1693 memset(data_buf[0], 0, ARRAY_SIZE(data_buf[0]));
1694 TC_PRINT("Assert path: %s\n", path);
1695
1696 res = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, COAP_TYPE_CON,
1697 COAP_TOKEN_MAX_LEN, coap_next_token(),
1698 COAP_METHOD_GET, 0x1234);
1699 zassert_equal(res, 0, "Could not initialize packet");
1700
1701 res = coap_packet_set_path(&cpkt, path);
1702 zassert_equal(res, 0, "Could not set path/query, path: %s", path);
1703
1704 res = coap_find_options(&cpkt, code, options, ARRAY_SIZE(options));
1705 if (res <= 0) {
1706 /* fail if we expect options */
1707 zassert_true(((expected == NULL) && (expected_len == 0U)),
1708 "Expected options but found none, path: %s", path);
1709 }
1710
1711 for (unsigned int i = 0U; i < expected_len; ++i) {
1712 /* validate expected options, the rest shall be 0 */
1713 if (i < expected_len) {
1714 zassert_true((options[i].len == strlen(expected[i])),
1715 "Expected and parsed option lengths don't match"
1716 ", path: %s",
1717 path);
1718
1719 zassert_mem_equal(options[i].value, expected[i], options[i].len,
1720 "Expected and parsed option values don't match"
1721 ", path: %s",
1722 path);
1723 } else {
1724 zassert_true((options[i].len == 0U),
1725 "Unexpected options shall be empty"
1726 ", path: %s",
1727 path);
1728 }
1729 }
1730 }
1731
ZTEST(coap,test_coap_packet_set_path)1732 ZTEST(coap, test_coap_packet_set_path)
1733 {
1734 assert_coap_packet_set_path_query_options(" ", NULL, 0U, COAP_OPTION_URI_PATH);
1735 assert_coap_packet_set_path_query_options("", NULL, 0U, COAP_OPTION_URI_PATH);
1736 assert_coap_packet_set_path_query_options("/", NULL, 0U, COAP_OPTION_URI_PATH);
1737 assert_coap_packet_set_path_query_options("?", NULL, 0U, COAP_OPTION_URI_QUERY);
1738
1739 assert_coap_packet_set_path_query_options("?a",
1740 (const char *const[]){"a"}, 1U,
1741 COAP_OPTION_URI_QUERY);
1742 assert_coap_packet_set_path_query_options("?a&b",
1743 (const char *const[]){"a", "b"}, 2U,
1744 COAP_OPTION_URI_QUERY);
1745
1746 assert_coap_packet_set_path_query_options("a",
1747 (const char *const[]){"a"}, 1U,
1748 COAP_OPTION_URI_PATH);
1749 assert_coap_packet_set_path_query_options("a", NULL, 0, COAP_OPTION_URI_QUERY);
1750 assert_coap_packet_set_path_query_options("a/",
1751 (const char *const[]){"a"}, 1U,
1752 COAP_OPTION_URI_PATH);
1753
1754 assert_coap_packet_set_path_query_options("a?b=t&a",
1755 (const char *const[]){"a"}, 1U,
1756 COAP_OPTION_URI_PATH);
1757 assert_coap_packet_set_path_query_options("a?b=t&a",
1758 (const char *const[]){"b=t", "a"}, 2U,
1759 COAP_OPTION_URI_QUERY);
1760 assert_coap_packet_set_path_query_options("a?b=t&aa",
1761 (const char *const[]){"b=t", "aa"},
1762 2U, COAP_OPTION_URI_QUERY);
1763
1764 assert_coap_packet_set_path_query_options("a?b&a",
1765 (const char *const[]){"a"}, 1U,
1766 COAP_OPTION_URI_PATH);
1767 assert_coap_packet_set_path_query_options("a?b&a",
1768 (const char *const[]){"b", "a"}, 2U,
1769 COAP_OPTION_URI_QUERY);
1770 assert_coap_packet_set_path_query_options("a?b&aa",
1771 (const char *const[]){"b", "aa"}, 2U,
1772 COAP_OPTION_URI_QUERY);
1773
1774 assert_coap_packet_set_path_query_options("a/b",
1775 (const char *const[]){"a", "b"}, 2U,
1776 COAP_OPTION_URI_PATH);
1777 assert_coap_packet_set_path_query_options("a/b/",
1778 (const char *const[]){"a", "b"}, 2U,
1779 COAP_OPTION_URI_PATH);
1780 assert_coap_packet_set_path_query_options("a/b?b&a",
1781 (const char *const[]){"b", "a"}, 2U,
1782 COAP_OPTION_URI_QUERY);
1783 assert_coap_packet_set_path_query_options("a/b?b&aa",
1784 (const char *const[]){"b", "aa"}, 2U,
1785 COAP_OPTION_URI_QUERY);
1786
1787 assert_coap_packet_set_path_query_options("a/bb",
1788 (const char *const[]){"a", "bb"}, 2U,
1789 COAP_OPTION_URI_PATH);
1790 assert_coap_packet_set_path_query_options("a/bb/",
1791 (const char *const[]){"a", "bb"}, 2U,
1792 COAP_OPTION_URI_PATH);
1793 }
1794
ZTEST(coap,test_transmission_parameters)1795 ZTEST(coap, test_transmission_parameters)
1796 {
1797 struct coap_packet cpkt;
1798 struct coap_pending *pending;
1799 struct coap_transmission_parameters params;
1800 uint8_t *data = data_buf[0];
1801 int r;
1802 uint16_t id;
1803
1804 params = coap_get_transmission_parameters();
1805 zassert_equal(params.ack_timeout, CONFIG_COAP_INIT_ACK_TIMEOUT_MS, "Wrong ACK timeout");
1806 zassert_equal(params.ack_random_percent, CONFIG_COAP_ACK_RANDOM_PERCENT,
1807 "Wrong ACK random percent");
1808 zassert_equal(params.coap_backoff_percent, CONFIG_COAP_BACKOFF_PERCENT,
1809 "Wrong backoff percent");
1810 zassert_equal(params.max_retransmission, CONFIG_COAP_MAX_RETRANSMIT,
1811 "Wrong max retransmission value");
1812
1813 params.ack_timeout = 1000;
1814 params.ack_random_percent = 110;
1815 params.coap_backoff_percent = 150;
1816 params.max_retransmission = 2;
1817
1818 coap_set_transmission_parameters(¶ms);
1819
1820 id = coap_next_id();
1821
1822 r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1,
1823 COAP_TYPE_CON, 0, coap_next_token(),
1824 COAP_METHOD_GET, id);
1825 zassert_equal(r, 0, "Could not initialize packet");
1826
1827 pending = coap_pending_next_unused(pendings, NUM_PENDINGS);
1828 zassert_not_null(pending, "No free pending");
1829
1830 params.ack_timeout = 3000;
1831 params.ack_random_percent = 130;
1832 params.coap_backoff_percent = 250;
1833 params.max_retransmission = 3;
1834
1835 r = coap_pending_init(pending, &cpkt, (struct net_sockaddr *) &dummy_addr,
1836 ¶ms);
1837 zassert_equal(r, 0, "Could not initialize packet");
1838
1839 zassert_equal(pending->params.ack_timeout, 3000, "Wrong ACK timeout");
1840 zassert_equal(pending->params.ack_random_percent, 130, "Wrong ACK random percent");
1841 zassert_equal(pending->params.coap_backoff_percent, 250, "Wrong backoff percent");
1842 zassert_equal(pending->params.max_retransmission, 3, "Wrong max retransmission value");
1843
1844 r = coap_pending_init(pending, &cpkt, (struct net_sockaddr *) &dummy_addr,
1845 NULL);
1846 zassert_equal(r, 0, "Could not initialize packet");
1847
1848 zassert_equal(pending->params.ack_timeout, 1000, "Wrong ACK timeout");
1849 zassert_equal(pending->params.ack_random_percent, 110, "Wrong ACK random percent");
1850 zassert_equal(pending->params.coap_backoff_percent, 150, "Wrong backoff percent");
1851 zassert_equal(pending->params.max_retransmission, 2, "Wrong max retransmission value");
1852 }
1853
ZTEST(coap,test_notify_age)1854 ZTEST(coap, test_notify_age)
1855 {
1856 uint8_t valid_request_pdu[] = {
1857 0x45, 0x01, 0x12, 0x34, 't', 'o', 'k', 'e', 'n', 0x60, /* enable observe option */
1858 0x51, 's', 0x01, '2', /* path */
1859 };
1860
1861 struct coap_packet req;
1862 struct coap_option options[4] = {};
1863 uint8_t *data = data_buf[0];
1864 uint8_t opt_num = ARRAY_SIZE(options) - 1;
1865 struct coap_resource *resource = &server_resources[1];
1866 int r;
1867 struct coap_observer *observer;
1868 int last_age;
1869
1870 memcpy(data, valid_request_pdu, sizeof(valid_request_pdu));
1871
1872 r = coap_packet_parse(&req, data, sizeof(valid_request_pdu), options, opt_num);
1873 zassert_equal(r, 0, "Could not initialize packet");
1874
1875 r = coap_handle_request(&req, server_resources, options, opt_num,
1876 (struct net_sockaddr *)&dummy_addr, sizeof(dummy_addr));
1877 zassert_equal(r, 0, "Could not handle packet");
1878
1879 /* Forward time a bit, as not to run this 8 million time */
1880 resource->age = COAP_OBSERVE_MAX_AGE - 10;
1881
1882 last_age = resource->age;
1883
1884 for (int i = 0; i < 15; i++) {
1885 r = coap_resource_notify(resource);
1886 zassert_true(coap_age_is_newer(last_age, resource->age),
1887 "Resource age expected to be newer");
1888 last_age = resource->age;
1889 }
1890
1891 observer =
1892 CONTAINER_OF(sys_slist_peek_head(&resource->observers), struct coap_observer, list);
1893 coap_remove_observer(resource, observer);
1894 }
1895
ZTEST(coap,test_age_is_newer)1896 ZTEST(coap, test_age_is_newer)
1897 {
1898 for (int i = COAP_FIRST_AGE; i < COAP_MAX_AGE; ++i) {
1899 zassert_true(coap_age_is_newer(i, i + 1),
1900 "Resource age expected to be marked as newer");
1901 }
1902
1903 zassert_true(coap_age_is_newer(COAP_MAX_AGE, COAP_FIRST_AGE),
1904 "First age should be marked as newer");
1905 zassert_true(coap_age_is_newer(COAP_FIRST_AGE, COAP_ROLLOVER_AGE),
1906 "Rollover age should be marked as newer");
1907 zassert_true(coap_age_is_newer(COAP_ROLLOVER_AGE, COAP_MAX_AGE),
1908 "Max age should be marked as newer");
1909 }
1910
1911 struct test_coap_request {
1912 uint16_t id;
1913 uint8_t token[COAP_TOKEN_MAX_LEN];
1914 uint8_t tkl;
1915 uint8_t code;
1916 enum coap_msgtype type;
1917 struct coap_reply *match;
1918 };
1919
reply_cb(const struct coap_packet * response,struct coap_reply * reply,const struct net_sockaddr * from)1920 static int reply_cb(const struct coap_packet *response,
1921 struct coap_reply *reply,
1922 const struct net_sockaddr *from)
1923 {
1924 return 0;
1925 }
1926
ZTEST(coap,test_response_matching)1927 ZTEST(coap, test_response_matching)
1928 {
1929 struct coap_reply matches[] = {
1930 { }, /* Non-initialized (unused) entry. */
1931 { .id = 100, .reply = reply_cb },
1932 { .id = 101, .token = { 1, 2, 3, 4 }, .tkl = 4, .reply = reply_cb },
1933 };
1934 struct test_coap_request test_responses[] = {
1935 /* #0 Piggybacked ACK, empty token */
1936 { .id = 100, .type = COAP_TYPE_ACK, .match = &matches[1],
1937 .code = COAP_RESPONSE_CODE_CONTENT },
1938 /* #1 Piggybacked ACK, matching token */
1939 { .id = 101, .type = COAP_TYPE_ACK, .match = &matches[2],
1940 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 4 },
1941 .tkl = 4 },
1942 /* #2 Piggybacked ACK, token mismatch */
1943 { .id = 101, .type = COAP_TYPE_ACK, .match = NULL,
1944 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 3 },
1945 .tkl = 4 },
1946 /* #3 Piggybacked ACK, token mismatch 2 */
1947 { .id = 100, .type = COAP_TYPE_ACK, .match = NULL,
1948 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 4 },
1949 .tkl = 4 },
1950 /* #4 Piggybacked ACK, token mismatch 3 */
1951 { .id = 101, .type = COAP_TYPE_ACK, .match = NULL,
1952 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3 },
1953 .tkl = 3 },
1954 /* #5 Piggybacked ACK, token mismatch 4 */
1955 { .id = 101, .type = COAP_TYPE_ACK, .match = NULL,
1956 .code = COAP_RESPONSE_CODE_CONTENT },
1957 /* #6 Piggybacked ACK, id mismatch */
1958 { .id = 102, .type = COAP_TYPE_ACK, .match = NULL,
1959 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 4 },
1960 .tkl = 4 },
1961 /* #7 Separate reply, empty token */
1962 { .id = 101, .type = COAP_TYPE_CON, .match = &matches[1],
1963 .code = COAP_RESPONSE_CODE_CONTENT },
1964 /* #8 Separate reply, matching token 1 */
1965 { .id = 101, .type = COAP_TYPE_CON, .match = &matches[2],
1966 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 4 },
1967 .tkl = 4 },
1968 /* #9 Separate reply, matching token 2 */
1969 { .id = 102, .type = COAP_TYPE_CON, .match = &matches[2],
1970 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 4 },
1971 .tkl = 4 },
1972 /* #10 Separate reply, token mismatch */
1973 { .id = 101, .type = COAP_TYPE_CON, .match = NULL,
1974 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 3 },
1975 .tkl = 4 },
1976 /* #11 Separate reply, token mismatch 2 */
1977 { .id = 100, .type = COAP_TYPE_CON, .match = NULL,
1978 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3, 3 },
1979 .tkl = 4 },
1980 /* #12 Separate reply, token mismatch 3 */
1981 { .id = 100, .type = COAP_TYPE_CON, .match = NULL,
1982 .code = COAP_RESPONSE_CODE_CONTENT, .token = { 1, 2, 3 },
1983 .tkl = 3 },
1984 /* #13 Request, empty token */
1985 { .id = 100, .type = COAP_TYPE_CON, .match = NULL,
1986 .code = COAP_METHOD_GET },
1987 /* #14 Request, matching token */
1988 { .id = 101, .type = COAP_TYPE_CON, .match = NULL,
1989 .code = COAP_METHOD_GET, .token = { 1, 2, 3, 4 }, .tkl = 4 },
1990 /* #15 Empty ACK */
1991 { .id = 100, .type = COAP_TYPE_ACK, .match = NULL,
1992 .code = COAP_CODE_EMPTY },
1993 /* #16 Empty ACK 2 */
1994 { .id = 101, .type = COAP_TYPE_ACK, .match = NULL,
1995 .code = COAP_CODE_EMPTY },
1996 /* #17 Empty RESET */
1997 { .id = 100, .type = COAP_TYPE_RESET, .match = &matches[1],
1998 .code = COAP_CODE_EMPTY },
1999 /* #18 Empty RESET 2 */
2000 { .id = 101, .type = COAP_TYPE_RESET, .match = &matches[2],
2001 .code = COAP_CODE_EMPTY },
2002 /* #19 Empty RESET, id mismatch */
2003 { .id = 102, .type = COAP_TYPE_RESET, .match = NULL,
2004 .code = COAP_CODE_EMPTY },
2005 };
2006
2007 ARRAY_FOR_EACH_PTR(test_responses, response) {
2008 struct coap_packet response_pkt = { 0 };
2009 struct net_sockaddr from = { 0 };
2010 struct coap_reply *match;
2011 uint8_t data[64];
2012 int ret;
2013
2014 ret = coap_packet_init(&response_pkt, data, sizeof(data), COAP_VERSION_1,
2015 response->type, response->tkl, response->token,
2016 response->code, response->id);
2017 zassert_ok(ret, "Failed to initialize test packet: %d", ret);
2018
2019 match = coap_response_received(&response_pkt, &from, matches,
2020 ARRAY_SIZE(matches));
2021 if (response->match != NULL) {
2022 zassert_not_null(match, "Did not found a response match when expected");
2023 zassert_equal_ptr(response->match, match,
2024 "Wrong response match, test %d match %d",
2025 response - test_responses, match - matches);
2026 } else {
2027 zassert_is_null(match,
2028 "Found unexpected response match, test %d match %d",
2029 response - test_responses, match - matches);
2030 }
2031 }
2032 }
2033
2034 ZTEST_SUITE(coap, NULL, NULL, NULL, NULL, NULL);
2035