libcoap 4.3.5-develop-3035cfd
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
15
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
613const char *
615 struct option_desc_t {
616 uint16_t value;
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_SIG_OPT_MAX_MESSAGE_SIZE, "Max-Message-Size" },
652 { COAP_SIG_OPT_BLOCK_WISE_TRANSFER, "Block-Wise-Transfer" },
653 { COAP_SIG_OPT_EXTENDED_TOKEN_LENGTH, "Extended-Token-Length" }
654 };
655
656 static struct option_desc_t options_pingpong[] = {
657 { COAP_SIG_OPT_CUSTODY, "Custody" }
658 };
659
660 static struct option_desc_t options_release[] = {
661 { COAP_SIG_OPT_ALTERNATIVE_ADDRESS, "Alternative-Address" },
662 { COAP_SIG_OPT_HOLD_OFF, "Hold-Off" }
663 };
664
665 static struct option_desc_t options_abort[] = {
666 { COAP_SIG_OPT_BAD_CSM_OPTION, "Bad-CSM-Option" }
667 };
668
669 static char buf[6];
670 size_t i;
671
672 if (code == COAP_SIGNALING_CODE_CSM) {
673 for (i = 0; i < sizeof(options_csm)/sizeof(struct option_desc_t); i++) {
674 if (number == options_csm[i].value) {
675 return options_csm[i].name;
676 }
677 }
678 } else if (code == COAP_SIGNALING_CODE_PING || code == COAP_SIGNALING_CODE_PONG) {
679 for (i = 0; i < sizeof(options_pingpong)/sizeof(struct option_desc_t); i++) {
680 if (number == options_pingpong[i].value) {
681 return options_pingpong[i].name;
682 }
683 }
684 } else if (code == COAP_SIGNALING_CODE_RELEASE) {
685 for (i = 0; i < sizeof(options_release)/sizeof(struct option_desc_t); i++) {
686 if (number == options_release[i].value) {
687 return options_release[i].name;
688 }
689 }
690 } else if (code == COAP_SIGNALING_CODE_ABORT) {
691 for (i = 0; i < sizeof(options_abort)/sizeof(struct option_desc_t); i++) {
692 if (number == options_abort[i].value) {
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 (number == options[i].value) {
700 return options[i].name;
701 }
702 }
703 }
704 /* unknown option type, just print to buf */
705 snprintf(buf, sizeof(buf), "%u", number);
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 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 ((coap_sig_csm_opt_t)opt_iter.number) {
888 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
890 coap_opt_length(option)));
891 break;
893 default:
894 buf_len = 0;
895 break;
896 }
897 } else if (pdu->code == COAP_SIGNALING_CODE_PING ||
899 switch ((coap_sig_ping_opt_t)opt_iter.number) {
901 default:
902 buf_len = 0;
903 }
904 } else if (pdu->code == COAP_SIGNALING_CODE_RELEASE) {
905 switch ((coap_sig_release_opt_t)opt_iter.number) {
907 buf_len = print_readable(coap_opt_value(option),
908 coap_opt_length(option),
909 buf, sizeof(buf), 0);
910 break;
912 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
914 coap_opt_length(option)));
915 break;
916 default:
917 buf_len = 0;
918 break;
919 }
920 } else if (pdu->code == COAP_SIGNALING_CODE_ABORT) {
921 switch ((coap_sig_abort_opt_t)opt_iter.number) {
923 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
925 coap_opt_length(option)));
926 break;
927 default:
928 buf_len = 0;
929 break;
930 }
931 } else {
932 switch ((coap_code_opt_num_t)opt_iter.number) {
935 content_format = (int)coap_decode_var_bytes(coap_opt_value(option),
936 coap_opt_length(option));
937
938 buf_len = print_content_format(content_format, buf, sizeof(buf));
939 break;
940
945 /* split block option into number/more/size where more is the
946 * letter M if set, the _ otherwise */
947 if (COAP_OPT_BLOCK_SZX(option) == 7) {
948 if (coap_get_data(pdu, &data_len, &data))
949 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/BERT(%" PRIuS ")",
950 coap_opt_block_num(option), /* block number */
951 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
952 data_len);
953 else
954 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/BERT",
955 coap_opt_block_num(option), /* block number */
956 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_'); /* M bit */
957 } else {
958 buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/%u",
959 coap_opt_block_num(option), /* block number */
960 COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
961 (1 << (COAP_OPT_BLOCK_SZX(option) + 4))); /* block size */
962 }
963
964 break;
965
967 opt_len = coap_opt_length(option);
968 buf[0] = '\000';
969 if (opt_len) {
970 size_t ofs = 1;
971 size_t cnt;
972
973 opt_val = coap_opt_value(option);
974 if (opt_val[0] & 0x20) {
975 /* Group Flag */
976 snprintf((char *)buf, sizeof(buf), "grp");
977 }
978 if (opt_val[0] & 0x07) {
979 /* Partial IV */
980 cnt = opt_val[0] & 0x07;
981 if (cnt > opt_len - ofs)
982 goto no_more;
983 buf_len = strlen((char *)buf);
984 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len, "%spIV=0x",
985 buf_len ? "," : "");
986 for (i = 0; (uint32_t)i < cnt; i++) {
987 buf_len = strlen((char *)buf);
988 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
989 "%02x", opt_val[ofs + i]);
990 }
991 ofs += cnt;
992 }
993 if (opt_val[0] & 0x10) {
994 /* kid context */
995 if (ofs >= opt_len)
996 goto no_more;
997 cnt = opt_val[ofs];
998 if (cnt > opt_len - ofs - 1)
999 goto no_more;
1000 ofs++;
1001 buf_len = strlen((char *)buf);
1002 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len, "%skc=0x",
1003 buf_len ? "," : "");
1004 for (i = 0; (uint32_t)i < cnt; i++) {
1005 buf_len = strlen((char *)buf);
1006 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
1007 "%02x", opt_val[ofs + i]);
1008 }
1009 ofs += cnt;
1010 }
1011 if (opt_val[0] & 0x08) {
1012 /* kid */
1013 if (ofs >= opt_len)
1014 goto no_more;
1015 cnt = opt_len - ofs;
1016 buf_len = strlen((char *)buf);
1017 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len, "%skid=0x",
1018 buf_len ? "," : "");
1019 for (i = 0; (uint32_t)i < cnt; i++) {
1020 buf_len = strlen((char *)buf);
1021 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
1022 "%02x", opt_val[ofs + i]);
1023 }
1024 }
1025 }
1026no_more:
1027 buf_len = strlen((char *)buf);
1028 is_oscore_payload = 1;
1029 break;
1030
1032 case COAP_OPTION_MAXAGE:
1034 case COAP_OPTION_SIZE1:
1035 case COAP_OPTION_SIZE2:
1037 if (coap_opt_length(option)) {
1038 /* show values as unsigned decimal value */
1039 buf_len = snprintf((char *)buf, sizeof(buf), "%u",
1041 coap_opt_length(option)));
1042 }
1043 break;
1044
1046 case COAP_OPTION_ETAG:
1047 case COAP_OPTION_ECHO:
1049 case COAP_OPTION_RTAG:
1050 opt_len = coap_opt_length(option);
1051 opt_val = coap_opt_value(option);
1052 snprintf((char *)buf, sizeof(buf), "0x");
1053 for (i = 0; (uint32_t)i < opt_len; i++) {
1054 buf_len = strlen((char *)buf);
1055 snprintf((char *)&buf[buf_len], sizeof(buf)-buf_len,
1056 "%02x", opt_val[i]);
1057 }
1058 buf_len = strlen((char *)buf);
1059 break;
1061 value = coap_decode_var_bytes(coap_opt_value(option),
1062 coap_opt_length(option));
1064 if (!exp) {
1066 }
1067 if (exp) {
1068 snprintf((char *)&buf, sizeof(buf), "%s", exp);
1069 } else {
1070 snprintf((char *)&buf, sizeof(buf), "(%" PRIu32 ")", value);
1071 }
1072 buf_len = strlen((char *)buf);
1073 break;
1081 buf_len = print_readable(coap_opt_value(option),
1082 coap_opt_length(option),
1083 buf, sizeof(buf), 0);
1084 break;
1086 case COAP_OPTION_EDHOC:
1087 default:
1088 buf_len = print_readable(coap_opt_value(option),
1089 coap_opt_length(option),
1090 buf, sizeof(buf), 1);
1091 }
1092 }
1093 outbuflen = strlen(outbuf);
1094 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1095 " %s:%.*s", coap_option_string(pdu->code, opt_iter.number),
1096 (int)buf_len, buf);
1097 }
1098
1099 outbuflen = strlen(outbuf);
1100 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " ]");
1101
1102 if (coap_get_data(pdu, &data_len, &data)) {
1104 /* Only output data if wanted */
1105 outbuflen = strlen(outbuf);
1106 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " :: ");
1107 outbuflen = strlen(outbuf);
1108 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1109 "data length %"PRIuS " (data suppressed)\n", data_len);
1111#if COAP_THREAD_SAFE
1112 coap_mutex_unlock(&m_show_pdu);
1113#endif /* COAP_THREAD_SAFE */
1114 return;
1115 }
1116
1117 outbuflen = strlen(outbuf);
1118 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " :: ");
1119
1120 if (is_binary(content_format) || !isprint(data[0]) || is_oscore_payload) {
1121 size_t keep_data_len = data_len;
1122 const uint8_t *keep_data = data;
1123
1124 outbuflen = strlen(outbuf);
1125 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1126 "binary data length %"PRIuS "\n", data_len);
1128 /*
1129 * Output hex dump of binary data as a continuous entry
1130 */
1131 outbuf[0] = '\000';
1132 snprintf(outbuf, sizeof(outbuf), "<<");
1133 while (data_len--) {
1134 outbuflen = strlen(outbuf);
1135 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1136 "%02x", *data++);
1137 }
1138 outbuflen = strlen(outbuf);
1139 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
1140 data_len = keep_data_len;
1141 data = keep_data;
1142 outbuflen = strlen(outbuf);
1143 if (outbuflen == sizeof(outbuf)-1)
1144 outbuflen--;
1145 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
1147 /*
1148 * Output ascii readable (if possible), immediately under the
1149 * hex value of the character output above to help binary debugging
1150 */
1151 outbuf[0] = '\000';
1152 snprintf(outbuf, sizeof(outbuf), "<<");
1153 while (data_len--) {
1154 outbuflen = strlen(outbuf);
1155 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
1156 "%c ", isprint(*data) ? *data : '.');
1157 data++;
1158 }
1159 outbuflen = strlen(outbuf);
1160 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
1161 } else {
1162 size_t max_length;
1163
1164 outbuflen = strlen(outbuf);
1165 max_length = sizeof(outbuf)-outbuflen;
1166 if (max_length > 1) {
1167 outbuf[outbuflen++] = '\'';
1168 outbuf[outbuflen] = '\000';
1169 max_length--;
1170 }
1171 if (max_length > 1) {
1172 outbuflen += print_readable(data, data_len,
1173 (unsigned char *)&outbuf[outbuflen],
1174 max_length, 0);
1175 }
1176 /* print_readable may be handling unprintables - hence headroom of 4 */
1177 if (outbuflen < sizeof(outbuf)-4-1) {
1178 outbuf[outbuflen++] = '\'';
1179 outbuf[outbuflen] = '\000';
1180 }
1181 }
1182 }
1183
1184 outbuflen = strlen(outbuf);
1185 if (outbuflen == sizeof(outbuf)-1)
1186 outbuflen--;
1187 snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
1189
1190#if COAP_THREAD_SAFE
1191 coap_mutex_unlock(&m_show_pdu);
1192#endif /* COAP_THREAD_SAFE */
1193}
1194
1195void
1197 char buffer[128];
1198 coap_string_tls_version(buffer, sizeof(buffer));
1199 coap_log(level, "%s\n", buffer);
1200}
1201
1202char *
1203coap_string_tls_version(char *buffer, size_t bufsize) {
1205 char beta[8];
1206 char sub[2];
1207 char b_beta[8];
1208 char b_sub[2];
1209
1210 switch (tls_version->type) {
1212 snprintf(buffer, bufsize, "TLS Library: None");
1213 break;
1215 snprintf(buffer, bufsize, "TLS Library: TinyDTLS - runtime %lu.%lu.%lu, "
1216 "libcoap built for %lu.%lu.%lu",
1217 (unsigned long)(tls_version->version >> 16),
1218 (unsigned long)((tls_version->version >> 8) & 0xff),
1219 (unsigned long)(tls_version->version & 0xff),
1220 (unsigned long)(tls_version->built_version >> 16),
1221 (unsigned long)((tls_version->built_version >> 8) & 0xff),
1222 (unsigned long)(tls_version->built_version & 0xff));
1223 break;
1225 switch (tls_version->version &0xf) {
1226 case 0:
1227 strcpy(beta, "-dev");
1228 break;
1229 case 0xf:
1230 strcpy(beta, "");
1231 break;
1232 default:
1233 strcpy(beta, "-beta");
1234 beta[5] = (tls_version->version &0xf) + '0';
1235 beta[6] = '\000';
1236 break;
1237 }
1238 sub[0] = ((tls_version->version >> 4) & 0xff) ?
1239 ((tls_version->version >> 4) & 0xff) + 'a' -1 : '\000';
1240 sub[1] = '\000';
1241 switch (tls_version->built_version &0xf) {
1242 case 0:
1243 strcpy(b_beta, "-dev");
1244 break;
1245 case 0xf:
1246 strcpy(b_beta, "");
1247 break;
1248 default:
1249 strcpy(b_beta, "-beta");
1250 b_beta[5] = (tls_version->built_version &0xf) + '0';
1251 b_beta[6] = '\000';
1252 break;
1253 }
1254 b_sub[0] = ((tls_version->built_version >> 4) & 0xff) ?
1255 ((tls_version->built_version >> 4) & 0xff) + 'a' -1 : '\000';
1256 b_sub[1] = '\000';
1257 snprintf(buffer, bufsize, "TLS Library: OpenSSL - runtime "
1258 "%lu.%lu.%lu%s%s, libcoap built for %lu.%lu.%lu%s%s",
1259 (unsigned long)(tls_version->version >> 28),
1260 (unsigned long)((tls_version->version >> 20) & 0xff),
1261 (unsigned long)((tls_version->version >> 12) & 0xff), sub, beta,
1262 (unsigned long)(tls_version->built_version >> 28),
1263 (unsigned long)((tls_version->built_version >> 20) & 0xff),
1264 (unsigned long)((tls_version->built_version >> 12) & 0xff),
1265 b_sub, b_beta);
1266 break;
1268 snprintf(buffer, bufsize, "TLS Library: GnuTLS - runtime %lu.%lu.%lu, "
1269 "libcoap built for %lu.%lu.%lu",
1270 (unsigned long)(tls_version->version >> 16),
1271 (unsigned long)((tls_version->version >> 8) & 0xff),
1272 (unsigned long)(tls_version->version & 0xff),
1273 (unsigned long)(tls_version->built_version >> 16),
1274 (unsigned long)((tls_version->built_version >> 8) & 0xff),
1275 (unsigned long)(tls_version->built_version & 0xff));
1276 break;
1278 snprintf(buffer, bufsize, "TLS Library: Mbed TLS - runtime %lu.%lu.%lu, "
1279 "libcoap built for %lu.%lu.%lu",
1280 (unsigned long)(tls_version->version >> 24),
1281 (unsigned long)((tls_version->version >> 16) & 0xff),
1282 (unsigned long)((tls_version->version >> 8) & 0xff),
1283 (unsigned long)(tls_version->built_version >> 24),
1284 (unsigned long)((tls_version->built_version >> 16) & 0xff),
1285 (unsigned long)((tls_version->built_version >> 8) & 0xff));
1286 break;
1288 snprintf(buffer, bufsize, "TLS Library: wolfSSL - runtime %lu.%lu.%lu, "
1289 "libcoap built for %lu.%lu.%lu",
1290 (unsigned long)(tls_version->version >> 24),
1291 (unsigned long)((tls_version->version >> 12) & 0xfff),
1292 (unsigned long)((tls_version->version >> 0) & 0xfff),
1293 (unsigned long)(tls_version->built_version >> 24),
1294 (unsigned long)((tls_version->built_version >> 12) & 0xfff),
1295 (unsigned long)((tls_version->built_version >> 0) & 0xfff));
1296 break;
1297 default:
1298 snprintf(buffer, bufsize, "Library type %d unknown", tls_version->type);
1299 break;
1300 }
1301 return buffer;
1302}
1303
1304char *
1305coap_string_tls_support(char *buffer, size_t bufsize) {
1306 const int have_tls = coap_tls_is_supported();
1307 const int have_dtls = coap_dtls_is_supported();
1308 const int have_psk = coap_dtls_psk_is_supported();
1309 const int have_pki = coap_dtls_pki_is_supported();
1310 const int have_pkcs11 = coap_dtls_pkcs11_is_supported();
1311 const int have_rpk = coap_dtls_rpk_is_supported();
1312 const int have_cid = coap_dtls_cid_is_supported();
1313 const int have_oscore = coap_oscore_is_supported();
1314 const int have_ws = coap_ws_is_supported();
1315
1316 if (have_dtls == 0 && have_tls == 0) {
1317 snprintf(buffer, bufsize, "(No DTLS or TLS support)\n(%sOSCORE)\n(%sWebSockets)",
1318 have_oscore ? "Have " : "No ",
1319 have_ws ? "Have " : "No ");
1320 return buffer;
1321 }
1322 snprintf(buffer, bufsize,
1323 "(%sDTLS and %sTLS support; %sPSK, %sPKI, %sPKCS11, %sRPK and %sCID support)\n(%sOSCORE)\n(%sWebSockets)",
1324 have_dtls ? "" : "No ",
1325 have_tls ? "" : "no ",
1326 have_psk ? "" : "no ",
1327 have_pki ? "" : "no ",
1328 have_pkcs11 ? "" : "no ",
1329 have_rpk ? "" : "no ",
1330 have_cid ? "" : "no ",
1331 have_oscore ? "Have " : "No ",
1332 have_ws ? "Have " : "No ");
1333 return buffer;
1334}
1335
1337
1338void
1340 log_handler = handler;
1341}
1342
1343#if COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING
1344/* Visible to only this thread */
1345extern COAP_THREAD_LOCAL_VAR uint32_t thread_no;
1346/* Visible across all threads */
1347extern uint32_t max_thread_no;
1348#endif /* COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING */
1349
1350void
1351coap_log_impl(coap_log_t level, const char *format, ...) {
1352
1353#if COAP_THREAD_SAFE
1354 coap_mutex_lock(&m_log_impl);
1355#endif /* COAP_THREAD_SAFE */
1356
1357 if (log_handler) {
1358#if COAP_CONSTRAINED_STACK
1359 /* message can be protected by m_log_impl if needed */
1360 static char message[COAP_DEBUG_BUF_SIZE];
1361#else /* ! COAP_CONSTRAINED_STACK */
1362 char message[COAP_DEBUG_BUF_SIZE];
1363#endif /* ! COAP_CONSTRAINED_STACK */
1364 va_list ap;
1365 va_start(ap, format);
1366
1367#ifdef RIOT_VERSION
1368 flash_vsnprintf(message, sizeof(message), format, ap);
1369#else /* !RIOT_VERSION */
1370 vsnprintf(message, sizeof(message), format, ap);
1371#endif /* !RIOT_VERSION */
1372 va_end(ap);
1373 log_handler(level, message);
1374 } else {
1375 char timebuf[32];
1376 coap_tick_t now;
1377 va_list ap;
1378 FILE *log_fd;
1379 size_t len;
1380
1381 log_fd = level <= COAP_LOG_CRIT ? COAP_ERR_FD : COAP_DEBUG_FD;
1382
1383 coap_ticks(&now);
1384 len = print_timestamp(timebuf,sizeof(timebuf), now);
1385 if (len)
1386 fprintf(log_fd, "%.*s ", (int)len, timebuf);
1387
1388#if COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING
1389 if (thread_no == 0) {
1390 /*
1391 * All other call to coap_mutex_lock(&m_io_threads) immediately
1392 * by setting thread_no if 0. So deadlock should never occur.
1393 */
1394 coap_mutex_lock(&m_io_threads);
1395 thread_no = ++max_thread_no;
1396 coap_mutex_unlock(&m_io_threads);
1397 }
1398 fprintf(log_fd, "%2d ", thread_no);
1399#endif /* COAP_THREAD_SAFE && COAP_THREAD_NUM_LOGGING */
1400
1401 fprintf(log_fd, "%s ", coap_log_level_desc(level));
1402
1403 va_start(ap, format);
1404#ifdef RIOT_VERSION
1405 flash_vfprintf(log_fd, format, ap);
1406#else /* !RIOT_VERSION */
1407 vfprintf(log_fd, format, ap);
1408#endif /* !RIOT_VERSION */
1409 va_end(ap);
1410 fflush(log_fd);
1411 }
1412
1413#if COAP_THREAD_SAFE
1414 coap_mutex_unlock(&m_log_impl);
1415#endif /* COAP_THREAD_SAFE */
1416}
1417
1423static uint16_t packet_loss_level = 0;
1424static int send_packet_count = 0;
1427static uint16_t packet_fail_level = 0;
1428
1429int
1430coap_debug_set_packet_loss(const char *loss_level) {
1431 const char *p = loss_level;
1432 char *end = NULL;
1433 int n = (int)strtol(p, &end, 10), i = 0;
1434 if (end == p || n < 0)
1435 return 0;
1436 if (*end == '%') {
1437 if (n > 100)
1438 n = 100;
1439 packet_loss_level = n * 0xffff / 100;
1440 coap_log_debug("packet loss level set to %d%%\n", n);
1441 } else {
1442 if (n <= 0)
1443 return 0;
1444 while (i < 10) {
1445 packet_loss_intervals[i].start = n;
1446 if (*end == '-') {
1447 p = end + 1;
1448 n = (int)strtol(p, &end, 10);
1449 if (end == p || n <= 0)
1450 return 0;
1451 }
1452 packet_loss_intervals[i++].end = n;
1453 if (*end == 0)
1454 break;
1455 if (*end != ',')
1456 return 0;
1457 p = end + 1;
1458 n = (int)strtol(p, &end, 10);
1459 if (end == p || n <= 0)
1460 return 0;
1461 }
1462 if (i == 10)
1463 return 0;
1465 }
1467 return 1;
1468}
1469
1470int
1473 if (num_packet_loss_intervals > 0) {
1474 int i;
1475 for (i = 0; i < num_packet_loss_intervals; i++) {
1478 coap_log_debug("Following packet no %u dropped\n", send_packet_count);
1479 return 0;
1480 }
1481 }
1482 }
1483 if (packet_loss_level > 0) {
1484 uint16_t r = 0;
1485 coap_prng_lkd((uint8_t *)&r, 2);
1486 if (r < packet_loss_level) {
1487 coap_log_debug("Following packet no %u dropped\n", send_packet_count);
1488 return 0;
1489 }
1490 }
1491 if (num_packet_fail_intervals > 0) {
1492 int i;
1493 for (i = 0; i < num_packet_fail_intervals; i++) {
1496 coap_log_debug("Following packet no %u failed\n", send_packet_count);
1497 errno = ECONNREFUSED;
1498 return -1;
1499 }
1500 }
1501 }
1502 if (packet_fail_level > 0) {
1503 uint16_t r = 0;
1504 coap_prng_lkd((uint8_t *)&r, 2);
1505 if (r < packet_fail_level) {
1506 coap_log_debug("Following packet no %u failed\n", send_packet_count);
1507 errno = ECONNREFUSED;
1508 return -1;
1509 }
1510 }
1511 return 1;
1512}
1513
1514int
1515coap_debug_set_packet_fail(const char *fail_level) {
1516 const char *p = fail_level;
1517 char *end = NULL;
1518 int n = (int)strtol(p, &end, 10), i = 0;
1519 if (end == p || n < 0)
1520 return 0;
1521 if (*end == '%') {
1522 if (n > 100)
1523 n = 100;
1524 packet_fail_level = n * 0xffff / 100;
1525 coap_log_debug("packet fail level set to %d%%\n", n);
1526 } else {
1527 if (n <= 0)
1528 return 0;
1529 while (i < 10) {
1530 packet_fail_intervals[i].start = n;
1531 if (*end == '-') {
1532 p = end + 1;
1533 n = (int)strtol(p, &end, 10);
1534 if (end == p || n <= 0)
1535 return 0;
1536 }
1537 packet_fail_intervals[i++].end = n;
1538 if (*end == 0)
1539 break;
1540 if (*end != ',')
1541 return 0;
1542 p = end + 1;
1543 n = (int)strtol(p, &end, 10);
1544 if (end == p || n <= 0)
1545 return 0;
1546 }
1547 if (i == 10)
1548 return 0;
1550 }
1552 return 1;
1553}
1554
1555void
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
const char * coap_option_string(coap_pdu_code_t code, coap_option_num_t number)
Returns a textual description of the option name.
Definition coap_debug.c:614
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 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
#define PRIu32
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
uint16_t coap_option_num_t
Definition coap_option.h:37
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
coap_sig_ping_opt_t
@ COAP_SIG_OPT_CUSTODY
coap_sig_csm_opt_t
@ COAP_SIG_OPT_BLOCK_WISE_TRANSFER
@ COAP_SIG_OPT_EXTENDED_TOKEN_LENGTH
@ COAP_SIG_OPT_MAX_MESSAGE_SIZE
coap_sig_release_opt_t
@ COAP_SIG_OPT_ALTERNATIVE_ADDRESS
@ COAP_SIG_OPT_HOLD_OFF
coap_code_opt_num_t
Definition coap_option.h:70
@ COAP_OPTION_OBSERVE
Definition coap_option.h:75
@ COAP_OPTION_IF_NONE_MATCH
Definition coap_option.h:74
@ COAP_OPTION_ETAG
Definition coap_option.h:73
@ COAP_OPTION_EDHOC
Definition coap_option.h:89
@ COAP_OPTION_NORESPONSE
Definition coap_option.h:98
@ COAP_OPTION_MAXAGE
Definition coap_option.h:83
@ COAP_OPTION_SIZE2
Definition coap_option.h:92
@ COAP_OPTION_Q_BLOCK2
Definition coap_option.h:93
@ COAP_OPTION_PROXY_SCHEME
Definition coap_option.h:95
@ COAP_OPTION_HOP_LIMIT
Definition coap_option.h:85
@ COAP_OPTION_URI_PORT
Definition coap_option.h:76
@ COAP_OPTION_URI_HOST
Definition coap_option.h:72
@ COAP_OPTION_BLOCK2
Definition coap_option.h:90
@ COAP_OPTION_IF_MATCH
Definition coap_option.h:71
@ COAP_OPTION_SIZE1
Definition coap_option.h:96
@ COAP_OPTION_ECHO
Definition coap_option.h:97
@ COAP_OPTION_RTAG
Definition coap_option.h:99
@ COAP_OPTION_BLOCK1
Definition coap_option.h:91
@ COAP_OPTION_URI_PATH
Definition coap_option.h:79
@ COAP_OPTION_Q_BLOCK1
Definition coap_option.h:87
@ COAP_OPTION_OSCORE
Definition coap_option.h:78
@ COAP_OPTION_CONTENT_FORMAT
Definition coap_option.h:80
@ COAP_OPTION_LOCATION_QUERY
Definition coap_option.h:88
@ COAP_OPTION_URI_QUERY
Definition coap_option.h:84
@ COAP_OPTION_PROXY_URI
Definition coap_option.h:94
@ COAP_OPTION_LOCATION_PATH
Definition coap_option.h:77
@ COAP_OPTION_URI_PATH_ABB
Definition coap_option.h:81
@ COAP_OPTION_ACCEPT
Definition coap_option.h:86
coap_sig_abort_opt_t
@ COAP_SIG_OPT_BAD_CSM_OPTION
#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:51
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:101
@ 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_MEDIATYPE_APPLICATION_COSE_MAC
Definition coap_pdu.h:152
#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI
Definition coap_pdu.h:164
#define COAP_MEDIATYPE_APPLICATION_CWT
Definition coap_pdu.h:142
#define COAP_MEDIATYPE_APPLICATION_MB_CBOR_SEQ
Definition coap_pdu.h:175
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT
Definition coap_pdu.h:150
#define COAP_MEDIATYPE_APPLICATION_RDF_XML
Definition coap_pdu.h:138
#define COAP_MEDIATYPE_APPLICATION_SENSML_XML
Definition coap_pdu.h:166
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN
Definition coap_pdu.h:148
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET
Definition coap_pdu.h:156
#define COAP_MEDIATYPE_APPLICATION_OSCORE
Definition coap_pdu.h:178
#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR
Definition coap_pdu.h:161
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY
Definition coap_pdu.h:155
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1
Definition coap_pdu.h:149
#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM
Definition coap_pdu.h:137
#define COAP_MEDIATYPE_APPLICATION_SENML_EXI
Definition coap_pdu.h:163
coap_pdu_code_t
Set of codes available for a PDU.
Definition coap_pdu.h:248
#define COAP_MEDIATYPE_APPLICATION_CBOR
Definition coap_pdu.h:141
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0
Definition coap_pdu.h:151
#define COAP_MEDIATYPE_TEXT_PLAIN
Definition coap_pdu.h:134
#define COAP_MEDIATYPE_APPLICATION_JSON
Definition coap_pdu.h:140
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0
Definition coap_pdu.h:153
#define COAP_MEDIATYPE_APPLICATION_ACE_CBOR
Definition coap_pdu.h:172
#define COAP_MEDIATYPE_APPLICATION_SENML_JSON
Definition coap_pdu.h:159
#define COAP_MEDIATYPE_APPLICATION_EXI
Definition coap_pdu.h:139
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:947
#define COAP_MEDIATYPE_APPLICATION_COAP_GROUP_JSON
Definition coap_pdu.h:145
#define COAP_MEDIATYPE_APPLICATION_SENML_XML
Definition coap_pdu.h:165
#define COAP_MEDIATYPE_APPLICATION_DOTS_CBOR
Definition coap_pdu.h:169
#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON
Definition coap_pdu.h:160
#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT
Definition coap_pdu.h:135
#define COAP_MEDIATYPE_APPLICATION_XML
Definition coap_pdu.h:136
#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR
Definition coap_pdu.h:162
@ COAP_PROTO_WS
Definition coap_pdu.h:240
@ COAP_PROTO_WSS
Definition coap_pdu.h:241
@ COAP_SIGNALING_CODE_ABORT
Definition coap_pdu.h:291
@ COAP_SIGNALING_CODE_CSM
Definition coap_pdu.h:287
@ COAP_SIGNALING_CODE_PING
Definition coap_pdu.h:288
@ COAP_SIGNALING_CODE_PONG
Definition coap_pdu.h:289
@ COAP_SIGNALING_CODE_RELEASE
Definition coap_pdu.h:290
@ COAP_MESSAGE_CON
Definition coap_pdu.h:71
#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.
union coap_address_t::@107143027060232071362347256026245042105001016231 addr
struct sockaddr_in sin
struct coap_sockaddr_un cun
struct sockaddr_in6 sin6
struct sockaddr sa
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