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