1 /* libcoap unit tests
2  *
3  * Copyright (C) 2012,2015 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * This file is part of the CoAP library libcoap. Please see
6  * README for terms of use.
7  */
8 
9 #include "coap_config.h"
10 #include "test_pdu.h"
11 
12 #include <coap.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((unsigned char *)teststr, sizeof(teststr), pdu);
31   CU_ASSERT(result > 0);
32 
33   CU_ASSERT(pdu->length == sizeof(teststr));
34   CU_ASSERT(pdu->hdr->version == 1);
35   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_CON);
36   CU_ASSERT(pdu->hdr->token_length == 0);
37   CU_ASSERT(pdu->hdr->code == COAP_REQUEST_GET);
38   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
39   CU_ASSERT_PTR_NULL(pdu->data);
40 }
41 
42 static void
t_parse_pdu2(void)43 t_parse_pdu2(void) {
44   uint8_t teststr[] = {  0x55, 0x69, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
45   int result;
46 
47   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
48   CU_ASSERT(result > 0);
49 
50   CU_ASSERT(pdu->length == sizeof(teststr));
51   CU_ASSERT(pdu->hdr->version == 1);
52   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_NON);
53   CU_ASSERT(pdu->hdr->token_length == 5);
54   CU_ASSERT(pdu->hdr->code == 0x69);
55   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
56   CU_ASSERT(memcmp(pdu->hdr->token, teststr + 4, 5) == 0);
57   CU_ASSERT_PTR_NULL(pdu->data);
58 }
59 
60 static void
t_parse_pdu3(void)61 t_parse_pdu3(void) {
62   uint8_t teststr[] = {  0x53, 0x69, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
63   int result;
64 
65   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
66   CU_ASSERT(result == 0);
67 }
68 
69 static void
t_parse_pdu4(void)70 t_parse_pdu4(void) {
71   /* illegal token length */
72   uint8_t teststr[] = {  0x59, 0x69, 0x12, 0x34,
73 		      't', 'o', 'k', 'e', 'n', '1', '2', '3', '4' };
74   int result;
75 
76   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
77   CU_ASSERT(result == 0);
78 
79   teststr[0] = 0x5f;
80 
81   result = coap_pdu_parse((unsigned char *)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((unsigned char *)teststr, sizeof(teststr), pdu);
94   CU_ASSERT(result > 0);
95 
96   CU_ASSERT(pdu->length == sizeof(teststr));
97   CU_ASSERT(pdu->hdr->version == 1);
98   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_NON);
99   CU_ASSERT(pdu->hdr->token_length == 5);
100   CU_ASSERT(pdu->hdr->code == 0x73);
101   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
102   CU_ASSERT(memcmp(pdu->hdr->token, teststr + 4, 5) == 0);
103   CU_ASSERT_PTR_NULL(pdu->data);
104 
105   /* FIXME: check options */
106 }
107 
108 static void
t_parse_pdu6(void)109 t_parse_pdu6(void) {
110   /* PDU with options that exceed the PDU */
111   uint8_t teststr[] = {  0x55, 0x73, 0x12, 0x34, 't', 'o', 'k', 'e',
112 		      'n',  0x00, 0xc1, 0x00, 0xae, 0xf0, 0x03
113   };
114   int result;
115 
116   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
117   CU_ASSERT(result == 0);
118 }
119 
120 static void
t_parse_pdu7(void)121 t_parse_pdu7(void) {
122   /* PDU with options and payload */
123   uint8_t teststr[] = {  0x55, 0x73, 0x12, 0x34, 't', 'o', 'k', 'e',
124 		      'n',  0x00, 0xc1, 0x00, 0xff, 'p', 'a', 'y',
125 		      'l', 'o', 'a', 'd'
126   };
127   int result;
128 
129   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
130   CU_ASSERT(result > 0);
131 
132   CU_ASSERT(pdu->length == sizeof(teststr));
133   CU_ASSERT(pdu->hdr->version == 1);
134   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_NON);
135   CU_ASSERT(pdu->hdr->token_length == 5);
136   CU_ASSERT(pdu->hdr->code == 0x73);
137   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
138   CU_ASSERT(memcmp(pdu->hdr->token, teststr + 4, 5) == 0);
139 
140   /* FIXME: check options */
141 
142   CU_ASSERT(pdu->data == (unsigned char *)pdu->hdr + 13);
143   CU_ASSERT(memcmp(pdu->data, teststr + 13, 7) == 0);
144 }
145 
146 static void
t_parse_pdu8(void)147 t_parse_pdu8(void) {
148   /* PDU without options but with payload */
149   uint8_t teststr[] = {  0x50, 0x73, 0x12, 0x34,
150 		      0xff, 'p', 'a', 'y', 'l', 'o', 'a',
151 		      'd'
152   };
153   int result;
154 
155   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
156   CU_ASSERT(result > 0);
157 
158   CU_ASSERT(pdu->length == sizeof(teststr));
159   CU_ASSERT(pdu->hdr->version == 1);
160   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_NON);
161   CU_ASSERT(pdu->hdr->token_length == 0);
162   CU_ASSERT(pdu->hdr->code == 0x73);
163   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
164 
165   /* FIXME: check options */
166 
167   CU_ASSERT(pdu->data == (unsigned char *)pdu->hdr + 5);
168   CU_ASSERT(memcmp(pdu->data, teststr + 5, 7) == 0);
169 }
170 
171 static void
t_parse_pdu9(void)172 t_parse_pdu9(void) {
173   /* PDU without options and payload but with payload start marker */
174   uint8_t teststr[] = {  0x70, 0x00, 0x12, 0x34, 0xff };
175   int result;
176 
177   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
178   CU_ASSERT(result == 0);
179 }
180 
181 static void
t_parse_pdu10(void)182 t_parse_pdu10(void) {
183   /* PDU without payload but with options and payload start marker */
184   uint8_t teststr[] = {  0x53, 0x73, 0x12, 0x34, 't', 'o', 'k',
185 		      0x30, 0xc1, 0x00, 0xff
186   };
187   int result;
188 
189   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
190   CU_ASSERT(result == 0);
191 }
192 
193 static void
t_parse_pdu11(void)194 t_parse_pdu11(void) {
195   uint8_t teststr[] = {  0x60, 0x00, 0x12, 0x34 };
196   int result;
197 
198   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
199   CU_ASSERT(result > 0);
200 
201   CU_ASSERT(pdu->length == sizeof(teststr));
202   CU_ASSERT(pdu->hdr->version == 1);
203   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_ACK);
204   CU_ASSERT(pdu->hdr->token_length == 0);
205   CU_ASSERT(pdu->hdr->code == 0);
206   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
207 }
208 
209 static void
t_parse_pdu12(void)210 t_parse_pdu12(void) {
211   /* RST */
212   uint8_t teststr[] = {  0x70, 0x00, 0x12, 0x34 };
213   int result;
214 
215   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
216   CU_ASSERT(result > 0);
217 
218   CU_ASSERT(pdu->length == sizeof(teststr));
219   CU_ASSERT(pdu->hdr->version == 1);
220   CU_ASSERT(pdu->hdr->type == COAP_MESSAGE_RST);
221   CU_ASSERT(pdu->hdr->token_length == 0);
222   CU_ASSERT(pdu->hdr->code == 0);
223   CU_ASSERT(memcmp(&pdu->hdr->id, teststr + 2, 2) == 0);
224 }
225 
226 static void
t_parse_pdu13(void)227 t_parse_pdu13(void) {
228   /* RST with content */
229   uint8_t teststr[] = {  0x70, 0x00, 0x12, 0x34,
230 		      0xff, 'c', 'o', 'n', 't', 'e', 'n', 't'
231   };
232   int result;
233 
234   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
235   CU_ASSERT(result == 0);
236 }
237 
238 static void
t_parse_pdu14(void)239 t_parse_pdu14(void) {
240   /* ACK with content */
241   uint8_t teststr[] = {  0x60, 0x00, 0x12, 0x34,
242 		      0xff, 'c', 'o', 'n', 't', 'e', 'n', 't'
243   };
244   int result;
245 
246   result = coap_pdu_parse((unsigned char *)teststr, sizeof(teststr), pdu);
247   CU_ASSERT(result == 0);
248 }
249 
250 /************************************************************************
251  ** PDU encoder
252  ************************************************************************/
253 
254 static void
t_encode_pdu1(void)255 t_encode_pdu1(void) {
256   uint8_t teststr[] = { 0x45, 0x01, 0x12, 0x34, 't', 'o', 'k', 'e', 'n' };
257   int result;
258 
259   coap_pdu_clear(pdu, pdu->max_size);
260   pdu->hdr->type = COAP_MESSAGE_CON;
261   pdu->hdr->code = COAP_REQUEST_GET;
262   pdu->hdr->id = htons(0x1234);
263 
264   result = coap_add_token(pdu, 5, (unsigned char *)"token");
265 
266   CU_ASSERT(result == 1);
267   CU_ASSERT(pdu->length = sizeof(teststr));
268   CU_ASSERT_PTR_NULL(pdu->data);
269   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
270 }
271 
272 static void
t_encode_pdu2(void)273 t_encode_pdu2(void) {
274   size_t old_max = pdu->max_size;
275   int result;
276 
277   coap_pdu_clear(pdu, 7);	/* set very small PDU size */
278 
279   pdu->hdr->type = COAP_MESSAGE_CON;
280   pdu->hdr->code = COAP_REQUEST_GET;
281   pdu->hdr->id = htons(0x1234);
282 
283   result = coap_add_token(pdu, 5, (unsigned char *)"token");
284 
285   CU_ASSERT(result == 0);
286 
287   coap_pdu_clear(pdu, old_max);	/* restore PDU size */
288 }
289 
290 static void
t_encode_pdu3(void)291 t_encode_pdu3(void) {
292   int result;
293 
294   result = coap_add_token(pdu, 9, (unsigned char *)"123456789");
295 
296   CU_ASSERT(result == 0);
297 }
298 
299 static void
t_encode_pdu4(void)300 t_encode_pdu4(void) {
301   /* PDU with options */
302   uint8_t teststr[] = { 0x60, 0x99, 0x12, 0x34, 0x3d, 0x05, 0x66, 0x61,
303 		     0x6e, 0x63, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79,
304 		     0x2e, 0x63, 0x6f, 0x61, 0x70, 0x2e, 0x6d, 0x65,
305 		     0x84, 0x70, 0x61, 0x74, 0x68, 0x00, 0xe8, 0x1e,
306 		     0x28, 0x66, 0x61, 0x6e, 0x63, 0x79, 0x6f, 0x70,
307 		     0x74
308   };
309   int result;
310 
311   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
312 
313   pdu->hdr->type = COAP_MESSAGE_ACK;
314   pdu->hdr->code = 0x99;
315   pdu->hdr->id = htons(0x1234);
316 
317   CU_ASSERT(pdu->length == 4);
318 
319   result = coap_add_option(pdu, COAP_OPTION_URI_HOST,
320        18, (unsigned char *)"fancyproxy.coap.me");
321 
322   CU_ASSERT(result == 20);
323   CU_ASSERT(pdu->max_delta == 3);
324   CU_ASSERT(pdu->length == 24);
325   CU_ASSERT_PTR_NULL(pdu->data);
326 
327   result = coap_add_option(pdu, COAP_OPTION_URI_PATH,
328 			   4, (unsigned char *)"path");
329 
330   CU_ASSERT(result == 5);
331   CU_ASSERT(pdu->max_delta == 11);
332   CU_ASSERT(pdu->length == 29);
333   CU_ASSERT_PTR_NULL(pdu->data);
334 
335   result = coap_add_option(pdu, COAP_OPTION_URI_PATH, 0, NULL);
336 
337   CU_ASSERT(result == 1);
338   CU_ASSERT(pdu->max_delta == 11);
339   CU_ASSERT(pdu->length == 30);
340   CU_ASSERT_PTR_NULL(pdu->data);
341 
342   result = coap_add_option(pdu, 8000, 8, (unsigned char *)"fancyopt");
343 
344   CU_ASSERT(result == 11);
345   CU_ASSERT(pdu->max_delta == 8000);
346   CU_ASSERT(pdu->length == 41);
347   CU_ASSERT_PTR_NULL(pdu->data);
348 
349   CU_ASSERT(pdu->length == sizeof(teststr));
350   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
351 }
352 
353 static void
t_encode_pdu5(void)354 t_encode_pdu5(void) {
355   /* PDU with token and options */
356   uint8_t teststr[] = { 0x68, 0x84, 0x12, 0x34, '1',  '2',  '3',  '4',
357                      '5',  '6',  '7',  '8',  0x18, 0x41, 0x42, 0x43,
358 		     0x44, 0x45, 0x46, 0x47, 0x48, 0xd1, 0x03, 0x12
359   };
360   int result;
361 
362   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
363 
364   pdu->hdr->type = COAP_MESSAGE_ACK;
365   pdu->hdr->code = COAP_RESPONSE_CODE(404);
366   pdu->hdr->id = htons(0x1234);
367 
368   CU_ASSERT(pdu->length == 4);
369 
370   result = coap_add_token(pdu, 8, (unsigned char *)"12345678");
371 
372   CU_ASSERT(pdu->length == 12);
373 
374   result = coap_add_option(pdu, COAP_OPTION_IF_MATCH,
375 			   8, (unsigned char *)"ABCDEFGH");
376 
377   CU_ASSERT(result == 9);
378   CU_ASSERT(pdu->max_delta == 1);
379   CU_ASSERT(pdu->length == 21);
380   CU_ASSERT_PTR_NULL(pdu->data);
381 
382   result = coap_add_option(pdu, COAP_OPTION_ACCEPT,
383 			   1, (unsigned char *)"\x12");
384 
385   CU_ASSERT(result == 3);
386   CU_ASSERT(pdu->max_delta == 17);
387   CU_ASSERT(pdu->length == 24);
388   CU_ASSERT_PTR_NULL(pdu->data);
389 
390   CU_ASSERT(pdu->length == sizeof(teststr));
391   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
392 }
393 
394 static void
t_encode_pdu6(void)395 t_encode_pdu6(void) {
396   /* PDU with data */
397   uint8_t teststr[] = { 0x50, 0x02, 0x12, 0x34, 0xff, '1',  '2',  '3',
398 		     '4', '5',  '6',  '7',  '8'
399   };
400   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
401 
402   pdu->hdr->type = COAP_MESSAGE_NON;
403   pdu->hdr->code = COAP_REQUEST_POST;
404   pdu->hdr->id = htons(0x1234);
405 
406   CU_ASSERT(pdu->length == 4);
407   CU_ASSERT_PTR_NULL(pdu->data);
408 
409   coap_add_data(pdu, 8, (unsigned char *)"12345678");
410 
411   CU_ASSERT(pdu->length == sizeof(teststr));
412   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
413 }
414 
415 static void
t_encode_pdu7(void)416 t_encode_pdu7(void) {
417   /* PDU with empty data */
418   uint8_t teststr[] = { 0x40, 0x43, 0x12, 0x34 };
419   int result;
420   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
421 
422   pdu->hdr->type = COAP_MESSAGE_CON;
423   pdu->hdr->code = COAP_RESPONSE_CODE(203);
424   pdu->hdr->id = htons(0x1234);
425 
426   CU_ASSERT(pdu->length == 4);
427 
428   result = coap_add_data(pdu, 0, NULL);
429 
430   CU_ASSERT(result > 0);
431   CU_ASSERT(pdu->length == 4);
432   CU_ASSERT_PTR_NULL(pdu->data);
433 
434   CU_ASSERT(pdu->length == sizeof(teststr));
435   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
436 }
437 
438 static void
t_encode_pdu8(void)439 t_encode_pdu8(void) {
440   /* PDU with token and data */
441   uint8_t teststr[] = { 0x42, 0x43, 0x12, 0x34, 0x00, 0x01, 0xff, 0x00 };
442   int result;
443   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
444 
445   pdu->hdr->type = COAP_MESSAGE_CON;
446   pdu->hdr->code = COAP_RESPONSE_CODE(203);
447   pdu->hdr->id = htons(0x1234);
448 
449   CU_ASSERT(pdu->length == 4);
450 
451   result = coap_add_token(pdu, 2, (unsigned char *)"\x00\x01");
452 
453   CU_ASSERT(result > 0);
454 
455   result = coap_add_data(pdu, 1, (unsigned char *)"\0");
456 
457   CU_ASSERT(result > 0);
458   CU_ASSERT(pdu->length == 8);
459   CU_ASSERT(pdu->data == (unsigned char *)pdu->hdr + 7);
460 
461   CU_ASSERT(pdu->length == sizeof(teststr));
462   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
463 }
464 
465 static void
t_encode_pdu9(void)466 t_encode_pdu9(void) {
467   /* PDU with options and data */
468   uint8_t teststr[] = { 0x60, 0x44, 0x12, 0x34, 0x48, 's',  'o',  'm',
469 		     'e',  'e',  't',  'a',  'g',  0x10, 0xdd, 0x11,
470 		     0x04, 's',  'o',  'm',  'e',  'r',  'a',  't',
471 		     'h',  'e',  'r',  'l',  'o',  'n',  'g',  'u',
472 		     'r',  'i',  0xff, 'd',  'a',  't',  'a'
473   };
474   int result;
475 
476   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
477 
478   pdu->hdr->type = COAP_MESSAGE_ACK;
479   pdu->hdr->code = COAP_RESPONSE_CODE(204);
480   pdu->hdr->id = htons(0x1234);
481 
482   CU_ASSERT(pdu->length == 4);
483 
484   result = coap_add_option(pdu, COAP_OPTION_ETAG, 8, (unsigned char *)"someetag");
485 
486   CU_ASSERT(result == 9);
487   CU_ASSERT(pdu->max_delta == 4);
488   CU_ASSERT(pdu->length == 13);
489   CU_ASSERT_PTR_NULL(pdu->data);
490 
491   result = coap_add_option(pdu, COAP_OPTION_IF_NONE_MATCH, 0, NULL);
492 
493   CU_ASSERT(result == 1);
494   CU_ASSERT(pdu->max_delta == 5);
495   CU_ASSERT(pdu->length == 14);
496   CU_ASSERT_PTR_NULL(pdu->data);
497 
498   result = coap_add_option(pdu, COAP_OPTION_PROXY_URI,
499 			   17, (unsigned char *)"someratherlonguri");
500 
501   CU_ASSERT(result == 20);
502   CU_ASSERT(pdu->max_delta == 35);
503   CU_ASSERT(pdu->length == 34);
504   CU_ASSERT_PTR_NULL(pdu->data);
505 
506   result = coap_add_data(pdu, 4, (unsigned char *)"data");
507 
508   CU_ASSERT(result > 0);
509   CU_ASSERT(pdu->length == 39);
510   CU_ASSERT(pdu->data == (unsigned char *)pdu->hdr + 35);
511 
512   CU_ASSERT(pdu->length == sizeof(teststr));
513   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
514 }
515 
516 static void
t_encode_pdu10(void)517 t_encode_pdu10(void) {
518   /* PDU with token, options and data */
519   uint8_t teststr[] = { 0x62, 0x44, 0x12, 0x34, 0x00, 0x00, 0x8d, 0xf2,
520 		     'c',  'o',  'a',  'p',  ':',  '/',  '/',  'e',
521 		     'x',  'a',  'm',  'p',  'l',  'e',  '.',  'c',
522 		     'o',  'm',  '/',  '1',  '2',  '3',  '4',  '5',
523 		     '/',  '%',  '3',  'F',  'x',  'y',  'z',  '/',
524 		     '3',  '0',  '4',  '8',  '2',  '3',  '4',  '2',
525 		     '3',  '4',  '/',  '2',  '3',  '4',  '0',  '2',
526 		     '3',  '4',  '8',  '2',  '3',  '4',  '/',  '2',
527 		     '3',  '9',  '0',  '8',  '4',  '2',  '3',  '4',
528 		     '-',  '2',  '3',  '/',  '%',  'A',  'B',  '%',
529 		     '3',  '0',  '%',  'a',  'f',  '/',  '+',  '1',
530 		     '2',  '3',  '/',  'h',  'f',  'k',  's',  'd',
531 		     'h',  '/',  '2',  '3',  '4',  '8',  '0',  '-',
532 		     '2',  '3',  '4',  '-',  '9',  '8',  '2',  '3',
533 		     '5',  '/',  '1',  '2',  '0',  '4',  '/',  '2',
534 		     '4',  '3',  '5',  '4',  '6',  '3',  '4',  '5',
535 		     '3',  '4',  '5',  '2',  '4',  '3',  '/',  '0',
536 		     '1',  '9',  '8',  's',  'd',  'n',  '3',  '-',
537 		     'a',  '-',  '3',  '/',  '/',  '/',  'a',  'f',
538 		     'f',  '0',  '9',  '3',  '4',  '/',  '9',  '7',
539 		     'u',  '2',  '1',  '4',  '1',  '/',  '0',  '0',
540 		     '0',  '2',  '/',  '3',  '9',  '3',  '2',  '4',
541 		     '2',  '3',  '5',  '3',  '2',  '/',  '5',  '6',
542 		     '2',  '3',  '4',  '0',  '2',  '3',  '/',  '-',
543 		     '-',  '-',  '-',  '/',  '=',  '1',  '2',  '3',
544 		     '4',  '=',  '/',  '0',  '9',  '8',  '1',  '4',
545 		     '1',  '-',  '9',  '5',  '6',  '4',  '6',  '4',
546 		     '3',  '/',  '2',  '1',  '9',  '7',  '0',  '-',
547 		     '-',  '-',  '-',  '-',  '/',  '8',  '2',  '3',
548 		     '6',  '4',  '9',  '2',  '3',  '4',  '7',  '2',
549 		     'w',  'e',  'r',  'e',  'r',  'e',  'w',  'r',
550 		     '0',  '-',  '9',  '2',  '1',  '-',  '3',  '9',
551 		     '1',  '2',  '3',  '-',  '3',  '4',  '/',  0x0d,
552 		     0x01, '/',  '/',  '4',  '9',  '2',  '4',  '0',
553 		     '3',  '-',  '-',  '0',  '9',  '8',  '/',  0xc1,
554 		     '*',  0xff, 'd',  'a',  't',  'a'
555   };
556   int result;
557 
558   coap_pdu_clear(pdu, pdu->max_size);	/* clear PDU */
559 
560   pdu->hdr->type = COAP_MESSAGE_ACK;
561   pdu->hdr->code = COAP_RESPONSE_CODE(204);
562   pdu->hdr->id = htons(0x1234);
563 
564   CU_ASSERT(pdu->length == 4);
565 
566   result = coap_add_token(pdu, 2, (unsigned char *)"\0\0");
567 
568   CU_ASSERT(result > 0);
569   result = coap_add_option(pdu, COAP_OPTION_LOCATION_PATH, 255,
570 			   (unsigned char *)"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/");
571 
572   CU_ASSERT(result == 257);
573   CU_ASSERT(pdu->max_delta == 8);
574   CU_ASSERT(pdu->length == 263);
575   CU_ASSERT_PTR_NULL(pdu->data);
576 
577   result = coap_add_option(pdu, COAP_OPTION_LOCATION_PATH, 14,
578 			   (unsigned char *)"//492403--098/");
579 
580   CU_ASSERT(result == 16);
581   CU_ASSERT(pdu->max_delta == 8);
582   CU_ASSERT(pdu->length == 279);
583   CU_ASSERT_PTR_NULL(pdu->data);
584 
585   result = coap_add_option(pdu, COAP_OPTION_LOCATION_QUERY,
586 			   1, (unsigned char *)"*");
587 
588   CU_ASSERT(result == 2);
589   CU_ASSERT(pdu->max_delta == 20);
590   CU_ASSERT(pdu->length == 281);
591   CU_ASSERT_PTR_NULL(pdu->data);
592 
593   result = coap_add_data(pdu, 4, (unsigned char *)"data");
594 
595   CU_ASSERT(result > 0);
596   CU_ASSERT(pdu->length == 286);
597   CU_ASSERT(pdu->data == (unsigned char *)pdu->hdr + 282);
598 
599   CU_ASSERT(pdu->length == sizeof(teststr));
600   CU_ASSERT(memcmp(pdu->hdr, teststr, sizeof(teststr)) == 0);
601 }
602 
603 static void
t_encode_pdu11(void)604 t_encode_pdu11(void) {
605   coap_log_t level = coap_get_log_level();
606   /* data too long for PDU */
607   size_t old_max = pdu->max_size;
608   int result;
609 
610   coap_pdu_clear(pdu, 8);	/* clear PDU, with small maximum */
611 
612   CU_ASSERT(pdu->data == NULL);
613   coap_set_log_level(LOG_CRIT);
614   result = coap_add_data(pdu, 10, (unsigned char *)"0123456789");
615   coap_set_log_level(level);
616 
617   CU_ASSERT(result == 0);
618   CU_ASSERT(pdu->data == NULL);
619 
620   pdu->max_size = old_max;
621 }
622 
623 static int
t_pdu_tests_create(void)624 t_pdu_tests_create(void) {
625   pdu = coap_pdu_init(0, 0, 0, COAP_MAX_PDU_SIZE);
626 
627   return pdu == NULL;
628 }
629 
630 static int
t_pdu_tests_remove(void)631 t_pdu_tests_remove(void) {
632   coap_delete_pdu(pdu);
633   return 0;
634 }
635 
636 CU_pSuite
t_init_pdu_tests(void)637 t_init_pdu_tests(void) {
638   CU_pSuite suite[2];
639 
640   suite[0] = CU_add_suite("pdu parser", t_pdu_tests_create, t_pdu_tests_remove);
641   if (!suite[0]) {			/* signal error */
642     fprintf(stderr, "W: cannot add pdu parser test suite (%s)\n",
643 	    CU_get_error_msg());
644 
645     return NULL;
646   }
647 
648 #define PDU_TEST(s,t)						      \
649   if (!CU_ADD_TEST(s,t)) {					      \
650     fprintf(stderr, "W: cannot add pdu parser test (%s)\n",	      \
651 	    CU_get_error_msg());				      \
652   }
653 
654   PDU_TEST(suite[0], t_parse_pdu1);
655   PDU_TEST(suite[0], t_parse_pdu2);
656   PDU_TEST(suite[0], t_parse_pdu3);
657   PDU_TEST(suite[0], t_parse_pdu4);
658   PDU_TEST(suite[0], t_parse_pdu5);
659   PDU_TEST(suite[0], t_parse_pdu6);
660   PDU_TEST(suite[0], t_parse_pdu7);
661   PDU_TEST(suite[0], t_parse_pdu8);
662   PDU_TEST(suite[0], t_parse_pdu9);
663   PDU_TEST(suite[0], t_parse_pdu10);
664   PDU_TEST(suite[0], t_parse_pdu11);
665   PDU_TEST(suite[0], t_parse_pdu12);
666   PDU_TEST(suite[0], t_parse_pdu13);
667   PDU_TEST(suite[0], t_parse_pdu14);
668 
669   suite[1] = CU_add_suite("pdu encoder", t_pdu_tests_create, t_pdu_tests_remove);
670   if (suite[1]) {
671 #define PDU_ENCODER_TEST(s,t)						      \
672   if (!CU_ADD_TEST(s,t)) {					      \
673     fprintf(stderr, "W: cannot add pdu encoder test (%s)\n",	      \
674 	    CU_get_error_msg());				      \
675   }
676     PDU_ENCODER_TEST(suite[1], t_encode_pdu1);
677     PDU_ENCODER_TEST(suite[1], t_encode_pdu2);
678     PDU_ENCODER_TEST(suite[1], t_encode_pdu3);
679     PDU_ENCODER_TEST(suite[1], t_encode_pdu4);
680     PDU_ENCODER_TEST(suite[1], t_encode_pdu5);
681     PDU_ENCODER_TEST(suite[1], t_encode_pdu6);
682     PDU_ENCODER_TEST(suite[1], t_encode_pdu7);
683     PDU_ENCODER_TEST(suite[1], t_encode_pdu8);
684     PDU_ENCODER_TEST(suite[1], t_encode_pdu9);
685     PDU_ENCODER_TEST(suite[1], t_encode_pdu10);
686     PDU_ENCODER_TEST(suite[1], t_encode_pdu11);
687 
688   } else 			/* signal error */
689     fprintf(stderr, "W: cannot add pdu parser test suite (%s)\n",
690 	    CU_get_error_msg());
691 
692   return suite[0];
693 }
694 
695