1 /* libcoap unit tests
2 *
3 * Copyright (C) 2012,2015,2022-2023 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
11 #include "test_common.h"
12 #include "test_pdu.h"
13
14 #include <assert.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 coap_pdu_t *pdu; /* Holds the parsed PDU for most tests */
20
21 /************************************************************************
22 ** PDU decoder
23 ************************************************************************/
24
25 static void
t_parse_pdu1(void)26 t_parse_pdu1(void) {
27 uint8_t teststr[] = { 0x40, 0x01, 0x93, 0x34 };
28 int result;
29
30 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
31 CU_ASSERT(result > 0);
32
33 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
34 CU_ASSERT(pdu->type == COAP_MESSAGE_CON);
35 CU_ASSERT(pdu->e_token_length == 0);
36 CU_ASSERT(pdu->code == COAP_REQUEST_CODE_GET);
37 CU_ASSERT(pdu->mid == 0x9334);
38 CU_ASSERT_PTR_NULL(pdu->data);
39 }
40
41 static void
t_parse_pdu2(void)42 t_parse_pdu2(void) {
43 uint8_t teststr[] = { 0x55, 0x69, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
44 int result;
45
46 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
47 CU_ASSERT(result > 0);
48
49 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
50 CU_ASSERT(pdu->type == COAP_MESSAGE_NON);
51 CU_ASSERT(pdu->e_token_length == 5);
52 CU_ASSERT(pdu->code == 0x69);
53 CU_ASSERT(pdu->mid == 0x1234);
54 CU_ASSERT(memcmp(pdu->token, teststr + 4, 5) == 0);
55 CU_ASSERT_PTR_NULL(pdu->data);
56 }
57
58 static void
t_parse_pdu3(void)59 t_parse_pdu3(void) {
60 uint8_t teststr[] = { 0x53, 0x69, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
61 int result;
62
63 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
64 CU_ASSERT(result == 0);
65 }
66
67 static void
t_parse_pdu4(void)68 t_parse_pdu4(void) {
69 /* illegal token length (token only 8 bytes) */
70 uint8_t teststr[] = { 0x59, 0x69, 0x12, 0x34,
71 't', 'o', 'k', 'e', 'n', '1', '2', '3'
72 };
73 int result;
74
75 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
76 CU_ASSERT(result == 0);
77
78 /* illegal token length */
79 teststr[0] = 0x5f;
80
81 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
82 CU_ASSERT(result == 0);
83 }
84
85 static void
t_parse_pdu5(void)86 t_parse_pdu5(void) {
87 /* PDU with options */
88 uint8_t teststr[] = { 0x55, 0x73, 0x12, 0x34, 't', 'o', 'k', 'e',
89 'n', 0x00, 0xc1, 0x00
90 };
91 int result;
92
93 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
94 CU_ASSERT(result > 0);
95
96 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
97 CU_ASSERT(pdu->type == COAP_MESSAGE_NON);
98 CU_ASSERT(pdu->e_token_length == 5);
99 CU_ASSERT(pdu->code == 0x73);
100 CU_ASSERT(pdu->mid == 0x1234);
101 CU_ASSERT(memcmp(pdu->token, teststr + 4, 5) == 0);
102 CU_ASSERT_PTR_NULL(pdu->data);
103
104 /* FIXME: check options */
105 }
106
107 static void
t_parse_pdu6(void)108 t_parse_pdu6(void) {
109 /* PDU with options that exceed the PDU */
110 uint8_t teststr[] = { 0x55, 0x73, 0x12, 0x34, 't', 'o', 'k', 'e',
111 'n', 0x00, 0xc1, 0x00, 0xae, 0xf0, 0x03
112 };
113 int result;
114
115 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
116 CU_ASSERT(result == 0);
117 }
118
119 static void
t_parse_pdu7(void)120 t_parse_pdu7(void) {
121 /* PDU with options and payload */
122 uint8_t teststr[] = { 0x55, 0x73, 0x12, 0x34, 't', 'o', 'k', 'e',
123 'n', 0x00, 0xc1, 0x00, 0xff, 'p', 'a', 'y',
124 'l', 'o', 'a', 'd'
125 };
126 int result;
127
128 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
129 CU_ASSERT(result > 0);
130
131 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
132 CU_ASSERT(pdu->type == COAP_MESSAGE_NON);
133 CU_ASSERT(pdu->e_token_length == 5);
134 CU_ASSERT(pdu->code == 0x73);
135 CU_ASSERT(pdu->mid == 0x1234);
136 CU_ASSERT(memcmp(pdu->token, teststr + 4, 5) == 0);
137
138 /* FIXME: check options */
139
140 CU_ASSERT(pdu->data == pdu->token + 9);
141 CU_ASSERT(memcmp(pdu->data, teststr + 13, 7) == 0);
142 }
143
144 static void
t_parse_pdu8(void)145 t_parse_pdu8(void) {
146 /* PDU without options but with payload */
147 uint8_t teststr[] = { 0x50, 0x73, 0x12, 0x34,
148 0xff, 'p', 'a', 'y', 'l', 'o', 'a',
149 'd'
150 };
151 int result;
152
153 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
154 CU_ASSERT(result > 0);
155
156 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
157 CU_ASSERT(pdu->type == COAP_MESSAGE_NON);
158 CU_ASSERT(pdu->e_token_length == 0);
159 CU_ASSERT(pdu->code == 0x73);
160 CU_ASSERT(pdu->mid == 0x1234);
161
162 /* FIXME: check options */
163
164 CU_ASSERT(pdu->data == pdu->token + 1);
165 CU_ASSERT(memcmp(pdu->data, teststr + 5, 7) == 0);
166 }
167
168 static void
t_parse_pdu9(void)169 t_parse_pdu9(void) {
170 /* PDU without options and payload but with payload start marker */
171 uint8_t teststr[] = { 0x70, 0x00, 0x12, 0x34, 0xff };
172 int result;
173
174 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
175 CU_ASSERT(result == 0);
176 }
177
178 static void
t_parse_pdu10(void)179 t_parse_pdu10(void) {
180 /* PDU without payload but with options and payload start marker */
181 uint8_t teststr[] = { 0x53, 0x73, 0x12, 0x34, 't', 'o', 'k',
182 0x31, 'a', 0xc1, 0x00, 0xff
183 };
184 int result;
185
186 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
187 CU_ASSERT(result == 0);
188 }
189
190 static void
t_parse_pdu11(void)191 t_parse_pdu11(void) {
192 uint8_t teststr[] = { 0x60, 0x00, 0x12, 0x34 };
193 int result;
194
195 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
196 CU_ASSERT(result > 0);
197
198 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
199 CU_ASSERT(pdu->type == COAP_MESSAGE_ACK);
200 CU_ASSERT(pdu->e_token_length == 0);
201 CU_ASSERT(pdu->code == 0);
202 CU_ASSERT(pdu->mid == 0x1234);
203 }
204
205 static void
t_parse_pdu12(void)206 t_parse_pdu12(void) {
207 /* RST */
208 uint8_t teststr[] = { 0x70, 0x00, 0x12, 0x34 };
209 int result;
210
211 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
212 CU_ASSERT(result > 0);
213
214 CU_ASSERT(pdu->used_size == sizeof(teststr) - 4);
215 CU_ASSERT(pdu->type == COAP_MESSAGE_RST);
216 CU_ASSERT(pdu->e_token_length == 0);
217 CU_ASSERT(pdu->code == 0);
218 CU_ASSERT(pdu->mid == 0x1234);
219 }
220
221 static void
t_parse_pdu13(void)222 t_parse_pdu13(void) {
223 /* RST with content */
224 uint8_t teststr[] = { 0x70, 0x00, 0x12, 0x34,
225 0xff, 'c', 'o', 'n', 't', 'e', 'n', 't'
226 };
227 int result;
228
229 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
230 CU_ASSERT(result == 0);
231 }
232
233 static void
t_parse_pdu14(void)234 t_parse_pdu14(void) {
235 /* ACK with content */
236 uint8_t teststr[] = { 0x60, 0x00, 0x12, 0x34,
237 0xff, 'c', 'o', 'n', 't', 'e', 'n', 't'
238 };
239 int result;
240
241 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
242 CU_ASSERT(result == 0);
243 }
244
245 /*
246 * To test Issue #199 which reads one byte past the end of teststr[]
247 * before fix to coap_opt_parse() as delta is two byte value and only
248 * one byte left
249 * Credit to OSS-Fuzz for finding this, work done by Bhargava Shastry
250 */
251 static void
t_parse_pdu15(void)252 t_parse_pdu15(void) {
253 int result;
254 uint8_t teststr[] = {
255 64, 91, 91, 91, 139, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0,
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 91, 224, 224, 224,
257 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
258 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 1, 0, 0, 0,
259 0, 0, 0, 0, 224, 192, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
260 224, 224, 224, 224, 224, 224, 224, 224, 228, 224, 224, 224, 224, 224, 224, 224,
261 224, 224, 224, 224, 224, 224, 224, 224, 224, 91, 91, 91, 91, 91, 91, 91,
262 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
263 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
264 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
265 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
266 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
267 91, 91, 91, 91, 91, 91, 91, 224, 224, 224, 224, 224, 224, 224, 224, 224,
268 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
269 224, 224, 224, 224, 224, 224, 1, 0, 0, 0, 0, 0, 0, 0, 224, 224,
270 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
271 224, 224, 224, 224, 224
272 };
273
274 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
275
276 CU_ASSERT(pdu->data == NULL);
277
278 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
279 CU_ASSERT(result == 0);
280 }
281
282 static void
log_handler(coap_log_t level, const char *message)283 log_handler(coap_log_t level, const char *message) {
284 (void)level;
285 (void)message;
286 }
287
288 /*
289 * To test Issue #214 which allows the token size to be set larger than the
290 * decoded PDU in coap_pdu_parse_header(). This then causes coap_show_pdu()
291 * to access invalid memory.
292 * Credit to OSS-Fuzz for finding this, work done by Bhargava Shastry
293 */
294 static void
t_parse_pdu16(void)295 t_parse_pdu16(void) {
296 int result;
297 coap_pdu_t *testpdu;
298 uint8_t teststr[] = { 0x5a, 0x0a, 0x5b, 0x5b };
299
300 testpdu = coap_pdu_init(0, 0, 0, sizeof(teststr));
301 CU_ASSERT(testpdu != NULL);
302
303 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), testpdu);
304 CU_ASSERT(result == 0);
305
306 coap_set_show_pdu_output(0);
307 coap_set_log_handler(log_handler);
308 coap_show_pdu(COAP_LOG_ERR, testpdu); /* display PDU */
309 coap_set_log_handler(NULL);
310
311 coap_delete_pdu(testpdu);
312 }
313
314 static void
t_parse_pdu17(void)315 t_parse_pdu17(void) {
316 uint8_t teststr[512] = { 0x40, 0x01, 0x93, 0x34 };
317 size_t idx;
318 int result;
319
320 /* 245 * option delta 268 > 65535, causing a overflow in the option
321 * number */
322 for (idx = 4; idx < sizeof(teststr) - 4; idx += 2) {
323 teststr[idx] = 0xd0; /* 1 byte option delta follows */
324 teststr[idx + 1] = 0xff; /* option delta 268 */
325 }
326
327 result = coap_pdu_parse(COAP_PROTO_UDP, teststr, sizeof(teststr), pdu);
328 CU_ASSERT(result == 0);
329 }
330
331 /************************************************************************
332 ** PDU encoder
333 ************************************************************************/
334
335 static void
t_encode_pdu1(void)336 t_encode_pdu1(void) {
337 uint8_t teststr[] = { 0x45, 0x01, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
338 int result;
339
340 coap_pdu_clear(pdu, pdu->max_size);
341 pdu->type = COAP_MESSAGE_CON;
342 pdu->code = COAP_REQUEST_CODE_GET;
343 pdu->mid = 0x1234;
344
345 result = coap_add_token(pdu, 5, (const uint8_t *)"token");
346
347 CU_ASSERT(result == 1);
348 CU_ASSERT(pdu->used_size == 5);
349 CU_ASSERT_PTR_NULL(pdu->data);
350 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
351 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
352 }
353
354 static void
t_encode_pdu2(void)355 t_encode_pdu2(void) {
356 coap_log_t level = coap_get_log_level();
357 size_t old_max = pdu->max_size;
358 int result;
359
360 coap_pdu_clear(pdu, 3); /* set very small PDU size */
361
362 pdu->type = COAP_MESSAGE_CON;
363 pdu->code = COAP_REQUEST_CODE_GET;
364 pdu->mid = 0x1234;
365
366 coap_set_log_level(COAP_LOG_CRIT);
367 result = coap_add_token(pdu, 5, (const uint8_t *)"token");
368 coap_set_log_level(level);
369
370 CU_ASSERT(result == 0);
371
372 coap_pdu_clear(pdu, old_max); /* restore PDU size */
373 }
374
375 static void
t_encode_pdu3(void)376 t_encode_pdu3(void) {
377 int result;
378 coap_bin_const_t check_token;
379
380 result = coap_add_token(pdu, 15, (const uint8_t *)"123456789012345");
381
382 /* length of 15 triggers extension */
383 CU_ASSERT(result == 1 && pdu->actual_token.length == 15 &&
384 pdu->e_token_length == 16 && pdu->token[0] == 2);
385
386 check_token = coap_pdu_get_token(pdu);
387 CU_ASSERT(check_token.length == 15);
388 }
389
390 static void
t_encode_pdu4(void)391 t_encode_pdu4(void) {
392 /* PDU with options */
393 uint8_t teststr[] = { 0x60, 0x99, 0x12, 0x34, 0x3d, 0x05, 0x66, 0x61,
394 0x6e, 0x63, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79,
395 0x2e, 0x63, 0x6f, 0x61, 0x70, 0x2e, 0x6d, 0x65,
396 0x84, 0x70, 0x61, 0x74, 0x68, 0x00, 0xe8, 0x1e,
397 0x28, 0x66, 0x61, 0x6e, 0x63, 0x79, 0x6f, 0x70,
398 0x74
399 };
400 int result;
401
402 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
403
404 pdu->type = COAP_MESSAGE_ACK;
405 pdu->code = 0x99;
406 pdu->mid = 0x1234;
407
408 CU_ASSERT(pdu->used_size == 0);
409
410 result = coap_add_option(pdu, COAP_OPTION_URI_HOST,
411 18, (const uint8_t *)"fancyproxy.coap.me");
412
413 CU_ASSERT(result == 20);
414 CU_ASSERT(pdu->max_opt == 3);
415 CU_ASSERT(pdu->used_size == 20);
416 CU_ASSERT_PTR_NULL(pdu->data);
417
418 result = coap_add_option(pdu, COAP_OPTION_URI_PATH,
419 4, (const uint8_t *)"path");
420
421 CU_ASSERT(result == 5);
422 CU_ASSERT(pdu->max_opt == 11);
423 CU_ASSERT(pdu->used_size == 25);
424 CU_ASSERT_PTR_NULL(pdu->data);
425
426 result = coap_add_option(pdu, COAP_OPTION_URI_PATH, 0, NULL);
427
428 CU_ASSERT(result == 1);
429 CU_ASSERT(pdu->max_opt == 11);
430 CU_ASSERT(pdu->used_size == 26);
431 CU_ASSERT_PTR_NULL(pdu->data);
432
433 result = coap_add_option(pdu, 8000, 8, (const uint8_t *)"fancyopt");
434
435 CU_ASSERT(result == 11);
436 CU_ASSERT(pdu->max_opt == 8000);
437 CU_ASSERT(pdu->used_size == 37);
438 CU_ASSERT_PTR_NULL(pdu->data);
439
440 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
441 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
442 }
443
444 static void
t_encode_pdu5(void)445 t_encode_pdu5(void) {
446 /* PDU with token and options */
447 uint8_t teststr[] = { 0x68, 0x84, 0x12, 0x34, '1', '2', '3', '4',
448 '5', '6', '7', '8', 0x18, 0x41, 0x42, 0x43,
449 0x44, 0x45, 0x46, 0x47, 0x48, 0xd1, 0x03, 0x12
450 };
451 int result;
452
453 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
454
455 pdu->type = COAP_MESSAGE_ACK;
456 pdu->code = COAP_RESPONSE_CODE(404);
457 pdu->mid = 0x1234;
458
459 CU_ASSERT(pdu->used_size == 0);
460
461 result = coap_add_token(pdu, 8, (const uint8_t *)"12345678");
462
463 CU_ASSERT(pdu->used_size == 8);
464
465 result = coap_add_option(pdu, COAP_OPTION_IF_MATCH,
466 8, (const uint8_t *)"ABCDEFGH");
467
468 CU_ASSERT(result == 9);
469 CU_ASSERT(pdu->max_opt == 1);
470 CU_ASSERT(pdu->used_size == 17);
471 CU_ASSERT_PTR_NULL(pdu->data);
472
473 result = coap_add_option(pdu, COAP_OPTION_ACCEPT,
474 1, (const uint8_t *)"\x12");
475
476 CU_ASSERT(result == 3);
477 CU_ASSERT(pdu->max_opt == 17);
478 CU_ASSERT(pdu->used_size == 20);
479 CU_ASSERT_PTR_NULL(pdu->data);
480
481 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
482 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
483 }
484
485 static void
t_encode_pdu6(void)486 t_encode_pdu6(void) {
487 /* PDU with data */
488 uint8_t teststr[] = { 0x50, 0x02, 0x12, 0x34, 0xff, '1', '2', '3',
489 '4', '5', '6', '7', '8'
490 };
491 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
492
493 pdu->type = COAP_MESSAGE_NON;
494 pdu->code = COAP_REQUEST_CODE_POST;
495 pdu->mid = 0x1234;
496
497 CU_ASSERT(pdu->used_size == 0);
498 CU_ASSERT_PTR_NULL(pdu->data);
499
500 coap_add_data(pdu, 8, (const uint8_t *)"12345678");
501
502 CU_ASSERT(pdu->used_size == 9);
503 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
504 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
505 }
506
507 static void
t_encode_pdu7(void)508 t_encode_pdu7(void) {
509 /* PDU with empty data */
510 uint8_t teststr[] = { 0x40, 0x43, 0x12, 0x34 };
511 int result;
512 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
513
514 pdu->type = COAP_MESSAGE_CON;
515 pdu->code = COAP_RESPONSE_CODE(203);
516 pdu->mid = 0x1234;
517
518 CU_ASSERT(pdu->used_size == 0);
519
520 result = coap_add_data(pdu, 0, NULL);
521
522 CU_ASSERT(result > 0);
523 CU_ASSERT(pdu->used_size == 0);
524 CU_ASSERT_PTR_NULL(pdu->data);
525
526 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
527 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
528 }
529
530 static void
t_encode_pdu8(void)531 t_encode_pdu8(void) {
532 /* PDU with token and data */
533 uint8_t teststr[] = { 0x42, 0x43, 0x12, 0x34, 0x00, 0x01, 0xff, 0x00 };
534 int result;
535 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
536
537 pdu->type = COAP_MESSAGE_CON;
538 pdu->code = COAP_RESPONSE_CODE(203);
539 pdu->mid = 0x1234;
540
541 CU_ASSERT(pdu->used_size == 0);
542
543 result = coap_add_token(pdu, 2, (const uint8_t *)"\x00\x01");
544
545 CU_ASSERT(result > 0);
546
547 result = coap_add_data(pdu, 1, (const uint8_t *)"\0");
548
549 CU_ASSERT(result > 0);
550 CU_ASSERT(pdu->used_size == 4);
551 CU_ASSERT(pdu->data == pdu->token + 3);
552
553 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
554 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
555 }
556
557 static void
t_encode_pdu9(void)558 t_encode_pdu9(void) {
559 /* PDU with options and data */
560 uint8_t teststr[] = { 0x60, 0x44, 0x12, 0x34, 0x48, 's', 'o', 'm',
561 'e', 'e', 't', 'a', 'g', 0x10, 0xdd, 0x11,
562 0x04, 's', 'o', 'm', 'e', 'r', 'a', 't',
563 'h', 'e', 'r', 'l', 'o', 'n', 'g', 'u',
564 'r', 'i', 0xff, 'd', 'a', 't', 'a'
565 };
566 int result;
567
568 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
569
570 pdu->type = COAP_MESSAGE_ACK;
571 pdu->code = COAP_RESPONSE_CODE(204);
572 pdu->mid = 0x1234;
573
574 CU_ASSERT(pdu->used_size == 0);
575
576 result = coap_add_option(pdu, COAP_OPTION_ETAG, 8, (const uint8_t *)"someetag");
577
578 CU_ASSERT(result == 9);
579 CU_ASSERT(pdu->max_opt == 4);
580 CU_ASSERT(pdu->used_size == 9);
581 CU_ASSERT_PTR_NULL(pdu->data);
582
583 result = coap_add_option(pdu, COAP_OPTION_IF_NONE_MATCH, 0, NULL);
584
585 CU_ASSERT(result == 1);
586 CU_ASSERT(pdu->max_opt == 5);
587 CU_ASSERT(pdu->used_size == 10);
588 CU_ASSERT_PTR_NULL(pdu->data);
589
590 result = coap_add_option(pdu, COAP_OPTION_PROXY_URI,
591 17, (const uint8_t *)"someratherlonguri");
592
593 CU_ASSERT(result == 20);
594 CU_ASSERT(pdu->max_opt == 35);
595 CU_ASSERT(pdu->used_size == 30);
596 CU_ASSERT_PTR_NULL(pdu->data);
597
598 result = coap_add_data(pdu, 4, (const uint8_t *)"data");
599
600 CU_ASSERT(result > 0);
601 CU_ASSERT(pdu->used_size == 35);
602 CU_ASSERT(pdu->data == pdu->token + 31);
603
604 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
605 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
606 }
607
608 static void
t_encode_pdu10(void)609 t_encode_pdu10(void) {
610 /* PDU with token, options and data */
611 uint8_t teststr[] = { 0x62, 0x44, 0x12, 0x34, 0x00, 0x00, 0x8d, 0xf2,
612 'c', 'o', 'a', 'p', ':', '/', '/', 'e',
613 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c',
614 'o', 'm', '/', '1', '2', '3', '4', '5',
615 '/', '%', '3', 'F', 'x', 'y', 'z', '/',
616 '3', '0', '4', '8', '2', '3', '4', '2',
617 '3', '4', '/', '2', '3', '4', '0', '2',
618 '3', '4', '8', '2', '3', '4', '/', '2',
619 '3', '9', '0', '8', '4', '2', '3', '4',
620 '-', '2', '3', '/', '%', 'A', 'B', '%',
621 '3', '0', '%', 'a', 'f', '/', '+', '1',
622 '2', '3', '/', 'h', 'f', 'k', 's', 'd',
623 'h', '/', '2', '3', '4', '8', '0', '-',
624 '2', '3', '4', '-', '9', '8', '2', '3',
625 '5', '/', '1', '2', '0', '4', '/', '2',
626 '4', '3', '5', '4', '6', '3', '4', '5',
627 '3', '4', '5', '2', '4', '3', '/', '0',
628 '1', '9', '8', 's', 'd', 'n', '3', '-',
629 'a', '-', '3', '/', '/', '/', 'a', 'f',
630 'f', '0', '9', '3', '4', '/', '9', '7',
631 'u', '2', '1', '4', '1', '/', '0', '0',
632 '0', '2', '/', '3', '9', '3', '2', '4',
633 '2', '3', '5', '3', '2', '/', '5', '6',
634 '2', '3', '4', '0', '2', '3', '/', '-',
635 '-', '-', '-', '/', '=', '1', '2', '3',
636 '4', '=', '/', '0', '9', '8', '1', '4',
637 '1', '-', '9', '5', '6', '4', '6', '4',
638 '3', '/', '2', '1', '9', '7', '0', '-',
639 '-', '-', '-', '-', '/', '8', '2', '3',
640 '6', '4', '9', '2', '3', '4', '7', '2',
641 'w', 'e', 'r', 'e', 'r', 'e', 'w', 'r',
642 '0', '-', '9', '2', '1', '-', '3', '9',
643 '1', '2', '3', '-', '3', '4', '/', 0x0d,
644 0x01, '/', '/', '4', '9', '2', '4', '0',
645 '3', '-', '-', '0', '9', '8', '/', 0xc1,
646 '*', 0xff, 'd', 'a', 't', 'a'
647 };
648 int result;
649
650 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
651
652 pdu->type = COAP_MESSAGE_ACK;
653 pdu->code = COAP_RESPONSE_CODE(204);
654 pdu->mid = 0x1234;
655
656 CU_ASSERT(pdu->used_size == 0);
657
658 result = coap_add_token(pdu, 2, (const uint8_t *)"\0\0");
659
660 CU_ASSERT(result > 0);
661 result = coap_add_option(pdu, COAP_OPTION_LOCATION_PATH, 255,
662 (const uint8_t *)
663 "coap://example.com/12345/%3Fxyz/3048234234/23402348234/239084234-23/%AB%30%af/+123/hfksdh/23480-234-98235/1204/243546345345243/0198sdn3-a-3///aff0934/97u2141/0002/3932423532/56234023/----/=1234=/098141-9564643/21970-----/82364923472wererewr0-921-39123-34/");
664
665 CU_ASSERT(result == 257);
666 CU_ASSERT(pdu->max_opt == 8);
667 CU_ASSERT(pdu->used_size == 259);
668 CU_ASSERT_PTR_NULL(pdu->data);
669
670 result = coap_add_option(pdu, COAP_OPTION_LOCATION_PATH, 14,
671 (const uint8_t *)"//492403--098/");
672
673 CU_ASSERT(result == 16);
674 CU_ASSERT(pdu->max_opt == 8);
675 CU_ASSERT(pdu->used_size == 275);
676 CU_ASSERT_PTR_NULL(pdu->data);
677
678 result = coap_add_option(pdu, COAP_OPTION_LOCATION_QUERY,
679 1, (const uint8_t *)"*");
680
681 CU_ASSERT(result == 2);
682 CU_ASSERT(pdu->max_opt == 20);
683 CU_ASSERT(pdu->used_size == 277);
684 CU_ASSERT_PTR_NULL(pdu->data);
685
686 result = coap_add_data(pdu, 4, (const uint8_t *)"data");
687
688 CU_ASSERT(result > 0);
689 CU_ASSERT(pdu->used_size == 282);
690 CU_ASSERT(pdu->data == pdu->token + 278);
691
692 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
693 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
694 }
695
696 static void
t_encode_pdu11(void)697 t_encode_pdu11(void) {
698 coap_log_t level = coap_get_log_level();
699 /* data too long for PDU */
700 size_t old_max = pdu->max_size;
701 int result;
702
703 coap_pdu_clear(pdu, 8); /* clear PDU, with small maximum */
704
705 CU_ASSERT(pdu->data == NULL);
706 coap_set_log_level(COAP_LOG_CRIT);
707 result = coap_add_data(pdu, 10, (const uint8_t *)"0123456789");
708 coap_set_log_level(level);
709
710 CU_ASSERT(result == 0);
711 CU_ASSERT(pdu->data == NULL);
712 CU_ASSERT(pdu->used_size == 0);
713
714 pdu->max_size = old_max;
715 }
716
717 static void
t_encode_pdu12(void)718 t_encode_pdu12(void) {
719 coap_optlist_t *optlist = NULL;
720 int n;
721 uint8_t opt_num[] = { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
722 uint8_t opt_val[] = { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
723 uint8_t opt_srt[] = { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
724 coap_opt_iterator_t oi;
725 coap_opt_t *option;
726
727 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
728
729 CU_ASSERT(pdu->data == NULL);
730
731 for (n = 0; n < (int)sizeof(opt_num); n++) {
732 coap_insert_optlist(&optlist, coap_new_optlist(opt_num[n],
733 sizeof(opt_val[n]), &opt_val[n]));
734 }
735 coap_add_optlist_pdu(pdu, &optlist);
736
737 /* Check options in pdu are in right order */
738 coap_option_iterator_init(pdu, &oi, COAP_OPT_ALL);
739 for (n = 0; n < (int)sizeof(opt_num); n++) {
740 option = coap_option_next(&oi);
741 CU_ASSERT(oi.bad == 0);
742 CU_ASSERT(option != NULL);
743 CU_ASSERT(coap_opt_length(option) == 1);
744 CU_ASSERT(*coap_opt_value(option) == opt_srt[n]);
745 }
746 option = coap_option_next(&oi);
747 CU_ASSERT(oi.bad == 1);
748 CU_ASSERT(option == NULL);
749 coap_delete_optlist(optlist);
750 }
751
752 static void
t_encode_pdu13(void)753 t_encode_pdu13(void) {
754 coap_optlist_t *optlist = NULL;
755 int n;
756 uint8_t opt_num[] = { 59, 58, 57, 56, 55, 54, 53, 52, 51, 50 };
757 uint8_t opt_val[] = { 59, 58, 57, 56, 55, 54, 53, 52, 51, 50 };
758 uint8_t opt_srt[] = { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
759 coap_opt_iterator_t oi;
760 coap_opt_t *option;
761
762 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
763
764 CU_ASSERT(pdu->data == NULL);
765
766 for (n = 0; n < (int)sizeof(opt_num); n++) {
767 coap_insert_optlist(&optlist, coap_new_optlist(opt_num[n],
768 sizeof(opt_val[n]), &opt_val[n]));
769 }
770 coap_add_optlist_pdu(pdu, &optlist);
771
772 /* Check options in pdu are in right order */
773 coap_option_iterator_init(pdu, &oi, COAP_OPT_ALL);
774 for (n = 0; n < (int)sizeof(opt_num); n++) {
775 option = coap_option_next(&oi);
776 CU_ASSERT(oi.bad == 0);
777 CU_ASSERT(option != NULL);
778 CU_ASSERT(coap_opt_length(option) == 1);
779 CU_ASSERT(*coap_opt_value(option) == opt_srt[n]);
780 }
781 option = coap_option_next(&oi);
782 CU_ASSERT(oi.bad == 1);
783 CU_ASSERT(option == NULL);
784 coap_delete_optlist(optlist);
785 }
786
787 static void
t_encode_pdu14(void)788 t_encode_pdu14(void) {
789 coap_optlist_t *optlist = NULL;
790 int n;
791 uint8_t opt_num[] = { 53, 52, 51, 50, 51, 52, 52, 51, 50, 50 };
792 uint8_t opt_val[] = { 59, 56, 53, 50, 54, 57, 58, 55, 51, 52 };
793 uint8_t opt_srt[] = { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
794 coap_opt_iterator_t oi;
795 coap_opt_t *option;
796
797 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
798
799 CU_ASSERT(pdu->data == NULL);
800
801 for (n = 0; n < (int)sizeof(opt_num); n++) {
802 coap_insert_optlist(&optlist, coap_new_optlist(opt_num[n],
803 sizeof(opt_val[n]), &opt_val[n]));
804 }
805 coap_add_optlist_pdu(pdu, &optlist);
806
807 /* Check options in pdu are in right order */
808 coap_option_iterator_init(pdu, &oi, COAP_OPT_ALL);
809 for (n = 0; n < (int)sizeof(opt_num); n++) {
810 option = coap_option_next(&oi);
811 CU_ASSERT(oi.bad == 0);
812 CU_ASSERT(option != NULL);
813 CU_ASSERT(coap_opt_length(option) == 1);
814 CU_ASSERT(*coap_opt_value(option) == opt_srt[n]);
815 }
816 option = coap_option_next(&oi);
817 CU_ASSERT(oi.bad == 1);
818 CU_ASSERT(option == NULL);
819 coap_delete_optlist(optlist);
820 }
821
822 /* Check inserting options with random types get put into the PDU in the
823 right order */
824 static void
t_encode_pdu15(void)825 t_encode_pdu15(void) {
826 size_t n;
827 uint16_t opt_num[] = { 300, 13, 10, 7, 11, 268, 269, 12, 8, 9 };
828 uint8_t opt_val[] = { 59, 56, 53, 50, 54, 57, 58, 55, 51, 52 };
829 uint8_t opt_srt[] = { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 };
830 coap_opt_iterator_t oi;
831 coap_opt_t *option;
832
833 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
834
835 CU_ASSERT(pdu->data == NULL);
836
837 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
838 coap_insert_option(pdu, opt_num[n],
839 sizeof(opt_val[n]), &opt_val[n]);
840 }
841
842 /* Check options in pdu are in right order */
843 coap_option_iterator_init(pdu, &oi, COAP_OPT_ALL);
844 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
845 option = coap_option_next(&oi);
846 CU_ASSERT(oi.bad == 0);
847 CU_ASSERT(option != NULL);
848 CU_ASSERT(coap_opt_length(option) == 1);
849 CU_ASSERT(*coap_opt_value(option) == opt_srt[n]);
850 }
851 option = coap_option_next(&oi);
852 CU_ASSERT(oi.bad == 1);
853 CU_ASSERT(option == NULL);
854 }
855
856 /* Check changing value of options works */
857 static void
t_encode_pdu16(void)858 t_encode_pdu16(void) {
859 size_t n;
860 uint16_t opt_num[] = { 300, 10, 7 };
861 uint8_t opt_val[] = { 53, 51, 50 };
862 uint8_t data[] = { 'd', 'a', 't', 'a' };
863 uint8_t data1[] = { 0x71, 0x32, 0x31, 0x33, 0xe1, 0x00, 0x15, 0x35,
864 0xff, 0x64, 0x61, 0x74, 0x61
865 };
866 uint8_t data2[] = { 0x71, 0x32, 0x33, 0x01, 0x23, 0x45, 0xe1, 0x00,
867 0x15, 0x35, 0xff, 0x64, 0x61, 0x74, 0x61
868 };
869 uint8_t data3[] = { 0x70, 0x31, 0x33, 0xe1, 0x00, 0x15, 0x35, 0xff,
870 0x64, 0x61, 0x74, 0x61
871 };
872 uint8_t data4[] = { 0x71, 0x32, 0x31, 0x33, 0xe4, 0x00, 0x15, 0x06,
873 0x54, 0x32, 0x10, 0xff, 0x64, 0x61, 0x74, 0x61
874 };
875 int new_val;
876 unsigned char buf[4];
877
878 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
879
880 CU_ASSERT(pdu->data == NULL);
881
882 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
883 coap_add_option(pdu, opt_num[n],
884 sizeof(opt_val[n]), &opt_val[n]);
885 }
886 coap_add_data(pdu, sizeof(data), data);
887 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
888 /* Now update an option in the middle */
889 new_val = 0x12345;
890 coap_update_option(pdu, 10,
891 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
892 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
893 /* Shrink it back again */
894 new_val = 51;
895 coap_update_option(pdu, 10,
896 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
897 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
898 /* Now update an option at the start */
899 new_val = 0;
900 coap_update_option(pdu, 7,
901 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
902 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
903 /* put it back again */
904 new_val = 50;
905 coap_update_option(pdu, 7,
906 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
907 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
908 /* Now update an option at the end */
909 new_val = 0x6543210;
910 coap_update_option(pdu, 300,
911 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
912 CU_ASSERT(memcmp(pdu->token, data4, pdu->used_size) == 0);
913 /* put it back again */
914 new_val = 53;
915 coap_update_option(pdu, 300,
916 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
917 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
918 }
919
920 /* Same as t_encode_pdu16, but without any data, but with a token */
921 static void
t_encode_pdu17(void)922 t_encode_pdu17(void) {
923 size_t n;
924 uint8_t token[] = { 't' };
925 uint16_t opt_num[] = { 300, 10, 7 };
926 uint8_t opt_val[] = { 53, 51, 50 };
927 uint8_t data1[] = { 0x74, 0x71, 0x32, 0x31, 0x33, 0xe1, 0x00, 0x15,
928 0x35
929 };
930 uint8_t data2[] = { 0x74, 0x71, 0x32, 0x33, 0x01, 0x23, 0x45, 0xe1,
931 0x00, 0x15, 0x35
932 };
933 uint8_t data3[] = { 0x74, 0x70, 0x31, 0x33, 0xe1, 0x00, 0x15, 0x35 };
934 uint8_t data4[] = { 0x74, 0x71, 0x32, 0x31, 0x33, 0xe4, 0x00, 0x15,
935 0x06, 0x54, 0x32, 0x10
936 };
937 int new_val;
938 unsigned char buf[4];
939
940 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
941
942 CU_ASSERT(pdu->data == NULL);
943
944 coap_add_token(pdu, sizeof(token), token);
945 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
946 coap_add_option(pdu, opt_num[n],
947 sizeof(opt_val[n]), &opt_val[n]);
948 }
949 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
950 /* Now update an option in the middle */
951 new_val = 0x12345;
952 coap_update_option(pdu, 10,
953 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
954 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
955 /* Shrink it back again */
956 new_val = 51;
957 coap_update_option(pdu, 10,
958 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
959 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
960 /* Now update an option at the start */
961 new_val = 0;
962 coap_update_option(pdu, 7,
963 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
964 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
965 /* put it back again */
966 new_val = 50;
967 coap_update_option(pdu, 7,
968 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
969 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
970 /* Now update an option at the end */
971 new_val = 0x6543210;
972 coap_update_option(pdu, 300,
973 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
974 CU_ASSERT(memcmp(pdu->token, data4, pdu->used_size) == 0);
975 /* put it back again */
976 new_val = 53;
977 coap_update_option(pdu, 300,
978 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
979 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
980 }
981
982 static void
t_encode_pdu18(void)983 t_encode_pdu18(void) {
984 /* PDU with token, options and data */
985 uint8_t teststr[] = { 0x62, 0x44, 0x12, 0x34, 0x00, 0x00, 0x8d, 0xf2,
986 'c', 'o', 'a', 'p', ':', '/', '/', 'e',
987 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c',
988 'o', 'm', '/', '1', '2', '3', '4', '5',
989 '/', '%', '3', 'F', 'x', 'y', 'z', '/',
990 '3', '0', '4', '8', '2', '3', '4', '2',
991 '3', '4', '/', '2', '3', '4', '0', '2',
992 '3', '4', '8', '2', '3', '4', '/', '2',
993 '3', '9', '0', '8', '4', '2', '3', '4',
994 '-', '2', '3', '/', '%', 'A', 'B', '%',
995 '3', '0', '%', 'a', 'f', '/', '+', '1',
996 '2', '3', '/', 'h', 'f', 'k', 's', 'd',
997 'h', '/', '2', '3', '4', '8', '0', '-',
998 '2', '3', '4', '-', '9', '8', '2', '3',
999 '5', '/', '1', '2', '0', '4', '/', '2',
1000 '4', '3', '5', '4', '6', '3', '4', '5',
1001 '3', '4', '5', '2', '4', '3', '/', '0',
1002 '1', '9', '8', 's', 'd', 'n', '3', '-',
1003 'a', '-', '3', '/', '/', '/', 'a', 'f',
1004 'f', '0', '9', '3', '4', '/', '9', '7',
1005 'u', '2', '1', '4', '1', '/', '0', '0',
1006 '0', '2', '/', '3', '9', '3', '2', '4',
1007 '2', '3', '5', '3', '2', '/', '5', '6',
1008 '2', '3', '4', '0', '2', '3', '/', '-',
1009 '-', '-', '-', '/', '=', '1', '2', '3',
1010 '4', '=', '/', '0', '9', '8', '1', '4',
1011 '1', '-', '9', '5', '6', '4', '6', '4',
1012 '3', '/', '2', '1', '9', '7', '0', '-',
1013 '-', '-', '-', '-', '/', '8', '2', '3',
1014 '6', '4', '9', '2', '3', '4', '7', '2',
1015 'w', 'e', 'r', 'e', 'r', 'e', 'w', 'r',
1016 '0', '-', '9', '2', '1', '-', '3', '9',
1017 '1', '2', '3', '-', '3', '4', '/', 0x0d,
1018 0x01, '/', '/', '4', '9', '2', '4', '0',
1019 '3', '-', '-', '0', '9', '8', '/', 0xc1,
1020 '*', 0xff, 'd', 'a', 't', 'a'
1021 };
1022 int result;
1023
1024 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1025
1026 pdu->type = COAP_MESSAGE_ACK;
1027 pdu->code = COAP_RESPONSE_CODE(204);
1028 pdu->mid = 0x1234;
1029
1030 CU_ASSERT(pdu->used_size == 0);
1031
1032 result = coap_add_token(pdu, 2, (const uint8_t *)"\0\0");
1033
1034 CU_ASSERT(result > 0);
1035 result = coap_add_option(pdu, COAP_OPTION_LOCATION_PATH, 255,
1036 (const uint8_t *)
1037 "coap://example.com/12345/%3Fxyz/3048234234/23402348234/239084234-23/%AB%30%af/+123/hfksdh/23480-234-98235/1204/243546345345243/0198sdn3-a-3///aff0934/97u2141/0002/3932423532/56234023/----/=1234=/098141-9564643/21970-----/82364923472wererewr0-921-39123-34/");
1038
1039 CU_ASSERT(result == 257);
1040 CU_ASSERT(pdu->max_opt == 8);
1041 CU_ASSERT(pdu->used_size == 259);
1042 CU_ASSERT_PTR_NULL(pdu->data);
1043
1044 result = coap_add_option(pdu, COAP_OPTION_LOCATION_QUERY,
1045 1, (const uint8_t *)"*");
1046
1047 CU_ASSERT(result == 2);
1048 CU_ASSERT(pdu->used_size == 261);
1049 CU_ASSERT_PTR_NULL(pdu->data);
1050
1051 result = coap_insert_option(pdu, COAP_OPTION_LOCATION_PATH, 14,
1052 (const uint8_t *)"//492403--098/");
1053
1054 CU_ASSERT(result == 16);
1055 CU_ASSERT(pdu->used_size == 277);
1056 CU_ASSERT_PTR_NULL(pdu->data);
1057
1058 result = coap_add_data(pdu, 4, (const uint8_t *)"data");
1059
1060 CU_ASSERT(result > 0);
1061 CU_ASSERT(pdu->used_size == 282);
1062 CU_ASSERT(pdu->data == pdu->token + 278);
1063
1064 CU_ASSERT(coap_pdu_encode_header(pdu, COAP_PROTO_UDP) == 4);
1065 CU_ASSERT(memcmp(pdu->token - 4, teststr, sizeof(teststr)) == 0);
1066
1067 }
1068
1069 /* Remove an option (no data) */
1070 /*
1071 * Next Delta New Delta
1072 * 4 18
1073 * 18 25
1074 */
1075 static void
t_encode_pdu19(void)1076 t_encode_pdu19(void) {
1077 size_t n;
1078 uint8_t token[] = { 't' };
1079 uint16_t opt_num[] = { 300, 7, 21, 25 };
1080 uint8_t opt_val[] = { 54, 50, 52, 53 };
1081 uint8_t data1[] = { 0x74, 0x71, 0x32, 0xd1, 0x01, 0x34, 0x41, 0x35,
1082 0xe1, 0x00, 0x06, 0x36
1083 };
1084 uint8_t data2[] = { 0x74, 0x71, 0x32, 0xd1, 0x05, 0x35, 0xe1, 0x00,
1085 0x06, 0x36
1086 };
1087 uint8_t data3[] = { 0x74, 0xd1, 0x0c, 0x35, 0xe1, 0x00, 0x06, 0x36 };
1088 uint8_t data4[] = { 0x74, 0xd1, 0x0c, 0x35 };
1089 uint8_t data5[] = { 0x74 };
1090 uint8_t data6[] = { 0x74, 0xd1, 0x0c, 0x0a };
1091 int new_val;
1092 unsigned char buf[4];
1093
1094 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1095
1096 CU_ASSERT(pdu->data == NULL);
1097
1098 coap_add_token(pdu, sizeof(token), token);
1099 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
1100 coap_add_option(pdu, opt_num[n],
1101 sizeof(opt_val[n]), &opt_val[n]);
1102 }
1103 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
1104
1105 /* Now remove an option in the middle */
1106 coap_remove_option(pdu, 21);
1107 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
1108
1109 /* Now remove an option from the start */
1110 coap_remove_option(pdu, 7);
1111 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
1112
1113 /* Now remove an option from the end */
1114 coap_remove_option(pdu, 300);
1115 CU_ASSERT(memcmp(pdu->token, data4, pdu->used_size) == 0);
1116
1117 /* Now remove the final option */
1118 coap_remove_option(pdu, 25);
1119 CU_ASSERT(memcmp(pdu->token, data5, pdu->used_size) == 0);
1120
1121 /* Now insert an option */
1122 new_val = 10;
1123 coap_update_option(pdu, 25,
1124 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
1125 CU_ASSERT(memcmp(pdu->token, data6, pdu->used_size) == 0);
1126 }
1127
1128 /* Remove an option (no data), but exercise delta boundaries (13 and 269) */
1129 /*
1130 * Next Delta New Delta
1131 * 11 12 if (opt_delta < 13) {
1132 * 1 13 } else if (opt_delta < 269 && decode_next.delta < 13) {
1133 * 254 268 } else if (opt_delta < 269) {
1134 * 1 269 } else if (decode_next.delta < 13) { // opt_delta >= 269
1135 * 71 350 } else if (decode_next.delta < 269) { // opt_delta >= 269
1136 * 320 670 } else { // decode_next.delta >= 269 && opt_delta >= 269
1137 */
1138 static void
t_encode_pdu20(void)1139 t_encode_pdu20(void) {
1140 size_t n;
1141 uint8_t token[] = { 't' };
1142 uint16_t opt_num[] = { 1, 12, 13, 268, 269, 350, 670 };
1143 uint8_t opt_val[] = { 50, 51, 52, 53, 54, 55, 56 };
1144 uint8_t data1[] = { 0x74, 0x11, 0x32, 0xb1, 0x33, 0x11, 0x34, 0xd1,
1145 0xf2, 0x35, 0x11, 0x36, 0xd1, 0x44, 0x37, 0xe1,
1146 0x00, 0x33, 0x38
1147 };
1148 uint8_t data2[] = { 0x74, 0xc1, 0x33, 0x11, 0x34, 0xd1, 0xf2, 0x35,
1149 0x11, 0x36, 0xd1, 0x44, 0x37, 0xe1, 0x00, 0x33,
1150 0x38
1151 };
1152 uint8_t data3[] = { 0x74, 0xd1, 0x00, 0x34, 0xd1, 0xf2, 0x35, 0x11,
1153 0x36, 0xd1, 0x44, 0x37, 0xe1, 0x00, 0x33, 0x38
1154 };
1155 uint8_t data4[] = { 0x74, 0xd1, 0xff, 0x35, 0x11, 0x36, 0xd1, 0x44,
1156 0x37, 0xe1, 0x00, 0x33, 0x38
1157 };
1158 uint8_t data5[] = { 0x74, 0xe1, 0x00, 0x00, 0x36, 0xd1, 0x44, 0x37,
1159 0xe1, 0x00, 0x33, 0x38
1160 };
1161 uint8_t data6[] = { 0x74, 0xe1, 0x00, 0x51, 0x37, 0xe1, 0x00, 0x33,
1162 0x38
1163 };
1164 uint8_t data7[] = { 0x74, 0xe1, 0x01, 0x91, 0x38 };
1165 uint8_t data8[] = { 0x74 };
1166
1167 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1168
1169 CU_ASSERT(pdu->data == NULL);
1170
1171 coap_add_token(pdu, sizeof(token), token);
1172 /* Put the options in in reverse order to test that logic */
1173 for (n = sizeof(opt_num)/sizeof(opt_num[0]); n > 0; n--) {
1174 coap_insert_option(pdu, opt_num[n-1],
1175 sizeof(opt_val[n-1]), &opt_val[n-1]);
1176 }
1177 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
1178
1179 /* Now remove an option from the start */
1180 coap_remove_option(pdu, 1);
1181 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
1182
1183 /* Now remove an option from the start */
1184 coap_remove_option(pdu, 12);
1185 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
1186
1187 /* Now remove an option from the start */
1188 coap_remove_option(pdu, 13);
1189 CU_ASSERT(memcmp(pdu->token, data4, pdu->used_size) == 0);
1190
1191 /* Now remove an option from the start */
1192 coap_remove_option(pdu, 268);
1193 CU_ASSERT(memcmp(pdu->token, data5, pdu->used_size) == 0);
1194
1195 /* Now remove an option from the start */
1196 coap_remove_option(pdu, 269);
1197 CU_ASSERT(memcmp(pdu->token, data6, pdu->used_size) == 0);
1198
1199 /* Now remove an option from the start */
1200 coap_remove_option(pdu, 350);
1201 CU_ASSERT(memcmp(pdu->token, data7, pdu->used_size) == 0);
1202
1203 /* Now remove the final option */
1204 coap_remove_option(pdu, 670);
1205 CU_ASSERT(memcmp(pdu->token, data8, pdu->used_size) == 0);
1206 }
1207
1208 /* Remove an option (with data) */
1209 /*
1210 * Next Delta New Delta
1211 * 4 18
1212 * 18 25
1213 */
1214 static void
t_encode_pdu21(void)1215 t_encode_pdu21(void) {
1216 size_t n;
1217 uint8_t token[] = { 't' };
1218 uint16_t opt_num[] = { 300, 7, 21, 25 };
1219 uint8_t opt_val[] = { 54, 50, 52, 53 };
1220 uint8_t data[] = { 'd', 'a', 't', 'a' };
1221 uint8_t data1[] = { 0x74, 0x71, 0x32, 0xd1, 0x01, 0x34, 0x41, 0x35,
1222 0xe1, 0x00, 0x06, 0x36, 0xff, 0x64, 0x61, 0x74,
1223 0x61
1224 };
1225 uint8_t data2[] = { 0x74, 0x71, 0x32, 0xd1, 0x05, 0x35, 0xe1, 0x00,
1226 0x06, 0x36, 0xff, 0x64, 0x61, 0x74, 0x61
1227 };
1228 uint8_t data3[] = { 0x74, 0xd1, 0x0c, 0x35, 0xe1, 0x00, 0x06, 0x36,
1229 0xff, 0x64, 0x61, 0x74, 0x61
1230 };
1231 uint8_t data4[] = { 0x74, 0xd1, 0x0c, 0x35, 0xff, 0x64, 0x61, 0x74,
1232 0x61
1233 };
1234 uint8_t data5[] = { 0x74, 0xff, 0x64, 0x61, 0x74, 0x61 };
1235 uint8_t data6[] = { 0x74, 0xd1, 0x0c, 0x0a, 0xff, 0x64, 0x61, 0x74,
1236 0x61
1237 };
1238 int new_val;
1239 unsigned char buf[4];
1240
1241 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1242
1243 CU_ASSERT(pdu->data == NULL);
1244
1245 coap_add_token(pdu, sizeof(token), token);
1246 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
1247 coap_add_option(pdu, opt_num[n],
1248 sizeof(opt_val[n]), &opt_val[n]);
1249 }
1250 coap_add_data(pdu, sizeof(data), data);
1251 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
1252
1253 /* Now remove an option in the middle */
1254 coap_remove_option(pdu, 21);
1255 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
1256
1257 /* Now remove an option from the start */
1258 coap_remove_option(pdu, 7);
1259 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
1260
1261 /* Now remove an option from the end */
1262 coap_remove_option(pdu, 300);
1263 CU_ASSERT(memcmp(pdu->token, data4, pdu->used_size) == 0);
1264
1265 /* Now remove the final option */
1266 coap_remove_option(pdu, 25);
1267 CU_ASSERT(memcmp(pdu->token, data5, pdu->used_size) == 0);
1268
1269 /* Now insert an option */
1270 new_val = 10;
1271 coap_update_option(pdu, 25,
1272 coap_encode_var_safe(buf, sizeof(buf), new_val), buf);
1273 CU_ASSERT(memcmp(pdu->token, data6, pdu->used_size) == 0);
1274 }
1275
1276 /* Remove an option (with data), but exercise delta boundaries (13 and 269) */
1277 /*
1278 * Next Delta New Delta
1279 * 11 12 if (opt_delta < 13) {
1280 * 1 13 } else if (opt_delta < 269 && decode_next.delta < 13) {
1281 * 254 268 } else if (opt_delta < 269) {
1282 * 1 269 } else if (decode_next.delta < 13) { // opt_delta >= 269
1283 * 71 350 } else if (decode_next.delta < 269) { // opt_delta >= 269
1284 * 320 670 } else { // decode_next.delta >= 269 && opt_delta >= 269
1285 */
1286 static void
t_encode_pdu22(void)1287 t_encode_pdu22(void) {
1288 size_t n;
1289 uint8_t token[] = { 't' };
1290 uint16_t opt_num[] = { 1, 12, 13, 268, 269, 350, 670 };
1291 uint8_t opt_val[] = { 50, 51, 52, 53, 54, 55, 56 };
1292 uint8_t data[] = { 'd', 'a', 't', 'a' };
1293 uint8_t data1[] = { 0x74, 0x11, 0x32, 0xb1, 0x33, 0x11, 0x34, 0xd1,
1294 0xf2, 0x35, 0x11, 0x36, 0xd1, 0x44, 0x37, 0xe1,
1295 0x00, 0x33, 0x38, 0xff, 0x64, 0x61, 0x74, 0x61
1296 };
1297 uint8_t data2[] = { 0x74, 0xc1, 0x33, 0x11, 0x34, 0xd1, 0xf2, 0x35,
1298 0x11, 0x36, 0xd1, 0x44, 0x37, 0xe1, 0x00, 0x33,
1299 0x38, 0xff, 0x64, 0x61, 0x74, 0x61
1300 };
1301 uint8_t data3[] = { 0x74, 0xd1, 0x00, 0x34, 0xd1, 0xf2, 0x35, 0x11,
1302 0x36, 0xd1, 0x44, 0x37, 0xe1, 0x00, 0x33, 0x38,
1303 0xff, 0x64, 0x61, 0x74, 0x61
1304 };
1305 uint8_t data4[] = { 0x74, 0xd1, 0xff, 0x35, 0x11, 0x36, 0xd1, 0x44,
1306 0x37, 0xe1, 0x00, 0x33, 0x38, 0xff, 0x64, 0x61,
1307 0x74, 0x61
1308 };
1309 uint8_t data5[] = { 0x74, 0xe1, 0x00, 0x00, 0x36, 0xd1, 0x44, 0x37,
1310 0xe1, 0x00, 0x33, 0x38, 0xff, 0x64, 0x61, 0x74,
1311 0x61
1312 };
1313 uint8_t data6[] = { 0x74, 0xe1, 0x00, 0x51, 0x37, 0xe1, 0x00, 0x33,
1314 0x38, 0xff, 0x64, 0x61, 0x74, 0x61
1315 };
1316 uint8_t data7[] = { 0x74, 0xe1, 0x01, 0x91, 0x38, 0xff, 0x64, 0x61,
1317 0x74, 0x61
1318 };
1319 uint8_t data8[] = { 0x74, 0xff, 0x64, 0x61, 0x74, 0x61 };
1320
1321 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1322
1323 CU_ASSERT(pdu->data == NULL);
1324
1325 coap_add_token(pdu, sizeof(token), token);
1326
1327 coap_add_data(pdu, sizeof(data), data);
1328
1329 /* Put the options in in reverse order to test that logic */
1330 for (n = sizeof(opt_num)/sizeof(opt_num[0]); n > 0; n--) {
1331 coap_insert_option(pdu, opt_num[n-1],
1332 sizeof(opt_val[n-1]), &opt_val[n-1]);
1333 }
1334 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
1335
1336 /* Now remove an option from the start */
1337 coap_remove_option(pdu, 1);
1338 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
1339
1340 /* Now remove an option from the start */
1341 coap_remove_option(pdu, 12);
1342 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
1343
1344 /* Now remove an option from the start */
1345 coap_remove_option(pdu, 13);
1346 CU_ASSERT(memcmp(pdu->token, data4, pdu->used_size) == 0);
1347
1348 /* Now remove an option from the start */
1349 coap_remove_option(pdu, 268);
1350 CU_ASSERT(memcmp(pdu->token, data5, pdu->used_size) == 0);
1351
1352 /* Now remove an option from the start */
1353 coap_remove_option(pdu, 269);
1354 CU_ASSERT(memcmp(pdu->token, data6, pdu->used_size) == 0);
1355
1356 /* Now remove an option from the start */
1357 coap_remove_option(pdu, 350);
1358 CU_ASSERT(memcmp(pdu->token, data7, pdu->used_size) == 0);
1359
1360 /* Now remove the final option */
1361 coap_remove_option(pdu, 670);
1362 CU_ASSERT(memcmp(pdu->token, data8, pdu->used_size) == 0);
1363 }
1364
1365
1366 /* Update token */
1367 static void
t_encode_pdu23(void)1368 t_encode_pdu23(void) {
1369 size_t n;
1370 uint8_t token[] = { 't' };
1371 uint8_t new_token[] = { 't', 'o', 'k', 'e', 'n' };
1372 uint16_t opt_num[] = { 300, 10, 7, 21, 25 };
1373 uint8_t opt_val[] = { 54, 51, 50, 52, 53 };
1374 uint8_t data[] = { 'd', 'a', 't', 'a' };
1375 uint8_t data1[] = { 0x74, 0x71, 0x32, 0x31, 0x33, 0xb1, 0x34, 0x41,
1376 0x35, 0xe1, 0x00, 0x06, 0x36, 0xff, 0x64, 0x61,
1377 0x74, 0x61
1378 };
1379 uint8_t data2[] = { 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x71, 0x32, 0x31,
1380 0x33, 0xb1, 0x34, 0x41, 0x35, 0xe1, 0x00, 0x06,
1381 0x36, 0xff, 0x64, 0x61, 0x74, 0x61
1382 };
1383 uint8_t data3[] = { 0x71, 0x32, 0x31, 0x33, 0xb1, 0x34, 0x41, 0x35,
1384 0xe1, 0x00, 0x06, 0x36, 0xff, 0x64, 0x61, 0x74,
1385 0x61
1386 };
1387
1388 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1389
1390 CU_ASSERT(pdu->data == NULL);
1391
1392 coap_add_token(pdu, sizeof(token), token);
1393 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
1394 coap_add_option(pdu, opt_num[n],
1395 sizeof(opt_val[n]), &opt_val[n]);
1396 }
1397 coap_add_data(pdu, sizeof(data), data);
1398 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
1399
1400 /* Now update token */
1401 coap_update_token(pdu, sizeof(new_token), new_token);
1402 CU_ASSERT(memcmp(pdu->token, data2, pdu->used_size) == 0);
1403
1404 /* Now restore token */
1405 coap_update_token(pdu, sizeof(token), token);
1406 CU_ASSERT(memcmp(pdu->token, data1, pdu->used_size) == 0);
1407
1408 /* Now set token to zero length */
1409 coap_update_token(pdu, 0, NULL);
1410 CU_ASSERT(memcmp(pdu->token, data3, pdu->used_size) == 0);
1411 }
1412
1413 /* insert option before (large) final one */
1414 static void
t_encode_pdu24(void)1415 t_encode_pdu24(void) {
1416 size_t n;
1417 uint8_t token[] = { 't' };
1418 uint8_t buf[4];
1419 uint16_t opt_num[] = { 28, 28, 28, 28 };
1420 uint32_t opt_val[] = { 0x1, 0x100, 0x10000, 0x1000000 };
1421 uint8_t data1[][8] = {
1422 { 0x74, 0xd1, 0x0f, 0x01 },
1423 { 0x74, 0xd2, 0x0f, 0x01, 0x00 },
1424 { 0x74, 0xd3, 0x0f, 0x01, 0x00, 0x00 },
1425 { 0x74, 0xd4, 0x0f, 0x01, 0x00, 0x00, 0x00 }
1426 };
1427 uint8_t data2[][16] = {
1428 { 0x74, 0xd3, 0x0a, 0xff, 0xff, 0xf6, 0x51, 0x01 },
1429 {
1430 0x74, 0xd3, 0x0a, 0xff, 0xff, 0xf6, 0x52, 0x01,
1431 0x00
1432 },
1433 {
1434 0x74, 0xd3, 0x0a, 0xff, 0xff, 0xf6, 0x53, 0x01,
1435 0x00, 0x00
1436 },
1437 {
1438 0x74, 0xd3, 0x0a, 0xff, 0xff, 0xf6, 0x54, 0x01,
1439 0x00, 0x00, 0x00
1440 }
1441 };
1442
1443 for (n = 0; n < (sizeof(opt_num)/sizeof(opt_num[0])); n++) {
1444 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
1445
1446 CU_ASSERT(pdu->data == NULL);
1447
1448 coap_add_token(pdu, sizeof(token), token);
1449 coap_add_option(pdu, opt_num[n],
1450 coap_encode_var_safe(buf, sizeof(buf), opt_val[n]), buf);
1451 CU_ASSERT(memcmp(pdu->token, data1[n], pdu->used_size) == 0);
1452
1453 /* Now insert option */
1454 coap_insert_option(pdu, 23,
1455 coap_encode_var_safe(buf, sizeof(buf), 0xfffff6), buf);
1456 CU_ASSERT(memcmp(pdu->token, data2[n], pdu->used_size) == 0);
1457 }
1458 }
1459
1460 static int
t_pdu_tests_create(void)1461 t_pdu_tests_create(void) {
1462 pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
1463
1464 return pdu == NULL;
1465 }
1466
1467 static int
t_pdu_tests_remove(void)1468 t_pdu_tests_remove(void) {
1469 coap_delete_pdu(pdu);
1470 return 0;
1471 }
1472
1473 CU_pSuite
t_init_pdu_tests(void)1474 t_init_pdu_tests(void) {
1475 CU_pSuite suite[2];
1476
1477 suite[0] = CU_add_suite("pdu parser", t_pdu_tests_create, t_pdu_tests_remove);
1478 if (!suite[0]) { /* signal error */
1479 fprintf(stderr, "W: cannot add pdu parser test suite (%s)\n",
1480 CU_get_error_msg());
1481
1482 return NULL;
1483 }
1484
1485 #define PDU_TEST(s,t) \
1486 if (!CU_ADD_TEST(s,t)) { \
1487 fprintf(stderr, "W: cannot add pdu parser test (%s)\n", \
1488 CU_get_error_msg()); \
1489 }
1490
1491 PDU_TEST(suite[0], t_parse_pdu1);
1492 PDU_TEST(suite[0], t_parse_pdu2);
1493 PDU_TEST(suite[0], t_parse_pdu3);
1494 PDU_TEST(suite[0], t_parse_pdu4);
1495 PDU_TEST(suite[0], t_parse_pdu5);
1496 PDU_TEST(suite[0], t_parse_pdu6);
1497 PDU_TEST(suite[0], t_parse_pdu7);
1498 PDU_TEST(suite[0], t_parse_pdu8);
1499 PDU_TEST(suite[0], t_parse_pdu9);
1500 PDU_TEST(suite[0], t_parse_pdu10);
1501 PDU_TEST(suite[0], t_parse_pdu11);
1502 PDU_TEST(suite[0], t_parse_pdu12);
1503 PDU_TEST(suite[0], t_parse_pdu13);
1504 PDU_TEST(suite[0], t_parse_pdu14);
1505 PDU_TEST(suite[0], t_parse_pdu15);
1506 PDU_TEST(suite[0], t_parse_pdu16);
1507 PDU_TEST(suite[0], t_parse_pdu17);
1508
1509 suite[1] = CU_add_suite("pdu encoder", t_pdu_tests_create, t_pdu_tests_remove);
1510 if (suite[1]) {
1511 #define PDU_ENCODER_TEST(s,t) \
1512 if (!CU_ADD_TEST(s,t)) { \
1513 fprintf(stderr, "W: cannot add pdu encoder test (%s)\n", \
1514 CU_get_error_msg()); \
1515 }
1516 PDU_ENCODER_TEST(suite[1], t_encode_pdu1);
1517 PDU_ENCODER_TEST(suite[1], t_encode_pdu2);
1518 PDU_ENCODER_TEST(suite[1], t_encode_pdu3);
1519 PDU_ENCODER_TEST(suite[1], t_encode_pdu4);
1520 PDU_ENCODER_TEST(suite[1], t_encode_pdu5);
1521 PDU_ENCODER_TEST(suite[1], t_encode_pdu6);
1522 PDU_ENCODER_TEST(suite[1], t_encode_pdu7);
1523 PDU_ENCODER_TEST(suite[1], t_encode_pdu8);
1524 PDU_ENCODER_TEST(suite[1], t_encode_pdu9);
1525 PDU_ENCODER_TEST(suite[1], t_encode_pdu10);
1526 PDU_ENCODER_TEST(suite[1], t_encode_pdu11);
1527 PDU_ENCODER_TEST(suite[1], t_encode_pdu12);
1528 PDU_ENCODER_TEST(suite[1], t_encode_pdu13);
1529 PDU_ENCODER_TEST(suite[1], t_encode_pdu14);
1530 PDU_ENCODER_TEST(suite[1], t_encode_pdu15);
1531 PDU_ENCODER_TEST(suite[1], t_encode_pdu16);
1532 PDU_ENCODER_TEST(suite[1], t_encode_pdu17);
1533 PDU_ENCODER_TEST(suite[1], t_encode_pdu18);
1534 PDU_ENCODER_TEST(suite[1], t_encode_pdu19);
1535 PDU_ENCODER_TEST(suite[1], t_encode_pdu20);
1536 PDU_ENCODER_TEST(suite[1], t_encode_pdu21);
1537 PDU_ENCODER_TEST(suite[1], t_encode_pdu22);
1538 PDU_ENCODER_TEST(suite[1], t_encode_pdu23);
1539 PDU_ENCODER_TEST(suite[1], t_encode_pdu24);
1540
1541 } else /* signal error */
1542 fprintf(stderr, "W: cannot add pdu parser test suite (%s)\n",
1543 CU_get_error_msg());
1544
1545 return suite[0];
1546 }
1547