1c87c5fbaSopenharmony_ci/* libcoap unit tests 2c87c5fbaSopenharmony_ci * 3c87c5fbaSopenharmony_ci * Copyright (C) 2013--2023 Olaf Bergmann <bergmann@tzi.org> 4c87c5fbaSopenharmony_ci * 5c87c5fbaSopenharmony_ci * SPDX-License-Identifier: BSD-2-Clause 6c87c5fbaSopenharmony_ci * 7c87c5fbaSopenharmony_ci * This file is part of the CoAP library libcoap. Please see 8c87c5fbaSopenharmony_ci * README for terms of use. 9c87c5fbaSopenharmony_ci */ 10c87c5fbaSopenharmony_ci 11c87c5fbaSopenharmony_ci#include "test_common.h" 12c87c5fbaSopenharmony_ci#include "test_wellknown.h" 13c87c5fbaSopenharmony_ci 14c87c5fbaSopenharmony_ci#if COAP_SERVER_SUPPORT 15c87c5fbaSopenharmony_ci#if COAP_CLIENT_SUPPORT 16c87c5fbaSopenharmony_ci#include <assert.h> 17c87c5fbaSopenharmony_ci#ifdef HAVE_NETINET_IN_H 18c87c5fbaSopenharmony_ci#include <netinet/in.h> 19c87c5fbaSopenharmony_ci#endif 20c87c5fbaSopenharmony_ci#include <stdio.h> 21c87c5fbaSopenharmony_ci#include <stdlib.h> 22c87c5fbaSopenharmony_ci#include <string.h> 23c87c5fbaSopenharmony_ci 24c87c5fbaSopenharmony_ci#define TEST_PDU_SIZE 120 25c87c5fbaSopenharmony_ci#define TEST_URI_LEN 4 26c87c5fbaSopenharmony_ci 27c87c5fbaSopenharmony_cistatic coap_context_t *ctx; /* Holds the coap context for most tests */ 28c87c5fbaSopenharmony_cistatic coap_pdu_t *pdu; /* Holds the parsed PDU for most tests */ 29c87c5fbaSopenharmony_cistatic coap_session_t *session; /* Holds a reference-counted session object 30c87c5fbaSopenharmony_ci * that is passed to coap_wellknown_response(). */ 31c87c5fbaSopenharmony_ci 32c87c5fbaSopenharmony_cistatic void 33c87c5fbaSopenharmony_cit_wellknown1(void) { 34c87c5fbaSopenharmony_ci coap_print_status_t result; 35c87c5fbaSopenharmony_ci coap_resource_t *r; 36c87c5fbaSopenharmony_ci unsigned char buf[40]; 37c87c5fbaSopenharmony_ci size_t buflen, offset, ofs; 38c87c5fbaSopenharmony_ci 39c87c5fbaSopenharmony_ci char teststr[] = { /* </>;title="some attribute";ct=0 (31 chars) */ 40c87c5fbaSopenharmony_ci '<', '/', '>', ';', 't', 'i', 't', 'l', 41c87c5fbaSopenharmony_ci 'e', '=', '"', 's', 'o', 'm', 'e', ' ', 42c87c5fbaSopenharmony_ci 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 43c87c5fbaSopenharmony_ci 'e', '"', ';', 'c', 't', '=', '0' 44c87c5fbaSopenharmony_ci }; 45c87c5fbaSopenharmony_ci 46c87c5fbaSopenharmony_ci r = coap_resource_init(NULL, 0); 47c87c5fbaSopenharmony_ci 48c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0); 49c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"some attribute\""), 0); 50c87c5fbaSopenharmony_ci 51c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 52c87c5fbaSopenharmony_ci 53c87c5fbaSopenharmony_ci for (offset = 0; offset < sizeof(teststr); offset++) { 54c87c5fbaSopenharmony_ci ofs = offset; 55c87c5fbaSopenharmony_ci buflen = sizeof(buf); 56c87c5fbaSopenharmony_ci 57c87c5fbaSopenharmony_ci result = coap_print_link(r, buf, &buflen, &ofs); 58c87c5fbaSopenharmony_ci 59c87c5fbaSopenharmony_ci CU_ASSERT(result == sizeof(teststr) - offset); 60c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 61c87c5fbaSopenharmony_ci CU_ASSERT(memcmp(buf, teststr + offset, sizeof(teststr) - offset) == 0); 62c87c5fbaSopenharmony_ci } 63c87c5fbaSopenharmony_ci 64c87c5fbaSopenharmony_ci /* offset points behind teststr */ 65c87c5fbaSopenharmony_ci ofs = offset; 66c87c5fbaSopenharmony_ci buflen = sizeof(buf); 67c87c5fbaSopenharmony_ci result = coap_print_link(r, buf, &buflen, &ofs); 68c87c5fbaSopenharmony_ci 69c87c5fbaSopenharmony_ci CU_ASSERT(result == 0); 70c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 71c87c5fbaSopenharmony_ci 72c87c5fbaSopenharmony_ci /* offset exceeds buffer */ 73c87c5fbaSopenharmony_ci buflen = sizeof(buf); 74c87c5fbaSopenharmony_ci ofs = buflen; 75c87c5fbaSopenharmony_ci result = coap_print_link(r, buf, &buflen, &ofs); 76c87c5fbaSopenharmony_ci 77c87c5fbaSopenharmony_ci CU_ASSERT(result == 0); 78c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 79c87c5fbaSopenharmony_ci} 80c87c5fbaSopenharmony_ci 81c87c5fbaSopenharmony_cistatic void 82c87c5fbaSopenharmony_cit_wellknown2(void) { 83c87c5fbaSopenharmony_ci coap_print_status_t result; 84c87c5fbaSopenharmony_ci coap_resource_t *r; 85c87c5fbaSopenharmony_ci unsigned char buf[10]; /* smaller than teststr */ 86c87c5fbaSopenharmony_ci size_t buflen, offset, ofs; 87c87c5fbaSopenharmony_ci 88c87c5fbaSopenharmony_ci char teststr[] = { /* ,</abcd>;if="one";obs (21 chars) */ 89c87c5fbaSopenharmony_ci '<', '/', 'a', 'b', 'c', 'd', '>', ';', 90c87c5fbaSopenharmony_ci 'i', 'f', '=', '"', 'o', 'n', 'e', '"', 91c87c5fbaSopenharmony_ci ';', 'o', 'b', 's' 92c87c5fbaSopenharmony_ci }; 93c87c5fbaSopenharmony_ci 94c87c5fbaSopenharmony_ci r = coap_resource_init(coap_make_str_const("abcd"), 0); 95c87c5fbaSopenharmony_ci coap_resource_set_get_observable(r, 1); 96c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"one\""), 0); 97c87c5fbaSopenharmony_ci 98c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 99c87c5fbaSopenharmony_ci 100c87c5fbaSopenharmony_ci for (offset = 0; offset < sizeof(teststr) - sizeof(buf); offset++) { 101c87c5fbaSopenharmony_ci ofs = offset; 102c87c5fbaSopenharmony_ci buflen = sizeof(buf); 103c87c5fbaSopenharmony_ci 104c87c5fbaSopenharmony_ci result = coap_print_link(r, buf, &buflen, &ofs); 105c87c5fbaSopenharmony_ci 106c87c5fbaSopenharmony_ci CU_ASSERT(result == (COAP_PRINT_STATUS_TRUNC | sizeof(buf))); 107c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 108c87c5fbaSopenharmony_ci CU_ASSERT(ofs == 0); 109c87c5fbaSopenharmony_ci CU_ASSERT(memcmp(buf, teststr + offset, sizeof(buf)) == 0); 110c87c5fbaSopenharmony_ci } 111c87c5fbaSopenharmony_ci 112c87c5fbaSopenharmony_ci /* from here on, the resource description fits into buf */ 113c87c5fbaSopenharmony_ci for (; offset < sizeof(teststr); offset++) { 114c87c5fbaSopenharmony_ci ofs = offset; 115c87c5fbaSopenharmony_ci buflen = sizeof(buf); 116c87c5fbaSopenharmony_ci result = coap_print_link(r, buf, &buflen, &ofs); 117c87c5fbaSopenharmony_ci 118c87c5fbaSopenharmony_ci CU_ASSERT(result == sizeof(teststr) - offset); 119c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 120c87c5fbaSopenharmony_ci CU_ASSERT(ofs == 0); 121c87c5fbaSopenharmony_ci CU_ASSERT(memcmp(buf, teststr + offset, 122c87c5fbaSopenharmony_ci COAP_PRINT_OUTPUT_LENGTH(result)) == 0); 123c87c5fbaSopenharmony_ci } 124c87c5fbaSopenharmony_ci 125c87c5fbaSopenharmony_ci /* offset exceeds buffer */ 126c87c5fbaSopenharmony_ci buflen = sizeof(buf); 127c87c5fbaSopenharmony_ci ofs = offset; 128c87c5fbaSopenharmony_ci result = coap_print_link(r, buf, &buflen, &ofs); 129c87c5fbaSopenharmony_ci CU_ASSERT(result == 0); 130c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 131c87c5fbaSopenharmony_ci CU_ASSERT(ofs == offset - sizeof(teststr)); 132c87c5fbaSopenharmony_ci} 133c87c5fbaSopenharmony_ci 134c87c5fbaSopenharmony_cistatic void 135c87c5fbaSopenharmony_cit_wellknown3(void) { 136c87c5fbaSopenharmony_ci coap_print_status_t result; 137c87c5fbaSopenharmony_ci int j; 138c87c5fbaSopenharmony_ci coap_resource_t *r; 139c87c5fbaSopenharmony_ci static char uris[2 * 1024]; 140c87c5fbaSopenharmony_ci unsigned char *uribuf = (unsigned char *)uris; 141c87c5fbaSopenharmony_ci unsigned char buf[40]; 142c87c5fbaSopenharmony_ci size_t buflen = sizeof(buf); 143c87c5fbaSopenharmony_ci size_t offset; 144c87c5fbaSopenharmony_ci const uint16_t num_resources = (sizeof(uris) / TEST_URI_LEN) - 1; 145c87c5fbaSopenharmony_ci 146c87c5fbaSopenharmony_ci /* ,</0000> (TEST_URI_LEN + 4 chars) */ 147c87c5fbaSopenharmony_ci for (j = 0; j < num_resources; j++) { 148c87c5fbaSopenharmony_ci int len = snprintf((char *)uribuf, TEST_URI_LEN + 1, 149c87c5fbaSopenharmony_ci "%0*d", TEST_URI_LEN, j); 150c87c5fbaSopenharmony_ci coap_str_const_t uri_path = {.length = len, .s = uribuf}; 151c87c5fbaSopenharmony_ci r = coap_resource_init(&uri_path, 0); 152c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 153c87c5fbaSopenharmony_ci uribuf += TEST_URI_LEN; 154c87c5fbaSopenharmony_ci } 155c87c5fbaSopenharmony_ci 156c87c5fbaSopenharmony_ci /* the following test assumes that the first two resources from 157c87c5fbaSopenharmony_ci * t_wellknown1() and t_wellknown2() need more than buflen 158c87c5fbaSopenharmony_ci * characters. Otherwise, CU_ASSERT(result > 0) will fail. 159c87c5fbaSopenharmony_ci */ 160c87c5fbaSopenharmony_ci offset = num_resources * (TEST_URI_LEN + 4); 161c87c5fbaSopenharmony_ci result = coap_print_wellknown(ctx, buf, &buflen, offset, NULL); 162c87c5fbaSopenharmony_ci CU_ASSERT((result & COAP_PRINT_STATUS_ERROR) == 0); 163c87c5fbaSopenharmony_ci CU_ASSERT(COAP_PRINT_OUTPUT_LENGTH(result) > 0); 164c87c5fbaSopenharmony_ci} 165c87c5fbaSopenharmony_ci 166c87c5fbaSopenharmony_cistatic void 167c87c5fbaSopenharmony_cit_wellknown4(void) { 168c87c5fbaSopenharmony_ci coap_print_status_t result; 169c87c5fbaSopenharmony_ci coap_string_t *query; 170c87c5fbaSopenharmony_ci unsigned char buf[40]; 171c87c5fbaSopenharmony_ci size_t buflen = sizeof(buf); 172c87c5fbaSopenharmony_ci char teststr[] = { /* ,</abcd>;if="one";obs (21 chars) */ 173c87c5fbaSopenharmony_ci '<', '/', 'a', 'b', 'c', 'd', '>', ';', 174c87c5fbaSopenharmony_ci 'i', 'f', '=', '"', 'o', 'n', 'e', '"', 175c87c5fbaSopenharmony_ci ';', 'o', 'b', 's' 176c87c5fbaSopenharmony_ci }; 177c87c5fbaSopenharmony_ci 178c87c5fbaSopenharmony_ci /* Check for the resource added in t_wellknown2 */ 179c87c5fbaSopenharmony_ci query = coap_new_string(sizeof("if=one")-1); 180c87c5fbaSopenharmony_ci CU_ASSERT(query != NULL); 181c87c5fbaSopenharmony_ci memcpy(query->s, "if=one", sizeof("if=one")-1); 182c87c5fbaSopenharmony_ci result = coap_print_wellknown(ctx, buf, &buflen, 0, query); 183c87c5fbaSopenharmony_ci CU_ASSERT((result & COAP_PRINT_STATUS_ERROR) == 0); 184c87c5fbaSopenharmony_ci CU_ASSERT(COAP_PRINT_OUTPUT_LENGTH(result) == sizeof(teststr)); 185c87c5fbaSopenharmony_ci CU_ASSERT(buflen == sizeof(teststr)); 186c87c5fbaSopenharmony_ci CU_ASSERT(memcmp(buf, teststr, buflen) == 0); 187c87c5fbaSopenharmony_ci coap_delete_string(query); 188c87c5fbaSopenharmony_ci} 189c87c5fbaSopenharmony_ci 190c87c5fbaSopenharmony_ci 191c87c5fbaSopenharmony_cistatic int 192c87c5fbaSopenharmony_cit_wkc_tests_create(void) { 193c87c5fbaSopenharmony_ci coap_address_t addr; 194c87c5fbaSopenharmony_ci 195c87c5fbaSopenharmony_ci coap_address_init(&addr); 196c87c5fbaSopenharmony_ci 197c87c5fbaSopenharmony_ci addr.size = sizeof(struct sockaddr_in6); 198c87c5fbaSopenharmony_ci addr.addr.sin6.sin6_family = AF_INET6; 199c87c5fbaSopenharmony_ci addr.addr.sin6.sin6_addr = in6addr_any; 200c87c5fbaSopenharmony_ci addr.addr.sin6.sin6_port = htons(COAP_DEFAULT_PORT); 201c87c5fbaSopenharmony_ci 202c87c5fbaSopenharmony_ci ctx = coap_new_context(&addr); 203c87c5fbaSopenharmony_ci 204c87c5fbaSopenharmony_ci addr.addr.sin6.sin6_addr = in6addr_loopback; 205c87c5fbaSopenharmony_ci session = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP); 206c87c5fbaSopenharmony_ci 207c87c5fbaSopenharmony_ci pdu = coap_pdu_init(0, 0, 0, TEST_PDU_SIZE); 208c87c5fbaSopenharmony_ci#if 0 209c87c5fbaSopenharmony_ci /* add resources to coap context */ 210c87c5fbaSopenharmony_ci if (ctx && pdu) { 211c87c5fbaSopenharmony_ci coap_resource_t *r; 212c87c5fbaSopenharmony_ci static char _buf[2 * 1024]; 213c87c5fbaSopenharmony_ci unsigned char *buf = (unsigned char *)_buf; 214c87c5fbaSopenharmony_ci int i; 215c87c5fbaSopenharmony_ci 216c87c5fbaSopenharmony_ci /* </>;title="some attribute";ct=0 (31 chars) */ 217c87c5fbaSopenharmony_ci r = coap_resource_init(NULL, 0, 0); 218c87c5fbaSopenharmony_ci 219c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0); 220c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"some attribute\""), 0); 221c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 222c87c5fbaSopenharmony_ci 223c87c5fbaSopenharmony_ci /* ,</abcd>;if="one";obs (21 chars) */ 224c87c5fbaSopenharmony_ci r = coap_resource_init((const uint8_t *)"abcd", 4, 0); 225c87c5fbaSopenharmony_ci r->observable = 1; 226c87c5fbaSopenharmony_ci coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"one\""), 0); 227c87c5fbaSopenharmony_ci 228c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 229c87c5fbaSopenharmony_ci 230c87c5fbaSopenharmony_ci /* ,</0000> (TEST_URI_LEN + 4 chars) */ 231c87c5fbaSopenharmony_ci for (i = 0; i < sizeof(_buf) / (TEST_URI_LEN + 4); i++) { 232c87c5fbaSopenharmony_ci int len = snprintf((char *)buf, TEST_URI_LEN + 1, 233c87c5fbaSopenharmony_ci "%0*d", TEST_URI_LEN, i); 234c87c5fbaSopenharmony_ci r = coap_resource_init(buf, len, 0); 235c87c5fbaSopenharmony_ci coap_add_resource(ctx, r); 236c87c5fbaSopenharmony_ci buf += TEST_URI_LEN + 1; 237c87c5fbaSopenharmony_ci } 238c87c5fbaSopenharmony_ci 239c87c5fbaSopenharmony_ci } 240c87c5fbaSopenharmony_ci#endif 241c87c5fbaSopenharmony_ci return ctx == NULL || pdu == NULL; 242c87c5fbaSopenharmony_ci} 243c87c5fbaSopenharmony_ci 244c87c5fbaSopenharmony_cistatic int 245c87c5fbaSopenharmony_cit_wkc_tests_remove(void) { 246c87c5fbaSopenharmony_ci coap_delete_pdu(pdu); 247c87c5fbaSopenharmony_ci coap_free_context(ctx); 248c87c5fbaSopenharmony_ci return 0; 249c87c5fbaSopenharmony_ci} 250c87c5fbaSopenharmony_ci 251c87c5fbaSopenharmony_ciCU_pSuite 252c87c5fbaSopenharmony_cit_init_wellknown_tests(void) { 253c87c5fbaSopenharmony_ci CU_pSuite suite; 254c87c5fbaSopenharmony_ci 255c87c5fbaSopenharmony_ci suite = CU_add_suite(".well-known/core", t_wkc_tests_create, t_wkc_tests_remove); 256c87c5fbaSopenharmony_ci if (!suite) { /* signal error */ 257c87c5fbaSopenharmony_ci fprintf(stderr, "W: cannot add .well-known/core test suite (%s)\n", 258c87c5fbaSopenharmony_ci CU_get_error_msg()); 259c87c5fbaSopenharmony_ci 260c87c5fbaSopenharmony_ci return NULL; 261c87c5fbaSopenharmony_ci } 262c87c5fbaSopenharmony_ci 263c87c5fbaSopenharmony_ci#define WKC_TEST(s,t) \ 264c87c5fbaSopenharmony_ci if (!CU_ADD_TEST(s,t)) { \ 265c87c5fbaSopenharmony_ci fprintf(stderr, "W: cannot add .well-known/core test (%s)\n", \ 266c87c5fbaSopenharmony_ci CU_get_error_msg()); \ 267c87c5fbaSopenharmony_ci } 268c87c5fbaSopenharmony_ci 269c87c5fbaSopenharmony_ci WKC_TEST(suite, t_wellknown1); 270c87c5fbaSopenharmony_ci WKC_TEST(suite, t_wellknown2); 271c87c5fbaSopenharmony_ci WKC_TEST(suite, t_wellknown3); 272c87c5fbaSopenharmony_ci WKC_TEST(suite, t_wellknown4); 273c87c5fbaSopenharmony_ci 274c87c5fbaSopenharmony_ci return suite; 275c87c5fbaSopenharmony_ci} 276c87c5fbaSopenharmony_ci#endif /* COAP_CLIENT_SUPPORT */ 277c87c5fbaSopenharmony_ci#endif /* COAP_SERVER_SUPPORT */ 278