9 #include "coap_config.h" 11 #if defined(HAVE_STRNLEN) && defined(__GNUC__) && !defined(_GNU_SOURCE) 15 #if defined(HAVE_ASSERT_H) && !defined(assert) 24 #ifdef HAVE_ARPA_INET_H 25 #include <arpa/inet.h> 27 #ifdef HAVE_WS2TCPIP_H 42 # define fprintf(fd, ...) LWIP_PLATFORM_DIAG((__VA_ARGS__)) 48 # define DEBUG DEBUG_PRINT 50 #include "net/ip/uip-debug.h" 62 return PACKAGE_STRING;
82 "EMRG",
"ALRT",
"CRIT",
"ERR ",
"WARN",
"NOTE",
"INFO",
"DEBG" 91 tmp = localtime(&now);
92 return strftime(s, len,
"%b %d %H:%M:%S", tmp);
100 return snprintf(s, len,
"%u.%03u",
123 while(*s++ && n < maxlen)
131 unsigned char *result,
size_t buflen,
int encode_always ) {
132 const uint8_t hex[] =
"0123456789ABCDEF";
141 if (!encode_always && isprint(*data)) {
142 if (cnt+1 < buflen) {
149 if (cnt+4 < buflen) {
152 *result++ = hex[(*data & 0xf0) >> 4];
153 *result++ = hex[*data & 0x0f];
167 #define min(a,b) ((a) < (b) ? (a) : (b)) 172 #if defined( HAVE_ARPA_INET_H ) || defined( HAVE_WS2TCPIP_H ) 173 const void *addrptr = NULL;
175 unsigned char *p = buf;
177 switch (addr->
addr.
sa.sa_family) {
179 addrptr = &addr->
addr.
sin.sin_addr;
180 port = ntohs(addr->
addr.
sin.sin_port);
188 addrptr = &addr->
addr.
sin6.sin6_addr;
189 port = ntohs(addr->
addr.
sin6.sin6_port);
193 memcpy(buf,
"(unknown address type)",
min(22, len));
198 if (inet_ntop(addr->
addr.
sa.sa_family, addrptr, (
char *)p, len) == 0) {
199 perror(
"coap_print_addr");
205 if (addr->
addr.
sa.sa_family == AF_INET6) {
212 p += snprintf((
char *)p, buf + len - p + 1,
":%d", port);
214 return buf + len - p;
217 unsigned char *p = buf;
219 # if NETSTACK_CONF_WITH_IPV6 220 const uint8_t hex[] =
"0123456789ABCDEF";
227 for (i=0; i < 16; i += 2) {
231 *p++ = hex[(addr->
addr.u8[i] & 0xf0) >> 4];
232 *p++ = hex[(addr->
addr.u8[i] & 0x0f)];
233 *p++ = hex[(addr->
addr.u8[i+1] & 0xf0) >> 4];
234 *p++ = hex[(addr->
addr.u8[i+1] & 0x0f)];
238 # warning "IPv4 network addresses will not be included in debug output" 243 if (buf + len - p < 6)
247 p += snprintf((
char *)p, buf + len - p + 1,
":%d", uip_htons(addr->port));
255 # warning "inet_ntop() not available, network addresses will not be included in debug output" 262 # define fprintf(fd, ...) PRINTF(__VA_ARGS__) 266 # define vfprintf(fd, ...) vprintf(__VA_ARGS__) 268 # define vfprintf(fd, ...) PRINTF(__VA_ARGS__) 275 static const char *types[] = {
"CON",
"NON",
"ACK",
"RST",
"???" };
277 return types[
min(t,
sizeof(types)/
sizeof(
char *) - 1)];
283 static const char *methods[] = {
"0.00",
"GET",
"POST",
"PUT",
"DELETE",
284 "FETCH",
"PATCH",
"iPATCH" };
285 static const char *signals[] = {
"7.00",
"CSM",
"Ping",
"Pong",
"Release",
289 if (c <
sizeof(methods)/
sizeof(
const char *)) {
291 }
else if (c >= 224 && c - 224 < (
int)(
sizeof(signals)/
sizeof(
const char *))) {
292 return signals[c-224];
294 snprintf(buf,
sizeof(buf),
"%u.%02u", c >> 5, c & 0x1f);
302 struct option_desc_t {
307 static struct option_desc_t options[] = {
330 static struct option_desc_t options_csm[] = {
335 static struct option_desc_t options_pingpong[] = {
339 static struct option_desc_t options_release[] = {
344 static struct option_desc_t options_abort[] = {
352 for (i = 0; i <
sizeof(options_csm)/
sizeof(
struct option_desc_t); i++) {
353 if (option_type == options_csm[i].type) {
354 return options_csm[i].name;
358 for (i = 0; i <
sizeof(options_pingpong)/
sizeof(
struct option_desc_t); i++) {
359 if (option_type == options_pingpong[i].type) {
360 return options_pingpong[i].name;
364 for (i = 0; i <
sizeof(options_release)/
sizeof(
struct option_desc_t); i++) {
365 if (option_type == options_release[i].type) {
366 return options_release[i].name;
370 for (i = 0; i <
sizeof(options_abort)/
sizeof(
struct option_desc_t); i++) {
371 if (option_type == options_abort[i].type) {
372 return options_abort[i].name;
377 for (i = 0; i <
sizeof(options)/
sizeof(
struct option_desc_t); i++) {
378 if (option_type == options[i].type) {
379 return options[i].name;
384 snprintf(buf,
sizeof(buf),
"%u", option_type);
390 unsigned char *result,
unsigned int buflen) {
396 static struct desc_t formats[] = {
420 { 75,
"application/dcaf+cbor" }
426 for (i = 0; i <
sizeof(formats)/
sizeof(
struct desc_t); i++) {
427 if (format_type == formats[i].type) {
428 return snprintf((
char *)result, buflen,
"%s", formats[i].name);
433 return snprintf((
char *)result, buflen,
"%d", format_type);
443 return !(content_format == -1 ||
450 #define COAP_DO_SHOW_OUTPUT_LINE \ 452 if (use_fprintf_for_show_pdu) { \ 453 fprintf(COAP_DEBUG_FD, "%s", outbuf); \ 456 coap_log(level, "%s", outbuf); \ 462 unsigned char buf[1024];
464 int encode = 0, have_options = 0, i;
467 int content_format = -1;
477 snprintf(outbuf,
sizeof(outbuf),
"v:%d t:%s c:%s i:%04x {",
482 outbuflen = strlen(outbuf);
483 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
484 "%02x", pdu->
token[i]);
486 outbuflen = strlen(outbuf);
487 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
"}");
492 outbuflen = strlen(outbuf);
493 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
" [");
498 outbuflen = strlen(outbuf);
499 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
",");
504 buf_len = snprintf((
char *)buf,
sizeof(buf),
"%u",
518 buf,
sizeof(buf), 0);
521 buf_len = snprintf((
char *)buf,
sizeof(buf),
"%u",
530 buf_len = snprintf((
char *)buf,
sizeof(buf),
"%u",
537 }
else switch (opt_iter.
type) {
549 buf_len = snprintf((
char *)buf,
sizeof(buf),
"%u/%c/%u",
562 buf_len = snprintf((
char *)buf,
sizeof(buf),
"%u",
582 buf,
sizeof(buf), encode);
585 outbuflen = strlen(outbuf);
586 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
591 outbuflen = strlen(outbuf);
592 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
" ]");
596 outbuflen = strlen(outbuf);
597 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
" :: ");
600 int keep_data_len = data_len;
603 outbuflen = strlen(outbuf);
604 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
605 "binary data length %ld\n", data_len);
611 snprintf(outbuf,
sizeof(outbuf),
"<<");
613 outbuflen = strlen(outbuf);
614 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
617 outbuflen = strlen(outbuf);
618 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
">>");
619 data_len = keep_data_len;
621 outbuflen = strlen(outbuf);
622 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
"\n");
629 snprintf(outbuf,
sizeof(outbuf),
"<<");
631 outbuflen = strlen(outbuf);
632 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
633 "%c ", isprint (*data) ? *data :
'.');
636 outbuflen = strlen(outbuf);
637 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
">>");
640 outbuflen = strlen(outbuf);
641 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
"'%s'", buf);
646 outbuflen = strlen(outbuf);
647 snprintf(&outbuf[outbuflen],
sizeof(outbuf)-outbuflen,
"\n");
666 switch (tls_version->
type) {
668 snprintf(buffer, bufsize,
"TLS Library: None");
671 snprintf(buffer, bufsize,
"TLS Library: TinyDTLS - runtime %ld.%ld.%ld, " 672 "libcoap built for %ld.%ld.%ld",
674 (tls_version->
version >> 8) & 0xff,
681 switch (tls_version->
version &0xf) {
683 strcpy(beta,
"-dev");
689 strcpy(beta,
"-beta");
690 beta[5] = (tls_version->
version &0xf) +
'0';
694 sub[0] = ((tls_version->
version >> 4) & 0xff) ?
695 ((tls_version->
version >> 4) & 0xff) +
'a' -1 :
'\000';
699 strcpy(b_beta,
"-dev");
705 strcpy(b_beta,
"-beta");
711 ((tls_version->
built_version >> 4) & 0xff) +
'a' -1 :
'\000';
713 snprintf(buffer, bufsize,
"TLS Library: OpenSSL - runtime " 714 "%ld.%ld.%ld%s%s, libcoap built for %ld.%ld.%ld%s%s",
716 (tls_version->
version >> 20) & 0xff,
717 (tls_version->
version >> 12) & 0xff, sub, beta,
723 snprintf(buffer, bufsize,
"TLS Library: GnuTLS - runtime %ld.%ld.%ld, " 724 "libcoap built for %ld.%ld.%ld",
726 (tls_version->
version >> 8) & 0xff,
733 snprintf(buffer, bufsize,
"Library type %d unknown", tls_version->
type);
752 #if defined(WITH_CONTIKI) || defined(WITH_LWIP) 755 char message[8 + 1024 * 2];
758 va_start(ap, format);
759 vsnprintf( message,
sizeof(message), format, ap);
772 fprintf(log_fd,
"%s ", timebuf);
775 fprintf(log_fd,
"%s ",
loglevels[level]);
777 va_start(ap, format);
778 vfprintf(log_fd, format, ap);
793 const char *p = loss_level;
795 int n = (int)strtol(p, &end, 10), i = 0;
796 if (end == p || n < 0)
810 n = (int)strtol(p, &end, 10);
811 if (end == p || n <= 0)
820 n = (int)strtol(p, &end, 10);
821 if (end == p || n <= 0)
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.
uint8_t code
request method (value 1–10) or response code (value 40-255)
void coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu)
Display the contents of the specified pdu.
#define COAP_OPTION_IF_MATCH
#define COAP_MEDIATYPE_APPLICATION_SENSML_JSON
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
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.
#define COAP_SIGNALING_PING
#define COAP_SIGNALING_CSM
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC0
#define COAP_OPTION_PROXY_URI
static int use_fprintf_for_show_pdu
#define COAP_OPTION_CONTENT_FORMAT
#define COAP_OPTION_NORESPONSE
multi-purpose address abstraction
int coap_debug_set_packet_loss(const char *loss_level)
Set the packet loss level for testing.
static const char * msg_type_string(uint16_t t)
Returns a textual description of the message type t.
#define COAP_OPT_ALL
Pre-defined filter that includes all options.
#define COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
const char * coap_package_name(void)
Get the library package name.
size_t coap_print_addr(const struct coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
#define COAP_OPTION_OBSERVE
#define COAP_DEBUG_BUF_SIZE
#define COAP_MEDIATYPE_APPLICATION_JSON
coap_time_t coap_ticks_to_rt(coap_tick_t t)
Helper function that converts coap ticks to wallclock time.
#define COAP_OPTION_BLOCK1
#define COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER
#define COAP_OPTION_MAXAGE
#define COAP_DO_SHOW_OUTPUT_LINE
uint64_t version
(D)TLS runtime Library Version
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
#define COAP_MEDIATYPE_APPLICATION_SENSML_EXI
#define COAP_OPTION_LOCATION_QUERY
#define COAP_OPTION_PROXY_SCHEME
uint16_t type
decoded option type
static int send_packet_count
static const char * msg_option_string(uint8_t code, uint16_t option_type)
Returns a textual description of the option name.
#define COAP_MEDIATYPE_APPLICATION_SENSML_XML
#define COAP_MEDIATYPE_APPLICATION_SENML_CBOR
#define COAP_MEDIATYPE_APPLICATION_SENML_JSON
#define COAP_MEDIATYPE_APPLICATION_EXI
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.
void coap_set_log_level(coap_log_t level)
Sets the log level to the specified value.
static int packet_loss_level
#define COAP_DEFAULT_VERSION
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)...
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
COAP_STATIC_INLINE size_t print_timestamp(char *s, size_t len, coap_tick_t t)
#define COAP_DEBUG_FD
Used for output for LOG_DEBUG to LOG_ERR.
void(* coap_log_handler_t)(coap_log_t level, const char *message)
Logging call-back handler definition.
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
#define COAP_SIGNALING_PONG
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
uint16_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE
int coap_debug_send_packet(void)
Check to see whether a packet should be sent or not.
#define COAP_SIGNALING_OPTION_CUSTODY
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN
#define COAP_OPTION_URI_PORT
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
#define COAP_ERR_FD
Used for output for LOG_CRIT to LOG_EMERG.
static int num_packet_loss_intervals
#define COAP_MEDIATYPE_APPLICATION_SENSML_CBOR
static size_t print_readable(const uint8_t *data, size_t len, unsigned char *result, size_t buflen, int encode_always)
#define COAP_TLS_LIBRARY_TINYDTLS
Using TinyDTLS library.
static struct packet_num_interval packet_loss_intervals[10]
uint8_t * token
first byte of token, if any, or options
void coap_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
The structure used for returning the underlying (D)TLS library information.
#define COAP_OPTION_IF_NONE_MATCH
Iterator to run through PDU options.
#define COAP_MEDIATYPE_APPLICATION_LINK_FORMAT
int coap_get_data(const coap_pdu_t *pdu, size_t *len, uint8_t **data)
Retrieves the length and data pointer of specified PDU.
#define COAP_OPTION_SIZE1
void coap_set_show_pdu_output(int use_fprintf)
Defines the output mode for the coap_show_pdu() function.
static size_t strnlen(const char *s, size_t maxlen)
A length-safe strlen() fake.
#define COAP_OPTION_SIZE2
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0
#define COAP_STATIC_INLINE
void coap_show_tls_version(coap_log_t level)
Display the current (D)TLS library linked with and built for version.
#define COAP_TLS_LIBRARY_GNUTLS
Using GnuTLS library.
#define COAP_MEDIATYPE_APPLICATION_XML
static const char * loglevels[]
#define COAP_OPTION_BLOCK2
#define COAP_OPTION_LOCATION_PATH
static const char * msg_code_string(uint16_t c)
Returns a textual description of the method or response code.
unsigned int coap_decode_var_bytes(const uint8_t *buf, unsigned int len)
Decodes multiple-length byte sequences.
static coap_log_handler_t log_handler
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
#define COAP_MEDIATYPE_APPLICATION_SENML_EXI
#define COAP_OPT_BLOCK_SZX(opt)
Returns the value of the SZX-field of a Block option opt.
coap_log_t
Pre-defined log levels akin to what is used in syslog.
#define COAP_OPTION_URI_PATH
const char * coap_package_version(void)
Get the library package version.
#define COAP_TLS_LIBRARY_NOTLS
No DTLS library.
#define COAP_MEDIATYPE_TEXT_PLAIN
#define COAP_MEDIATYPE_APPLICATION_COSE_SIGN1
coap_log_t coap_get_log_level(void)
Get the current logging level.
#define COAP_OPTION_URI_QUERY
#define coap_log(level,...)
Logging function.
union coap_address_t::@0 addr
#define COAP_OPTION_ACCEPT
#define COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS
#define COAP_SIGNALING_RELEASE
#define COAP_SIGNALING_OPTION_BAD_CSM_OPTION
void coap_set_log_handler(coap_log_handler_t handler)
Add a custom log callback handler.
#define COAP_MEDIATYPE_APPLICATION_CBOR
#define COAP_SIGNALING_OPTION_HOLD_OFF
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY
#define COAP_OPT_BLOCK_MORE(opt)
Returns the value of the More-bit of a Block option opt.
#define COAP_MEDIATYPE_APPLICATION_SENML_XML
#define prng(Buf, Length)
Fills Buf with Length bytes of random data.
uint8_t token_length
length of Token
#define COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT
#define COAP_MEDIATYPE_APPLICATION_COSE_MAC
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...
uint64_t built_version
(D)TLS Built against Library Version
#define COAP_MEDIATYPE_APPLICATION_OCTET_STREAM
#define COAP_OPTION_URI_HOST
#define COAP_SIGNALING_ABORT
#define COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET
static unsigned int print_content_format(unsigned int format_type, unsigned char *result, unsigned int buflen)
uint16_t tid
transaction id, if any, in regular host byte order