3 * Copyright (C) 2013--2014 Olaf Bergmann <bergmann@tzi.org>
5 * This file is part of the CoAP library libcoap. Please see
6 * README for terms of use.
14 #include <netinet/in.h>
15 #include "test_wellknown.h"
17 #define TEST_PDU_SIZE 120
18 #define TEST_URI_LEN 4
20 coap_context_t *ctx; /* Holds the coap context for most tests */
21 coap_pdu_t *pdu; /* Holds the parsed PDU for most tests */
23 extern coap_pdu_t *wellknown_response(coap_context_t *, coap_pdu_t *);
24 extern int print_wellknown(coap_context_t *context, unsigned char *buf, size_t *buflen,
25 size_t offset, coap_opt_t *query_filter);
27 void t_wellknown1(void)
29 coap_print_status_t result;
31 unsigned char buf[40];
32 size_t buflen, offset, ofs;
35 { /* </>;title="some attribute";ct=0 (31 chars) */
36 '<', '/', '>', ';', 't', 'i', 't', 'l', 'e', '=', '"', 's', 'o', 'm', 'e', ' ', 'a', 't', 't',
37 'r', 'i', 'b', 'u', 't', 'e', '"', ';', 'c', 't', '=', '0' };
39 r = coap_resource_init(NULL, 0, 0);
41 coap_add_attr(r, (unsigned char *) "ct", 2, (unsigned char *) "0", 1, 0);
42 coap_add_attr(r, (unsigned char *) "title", 5, (unsigned char *) "\"some attribute\"", 16, 0);
44 coap_add_resource(ctx, r);
46 for (offset = 0; offset < sizeof(teststr); offset++)
51 result = coap_print_link(r, buf, &buflen, &ofs);
53 CU_ASSERT(result == sizeof(teststr) - offset);
54 CU_ASSERT(buflen == sizeof(teststr));
55 CU_ASSERT(memcmp(buf, teststr + offset, sizeof(teststr) - offset) == 0);
58 /* offset points behind teststr */
61 result = coap_print_link(r, buf, &buflen, &ofs);
63 CU_ASSERT(result == 0);
64 CU_ASSERT(buflen == sizeof(teststr));
66 /* offset exceeds buffer */
69 result = coap_print_link(r, buf, &buflen, &ofs);
71 CU_ASSERT(result == 0);
72 CU_ASSERT(buflen == sizeof(teststr));
75 void t_wellknown2(void)
77 coap_print_status_t result;
79 unsigned char buf[10]; /* smaller than teststr */
80 size_t buflen, offset, ofs;
83 { /* ,</abcd>;if="one";obs (21 chars) */
84 '<', '/', 'a', 'b', 'c', 'd', '>', ';', 'i', 'f', '=', '"', 'o', 'n', 'e', '"', ';', 'o', 'b',
87 r = coap_resource_init((unsigned char *) "abcd", 4, 0);
89 coap_add_attr(r, (unsigned char *) "if", 2, (unsigned char *) "\"one\"", 5, 0);
91 coap_add_resource(ctx, r);
93 for (offset = 0; offset < sizeof(teststr) - sizeof(buf); offset++)
98 result = coap_print_link(r, buf, &buflen, &ofs);
100 CU_ASSERT(result == (COAP_PRINT_STATUS_TRUNC | sizeof(buf)));
101 CU_ASSERT(buflen == sizeof(teststr));
103 CU_ASSERT(memcmp(buf, teststr + offset, sizeof(buf)) == 0);
106 /* from here on, the resource description fits into buf */
107 for (; offset < sizeof(teststr); offset++)
110 buflen = sizeof(buf);
111 result = coap_print_link(r, buf, &buflen, &ofs);
113 CU_ASSERT(result == sizeof(teststr) - offset);
114 CU_ASSERT(buflen == sizeof(teststr));
116 CU_ASSERT(memcmp(buf, teststr + offset, COAP_PRINT_OUTPUT_LENGTH(result)) == 0);
119 /* offset exceeds buffer */
120 buflen = sizeof(buf);
122 result = coap_print_link(r, buf, &buflen, &ofs);
123 CU_ASSERT(result == 0);
124 CU_ASSERT(buflen == sizeof(teststr));
125 CU_ASSERT(ofs == offset - sizeof(teststr));
128 void t_wellknown3(void)
130 coap_print_status_t result;
133 static char uris[2 * COAP_MAX_PDU_SIZE];
134 unsigned char *uribuf = (unsigned char *) uris;
135 unsigned char buf[40];
136 size_t buflen = sizeof(buf);
138 const unsigned short num_resources = (sizeof(uris) / TEST_URI_LEN) - 1;
140 /* ,</0000> (TEST_URI_LEN + 4 chars) */
141 for (j = 0; j < num_resources; j++)
143 int len = snprintf((char *) uribuf, TEST_URI_LEN + 1, "%0*d", TEST_URI_LEN, j);
144 r = coap_resource_init(uribuf, len, 0);
145 coap_add_resource(ctx, r);
146 uribuf += TEST_URI_LEN;
149 /* the following test assumes that the first two resources from
150 * t_wellknown1() and t_wellknown2() need more than buflen
151 * characters. Otherwise, CU_ASSERT(result > 0) will fail.
153 offset = num_resources * (TEST_URI_LEN + 4);
154 result = print_wellknown(ctx, buf, &buflen, offset, NULL);
155 CU_ASSERT((result & COAP_PRINT_STATUS_ERROR) == 0);
156 CU_ASSERT(COAP_PRINT_OUTPUT_LENGTH(result) > 0);
159 /* Create wellknown response for request without Block-option. */
160 void t_wellknown4(void)
162 coap_pdu_t *response;
165 response = wellknown_response(ctx, pdu);
167 CU_ASSERT_PTR_NOT_NULL(response);
169 CU_ASSERT(coap_get_block(response, COAP_OPTION_BLOCK2, &block) != 0);
171 CU_ASSERT(block.num == 0);
172 CU_ASSERT(block.m == 1);
175 == (unsigned char *) response->hdr + response->length - response->data);
177 coap_delete_pdu(response);
180 /* Create wellknown response for request with Block2-option and an szx
181 * value smaller than COAP_MAX_BLOCK_SZX.
183 void t_wellknown5(void)
185 coap_pdu_t *response;
186 coap_block_t inblock =
187 { .num = 1, .m = 0, .szx = 1 };
189 unsigned char buf[3];
191 if (!coap_add_option(pdu, COAP_OPTION_BLOCK2,
192 coap_encode_var_bytes(buf, ((inblock.num << 4) | (inblock.m << 3) | inblock.szx)), buf))
194 CU_FAIL("cannot add Block2 option");
198 response = wellknown_response(ctx, pdu);
200 CU_ASSERT_PTR_NOT_NULL(response);
202 CU_ASSERT(coap_get_block(response, COAP_OPTION_BLOCK2, &block) != 0);
204 CU_ASSERT(block.num == inblock.num);
205 CU_ASSERT(block.m == 1);
208 == (unsigned char *) response->hdr + response->length - response->data);
210 coap_delete_pdu(response);
213 void t_wellknown6(void)
215 coap_pdu_t *response;
217 { .num = 0, .szx = 6 };
218 unsigned char buf[TEST_PDU_SIZE];
222 coap_pdu_clear(pdu, pdu->max_size); /* clear PDU */
224 pdu->hdr->type = COAP_MESSAGE_NON;
225 pdu->hdr->code = COAP_REQUEST_GET;
226 pdu->hdr->id = htons(0x1234);
228 CU_ASSERT_PTR_NOT_NULL(pdu);
231 || !coap_add_option(pdu, COAP_OPTION_BLOCK2,
232 coap_encode_var_bytes(buf, ((block.num << 4) | block.szx)), buf))
234 CU_FAIL("cannot create request");
238 response = wellknown_response(ctx, pdu);
240 CU_ASSERT_PTR_NOT_NULL(response);
242 /* coap_show_pdu(response); */
244 CU_ASSERT(coap_get_block(response, COAP_OPTION_BLOCK2, &block) != 0);
247 coap_delete_pdu(response);
248 } while (block.m == 1);
251 int t_wkc_tests_create(void)
255 coap_address_init(&addr);
257 addr.size = sizeof(struct sockaddr_in6);
258 addr.addr.sin6.sin6_family = AF_INET6;
259 addr.addr.sin6.sin6_addr = in6addr_any;
260 addr.addr.sin6.sin6_port = htons(COAP_DEFAULT_PORT);
262 ctx = coap_new_context(&addr);
264 pdu = coap_pdu_init(0, 0, 0, TEST_PDU_SIZE);
266 /* add resources to coap context */
270 static char _buf[2 * COAP_MAX_PDU_SIZE];
271 unsigned char *buf = (unsigned char *)_buf;
274 /* </>;title="some attribute";ct=0 (31 chars) */
275 r = coap_resource_init(NULL, 0, 0);
277 coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0);
278 coap_add_attr(r, (unsigned char *)"title", 5, (unsigned char *)"\"some attribute\"", 16, 0);
279 coap_add_resource(ctx, r);
281 /* ,</abcd>;if="one";obs (21 chars) */
282 r = coap_resource_init((unsigned char *)"abcd", 4, 0);
284 coap_add_attr(r, (unsigned char *)"if", 2, (unsigned char *)"\"one\"", 5, 0);
286 coap_add_resource(ctx, r);
288 /* ,</0000> (TEST_URI_LEN + 4 chars) */
289 for (i = 0; i < sizeof(_buf) / (TEST_URI_LEN + 4); i++)
291 int len = snprintf((char *)buf, TEST_URI_LEN + 1,
292 "%0*d", TEST_URI_LEN, i);
293 r = coap_resource_init(buf, len, 0);
294 coap_add_resource(ctx, r);
295 buf += TEST_URI_LEN + 1;
300 return ctx == NULL || pdu == NULL;
303 int t_wkc_tests_remove(void)
305 coap_delete_pdu(pdu);
306 coap_free_context(ctx);
310 CU_pSuite t_init_wellknown_tests(void)
314 suite = CU_add_suite(".well-known/core", t_wkc_tests_create, t_wkc_tests_remove);
317 fprintf(stderr, "W: cannot add .well-known/core test suite (%s)\n", CU_get_error_msg());
322 #define WKC_TEST(s,t) \
323 if (!CU_ADD_TEST(s,t)) { \
324 fprintf(stderr, "W: cannot add .well-known/core test (%s)\n", \
325 CU_get_error_msg()); \
328 WKC_TEST(suite, t_wellknown1);
329 WKC_TEST(suite, t_wellknown2);
330 WKC_TEST(suite, t_wellknown3);
331 WKC_TEST(suite, t_wellknown4);
332 WKC_TEST(suite, t_wellknown5);
333 WKC_TEST(suite, t_wellknown6);