libcoap 4.3.5-develop-783b531
Loading...
Searching...
No Matches
coap_debug.c
Go to the documentation of this file.
1/* coap_debug.c -- debug utilities
2 *
3 * Copyright (C) 2010--2012,2014--2026 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
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#ifndef __ZEPHYR__
31#ifdef HAVE_WS2TCPIP_H
32#include <ws2tcpip.h>
33#endif
34#endif /* !__ZEPHYR__ */
35
36#ifdef HAVE_TIME_H
37#include <time.h>
38#endif
39
40#ifdef WITH_LWIP
41# define fprintf(fd, ...) LWIP_PLATFORM_DIAG((__VA_ARGS__))
42# define fflush(...)
43#endif
44
45#ifdef WITH_CONTIKI
46# define fprintf(fd, ...) { (void)fd; printf(__VA_ARGS__); }
47# define fflush(...)
48# define vfprintf(fd, ...) { (void)fd; printf(__VA_ARGS__); }
49
50# ifndef LOG_CONF_LEVEL_COAP
51# define LOG_CONF_LEVEL_COAP 2 /* = LOG_LEVEL_WARN */
52# endif
53static coap_log_t maxlog = LOG_CONF_LEVEL_COAP == 0 ? /* = LOG_LEVEL_NONE */
55 (LOG_CONF_LEVEL_COAP == 1 ? /* = LOG_LEVEL_ERR */
57 (LOG_CONF_LEVEL_COAP == 2 ? /* = LOG_LEVEL_WARN */
59 (LOG_CONF_LEVEL_COAP == 3 ? /* = LOG_LEVEL_INFO */
62#else /* !WITH_CONTIKI */
63static coap_log_t maxlog = COAP_LOG_WARN; /* default maximum CoAP log level */
64#endif /* !WITH_CONTIKI */
65
66#ifdef RIOT_VERSION
67#include "flash_utils.h"
68#endif /* RIOT_VERSION */
69
70static int use_fprintf_for_show_pdu = 1; /* non zero to output with fprintf */
71static int enable_data_for_show_pdu = 1; /* By default show PDU data for coap_show_pdu() */
72
73const char *
75 return PACKAGE_NAME;
76}
77
78const char *
80 return PACKAGE_STRING;
81}
82
83const char *
85#ifdef LIBCOAP_PACKAGE_BUILD
86 return LIBCOAP_PACKAGE_BUILD;
87#else /* !LIBCOAP_PACKAGE_BUILD */
88 return PACKAGE_STRING;
89#endif /* !LIBCOAP_PACKAGE_BUILD */
90}
91
92void
93coap_set_show_pdu_output(int use_fprintf) {
94 use_fprintf_for_show_pdu = use_fprintf;
95}
96
97void
99 enable_data_for_show_pdu = enable_data;
100}
101
104 return maxlog;
105}
106
107void
109 if (level > COAP_MAX_LOGGING_LEVEL)
111 maxlog = level;
112}
113
114/* this array has the same order as the type coap_log_t with the (D)TLS
115 entries added to the list with a COAP_LOG_DTLS_BASE offset */
116static const char *loglevels[] = {
117 /* General logging */
118 "EMRG", "ALRT", "CRIT", "ERR ", "WARN", "NOTE", "INFO", "DEBG", "OSC ",
119 /* (D)TLS logging */
120 "Emrg", "Alrt", "Crit", "Err ", "Warn", "Note", "Info", "Debg"
121};
122
123const char *
125 static char bad[8];
126 if (level >= sizeof(loglevels)/sizeof(loglevels[0])) {
127 snprintf(bad, sizeof(bad), "%4d", level);
128 return bad;
129 } else {
130 return loglevels[level];
131 }
132}
133
134#ifdef WITH_CONTIKI
135void
136coap_print_contiki_prefix(coap_log_t level) {
137 printf("[%s: COAP ] ", coap_log_level_desc(level));
138}
139#endif /* WITH_CONTIKI */
140
141#ifdef HAVE_TIME_H
142
144print_timestamp(char *s, size_t len, coap_tick_t t) {
145 struct tm *tmp;
146 size_t lensofar;
147 time_t now = coap_ticks_to_rt(t);
148 tmp = localtime(&now);
149 lensofar = strftime(s, len, "%b %d %H:%M:%S", tmp);
150 if (len > lensofar + 4) {
151 lensofar += snprintf(&s[lensofar], len-lensofar, ".%03u",
152 (unsigned int)((coap_ticks_to_rt_us(t) % 1000000)/1000));
153 }
154 return lensofar;
155}
156
157#else /* alternative implementation: just print the timestamp */
158
160print_timestamp(char *s, size_t len, coap_tick_t t) {
161#ifdef HAVE_SNPRINTF
162 return snprintf(s, len, "%u.%03u",
163 (unsigned int)coap_ticks_to_rt(t),
164 (unsigned int)((coap_ticks_to_rt_us(t) % 1000000)/1000));
165#else /* HAVE_SNPRINTF */
166 /* @todo do manual conversion of timestamp */
167 return 0;
168#endif /* HAVE_SNPRINTF */
169}
170
171#endif /* HAVE_TIME_H */
172
173#if !defined(HAVE_STRNLEN) && !defined(__MINGW32__) && !defined(__ZEPHYR__)
182static inline size_t
183strnlen(const char *s, size_t maxlen) {
184 size_t n = 0;
185 while (*s++ && n < maxlen)
186 ++n;
187 return n;
188}
189#endif /* HAVE_STRNLEN && !__MINGW32__ && !__ZEPHYR__*/
190
191static size_t
192print_readable(const uint8_t *data, size_t len,
193 unsigned char *result, size_t buflen, int encode_always) {
194 const uint8_t hex[] = "0123456789ABCDEF";
195 size_t cnt = 0;
196 assert(data || len == 0);
197
198 if (buflen == 0) { /* there is nothing we can do here but return */
199 return 0;
200 }
201
202 while (len) {
203 if (!encode_always && isprint(*data)) {
204 if (cnt+1 < buflen) { /* keep one byte for terminating zero */
205 *result++ = *data;
206 ++cnt;
207 } else {
208 break;
209 }
210 } else {
211 if (cnt+4 < buflen) { /* keep one byte for terminating zero */
212 *result++ = '\\';
213 *result++ = 'x';
214 *result++ = hex[(*data & 0xf0) >> 4];
215 *result++ = hex[*data & 0x0f];
216 cnt += 4;
217 } else
218 break;
219 }
220
221 ++data;
222 --len;
223 }
224
225 *result = '\0'; /* add a terminating zero */
226 return cnt;
227}
228
229#ifndef min
230#define min(a,b) ((a) < (b) ? (a) : (b))
231#endif
232
233#ifndef INET6_ADDRSTRLEN
234#define INET6_ADDRSTRLEN 46
235#endif
236/*
237 * Returned buf is always NULL terminated.
238 * Returned size is number of characters, not including NULL terminator.
239 */
240size_t
241coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len) {
242#if (defined( HAVE_ARPA_INET_H ) || defined( HAVE_WS2TCPIP_H )) && !defined(RIOT_VERSION) || defined(__ZEPHYR__)
243 char scratch[INET6_ADDRSTRLEN];
244
245 assert(buf);
246 assert(len);
247 buf[0] = '\000';
248
249 switch (addr->addr.sa.sa_family) {
250#if COAP_IPV4_SUPPORT
251 case AF_INET:
252 snprintf((char *)buf, len, "%s:%d",
253 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
255 break;
256#endif /* COAP_IPV4_SUPPORT */
257#if COAP_IPV6_SUPPORT
258 case AF_INET6:
259 snprintf((char *)buf, len, "[%s]:%d",
260 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
262 break;
263#endif /* COAP_IPV6_SUPPORT */
264#if COAP_AF_UNIX_SUPPORT
265 case AF_UNIX:
266 snprintf((char *)buf, len, "%s", addr->addr.cun.sun_path);
267 break;
268#endif /* COAP_AF_UNIX_SUPPORT */
269#if COAP_AF_LLC_SUPPORT
270 case AF_LLC:
271 snprintf((char *)buf, len, "%s:%02x",
272 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
274 break;
275#endif /* COAP_AF_LLC_SUPPORT */
276 default:
277 /* Include trailing NULL if possible */
278 memcpy(buf, "(unknown address type)", min(22+1, len));
279 buf[len-1] = '\000';
280 break;
281 }
282 return strlen((char *)buf);
283
284#else /* HAVE_ARPA_INET_H */
285
286# if defined(RIOT_VERSION)
287 char scratch[INET6_ADDRSTRLEN];
288
289 assert(buf);
290 assert(len);
291 buf[0] = '\000';
292
293 switch (addr->riot.family) {
294#if COAP_IPV4_SUPPORT
295 case AF_INET:
296 snprintf((char *)buf, len, "%s:%d",
297 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
299 break;
300#endif /* COAP_IPV4_SUPPORT */
301#if COAP_IPV6_SUPPORT
302 case AF_INET6:
303 snprintf((char *)buf, len, "[%s]:%d",
304 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
306 break;
307#endif /* COAP_IPV6_SUPPORT */
308 default:
309 /* Include trailing NULL if possible */
310 memcpy(buf, "(unknown address type)", min(22+1, len));
311 buf[len-1] = '\000';
312 break;
313 }
314 return strlen((char *)buf);
315
316# elif WITH_CONTIKI
317
318 char scratch[INET6_ADDRSTRLEN];
319#ifdef HAVE_SNPRINTF
320
321 snprintf((char *)buf, len, "[%s]:%d",
322 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
324 return strlen((char *)buf);
325#else /* HAVE_SNPRINTF */
326 unsigned char *p = buf;
327# if NETSTACK_CONF_WITH_IPV6
328
329 assert(buf);
330 assert(len);
331 buf[0] = '\000';
332 if (len < 40 + 2 + 6)
333 return 0;
334
335 *p++ = '[';
336 memcpy(p, coap_print_ip_addr(addr, scratch, sizeof(scratch)), 40);
337 p += 40 - 1;
338 *p++ = ']';
339# else /* WITH_UIP6 */
340# warning "IPv4 network addresses will not be included in debug output"
341
342 if (len < 21) {
343 *p = '\000';
344 return 0;
345 }
346# endif /* WITH_UIP6 */
347
348 *p++ = ':';
349 *p++ = '0' + (coap_address_get_port(addr) / 10000) % 10;
350 *p++ = '0' + (coap_address_get_port(addr) / 1000) % 10;
351 *p++ = '0' + (coap_address_get_port(addr) / 100) % 10;
352 *p++ = '0' + (coap_address_get_port(addr) / 10) % 10;
353 *p++ = '0' + coap_address_get_port(addr) % 10;
354 *p = '\000';
355
356 return strlen((char *)buf);
357#endif /* HAVE_SNPRINTF */
358
359# elif WITH_LWIP
360
361 char scratch[INET6_ADDRSTRLEN];
362#ifdef HAVE_SNPRINTF
363
364 snprintf((char *)buf, len, "[%s]:%d",
365 coap_print_ip_addr(addr, scratch, sizeof(scratch)),
366 addr->port);
367 return strlen((char *)buf);
368#else /* HAVE_SNPRINTF */
369 unsigned char *p = buf;
370
371 assert(buf);
372 assert(len);
373 buf[0] = '\000';
374
375 switch (IP_GET_TYPE(addr->addr)) {
376 case IPADDR_TYPE_V4:
377 if (len < IP4ADDR_STRLEN_MAX + 6)
378 return 0;
379 memcpy(buf, coap_print_ip_addr(addr, scratch, sizeof(scratch)), IP4ADDR_STRLEN_MAX);
380 p += strlen((char *)buf);
381 break;
382#if LWIP_IPV6
383 case IPADDR_TYPE_V6:
384 case IPADDR_TYPE_ANY:
385 if (len < 40 + 2 + 6)
386 return 0;
387 *p++ = '[';
388 memcpy(p, coap_print_ip_addr(addr, scratch, sizeof(scratch)), 40);
389 p += strlen((char *)buf);
390 *p++ = ']';
391 break;
392#endif /* LWIP_IPV6 */
393 }
394
395 *p++ = ':';
396 *p++ = '0' + (addr->port / 10000) % 10;
397 *p++ = '0' + (addr->port / 1000) % 10;
398 *p++ = '0' + (addr->port / 100) % 10;
399 *p++ = '0' + (addr->port / 10) % 10;
400 *p++ = '0' + addr->port % 10;
401 *p = '\000';
402
403 return strlen((char *)buf);
404#endif /* HAVE_SNPRINTF */
405
406# else /* ! WITH_CONTIKI && ! WITH_LWIP */
407
408 (void)addr;
409 (void)len;
410
411 /* TODO: output addresses manually */
412# warning "inet_ntop() not available, network addresses will not be included in debug output"
413# endif /* ! WITH_CONTIKI && ! WITH_LWIP */
414 buf[0] = '\000';
415 return 0;
416#endif
417}
418
419/*
420 * Returned buf is always NULL terminated with as much as possible of the
421 * IP address filled in.
422 */
423const char *
424coap_print_ip_addr(const coap_address_t *addr, char *buf, size_t len) {
425#if (defined( HAVE_ARPA_INET_H ) || defined( HAVE_WS2TCPIP_H )) && !defined(RIOT_VERSION) || defined(__ZEPHYR__)
426 const void *addrptr = NULL;
427
428 assert(buf);
429 assert(len);
430 buf[0] = '\000';
431
432 switch (addr->addr.sa.sa_family) {
433#if COAP_IPV4_SUPPORT
434 case AF_INET:
435 if (len < INET_ADDRSTRLEN)
436 return buf;
437 addrptr = &addr->addr.sin.sin_addr;
438 break;
439#endif /* COAP_IPV4_SUPPORT */
440#if COAP_IPV6_SUPPORT
441 case AF_INET6:
442 if (len < INET6_ADDRSTRLEN)
443 return buf;
444 addrptr = &addr->addr.sin6.sin6_addr;
445 break;
446#endif /* COAP_IPV6_SUPPORT */
447#if COAP_AF_UNIX_SUPPORT
448 case AF_UNIX:
449 snprintf(buf, len, "%s", addr->addr.cun.sun_path);
450 return buf;
451#endif /* COAP_AF_UNIX_SUPPORT */
452#if COAP_AF_LLC_SUPPORT
453 case AF_LLC:
454 snprintf((char *)buf, len, "llc[%02x:%02x:%02x:%02x:%02x:%02x]",
455 addr->addr.llc.sllc_mac[0],
456 addr->addr.llc.sllc_mac[1],
457 addr->addr.llc.sllc_mac[2],
458 addr->addr.llc.sllc_mac[3],
459 addr->addr.llc.sllc_mac[4],
460 addr->addr.llc.sllc_mac[5]);
461 return buf;
462#endif /* COAP_AF_LLC_SUPPORT */
463 default:
464 /* Include trailing NULL if possible */
465 memcpy(buf, "(unknown address type)", min(22+1, len));
466 buf[len-1] = '\000';
467 return buf;
468 }
469
470 /* Cast needed for Windows, since it doesn't have the correct API signature. */
471 if (inet_ntop(addr->addr.sa.sa_family, addrptr, (char *)buf, len) == 0) {
472 coap_log_err("coap_print_ip_addr: inet_ntop\n");
473 buf[0] = '\000';
474 return buf;
475 }
476 return buf;
477
478#else /* HAVE_ARPA_INET_H */
479
480# if defined(RIOT_VERSION)
481 assert(buf);
482 assert(len);
483 buf[0] = '\000';
484
485 switch (addr->riot.family) {
486#if COAP_IPV4_SUPPORT
487 case AF_INET:
488 if (ipv4_addr_to_str(buf, (ipv4_addr_t *)&addr->riot.addr.ipv4, (size_t)len) == NULL) {
489 goto error;
490 }
491 break;
492#endif /* COAP_IPV4_SUPPORT */
493#if COAP_IPV6_SUPPORT
494 case AF_INET6:
495 if (ipv6_addr_to_str(buf, (ipv6_addr_t *)&addr->riot.addr.ipv6, (size_t)len) == NULL) {
496 goto error;
497 }
498 break;
499#endif /* COAP_IPV6_SUPPORT */
500 default:
501 goto error;
502 }
503 return buf;
504
505error:
506 coap_log_err("coap_print_ip_addr: inet_ntop\n");
507 buf[0] = '\000';
508 return buf;
509
510# elif WITH_CONTIKI
511 char *p = buf;
512 uint8_t i;
513# if NETSTACK_CONF_WITH_IPV6
514 const char hex[] = "0123456789ABCDEF";
515
516 assert(buf);
517 assert(len);
518 buf[0] = '\000';
519 if (len < 40)
520 return 0;
521
522 for (i=0; i < 16; i += 2) {
523 if (i) {
524 *p++ = ':';
525 }
526 *p++ = hex[(addr->addr.u8[i] & 0xf0) >> 4];
527 *p++ = hex[(addr->addr.u8[i] & 0x0f)];
528 *p++ = hex[(addr->addr.u8[i+1] & 0xf0) >> 4];
529 *p++ = hex[(addr->addr.u8[i+1] & 0x0f)];
530 }
531 *p = '\000';
532# else /* WITH_UIP6 */
533# warning "IPv4 network addresses will not be included in debug output"
534
535 if (len < 21) {
536 return buf;
537 }
538# endif /* WITH_UIP6 */
539 return buf;
540
541# elif WITH_LWIP
542
543 assert(buf);
544 assert(len);
545 buf[0] = '\000';
546
547 switch (IP_GET_TYPE(&addr->addr)) {
548#if LWIP_IPV4
549 case IPADDR_TYPE_V4:
550 if (len < IP4ADDR_STRLEN_MAX)
551 return buf;
552 memcpy(buf, ip4addr_ntoa(ip_2_ip4(&addr->addr)), IP4ADDR_STRLEN_MAX);
553 break;
554#endif /* LWIP_IPV4 */
555#if LWIP_IPV6
556 case IPADDR_TYPE_V6:
557 case IPADDR_TYPE_ANY:
558 if (len < 40)
559 return buf;
560#if LWIP_IPV4
561 memcpy(buf, ip6addr_ntoa(&addr->addr.u_addr.ip6), 40);
562#else /* LWIP_IPV4 */
563 memcpy(buf, ip6addr_ntoa(&addr->addr), 40);
564#endif /* LWIP_IPV4 */
565 break;
566#endif /* LWIP_IPV6 */
567 }
568 return buf;
569
570# else /* ! WITH_CONTIKI && ! WITH_LWIP */
571
572 (void)addr;
573 (void)len;
574
575 /* TODO: output addresses manually */
576# warning "inet_ntop() not available, network addresses will not be included in debug output"
577# endif /* WITH_CONTIKI */
578 buf[0] = '\000';
579 return buf;
580#endif
581}
582
584static const char *
585msg_type_string(uint16_t t) {
586 static const char *types[] = { "CON", "NON", "ACK", "RST", "???" };
587
588 return types[min(t, sizeof(types)/sizeof(char *) - 1)];
589}
590
592static const char *
593msg_code_string(uint16_t c) {
594 static const char *methods[] = { "0.00", "GET", "POST", "PUT", "DELETE",
595 "FETCH", "PATCH", "iPATCH"
596 };
597 static const char *signals[] = { "7.00", "CSM", "Ping", "Pong", "Release",
598 "Abort"
599 };
600 static char buf[5];
601
602 if (c < sizeof(methods)/sizeof(const char *)) {
603 return methods[c];
604 } else if (c >= 224 && c - 224 < (int)(sizeof(signals)/sizeof(const char *))) {
605 return signals[c-224];
606 } else {
607 snprintf(buf, sizeof(buf), "%u.%02u", (c >> 5) & 0x7, c & 0x1f);
608 return buf;
609 }
610}
611
613static const char *
614msg_option_string(uint8_t code, uint16_t option_type) {
615 struct option_desc_t {
616 uint16_t type;
617 const char *name;
618 };
619
620 static struct option_desc_t options[] = {
621 { COAP_OPTION_IF_MATCH, "If-Match" },
622 { COAP_OPTION_URI_HOST, "Uri-Host" },
623 { COAP_OPTION_ETAG, "ETag" },
624 { COAP_OPTION_IF_NONE_MATCH, "If-None-Match" },
625 { COAP_OPTION_OBSERVE, "Observe" },
626 { COAP_OPTION_URI_PORT, "Uri-Port" },
627 { COAP_OPTION_LOCATION_PATH, "Location-Path" },
628 { COAP_OPTION_OSCORE, "Oscore" },
629 { COAP_OPTION_URI_PATH, "Uri-Path" },
630 { COAP_OPTION_CONTENT_FORMAT, "Content-Format" },
631 { COAP_OPTION_URI_PATH_ABB, "Uri-Path-Abbrev" },
632 { COAP_OPTION_MAXAGE, "Max-Age" },
633 { COAP_OPTION_URI_QUERY, "Uri-Query" },
634 { COAP_OPTION_HOP_LIMIT, "Hop-Limit" },
635 { COAP_OPTION_ACCEPT, "Accept" },
636 { COAP_OPTION_LOCATION_QUERY, "Location-Query" },
637 { COAP_OPTION_BLOCK2, "Block2" },
638 { COAP_OPTION_BLOCK1, "Block1" },
639 { COAP_OPTION_SIZE2, "Size2" },
640 { COAP_OPTION_PROXY_URI, "Proxy-Uri" },
641 { COAP_OPTION_PROXY_SCHEME, "Proxy-Scheme" },
642 { COAP_OPTION_SIZE1, "Size1" },
643 { COAP_OPTION_ECHO, "Echo" },
644 { COAP_OPTION_NORESPONSE, "No-Response" },
645 { COAP_OPTION_RTAG, "Request-Tag" },
646 { COAP_OPTION_Q_BLOCK1, "Q-Block1" },
647 { COAP_OPTION_Q_BLOCK2, "Q-Block2" }
648 };
649
650 static struct option_desc_t options_csm[] = {
651 { COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE, "Max-Message-Size" },
652 { COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER, "Block-Wise-Transfer" },
653 { COAP_SIGNALING_OPTION_EXTENDED_TOKEN_LENGTH, "Extended-Token-Length" }
654 };
655
656 static struct option_desc_t options_pingpong[] = {
657 { COAP_SIGNALING_OPTION_CUSTODY, "Custody" }
658 };
659
660 static struct option_desc_t options_release[] = {
661 { COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS, "Alternative-Address" },
662 { COAP_SIGNALING_OPTION_HOLD_OFF, "Hold-Off" }
663 };
664
665 static struct option_desc_t options_abort[] = {
666 { COAP_SIGNALING_OPTION_BAD_CSM_OPTION, "Bad-CSM-Option" }
667 };
668
669 static char buf[6];
670 size_t i;
671
672 if (code == COAP_SIGNALING_CSM) {
673 for (i = 0; i < sizeof(options_csm)/sizeof(struct option_desc_t); i++) {
674 if (option_type == options_csm[i].type) {
675 return options_csm[i].name;
676 }
677 }
678 } else if (code == COAP_SIGNALING_PING || code == COAP_SIGNALING_PONG) {
679 for (i = 0; i < sizeof(options_pingpong)/sizeof(struct option_desc_t); i++) {
680 if (option_type == options_pingpong[i].type) {
681 return options_pingpong[i].name;
682 }
683 }
684 } else if (code == COAP_SIGNALING_RELEASE) {
685 for (i = 0; i < sizeof(options_release)/sizeof(struct option_desc_t); i++) {
686 if (option_type == options_release[i].type) {
687 return options_release[i].name;
688 }
689 }
690 } else if (code == COAP_SIGNALING_ABORT) {
691 for (i = 0; i < sizeof(options_abort)/sizeof(struct option_desc_t); i++) {
692 if (option_type == options_abort[i].type) {
693 return options_abort[i].name;
694 }
695 }
696 } else {
697 /* search option_type in list of known options */
698 for (i = 0; i < sizeof(options)/sizeof(struct option_desc_t); i++) {
699 if (option_type == options[i].type) {
700 return options[i].name;
701 }
702 }
703 }
704 /* unknown option type, just print to buf */
705 snprintf(buf, sizeof(buf), "%u", option_type);
706 return buf;
707}
708
709static unsigned int
710print_content_format(unsigned int format_type,
711 unsigned char *result, unsigned int buflen) {
712 struct desc_t {
713 unsigned int type;
714 const char *name;
715 };
716
717 static struct desc_t formats[] = {
718 { COAP_MEDIATYPE_TEXT_PLAIN, "text/plain" },
719 { COAP_MEDIATYPE_APPLICATION_LINK_FORMAT, "application/link-format" },
720 { COAP_MEDIATYPE_APPLICATION_XML, "application/xml" },
721 { COAP_MEDIATYPE_APPLICATION_OCTET_STREAM, "application/octet-stream" },
722 { COAP_MEDIATYPE_APPLICATION_RDF_XML, "application/rdf+xml" },
723 { COAP_MEDIATYPE_APPLICATION_EXI, "application/exi" },
724 { COAP_MEDIATYPE_APPLICATION_JSON, "application/json" },
725 { COAP_MEDIATYPE_APPLICATION_CBOR, "application/cbor" },
726 { COAP_MEDIATYPE_APPLICATION_CWT, "application/cwt" },
727 { COAP_MEDIATYPE_APPLICATION_COAP_GROUP_JSON, "application/coap-group+json" },
728 { COAP_MEDIATYPE_APPLICATION_COSE_SIGN, "application/cose; cose-type=\"cose-sign\"" },
729 { COAP_MEDIATYPE_APPLICATION_COSE_SIGN1, "application/cose; cose-type=\"cose-sign1\"" },
730 { COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT, "application/cose; cose-type=\"cose-encrypt\"" },
731 { COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0, "application/cose; cose-type=\"cose-encrypt0\"" },
732 { COAP_MEDIATYPE_APPLICATION_COSE_MAC, "application/cose; cose-type=\"cose-mac\"" },
733 { COAP_MEDIATYPE_APPLICATION_COSE_MAC0, "application/cose; cose-type=\"cose-mac0\"" },
734 { COAP_MEDIATYPE_APPLICATION_COSE_KEY, "application/cose-key" },
735 { COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET, "application/cose-key-set" },
736 { COAP_MEDIATYPE_APPLICATION_SENML_JSON, "application/senml+json" },
737 { COAP_MEDIATYPE_APPLICATION_SENSML_JSON, "application/sensml+json" },
738 { COAP_MEDIATYPE_APPLICATION_SENML_CBOR, "application/senml+cbor" },
739 { COAP_MEDIATYPE_APPLICATION_SENSML_CBOR, "application/sensml+cbor" },
740 { COAP_MEDIATYPE_APPLICATION_SENML_EXI, "application/senml-exi" },
741 { COAP_MEDIATYPE_APPLICATION_SENSML_EXI, "application/sensml-exi" },
742 { COAP_MEDIATYPE_APPLICATION_SENML_XML, "application/senml+xml" },
743 { COAP_MEDIATYPE_APPLICATION_SENSML_XML, "application/sensml+xml" },
744 { COAP_MEDIATYPE_APPLICATION_DOTS_CBOR, "application/dots+cbor" },
745 { COAP_MEDIATYPE_APPLICATION_ACE_CBOR, "application/ace+cbor" },
746 { COAP_MEDIATYPE_APPLICATION_MB_CBOR_SEQ, "application/missing-blocks+cbor-seq" },
747 { COAP_MEDIATYPE_APPLICATION_OSCORE, "application/oscore" },
748 { 75, "application/dcaf+cbor" }
749 };
750
751 size_t i;
752
753 /* search format_type in list of known content formats */
754 for (i = 0; i < sizeof(formats)/sizeof(struct desc_t); i++) {
755 if (format_type == formats[i].type) {
756 return snprintf((char *)result, buflen, "%s", formats[i].name);
757 }
758 }
759
760 /* unknown content format, just print numeric value to buf */
761 return snprintf((char *)result, buflen, "%d", format_type);
762}
763
770is_binary(int content_format) {
771 return !(content_format == -1 ||
772 content_format == COAP_MEDIATYPE_TEXT_PLAIN ||
773 content_format == COAP_MEDIATYPE_APPLICATION_LINK_FORMAT ||
774 content_format == COAP_MEDIATYPE_APPLICATION_XML ||
775 content_format == COAP_MEDIATYPE_APPLICATION_JSON);
776}
777
778#define COAP_DO_SHOW_OUTPUT_LINE \
779 do { \
780 if (use_fprintf_for_show_pdu) { \
781 fprintf(COAP_DEBUG_FD, "%s", outbuf); \
782 } \
783 else { \
784 coap_log(level, "%s", outbuf); \
785 } \
786 } while (0)
787
788/*
789 * It is possible to override the output debug buffer size and hence control
790 * the amount of information printed out about a CoAP PDU.
791 * Note: Adding a byte may be insufficient to output the next byte of the PDU.
792 *
793 * This is done by the adding of a -DCOAP_DEBUG_BUF_SIZE=nnnn option to the
794 * CPPFLAGS parameter that is optionally used on the ./configure command line.
795 *
796 * E.g. ./configure CPPFLAGS="-DCOAP_DEBUG_BUF_SIZE=4096"
797 *
798 */
799
800#if COAP_DEBUG_BUF_SIZE < 5
801#error "COAP_DEBUG_BUF_SIZE must be at least 5, should be >= 32 to be useful"
802#endif /* COAP_DEBUG_BUF_SIZE < 5 */
803
804/* Proxy-Uri: can be 1034 bytes long */
805#if COAP_DEBUG_BUF_SIZE < 1035
806#define USE_BUF_SIZE COAP_DEBUG_BUF_SIZE
807#else
808#define USE_BUF_SIZE 1035
809#endif
810
811void
813#if COAP_CONSTRAINED_STACK
814 /* Proxy-Uri: can be 1034 bytes long */
815 /* buf and outbuf can be protected by m_show_pdu if needed */
816 static unsigned char buf[USE_BUF_SIZE];
817 static char outbuf[COAP_DEBUG_BUF_SIZE];
818#else /* ! COAP_CONSTRAINED_STACK */
819 /* Proxy-Uri: can be 1034 bytes long */
820 unsigned char buf[USE_BUF_SIZE];
821 char outbuf[COAP_DEBUG_BUF_SIZE];
822#endif /* ! COAP_CONSTRAINED_STACK */
823 size_t buf_len = 0; /* takes the number of bytes written to buf */
824 int encode = 0, have_options = 0;
825 uint32_t i;
826 coap_opt_iterator_t opt_iter;
827 coap_opt_t *option;
828 int content_format = -1;
829 size_t data_len;
830 const uint8_t *data;
831 uint32_t opt_len;
832 const uint8_t *opt_val;
833 size_t outbuflen = 0;
834 int is_oscore_payload = 0;
835 const char *exp;
836 uint32_t value;
837
838 /* Save time if not needed */
839 if (level > coap_get_log_level())
840 return;
841
842#if COAP_THREAD_SAFE
843 coap_mutex_lock(&m_show_pdu);
844#endif /* COAP_THREAD_SAFE */
845 if (!pdu->session || COAP_PROTO_NOT_RELIABLE(pdu->session->proto)) {
846 snprintf(outbuf, sizeof(outbuf), "v:%d t:%s c:%s i:%04x {",
848 msg_code_string(pdu->code), pdu->mid);
849 } else if (pdu->session->proto == COAP_PROTO_WS ||
850 pdu->session->proto == COAP_PROTO_WSS) {
851 if (pdu->type != COAP_MESSAGE_CON)
852 coap_log_alert("WebSocket: type != CON\n");
853 snprintf(outbuf, sizeof(outbuf), "v:WebSocket c:%s {",
854 msg_code_string(pdu->code));
855 } else {
856 if (pdu->type != COAP_MESSAGE_CON)
857 coap_log_alert("Reliable: type != CON\n");
858 snprintf(outbuf, sizeof(outbuf), "v:Reliable c:%s {",
859 msg_code_string(pdu->code));
860 }
861
862 for (i = 0; i < pdu->actual_token.length; i++) {
863 outbuflen = strlen(outbuf);
864 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
865 "%02x", pdu->actual_token.s[i]);
866 }
867 outbuflen = strlen(outbuf);
868 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "}");
869
870 /* show options, if any */
872
873 outbuflen = strlen(outbuf);
874 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " [");
875 while ((option = coap_option_next(&opt_iter))) {
876 buf[0] = '\000';
877 if (!have_options) {
878 have_options = 1;
879 } else {
880 outbuflen = strlen(outbuf);
881 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ",");
882 }
883
884 if (pdu->code == COAP_SIGNALING_CODE_CSM) {
885 switch (opt_iter.number) {
888 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
890 coap_opt_length(option)));
891 break;
892 default:
893 buf_len = 0;
894 break;
895 }
896 } else if (pdu->code == COAP_SIGNALING_CODE_PING ||
898 buf_len = 0;
899 } else if (pdu->code == COAP_SIGNALING_CODE_RELEASE) {
900 switch (opt_iter.number) {
902 buf_len = print_readable(coap_opt_value(option),
903 coap_opt_length(option),
904 buf, sizeof(buf), 0);
905 break;
907 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
909 coap_opt_length(option)));
910 break;
911 default:
912 buf_len = 0;
913 break;
914 }
915 } else if (pdu->code == COAP_SIGNALING_CODE_ABORT) {
916 switch (opt_iter.number) {
918 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
920 coap_opt_length(option)));
921 break;
922 default:
923 buf_len = 0;
924 break;
925 }
926 } else {
927 switch (opt_iter.number) {
930 content_format = (int)coap_decode_var_bytes(coap_opt_value(option),
931 coap_opt_length(option));
932
933 buf_len = print_content_format(content_format, buf, sizeof(buf));
934 break;
935
940 /* split block option into number/more/size where more is the
941 * letter M if set, the _ otherwise */
942 if (COAP_OPT_BLOCK_SZX(option) == 7) {
943 if (coap_get_data(pdu, &data_len, &data))
944 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/BERT(%" PRIuS ")",
945 coap_opt_block_num(option), /* block number */
946 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
947 data_len);
948 else
949 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/BERT",
950 coap_opt_block_num(option), /* block number */
951 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_'); /* M bit */
952 } else {
953 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/%u",
954 coap_opt_block_num(option), /* block number */
955 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
956 (1 << (COAP_OPT_BLOCK_SZX(option) + 4))); /* block size */
957 }
958
959 break;
960
962 opt_len = coap_opt_length(option);
963 buf[0] = '\000';
964 if (opt_len) {
965 size_t ofs = 1;
966 size_t cnt;
967
968 opt_val = coap_opt_value(option);
969 if (opt_val[0] & 0x20) {
970 /* Group Flag */
971 snprintf((char *)buf, sizeof(buf), "grp");
972 }
973 if (opt_val[0] & 0x07) {
974 /* Partial IV */
975 cnt = opt_val[0] & 0x07;
976 if (cnt > opt_len - ofs)
977 goto no_more;
978 buf_len = strlen((char *)buf);
979 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len, "%spIV=0x",
980 buf_len ? "," : "");
981 for (i = 0; (uint32_t)i < cnt; i++) {
982 buf_len = strlen((char *)buf);
983 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
984 "%02x", opt_val[ofs + i]);
985 }
986 ofs += cnt;
987 }
988 if (opt_val[0] & 0x10) {
989 /* kid context */
990 if (ofs >= opt_len)
991 goto no_more;
992 cnt = opt_val[ofs];
993 if (cnt > opt_len - ofs - 1)
994 goto no_more;
995 ofs++;
996 buf_len = strlen((char *)buf);
997 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len, "%skc=0x",
998 buf_len ? "," : "");
999 for (i = 0; (uint32_t)i < cnt; i++) {
1000 buf_len = strlen((char *)buf);
1001 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
1002 "%02x", opt_val[ofs + i]);
1003 }
1004 ofs += cnt;
1005 }
1006 if (opt_val[0] & 0x08) {
1007 /* kid */
1008 if (ofs >= opt_len)
1009 goto no_more;
1010 cnt = opt_len - ofs;
1011 buf_len = strlen((char *)buf);
1012 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len, "%skid=0x",
1013 buf_len ? "," : "");
1014 for (i = 0; (uint32_t)i < cnt; i++) {
1015 buf_len = strlen((char *)buf);
1016 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
1017 "%02x", opt_val[ofs + i]);
1018 }
1019 }
1020 }
1021no_more:
1022 buf_len = strlen((char *)buf);
1023 is_oscore_payload = 1;
1024 break;
1025
1027 case COAP_OPTION_MAXAGE:
1029 case COAP_OPTION_SIZE1:
1030 case COAP_OPTION_SIZE2:
1032 if (coap_opt_length(option)) {
1033 /* show values as unsigned decimal value */
1034 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
1036 coap_opt_length(option)));
1037 }
1038 break;
1039
1041 case COAP_OPTION_ETAG:
1042 case COAP_OPTION_ECHO:
1044 case COAP_OPTION_RTAG:
1045 opt_len = coap_opt_length(option);
1046 opt_val = coap_opt_value(option);
1047 snprintf((char *)buf, sizeof(buf), "0x");
1048 for (i = 0; (uint32_t)i < opt_len; i++) {
1049 buf_len = strlen((char *)buf);
1050 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
1051 "%02x", opt_val[i]);
1052 }
1053 buf_len = strlen((char *)buf);
1054 break;
1056 value = coap_decode_var_bytes(coap_opt_value(option),
1057 coap_opt_length(option));
1059 if (!exp) {
1061 }
1062 if (exp) {
1063 snprintf((char *)&buf, sizeof(buf), "%s", exp);
1064 } else {
1065 snprintf((char *)&buf, sizeof(buf), "(%u)", value);
1066 }
1067 buf_len = strlen((char *)buf);
1068 break;
1069 default:
1070 /* generic output function for all other option types */
1071 if (opt_iter.number == COAP_OPTION_URI_PATH ||
1072 opt_iter.number == COAP_OPTION_PROXY_URI ||
1073 opt_iter.number == COAP_OPTION_URI_HOST ||
1074 opt_iter.number == COAP_OPTION_LOCATION_PATH ||
1075 opt_iter.number == COAP_OPTION_LOCATION_QUERY ||
1076 opt_iter.number == COAP_OPTION_PROXY_SCHEME ||
1077 opt_iter.number == COAP_OPTION_URI_QUERY) {
1078 encode = 0;
1079 } else {
1080 encode = 1;
1081 }
1082 buf_len = print_readable(coap_opt_value(option),
1083 coap_opt_length(option),
1084 buf, sizeof(buf), encode);
1085 }
1086 }
1087 outbuflen = strlen(outbuf);
1088 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1089 " %s:%.*s", msg_option_string(pdu->code, opt_iter.number),
1090 (int)buf_len, buf);
1091 }
1092
1093 outbuflen = strlen(outbuf);
1094 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " ]");
1095
1096 if (coap_get_data(pdu, &data_len, &data)) {
1098 /* Only output data if wanted */
1099 outbuflen = strlen(outbuf);
1100 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " :: ");
1101 outbuflen = strlen(outbuf);
1102 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1103 "data length %"PRIuS " (data suppressed)\n", data_len);
1105#if COAP_THREAD_SAFE
1106 coap_mutex_unlock(&m_show_pdu);
1107#endif /* COAP_THREAD_SAFE */
1108 return;
1109 }
1110
1111 outbuflen = strlen(outbuf);
1112 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " :: ");
1113
1114 if (is_binary(content_format) || !isprint(data[0]) || is_oscore_payload) {
1115 size_t keep_data_len = data_len;
1116 const uint8_t *keep_data = data;
1117
1118 outbuflen = strlen(outbuf);
1119 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1120 "binary data length %"PRIuS "\n", data_len);
1122 /*
1123 * Output hex dump of binary data as a continuous entry
1124 */
1125 outbuf[0] = '\000';
1126 snprintf(outbuf, sizeof(outbuf), "<<");
1127 while (data_len--) {
1128 outbuflen = strlen(outbuf);
1129 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1130 "%02x", *data++);
1131 }
1132 outbuflen = strlen(outbuf);
1133 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
1134 data_len = keep_data_len;
1135 data = keep_data;
1136 outbuflen = strlen(outbuf);
1137 if (outbuflen == sizeof(outbuf)-1)
1138 outbuflen--;
1139 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
1141 /*
1142 * Output ascii readable (if possible), immediately under the
1143 * hex value of the character output above to help binary debugging
1144 */
1145 outbuf[0] = '\000';
1146 snprintf(outbuf, sizeof(outbuf), "<<");
1147 while (data_len--) {
1148 outbuflen = strlen(outbuf);
1149 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1150 "%c ", isprint(*data) ? *data : '.');
1151 data++;
1152 }
1153 outbuflen = strlen(outbuf);
1154 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
1155 } else {
1156 size_t max_length;
1157
1158 outbuflen = strlen(outbuf);
1159 max_length = sizeof(outbuf)-outbuflen;
1160 if (max_length > 1) {
1161 outbuf[outbuflen++] = '\'';
1162 outbuf[outbuflen] = '\000';
1163 max_length--;
1164 }
1165 if (max_length > 1) {
1166 outbuflen += print_readable(data, data_len,
1167 (unsigned char *)&outbuf[outbuflen],
1168 max_length, 0);
1169 }
1170 /* print_readable may be handling unprintables - hence headroom of 4 */
1171 if (outbuflen < sizeof(outbuf)-4-1) {
1172 outbuf[outbuflen++] = '\'';
1173 outbuf[outbuflen] = '\000';
1174 }
1175 }
1176 }
1177
1178 outbuflen = strlen(outbuf);
1179 if (outbuflen == sizeof(outbuf)-1)
1180 outbuflen--;
1181 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
1183
1184#if COAP_THREAD_SAFE
1185 coap_mutex_unlock(&m_show_pdu);
1186#endif /* COAP_THREAD_SAFE */
1187}
1188
1189void
1191 char buffer[128];
1192 coap_string_tls_version(buffer, sizeof(buffer));
1193 coap_log(level, "%s\n", buffer);
1194}
1195
1196char *
1197coap_string_tls_version(char *buffer, size_t bufsize) {
1199 char beta[8];
1200 char sub[2];
1201 char b_beta[8];
1202 char b_sub[2];
1203
1204 switch (tls_version->type) {
1206 snprintf(buffer, bufsize, "TLS Library: None");
1207 break;
1209 snprintf(buffer, bufsize, "TLS Library: TinyDTLS - runtime %lu.%lu.%lu, "
1210 "libcoap built for %lu.%lu.%lu",
1211 (unsigned long)(tls_version->version >> 16),
1212 (unsigned long)((tls_version->version >> 8) & 0xff),
1213 (unsigned long)(tls_version->version & 0xff),
1214 (unsigned long)(tls_version->built_version >> 16),
1215 (unsigned long)((tls_version->built_version >> 8) & 0xff),
1216 (unsigned long)(tls_version->built_version & 0xff));
1217 break;
1219 switch (tls_version->version &0xf) {
1220 case 0:
1221 strcpy(beta, "-dev");
1222 break;
1223 case 0xf:
1224 strcpy(beta, "");
1225 break;
1226 default:
1227 strcpy(beta, "-beta");
1228 beta[5] = (tls_version->version &0xf) + '0';
1229 beta[6] = '\000';
1230 break;
1231 }
1232 sub[0] = ((tls_version->version >> 4) & 0xff) ?
1233 ((tls_version->version >> 4) & 0xff) + 'a' -1 : '\000';
1234 sub[1] = '\000';
1235 switch (tls_version->built_version &0xf) {
1236 case 0:
1237 strcpy(b_beta, "-dev");
1238 break;
1239 case 0xf:
1240 strcpy(b_beta, "");
1241 break;
1242 default:
1243 strcpy(b_beta, "-beta");
1244 b_beta[5] = (tls_version->built_version &0xf) + '0';
1245 b_beta[6] = '\000';
1246 break;
1247 }
1248 b_sub[0] = ((tls_version->built_version >> 4) & 0xff) ?
1249 ((tls_version->built_version >> 4) & 0xff) + 'a' -1 : '\000';
1250 b_sub[1] = '\000';
1251 snprintf(buffer, bufsize, "TLS Library: OpenSSL - runtime "
1252 "%lu.%lu.%lu%s%s, libcoap built for %lu.%lu.%lu%s%s",
1253 (unsigned long)(tls_version->version >> 28),
1254 (unsigned long)((tls_version->version >> 20) & 0xff),
1255 (unsigned long)((tls_version->version >> 12) & 0xff), sub, beta,
1256 (unsigned long)(tls_version->built_version >> 28),
1257 (unsigned long)((tls_version->built_version >> 20) & 0xff),
1258 (unsigned long)((tls_version->built_version >> 12) & 0xff),
1259 b_sub, b_beta);
1260 break;
1262 snprintf(buffer, bufsize, "TLS Library: GnuTLS - runtime %lu.%lu.%lu, "
1263 "libcoap built for %lu.%lu.%lu",
1264 (unsigned long)(tls_version->version >> 16),
1265 (unsigned long)((tls_version->version >> 8) & 0xff),
1266 (unsigned long)(tls_version->version & 0xff),
1267 (unsigned long)(tls_version->built_version >> 16),
1268 (unsigned long)((tls_version->built_version >> 8) & 0xff),
1269 (unsigned long)(tls_version->built_version & 0xff));
1270 break;
1272 snprintf(buffer, bufsize, "TLS Library: Mbed TLS - runtime %lu.%lu.%lu, "
1273 "libcoap built for %lu.%lu.%lu",
1274 (unsigned long)(tls_version->version >> 24),
1275 (unsigned long)((tls_version->version >> 16) & 0xff),
1276 (unsigned long)((tls_version->version >> 8) & 0xff),
1277 (unsigned long)(tls_version->built_version >> 24),
1278 (unsigned long)((tls_version->built_version >> 16) & 0xff),
1279 (unsigned long)((tls_version->built_version >> 8) & 0xff));
1280 break;
1282 snprintf(buffer, bufsize, "TLS Library: wolfSSL - runtime %lu.%lu.%lu, "
1283 "libcoap built for %lu.%lu.%lu",
1284 (unsigned long)(tls_version->version >> 24),
1285 (unsigned long)((tls_version->version >> 12) & 0xfff),
1286 (unsigned long)((tls_version->version >> 0) & 0xfff),
1287 (unsigned long)(tls_version->built_version >> 24),
1288 (unsigned long)((tls_version->built_version >> 12) & 0xfff),
1289 (unsigned long)((tls_version->built_version >> 0) & 0xfff));
1290 break;
1291 default:
1292 snprintf(buffer, bufsize, "Library type %d unknown", tls_version->type);
1293 break;
1294 }
1295 return buffer;
1296}
1297
1298char *
1299coap_string_tls_support(char *buffer, size_t bufsize) {
1300 const int have_tls = coap_tls_is_supported();
1301 const int have_dtls = coap_dtls_is_supported();
1302 const int have_psk = coap_dtls_psk_is_supported();
1303 const int have_pki = coap_dtls_pki_is_supported();
1304 const int have_pkcs11 = coap_dtls_pkcs11_is_supported();
1305 const int have_rpk = coap_dtls_rpk_is_supported();
1306 const int have_cid = coap_dtls_cid_is_supported();
1307 const int have_oscore = coap_oscore_is_supported();
1308 const int have_ws = coap_ws_is_supported();
1309
1310 if (have_dtls == 0 && have_tls == 0) {
1311 snprintf(buffer, bufsize, "(No DTLS or TLS support)");
1312 return buffer;
1313 }
1314 snprintf(buffer, bufsize,
1315 "(%sDTLS and %sTLS support; %sPSK, %sPKI, %sPKCS11, %sRPK and %sCID support)\n(%sOSCORE)\n(%sWebSockets)",
1316 have_dtls ? "" : "No ",
1317 have_tls ? "" : "no ",
1318 have_psk ? "" : "no ",
1319 have_pki ? "" : "no ",
1320 have_pkcs11 ? "" : "no ",
1321 have_rpk ? "" : "no ",
1322 have_cid ? "" : "no ",
1323 have_oscore ? "Have " : "No ",
1324 have_ws ? "Have " : "No ");
1325 return buffer;
1326}
1327
1329
1330void
1332 log_handler = handler;
1333}
1334
1335#if COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING
1336/* Visible to only this thread */
1337extern COAP_THREAD_LOCAL_VAR uint32_t thread_no;
1338/* Visible across all threads */
1339extern uint32_t max_thread_no;
1340#endif /* COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING */
1341
1342void
1343coap_log_impl(coap_log_t level, const char *format, ...) {
1344
1345#if COAP_THREAD_SAFE
1346 coap_mutex_lock(&m_log_impl);
1347#endif /* COAP_THREAD_SAFE */
1348
1349 if (log_handler) {
1350#if COAP_CONSTRAINED_STACK
1351 /* message can be protected by m_log_impl if needed */
1352 static char message[COAP_DEBUG_BUF_SIZE];
1353#else /* ! COAP_CONSTRAINED_STACK */
1354 char message[COAP_DEBUG_BUF_SIZE];
1355#endif /* ! COAP_CONSTRAINED_STACK */
1356 va_list ap;
1357 va_start(ap, format);
1358
1359#ifdef RIOT_VERSION
1360 flash_vsnprintf(message, sizeof(message), format, ap);
1361#else /* !RIOT_VERSION */
1362 vsnprintf(message, sizeof(message), format, ap);
1363#endif /* !RIOT_VERSION */
1364 va_end(ap);
1365 log_handler(level, message);
1366 } else {
1367 char timebuf[32];
1368 coap_tick_t now;
1369 va_list ap;
1370 FILE *log_fd;
1371 size_t len;
1372
1373 log_fd = level <= COAP_LOG_CRIT ? COAP_ERR_FD : COAP_DEBUG_FD;
1374
1375 coap_ticks(&now);
1376 len = print_timestamp(timebuf,sizeof(timebuf), now);
1377 if (len)
1378 fprintf(log_fd, "%.*s ", (int)len, timebuf);
1379
1380#if COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING
1381 if (thread_no == 0) {
1382 /*
1383 * All other call to coap_mutex_lock(&m_io_threads) immediately
1384 * by setting thread_no if 0. So deadlock should never occur.
1385 */
1386 coap_mutex_lock(&m_io_threads);
1387 thread_no = ++max_thread_no;
1388 coap_mutex_unlock(&m_io_threads);
1389 }
1390 fprintf(log_fd, "%2d ", thread_no);
1391#endif /* COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING */
1392
1393 fprintf(log_fd, "%s ", coap_log_level_desc(level));
1394
1395 va_start(ap, format);
1396#ifdef RIOT_VERSION
1397 flash_vfprintf(log_fd, format, ap);
1398#else /* !RIOT_VERSION */
1399 vfprintf(log_fd, format, ap);
1400#endif /* !RIOT_VERSION */
1401 va_end(ap);
1402 fflush(log_fd);
1403 }
1404
1405#if COAP_THREAD_SAFE
1406 coap_mutex_unlock(&m_log_impl);
1407#endif /* COAP_THREAD_SAFE */
1408}
1409
1415static uint16_t packet_loss_level = 0;
1416static int send_packet_count = 0;
1419static uint16_t packet_fail_level = 0;
1420
1421int
1422coap_debug_set_packet_loss(const char *loss_level) {
1423 const char *p = loss_level;
1424 char *end = NULL;
1425 int n = (int)strtol(p, &end, 10), i = 0;
1426 if (end == p || n < 0)
1427 return 0;
1428 if (*end == '%') {
1429 if (n > 100)
1430 n = 100;
1431 packet_loss_level = n * 0xffff / 100;
1432 coap_log_debug("packet loss level set to %d%%\n", n);
1433 } else {
1434 if (n <= 0)
1435 return 0;
1436 while (i < 10) {
1438 if (*end == '-') {
1439 p = end + 1;
1440 n = (int)strtol(p, &end, 10);
1441 if (end == p || n <= 0)
1442 return 0;
1443 }
1444 packet_loss_intervals[i++].end = n;
1445 if (*end == 0)
1446 break;
1447 if (*end != ',')
1448 return 0;
1449 p = end + 1;
1450 n = (int)strtol(p, &end, 10);
1451 if (end == p || n <= 0)
1452 return 0;
1453 }
1454 if (i == 10)
1455 return 0;
1457 }
1459 return 1;
1460}
1461
1462int
1465 if (num_packet_loss_intervals > 0) {
1466 int i;
1467 for (i = 0; i < num_packet_loss_intervals; i++) {
1470 coap_log_debug("Packet %u dropped\n", send_packet_count);
1471 return 0;
1472 }
1473 }
1474 }
1475 if (packet_loss_level > 0) {
1476 uint16_t r = 0;
1477 coap_prng_lkd((uint8_t *)&r, 2);
1478 if (r < packet_loss_level) {
1479 coap_log_debug("Packet %u dropped\n", send_packet_count);
1480 return 0;
1481 }
1482 }
1483 if (num_packet_fail_intervals > 0) {
1484 int i;
1485 for (i = 0; i < num_packet_fail_intervals; i++) {
1488 coap_log_debug("Packet %u failed\n", send_packet_count);
1489 errno = ECONNREFUSED;
1490 return -1;
1491 }
1492 }
1493 }
1494 if (packet_fail_level > 0) {
1495 uint16_t r = 0;
1496 coap_prng_lkd((uint8_t *)&r, 2);
1497 if (r < packet_fail_level) {
1498 coap_log_debug("Packet %u failed\n", send_packet_count);
1499 errno = ECONNREFUSED;
1500 return -1;
1501 }
1502 }
1503 return 1;
1504}
1505
1506int
1507coap_debug_set_packet_fail(const char *fail_level) {
1508 const char *p = fail_level;
1509 char *end = NULL;
1510 int n = (int)strtol(p, &end, 10), i = 0;
1511 if (end == p || n < 0)
1512 return 0;
1513 if (*end == '%') {
1514 if (n > 100)
1515 n = 100;
1516 packet_fail_level = n * 0xffff / 100;
1517 coap_log_debug("packet fail level set to %d%%\n", n);
1518 } else {
1519 if (n <= 0)
1520 return 0;
1521 while (i < 10) {
1523 if (*end == '-') {
1524 p = end + 1;
1525 n = (int)strtol(p, &end, 10);
1526 if (end == p || n <= 0)
1527 return 0;
1528 }
1529 packet_fail_intervals[i++].end = n;
1530 if (*end == 0)
1531 break;
1532 if (*end != ',')
1533 return 0;
1534 p = end + 1;
1535 n = (int)strtol(p, &end, 10);
1536 if (end == p || n <= 0)
1537 return 0;
1538 }
1539 if (i == 10)
1540 return 0;
1542 }
1544 return 1;
1545}
1546
1547void
uint16_t coap_address_get_port(const coap_address_t *addr)
Returns the port from addr in host byte order.
static uint16_t packet_loss_level
static struct packet_num_interval packet_loss_intervals[10]
static int send_packet_count
#define USE_BUF_SIZE
Definition coap_debug.c:806
int coap_debug_set_packet_loss(const char *loss_level)
Set the packet loss level for testing.
static coap_log_t maxlog
Definition coap_debug.c:63
static coap_log_handler_t log_handler
int coap_debug_set_packet_fail(const char *fail_level)
Set the packet transmit fail level for testing.
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:770
static int enable_data_for_show_pdu
Definition coap_debug.c:71
static const char * msg_code_string(uint16_t c)
Returns a textual description of the method or response code.
Definition coap_debug.c:593
#define COAP_DO_SHOW_OUTPUT_LINE
Definition coap_debug.c:778
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:192
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:614
static size_t strnlen(const char *s, size_t maxlen)
A length-safe strlen() fake.
Definition coap_debug.c:183
struct packet_num_interval packet_fail_intervals[10]
static uint16_t packet_fail_level
static const char * loglevels[]
Definition coap_debug.c:116
COAP_STATIC_INLINE size_t print_timestamp(char *s, size_t len, coap_tick_t t)
Definition coap_debug.c:160
#define min(a, b)
Definition coap_debug.c:230
static int num_packet_fail_intervals
static const char * msg_type_string(uint16_t t)
Returns a textual description of the message type t.
Definition coap_debug.c:585
static int use_fprintf_for_show_pdu
Definition coap_debug.c:70
static int num_packet_loss_intervals
int coap_debug_send_packet(void)
Check to see whether a packet should be sent or not.
void coap_debug_reset(void)
Reset all the defined logging parameters.
static unsigned int print_content_format(unsigned int format_type, unsigned char *result, unsigned int buflen)
Definition coap_debug.c:710
#define INET6_ADDRSTRLEN
Definition coap_debug.c:234
#define PRIuS
Library specific build wrapper for coap_internal.h.
#define coap_mutex_unlock(a)
#define coap_mutex_lock(a)
#define NULL
Definition coap_option.h:30
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:43
#define COAP_OPT_BLOCK_SZX(opt)
Returns the value of the SZX-field of a Block option opt.
Definition coap_block.h:95
#define COAP_OPT_BLOCK_MORE(opt)
Returns the value of the More-bit of a Block option opt.
Definition coap_block.h:91
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 coap_block.c:45
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition coap_time.h:149
coap_time_t coap_ticks_to_rt(coap_tick_t t)
Helper function that converts coap ticks to wallclock time.
Definition coap_time.c:123
uint64_t coap_ticks_to_rt_us(coap_tick_t t)
Helper function that converts coap ticks to POSIX wallclock time in us.
Definition coap_time.c:128
int coap_prng_lkd(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
Definition coap_prng.c:190
void coap_ticks(coap_tick_t *t)
Returns the current value of an internal tick counter.
Definition coap_time.c:90
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:100
@ COAP_TLS_LIBRARY_WOLFSSL
Using wolfSSL library.
Definition coap_dtls.h:80
@ COAP_TLS_LIBRARY_GNUTLS
Using GnuTLS library.
Definition coap_dtls.h:78
@ COAP_TLS_LIBRARY_TINYDTLS
Using TinyDTLS library.
Definition coap_dtls.h:76
@ COAP_TLS_LIBRARY_NOTLS
No DTLS library.
Definition coap_dtls.h:75
@ COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
Definition coap_dtls.h:77
@ COAP_TLS_LIBRARY_MBEDTLS
Using Mbed TLS library.
Definition coap_dtls.h:79
unsigned int coap_decode_var_bytes(const uint8_t *buf, size_t len)
Decodes multiple-length byte sequences.
Definition coap_encode.c:38
void coap_set_log_handler(coap_log_handler_t handler)
Add a custom log callback handler.
const char * coap_log_level_desc(coap_log_t level)
Get the current logging description.
Definition coap_debug.c:124
#define coap_log_debug(...)
Definition coap_debug.h:126
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition coap_debug.c:103
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.
#define coap_log_alert(...)
Definition coap_debug.h:90
void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu)
Display the contents of the specified pdu.
Definition coap_debug.c:812
void coap_enable_pdu_data_output(int enable_data)
Defines whether the data is to be output or not for the coap_show_pdu() function.
Definition coap_debug.c:98
char * coap_string_tls_support(char *buffer, size_t bufsize)
Build a string containing the current (D)TLS library support.
#define COAP_MAX_LOGGING_LEVEL
Definition coap_debug.h:48
#define COAP_ERR_FD
Used for output for COAP_LOG_CRIT to COAP_LOG_EMERG.
Definition coap_debug.h:44
coap_log_t
Logging type.
Definition coap_debug.h:56
const char * coap_package_version(void)
Get the library package version.
Definition coap_debug.c:79
void coap_set_log_level(coap_log_t level)
Sets the log level to the specified value.
Definition coap_debug.c:108
void coap_log_impl(coap_log_t level, const char *format,...)
Writes the given text to COAP_ERR_FD (for level <= COAP_LOG_CRIT) or COAP_DEBUG_FD (for level >= COAP...
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:241
#define COAP_DEBUG_FD
Used for output for COAP_LOG_OSCORE to COAP_LOG_ERR.
Definition coap_debug.h:37
const char * coap_package_build(void)
Get the library package build.
Definition coap_debug.c:84
const char * coap_print_ip_addr(const coap_address_t *addr, char *buf, size_t len)
Print the IP address into the defined buffer.
Definition coap_debug.c:424
void coap_show_tls_version(coap_log_t level)
Display the current (D)TLS library linked with and built for version.
void coap_set_show_pdu_output(int use_fprintf)
Defines the output mode for the coap_show_pdu() function.
Definition coap_debug.c:93
#define coap_log_err(...)
Definition coap_debug.h:102
const char * coap_package_name(void)
Get the library package name.
Definition coap_debug.c:74
void(* coap_log_handler_t)(coap_log_t level, const char *message)
Logging callback handler definition.
Definition coap_debug.h:215
#define coap_log(level,...)
Logging function.
Definition coap_debug.h:290
@ COAP_LOG_INFO
Definition coap_debug.h:63
@ COAP_LOG_EMERG
Definition coap_debug.h:57
@ COAP_LOG_DEBUG
Definition coap_debug.h:64
@ COAP_LOG_CRIT
Definition coap_debug.h:59
@ COAP_LOG_ERR
Definition coap_debug.h:60
@ COAP_LOG_WARN
Definition coap_debug.h:61
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
uint32_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
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.
#define COAP_OPT_ALL
Pre-defined filter that includes all options.
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
#define COAP_DEBUG_BUF_SIZE
#define COAP_DEFAULT_VERSION
#define COAP_OPTION_HOP_LIMIT
Definition coap_pdu.h:136
#define COAP_OPTION_NORESPONSE
Definition coap_pdu.h:149
#define COAP_OPTION_URI_HOST
Definition coap_pdu.h:122
#define COAP_OPTION_IF_MATCH
Definition coap_pdu.h:121
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC
Definition coap_pdu.h:235
#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI
Definition coap_pdu.h:247
#define COAP_MEDIATYPE_APPLICATION_CWT
Definition coap_pdu.h:225
#define COAP_OPTION_BLOCK2
Definition coap_pdu.h:141
#define COAP_MEDIATYPE_APPLICATION_MB_CBOR_SEQ
Definition coap_pdu.h:258
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT
Definition coap_pdu.h:233
#define COAP_MEDIATYPE_APPLICATION_RDF_XML
Definition coap_pdu.h:221
#define COAP_OPTION_CONTENT_FORMAT
Definition coap_pdu.h:130
#define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS
Definition coap_pdu.h:209
#define COAP_OPTION_SIZE2
Definition coap_pdu.h:143
#define COAP_MEDIATYPE_APPLICATION_SENSML_XML
Definition coap_pdu.h:249
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN
Definition coap_pdu.h:231
#define COAP_OPTION_BLOCK1
Definition coap_pdu.h:142
#define COAP_OPTION_Q_BLOCK1
Definition coap_pdu.h:138
#define COAP_OPTION_PROXY_SCHEME
Definition coap_pdu.h:146
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET
Definition coap_pdu.h:239
#define COAP_MEDIATYPE_APPLICATION_OSCORE
Definition coap_pdu.h:261
#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR
Definition coap_pdu.h:244
#define COAP_OPTION_URI_QUERY
Definition coap_pdu.h:135
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY
Definition coap_pdu.h:238
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1
Definition coap_pdu.h:232
#define COAP_OPTION_IF_NONE_MATCH
Definition coap_pdu.h:124
#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM
Definition coap_pdu.h:220
#define COAP_OPTION_LOCATION_PATH
Definition coap_pdu.h:127
#define COAP_OPTION_URI_PATH
Definition coap_pdu.h:129
#define COAP_SIGNALING_OPTION_EXTENDED_TOKEN_LENGTH
Definition coap_pdu.h:203
#define COAP_MEDIATYPE_APPLICATION_SENML_EXI
Definition coap_pdu.h:246
#define COAP_OPTION_OSCORE
Definition coap_pdu.h:128
#define COAP_MEDIATYPE_APPLICATION_CBOR
Definition coap_pdu.h:224
#define COAP_OPTION_SIZE1
Definition coap_pdu.h:147
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0
Definition coap_pdu.h:234
#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER
Definition coap_pdu.h:202
#define COAP_MEDIATYPE_TEXT_PLAIN
Definition coap_pdu.h:217
#define COAP_MEDIATYPE_APPLICATION_JSON
Definition coap_pdu.h:223
#define COAP_OPTION_LOCATION_QUERY
Definition coap_pdu.h:139
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0
Definition coap_pdu.h:236
#define COAP_MEDIATYPE_APPLICATION_ACE_CBOR
Definition coap_pdu.h:255
#define COAP_OPTION_Q_BLOCK2
Definition coap_pdu.h:144
#define COAP_MEDIATYPE_APPLICATION_SENML_JSON
Definition coap_pdu.h:242
#define COAP_MEDIATYPE_APPLICATION_EXI
Definition coap_pdu.h:222
#define COAP_SIGNALING_OPTION_CUSTODY
Definition coap_pdu.h:206
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 coap_pdu.c:934
#define COAP_OPTION_RTAG
Definition coap_pdu.h:150
#define COAP_OPTION_URI_PATH_ABB
Definition coap_pdu.h:131
#define COAP_MEDIATYPE_APPLICATION_COAP_GROUP_JSON
Definition coap_pdu.h:228
#define COAP_OPTION_URI_PORT
Definition coap_pdu.h:126
#define COAP_MEDIATYPE_APPLICATION_SENML_XML
Definition coap_pdu.h:248
#define COAP_OPTION_ACCEPT
Definition coap_pdu.h:137
#define COAP_MEDIATYPE_APPLICATION_DOTS_CBOR
Definition coap_pdu.h:252
#define COAP_OPTION_MAXAGE
Definition coap_pdu.h:134
#define COAP_OPTION_ETAG
Definition coap_pdu.h:123
#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON
Definition coap_pdu.h:243
#define COAP_OPTION_PROXY_URI
Definition coap_pdu.h:145
#define COAP_OPTION_OBSERVE
Definition coap_pdu.h:125
#define COAP_SIGNALING_OPTION_HOLD_OFF
Definition coap_pdu.h:210
#define COAP_OPTION_ECHO
Definition coap_pdu.h:148
#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT
Definition coap_pdu.h:218
#define COAP_SIGNALING_OPTION_BAD_CSM_OPTION
Definition coap_pdu.h:213
#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE
Definition coap_pdu.h:201
#define COAP_MEDIATYPE_APPLICATION_XML
Definition coap_pdu.h:219
#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR
Definition coap_pdu.h:245
@ COAP_PROTO_WS
Definition coap_pdu.h:323
@ COAP_PROTO_WSS
Definition coap_pdu.h:324
@ COAP_SIGNALING_CODE_ABORT
Definition coap_pdu.h:374
@ COAP_SIGNALING_CODE_CSM
Definition coap_pdu.h:370
@ COAP_SIGNALING_CODE_PING
Definition coap_pdu.h:371
@ COAP_SIGNALING_CODE_PONG
Definition coap_pdu.h:372
@ COAP_SIGNALING_CODE_RELEASE
Definition coap_pdu.h:373
@ COAP_MESSAGE_CON
Definition coap_pdu.h:71
@ COAP_SIGNALING_RELEASE
Definition coap_pdu.h:196
@ COAP_SIGNALING_CSM
Definition coap_pdu.h:193
@ COAP_SIGNALING_PONG
Definition coap_pdu.h:195
@ COAP_SIGNALING_PING
Definition coap_pdu.h:194
@ COAP_SIGNALING_ABORT
Definition coap_pdu.h:197
#define COAP_PROTO_NOT_RELIABLE(p)
int coap_dtls_cid_is_supported(void)
Check whether (D)TLS CID is available.
Definition coap_notls.c:86
int coap_dtls_psk_is_supported(void)
Check whether (D)TLS PSK is available.
Definition coap_notls.c:50
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition coap_notls.c:41
int coap_ws_is_supported(void)
Check whether WebSockets is available.
Definition coap_ws.c:934
int coap_oscore_is_supported(void)
Check whether OSCORE is available.
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition coap_notls.c:36
int coap_dtls_pki_is_supported(void)
Check whether (D)TLS PKI is available.
Definition coap_notls.c:59
int coap_dtls_rpk_is_supported(void)
Check whether (D)TLS RPK is available.
Definition coap_notls.c:77
int coap_dtls_pkcs11_is_supported(void)
Check whether (D)TLS PKCS11 is available.
Definition coap_notls.c:68
coap_upa_chain_t * coap_upa_server_mapping_chain
Definition coap_uri.c:33
const char * coap_map_abbrev_uri_path(coap_upa_chain_t *chain, uint32_t value)
Determine the expanded Uri-Path-Abbrev option value.
Definition coap_uri.c:1154
coap_upa_chain_t * coap_upa_client_fallback_chain
Definition coap_uri.c:32
#define COAP_STATIC_INLINE
Definition libcoap.h:57
#define COAP_THREAD_LOCAL_VAR
Definition libcoap.h:84
Multi-purpose address abstraction.
struct sockaddr_in sin
struct coap_sockaddr_un cun
struct sockaddr_in6 sin6
struct sockaddr sa
union coap_address_t::@0 addr
size_t length
length of binary data
Definition coap_str.h:66
const uint8_t * s
read-only binary data
Definition coap_str.h:67
Iterator to run through PDU options.
coap_option_num_t number
decoded option number
structure for CoAP PDUs
coap_pdu_code_t code
request method (value 1–31) or response code (value 64-255)
coap_bin_const_t actual_token
Actual token in pdu.
coap_mid_t mid
message id, if any, in regular host byte order
coap_session_t * session
Session responsible for PDU or NULL.
coap_pdu_type_t type
message type
coap_proto_t proto
protocol used
char sun_path[COAP_UNIX_PATH_MAX]
The structure used for returning the underlying (D)TLS library information.
Definition coap_dtls.h:87
uint64_t built_version
(D)TLS Built against Library Version
Definition coap_dtls.h:90
coap_tls_library_t type
Library type.
Definition coap_dtls.h:89
uint64_t version
(D)TLS runtime Library Version
Definition coap_dtls.h:88