libcoap 4.3.1
coap_debug.c
Go to the documentation of this file.
1/* coap_debug.c -- debug utilities
2 *
3 * Copyright (C) 2010--2012,2014--2022 Olaf Bergmann <bergmann@tzi.org> and others
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
16#include "coap3/coap_internal.h"
17
18#if defined(HAVE_STRNLEN) && defined(__GNUC__) && !defined(_GNU_SOURCE)
19#define _GNU_SOURCE 1
20#endif
21
22#include <stdarg.h>
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26
27#ifdef HAVE_ARPA_INET_H
28#include <arpa/inet.h>
29#endif
30#ifdef HAVE_WS2TCPIP_H
31#include <ws2tcpip.h>
32#endif
33
34#ifdef HAVE_TIME_H
35#include <time.h>
36#endif
37
38#ifdef WITH_LWIP
39# define fprintf(fd, ...) LWIP_PLATFORM_DIAG((__VA_ARGS__))
40# define fflush(...)
41#endif
42
43#ifdef WITH_CONTIKI
44# ifndef DEBUG
45# define DEBUG DEBUG_PRINT
46# endif /* DEBUG */
47#include "net/ip/uip-debug.h"
48#endif
49
50static coap_log_t maxlog = LOG_WARNING; /* default maximum log level */
51
52static int use_fprintf_for_show_pdu = 1; /* non zero to output with fprintf */
53
54const char *coap_package_name(void) {
55 return PACKAGE_NAME;
56}
57
58const char *coap_package_version(void) {
59 return PACKAGE_STRING;
60}
61
62const char *coap_package_build(void) {
63#ifdef LIBCOAP_PACKAGE_BUILD
64 return LIBCOAP_PACKAGE_BUILD;
65#else /* !LIBCOAP_PACKAGE_BUILD */
66 return PACKAGE_STRING;
67#endif /* !LIBCOAP_PACKAGE_BUILD */
68}
69
70void
71coap_set_show_pdu_output(int use_fprintf) {
72 use_fprintf_for_show_pdu = use_fprintf;
73}
74
77 return maxlog;
78}
79
80void
82 maxlog = level;
83}
84
85/* this array has the same order as the type log_t */
86static const char *loglevels[] = {
87 "EMRG", "ALRT", "CRIT", "ERR ", "WARN", "NOTE", "INFO", "DEBG", "????", "CIPH"
88};
89
90#ifdef HAVE_TIME_H
91
93print_timestamp(char *s, size_t len, coap_tick_t t) {
94 struct tm *tmp;
95 size_t lensofar;
96 time_t now = coap_ticks_to_rt(t);
97 tmp = localtime(&now);
98 lensofar = strftime(s, len, "%b %d %H:%M:%S", tmp);
99 if (len > lensofar + 4) {
100 lensofar += snprintf(&s[lensofar], len-lensofar, ".%03u",
101 (unsigned int)((coap_ticks_to_rt_us(t) % 1000000)/1000));
102 }
103 return lensofar;
104}
105
106#else /* alternative implementation: just print the timestamp */
107
109print_timestamp(char *s, size_t len, coap_tick_t t) {
110#ifdef HAVE_SNPRINTF
111 return snprintf(s, len, "%u.%03u",
112 (unsigned int)coap_ticks_to_rt(t),
113 (unsigned int)((coap_ticks_to_rt_us(t) % 1000000)/1000));
114#else /* HAVE_SNPRINTF */
115 /* @todo do manual conversion of timestamp */
116 return 0;
117#endif /* HAVE_SNPRINTF */
118}
119
120#endif /* HAVE_TIME_H */
121
122#ifndef HAVE_STRNLEN
131static inline size_t
132strnlen(const char *s, size_t maxlen) {
133 size_t n = 0;
134 while(*s++ && n < maxlen)
135 ++n;
136 return n;
137}
138#endif /* HAVE_STRNLEN */
139
140static size_t
141print_readable( const uint8_t *data, size_t len,
142 unsigned char *result, size_t buflen, int encode_always ) {
143 const uint8_t hex[] = "0123456789ABCDEF";
144 size_t cnt = 0;
145 assert(data || len == 0);
146
147 if (buflen == 0) { /* there is nothing we can do here but return */
148 return 0;
149 }
150
151 while (len) {
152 if (!encode_always && isprint(*data)) {
153 if (cnt+1 < buflen) { /* keep one byte for terminating zero */
154 *result++ = *data;
155 ++cnt;
156 } else {
157 break;
158 }
159 } else {
160 if (cnt+4 < buflen) { /* keep one byte for terminating zero */
161 *result++ = '\\';
162 *result++ = 'x';
163 *result++ = hex[(*data & 0xf0) >> 4];
164 *result++ = hex[*data & 0x0f];
165 cnt += 4;
166 } else
167 break;
168 }
169
170 ++data; --len;
171 }
172
173 *result = '\0'; /* add a terminating zero */
174 return cnt;
175}
176
177#ifndef min
178#define min(a,b) ((a) < (b) ? (a) : (b))
179#endif
180
181/*
182 * Returned buf is always NULL terminated.
183 * Returned size is number of characters, not including NULL terminator.
184 */
185size_t
186coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len) {
187#if defined( HAVE_ARPA_INET_H ) || defined( HAVE_WS2TCPIP_H )
188 const void *addrptr = NULL;
189 in_port_t port;
190 unsigned char *p = buf;
191 size_t need_buf;
192
193 assert(buf);
194 assert(len);
195 buf[0] = '\000';
196
197 switch (addr->addr.sa.sa_family) {
198 case AF_INET:
199 if (len < INET_ADDRSTRLEN + 1) /* Include : */
200 return 0;
201 addrptr = &addr->addr.sin.sin_addr;
202 port = ntohs(addr->addr.sin.sin_port);
203 need_buf = INET_ADDRSTRLEN;
204 break;
205 case AF_INET6:
206 if (len < INET6_ADDRSTRLEN + 3) /* Include [ ] : */
207 return 0;
208
209 *p++ = '[';
210
211 addrptr = &addr->addr.sin6.sin6_addr;
212 port = ntohs(addr->addr.sin6.sin6_port);
213 need_buf = INET6_ADDRSTRLEN;
214
215 break;
216 default:
217 /* Include trailing NULL if possible */
218 memcpy(buf, "(unknown address type)", min(22+1, len));
219 buf[len-1] = '\000';
220 return min(22, len);
221 }
222
223 /* Cast needed for Windows, since it doesn't have the correct API signature. */
224 if (inet_ntop(addr->addr.sa.sa_family, addrptr, (char *)p,
225 min(len, need_buf)) == 0) {
226 perror("coap_print_addr");
227 buf[0] = '\000';
228 return 0;
229 }
230
231 p += strlen((char *)p);
232
233 if (addr->addr.sa.sa_family == AF_INET6) {
234 if (p + 1 < buf + len) {
235 *p++ = ']';
236 } else
237 return p - buf; /* Already NULL terminated */
238 }
239
240 /* Cannot rely on snprintf() return value for short buffers */
241 snprintf((char *)p, buf + len - p, ":%d", port);
242
243 return strlen((char *)buf);
244#else /* HAVE_ARPA_INET_H */
245# if WITH_CONTIKI
246 unsigned char *p = buf;
247 uint8_t i;
248# if NETSTACK_CONF_WITH_IPV6
249 const uint8_t hex[] = "0123456789ABCDEF";
250
251 assert(buf);
252 assert(len);
253 buf[0] = '\000';
254 if (len < 42)
255 return 0;
256
257 *p++ = '[';
258
259 for (i=0; i < 16; i += 2) {
260 if (i) {
261 *p++ = ':';
262 }
263 *p++ = hex[(addr->addr.u8[i] & 0xf0) >> 4];
264 *p++ = hex[(addr->addr.u8[i] & 0x0f)];
265 *p++ = hex[(addr->addr.u8[i+1] & 0xf0) >> 4];
266 *p++ = hex[(addr->addr.u8[i+1] & 0x0f)];
267 }
268 *p++ = ']';
269# else /* WITH_UIP6 */
270# warning "IPv4 network addresses will not be included in debug output"
271
272 if (len < 21) {
273 *p = '\000';
274 return 0;
275 }
276# endif /* WITH_UIP6 */
277 if (buf + len - p < 6) {
278 *p = '\000';
279 return p - buf;
280 }
281
282#ifdef HAVE_SNPRINTF
283 /* Cannot rely on snprintf() return value for short buffers */
284 snprintf((char *)p, buf + len - p, ":%d", uip_htons(addr->port));
285#else /* HAVE_SNPRINTF */
286 /* @todo manual conversion of port number */
287 *p = '\000';
288#endif /* HAVE_SNPRINTF */
289
290 return strlen((char *)p);
291# else /* WITH_CONTIKI */
292 /* TODO: output addresses manually */
293# warning "inet_ntop() not available, network addresses will not be included in debug output"
294# endif /* WITH_CONTIKI */
295 buf[0] = '\000';
296 return 0;
297#endif
298}
299
300#ifdef WITH_CONTIKI
301# define fprintf(fd, ...) { (void)fd; PRINTF(__VA_ARGS__); }
302# define fflush(...)
303
304# ifdef HAVE_VPRINTF
305# define vfprintf(fd, ...) { (void)fd; vprintf(__VA_ARGS__); }
306# else /* HAVE_VPRINTF */
307# define vfprintf(fd, ...) { (void)fd; PRINTF(__VA_ARGS__); }
308# endif /* HAVE_VPRINTF */
309#endif /* WITH_CONTIKI */
310
312static const char *
313msg_type_string(uint16_t t) {
314 static const char *types[] = { "CON", "NON", "ACK", "RST", "???" };
315
316 return types[min(t, sizeof(types)/sizeof(char *) - 1)];
317}
318
320static const char *
321msg_code_string(uint16_t c) {
322 static const char *methods[] = { "0.00", "GET", "POST", "PUT", "DELETE",
323 "FETCH", "PATCH", "iPATCH" };
324 static const char *signals[] = { "7.00", "CSM", "Ping", "Pong", "Release",
325 "Abort" };
326 static char buf[5];
327
328 if (c < sizeof(methods)/sizeof(const char *)) {
329 return methods[c];
330 } else if (c >= 224 && c - 224 < (int)(sizeof(signals)/sizeof(const char *))) {
331 return signals[c-224];
332 } else {
333 snprintf(buf, sizeof(buf), "%u.%02u", (c >> 5) & 0x7, c & 0x1f);
334 return buf;
335 }
336}
337
339static const char *
340msg_option_string(uint8_t code, uint16_t option_type) {
341 struct option_desc_t {
342 uint16_t type;
343 const char *name;
344 };
345
346 static struct option_desc_t options[] = {
347 { COAP_OPTION_IF_MATCH, "If-Match" },
348 { COAP_OPTION_URI_HOST, "Uri-Host" },
349 { COAP_OPTION_ETAG, "ETag" },
350 { COAP_OPTION_IF_NONE_MATCH, "If-None-Match" },
351 { COAP_OPTION_OBSERVE, "Observe" },
352 { COAP_OPTION_URI_PORT, "Uri-Port" },
353 { COAP_OPTION_LOCATION_PATH, "Location-Path" },
354 { COAP_OPTION_URI_PATH, "Uri-Path" },
355 { COAP_OPTION_CONTENT_FORMAT, "Content-Format" },
356 { COAP_OPTION_MAXAGE, "Max-Age" },
357 { COAP_OPTION_URI_QUERY, "Uri-Query" },
358 { COAP_OPTION_HOP_LIMIT, "Hop-Limit" },
359 { COAP_OPTION_ACCEPT, "Accept" },
360 { COAP_OPTION_LOCATION_QUERY, "Location-Query" },
361 { COAP_OPTION_BLOCK2, "Block2" },
362 { COAP_OPTION_BLOCK1, "Block1" },
363 { COAP_OPTION_SIZE2, "Size2" },
364 { COAP_OPTION_PROXY_URI, "Proxy-Uri" },
365 { COAP_OPTION_PROXY_SCHEME, "Proxy-Scheme" },
366 { COAP_OPTION_SIZE1, "Size1" },
367 { COAP_OPTION_ECHO, "Echo" },
368 { COAP_OPTION_NORESPONSE, "No-Response" },
369 { COAP_OPTION_RTAG, "Request-Tag" }
370 };
371
372 static struct option_desc_t options_csm[] = {
373 { COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE, "Max-Message-Size" },
374 { COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER, "Block-Wise-Transfer" }
375 };
376
377 static struct option_desc_t options_pingpong[] = {
378 { COAP_SIGNALING_OPTION_CUSTODY, "Custody" }
379 };
380
381 static struct option_desc_t options_release[] = {
382 { COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS, "Alternative-Address" },
383 { COAP_SIGNALING_OPTION_HOLD_OFF, "Hold-Off" }
384 };
385
386 static struct option_desc_t options_abort[] = {
387 { COAP_SIGNALING_OPTION_BAD_CSM_OPTION, "Bad-CSM-Option" }
388 };
389
390 static char buf[6];
391 size_t i;
392
393 if (code == COAP_SIGNALING_CSM) {
394 for (i = 0; i < sizeof(options_csm)/sizeof(struct option_desc_t); i++) {
395 if (option_type == options_csm[i].type) {
396 return options_csm[i].name;
397 }
398 }
399 } else if (code == COAP_SIGNALING_PING || code == COAP_SIGNALING_PONG) {
400 for (i = 0; i < sizeof(options_pingpong)/sizeof(struct option_desc_t); i++) {
401 if (option_type == options_pingpong[i].type) {
402 return options_pingpong[i].name;
403 }
404 }
405 } else if (code == COAP_SIGNALING_RELEASE) {
406 for (i = 0; i < sizeof(options_release)/sizeof(struct option_desc_t); i++) {
407 if (option_type == options_release[i].type) {
408 return options_release[i].name;
409 }
410 }
411 } else if (code == COAP_SIGNALING_ABORT) {
412 for (i = 0; i < sizeof(options_abort)/sizeof(struct option_desc_t); i++) {
413 if (option_type == options_abort[i].type) {
414 return options_abort[i].name;
415 }
416 }
417 } else {
418 /* search option_type in list of known options */
419 for (i = 0; i < sizeof(options)/sizeof(struct option_desc_t); i++) {
420 if (option_type == options[i].type) {
421 return options[i].name;
422 }
423 }
424 }
425 /* unknown option type, just print to buf */
426 snprintf(buf, sizeof(buf), "%u", option_type);
427 return buf;
428}
429
430static unsigned int
431print_content_format(unsigned int format_type,
432 unsigned char *result, unsigned int buflen) {
433 struct desc_t {
434 unsigned int type;
435 const char *name;
436 };
437
438 static struct desc_t formats[] = {
439 { COAP_MEDIATYPE_TEXT_PLAIN, "text/plain" },
440 { COAP_MEDIATYPE_APPLICATION_LINK_FORMAT, "application/link-format" },
441 { COAP_MEDIATYPE_APPLICATION_XML, "application/xml" },
442 { COAP_MEDIATYPE_APPLICATION_OCTET_STREAM, "application/octet-stream" },
443 { COAP_MEDIATYPE_APPLICATION_RDF_XML, "application/rdf+xml" },
444 { COAP_MEDIATYPE_APPLICATION_EXI, "application/exi" },
445 { COAP_MEDIATYPE_APPLICATION_JSON, "application/json" },
446 { COAP_MEDIATYPE_APPLICATION_CBOR, "application/cbor" },
447 { COAP_MEDIATYPE_APPLICATION_CWT, "application/cwt" },
448 { COAP_MEDIATYPE_APPLICATION_COSE_SIGN, "application/cose; cose-type=\"cose-sign\"" },
449 { COAP_MEDIATYPE_APPLICATION_COSE_SIGN1, "application/cose; cose-type=\"cose-sign1\"" },
450 { COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT, "application/cose; cose-type=\"cose-encrypt\"" },
451 { COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0, "application/cose; cose-type=\"cose-encrypt0\"" },
452 { COAP_MEDIATYPE_APPLICATION_COSE_MAC, "application/cose; cose-type=\"cose-mac\"" },
453 { COAP_MEDIATYPE_APPLICATION_COSE_MAC0, "application/cose; cose-type=\"cose-mac0\"" },
454 { COAP_MEDIATYPE_APPLICATION_COSE_KEY, "application/cose-key" },
455 { COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET, "application/cose-key-set" },
456 { COAP_MEDIATYPE_APPLICATION_SENML_JSON, "application/senml+json" },
457 { COAP_MEDIATYPE_APPLICATION_SENSML_JSON, "application/sensml+json" },
458 { COAP_MEDIATYPE_APPLICATION_SENML_CBOR, "application/senml+cbor" },
459 { COAP_MEDIATYPE_APPLICATION_SENSML_CBOR, "application/sensml+cbor" },
460 { COAP_MEDIATYPE_APPLICATION_SENML_EXI, "application/senml-exi" },
461 { COAP_MEDIATYPE_APPLICATION_SENSML_EXI, "application/sensml-exi" },
462 { COAP_MEDIATYPE_APPLICATION_SENML_XML, "application/senml+xml" },
463 { COAP_MEDIATYPE_APPLICATION_SENSML_XML, "application/sensml+xml" },
464 { COAP_MEDIATYPE_APPLICATION_COAP_GROUP_JSON, "application/coap-group+json" },
465 { COAP_MEDIATYPE_APPLICATION_DOTS_CBOR, "application/dots+cbor" },
466 { 75, "application/dcaf+cbor" }
467 };
468
469 size_t i;
470
471 /* search format_type in list of known content formats */
472 for (i = 0; i < sizeof(formats)/sizeof(struct desc_t); i++) {
473 if (format_type == formats[i].type) {
474 return snprintf((char *)result, buflen, "%s", formats[i].name);
475 }
476 }
477
478 /* unknown content format, just print numeric value to buf */
479 return snprintf((char *)result, buflen, "%d", format_type);
480}
481
488is_binary(int content_format) {
489 return !(content_format == -1 ||
490 content_format == COAP_MEDIATYPE_TEXT_PLAIN ||
491 content_format == COAP_MEDIATYPE_APPLICATION_LINK_FORMAT ||
492 content_format == COAP_MEDIATYPE_APPLICATION_XML ||
493 content_format == COAP_MEDIATYPE_APPLICATION_JSON);
494}
495
496#define COAP_DO_SHOW_OUTPUT_LINE \
497 do { \
498 if (use_fprintf_for_show_pdu) { \
499 fprintf(COAP_DEBUG_FD, "%s", outbuf); \
500 } \
501 else { \
502 coap_log(level, "%s", outbuf); \
503 } \
504 } while (0)
505
506/*
507 * It is possible to override the output debug buffer size and hence control
508 * the amount of information printed out about a CoAP PDU.
509 * Note: Adding a byte may be insufficient to output the next byte of the PDU.
510 *
511 * This is done by the adding of a -DCOAP_DEBUG_BUF_SIZE=nnnn option to the
512 * CPPFLAGS parameter that is optionally used on the ./configure command line.
513 *
514 * E.g. ./configure CPPFLAGS="-DCOAP_DEBUG_BUF_SIZE=4096"
515 *
516 */
517
518#if COAP_DEBUG_BUF_SIZE < 5
519#error "COAP_DEBUG_BUF_SIZE must be at least 5, should be >= 32 to be useful"
520#endif /* COAP_DEBUG_BUF_SIZE < 5 */
521
522void
524#if COAP_CONSTRAINED_STACK
525 static coap_mutex_t static_show_pdu_mutex = COAP_MUTEX_INITIALIZER;
526 /* Proxy-Uri: can be 1034 bytes long */
527 static unsigned char buf[min(COAP_DEBUG_BUF_SIZE, 1035)];
528 static char outbuf[COAP_DEBUG_BUF_SIZE];
529#else /* ! COAP_CONSTRAINED_STACK */
530 /* Proxy-Uri: can be 1034 bytes long */
531 unsigned char buf[min(COAP_DEBUG_BUF_SIZE, 1035)];
532 char outbuf[COAP_DEBUG_BUF_SIZE];
533#endif /* ! COAP_CONSTRAINED_STACK */
534 size_t buf_len = 0; /* takes the number of bytes written to buf */
535 int encode = 0, have_options = 0, i;
536 coap_opt_iterator_t opt_iter;
537 coap_opt_t *option;
538 int content_format = -1;
539 size_t data_len;
540 const uint8_t *data;
541 uint32_t opt_len;
542 const uint8_t* opt_val;
543 size_t outbuflen = 0;
544
545 /* Save time if not needed */
546 if (level > coap_get_log_level())
547 return;
548
549#if COAP_CONSTRAINED_STACK
550 coap_mutex_lock(&static_show_pdu_mutex);
551#endif /* COAP_CONSTRAINED_STACK */
552
553 snprintf(outbuf, sizeof(outbuf), "v:%d t:%s c:%s i:%04x {",
555 msg_code_string(pdu->code), pdu->mid);
556
557 for (i = 0; i < pdu->token_length; i++) {
558 outbuflen = strlen(outbuf);
559 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
560 "%02x", pdu->token[i]);
561 }
562 outbuflen = strlen(outbuf);
563 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "}");
564
565 /* show options, if any */
567
568 outbuflen = strlen(outbuf);
569 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " [");
570 while ((option = coap_option_next(&opt_iter))) {
571 buf[0] = '\000';
572 if (!have_options) {
573 have_options = 1;
574 } else {
575 outbuflen = strlen(outbuf);
576 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ",");
577 }
578
579 if (pdu->code == COAP_SIGNALING_CODE_CSM) switch(opt_iter.number) {
581 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
583 coap_opt_length(option)));
584 break;
585 default:
586 buf_len = 0;
587 break;
588 } else if (pdu->code == COAP_SIGNALING_CODE_PING
589 || pdu->code == COAP_SIGNALING_CODE_PONG) {
590 buf_len = 0;
591 } else if (pdu->code == COAP_SIGNALING_CODE_RELEASE) switch(opt_iter.number) {
593 buf_len = print_readable(coap_opt_value(option),
594 coap_opt_length(option),
595 buf, sizeof(buf), 0);
596 break;
598 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
600 coap_opt_length(option)));
601 break;
602 default:
603 buf_len = 0;
604 break;
605 } else if (pdu->code == COAP_SIGNALING_CODE_ABORT) switch(opt_iter.number) {
607 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
609 coap_opt_length(option)));
610 break;
611 default:
612 buf_len = 0;
613 break;
614 } else switch (opt_iter.number) {
617 content_format = (int)coap_decode_var_bytes(coap_opt_value(option),
618 coap_opt_length(option));
619
620 buf_len = print_content_format(content_format, buf, sizeof(buf));
621 break;
622
625 /* split block option into number/more/size where more is the
626 * letter M if set, the _ otherwise */
627 if (COAP_OPT_BLOCK_SZX(option) == 7) {
628 if (coap_get_data(pdu, &data_len, &data))
629 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/BERT(%zu)",
630 coap_opt_block_num(option), /* block number */
631 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
632 data_len);
633 else
634 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/BERT",
635 coap_opt_block_num(option), /* block number */
636 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_'); /* M bit */
637 } else {
638 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/%u",
639 coap_opt_block_num(option), /* block number */
640 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
641 (1 << (COAP_OPT_BLOCK_SZX(option) + 4))); /* block size */
642 }
643
644 break;
645
652 /* show values as unsigned decimal value */
653 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
655 coap_opt_length(option)));
656 break;
657
659 case COAP_OPTION_ETAG:
660 case COAP_OPTION_ECHO:
662 case COAP_OPTION_RTAG:
663 opt_len = coap_opt_length(option);
664 opt_val = coap_opt_value(option);
665 snprintf((char *)buf, sizeof(buf), "0x");
666 for (i = 0; (uint32_t)i < opt_len; i++) {
667 buf_len = strlen((char *)buf);
668 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
669 "%02x", opt_val[i]);
670 }
671 buf_len = strlen((char *)buf);
672 break;
673 default:
674 /* generic output function for all other option types */
675 if (opt_iter.number == COAP_OPTION_URI_PATH ||
676 opt_iter.number == COAP_OPTION_PROXY_URI ||
677 opt_iter.number == COAP_OPTION_URI_HOST ||
678 opt_iter.number == COAP_OPTION_LOCATION_PATH ||
680 opt_iter.number == COAP_OPTION_PROXY_SCHEME ||
681 opt_iter.number == COAP_OPTION_URI_QUERY) {
682 encode = 0;
683 } else {
684 encode = 1;
685 }
686
687 buf_len = print_readable(coap_opt_value(option),
688 coap_opt_length(option),
689 buf, sizeof(buf), encode);
690 }
691
692 outbuflen = strlen(outbuf);
693 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
694 " %s:%.*s", msg_option_string(pdu->code, opt_iter.number),
695 (int)buf_len, buf);
696 }
697
698 outbuflen = strlen(outbuf);
699 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " ]");
700
701 if (coap_get_data(pdu, &data_len, &data)) {
702
703 outbuflen = strlen(outbuf);
704 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " :: ");
705
706 if (is_binary(content_format) || !isprint(data[0])) {
707 size_t keep_data_len = data_len;
708 const uint8_t *keep_data = data;
709
710 outbuflen = strlen(outbuf);
711 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
712 "binary data length %zu\n", data_len);
714 /*
715 * Output hex dump of binary data as a continuous entry
716 */
717 outbuf[0] = '\000';
718 snprintf(outbuf, sizeof(outbuf), "<<");
719 while (data_len--) {
720 outbuflen = strlen(outbuf);
721 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
722 "%02x", *data++);
723 }
724 outbuflen = strlen(outbuf);
725 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
726 data_len = keep_data_len;
727 data = keep_data;
728 outbuflen = strlen(outbuf);
729 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
731 /*
732 * Output ascii readable (if possible), immediately under the
733 * hex value of the character output above to help binary debugging
734 */
735 outbuf[0] = '\000';
736 snprintf(outbuf, sizeof(outbuf), "<<");
737 while (data_len--) {
738 outbuflen = strlen(outbuf);
739 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
740 "%c ", isprint (*data) ? *data : '.');
741 data++;
742 }
743 outbuflen = strlen(outbuf);
744 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
745 } else {
746 size_t max_length;
747
748 outbuflen = strlen(outbuf);
749 max_length = sizeof(outbuf)-outbuflen;
750 if (max_length > 1) {
751 outbuf[outbuflen++] = '\'';
752 outbuf[outbuflen] = '\000';
753 max_length--;
754 }
755 if (max_length > 1) {
756 outbuflen += print_readable(data, data_len,
757 (unsigned char*)&outbuf[outbuflen],
758 max_length, 0);
759 }
760 /* print_readable may be handling unprintables - hence headroom of 4 */
761 if (outbuflen < sizeof(outbuf)-4-1) {
762 outbuf[outbuflen++] = '\'';
763 outbuf[outbuflen] = '\000';
764 }
765 }
766 }
767
768 outbuflen = strlen(outbuf);
769 if (outbuflen == sizeof(outbuf)-1) outbuflen--;
770 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
772
773#if COAP_CONSTRAINED_STACK
774 coap_mutex_unlock(&static_show_pdu_mutex);
775#endif /* COAP_CONSTRAINED_STACK */
776}
777
779{
780 char buffer[128];
781 coap_string_tls_version(buffer, sizeof(buffer));
782 coap_log(level, "%s\n", buffer);
783}
784
785char *coap_string_tls_version(char *buffer, size_t bufsize)
786{
788 char beta[8];
789 char sub[2];
790 char b_beta[8];
791 char b_sub[2];
792
793 switch (tls_version->type) {
795 snprintf(buffer, bufsize, "TLS Library: None");
796 break;
798 snprintf(buffer, bufsize, "TLS Library: TinyDTLS - runtime %lu.%lu.%lu, "
799 "libcoap built for %lu.%lu.%lu",
800 (unsigned long)(tls_version->version >> 16),
801 (unsigned long)((tls_version->version >> 8) & 0xff),
802 (unsigned long)(tls_version->version & 0xff),
803 (unsigned long)(tls_version->built_version >> 16),
804 (unsigned long)((tls_version->built_version >> 8) & 0xff),
805 (unsigned long)(tls_version->built_version & 0xff));
806 break;
808 switch (tls_version->version &0xf) {
809 case 0:
810 strcpy(beta, "-dev");
811 break;
812 case 0xf:
813 strcpy(beta, "");
814 break;
815 default:
816 strcpy(beta, "-beta");
817 beta[5] = (tls_version->version &0xf) + '0';
818 beta[6] = '\000';
819 break;
820 }
821 sub[0] = ((tls_version->version >> 4) & 0xff) ?
822 ((tls_version->version >> 4) & 0xff) + 'a' -1 : '\000';
823 sub[1] = '\000';
824 switch (tls_version->built_version &0xf) {
825 case 0:
826 strcpy(b_beta, "-dev");
827 break;
828 case 0xf:
829 strcpy(b_beta, "");
830 break;
831 default:
832 strcpy(b_beta, "-beta");
833 b_beta[5] = (tls_version->built_version &0xf) + '0';
834 b_beta[6] = '\000';
835 break;
836 }
837 b_sub[0] = ((tls_version->built_version >> 4) & 0xff) ?
838 ((tls_version->built_version >> 4) & 0xff) + 'a' -1 : '\000';
839 b_sub[1] = '\000';
840 snprintf(buffer, bufsize, "TLS Library: OpenSSL - runtime "
841 "%lu.%lu.%lu%s%s, libcoap built for %lu.%lu.%lu%s%s",
842 (unsigned long)(tls_version->version >> 28),
843 (unsigned long)((tls_version->version >> 20) & 0xff),
844 (unsigned long)((tls_version->version >> 12) & 0xff), sub, beta,
845 (unsigned long)(tls_version->built_version >> 28),
846 (unsigned long)((tls_version->built_version >> 20) & 0xff),
847 (unsigned long)((tls_version->built_version >> 12) & 0xff),
848 b_sub, b_beta);
849 break;
851 snprintf(buffer, bufsize, "TLS Library: GnuTLS - runtime %lu.%lu.%lu, "
852 "libcoap built for %lu.%lu.%lu",
853 (unsigned long)(tls_version->version >> 16),
854 (unsigned long)((tls_version->version >> 8) & 0xff),
855 (unsigned long)(tls_version->version & 0xff),
856 (unsigned long)(tls_version->built_version >> 16),
857 (unsigned long)((tls_version->built_version >> 8) & 0xff),
858 (unsigned long)(tls_version->built_version & 0xff));
859 break;
861 snprintf(buffer, bufsize, "TLS Library: Mbed TLS - runtime %lu.%lu.%lu, "
862 "libcoap built for %lu.%lu.%lu",
863 (unsigned long)(tls_version->version >> 24),
864 (unsigned long)((tls_version->version >> 16) & 0xff),
865 (unsigned long)((tls_version->version >> 8) & 0xff),
866 (unsigned long)(tls_version->built_version >> 24),
867 (unsigned long)((tls_version->built_version >> 16) & 0xff),
868 (unsigned long)((tls_version->built_version >> 8) & 0xff));
869 break;
870 default:
871 snprintf(buffer, bufsize, "Library type %d unknown", tls_version->type);
872 break;
873 }
874 return buffer;
875}
876
877char *coap_string_tls_support(char *buffer, size_t bufsize)
878{
880 const int have_tls = coap_tls_is_supported();
881 const int have_dtls = coap_dtls_is_supported();
882
883 if (have_dtls == 0 && have_tls == 0) {
884 snprintf(buffer, bufsize, "(No DTLS or TLS support)");
885 return buffer;
886 }
887 switch (tls_version->type) {
889 snprintf(buffer, bufsize, "(No DTLS or TLS support)");
890 break;
892 snprintf(buffer, bufsize,
893 "(%sDTLS and%s TLS support; PSK, no PKI, no PKCS11, and RPK support)",
894 have_dtls ? "" : " no",
895 have_tls ? "" : " no");
896 break;
898 snprintf(buffer, bufsize,
899 "(%sDTLS and%s TLS support; PSK, PKI, PKCS11, and no RPK support)",
900 have_dtls ? "" : " no",
901 have_tls ? "" : " no");
902 break;
904 if (tls_version->version >= 0x030606)
905 snprintf(buffer, bufsize,
906 "(%sDTLS and%s TLS support; PSK, PKI, PKCS11, and RPK support)",
907 have_dtls ? "" : " no",
908 have_tls ? "" : " no");
909 else
910 snprintf(buffer, bufsize,
911 "(%sDTLS and%s TLS support; PSK, PKI, PKCS11, and no RPK support)",
912 have_dtls ? "" : " no",
913 have_tls ? "" : " no");
914 break;
916 snprintf(buffer, bufsize,
917 "(%sDTLS and%s TLS support; PSK, PKI, no PKCS11, and no RPK support)",
918 have_dtls ? "" : " no",
919 have_tls ? "" : " no");
920 break;
921 default:
922 buffer[0] = '\000';
923 break;
924 }
925 return buffer;
926}
927
929
931 log_handler = handler;
932}
933
934void
935coap_log_impl(coap_log_t level, const char *format, ...) {
936
937 if (maxlog < level)
938 return;
939
940 if (log_handler) {
941#if COAP_CONSTRAINED_STACK
942 static coap_mutex_t static_log_mutex = COAP_MUTEX_INITIALIZER;
943 static char message[COAP_DEBUG_BUF_SIZE];
944#else /* ! COAP_CONSTRAINED_STACK */
945 char message[COAP_DEBUG_BUF_SIZE];
946#endif /* ! COAP_CONSTRAINED_STACK */
947 va_list ap;
948 va_start(ap, format);
949#if COAP_CONSTRAINED_STACK
950 coap_mutex_lock(&static_log_mutex);
951#endif /* COAP_CONSTRAINED_STACK */
952
953 vsnprintf( message, sizeof(message), format, ap);
954 va_end(ap);
955 log_handler(level, message);
956#if COAP_CONSTRAINED_STACK
957 coap_mutex_unlock(&static_log_mutex);
958#endif /* COAP_CONSTRAINED_STACK */
959 } else {
960 char timebuf[32];
961 coap_tick_t now;
962 va_list ap;
963 FILE *log_fd;
964 size_t len;
965
966 log_fd = level <= LOG_CRIT ? COAP_ERR_FD : COAP_DEBUG_FD;
967
968 coap_ticks(&now);
969 len = print_timestamp(timebuf,sizeof(timebuf), now);
970 if (len)
971 fprintf(log_fd, "%.*s ", (int)len, timebuf);
972
973 if (level <= COAP_LOG_CIPHERS)
974 fprintf(log_fd, "%s ", loglevels[level]);
975
976 va_start(ap, format);
977 vfprintf(log_fd, format, ap);
978 va_end(ap);
979 fflush(log_fd);
980 }
981}
982
983static struct packet_num_interval {
984 int start;
985 int end;
988static int packet_loss_level = 0;
989static int send_packet_count = 0;
990
991int coap_debug_set_packet_loss(const char *loss_level) {
992 const char *p = loss_level;
993 char *end = NULL;
994 int n = (int)strtol(p, &end, 10), i = 0;
995 if (end == p || n < 0)
996 return 0;
997 if (*end == '%') {
998 if (n > 100)
999 n = 100;
1000 packet_loss_level = n * 65536 / 100;
1001 coap_log(LOG_DEBUG, "packet loss level set to %d%%\n", n);
1002 } else {
1003 if (n <= 0)
1004 return 0;
1005 while (i < 10) {
1007 if (*end == '-') {
1008 p = end + 1;
1009 n = (int)strtol(p, &end, 10);
1010 if (end == p || n <= 0)
1011 return 0;
1012 }
1014 if (*end == 0)
1015 break;
1016 if (*end != ',')
1017 return 0;
1018 p = end + 1;
1019 n = (int)strtol(p, &end, 10);
1020 if (end == p || n <= 0)
1021 return 0;
1022 }
1023 if (i == 10)
1024 return 0;
1026 }
1028 return 1;
1029}
1030
1033 if (num_packet_loss_intervals > 0) {
1034 int i;
1035 for (i = 0; i < num_packet_loss_intervals; i++) {
1038 coap_log(LOG_DEBUG, "Packet %u dropped\n", send_packet_count);
1039 return 0;
1040 }
1041 }
1042 }
1043 if ( packet_loss_level > 0 ) {
1044 uint16_t r = 0;
1045 coap_prng( (uint8_t*)&r, 2 );
1046 if ( r < packet_loss_level ) {
1047 coap_log(LOG_DEBUG, "Packet %u dropped\n", send_packet_count);
1048 return 0;
1049 }
1050 }
1051 return 1;
1052}
static int packet_loss_level
Definition: coap_debug.c:988
static struct packet_num_interval packet_loss_intervals[10]
static int send_packet_count
Definition: coap_debug.c:989
int coap_debug_set_packet_loss(const char *loss_level)
Set the packet loss level for testing.
Definition: coap_debug.c:991
static coap_log_t maxlog
Definition: coap_debug.c:50
static coap_log_handler_t log_handler
Definition: coap_debug.c:928
COAP_STATIC_INLINE int is_binary(int content_format)
Returns 1 if the given content_format is either unknown or known to carry binary data.
Definition: coap_debug.c:488
static const char * msg_code_string(uint16_t c)
Returns a textual description of the method or response code.
Definition: coap_debug.c:321
#define COAP_DO_SHOW_OUTPUT_LINE
Definition: coap_debug.c:496
static size_t print_readable(const uint8_t *data, size_t len, unsigned char *result, size_t buflen, int encode_always)
Definition: coap_debug.c:141
static const char * msg_option_string(uint8_t code, uint16_t option_type)
Returns a textual description of the option name.
Definition: coap_debug.c:340
static size_t strnlen(const char *s, size_t maxlen)
A length-safe strlen() fake.
Definition: coap_debug.c:132
static const char * loglevels[]
Definition: coap_debug.c:86
COAP_STATIC_INLINE size_t print_timestamp(char *s, size_t len, coap_tick_t t)
Definition: coap_debug.c:109
#define min(a, b)
Definition: coap_debug.c:178
static const char * msg_type_string(uint16_t t)
Returns a textual description of the message type t.
Definition: coap_debug.c:313
static int use_fprintf_for_show_pdu
Definition: coap_debug.c:52
static int num_packet_loss_intervals
Definition: coap_debug.c:987
int coap_debug_send_packet(void)
Check to see whether a packet should be sent or not.
Definition: coap_debug.c:1031
static unsigned int print_content_format(unsigned int format_type, unsigned char *result, unsigned int buflen)
Definition: coap_debug.c:431
Pulls together all the internal only header files.
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
Definition: coap_option.h:26
#define COAP_OPT_BLOCK_SZX(opt)
Returns the value of the SZX-field of a Block option opt.
Definition: block.h:77
#define COAP_OPT_BLOCK_MORE(opt)
Returns the value of the More-bit of a Block option opt.
Definition: block.h:73
unsigned int coap_opt_block_num(const coap_opt_t *block_opt)
Returns the value of field num in the given block option block_opt.
Definition: block.c:27
void coap_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition: coap_time.h:127
coap_time_t coap_ticks_to_rt(coap_tick_t t)
Helper function that converts coap ticks to wallclock time.
uint64_t coap_ticks_to_rt_us(coap_tick_t t)
Helper function that converts coap ticks to POSIX wallclock time in us.
int coap_prng(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
Definition: coap_prng.c:105
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
Definition: coap_notls.c:33
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition: coap_notls.c:28
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition: coap_notls.c:23
@ COAP_TLS_LIBRARY_GNUTLS
Using GnuTLS library.
Definition: coap_dtls.h:68
@ COAP_TLS_LIBRARY_TINYDTLS
Using TinyDTLS library.
Definition: coap_dtls.h:66
@ COAP_TLS_LIBRARY_NOTLS
No DTLS library.
Definition: coap_dtls.h:65
@ COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
Definition: coap_dtls.h:67
@ COAP_TLS_LIBRARY_MBEDTLS
Using Mbed TLS library.
Definition: coap_dtls.h:69
unsigned int coap_decode_var_bytes(const uint8_t *buf, size_t len)
Decodes multiple-length byte sequences.
Definition: encode.c:36
void coap_set_log_handler(coap_log_handler_t handler)
Add a custom log callback handler.
Definition: coap_debug.c:930
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition: coap_debug.c:76
char * coap_string_tls_version(char *buffer, size_t bufsize)
Build a string containing the current (D)TLS library linked with and built for version.
Definition: coap_debug.c:785
int coap_log_t
Logging type.
Definition: coap_debug.h:44
void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu)
Display the contents of the specified pdu.
Definition: coap_debug.c:523
char * coap_string_tls_support(char *buffer, size_t bufsize)
Build a string containing the current (D)TLS library support.
Definition: coap_debug.c:877
#define COAP_ERR_FD
Used for output for LOG_CRIT to LOG_EMERG.
Definition: coap_debug.h:38
#define LOG_DEBUG
Definition: coap_debug.h:81
const char * coap_package_version(void)
Get the library package version.
Definition: coap_debug.c:58
void coap_set_log_level(coap_log_t level)
Sets the log level to the specified value.
Definition: coap_debug.c:81
void coap_log_impl(coap_log_t level, const char *format,...)
Writes the given text to COAP_ERR_FD (for level <= LOG_CRIT) or COAP_DEBUG_FD (for level >= LOG_ERR).
Definition: coap_debug.c:935
#define COAP_LOG_CIPHERS
Definition: coap_debug.h:87
size_t coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
Definition: coap_debug.c:186
#define LOG_CRIT
Definition: coap_debug.h:66
#define COAP_DEBUG_FD
Used for output for LOG_DEBUG to LOG_ERR.
Definition: coap_debug.h:31
const char * coap_package_build(void)
Get the library package build.
Definition: coap_debug.c:62
void coap_show_tls_version(coap_log_t level)
Display the current (D)TLS library linked with and built for version.
Definition: coap_debug.c:778
void coap_set_show_pdu_output(int use_fprintf)
Defines the output mode for the coap_show_pdu() function.
Definition: coap_debug.c:71
#define LOG_WARNING
Definition: coap_debug.h:72
const char * coap_package_name(void)
Get the library package name.
Definition: coap_debug.c:54
void(* coap_log_handler_t)(coap_log_t level, const char *message)
Logging callback handler definition.
Definition: coap_debug.h:109
#define coap_log(level,...)
Logging function.
Definition: coap_debug.h:165
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
Definition: coap_option.c:152
uint32_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
Definition: coap_option.c:215
coap_opt_iterator_t * coap_option_iterator_init(const coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t *filter)
Initializes the given option iterator oi to point to the beginning of the pdu's option list.
Definition: coap_option.c:116
#define COAP_OPT_ALL
Pre-defined filter that includes all options.
Definition: coap_option.h:108
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
Definition: coap_option.c:252
#define COAP_DEFAULT_VERSION
#define COAP_OPTION_HOP_LIMIT
Definition: pdu.h:125
#define COAP_OPTION_NORESPONSE
Definition: pdu.h:135
#define COAP_OPTION_URI_HOST
Definition: pdu.h:112
#define COAP_OPTION_IF_MATCH
Definition: pdu.h:111
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC
Definition: pdu.h:213
#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI
Definition: pdu.h:225
#define COAP_MEDIATYPE_APPLICATION_CWT
Definition: pdu.h:203
#define COAP_OPTION_BLOCK2
Definition: pdu.h:128
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT
Definition: pdu.h:211
#define COAP_MEDIATYPE_APPLICATION_RDF_XML
Definition: pdu.h:199
#define COAP_OPTION_CONTENT_FORMAT
Definition: pdu.h:120
#define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS
Definition: pdu.h:188
#define COAP_OPTION_SIZE2
Definition: pdu.h:130
#define COAP_MEDIATYPE_APPLICATION_SENSML_XML
Definition: pdu.h:227
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN
Definition: pdu.h:209
#define COAP_OPTION_BLOCK1
Definition: pdu.h:129
#define COAP_OPTION_PROXY_SCHEME
Definition: pdu.h:132
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET
Definition: pdu.h:217
#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR
Definition: pdu.h:222
#define COAP_OPTION_URI_QUERY
Definition: pdu.h:124
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY
Definition: pdu.h:216
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1
Definition: pdu.h:210
#define COAP_OPTION_IF_NONE_MATCH
Definition: pdu.h:114
#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM
Definition: pdu.h:198
#define COAP_OPTION_LOCATION_PATH
Definition: pdu.h:117
#define COAP_OPTION_URI_PATH
Definition: pdu.h:119
#define COAP_MEDIATYPE_APPLICATION_SENML_EXI
Definition: pdu.h:224
#define COAP_MEDIATYPE_APPLICATION_CBOR
Definition: pdu.h:202
#define COAP_OPTION_SIZE1
Definition: pdu.h:133
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0
Definition: pdu.h:212
#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER
Definition: pdu.h:184
#define COAP_MEDIATYPE_TEXT_PLAIN
Definition: pdu.h:195
#define COAP_MEDIATYPE_APPLICATION_JSON
Definition: pdu.h:201
#define COAP_OPTION_LOCATION_QUERY
Definition: pdu.h:127
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0
Definition: pdu.h:214
#define COAP_MEDIATYPE_APPLICATION_SENML_JSON
Definition: pdu.h:220
#define COAP_MEDIATYPE_APPLICATION_EXI
Definition: pdu.h:200
#define COAP_SIGNALING_OPTION_CUSTODY
Definition: pdu.h:186
int coap_get_data(const coap_pdu_t *pdu, size_t *len, const uint8_t **data)
Retrieves the length and data pointer of specified PDU.
Definition: pdu.c:713
#define COAP_OPTION_RTAG
Definition: pdu.h:136
#define COAP_MEDIATYPE_APPLICATION_COAP_GROUP_JSON
Definition: pdu.h:206
#define COAP_OPTION_URI_PORT
Definition: pdu.h:116
#define COAP_MEDIATYPE_APPLICATION_SENML_XML
Definition: pdu.h:226
#define COAP_OPTION_ACCEPT
Definition: pdu.h:126
#define COAP_MEDIATYPE_APPLICATION_DOTS_CBOR
Definition: pdu.h:230
#define COAP_OPTION_MAXAGE
Definition: pdu.h:123
#define COAP_OPTION_ETAG
Definition: pdu.h:113
#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON
Definition: pdu.h:221
#define COAP_OPTION_PROXY_URI
Definition: pdu.h:131
#define COAP_OPTION_OBSERVE
Definition: pdu.h:115
#define COAP_SIGNALING_OPTION_HOLD_OFF
Definition: pdu.h:189
#define COAP_OPTION_ECHO
Definition: pdu.h:134
#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT
Definition: pdu.h:196
#define COAP_SIGNALING_OPTION_BAD_CSM_OPTION
Definition: pdu.h:191
#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE
Definition: pdu.h:183
#define COAP_MEDIATYPE_APPLICATION_XML
Definition: pdu.h:197
#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR
Definition: pdu.h:223
@ COAP_SIGNALING_CODE_ABORT
Definition: pdu.h:346
@ COAP_SIGNALING_CODE_CSM
Definition: pdu.h:342
@ COAP_SIGNALING_CODE_PING
Definition: pdu.h:343
@ COAP_SIGNALING_CODE_PONG
Definition: pdu.h:344
@ COAP_SIGNALING_CODE_RELEASE
Definition: pdu.h:345
@ COAP_SIGNALING_RELEASE
Definition: pdu.h:178
@ COAP_SIGNALING_CSM
Definition: pdu.h:175
@ COAP_SIGNALING_PONG
Definition: pdu.h:177
@ COAP_SIGNALING_PING
Definition: pdu.h:176
@ COAP_SIGNALING_ABORT
Definition: pdu.h:179
#define COAP_STATIC_INLINE
Definition: libcoap.h:45
const uint32_t n
Definition: murmur3.c:56
#define INET6_ADDRSTRLEN
Definition: net.c:68
multi-purpose address abstraction
Definition: coap_address.h:96
struct sockaddr_in sin
Definition: coap_address.h:100
struct sockaddr_in6 sin6
Definition: coap_address.h:101
struct sockaddr sa
Definition: coap_address.h:99
union coap_address_t::@0 addr
Iterator to run through PDU options.
Definition: coap_option.h:171
coap_option_num_t number
decoded option number
Definition: coap_option.h:173
structure for CoAP PDUs
uint8_t * token
first byte of token, if any, or options
coap_pdu_code_t code
request method (value 1–31) or response code (value 64-255)
uint8_t token_length
length of Token
coap_mid_t mid
message id, if any, in regular host byte order
coap_pdu_type_t type
message type
The structure used for returning the underlying (D)TLS library information.
Definition: coap_dtls.h:76
uint64_t built_version
(D)TLS Built against Library Version
Definition: coap_dtls.h:79
coap_tls_library_t type
Library type.
Definition: coap_dtls.h:78
uint64_t version
(D)TLS runtime Library Version
Definition: coap_dtls.h:77