mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
libcoap_430: Update code for use with libcoap 4.3.0
Remove no longer needed code from coap_server/coap_client. Add in multicast support for coap_server/coap_client. Update libcoap logging to use esp-idf logging Signed-off-by: Harshit Malpani <harshit.malpani@espressif.com>
This commit is contained in:
parent
ef5fe39faa
commit
ed3d440428
@ -6,17 +6,24 @@ if(NOT CONFIG_LWIP_IPV6 AND NOT CMAKE_BUILD_EARLY_EXPANSION)
|
|||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(include_dirs port/include port/include/coap libcoap/include libcoap/include/coap2)
|
set(include_dirs port/include port/include libcoap/include)
|
||||||
|
|
||||||
set(srcs
|
set(srcs
|
||||||
"libcoap/src/address.c"
|
"libcoap/src/address.c"
|
||||||
"libcoap/src/async.c"
|
"libcoap/src/async.c"
|
||||||
"libcoap/src/block.c"
|
"libcoap/src/block.c"
|
||||||
|
"libcoap/src/coap_asn1.c"
|
||||||
|
"libcoap/src/coap_cache.c"
|
||||||
|
"libcoap/src/coap_debug.c"
|
||||||
"libcoap/src/coap_event.c"
|
"libcoap/src/coap_event.c"
|
||||||
"libcoap/src/coap_hashkey.c"
|
"libcoap/src/coap_hashkey.c"
|
||||||
|
"libcoap/src/coap_io.c"
|
||||||
|
"libcoap/src/coap_mbedtls.c"
|
||||||
|
"libcoap/src/coap_notls.c"
|
||||||
|
"libcoap/src/coap_prng.c"
|
||||||
"libcoap/src/coap_session.c"
|
"libcoap/src/coap_session.c"
|
||||||
|
"libcoap/src/coap_tcp.c"
|
||||||
"libcoap/src/coap_time.c"
|
"libcoap/src/coap_time.c"
|
||||||
"port/coap_debug.c"
|
|
||||||
"libcoap/src/encode.c"
|
"libcoap/src/encode.c"
|
||||||
"libcoap/src/mem.c"
|
"libcoap/src/mem.c"
|
||||||
"libcoap/src/net.c"
|
"libcoap/src/net.c"
|
||||||
@ -25,17 +32,14 @@ set(srcs
|
|||||||
"libcoap/src/resource.c"
|
"libcoap/src/resource.c"
|
||||||
"libcoap/src/str.c"
|
"libcoap/src/str.c"
|
||||||
"libcoap/src/subscribe.c"
|
"libcoap/src/subscribe.c"
|
||||||
"libcoap/src/uri.c"
|
"libcoap/src/uri.c")
|
||||||
"libcoap/src/coap_io.c"
|
|
||||||
"port/coap_notls.c"
|
|
||||||
"port/coap_mbedtls.c")
|
|
||||||
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
INCLUDE_DIRS "${include_dirs}"
|
INCLUDE_DIRS "${include_dirs}"
|
||||||
REQUIRES lwip mbedtls)
|
REQUIRES lwip mbedtls)
|
||||||
|
|
||||||
# Silence format truncation warning, until it is fixed upstream
|
# Silence format truncation warning, until it is fixed upstream
|
||||||
set_source_files_properties(port/coap_debug.c PROPERTIES COMPILE_FLAGS -Wno-format-truncation)
|
# set_source_files_properties(libcoap/src/coap_debug.c PROPERTIES COMPILE_FLAGS -Wno-format-truncation)
|
||||||
|
|
||||||
# Needed for coap headers in public builds, also.
|
# Needed for coap headers in public builds, also.
|
||||||
#
|
#
|
||||||
|
@ -52,6 +52,8 @@ menu "CoAP Configuration"
|
|||||||
bool "Info"
|
bool "Info"
|
||||||
config COAP_LOG_DEBUG
|
config COAP_LOG_DEBUG
|
||||||
bool "Debug"
|
bool "Debug"
|
||||||
|
config COAP_LOG_MBEDTLS
|
||||||
|
bool "mbedTLS"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config COAP_LOG_DEFAULT_LEVEL
|
config COAP_LOG_DEFAULT_LEVEL
|
||||||
@ -65,5 +67,6 @@ menu "CoAP Configuration"
|
|||||||
default 5 if COAP_LOG_NOTICE
|
default 5 if COAP_LOG_NOTICE
|
||||||
default 6 if COAP_LOG_INFO
|
default 6 if COAP_LOG_INFO
|
||||||
default 7 if COAP_LOG_DEBUG
|
default 7 if COAP_LOG_DEBUG
|
||||||
|
default 9 if COAP_LOG_MBEDTLS
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
ifdef CONFIG_LWIP_IPV6
|
ifdef CONFIG_LWIP_IPV6
|
||||||
|
|
||||||
COMPONENT_ADD_INCLUDEDIRS := port/include port/include/coap libcoap/include libcoap/include/coap2
|
COMPONENT_ADD_INCLUDEDIRS := port/include port/include libcoap/include
|
||||||
|
|
||||||
COMPONENT_OBJS = libcoap/src/address.o libcoap/src/async.o libcoap/src/block.o libcoap/src/coap_event.o libcoap/src/coap_hashkey.o libcoap/src/coap_session.o libcoap/src/coap_time.o port/coap_debug.o libcoap/src/encode.o libcoap/src/mem.o libcoap/src/net.o libcoap/src/option.o libcoap/src/pdu.o libcoap/src/resource.o libcoap/src/str.o libcoap/src/subscribe.o libcoap/src/uri.o port/coap_mbedtls.o libcoap/src/coap_io.o port/coap_notls.o
|
COMPONENT_OBJS = libcoap/src/address.o libcoap/src/async.o libcoap/src/block.o libcoap/src/coap_asn1.o libcoap/src/coap_cache.o libcoap/src/coap_debug.o libcoap/src/coap_event.o libcoap/src/coap_hashkey.o libcoap/src/coap_io.o libcoap/src/coap_mbedtls.o libcoap/src/coap_notls.o libcoap/src/coap_prng.o libcoap/src/coap_session.o libcoap/src/coap_tcp.o libcoap/src/coap_time.o libcoap/src/encode.o libcoap/src/mem.o libcoap/src/net.o libcoap/src/option.o libcoap/src/pdu.o libcoap/src/resource.o libcoap/src/str.o libcoap/src/subscribe.o libcoap/src/uri.o
|
||||||
|
|
||||||
COMPONENT_SRCDIRS := libcoap/src libcoap port
|
COMPONENT_SRCDIRS := libcoap/src libcoap port
|
||||||
|
|
||||||
COMPONENT_SUBMODULES += libcoap
|
COMPONENT_SUBMODULES += libcoap
|
||||||
|
|
||||||
# Silence format truncation warning, until it is fixed upstream
|
# Silence format truncation warning, until it is fixed upstream
|
||||||
port/coap_debug.o: CFLAGS += -Wno-format-truncation
|
# libcoap/src/coap_debug.o: CFLAGS += -Wno-format-truncation
|
||||||
|
|
||||||
endif # CONFIG_LWIP_IPV6
|
endif # CONFIG_LWIP_IPV6
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 98954eb30a2e728e172a6cd29430ae5bc999b585
|
Subproject commit 9b6451c3654bc1f625e36c87f018c2da34bea5e6
|
@ -1,888 +0,0 @@
|
|||||||
/* debug.c -- debug utilities
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010--2012,2014--2019 Olaf Bergmann <bergmann@tzi.org> and others
|
|
||||||
*
|
|
||||||
* This file is part of the CoAP library libcoap. Please see
|
|
||||||
* README for terms of use.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "coap_config.h"
|
|
||||||
|
|
||||||
#if defined(HAVE_STRNLEN) && defined(__GNUC__) && !defined(_GNU_SOURCE)
|
|
||||||
#define _GNU_SOURCE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_ASSERT_H) && !defined(assert)
|
|
||||||
# include <assert.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TIME_H
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "libcoap.h"
|
|
||||||
#include "coap_dtls.h"
|
|
||||||
#include "block.h"
|
|
||||||
#include "coap_debug.h"
|
|
||||||
#include "encode.h"
|
|
||||||
#include "net.h"
|
|
||||||
#include "coap_mutex.h"
|
|
||||||
|
|
||||||
#ifdef WITH_LWIP
|
|
||||||
# define fprintf(fd, ...) LWIP_PLATFORM_DIAG((__VA_ARGS__))
|
|
||||||
# define fflush(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_CONTIKI
|
|
||||||
# ifndef DEBUG
|
|
||||||
# define DEBUG DEBUG_PRINT
|
|
||||||
# endif /* DEBUG */
|
|
||||||
#include "net/ip/uip-debug.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static coap_log_t maxlog = LOG_WARNING; /* default maximum log level */
|
|
||||||
|
|
||||||
static int use_fprintf_for_show_pdu = 1; /* non zero to output with fprintf */
|
|
||||||
|
|
||||||
const char *coap_package_name(void) {
|
|
||||||
return PACKAGE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *coap_package_version(void) {
|
|
||||||
return PACKAGE_STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coap_set_show_pdu_output(int use_fprintf) {
|
|
||||||
use_fprintf_for_show_pdu = use_fprintf;
|
|
||||||
}
|
|
||||||
|
|
||||||
coap_log_t
|
|
||||||
coap_get_log_level(void) {
|
|
||||||
return maxlog;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coap_set_log_level(coap_log_t level) {
|
|
||||||
maxlog = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this array has the same order as the type log_t */
|
|
||||||
static const char *loglevels[] = {
|
|
||||||
"EMRG", "ALRT", "CRIT", "ERR ", "WARN", "NOTE", "INFO", "DEBG"
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef HAVE_TIME_H
|
|
||||||
|
|
||||||
COAP_STATIC_INLINE size_t
|
|
||||||
print_timestamp(char *s, size_t len, coap_tick_t t) {
|
|
||||||
struct tm *tmp;
|
|
||||||
time_t now = coap_ticks_to_rt(t);
|
|
||||||
tmp = localtime(&now);
|
|
||||||
return strftime(s, len, "%b %d %H:%M:%S", tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* alternative implementation: just print the timestamp */
|
|
||||||
|
|
||||||
COAP_STATIC_INLINE size_t
|
|
||||||
print_timestamp(char *s, size_t len, coap_tick_t t) {
|
|
||||||
#ifdef HAVE_SNPRINTF
|
|
||||||
return snprintf(s, len, "%u.%03u",
|
|
||||||
(unsigned int)coap_ticks_to_rt(t),
|
|
||||||
(unsigned int)(t % COAP_TICKS_PER_SECOND));
|
|
||||||
#else /* HAVE_SNPRINTF */
|
|
||||||
/* @todo do manual conversion of timestamp */
|
|
||||||
return 0;
|
|
||||||
#endif /* HAVE_SNPRINTF */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_TIME_H */
|
|
||||||
|
|
||||||
#ifndef HAVE_STRNLEN
|
|
||||||
/**
|
|
||||||
* A length-safe strlen() fake.
|
|
||||||
*
|
|
||||||
* @param s The string to count characters != 0.
|
|
||||||
* @param maxlen The maximum length of @p s.
|
|
||||||
*
|
|
||||||
* @return The length of @p s.
|
|
||||||
*/
|
|
||||||
static inline size_t
|
|
||||||
strnlen(const char *s, size_t maxlen) {
|
|
||||||
size_t n = 0;
|
|
||||||
while(*s++ && n < maxlen)
|
|
||||||
++n;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_STRNLEN */
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
print_readable( const uint8_t *data, size_t len,
|
|
||||||
unsigned char *result, size_t buflen, int encode_always ) {
|
|
||||||
const uint8_t hex[] = "0123456789ABCDEF";
|
|
||||||
size_t cnt = 0;
|
|
||||||
assert(data || len == 0);
|
|
||||||
|
|
||||||
if (buflen == 0) { /* there is nothing we can do here but return */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (len) {
|
|
||||||
if (!encode_always && isprint(*data)) {
|
|
||||||
if (cnt+1 < buflen) { /* keep one byte for terminating zero */
|
|
||||||
*result++ = *data;
|
|
||||||
++cnt;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (cnt+4 < buflen) { /* keep one byte for terminating zero */
|
|
||||||
*result++ = '\\';
|
|
||||||
*result++ = 'x';
|
|
||||||
*result++ = hex[(*data & 0xf0) >> 4];
|
|
||||||
*result++ = hex[*data & 0x0f];
|
|
||||||
cnt += 4;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++data; --len;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = '\0'; /* add a terminating zero */
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef min
|
|
||||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t
|
|
||||||
coap_print_addr(const struct coap_address_t *addr, unsigned char *buf, size_t len) {
|
|
||||||
#if defined( HAVE_ARPA_INET_H ) || defined( HAVE_WS2TCPIP_H )
|
|
||||||
const void *addrptr = NULL;
|
|
||||||
in_port_t port;
|
|
||||||
unsigned char *p = buf;
|
|
||||||
size_t need_buf;
|
|
||||||
|
|
||||||
switch (addr->addr.sa.sa_family) {
|
|
||||||
case AF_INET:
|
|
||||||
addrptr = &addr->addr.sin.sin_addr;
|
|
||||||
port = ntohs(addr->addr.sin.sin_port);
|
|
||||||
need_buf = INET_ADDRSTRLEN;
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
if (len < 7) /* do not proceed if buffer is even too short for [::]:0 */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*p++ = '[';
|
|
||||||
|
|
||||||
addrptr = &addr->addr.sin6.sin6_addr;
|
|
||||||
port = ntohs(addr->addr.sin6.sin6_port);
|
|
||||||
need_buf = INET6_ADDRSTRLEN;
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
memcpy(buf, "(unknown address type)", min(22, len));
|
|
||||||
return min(22, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cast needed for Windows, since it doesn't have the correct API signature. */
|
|
||||||
if (inet_ntop(addr->addr.sa.sa_family, addrptr, (char *)p,
|
|
||||||
min(len, need_buf)) == 0) {
|
|
||||||
perror("coap_print_addr");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += strnlen((char *)p, len);
|
|
||||||
|
|
||||||
if (addr->addr.sa.sa_family == AF_INET6) {
|
|
||||||
if (p < buf + len) {
|
|
||||||
*p++ = ']';
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += snprintf((char *)p, buf + len - p + 1, ":%d", port);
|
|
||||||
|
|
||||||
return buf + len - p;
|
|
||||||
#else /* HAVE_ARPA_INET_H */
|
|
||||||
# if WITH_CONTIKI
|
|
||||||
unsigned char *p = buf;
|
|
||||||
uint8_t i;
|
|
||||||
# if NETSTACK_CONF_WITH_IPV6
|
|
||||||
const uint8_t hex[] = "0123456789ABCDEF";
|
|
||||||
|
|
||||||
if (len < 41)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*p++ = '[';
|
|
||||||
|
|
||||||
for (i=0; i < 16; i += 2) {
|
|
||||||
if (i) {
|
|
||||||
*p++ = ':';
|
|
||||||
}
|
|
||||||
*p++ = hex[(addr->addr.u8[i] & 0xf0) >> 4];
|
|
||||||
*p++ = hex[(addr->addr.u8[i] & 0x0f)];
|
|
||||||
*p++ = hex[(addr->addr.u8[i+1] & 0xf0) >> 4];
|
|
||||||
*p++ = hex[(addr->addr.u8[i+1] & 0x0f)];
|
|
||||||
}
|
|
||||||
*p++ = ']';
|
|
||||||
# else /* WITH_UIP6 */
|
|
||||||
# warning "IPv4 network addresses will not be included in debug output"
|
|
||||||
|
|
||||||
if (len < 21)
|
|
||||||
return 0;
|
|
||||||
# endif /* WITH_UIP6 */
|
|
||||||
if (buf + len - p < 6)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef HAVE_SNPRINTF
|
|
||||||
p += snprintf((char *)p, buf + len - p + 1, ":%d", uip_htons(addr->port));
|
|
||||||
#else /* HAVE_SNPRINTF */
|
|
||||||
/* @todo manual conversion of port number */
|
|
||||||
#endif /* HAVE_SNPRINTF */
|
|
||||||
|
|
||||||
return p - buf;
|
|
||||||
# else /* WITH_CONTIKI */
|
|
||||||
/* TODO: output addresses manually */
|
|
||||||
# warning "inet_ntop() not available, network addresses will not be included in debug output"
|
|
||||||
# endif /* WITH_CONTIKI */
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WITH_CONTIKI
|
|
||||||
# define fprintf(fd, ...) PRINTF(__VA_ARGS__)
|
|
||||||
# define fflush(...)
|
|
||||||
|
|
||||||
# ifdef HAVE_VPRINTF
|
|
||||||
# define vfprintf(fd, ...) vprintf(__VA_ARGS__)
|
|
||||||
# else /* HAVE_VPRINTF */
|
|
||||||
# define vfprintf(fd, ...) PRINTF(__VA_ARGS__)
|
|
||||||
# endif /* HAVE_VPRINTF */
|
|
||||||
#endif /* WITH_CONTIKI */
|
|
||||||
|
|
||||||
/** Returns a textual description of the message type @p t. */
|
|
||||||
static const char *
|
|
||||||
msg_type_string(uint16_t t) {
|
|
||||||
static const char *types[] = { "CON", "NON", "ACK", "RST", "???" };
|
|
||||||
|
|
||||||
return types[min(t, sizeof(types)/sizeof(char *) - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a textual description of the method or response code. */
|
|
||||||
static const char *
|
|
||||||
msg_code_string(uint16_t c) {
|
|
||||||
static const char *methods[] = { "0.00", "GET", "POST", "PUT", "DELETE",
|
|
||||||
"FETCH", "PATCH", "iPATCH" };
|
|
||||||
static const char *signals[] = { "7.00", "CSM", "Ping", "Pong", "Release",
|
|
||||||
"Abort" };
|
|
||||||
static char buf[5];
|
|
||||||
|
|
||||||
if (c < sizeof(methods)/sizeof(const char *)) {
|
|
||||||
return methods[c];
|
|
||||||
} else if (c >= 224 && c - 224 < (int)(sizeof(signals)/sizeof(const char *))) {
|
|
||||||
return signals[c-224];
|
|
||||||
} else {
|
|
||||||
snprintf(buf, sizeof(buf), "%u.%02u", (c >> 5) & 0x7, c & 0x1f);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a textual description of the option name. */
|
|
||||||
static const char *
|
|
||||||
msg_option_string(uint8_t code, uint16_t option_type) {
|
|
||||||
struct option_desc_t {
|
|
||||||
uint16_t type;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct option_desc_t options[] = {
|
|
||||||
{ COAP_OPTION_IF_MATCH, "If-Match" },
|
|
||||||
{ COAP_OPTION_URI_HOST, "Uri-Host" },
|
|
||||||
{ COAP_OPTION_ETAG, "ETag" },
|
|
||||||
{ COAP_OPTION_IF_NONE_MATCH, "If-None-Match" },
|
|
||||||
{ COAP_OPTION_OBSERVE, "Observe" },
|
|
||||||
{ COAP_OPTION_URI_PORT, "Uri-Port" },
|
|
||||||
{ COAP_OPTION_LOCATION_PATH, "Location-Path" },
|
|
||||||
{ COAP_OPTION_URI_PATH, "Uri-Path" },
|
|
||||||
{ COAP_OPTION_CONTENT_FORMAT, "Content-Format" },
|
|
||||||
{ COAP_OPTION_MAXAGE, "Max-Age" },
|
|
||||||
{ COAP_OPTION_URI_QUERY, "Uri-Query" },
|
|
||||||
{ COAP_OPTION_ACCEPT, "Accept" },
|
|
||||||
{ COAP_OPTION_LOCATION_QUERY, "Location-Query" },
|
|
||||||
{ COAP_OPTION_BLOCK2, "Block2" },
|
|
||||||
{ COAP_OPTION_BLOCK1, "Block1" },
|
|
||||||
{ COAP_OPTION_PROXY_URI, "Proxy-Uri" },
|
|
||||||
{ COAP_OPTION_PROXY_SCHEME, "Proxy-Scheme" },
|
|
||||||
{ COAP_OPTION_SIZE1, "Size1" },
|
|
||||||
{ COAP_OPTION_SIZE2, "Size2" },
|
|
||||||
{ COAP_OPTION_NORESPONSE, "No-Response" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct option_desc_t options_csm[] = {
|
|
||||||
{ COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE, "Max-Message-Size" },
|
|
||||||
{ COAP_SIGNALING_OPTION_BLOCK_WISE_TRANSFER, "Block-wise-Transfer" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct option_desc_t options_pingpong[] = {
|
|
||||||
{ COAP_SIGNALING_OPTION_CUSTODY, "Custody" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct option_desc_t options_release[] = {
|
|
||||||
{ COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS, "Alternative-Address" },
|
|
||||||
{ COAP_SIGNALING_OPTION_HOLD_OFF, "Hold-Off" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct option_desc_t options_abort[] = {
|
|
||||||
{ COAP_SIGNALING_OPTION_BAD_CSM_OPTION, "Bad-CSM-Option" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static char buf[6];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (code == COAP_SIGNALING_CSM) {
|
|
||||||
for (i = 0; i < sizeof(options_csm)/sizeof(struct option_desc_t); i++) {
|
|
||||||
if (option_type == options_csm[i].type) {
|
|
||||||
return options_csm[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (code == COAP_SIGNALING_PING || code == COAP_SIGNALING_PONG) {
|
|
||||||
for (i = 0; i < sizeof(options_pingpong)/sizeof(struct option_desc_t); i++) {
|
|
||||||
if (option_type == options_pingpong[i].type) {
|
|
||||||
return options_pingpong[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (code == COAP_SIGNALING_RELEASE) {
|
|
||||||
for (i = 0; i < sizeof(options_release)/sizeof(struct option_desc_t); i++) {
|
|
||||||
if (option_type == options_release[i].type) {
|
|
||||||
return options_release[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (code == COAP_SIGNALING_ABORT) {
|
|
||||||
for (i = 0; i < sizeof(options_abort)/sizeof(struct option_desc_t); i++) {
|
|
||||||
if (option_type == options_abort[i].type) {
|
|
||||||
return options_abort[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* search option_type in list of known options */
|
|
||||||
for (i = 0; i < sizeof(options)/sizeof(struct option_desc_t); i++) {
|
|
||||||
if (option_type == options[i].type) {
|
|
||||||
return options[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* unknown option type, just print to buf */
|
|
||||||
snprintf(buf, sizeof(buf), "%u", option_type);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
print_content_format(unsigned int format_type,
|
|
||||||
unsigned char *result, unsigned int buflen) {
|
|
||||||
struct desc_t {
|
|
||||||
unsigned int type;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct desc_t formats[] = {
|
|
||||||
{ COAP_MEDIATYPE_TEXT_PLAIN, "text/plain" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_LINK_FORMAT, "application/link-format" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_XML, "application/xml" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_OCTET_STREAM, "application/octet-stream" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_EXI, "application/exi" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_JSON, "application/json" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_CBOR, "application/cbor" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_SIGN, "application/cose; cose-type=\"cose-sign\"" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_SIGN1, "application/cose; cose-type=\"cose-sign1\"" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT, "application/cose; cose-type=\"cose-encrypt\"" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_ENCRYPT0, "application/cose; cose-type=\"cose-encrypt0\"" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_MAC, "application/cose; cose-type=\"cose-mac\"" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_MAC0, "application/cose; cose-type=\"cose-mac0\"" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_KEY, "application/cose-key" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_COSE_KEY_SET, "application/cose-key-set" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENML_JSON, "application/senml+json" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENSML_JSON, "application/sensml+json" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENML_CBOR, "application/senml+cbor" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENSML_CBOR, "application/sensml+cbor" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENML_EXI, "application/senml-exi" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENSML_EXI, "application/sensml-exi" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENML_XML, "application/senml+xml" },
|
|
||||||
{ COAP_MEDIATYPE_APPLICATION_SENSML_XML, "application/sensml+xml" },
|
|
||||||
{ 75, "application/dcaf+cbor" }
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
/* search format_type in list of known content formats */
|
|
||||||
for (i = 0; i < sizeof(formats)/sizeof(struct desc_t); i++) {
|
|
||||||
if (format_type == formats[i].type) {
|
|
||||||
return snprintf((char *)result, buflen, "%s", formats[i].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unknown content format, just print numeric value to buf */
|
|
||||||
return snprintf((char *)result, buflen, "%d", format_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns 1 if the given @p content_format is either unknown or known
|
|
||||||
* to carry binary data. The return value @c 0 hence indicates
|
|
||||||
* printable data which is also assumed if @p content_format is @c 01.
|
|
||||||
*/
|
|
||||||
COAP_STATIC_INLINE int
|
|
||||||
is_binary(int content_format) {
|
|
||||||
return !(content_format == -1 ||
|
|
||||||
content_format == COAP_MEDIATYPE_TEXT_PLAIN ||
|
|
||||||
content_format == COAP_MEDIATYPE_APPLICATION_LINK_FORMAT ||
|
|
||||||
content_format == COAP_MEDIATYPE_APPLICATION_XML ||
|
|
||||||
content_format == COAP_MEDIATYPE_APPLICATION_JSON);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define COAP_DO_SHOW_OUTPUT_LINE \
|
|
||||||
do { \
|
|
||||||
if (use_fprintf_for_show_pdu) { \
|
|
||||||
fprintf(COAP_DEBUG_FD, "%s", outbuf); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
coap_log(level, "%s", outbuf); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
void
|
|
||||||
coap_show_pdu(coap_log_t level, const coap_pdu_t *pdu) {
|
|
||||||
#if COAP_CONSTRAINED_STACK
|
|
||||||
static coap_mutex_t static_show_pdu_mutex = COAP_MUTEX_INITIALIZER;
|
|
||||||
static unsigned char buf[1024]; /* need some space for output creation */
|
|
||||||
static char outbuf[COAP_DEBUG_BUF_SIZE];
|
|
||||||
#else /* ! COAP_CONSTRAINED_STACK */
|
|
||||||
unsigned char buf[1024]; /* need some space for output creation */
|
|
||||||
char outbuf[COAP_DEBUG_BUF_SIZE];
|
|
||||||
#endif /* ! COAP_CONSTRAINED_STACK */
|
|
||||||
size_t buf_len = 0; /* takes the number of bytes written to buf */
|
|
||||||
int encode = 0, have_options = 0, i;
|
|
||||||
coap_opt_iterator_t opt_iter;
|
|
||||||
coap_opt_t *option;
|
|
||||||
int content_format = -1;
|
|
||||||
size_t data_len;
|
|
||||||
unsigned char *data;
|
|
||||||
int outbuflen = 0;
|
|
||||||
|
|
||||||
/* Save time if not needed */
|
|
||||||
if (level > coap_get_log_level())
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if COAP_CONSTRAINED_STACK
|
|
||||||
coap_mutex_lock(&static_show_pdu_mutex);
|
|
||||||
#endif /* COAP_CONSTRAINED_STACK */
|
|
||||||
|
|
||||||
snprintf(outbuf, sizeof(outbuf), "v:%d t:%s c:%s i:%04x {",
|
|
||||||
COAP_DEFAULT_VERSION, msg_type_string(pdu->type),
|
|
||||||
msg_code_string(pdu->code), pdu->tid);
|
|
||||||
|
|
||||||
for (i = 0; i < pdu->token_length; i++) {
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
|
|
||||||
"%02x", pdu->token[i]);
|
|
||||||
}
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "}");
|
|
||||||
|
|
||||||
/* show options, if any */
|
|
||||||
coap_option_iterator_init(pdu, &opt_iter, COAP_OPT_ALL);
|
|
||||||
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " [");
|
|
||||||
while ((option = coap_option_next(&opt_iter))) {
|
|
||||||
if (!have_options) {
|
|
||||||
have_options = 1;
|
|
||||||
} else {
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pdu->code == COAP_SIGNALING_CSM) switch(opt_iter.type) {
|
|
||||||
case COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE:
|
|
||||||
buf_len = snprintf((char *)buf, sizeof(buf), "%u",
|
|
||||||
coap_decode_var_bytes(coap_opt_value(option),
|
|
||||||
coap_opt_length(option)));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buf_len = 0;
|
|
||||||
break;
|
|
||||||
} else if (pdu->code == COAP_SIGNALING_PING
|
|
||||||
|| pdu->code == COAP_SIGNALING_PONG) {
|
|
||||||
buf_len = 0;
|
|
||||||
} else if (pdu->code == COAP_SIGNALING_RELEASE) switch(opt_iter.type) {
|
|
||||||
case COAP_SIGNALING_OPTION_ALTERNATIVE_ADDRESS:
|
|
||||||
buf_len = print_readable(coap_opt_value(option),
|
|
||||||
coap_opt_length(option),
|
|
||||||
buf, sizeof(buf), 0);
|
|
||||||
break;
|
|
||||||
case COAP_SIGNALING_OPTION_HOLD_OFF:
|
|
||||||
buf_len = snprintf((char *)buf, sizeof(buf), "%u",
|
|
||||||
coap_decode_var_bytes(coap_opt_value(option),
|
|
||||||
coap_opt_length(option)));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buf_len = 0;
|
|
||||||
break;
|
|
||||||
} else if (pdu->code == COAP_SIGNALING_ABORT) switch(opt_iter.type) {
|
|
||||||
case COAP_SIGNALING_OPTION_BAD_CSM_OPTION:
|
|
||||||
buf_len = snprintf((char *)buf, sizeof(buf), "%u",
|
|
||||||
coap_decode_var_bytes(coap_opt_value(option),
|
|
||||||
coap_opt_length(option)));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buf_len = 0;
|
|
||||||
break;
|
|
||||||
} else switch (opt_iter.type) {
|
|
||||||
case COAP_OPTION_CONTENT_FORMAT:
|
|
||||||
content_format = (int)coap_decode_var_bytes(coap_opt_value(option),
|
|
||||||
coap_opt_length(option));
|
|
||||||
|
|
||||||
buf_len = print_content_format(content_format, buf, sizeof(buf));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COAP_OPTION_BLOCK1:
|
|
||||||
case COAP_OPTION_BLOCK2:
|
|
||||||
/* split block option into number/more/size where more is the
|
|
||||||
* letter M if set, the _ otherwise */
|
|
||||||
buf_len = snprintf((char *)buf, sizeof(buf), "%u/%c/%u",
|
|
||||||
coap_opt_block_num(option), /* block number */
|
|
||||||
COAP_OPT_BLOCK_MORE(option) ? 'M' : '_', /* M bit */
|
|
||||||
(1 << (COAP_OPT_BLOCK_SZX(option) + 4))); /* block size */
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COAP_OPTION_URI_PORT:
|
|
||||||
case COAP_OPTION_MAXAGE:
|
|
||||||
case COAP_OPTION_OBSERVE:
|
|
||||||
case COAP_OPTION_SIZE1:
|
|
||||||
case COAP_OPTION_SIZE2:
|
|
||||||
/* show values as unsigned decimal value */
|
|
||||||
buf_len = snprintf((char *)buf, sizeof(buf), "%u",
|
|
||||||
coap_decode_var_bytes(coap_opt_value(option),
|
|
||||||
coap_opt_length(option)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* generic output function for all other option types */
|
|
||||||
if (opt_iter.type == COAP_OPTION_URI_PATH ||
|
|
||||||
opt_iter.type == COAP_OPTION_PROXY_URI ||
|
|
||||||
opt_iter.type == COAP_OPTION_URI_HOST ||
|
|
||||||
opt_iter.type == COAP_OPTION_LOCATION_PATH ||
|
|
||||||
opt_iter.type == COAP_OPTION_LOCATION_QUERY ||
|
|
||||||
opt_iter.type == COAP_OPTION_URI_QUERY) {
|
|
||||||
encode = 0;
|
|
||||||
} else {
|
|
||||||
encode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf_len = print_readable(coap_opt_value(option),
|
|
||||||
coap_opt_length(option),
|
|
||||||
buf, sizeof(buf), encode);
|
|
||||||
}
|
|
||||||
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
|
|
||||||
" %s:%.*s", msg_option_string(pdu->code, opt_iter.type),
|
|
||||||
(int)buf_len, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " ]");
|
|
||||||
|
|
||||||
if (coap_get_data(pdu, &data_len, &data)) {
|
|
||||||
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, " :: ");
|
|
||||||
|
|
||||||
if (is_binary(content_format)) {
|
|
||||||
int keep_data_len = data_len;
|
|
||||||
uint8_t *keep_data = data;
|
|
||||||
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
|
|
||||||
"binary data length %zu\n", data_len);
|
|
||||||
COAP_DO_SHOW_OUTPUT_LINE;
|
|
||||||
/*
|
|
||||||
* Output hex dump of binary data as a continuous entry
|
|
||||||
*/
|
|
||||||
outbuf[0] = '\000';
|
|
||||||
snprintf(outbuf, sizeof(outbuf), "<<");
|
|
||||||
while (data_len--) {
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
|
|
||||||
"%02x", *data++);
|
|
||||||
}
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
|
|
||||||
data_len = keep_data_len;
|
|
||||||
data = keep_data;
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
|
|
||||||
COAP_DO_SHOW_OUTPUT_LINE;
|
|
||||||
/*
|
|
||||||
* Output ascii readable (if possible), immediately under the
|
|
||||||
* hex value of the character output above to help binary debugging
|
|
||||||
*/
|
|
||||||
outbuf[0] = '\000';
|
|
||||||
snprintf(outbuf, sizeof(outbuf), "<<");
|
|
||||||
while (data_len--) {
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen,
|
|
||||||
"%c ", isprint (*data) ? *data : '.');
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, ">>");
|
|
||||||
} else {
|
|
||||||
if (print_readable(data, data_len, buf, sizeof(buf), 0)) {
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "'%s'", buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outbuflen = strlen(outbuf);
|
|
||||||
snprintf(&outbuf[outbuflen], sizeof(outbuf)-outbuflen, "\n");
|
|
||||||
COAP_DO_SHOW_OUTPUT_LINE;
|
|
||||||
|
|
||||||
#if COAP_CONSTRAINED_STACK
|
|
||||||
coap_mutex_unlock(&static_show_pdu_mutex);
|
|
||||||
#endif /* COAP_CONSTRAINED_STACK */
|
|
||||||
}
|
|
||||||
|
|
||||||
void coap_show_tls_version(coap_log_t level)
|
|
||||||
{
|
|
||||||
char buffer[64];
|
|
||||||
coap_string_tls_version(buffer, sizeof(buffer));
|
|
||||||
coap_log(level, "%s\n", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *coap_string_tls_version(char *buffer, size_t bufsize)
|
|
||||||
{
|
|
||||||
coap_tls_version_t *tls_version = coap_get_tls_library_version();
|
|
||||||
char beta[8];
|
|
||||||
char sub[2];
|
|
||||||
char b_beta[8];
|
|
||||||
char b_sub[2];
|
|
||||||
|
|
||||||
switch (tls_version->type) {
|
|
||||||
case COAP_TLS_LIBRARY_NOTLS:
|
|
||||||
snprintf(buffer, bufsize, "TLS Library: None");
|
|
||||||
break;
|
|
||||||
case COAP_TLS_LIBRARY_TINYDTLS:
|
|
||||||
snprintf(buffer, bufsize, "TLS Library: TinyDTLS - runtime %lu.%lu.%lu, "
|
|
||||||
"libcoap built for %lu.%lu.%lu",
|
|
||||||
(unsigned long)(tls_version->version >> 16),
|
|
||||||
(unsigned long)((tls_version->version >> 8) & 0xff),
|
|
||||||
(unsigned long)(tls_version->version & 0xff),
|
|
||||||
(unsigned long)(tls_version->built_version >> 16),
|
|
||||||
(unsigned long)((tls_version->built_version >> 8) & 0xff),
|
|
||||||
(unsigned long)(tls_version->built_version & 0xff));
|
|
||||||
break;
|
|
||||||
case COAP_TLS_LIBRARY_OPENSSL:
|
|
||||||
switch (tls_version->version &0xf) {
|
|
||||||
case 0:
|
|
||||||
strcpy(beta, "-dev");
|
|
||||||
break;
|
|
||||||
case 0xf:
|
|
||||||
strcpy(beta, "");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
strcpy(beta, "-beta");
|
|
||||||
beta[5] = (tls_version->version &0xf) + '0';
|
|
||||||
beta[6] = '\000';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sub[0] = ((tls_version->version >> 4) & 0xff) ?
|
|
||||||
((tls_version->version >> 4) & 0xff) + 'a' -1 : '\000';
|
|
||||||
sub[1] = '\000';
|
|
||||||
switch (tls_version->built_version &0xf) {
|
|
||||||
case 0:
|
|
||||||
strcpy(b_beta, "-dev");
|
|
||||||
break;
|
|
||||||
case 0xf:
|
|
||||||
strcpy(b_beta, "");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
strcpy(b_beta, "-beta");
|
|
||||||
b_beta[5] = (tls_version->built_version &0xf) + '0';
|
|
||||||
b_beta[6] = '\000';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
b_sub[0] = ((tls_version->built_version >> 4) & 0xff) ?
|
|
||||||
((tls_version->built_version >> 4) & 0xff) + 'a' -1 : '\000';
|
|
||||||
b_sub[1] = '\000';
|
|
||||||
snprintf(buffer, bufsize, "TLS Library: OpenSSL - runtime "
|
|
||||||
"%lu.%lu.%lu%s%s, libcoap built for %lu.%lu.%lu%s%s",
|
|
||||||
(unsigned long)(tls_version->version >> 28),
|
|
||||||
(unsigned long)((tls_version->version >> 20) & 0xff),
|
|
||||||
(unsigned long)((tls_version->version >> 12) & 0xff), sub, beta,
|
|
||||||
(unsigned long)(tls_version->built_version >> 28),
|
|
||||||
(unsigned long)((tls_version->built_version >> 20) & 0xff),
|
|
||||||
(unsigned long)((tls_version->built_version >> 12) & 0xff),
|
|
||||||
b_sub, b_beta);
|
|
||||||
break;
|
|
||||||
case COAP_TLS_LIBRARY_GNUTLS:
|
|
||||||
snprintf(buffer, bufsize, "TLS Library: GnuTLS - runtime %lu.%lu.%lu, "
|
|
||||||
"libcoap built for %lu.%lu.%lu",
|
|
||||||
(unsigned long)(tls_version->version >> 16),
|
|
||||||
(unsigned long)((tls_version->version >> 8) & 0xff),
|
|
||||||
(unsigned long)(tls_version->version & 0xff),
|
|
||||||
(unsigned long)(tls_version->built_version >> 16),
|
|
||||||
(unsigned long)((tls_version->built_version >> 8) & 0xff),
|
|
||||||
(unsigned long)(tls_version->built_version & 0xff));
|
|
||||||
break;
|
|
||||||
case COAP_TLS_LIBRARY_MBEDTLS:
|
|
||||||
snprintf(buffer, bufsize, "TLS Library: MbedTLS - runtime %lu.%lu.%lu, "
|
|
||||||
"libcoap built for %lu.%lu.%lu",
|
|
||||||
(unsigned long)(tls_version->version >> 24),
|
|
||||||
(unsigned long)((tls_version->version >> 16) & 0xff),
|
|
||||||
(unsigned long)((tls_version->version >> 8) & 0xff),
|
|
||||||
(unsigned long)(tls_version->built_version >> 24),
|
|
||||||
(unsigned long)((tls_version->built_version >> 16) & 0xff),
|
|
||||||
(unsigned long)((tls_version->built_version >> 8) & 0xff));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
snprintf(buffer, bufsize, "Library type %d unknown", tls_version->type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static coap_log_handler_t log_handler = NULL;
|
|
||||||
|
|
||||||
void coap_set_log_handler(coap_log_handler_t handler) {
|
|
||||||
log_handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coap_log_impl(coap_log_t level, const char *format, ...) {
|
|
||||||
|
|
||||||
if (maxlog < level)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (log_handler) {
|
|
||||||
#if COAP_CONSTRAINED_STACK
|
|
||||||
static coap_mutex_t static_log_mutex = COAP_MUTEX_INITIALIZER;
|
|
||||||
static char message[COAP_DEBUG_BUF_SIZE];
|
|
||||||
#else /* ! COAP_CONSTRAINED_STACK */
|
|
||||||
char message[COAP_DEBUG_BUF_SIZE];
|
|
||||||
#endif /* ! COAP_CONSTRAINED_STACK */
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
#if COAP_CONSTRAINED_STACK
|
|
||||||
coap_mutex_lock(&static_log_mutex);
|
|
||||||
#endif /* COAP_CONSTRAINED_STACK */
|
|
||||||
|
|
||||||
vsnprintf( message, sizeof(message), format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
log_handler(level, message);
|
|
||||||
#if COAP_CONSTRAINED_STACK
|
|
||||||
coap_mutex_unlock(&static_log_mutex);
|
|
||||||
#endif /* COAP_CONSTRAINED_STACK */
|
|
||||||
} else {
|
|
||||||
char timebuf[32];
|
|
||||||
coap_tick_t now;
|
|
||||||
va_list ap;
|
|
||||||
FILE *log_fd;
|
|
||||||
|
|
||||||
log_fd = level <= LOG_CRIT ? COAP_ERR_FD : COAP_DEBUG_FD;
|
|
||||||
|
|
||||||
coap_ticks(&now);
|
|
||||||
if (print_timestamp(timebuf,sizeof(timebuf), now))
|
|
||||||
fprintf(log_fd, "%s ", timebuf);
|
|
||||||
|
|
||||||
if (level <= LOG_DEBUG)
|
|
||||||
fprintf(log_fd, "%s ", loglevels[level]);
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
vfprintf(log_fd, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
fflush(log_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct packet_num_interval {
|
|
||||||
int start;
|
|
||||||
int end;
|
|
||||||
} packet_loss_intervals[10];
|
|
||||||
static int num_packet_loss_intervals = 0;
|
|
||||||
static int packet_loss_level = 0;
|
|
||||||
static int send_packet_count = 0;
|
|
||||||
|
|
||||||
int coap_debug_set_packet_loss(const char *loss_level) {
|
|
||||||
const char *p = loss_level;
|
|
||||||
char *end = NULL;
|
|
||||||
int n = (int)strtol(p, &end, 10), i = 0;
|
|
||||||
if (end == p || n < 0)
|
|
||||||
return 0;
|
|
||||||
if (*end == '%') {
|
|
||||||
if (n > 100)
|
|
||||||
n = 100;
|
|
||||||
packet_loss_level = n * 65536 / 100;
|
|
||||||
coap_log(LOG_DEBUG, "packet loss level set to %d%%\n", n);
|
|
||||||
} else {
|
|
||||||
if (n <= 0)
|
|
||||||
return 0;
|
|
||||||
while (i < 10) {
|
|
||||||
packet_loss_intervals[i].start = n;
|
|
||||||
if (*end == '-') {
|
|
||||||
p = end + 1;
|
|
||||||
n = (int)strtol(p, &end, 10);
|
|
||||||
if (end == p || n <= 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
packet_loss_intervals[i++].end = n;
|
|
||||||
if (*end == 0)
|
|
||||||
break;
|
|
||||||
if (*end != ',')
|
|
||||||
return 0;
|
|
||||||
p = end + 1;
|
|
||||||
n = (int)strtol(p, &end, 10);
|
|
||||||
if (end == p || n <= 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (i == 10)
|
|
||||||
return 0;
|
|
||||||
num_packet_loss_intervals = i;
|
|
||||||
}
|
|
||||||
send_packet_count = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int coap_debug_send_packet(void) {
|
|
||||||
++send_packet_count;
|
|
||||||
if (num_packet_loss_intervals > 0) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < num_packet_loss_intervals; i++) {
|
|
||||||
if (send_packet_count >= packet_loss_intervals[i].start
|
|
||||||
&& send_packet_count <= packet_loss_intervals[i].end)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( packet_loss_level > 0 ) {
|
|
||||||
uint16_t r = 0;
|
|
||||||
prng( (uint8_t*)&r, 2 );
|
|
||||||
if ( r < packet_loss_level )
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
* coap_notls.c -- Stub Datagram Transport Layer Support for libcoap
|
|
||||||
*
|
|
||||||
* Copyright (C) 2016 Olaf Bergmann <bergmann@tzi.org>
|
|
||||||
*
|
|
||||||
* This file is part of the CoAP library libcoap. Please see README for terms
|
|
||||||
* of use.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "coap_config.h"
|
|
||||||
|
|
||||||
#if !defined(HAVE_LIBTINYDTLS) && !defined(HAVE_OPENSSL) && !defined(HAVE_LIBGNUTLS) && !defined(HAVE_MBEDTLS)
|
|
||||||
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define UNUSED __attribute__((unused))
|
|
||||||
#else /* __GNUC__ */
|
|
||||||
#define UNUSED
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_is_supported(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_tls_is_supported(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
coap_tls_version_t *
|
|
||||||
coap_get_tls_library_version(void) {
|
|
||||||
static coap_tls_version_t version;
|
|
||||||
version.version = 0;
|
|
||||||
version.type = COAP_TLS_LIBRARY_NOTLS;
|
|
||||||
return &version;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_set_pki(coap_context_t *ctx UNUSED,
|
|
||||||
coap_dtls_pki_t* setup_data UNUSED,
|
|
||||||
coap_dtls_role_t role UNUSED
|
|
||||||
) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_set_pki_root_cas(struct coap_context_t *ctx UNUSED,
|
|
||||||
const char *ca_file UNUSED,
|
|
||||||
const char *ca_path UNUSED
|
|
||||||
) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_set_psk(coap_context_t *ctx UNUSED,
|
|
||||||
const char *hint UNUSED,
|
|
||||||
coap_dtls_role_t role UNUSED
|
|
||||||
) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dtls_log_level = 0;
|
|
||||||
|
|
||||||
void coap_dtls_startup(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coap_dtls_set_log_level(int level) {
|
|
||||||
dtls_log_level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_get_log_level(void) {
|
|
||||||
return dtls_log_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
coap_dtls_new_context(struct coap_context_t *coap_context UNUSED) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
coap_dtls_free_context(void *handle UNUSED) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void *coap_dtls_new_server_session(coap_session_t *session UNUSED) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *coap_dtls_new_client_session(coap_session_t *session UNUSED) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coap_dtls_free_session(coap_session_t *coap_session UNUSED) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void coap_dtls_session_update_mtu(coap_session_t *session UNUSED) {
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_send(coap_session_t *session UNUSED,
|
|
||||||
const uint8_t *data UNUSED,
|
|
||||||
size_t data_len UNUSED
|
|
||||||
) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int coap_dtls_is_context_timeout(void) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context UNUSED) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
coap_tick_t
|
|
||||||
coap_dtls_get_timeout(coap_session_t *session UNUSED, coap_tick_t now UNUSED) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coap_dtls_handle_timeout(coap_session_t *session UNUSED) {
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_receive(coap_session_t *session UNUSED,
|
|
||||||
const uint8_t *data UNUSED,
|
|
||||||
size_t data_len UNUSED
|
|
||||||
) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_hello(coap_session_t *session UNUSED,
|
|
||||||
const uint8_t *data UNUSED,
|
|
||||||
size_t data_len UNUSED
|
|
||||||
) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coap_tls_free_session(coap_session_t *coap_session UNUSED) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t coap_tls_write(coap_session_t *session UNUSED,
|
|
||||||
const uint8_t *data UNUSED,
|
|
||||||
size_t data_len UNUSED
|
|
||||||
) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t coap_tls_read(coap_session_t *session UNUSED,
|
|
||||||
uint8_t *data UNUSED,
|
|
||||||
size_t data_len UNUSED
|
|
||||||
) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef UNUSED
|
|
||||||
|
|
||||||
#else /* !HAVE_LIBTINYDTLS && !HAVE_OPENSSL && !HAVE_LIBGNUTLS */
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
/* Make compilers happy that do not like empty modules. As this function is
|
|
||||||
* never used, we ignore -Wunused-function at the end of compiling this file
|
|
||||||
*/
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
|
||||||
#endif
|
|
||||||
static inline void dummy(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !HAVE_LIBTINYDTLS && !HAVE_OPENSSL && !HAVE_LIBGNUTLS */
|
|
@ -1,631 +0,0 @@
|
|||||||
/*
|
|
||||||
* coap_dtls.h -- (Datagram) Transport Layer Support for libcoap
|
|
||||||
*
|
|
||||||
* Copyright (C) 2016 Olaf Bergmann <bergmann@tzi.org>
|
|
||||||
* Copyright (C) 2017 Jean-Claude Michelou <jcm@spinetix.com>
|
|
||||||
*
|
|
||||||
* This file is part of the CoAP library libcoap. Please see README for terms
|
|
||||||
* of use.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COAP_DTLS_H_
|
|
||||||
#define COAP_DTLS_H_
|
|
||||||
|
|
||||||
#include "coap_time.h"
|
|
||||||
#include "str.h"
|
|
||||||
|
|
||||||
struct coap_context_t;
|
|
||||||
struct coap_session_t;
|
|
||||||
struct coap_dtls_pki_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dtls DTLS Support
|
|
||||||
* API functions for interfacing with DTLS libraries.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether DTLS is available.
|
|
||||||
*
|
|
||||||
* @return @c 1 if support for DTLS is enabled, or @c 0 otherwise.
|
|
||||||
*/
|
|
||||||
int coap_dtls_is_supported(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether TLS is available.
|
|
||||||
*
|
|
||||||
* @return @c 1 if support for TLS is enabled, or @c 0 otherwise.
|
|
||||||
*/
|
|
||||||
int coap_tls_is_supported(void);
|
|
||||||
|
|
||||||
typedef enum coap_tls_library_t {
|
|
||||||
COAP_TLS_LIBRARY_NOTLS = 0, /**< No DTLS library */
|
|
||||||
COAP_TLS_LIBRARY_TINYDTLS, /**< Using TinyDTLS library */
|
|
||||||
COAP_TLS_LIBRARY_OPENSSL, /**< Using OpenSSL library */
|
|
||||||
COAP_TLS_LIBRARY_GNUTLS, /**< Using GnuTLS library */
|
|
||||||
COAP_TLS_LIBRARY_MBEDTLS, /**< Using MbedTLS library */
|
|
||||||
} coap_tls_library_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The structure used for returning the underlying (D)TLS library
|
|
||||||
* information.
|
|
||||||
*/
|
|
||||||
typedef struct coap_tls_version_t {
|
|
||||||
uint64_t version; /**< (D)TLS runtime Library Version */
|
|
||||||
coap_tls_library_t type; /**< Library type. One of COAP_TLS_LIBRARY_* */
|
|
||||||
uint64_t built_version; /**< (D)TLS Built against Library Version */
|
|
||||||
} coap_tls_version_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine the type and version of the underlying (D)TLS library.
|
|
||||||
*
|
|
||||||
* @return The version and type of library libcoap was compiled against.
|
|
||||||
*/
|
|
||||||
coap_tls_version_t *coap_get_tls_library_version(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Additional Security setup handler that can be set up by
|
|
||||||
* coap_context_set_pki().
|
|
||||||
* Invoked when libcoap has done the validation checks at the TLS level,
|
|
||||||
* but the application needs to do some additional checks/changes/updates.
|
|
||||||
*
|
|
||||||
* @param tls_session The security session definition - e.g. SSL * for OpenSSL.
|
|
||||||
* NULL if server call-back.
|
|
||||||
* This will be dependent on the underlying TLS library -
|
|
||||||
* see coap_get_tls_library_version()
|
|
||||||
* @param setup_data A structure containing setup data originally passed into
|
|
||||||
* coap_context_set_pki() or coap_new_client_session_pki().
|
|
||||||
*
|
|
||||||
* @return @c 1 if successful, else @c 0.
|
|
||||||
*/
|
|
||||||
typedef int (*coap_dtls_security_setup_t)(void* tls_session,
|
|
||||||
struct coap_dtls_pki_t *setup_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CN Validation call-back that can be set up by coap_context_set_pki().
|
|
||||||
* Invoked when libcoap has done the validation checks at the TLS level,
|
|
||||||
* but the application needs to check that the CN is allowed.
|
|
||||||
* CN is the SubjectAltName in the cert, if not present, then the leftmost
|
|
||||||
* Common Name (CN) component of the subject name.
|
|
||||||
*
|
|
||||||
* @param cn The determined CN from the certificate
|
|
||||||
* @param asn1_public_cert The ASN.1 DER encoded X.509 certificate
|
|
||||||
* @param asn1_length The ASN.1 length
|
|
||||||
* @param coap_session The CoAP session associated with the certificate update
|
|
||||||
* @param depth Depth in cert chain. If 0, then client cert, else a CA
|
|
||||||
* @param validated TLS layer can find no issues if 1
|
|
||||||
* @param arg The same as was passed into coap_context_set_pki()
|
|
||||||
* in setup_data->cn_call_back_arg
|
|
||||||
*
|
|
||||||
* @return @c 1 if accepted, else @c 0 if to be rejected.
|
|
||||||
*/
|
|
||||||
typedef int (*coap_dtls_cn_callback_t)(const char *cn,
|
|
||||||
const uint8_t *asn1_public_cert,
|
|
||||||
size_t asn1_length,
|
|
||||||
struct coap_session_t *coap_session,
|
|
||||||
unsigned depth,
|
|
||||||
int validated,
|
|
||||||
void *arg);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The enum used for determining the provided PKI ASN.1 (DER) Private Key
|
|
||||||
* formats.
|
|
||||||
*/
|
|
||||||
typedef enum coap_asn1_privatekey_type_t {
|
|
||||||
COAP_ASN1_PKEY_NONE, /**< NONE */
|
|
||||||
COAP_ASN1_PKEY_RSA, /**< RSA type */
|
|
||||||
COAP_ASN1_PKEY_RSA2, /**< RSA2 type */
|
|
||||||
COAP_ASN1_PKEY_DSA, /**< DSA type */
|
|
||||||
COAP_ASN1_PKEY_DSA1, /**< DSA1 type */
|
|
||||||
COAP_ASN1_PKEY_DSA2, /**< DSA2 type */
|
|
||||||
COAP_ASN1_PKEY_DSA3, /**< DSA3 type */
|
|
||||||
COAP_ASN1_PKEY_DSA4, /**< DSA4 type */
|
|
||||||
COAP_ASN1_PKEY_DH, /**< DH type */
|
|
||||||
COAP_ASN1_PKEY_DHX, /**< DHX type */
|
|
||||||
COAP_ASN1_PKEY_EC, /**< EC type */
|
|
||||||
COAP_ASN1_PKEY_HMAC, /**< HMAC type */
|
|
||||||
COAP_ASN1_PKEY_CMAC, /**< CMAC type */
|
|
||||||
COAP_ASN1_PKEY_TLS1_PRF, /**< TLS1_PRF type */
|
|
||||||
COAP_ASN1_PKEY_HKDF /**< HKDF type */
|
|
||||||
} coap_asn1_privatekey_type_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The enum used for determining the PKI key formats.
|
|
||||||
*/
|
|
||||||
typedef enum coap_pki_key_t {
|
|
||||||
COAP_PKI_KEY_PEM = 0, /**< The PKI key type is PEM file */
|
|
||||||
COAP_PKI_KEY_ASN1, /**< The PKI key type is ASN.1 (DER) */
|
|
||||||
COAP_PKI_KEY_PEM_BUF, /**< The PKI key type is PEM buffer */
|
|
||||||
} coap_pki_key_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The structure that holds the PKI PEM definitions.
|
|
||||||
*/
|
|
||||||
typedef struct coap_pki_key_pem_t {
|
|
||||||
const char *ca_file; /**< File location of Common CA in PEM format */
|
|
||||||
const char *public_cert; /**< File location of Public Cert in PEM format */
|
|
||||||
const char *private_key; /**< File location of Private Key in PEM format */
|
|
||||||
} coap_pki_key_pem_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The structure that holds the PKI PEM buffer definitions.
|
|
||||||
*/
|
|
||||||
typedef struct coap_pki_key_pem_buf_t {
|
|
||||||
const uint8_t *ca_cert; /**< PEM buffer Common CA Cert */
|
|
||||||
const uint8_t *public_cert; /**< PEM buffer Public Cert */
|
|
||||||
const uint8_t *private_key; /**< PEM buffer Private Key */
|
|
||||||
size_t ca_cert_len; /**< PEM buffer CA Cert length */
|
|
||||||
size_t public_cert_len; /**< PEM buffer Public Cert length */
|
|
||||||
size_t private_key_len; /**< PEM buffer Private Key length */
|
|
||||||
} coap_pki_key_pem_buf_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The structure that holds the PKI ASN.1 (DER) definitions.
|
|
||||||
*/
|
|
||||||
typedef struct coap_pki_key_asn1_t {
|
|
||||||
const uint8_t *ca_cert; /**< ASN1 (DER) Common CA Cert */
|
|
||||||
const uint8_t *public_cert; /**< ASN1 (DER) Public Cert */
|
|
||||||
const uint8_t *private_key; /**< ASN1 (DER) Private Key */
|
|
||||||
size_t ca_cert_len; /**< ASN1 CA Cert length */
|
|
||||||
size_t public_cert_len; /**< ASN1 Public Cert length */
|
|
||||||
size_t private_key_len; /**< ASN1 Private Key length */
|
|
||||||
coap_asn1_privatekey_type_t private_key_type; /**< Private Key Type */
|
|
||||||
} coap_pki_key_asn1_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The structure that holds the PKI key information.
|
|
||||||
*/
|
|
||||||
typedef struct coap_dtls_key_t {
|
|
||||||
coap_pki_key_t key_type; /**< key format type */
|
|
||||||
union {
|
|
||||||
coap_pki_key_pem_t pem; /**< for PEM file keys */
|
|
||||||
coap_pki_key_pem_buf_t pem_buf; /**< for PEM memory keys */
|
|
||||||
coap_pki_key_asn1_t asn1; /**< for ASN.1 (DER) file keys */
|
|
||||||
} key;
|
|
||||||
} coap_dtls_key_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server Name Indication (SNI) Validation call-back that can be set up by
|
|
||||||
* coap_context_set_pki().
|
|
||||||
* Invoked if the SNI is not previously seen and prior to sending a certificate
|
|
||||||
* set back to the client so that the appropriate certificate set can be used
|
|
||||||
* based on the requesting SNI.
|
|
||||||
*
|
|
||||||
* @param sni The requested SNI
|
|
||||||
* @param arg The same as was passed into coap_context_set_pki()
|
|
||||||
* in setup_data->sni_call_back_arg
|
|
||||||
*
|
|
||||||
* @return New set of certificates to use, or @c NULL if SNI is to be rejected.
|
|
||||||
*/
|
|
||||||
typedef coap_dtls_key_t *(*coap_dtls_sni_callback_t)(const char *sni,
|
|
||||||
void* arg);
|
|
||||||
|
|
||||||
|
|
||||||
#define COAP_DTLS_PKI_SETUP_VERSION 1 /**< Latest PKI setup version */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The structure used for defining the PKI setup data to be used.
|
|
||||||
*/
|
|
||||||
typedef struct coap_dtls_pki_t {
|
|
||||||
uint8_t version; /** Set to 1 to support this version of the struct */
|
|
||||||
|
|
||||||
/* Options to enable different TLS functionality in libcoap */
|
|
||||||
uint8_t verify_peer_cert; /**< 1 if peer cert is to be verified */
|
|
||||||
uint8_t require_peer_cert; /**< 1 if peer cert is required */
|
|
||||||
uint8_t allow_self_signed; /**< 1 if self signed certs are allowed */
|
|
||||||
uint8_t allow_expired_certs; /**< 1 if expired certs are allowed */
|
|
||||||
uint8_t cert_chain_validation; /**< 1 if to check cert_chain_verify_depth */
|
|
||||||
uint8_t cert_chain_verify_depth; /**< recommended depth is 3 */
|
|
||||||
uint8_t check_cert_revocation; /**< 1 if revocation checks wanted */
|
|
||||||
uint8_t allow_no_crl; /**< 1 ignore if CRL not there */
|
|
||||||
uint8_t allow_expired_crl; /**< 1 if expired crl is allowed */
|
|
||||||
uint8_t allow_bad_md_hash; /**< 1 if expired certs are allowed */
|
|
||||||
uint8_t allow_short_rsa_length; /**< 1 if expired certs are allowed */
|
|
||||||
uint8_t reserved[4]; /**< Reserved - must be set to 0 for
|
|
||||||
future compatibility */
|
|
||||||
/* Size of 4 chosen to align to next
|
|
||||||
* parameter, so if newly defined option
|
|
||||||
* it can use one of the reserverd slot so
|
|
||||||
* no need to change
|
|
||||||
* COAP_DTLS_PKI_SETUP_VERSION and just
|
|
||||||
* decrement the reserved[] count.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** CN check call-back function.
|
|
||||||
* If not NULL, is called when the TLS connection has passed the configured
|
|
||||||
* TLS options above for the application to verify if the CN is valid.
|
|
||||||
*/
|
|
||||||
coap_dtls_cn_callback_t validate_cn_call_back;
|
|
||||||
void *cn_call_back_arg; /**< Passed in to the CN call-back function */
|
|
||||||
|
|
||||||
/** SNI check call-back function.
|
|
||||||
* If not @p NULL, called if the SNI is not previously seen and prior to
|
|
||||||
* sending a certificate set back to the client so that the appropriate
|
|
||||||
* certificate set can be used based on the requesting SNI.
|
|
||||||
*/
|
|
||||||
coap_dtls_sni_callback_t validate_sni_call_back;
|
|
||||||
void *sni_call_back_arg; /**< Passed in to the sni call-back function */
|
|
||||||
|
|
||||||
/** Additional Security call-back handler that is invoked when libcoap has
|
|
||||||
* done the standerd, defined validation checks at the TLS level,
|
|
||||||
* If not @p NULL, called from within the TLS Client Hello connection
|
|
||||||
* setup.
|
|
||||||
*/
|
|
||||||
coap_dtls_security_setup_t additional_tls_setup_call_back;
|
|
||||||
|
|
||||||
char* client_sni; /**< If not NULL, SNI to use in client TLS setup.
|
|
||||||
Owned by the client app and must remain valid
|
|
||||||
during the call to coap_new_client_session_pki() */
|
|
||||||
|
|
||||||
coap_dtls_key_t pki_key; /**< PKI key definition */
|
|
||||||
} coap_dtls_pki_t;
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dtls_internal DTLS Support (Internal)
|
|
||||||
* Internal API functions for interfacing with DTLS libraries.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new DTLS context for the given @p coap_context. This function
|
|
||||||
* returns a pointer to a new DTLS context object or @c NULL on error.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_context The CoAP context where the DTLS object shall be used.
|
|
||||||
*
|
|
||||||
* @return A DTLS context object or @c NULL on error.
|
|
||||||
*/
|
|
||||||
void *
|
|
||||||
coap_dtls_new_context(struct coap_context_t *coap_context);
|
|
||||||
|
|
||||||
typedef enum coap_dtls_role_t {
|
|
||||||
COAP_DTLS_ROLE_CLIENT, /**< Internal function invoked for client */
|
|
||||||
COAP_DTLS_ROLE_SERVER /**< Internal function invoked for server */
|
|
||||||
} coap_dtls_role_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the DTLS context's default PSK information.
|
|
||||||
* This does the PSK specifics following coap_dtls_new_context().
|
|
||||||
* If @p COAP_DTLS_ROLE_SERVER, then identity hint will also get set.
|
|
||||||
* If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the
|
|
||||||
* TLS library's context (from which sessions are derived).
|
|
||||||
* If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the
|
|
||||||
* TLS library's session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_context The CoAP context.
|
|
||||||
* @param identity_hint The default PSK server identity hint sent to a client.
|
|
||||||
* Required parameter. If @p NULL, will be set to "".
|
|
||||||
* Empty string is a valid hint.
|
|
||||||
* This parameter is ignored if COAP_DTLS_ROLE_CLIENT
|
|
||||||
* @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER
|
|
||||||
*
|
|
||||||
* @return @c 1 if successful, else @c 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_set_psk(struct coap_context_t *coap_context,
|
|
||||||
const char *identity_hint,
|
|
||||||
coap_dtls_role_t role);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the DTLS context's default server PKI information.
|
|
||||||
* This does the PKI specifics following coap_dtls_new_context().
|
|
||||||
* If @p COAP_DTLS_ROLE_SERVER, then the information will get put into the
|
|
||||||
* TLS library's context (from which sessions are derived).
|
|
||||||
* If @p COAP_DTLS_ROLE_CLIENT, then the information will get put into the
|
|
||||||
* TLS library's session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_context The CoAP context.
|
|
||||||
* @param setup_data Setup information defining how PKI is to be setup.
|
|
||||||
* Required parameter. If @p NULL, PKI will not be
|
|
||||||
* set up.
|
|
||||||
* @param role One of @p COAP_DTLS_ROLE_CLIENT or @p COAP_DTLS_ROLE_SERVER
|
|
||||||
*
|
|
||||||
* @return @c 1 if successful, else @c 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_set_pki(struct coap_context_t *coap_context,
|
|
||||||
coap_dtls_pki_t *setup_data,
|
|
||||||
coap_dtls_role_t role);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the dtls context's default Root CA information for a client or server.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_context The current coap_context_t object.
|
|
||||||
* @param ca_file If not @p NULL, is the full path name of a PEM encoded
|
|
||||||
* file containing all the Root CAs to be used.
|
|
||||||
* @param ca_dir If not @p NULL, points to a directory containing PEM
|
|
||||||
* encoded files containing all the Root CAs to be used.
|
|
||||||
*
|
|
||||||
* @return @c 1 if successful, else @c 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
coap_dtls_context_set_pki_root_cas(struct coap_context_t *coap_context,
|
|
||||||
const char *ca_file,
|
|
||||||
const char *ca_dir);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether one of the coap_dtls_context_set_{psk|pki}() functions have
|
|
||||||
* been called.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_context The current coap_context_t object.
|
|
||||||
*
|
|
||||||
* @return @c 1 if coap_dtls_context_set_{psk|pki}() called, else @c 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int coap_dtls_context_check_keys_enabled(struct coap_context_t *coap_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Releases the storage allocated for @p dtls_context.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param dtls_context The DTLS context as returned by coap_dtls_new_context().
|
|
||||||
*/
|
|
||||||
void coap_dtls_free_context(void *dtls_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new client-side session. This should send a HELLO to the server.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*
|
|
||||||
* @return Opaque handle to underlying TLS library object containing security
|
|
||||||
* parameters for the session.
|
|
||||||
*/
|
|
||||||
void *coap_dtls_new_client_session(struct coap_session_t *coap_session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new DTLS server-side session.
|
|
||||||
* Called after coap_dtls_hello() has returned @c 1, signalling that a validated
|
|
||||||
* HELLO was received from a client.
|
|
||||||
* This should send a HELLO to the server.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*
|
|
||||||
* @return Opaque handle to underlying TLS library object containing security
|
|
||||||
* parameters for the DTLS session.
|
|
||||||
*/
|
|
||||||
void *coap_dtls_new_server_session(struct coap_session_t *coap_session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Terminates the DTLS session (may send an ALERT if necessary) then frees the
|
|
||||||
* underlying TLS library object containing security parameters for the session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*/
|
|
||||||
void coap_dtls_free_session(struct coap_session_t *coap_session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify of a change in the CoAP session's MTU, for example after
|
|
||||||
* a PMTU update.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*/
|
|
||||||
void coap_dtls_session_update_mtu(struct coap_session_t *coap_session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to a DTLS peer.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param data pointer to data.
|
|
||||||
* @param data_len Number of bytes to send.
|
|
||||||
*
|
|
||||||
* @return @c 0 if this would be blocking, @c -1 if there is an error or the
|
|
||||||
* number of cleartext bytes sent.
|
|
||||||
*/
|
|
||||||
int coap_dtls_send(struct coap_session_t *coap_session,
|
|
||||||
const uint8_t *data,
|
|
||||||
size_t data_len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if timeout is handled per CoAP session or per CoAP context.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @return @c 1 of timeout and retransmit is per context, @c 0 if it is
|
|
||||||
* per session.
|
|
||||||
*/
|
|
||||||
int coap_dtls_is_context_timeout(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do all pending retransmits and get next timeout
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param dtls_context The DTLS context.
|
|
||||||
*
|
|
||||||
* @return @c 0 if no event is pending or date of the next retransmit.
|
|
||||||
*/
|
|
||||||
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get next timeout for this session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param now The current time in ticks.
|
|
||||||
*
|
|
||||||
* @return @c 0 If no event is pending or ticks time of the next retransmit.
|
|
||||||
*/
|
|
||||||
coap_tick_t coap_dtls_get_timeout(struct coap_session_t *coap_session,
|
|
||||||
coap_tick_t now);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a DTLS timeout expiration.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*/
|
|
||||||
void coap_dtls_handle_timeout(struct coap_session_t *coap_session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handling incoming data from a DTLS peer.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param data Encrypted datagram.
|
|
||||||
* @param data_len Encrypted datagram size.
|
|
||||||
*
|
|
||||||
* @return Result of coap_handle_dgram on the decrypted CoAP PDU
|
|
||||||
* or @c -1 for error.
|
|
||||||
*/
|
|
||||||
int coap_dtls_receive(struct coap_session_t *coap_session,
|
|
||||||
const uint8_t *data,
|
|
||||||
size_t data_len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handling client HELLO messages from a new candiate peer.
|
|
||||||
* Note that session->tls is empty.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param data Encrypted datagram.
|
|
||||||
* @param data_len Encrypted datagram size.
|
|
||||||
*
|
|
||||||
* @return @c 0 if a cookie verification message has been sent, @c 1 if the
|
|
||||||
* HELLO contains a valid cookie and a server session should be created,
|
|
||||||
* @c -1 if the message is invalid.
|
|
||||||
*/
|
|
||||||
int coap_dtls_hello(struct coap_session_t *coap_session,
|
|
||||||
const uint8_t *data,
|
|
||||||
size_t data_len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get DTLS overhead over cleartext PDUs.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*
|
|
||||||
* @return Maximum number of bytes added by DTLS layer.
|
|
||||||
*/
|
|
||||||
unsigned int coap_dtls_get_overhead(struct coap_session_t *coap_session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new TLS client-side session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param connected Updated with whether the connection is connected yet or not.
|
|
||||||
* @c 0 is not connected, @c 1 is connected.
|
|
||||||
*
|
|
||||||
* @return Opaque handle to underlying TLS library object containing security
|
|
||||||
* parameters for the session.
|
|
||||||
*/
|
|
||||||
void *coap_tls_new_client_session(struct coap_session_t *coap_session, int *connected);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a TLS new server-side session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param connected Updated with whether the connection is connected yet or not.
|
|
||||||
* @c 0 is not connected, @c 1 is connected.
|
|
||||||
*
|
|
||||||
* @return Opaque handle to underlying TLS library object containing security
|
|
||||||
* parameters for the session.
|
|
||||||
*/
|
|
||||||
void *coap_tls_new_server_session(struct coap_session_t *coap_session, int *connected);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Terminates the TLS session (may send an ALERT if necessary) then frees the
|
|
||||||
* underlying TLS library object containing security parameters for the session.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
*/
|
|
||||||
void coap_tls_free_session( struct coap_session_t *coap_session );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send data to a TLS peer, with implicit flush.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param data Pointer to data.
|
|
||||||
* @param data_len Number of bytes to send.
|
|
||||||
*
|
|
||||||
* @return @c 0 if this should be retried, @c -1 if there is an error
|
|
||||||
* or the number of cleartext bytes sent.
|
|
||||||
*/
|
|
||||||
ssize_t coap_tls_write(struct coap_session_t *coap_session,
|
|
||||||
const uint8_t *data,
|
|
||||||
size_t data_len
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read some data from a TLS peer.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
* @param coap_session The CoAP session.
|
|
||||||
* @param data Pointer to data.
|
|
||||||
* @param data_len Maximum number of bytes to read.
|
|
||||||
*
|
|
||||||
* @return @c 0 if this should be retried, @c -1 if there is an error
|
|
||||||
* or the number of cleartext bytes read.
|
|
||||||
*/
|
|
||||||
ssize_t coap_tls_read(struct coap_session_t *coap_session,
|
|
||||||
uint8_t *data,
|
|
||||||
size_t data_len
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the underlying (D)TLS Library layer.
|
|
||||||
*
|
|
||||||
* Internal function.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void coap_dtls_startup(void);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup logging
|
|
||||||
* Sets the (D)TLS logging level to the specified @p level.
|
|
||||||
* Note: coap_log_level() will influence output if at a specified level.
|
|
||||||
*
|
|
||||||
* @param level The logging level to use - LOG_*
|
|
||||||
*/
|
|
||||||
void coap_dtls_set_log_level(int level);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup logging
|
|
||||||
* Get the current (D)TLS logging.
|
|
||||||
*
|
|
||||||
* @return The current log level (one of LOG_*).
|
|
||||||
*/
|
|
||||||
int coap_dtls_get_log_level(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* COAP_DTLS_H */
|
|
@ -21,27 +21,28 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libcoap.h"
|
#include "coap3/libcoap.h"
|
||||||
|
|
||||||
#include "address.h"
|
#include "coap3/coap_forward_decls.h"
|
||||||
#include "async.h"
|
#include "coap3/address.h"
|
||||||
#include "bits.h"
|
#include "coap3/async.h"
|
||||||
#include "block.h"
|
#include "coap3/block.h"
|
||||||
#include "coap_dtls.h"
|
#include "coap3/coap_cache.h"
|
||||||
#include "coap_event.h"
|
#include "coap3/coap_dtls.h"
|
||||||
#include "coap_io.h"
|
#include "coap3/coap_event.h"
|
||||||
#include "coap_time.h"
|
#include "coap3/coap_io.h"
|
||||||
#include "coap_debug.h"
|
#include "coap3/coap_time.h"
|
||||||
#include "encode.h"
|
#include "coap3/coap_debug.h"
|
||||||
#include "mem.h"
|
#include "coap3/encode.h"
|
||||||
#include "net.h"
|
#include "coap3/mem.h"
|
||||||
#include "option.h"
|
#include "coap3/net.h"
|
||||||
#include "pdu.h"
|
#include "coap3/option.h"
|
||||||
#include "prng.h"
|
#include "coap3/pdu.h"
|
||||||
#include "resource.h"
|
#include "coap3/coap_prng.h"
|
||||||
#include "str.h"
|
#include "coap3/resource.h"
|
||||||
#include "subscribe.h"
|
#include "coap3/str.h"
|
||||||
#include "uri.h"
|
#include "coap3/subscribe.h"
|
||||||
|
#include "coap3/uri.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
@ -30,6 +30,7 @@
|
|||||||
#define HAVE_NETDB_H
|
#define HAVE_NETDB_H
|
||||||
#define HAVE_NETINET_IN_H
|
#define HAVE_NETINET_IN_H
|
||||||
#define HAVE_STRUCT_CMSGHDR
|
#define HAVE_STRUCT_CMSGHDR
|
||||||
|
#define COAP_DISABLE_TCP 0
|
||||||
|
|
||||||
#define ipi_spec_dst ipi_addr
|
#define ipi_spec_dst ipi_addr
|
||||||
struct in6_pktinfo {
|
struct in6_pktinfo {
|
||||||
@ -53,8 +54,6 @@ struct in6_pktinfo {
|
|||||||
#define COAP_CONSTRAINED_STACK 1
|
#define COAP_CONSTRAINED_STACK 1
|
||||||
#define ESPIDF_VERSION
|
#define ESPIDF_VERSION
|
||||||
|
|
||||||
#define _POSIX_TIMERS 1
|
|
||||||
|
|
||||||
#define gai_strerror(x) "gai_strerror() not supported"
|
#define gai_strerror(x) "gai_strerror() not supported"
|
||||||
|
|
||||||
#endif /* WITH_POSIX */
|
#endif /* WITH_POSIX */
|
||||||
|
@ -43,6 +43,8 @@ Component config --->
|
|||||||
CoAP Configuration --->
|
CoAP Configuration --->
|
||||||
* Set encryption method definition, PSK (default) or PKI
|
* Set encryption method definition, PSK (default) or PKI
|
||||||
* Enable CoAP debugging if required
|
* Enable CoAP debugging if required
|
||||||
|
High resolution timer (esp_timer) --->
|
||||||
|
* Hardware timer to use for esp_timer - change if required (FRC2 for QEMU)
|
||||||
|
|
||||||
### Build and Flash
|
### Build and Flash
|
||||||
|
|
||||||
@ -59,20 +61,24 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
|
|||||||
|
|
||||||
## Example Output
|
## Example Output
|
||||||
Prerequisite: we startup a CoAP server on coap server example,
|
Prerequisite: we startup a CoAP server on coap server example,
|
||||||
or use the default of coaps://californium.eclipseprojects.io.
|
or use the default of coap://californium.eclipseprojects.io.
|
||||||
|
|
||||||
and you could receive data from CoAP server if succeed,
|
and you could receive data from CoAP server if succeed,
|
||||||
such as the following log:
|
such as the following log:
|
||||||
|
|
||||||
```
|
```
|
||||||
...
|
...
|
||||||
I (5104) esp_netif_handlers: example_connect: sta ip: 192.168.0.103, mask: 255.255.255.0, gw: 192.168.0.1
|
I (332) wifi: mode : sta (30:ae:a4:04:1b:7c)
|
||||||
I (5104) example_connect: Got IPv4 event: Interface "example_connect: sta" address: 192.168.0.103
|
I (1672) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1
|
||||||
I (5604) example_connect: Got IPv6 event: Interface "example_connect: sta" address: fe80:0000:0000:0000:32ae:a4ff:fec5:3234, type: ESP_IP6_ADDR_IS_LINK_LOCAL
|
I (1672) wifi: state: init -> auth (b0)
|
||||||
I (5604) example_connect: Connected to example_connect: sta
|
I (1682) wifi: state: auth -> assoc (0)
|
||||||
I (5614) example_connect: - IPv4 address: 192.168.0.103
|
I (1692) wifi: state: assoc -> run (10)
|
||||||
I (5614) example_connect: - IPv6 address: fe80:0000:0000:0000:32ae:a4ff:fec5:3234, type: ESP_IP6_ADDR_IS_LINK_LOCAL
|
I (1692) wifi: connected with huawei_cw, channel 11
|
||||||
I (6004) CoAP_client: DNS lookup succeeded. IP=35.185.40.182
|
I (1692) wifi: pm start, type: 1
|
||||||
|
|
||||||
|
I (2582) event: sta ip: 192.168.3.89, mask: 255.255.255.0, gw: 192.168.3.1
|
||||||
|
I (2582) CoAP_client: Connected to AP
|
||||||
|
I (2582) CoAP_client: DNS lookup succeeded. IP=35.185.40.182
|
||||||
Received:
|
Received:
|
||||||
****************************************************************
|
****************************************************************
|
||||||
CoAP RFC 7252 Cf 3.0.0-SNAPSHOT
|
CoAP RFC 7252 Cf 3.0.0-SNAPSHOT
|
||||||
@ -86,7 +92,11 @@ published under EPL+EDL: http://www.eclipse.org/californium/
|
|||||||
```
|
```
|
||||||
|
|
||||||
## libcoap Documentation
|
## libcoap Documentation
|
||||||
This can be found at https://libcoap.net/doc/reference/4.2.0/
|
This can be found at [libcoap Documentation](https://libcoap.net/documentation.html).
|
||||||
|
The current API is 4.3.0.
|
||||||
|
|
||||||
|
## libcoap Specific Issues
|
||||||
|
These can be raised at [libcoap Issues](https://github.com/obgm/libcoap/issues).
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
* Please make sure Target Url includes valid `host`, optional `port`,
|
* Please make sure Target Url includes valid `host`, optional `port`,
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIID3DCCA0WgAwIBAgIJAMnlgL1czsmjMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
|
MIICDzCCAbSgAwIBAgIIAbOUoVFDz/QwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
|
||||||
VQQGEwJGUjEPMA0GA1UECAwGUmFkaXVzMRIwEAYDVQQHDAlTb21ld2hlcmUxFTAT
|
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
|
||||||
BgNVBAoMDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs
|
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
|
||||||
ZS5jb20xJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X
|
MDMzWhcNMjExMTExMTAzMDMzWjBaMQ4wDAYDVQQDEwVjZi1jYTEUMBIGA1UECxML
|
||||||
DTE3MDYwNzA4MDY0OVoXDTI3MDYwNTA4MDY0OVowgZMxCzAJBgNVBAYTAkZSMQ8w
|
Q2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZPdHRh
|
||||||
DQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMGA1UECgwMRXhh
|
d2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7/3EXOZn
|
||||||
bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG
|
GZXNEIj7LuQAMZ8lfRYSCnpME1TBjKjZPtVeztLtGWgkkLvIX11pAJcBh51cpi7Z
|
||||||
A1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcN
|
fQtGpVE9CLOh6aNgMF4wHQYDVR0OBBYEFEvf57UcJhYYkx14twkeitd691fVMAsG
|
||||||
AQEBBQADgY0AMIGJAoGBALpWR23fn/TmHxsXsHdrydzPSd17fZkc71WsaicgQR66
|
A1UdDwQEAwIBBjAPBgNVHRMECDAGAQH/AgEBMB8GA1UdIwQYMBaAFAsi3KbVERiK
|
||||||
1tIVYb22UWGfj9KPM8THMsV74ew4ZkaQ39qvU0iuQIRrKARFHFok+vbaecgWMeWe
|
JzFCfC/GVrYksGzEMAwGCCqGSM49BAMCBQADRwAwRAIgc5nVF/5Pip0XB17IZXqi
|
||||||
vGIqdnmyB9gJYaFOKgtSkfXsu2ddsqdvLYwcDbczrq8X9yEXpN6mnxXeCcPG4F0p
|
V84FXanWdn9Z0SiPdpOgvZMCIH13vL9tkCCjPN3tg3TYRY/bzyGohFGBcTrrEtUr
|
||||||
AgMBAAGjggE0MIIBMDAdBgNVHQ4EFgQUgigpdAUpONoDq0pQ3yfxrslCSpcwgcgG
|
rVIm
|
||||||
A1UdIwSBwDCBvYAUgigpdAUpONoDq0pQ3yfxrslCSpehgZmkgZYwgZMxCzAJBgNV
|
-----END CERTIFICATE-----
|
||||||
BAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMG
|
-----BEGIN CERTIFICATE-----
|
||||||
A1UECgwMRXhhbXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxl
|
MIIB4DCCAYWgAwIBAgIIQR8ro8AQ02AwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
|
||||||
LmNvbTEmMCQGA1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCCQDJ
|
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
|
||||||
5YC9XM7JozAMBgNVHRMEBTADAQH/MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly93
|
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
|
||||||
d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZIhvcNAQELBQADgYEA
|
MDMyWhcNMjExMTExMTAzMDMyWjBcMRAwDgYDVQQDEwdjZi1yb290MRQwEgYDVQQL
|
||||||
euxOBPInSJRKAIseMxPmAabtAqKNslZSmpG4He3lkKt+HM3jfznUt3psmD7j1hFW
|
EwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBzZSBJb1QxDzANBgNVBAcTBk90
|
||||||
S4l7KXzzajvaGYybDq5N9MqrDjhGn3VXZqOLMUNDL7OQq96TzgqsTBT1dmVSbNlt
|
dGF3YTELMAkGA1UEBhMCQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATZ1BRM
|
||||||
PQgiAeKAk3tmH4lRRi9MTBSyJ6I92JYcS5H6Bs4ZwCc=
|
T1//Fzh9sneRZNwS4kgCxN1PvgwT271qCpYqyxnjLEa38AP1IAanhpiD/OkVc0Zd
|
||||||
|
7NgDPCw7n94EULMyoy8wLTAdBgNVHQ4EFgQUCyLcptURGIonMUJ8L8ZWtiSwbMQw
|
||||||
|
DAYDVR0TBAUwAwEB/zAMBggqhkjOPQQDAgUAA0cAMEQCIAdLEgcUWdpAl9jwdJiz
|
||||||
|
/cHW7/CBIWEvqiQfzE+XLyLOAiAvuxSdOtSDjh2aC5qEjUCH8CSKCxWB74j23tmp
|
||||||
|
aqPH4A==
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
@ -1,70 +1,13 @@
|
|||||||
Certificate:
|
|
||||||
Data:
|
|
||||||
Version: 3 (0x2)
|
|
||||||
Serial Number: 48 (0x30)
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
Issuer: C=FR, ST=Radius, L=Somewhere, O=Example Inc./emailAddress=admin@example.com, CN=Example Certificate Authority
|
|
||||||
Validity
|
|
||||||
Not Before: Jun 7 08:06:49 2017 GMT
|
|
||||||
Not After : Jun 5 08:06:49 2027 GMT
|
|
||||||
Subject: C=FR, ST=Radius, O=Example Inc., CN=user@example.com/emailAddress=user@example.com
|
|
||||||
Subject Public Key Info:
|
|
||||||
Public Key Algorithm: rsaEncryption
|
|
||||||
Public-Key: (2048 bit)
|
|
||||||
Modulus:
|
|
||||||
00:d2:f6:be:72:a5:ab:2e:56:0c:dd:f2:3b:2c:7c:
|
|
||||||
e0:5d:05:40:af:0c:8c:f3:82:0c:d0:18:34:b4:e3:
|
|
||||||
7d:5f:8d:0a:3e:aa:79:02:f9:96:ad:10:00:ec:51:
|
|
||||||
e9:dc:3f:fb:ea:b0:57:eb:48:c7:ca:ef:e8:05:ab:
|
|
||||||
ee:3f:66:ba:5c:9e:7f:40:85:9f:25:a0:e0:e3:7c:
|
|
||||||
cf:b6:e6:31:f5:fd:24:03:c8:f4:fb:d8:a4:f3:92:
|
|
||||||
29:05:aa:55:43:80:f7:3e:13:10:43:3a:89:24:be:
|
|
||||||
d8:01:86:d1:69:73:44:7d:f8:b9:46:2b:6b:51:d0:
|
|
||||||
11:31:4b:06:ae:9f:45:fa:12:17:0c:ef:6a:fa:d0:
|
|
||||||
f7:36:46:eb:2e:db:4e:20:46:01:33:ac:b1:f7:4a:
|
|
||||||
e6:18:3d:53:22:dc:e8:4a:12:78:11:2f:e4:3b:92:
|
|
||||||
bd:d7:07:5a:c9:81:5d:48:58:c8:0f:9b:e9:a4:0f:
|
|
||||||
bb:89:b1:ad:38:07:6f:93:d0:a6:12:56:f9:07:48:
|
|
||||||
d2:23:2f:a3:a9:93:b0:11:0a:27:4c:48:0a:8d:70:
|
|
||||||
41:68:76:7a:dd:bc:54:c3:42:33:b0:7b:f6:ae:1f:
|
|
||||||
e7:95:5e:11:ca:f2:b4:4b:5c:ba:47:64:f0:f3:d7:
|
|
||||||
87:95:7f:93:06:a1:72:c9:81:12:a5:b7:8f:9d:7e:
|
|
||||||
d1:ef
|
|
||||||
Exponent: 65537 (0x10001)
|
|
||||||
X509v3 extensions:
|
|
||||||
X509v3 Extended Key Usage:
|
|
||||||
TLS Web Client Authentication
|
|
||||||
X509v3 CRL Distribution Points:
|
|
||||||
|
|
||||||
Full Name:
|
|
||||||
URI:http://www.example.com/example_ca.crl
|
|
||||||
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
2d:02:bc:7b:88:b8:5c:e1:07:b8:bb:ba:b2:f3:98:14:8f:cb:
|
|
||||||
b0:21:13:b5:e5:6f:05:4f:92:fa:ac:c0:53:a7:b0:cd:7e:ba:
|
|
||||||
87:36:85:25:d7:41:c5:29:84:22:74:af:bf:3e:34:36:d5:24:
|
|
||||||
7a:81:e2:1b:54:52:85:6f:76:de:dc:63:98:45:fc:2c:31:fa:
|
|
||||||
22:a4:72:3a:8d:d4:6a:2e:de:33:10:41:eb:94:1d:e3:59:cd:
|
|
||||||
b2:be:ab:f0:b6:20:86:9c:b8:46:ee:c5:64:ba:b6:6c:cc:53:
|
|
||||||
44:7a:80:12:77:7c:e7:51:67:91:32:2f:88:9d:93:a8:ef:d6:
|
|
||||||
cd:de
|
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDTjCCAregAwIBAgIBMDANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx
|
MIICAzCCAaagAwIBAgIJAJnE6sMNQNAoMAwGCCqGSM49BAMCBQAwWjEOMAwGA1UE
|
||||||
DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF
|
AxMFY2YtY2ExFDASBgNVBAsTC0NhbGlmb3JuaXVtMRQwEgYDVQQKEwtFY2xpcHNl
|
||||||
eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw
|
IElvVDEPMA0GA1UEBxMGT3R0YXdhMQswCQYDVQQGEwJDQTAeFw0yMDExMTExMDMw
|
||||||
JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw
|
NDVaFw0yMTExMTExMDMwNDVaMF4xEjAQBgNVBAMTCWNmLWNsaWVudDEUMBIGA1UE
|
||||||
ODA2NDlaFw0yNzA2MDUwODA2NDlaMHExCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS
|
CxMLQ2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZP
|
||||||
YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEZMBcGA1UEAwwQdXNlckBleGFt
|
dHRhd2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFGno
|
||||||
cGxlLmNvbTEfMB0GCSqGSIb3DQEJARYQdXNlckBleGFtcGxlLmNvbTCCASIwDQYJ
|
107kFgJ4AvABQviE9hTJlEeB4wfS3L58Q5J8srWxSunEgniIbfr0p8Shw+C1XAcz
|
||||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANL2vnKlqy5WDN3yOyx84F0FQK8MjPOC
|
FxJrn8SjFCVqOKjrrqNPME0wHQYDVR0OBBYEFIwAAdmpYSm184Jx1ycc3BQGybhN
|
||||||
DNAYNLTjfV+NCj6qeQL5lq0QAOxR6dw/++qwV+tIx8rv6AWr7j9mulyef0CFnyWg
|
MAsGA1UdDwQEAwIHgDAfBgNVHSMEGDAWgBRL3+e1HCYWGJMdeLcJHorXevdX1TAM
|
||||||
4ON8z7bmMfX9JAPI9PvYpPOSKQWqVUOA9z4TEEM6iSS+2AGG0WlzRH34uUYra1HQ
|
BggqhkjOPQQDAgUAA0kAMEYCIQC+w/hm8TfTCqUV6midHAvmNxJN7MfMcpAiyi4e
|
||||||
ETFLBq6fRfoSFwzvavrQ9zZG6y7bTiBGATOssfdK5hg9UyLc6EoSeBEv5DuSvdcH
|
6NBrPAIhAPeMUrnOlykTMcpYMRZs4YnyM6ihgU/F8UjknhDpkywm
|
||||||
WsmBXUhYyA+b6aQPu4mxrTgHb5PQphJW+QdI0iMvo6mTsBEKJ0xICo1wQWh2et28
|
|
||||||
VMNCM7B79q4f55VeEcrytEtcukdk8PPXh5V/kwahcsmBEqW3j51+0e8CAwEAAaNP
|
|
||||||
ME0wEwYDVR0lBAwwCgYIKwYBBQUHAwIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDov
|
|
||||||
L3d3dy5leGFtcGxlLmNvbS9leGFtcGxlX2NhLmNybDANBgkqhkiG9w0BAQUFAAOB
|
|
||||||
gQAtArx7iLhc4Qe4u7qy85gUj8uwIRO15W8FT5L6rMBTp7DNfrqHNoUl10HFKYQi
|
|
||||||
dK+/PjQ21SR6geIbVFKFb3be3GOYRfwsMfoipHI6jdRqLt4zEEHrlB3jWc2yvqvw
|
|
||||||
tiCGnLhG7sVkurZszFNEeoASd3znUWeRMi+InZOo79bN3g==
|
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
@ -1,27 +1,4 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MIIEpAIBAAKCAQEA0va+cqWrLlYM3fI7LHzgXQVArwyM84IM0Bg0tON9X40KPqp5
|
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBgNuyqKuRW0RxU1DVs
|
||||||
AvmWrRAA7FHp3D/76rBX60jHyu/oBavuP2a6XJ5/QIWfJaDg43zPtuYx9f0kA8j0
|
aEpBPtVRVLRZYq6hZRzvZ6igBw==
|
||||||
+9ik85IpBapVQ4D3PhMQQzqJJL7YAYbRaXNEffi5RitrUdARMUsGrp9F+hIXDO9q
|
-----END PRIVATE KEY-----
|
||||||
+tD3NkbrLttOIEYBM6yx90rmGD1TItzoShJ4ES/kO5K91wdayYFdSFjID5vppA+7
|
|
||||||
ibGtOAdvk9CmElb5B0jSIy+jqZOwEQonTEgKjXBBaHZ63bxUw0IzsHv2rh/nlV4R
|
|
||||||
yvK0S1y6R2Tw89eHlX+TBqFyyYESpbePnX7R7wIDAQABAoIBAQC5PncO3tBIeMEF
|
|
||||||
pu007FZq9/DLhP7D2B9+HrMxX0y4uXUUf8aQyS74ukPFP0xV3U1M0BnzfU4KscyQ
|
|
||||||
Jl+nBoKAT6C3vF15wiGXQAJ4vPuD4Ate03fjKWH2ixJAakhCZR01QbIXBnBkdrvf
|
|
||||||
401BBjlPUDcIGZo8FbLzEMlGTo84vE9v3Qmkbi+PzPCh2YC+NDmsOcIW1zpmwyYC
|
|
||||||
ZYCpoWgl4++kqXXn0NGhuaOgB0JLsJOBpx/hOOjBU/wXCKaXZ1vchYqfbvvx2gf2
|
|
||||||
WX4P0CiTH1z7MEAHanaZkcnNyxV/oF1EIMY5p0vDDzgrKtppvPOqspjydje03+CE
|
|
||||||
t0wKGPi5AoGBAPAG2Y4efgwLcoWdPjKZtsHLhDhLJnvxkqnNkzdPnLZojNi8pKkV
|
|
||||||
/Yu++pPemJZZa4YAp+OnqyEfhcha+HYqKMwRC8t3YrEVOlRQTfW/OoSrp059JIRV
|
|
||||||
jTvq/u7DdYGJRRgMLUJiEI+7xj1WbTc2EceJAgn0qfKvbvBtVJP0LH1TAoGBAOEA
|
|
||||||
xZB7SwyX+zDGRTugqMYg+sYobbQHJ7utLyoX+ckeG+sPEjEYLpQQfshET/gwF8ZK
|
|
||||||
4aILkACx/tna799xCjQdmyyc338NO9WULlY1xF+65WfeaxrtTAsqVikX3p19McRI
|
|
||||||
ijX8k7Msy3gYWJXev3MCtPT2+g68IgbL/W2wY+l1AoGAT7xGy0Jv5vpqid5pig+s
|
|
||||||
OYatHrJAT445hXUIQaiNy77Bg0JvhMgMWT8RKMwabl+4K2TOYP8TB0bcf2lQ/pgU
|
|
||||||
w22qOGYpf+AoZ1fh/hAPlYEcbCOAXQG6kDwJgjGmOGjsbgelhVbkX4smWLv8PgoV
|
|
||||||
L+7goYQIbNlAhlgbb6b+nIcCgYBB7Zr2Cdpkt0en9ACnRx0M6O7yDziNzqbqzAUM
|
|
||||||
3XeYYZUmnATlk8NaKTcs8S9JdrYQqTJR6/dm7MDTDt7IZvPpb19fhBvMu5DztPaa
|
|
||||||
1ihTMI01kStq+WsVvnL+mXrmRJ/HdsXgqcCReKep6eBTEbChP4LMYG3G0YNa4HzC
|
|
||||||
njO4XQKBgQDRnbqqg2CNTnS94BN2D3uzzELtwsIG6aVCtl09ZsLnGaBKVVDtP6BI
|
|
||||||
j2hGD7xw4g5JeSPIJU5J03nALTY3hz1JyI7AJCX7+JRtUTX2A8C4mlbeul7ilGaU
|
|
||||||
A7MFT8GqhjYYa84GzNcA1mK8ynlixpL8+yzTT/8lWInWRBa69SkktA==
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
|
@ -31,17 +31,12 @@
|
|||||||
|
|
||||||
#include "protocol_examples_common.h"
|
#include "protocol_examples_common.h"
|
||||||
|
|
||||||
#if 1
|
#include "coap3/coap.h"
|
||||||
/* Needed until coap_dtls.h becomes a part of libcoap proper */
|
|
||||||
#include "libcoap.h"
|
|
||||||
#include "coap_dtls.h"
|
|
||||||
#endif
|
|
||||||
#include "coap.h"
|
|
||||||
|
|
||||||
#define COAP_DEFAULT_TIME_SEC 5
|
#define COAP_DEFAULT_TIME_SEC 60
|
||||||
|
|
||||||
/* The examples use simple Pre-Shared-Key configuration that you can set via
|
/* The examples use simple Pre-Shared-Key configuration that you can set via
|
||||||
'make menuconfig'.
|
'idf.py menuconfig'.
|
||||||
|
|
||||||
If you'd rather not, just change the below entries to strings with
|
If you'd rather not, just change the below entries to strings with
|
||||||
the config you want - ie #define EXAMPLE_COAP_PSK_KEY "some-agreed-preshared-key"
|
the config you want - ie #define EXAMPLE_COAP_PSK_KEY "some-agreed-preshared-key"
|
||||||
@ -54,7 +49,7 @@
|
|||||||
#define EXAMPLE_COAP_PSK_IDENTITY CONFIG_EXAMPLE_COAP_PSK_IDENTITY
|
#define EXAMPLE_COAP_PSK_IDENTITY CONFIG_EXAMPLE_COAP_PSK_IDENTITY
|
||||||
|
|
||||||
/* The examples use uri Logging Level that
|
/* The examples use uri Logging Level that
|
||||||
you can set via 'make menuconfig'.
|
you can set via 'idf.py menuconfig'.
|
||||||
|
|
||||||
If you'd rather not, just change the below entry to a value
|
If you'd rather not, just change the below entry to a value
|
||||||
that is between 0 and 7 with
|
that is between 0 and 7 with
|
||||||
@ -62,11 +57,11 @@
|
|||||||
*/
|
*/
|
||||||
#define EXAMPLE_COAP_LOG_DEFAULT_LEVEL CONFIG_COAP_LOG_DEFAULT_LEVEL
|
#define EXAMPLE_COAP_LOG_DEFAULT_LEVEL CONFIG_COAP_LOG_DEFAULT_LEVEL
|
||||||
|
|
||||||
/* The examples use uri "coap://californium.eclipse.org" that
|
/* The examples use uri "coap://californium.eclipseprojects.io" that
|
||||||
you can set via the project configuration (idf.py menuconfig)
|
you can set via the project configuration (idf.py menuconfig)
|
||||||
|
|
||||||
If you'd rather not, just change the below entries to strings with
|
If you'd rather not, just change the below entries to strings with
|
||||||
the config you want - ie #define COAP_DEFAULT_DEMO_URI "coaps://californium.eclipse.org"
|
the config you want - ie #define COAP_DEFAULT_DEMO_URI "coaps://californium.eclipseprojects.io"
|
||||||
*/
|
*/
|
||||||
#define COAP_DEFAULT_DEMO_URI CONFIG_EXAMPLE_TARGET_DOMAIN_URI
|
#define COAP_DEFAULT_DEMO_URI CONFIG_EXAMPLE_TARGET_DOMAIN_URI
|
||||||
|
|
||||||
@ -81,8 +76,9 @@ static int wait_ms;
|
|||||||
Client cert, taken from coap_client.crt
|
Client cert, taken from coap_client.crt
|
||||||
Client key, taken from coap_client.key
|
Client key, taken from coap_client.key
|
||||||
|
|
||||||
The PEM, CRT and KEY file are examples taken from the wpa2 enterprise
|
The PEM, CRT and KEY file are examples taken from
|
||||||
example.
|
https://github.com/eclipse/californium/tree/master/demo-certs/src/main/resources
|
||||||
|
as the Certificate test (by default) is against the californium server.
|
||||||
|
|
||||||
To embed it in the app binary, the PEM, CRT and KEY file is named
|
To embed it in the app binary, the PEM, CRT and KEY file is named
|
||||||
in the component.mk COMPONENT_EMBED_TXTFILES variable.
|
in the component.mk COMPONENT_EMBED_TXTFILES variable.
|
||||||
@ -95,84 +91,39 @@ extern uint8_t client_key_start[] asm("_binary_coap_client_key_start");
|
|||||||
extern uint8_t client_key_end[] asm("_binary_coap_client_key_end");
|
extern uint8_t client_key_end[] asm("_binary_coap_client_key_end");
|
||||||
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
||||||
|
|
||||||
static void message_handler(coap_context_t *ctx, coap_session_t *session,
|
static coap_response_t
|
||||||
coap_pdu_t *sent, coap_pdu_t *received,
|
message_handler(coap_session_t *session,
|
||||||
const coap_tid_t id)
|
const coap_pdu_t *sent,
|
||||||
|
const coap_pdu_t *received,
|
||||||
|
const coap_mid_t mid)
|
||||||
{
|
{
|
||||||
unsigned char *data = NULL;
|
const unsigned char *data = NULL;
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
coap_pdu_t *pdu = NULL;
|
size_t offset;
|
||||||
coap_opt_t *block_opt;
|
size_t total;
|
||||||
coap_opt_iterator_t opt_iter;
|
coap_pdu_code_t rcvd_code = coap_pdu_get_code(received);
|
||||||
unsigned char buf[4];
|
|
||||||
coap_optlist_t *option;
|
|
||||||
coap_tid_t tid;
|
|
||||||
|
|
||||||
if (COAP_RESPONSE_CLASS(received->code) == 2) {
|
if (COAP_RESPONSE_CLASS(rcvd_code) == 2) {
|
||||||
/* Need to see if blocked response */
|
if (coap_get_data_large(received, &data_len, &data, &offset, &total)) {
|
||||||
block_opt = coap_check_option(received, COAP_OPTION_BLOCK2, &opt_iter);
|
if (data_len != total) {
|
||||||
if (block_opt) {
|
printf("Unexpected partial data received offset %u, length %u\n", offset, data_len);
|
||||||
uint16_t blktype = opt_iter.type;
|
|
||||||
|
|
||||||
if (coap_opt_block_num(block_opt) == 0) {
|
|
||||||
printf("Received:\n");
|
|
||||||
}
|
|
||||||
if (coap_get_data(received, &data_len, &data)) {
|
|
||||||
printf("%.*s", (int)data_len, data);
|
|
||||||
}
|
|
||||||
if (COAP_OPT_BLOCK_MORE(block_opt)) {
|
|
||||||
/* more bit is set */
|
|
||||||
|
|
||||||
/* create pdu with request for next block */
|
|
||||||
pdu = coap_new_pdu(session);
|
|
||||||
if (!pdu) {
|
|
||||||
ESP_LOGE(TAG, "coap_new_pdu() failed");
|
|
||||||
goto clean_up;
|
|
||||||
}
|
|
||||||
pdu->type = COAP_MESSAGE_CON;
|
|
||||||
pdu->tid = coap_new_message_id(session);
|
|
||||||
pdu->code = COAP_REQUEST_GET;
|
|
||||||
|
|
||||||
/* add URI components from optlist */
|
|
||||||
for (option = optlist; option; option = option->next ) {
|
|
||||||
switch (option->number) {
|
|
||||||
case COAP_OPTION_URI_HOST :
|
|
||||||
case COAP_OPTION_URI_PORT :
|
|
||||||
case COAP_OPTION_URI_PATH :
|
|
||||||
case COAP_OPTION_URI_QUERY :
|
|
||||||
coap_add_option(pdu, option->number, option->length,
|
|
||||||
option->data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
; /* skip other options */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finally add updated block option from response, clear M bit */
|
|
||||||
/* blocknr = (blocknr & 0xfffffff7) + 0x10; */
|
|
||||||
coap_add_option(pdu,
|
|
||||||
blktype,
|
|
||||||
coap_encode_var_safe(buf, sizeof(buf),
|
|
||||||
((coap_opt_block_num(block_opt) + 1) << 4) |
|
|
||||||
COAP_OPT_BLOCK_SZX(block_opt)), buf);
|
|
||||||
|
|
||||||
tid = coap_send(session, pdu);
|
|
||||||
|
|
||||||
if (tid != COAP_INVALID_TID) {
|
|
||||||
resp_wait = 1;
|
|
||||||
wait_ms = COAP_DEFAULT_TIME_SEC * 1000;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
} else {
|
|
||||||
if (coap_get_data(received, &data_len, &data)) {
|
|
||||||
printf("Received: %.*s\n", (int)data_len, data);
|
|
||||||
}
|
}
|
||||||
|
printf("Received:\n%.*s\n", (int)data_len, data);
|
||||||
|
resp_wait = 0;
|
||||||
|
}
|
||||||
|
return COAP_RESPONSE_OK;
|
||||||
|
}
|
||||||
|
printf("%d.%02d", (rcvd_code >> 5), rcvd_code & 0x1F);
|
||||||
|
if (coap_get_data_large(received, &data_len, &data, &offset, &total)) {
|
||||||
|
printf(": ");
|
||||||
|
while(data_len--) {
|
||||||
|
printf("%c", isprint(*data) ? *data : '.');
|
||||||
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean_up:
|
printf("\n");
|
||||||
resp_wait = 0;
|
resp_wait = 0;
|
||||||
|
return COAP_RESPONSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
||||||
@ -193,210 +144,303 @@ verify_cn_callback(const char *cn,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
||||||
|
|
||||||
static void coap_example_client(void *p)
|
static void
|
||||||
|
coap_log_handler (coap_log_t level, const char *message)
|
||||||
{
|
{
|
||||||
struct hostent *hp;
|
uint32_t esp_level = ESP_LOG_INFO;
|
||||||
coap_address_t dst_addr;
|
char *cp = strchr(message, '\n');
|
||||||
static coap_uri_t uri;
|
|
||||||
const char *server_uri = COAP_DEFAULT_DEMO_URI;
|
if (cp)
|
||||||
|
ESP_LOG_LEVEL(esp_level, TAG, "%.*s", (int)(cp-message), message);
|
||||||
|
else
|
||||||
|
ESP_LOG_LEVEL(esp_level, TAG, "%s", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static coap_address_t *
|
||||||
|
coap_get_address(coap_uri_t *uri)
|
||||||
|
{
|
||||||
|
static coap_address_t dst_addr;
|
||||||
char *phostname = NULL;
|
char *phostname = NULL;
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *addrres;
|
||||||
|
int error;
|
||||||
|
char tmpbuf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
coap_set_log_level(EXAMPLE_COAP_LOG_DEFAULT_LEVEL);
|
phostname = (char *)calloc(1, uri->host.length + 1);
|
||||||
|
if (phostname == NULL) {
|
||||||
|
ESP_LOGE(TAG, "calloc failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(phostname, uri->host.s, uri->host.length);
|
||||||
|
|
||||||
while (1) {
|
memset ((char *)&hints, 0, sizeof(hints));
|
||||||
#define BUFSIZE 40
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
unsigned char _buf[BUFSIZE];
|
hints.ai_family = AF_UNSPEC;
|
||||||
unsigned char *buf;
|
|
||||||
size_t buflen;
|
|
||||||
int res;
|
|
||||||
coap_context_t *ctx = NULL;
|
|
||||||
coap_session_t *session = NULL;
|
|
||||||
coap_pdu_t *request = NULL;
|
|
||||||
|
|
||||||
optlist = NULL;
|
error = getaddrinfo(phostname, NULL, &hints, &addrres);
|
||||||
if (coap_split_uri((const uint8_t *)server_uri, strlen(server_uri), &uri) == -1) {
|
if (error != 0) {
|
||||||
ESP_LOGE(TAG, "CoAP server uri error");
|
ESP_LOGE(TAG, "DNS lookup failed for destination address %s. error: %d", phostname, error);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uri.scheme == COAP_URI_SCHEME_COAPS && !coap_dtls_is_supported()) {
|
|
||||||
ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (uri.scheme == COAP_URI_SCHEME_COAPS_TCP && !coap_tls_is_supported()) {
|
|
||||||
ESP_LOGE(TAG, "CoAP server uri coaps+tcp:// scheme is not supported");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
phostname = (char *)calloc(1, uri.host.length + 1);
|
|
||||||
if (phostname == NULL) {
|
|
||||||
ESP_LOGE(TAG, "calloc failed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(phostname, uri.host.s, uri.host.length);
|
|
||||||
hp = gethostbyname(phostname);
|
|
||||||
free(phostname);
|
free(phostname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (addrres == NULL) {
|
||||||
|
ESP_LOGE(TAG, "DNS lookup %s did not return any addresses", phostname);
|
||||||
|
free(phostname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
free(phostname);
|
||||||
|
coap_address_init(&dst_addr);
|
||||||
|
switch (addrres->ai_family) {
|
||||||
|
case AF_INET:
|
||||||
|
memcpy(&dst_addr.addr.sin, addrres->ai_addr, sizeof(dst_addr.addr.sin));
|
||||||
|
dst_addr.addr.sin.sin_port = htons(uri->port);
|
||||||
|
inet_ntop(AF_INET, &dst_addr.addr.sin.sin_addr, tmpbuf, sizeof(tmpbuf));
|
||||||
|
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", tmpbuf);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(&dst_addr.addr.sin6, addrres->ai_addr, sizeof(dst_addr.addr.sin6));
|
||||||
|
dst_addr.addr.sin6.sin6_port = htons(uri->port);
|
||||||
|
inet_ntop(AF_INET6, &dst_addr.addr.sin6.sin6_addr, tmpbuf, sizeof(tmpbuf));
|
||||||
|
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", tmpbuf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGE(TAG, "DNS lookup response failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
freeaddrinfo(addrres);
|
||||||
|
|
||||||
if (hp == NULL) {
|
return &dst_addr;
|
||||||
ESP_LOGE(TAG, "DNS lookup failed");
|
}
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
||||||
free(phostname);
|
static int
|
||||||
continue;
|
coap_build_optlist(coap_uri_t *uri)
|
||||||
|
{
|
||||||
|
#define BUFSIZE 40
|
||||||
|
unsigned char _buf[BUFSIZE];
|
||||||
|
unsigned char *buf;
|
||||||
|
size_t buflen;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
optlist = NULL;
|
||||||
|
|
||||||
|
if (uri->scheme == COAP_URI_SCHEME_COAPS && !coap_dtls_is_supported()) {
|
||||||
|
ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (uri->scheme == COAP_URI_SCHEME_COAPS_TCP && !coap_tls_is_supported()) {
|
||||||
|
ESP_LOGE(TAG, "CoAP server uri->+tcp:// scheme is not supported");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uri->path.length) {
|
||||||
|
buflen = BUFSIZE;
|
||||||
|
buf = _buf;
|
||||||
|
res = coap_split_path(uri->path.s, uri->path.length, buf, &buflen);
|
||||||
|
|
||||||
|
while (res--) {
|
||||||
|
coap_insert_optlist(&optlist,
|
||||||
|
coap_new_optlist(COAP_OPTION_URI_PATH,
|
||||||
|
coap_opt_length(buf),
|
||||||
|
coap_opt_value(buf)));
|
||||||
|
|
||||||
|
buf += coap_opt_size(buf);
|
||||||
}
|
}
|
||||||
char tmpbuf[INET6_ADDRSTRLEN];
|
}
|
||||||
coap_address_init(&dst_addr);
|
|
||||||
switch (hp->h_addrtype) {
|
if (uri->query.length) {
|
||||||
case AF_INET:
|
buflen = BUFSIZE;
|
||||||
dst_addr.addr.sin.sin_family = AF_INET;
|
buf = _buf;
|
||||||
dst_addr.addr.sin.sin_port = htons(uri.port);
|
res = coap_split_query(uri->query.s, uri->query.length, buf, &buflen);
|
||||||
memcpy(&dst_addr.addr.sin.sin_addr, hp->h_addr, sizeof(dst_addr.addr.sin.sin_addr));
|
|
||||||
inet_ntop(AF_INET, &dst_addr.addr.sin.sin_addr, tmpbuf, sizeof(tmpbuf));
|
while (res--) {
|
||||||
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", tmpbuf);
|
coap_insert_optlist(&optlist,
|
||||||
break;
|
coap_new_optlist(COAP_OPTION_URI_QUERY,
|
||||||
case AF_INET6:
|
coap_opt_length(buf),
|
||||||
dst_addr.addr.sin6.sin6_family = AF_INET6;
|
coap_opt_value(buf)));
|
||||||
dst_addr.addr.sin6.sin6_port = htons(uri.port);
|
|
||||||
memcpy(&dst_addr.addr.sin6.sin6_addr, hp->h_addr, sizeof(dst_addr.addr.sin6.sin6_addr));
|
buf += coap_opt_size(buf);
|
||||||
inet_ntop(AF_INET6, &dst_addr.addr.sin6.sin6_addr, tmpbuf, sizeof(tmpbuf));
|
|
||||||
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", tmpbuf);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_LOGE(TAG, "DNS lookup response failed");
|
|
||||||
goto clean_up;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (uri.path.length) {
|
return 1;
|
||||||
buflen = BUFSIZE;
|
}
|
||||||
buf = _buf;
|
|
||||||
res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
|
|
||||||
|
|
||||||
while (res--) {
|
|
||||||
coap_insert_optlist(&optlist,
|
|
||||||
coap_new_optlist(COAP_OPTION_URI_PATH,
|
|
||||||
coap_opt_length(buf),
|
|
||||||
coap_opt_value(buf)));
|
|
||||||
|
|
||||||
buf += coap_opt_size(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uri.query.length) {
|
|
||||||
buflen = BUFSIZE;
|
|
||||||
buf = _buf;
|
|
||||||
res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
|
|
||||||
|
|
||||||
while (res--) {
|
|
||||||
coap_insert_optlist(&optlist,
|
|
||||||
coap_new_optlist(COAP_OPTION_URI_QUERY,
|
|
||||||
coap_opt_length(buf),
|
|
||||||
coap_opt_value(buf)));
|
|
||||||
|
|
||||||
buf += coap_opt_size(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = coap_new_context(NULL);
|
|
||||||
if (!ctx) {
|
|
||||||
ESP_LOGE(TAG, "coap_new_context() failed");
|
|
||||||
goto clean_up;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that if the URI starts with just coap:// (not coaps://) the
|
|
||||||
* session will still be plain text.
|
|
||||||
*
|
|
||||||
* coaps+tcp:// is NOT supported by the libcoap->mbedtls interface
|
|
||||||
* so COAP_URI_SCHEME_COAPS_TCP will have failed in a test above,
|
|
||||||
* but the code is left in for completeness.
|
|
||||||
*/
|
|
||||||
if (uri.scheme == COAP_URI_SCHEME_COAPS || uri.scheme == COAP_URI_SCHEME_COAPS_TCP) {
|
|
||||||
#ifndef CONFIG_MBEDTLS_TLS_CLIENT
|
|
||||||
ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured");
|
|
||||||
goto clean_up;
|
|
||||||
#endif /* CONFIG_MBEDTLS_TLS_CLIENT */
|
|
||||||
#ifdef CONFIG_COAP_MBEDTLS_PSK
|
#ifdef CONFIG_COAP_MBEDTLS_PSK
|
||||||
session = coap_new_client_session_psk(ctx, NULL, &dst_addr,
|
static coap_session_t *
|
||||||
uri.scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS,
|
coap_start_psk_session(coap_context_t *ctx, coap_address_t *dst_addr, coap_uri_t *uri)
|
||||||
EXAMPLE_COAP_PSK_IDENTITY,
|
{
|
||||||
(const uint8_t *)EXAMPLE_COAP_PSK_KEY,
|
static coap_dtls_cpsk_t dtls_psk;
|
||||||
sizeof(EXAMPLE_COAP_PSK_KEY) - 1);
|
static char client_sni[256];
|
||||||
|
|
||||||
|
memset(client_sni, 0, sizeof(client_sni));
|
||||||
|
memset (&dtls_psk, 0, sizeof(dtls_psk));
|
||||||
|
dtls_psk.version = COAP_DTLS_CPSK_SETUP_VERSION;
|
||||||
|
dtls_psk.validate_ih_call_back = NULL;
|
||||||
|
dtls_psk.ih_call_back_arg = NULL;
|
||||||
|
if (uri->host.length)
|
||||||
|
memcpy(client_sni, uri->host.s, MIN(uri->host.length, sizeof(client_sni) - 1));
|
||||||
|
else
|
||||||
|
memcpy(client_sni, "localhost", 9);
|
||||||
|
dtls_psk.client_sni = client_sni;
|
||||||
|
dtls_psk.psk_info.identity.s = (const uint8_t *)EXAMPLE_COAP_PSK_IDENTITY;
|
||||||
|
dtls_psk.psk_info.identity.length = sizeof(EXAMPLE_COAP_PSK_IDENTITY)-1;
|
||||||
|
dtls_psk.psk_info.key.s = (const uint8_t *)EXAMPLE_COAP_PSK_KEY;
|
||||||
|
dtls_psk.psk_info.key.length = sizeof(EXAMPLE_COAP_PSK_KEY)-1;
|
||||||
|
return coap_new_client_session_psk2(ctx, NULL, dst_addr,
|
||||||
|
uri->scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS,
|
||||||
|
&dtls_psk);
|
||||||
|
}
|
||||||
#endif /* CONFIG_COAP_MBEDTLS_PSK */
|
#endif /* CONFIG_COAP_MBEDTLS_PSK */
|
||||||
|
|
||||||
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
||||||
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
|
static coap_session_t *
|
||||||
unsigned int client_crt_bytes = client_crt_end - client_crt_start;
|
coap_start_pki_session(coap_context_t *ctx, coap_address_t *dst_addr, coap_uri_t *uri)
|
||||||
unsigned int client_key_bytes = client_key_end - client_key_start;
|
{
|
||||||
coap_dtls_pki_t dtls_pki;
|
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
|
||||||
static char client_sni[256];
|
unsigned int client_crt_bytes = client_crt_end - client_crt_start;
|
||||||
|
unsigned int client_key_bytes = client_key_end - client_key_start;
|
||||||
|
static coap_dtls_pki_t dtls_pki;
|
||||||
|
static char client_sni[256];
|
||||||
|
|
||||||
memset (&dtls_pki, 0, sizeof(dtls_pki));
|
memset (&dtls_pki, 0, sizeof(dtls_pki));
|
||||||
dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION;
|
dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION;
|
||||||
if (ca_pem_bytes) {
|
if (ca_pem_bytes) {
|
||||||
/*
|
/*
|
||||||
* Add in additional certificate checking.
|
* Add in additional certificate checking.
|
||||||
* This list of enabled can be tuned for the specific
|
* This list of enabled can be tuned for the specific
|
||||||
* requirements - see 'man coap_encryption'.
|
* requirements - see 'man coap_encryption'.
|
||||||
*
|
*
|
||||||
* Note: A list of root ca file can be setup separately using
|
* Note: A list of root cas file can be setup separately using
|
||||||
* coap_context_set_pki_root_cas(), but the below is used to
|
* coap_context_set_pki_root_cas(), but the below is used to
|
||||||
* define what checking actually takes place.
|
* define what checking actually takes place.
|
||||||
*/
|
*/
|
||||||
dtls_pki.verify_peer_cert = 1;
|
dtls_pki.verify_peer_cert = 1;
|
||||||
dtls_pki.require_peer_cert = 1;
|
dtls_pki.check_common_ca = 1;
|
||||||
dtls_pki.allow_self_signed = 1;
|
dtls_pki.allow_self_signed = 1;
|
||||||
dtls_pki.allow_expired_certs = 1;
|
dtls_pki.allow_expired_certs = 1;
|
||||||
dtls_pki.cert_chain_validation = 1;
|
dtls_pki.cert_chain_validation = 1;
|
||||||
dtls_pki.cert_chain_verify_depth = 2;
|
dtls_pki.cert_chain_verify_depth = 2;
|
||||||
dtls_pki.check_cert_revocation = 1;
|
dtls_pki.check_cert_revocation = 1;
|
||||||
dtls_pki.allow_no_crl = 1;
|
dtls_pki.allow_no_crl = 1;
|
||||||
dtls_pki.allow_expired_crl = 1;
|
dtls_pki.allow_expired_crl = 1;
|
||||||
dtls_pki.allow_bad_md_hash = 1;
|
dtls_pki.allow_bad_md_hash = 1;
|
||||||
dtls_pki.allow_short_rsa_length = 1;
|
dtls_pki.allow_short_rsa_length = 1;
|
||||||
dtls_pki.validate_cn_call_back = verify_cn_callback;
|
dtls_pki.validate_cn_call_back = verify_cn_callback;
|
||||||
dtls_pki.cn_call_back_arg = NULL;
|
dtls_pki.cn_call_back_arg = NULL;
|
||||||
dtls_pki.validate_sni_call_back = NULL;
|
dtls_pki.validate_sni_call_back = NULL;
|
||||||
dtls_pki.sni_call_back_arg = NULL;
|
dtls_pki.sni_call_back_arg = NULL;
|
||||||
memset(client_sni, 0, sizeof(client_sni));
|
memset(client_sni, 0, sizeof(client_sni));
|
||||||
if (uri.host.length) {
|
if (uri->host.length) {
|
||||||
memcpy(client_sni, uri.host.s, MIN(uri.host.length, sizeof(client_sni)));
|
memcpy(client_sni, uri->host.s, MIN(uri->host.length, sizeof(client_sni)));
|
||||||
} else {
|
|
||||||
memcpy(client_sni, "localhost", 9);
|
|
||||||
}
|
|
||||||
dtls_pki.client_sni = client_sni;
|
|
||||||
}
|
|
||||||
dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM_BUF;
|
|
||||||
dtls_pki.pki_key.key.pem_buf.public_cert = client_crt_start;
|
|
||||||
dtls_pki.pki_key.key.pem_buf.public_cert_len = client_crt_bytes;
|
|
||||||
dtls_pki.pki_key.key.pem_buf.private_key = client_key_start;
|
|
||||||
dtls_pki.pki_key.key.pem_buf.private_key_len = client_key_bytes;
|
|
||||||
dtls_pki.pki_key.key.pem_buf.ca_cert = ca_pem_start;
|
|
||||||
dtls_pki.pki_key.key.pem_buf.ca_cert_len = ca_pem_bytes;
|
|
||||||
|
|
||||||
session = coap_new_client_session_pki(ctx, NULL, &dst_addr,
|
|
||||||
uri.scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS,
|
|
||||||
&dtls_pki);
|
|
||||||
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
|
||||||
} else {
|
} else {
|
||||||
session = coap_new_client_session(ctx, NULL, &dst_addr,
|
memcpy(client_sni, "localhost", 9);
|
||||||
uri.scheme == COAP_URI_SCHEME_COAP_TCP ? COAP_PROTO_TCP :
|
|
||||||
COAP_PROTO_UDP);
|
|
||||||
}
|
|
||||||
if (!session) {
|
|
||||||
ESP_LOGE(TAG, "coap_new_client_session() failed");
|
|
||||||
goto clean_up;
|
|
||||||
}
|
}
|
||||||
|
dtls_pki.client_sni = client_sni;
|
||||||
|
}
|
||||||
|
dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM_BUF;
|
||||||
|
dtls_pki.pki_key.key.pem_buf.public_cert = client_crt_start;
|
||||||
|
dtls_pki.pki_key.key.pem_buf.public_cert_len = client_crt_bytes;
|
||||||
|
dtls_pki.pki_key.key.pem_buf.private_key = client_key_start;
|
||||||
|
dtls_pki.pki_key.key.pem_buf.private_key_len = client_key_bytes;
|
||||||
|
dtls_pki.pki_key.key.pem_buf.ca_cert = ca_pem_start;
|
||||||
|
dtls_pki.pki_key.key.pem_buf.ca_cert_len = ca_pem_bytes;
|
||||||
|
|
||||||
coap_register_response_handler(ctx, message_handler);
|
return coap_new_client_session_pki(ctx, NULL, dst_addr,
|
||||||
|
uri->scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS,
|
||||||
|
&dtls_pki);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
||||||
|
|
||||||
request = coap_new_pdu(session);
|
static void coap_example_client(void *p)
|
||||||
|
{
|
||||||
|
coap_address_t *dst_addr;
|
||||||
|
static coap_uri_t uri;
|
||||||
|
const char *server_uri = COAP_DEFAULT_DEMO_URI;
|
||||||
|
coap_context_t *ctx = NULL;
|
||||||
|
coap_session_t *session = NULL;
|
||||||
|
coap_pdu_t *request = NULL;
|
||||||
|
unsigned char token[8];
|
||||||
|
size_t tokenlength;
|
||||||
|
|
||||||
|
/* Set up the CoAP logging */
|
||||||
|
coap_set_log_handler(coap_log_handler);
|
||||||
|
coap_set_log_level(EXAMPLE_COAP_LOG_DEFAULT_LEVEL);
|
||||||
|
|
||||||
|
/* Set up the CoAP context */
|
||||||
|
ctx = coap_new_context(NULL);
|
||||||
|
if (!ctx) {
|
||||||
|
ESP_LOGE(TAG, "coap_new_context() failed");
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
coap_context_set_block_mode(ctx,
|
||||||
|
COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY);
|
||||||
|
|
||||||
|
coap_register_response_handler(ctx, message_handler);
|
||||||
|
|
||||||
|
if (coap_split_uri((const uint8_t *)server_uri, strlen(server_uri), &uri) == -1) {
|
||||||
|
ESP_LOGE(TAG, "CoAP server uri error");
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
if (!coap_build_optlist(&uri))
|
||||||
|
goto clean_up;
|
||||||
|
|
||||||
|
dst_addr = coap_get_address(&uri);
|
||||||
|
if (!dst_addr)
|
||||||
|
goto clean_up;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that if the URI starts with just coap:// (not coaps://) the
|
||||||
|
* session will still be plain text.
|
||||||
|
*
|
||||||
|
* coaps+tcp:// is NOT yet supported by the libcoap->mbedtls interface
|
||||||
|
* so COAP_URI_SCHEME_COAPS_TCP will have failed in a test above,
|
||||||
|
* but the code is left in for completeness.
|
||||||
|
*/
|
||||||
|
if (uri.scheme == COAP_URI_SCHEME_COAPS || uri.scheme == COAP_URI_SCHEME_COAPS_TCP) {
|
||||||
|
#ifndef CONFIG_MBEDTLS_TLS_CLIENT
|
||||||
|
ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured");
|
||||||
|
goto clean_up;
|
||||||
|
#endif /* CONFIG_MBEDTLS_TLS_CLIENT */
|
||||||
|
|
||||||
|
#ifdef CONFIG_COAP_MBEDTLS_PSK
|
||||||
|
session = coap_start_psk_session(ctx, dst_addr, &uri);
|
||||||
|
#endif /* CONFIG_COAP_MBEDTLS_PSK */
|
||||||
|
|
||||||
|
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
||||||
|
session = coap_start_pki_session(ctx, dst_addr, &uri);
|
||||||
|
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
||||||
|
} else {
|
||||||
|
session = coap_new_client_session(ctx, NULL, dst_addr,
|
||||||
|
uri.scheme == COAP_URI_SCHEME_COAP_TCP ? COAP_PROTO_TCP :
|
||||||
|
COAP_PROTO_UDP);
|
||||||
|
}
|
||||||
|
if (!session) {
|
||||||
|
ESP_LOGE(TAG, "coap_new_client_session() failed");
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
request = coap_new_pdu(coap_is_mcast(dst_addr) ? COAP_MESSAGE_NON : COAP_MESSAGE_CON,
|
||||||
|
COAP_REQUEST_CODE_GET, session);
|
||||||
if (!request) {
|
if (!request) {
|
||||||
ESP_LOGE(TAG, "coap_new_pdu() failed");
|
ESP_LOGE(TAG, "coap_new_pdu() failed");
|
||||||
goto clean_up;
|
goto clean_up;
|
||||||
}
|
}
|
||||||
request->type = COAP_MESSAGE_CON;
|
/* Add in an unique token */
|
||||||
request->tid = coap_new_message_id(session);
|
coap_session_new_token(session, &tokenlength, token);
|
||||||
request->code = COAP_REQUEST_GET;
|
coap_add_token(request, tokenlength, token);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To make this a POST, you will need to do the following
|
||||||
|
* Change COAP_REQUEST_CODE_GET to COAP_REQUEST_CODE_POST for coap_new_pdu()
|
||||||
|
* Add in here a Content-Type Option based on the format of the POST text. E.G. for JSON
|
||||||
|
* u_char buf[4];
|
||||||
|
* coap_insert_optlist(&optlist,
|
||||||
|
* coap_new_optlist(COAP_OPTION_CONTENT_FORMAT,
|
||||||
|
* coap_encode_var_safe (buf, sizeof (buf),
|
||||||
|
* COAP_MEDIATYPE_APPLICATION_JSON));
|
||||||
|
* Add in here the POST data of length length. E.G.
|
||||||
|
* coap_add_data_large_request(session, request length, data, NULL, NULL);
|
||||||
|
*/
|
||||||
|
|
||||||
coap_add_optlist_pdu(request, &optlist);
|
coap_add_optlist_pdu(request, &optlist);
|
||||||
|
|
||||||
resp_wait = 1;
|
resp_wait = 1;
|
||||||
@ -405,35 +449,37 @@ static void coap_example_client(void *p)
|
|||||||
wait_ms = COAP_DEFAULT_TIME_SEC * 1000;
|
wait_ms = COAP_DEFAULT_TIME_SEC * 1000;
|
||||||
|
|
||||||
while (resp_wait) {
|
while (resp_wait) {
|
||||||
int result = coap_run_once(ctx, wait_ms > 1000 ? 1000 : wait_ms);
|
int result = coap_io_process(ctx, wait_ms > 1000 ? 1000 : wait_ms);
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
if (result >= wait_ms) {
|
if (result >= wait_ms) {
|
||||||
ESP_LOGE(TAG, "select timeout");
|
ESP_LOGE(TAG, "No response from server");
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
wait_ms -= result;
|
wait_ms -= result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean_up:
|
for(int countdown = 10; countdown >= 0; countdown--) {
|
||||||
if (optlist) {
|
ESP_LOGI(TAG, "%d... ", countdown);
|
||||||
coap_delete_optlist(optlist);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
optlist = NULL;
|
|
||||||
}
|
}
|
||||||
if (session) {
|
ESP_LOGI(TAG, "Starting again!");
|
||||||
coap_session_release(session);
|
|
||||||
}
|
|
||||||
if (ctx) {
|
|
||||||
coap_free_context(ctx);
|
|
||||||
}
|
|
||||||
coap_cleanup();
|
|
||||||
/*
|
|
||||||
* change the following line to something like sleep(2)
|
|
||||||
* if you want the request to continually be sent
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clean_up:
|
||||||
|
if (optlist) {
|
||||||
|
coap_delete_optlist(optlist);
|
||||||
|
optlist = NULL;
|
||||||
|
}
|
||||||
|
if (session) {
|
||||||
|
coap_session_release(session);
|
||||||
|
}
|
||||||
|
if (ctx) {
|
||||||
|
coap_free_context(ctx);
|
||||||
|
}
|
||||||
|
coap_cleanup();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Finished");
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
|
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
|
||||||
CONFIG_MBEDTLS_PSK_MODES=y
|
CONFIG_MBEDTLS_PSK_MODES=y
|
||||||
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
|
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
|
||||||
|
CONFIG_LWIP_NETBUF_RECVINFO=y
|
||||||
|
@ -40,6 +40,9 @@ Component config --->
|
|||||||
CoAP Configuration --->
|
CoAP Configuration --->
|
||||||
* Set encryption method definition, PSK (default) or PKI
|
* Set encryption method definition, PSK (default) or PKI
|
||||||
* Enable CoAP debugging if required
|
* Enable CoAP debugging if required
|
||||||
|
High resolution timer (esp_timer) --->
|
||||||
|
* Hardware timer to use for esp_timer - change if required (FRC2 for QEMU)
|
||||||
|
|
||||||
|
|
||||||
### Build and Flash
|
### Build and Flash
|
||||||
|
|
||||||
@ -77,7 +80,11 @@ If a CoAP client queries the `/Espressif` resource, CoAP server will return `"He
|
|||||||
until a CoAP client does a PUT with different data.
|
until a CoAP client does a PUT with different data.
|
||||||
|
|
||||||
## libcoap Documentation
|
## libcoap Documentation
|
||||||
This can be found at https://libcoap.net/doc/reference/4.2.0/
|
This can be found at [libcoap Documentation](https://libcoap.net/documentation.html).
|
||||||
|
The current API is 4.3.0.
|
||||||
|
|
||||||
|
## libcoap Specific Issues
|
||||||
|
These can be raised at [libcoap Issues](https://github.com/obgm/libcoap/issues).
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
* Please make sure CoAP client fetchs or puts data under path: `/Espressif` or
|
* Please make sure CoAP client fetchs or puts data under path: `/Espressif` or
|
||||||
|
@ -8,4 +8,54 @@ menu "Example CoAP Server Configuration"
|
|||||||
The Preshared Key to use to encrypt the communicatons. The same key must be
|
The Preshared Key to use to encrypt the communicatons. The same key must be
|
||||||
used at both ends of the CoAP connection, and the CoaP client must request
|
used at both ends of the CoAP connection, and the CoaP client must request
|
||||||
an URI prefixed with coaps:// instead of coap:// for DTLS to be used.
|
an URI prefixed with coaps:// instead of coap:// for DTLS to be used.
|
||||||
|
|
||||||
|
choice EXAMPLE_COAP_MCAST_IP_MODE
|
||||||
|
prompt "Receive Multicast IP type"
|
||||||
|
help
|
||||||
|
Example can receive multicast IPV4, IPV6, both or none.
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MCAST_NONE
|
||||||
|
bool "None"
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MCAST_IPV4_V6
|
||||||
|
bool "IPV4 & IPV6"
|
||||||
|
select EXAMPLE_COAP_MCAST_IPV4
|
||||||
|
select EXAMPLE_COAP_MCAST_IPV6
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MCAST_IPV4_ONLY
|
||||||
|
bool "IPV4"
|
||||||
|
select EXAMPLE_COAP_MCAST_IPV4
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MCAST_IPV6_ONLY
|
||||||
|
bool "IPV6"
|
||||||
|
select EXAMPLE_COAP_MCAST_IPV6
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MCAST_IPV4
|
||||||
|
bool
|
||||||
|
config EXAMPLE_COAP_MCAST_IPV6
|
||||||
|
bool
|
||||||
|
select EXAMPLE_CONNECT_IPV6 if IDF_TARGET_ESP32
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MULTICAST_IPV4_ADDR
|
||||||
|
string "CoAP Multicast IPV4 Address (receive)"
|
||||||
|
default "224.0.1.187"
|
||||||
|
depends on EXAMPLE_COAP_MCAST_IPV4
|
||||||
|
help
|
||||||
|
IPV4 multicast address to receive multicast traffic on.
|
||||||
|
|
||||||
|
The default CoAP IPV4 address is 224.0.1.187.
|
||||||
|
|
||||||
|
config EXAMPLE_COAP_MULTICAST_IPV6_ADDR
|
||||||
|
string "CoAP Multicast IPV6 Address (receive)"
|
||||||
|
default "FF02::FD"
|
||||||
|
depends on EXAMPLE_COAP_MCAST_IPV6
|
||||||
|
help
|
||||||
|
IPV6 multicast address to receive multicast traffic on.
|
||||||
|
|
||||||
|
The default CoAP FF02::FD address is a link-local multicast address.
|
||||||
|
Consult IPV6 specifications or documentation for information about
|
||||||
|
meaning of different IPV6 multicast ranges.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIID3DCCA0WgAwIBAgIJAMnlgL1czsmjMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
|
MIICDzCCAbSgAwIBAgIIAbOUoVFDz/QwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
|
||||||
VQQGEwJGUjEPMA0GA1UECAwGUmFkaXVzMRIwEAYDVQQHDAlTb21ld2hlcmUxFTAT
|
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
|
||||||
BgNVBAoMDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs
|
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
|
||||||
ZS5jb20xJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X
|
MDMzWhcNMjExMTExMTAzMDMzWjBaMQ4wDAYDVQQDEwVjZi1jYTEUMBIGA1UECxML
|
||||||
DTE3MDYwNzA4MDY0OVoXDTI3MDYwNTA4MDY0OVowgZMxCzAJBgNVBAYTAkZSMQ8w
|
Q2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZPdHRh
|
||||||
DQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMGA1UECgwMRXhh
|
d2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7/3EXOZn
|
||||||
bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG
|
GZXNEIj7LuQAMZ8lfRYSCnpME1TBjKjZPtVeztLtGWgkkLvIX11pAJcBh51cpi7Z
|
||||||
A1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcN
|
fQtGpVE9CLOh6aNgMF4wHQYDVR0OBBYEFEvf57UcJhYYkx14twkeitd691fVMAsG
|
||||||
AQEBBQADgY0AMIGJAoGBALpWR23fn/TmHxsXsHdrydzPSd17fZkc71WsaicgQR66
|
A1UdDwQEAwIBBjAPBgNVHRMECDAGAQH/AgEBMB8GA1UdIwQYMBaAFAsi3KbVERiK
|
||||||
1tIVYb22UWGfj9KPM8THMsV74ew4ZkaQ39qvU0iuQIRrKARFHFok+vbaecgWMeWe
|
JzFCfC/GVrYksGzEMAwGCCqGSM49BAMCBQADRwAwRAIgc5nVF/5Pip0XB17IZXqi
|
||||||
vGIqdnmyB9gJYaFOKgtSkfXsu2ddsqdvLYwcDbczrq8X9yEXpN6mnxXeCcPG4F0p
|
V84FXanWdn9Z0SiPdpOgvZMCIH13vL9tkCCjPN3tg3TYRY/bzyGohFGBcTrrEtUr
|
||||||
AgMBAAGjggE0MIIBMDAdBgNVHQ4EFgQUgigpdAUpONoDq0pQ3yfxrslCSpcwgcgG
|
rVIm
|
||||||
A1UdIwSBwDCBvYAUgigpdAUpONoDq0pQ3yfxrslCSpehgZmkgZYwgZMxCzAJBgNV
|
-----END CERTIFICATE-----
|
||||||
BAYTAkZSMQ8wDQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMG
|
-----BEGIN CERTIFICATE-----
|
||||||
A1UECgwMRXhhbXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxl
|
MIIB4DCCAYWgAwIBAgIIQR8ro8AQ02AwDAYIKoZIzj0EAwIFADBcMRAwDgYDVQQD
|
||||||
LmNvbTEmMCQGA1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCCQDJ
|
EwdjZi1yb290MRQwEgYDVQQLEwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBz
|
||||||
5YC9XM7JozAMBgNVHRMEBTADAQH/MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly93
|
ZSBJb1QxDzANBgNVBAcTBk90dGF3YTELMAkGA1UEBhMCQ0EwHhcNMjAxMTExMTAz
|
||||||
d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZIhvcNAQELBQADgYEA
|
MDMyWhcNMjExMTExMTAzMDMyWjBcMRAwDgYDVQQDEwdjZi1yb290MRQwEgYDVQQL
|
||||||
euxOBPInSJRKAIseMxPmAabtAqKNslZSmpG4He3lkKt+HM3jfznUt3psmD7j1hFW
|
EwtDYWxpZm9ybml1bTEUMBIGA1UEChMLRWNsaXBzZSBJb1QxDzANBgNVBAcTBk90
|
||||||
S4l7KXzzajvaGYybDq5N9MqrDjhGn3VXZqOLMUNDL7OQq96TzgqsTBT1dmVSbNlt
|
dGF3YTELMAkGA1UEBhMCQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATZ1BRM
|
||||||
PQgiAeKAk3tmH4lRRi9MTBSyJ6I92JYcS5H6Bs4ZwCc=
|
T1//Fzh9sneRZNwS4kgCxN1PvgwT271qCpYqyxnjLEa38AP1IAanhpiD/OkVc0Zd
|
||||||
|
7NgDPCw7n94EULMyoy8wLTAdBgNVHQ4EFgQUCyLcptURGIonMUJ8L8ZWtiSwbMQw
|
||||||
|
DAYDVR0TBAUwAwEB/zAMBggqhkjOPQQDAgUAA0cAMEQCIAdLEgcUWdpAl9jwdJiz
|
||||||
|
/cHW7/CBIWEvqiQfzE+XLyLOAiAvuxSdOtSDjh2aC5qEjUCH8CSKCxWB74j23tmp
|
||||||
|
aqPH4A==
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
@ -1,70 +1,13 @@
|
|||||||
Certificate:
|
|
||||||
Data:
|
|
||||||
Version: 3 (0x2)
|
|
||||||
Serial Number: 47 (0x2f)
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
Issuer: C=FR, ST=Radius, L=Somewhere, O=Example Inc./emailAddress=admin@example.com, CN=Example Certificate Authority
|
|
||||||
Validity
|
|
||||||
Not Before: Jun 7 08:06:49 2017 GMT
|
|
||||||
Not After : Jun 5 08:06:49 2027 GMT
|
|
||||||
Subject: C=FR, ST=Radius, O=Example Inc., CN=Example Server Certificate/emailAddress=admin@example.com
|
|
||||||
Subject Public Key Info:
|
|
||||||
Public Key Algorithm: rsaEncryption
|
|
||||||
Public-Key: (2048 bit)
|
|
||||||
Modulus:
|
|
||||||
00:c9:d8:e2:e0:75:91:83:87:d8:c8:80:c6:20:4d:
|
|
||||||
e9:14:24:30:98:33:53:fa:56:0e:ec:9a:43:7f:87:
|
|
||||||
a9:22:94:26:06:c7:ac:b5:d9:ec:55:06:81:b7:0d:
|
|
||||||
c9:24:51:49:fa:47:fb:4b:4e:fc:ed:75:8a:e1:28:
|
|
||||||
32:bc:c5:e0:4c:45:c4:58:60:15:67:1e:6b:40:19:
|
|
||||||
3f:f0:ab:92:61:92:2d:71:10:2e:f2:eb:bc:81:2f:
|
|
||||||
5a:3b:74:ca:5f:fd:e0:ee:d1:d9:07:6a:6c:20:c0:
|
|
||||||
07:88:b4:8b:0f:ad:1e:c9:4f:7c:11:98:37:89:15:
|
|
||||||
de:24:b1:11:1a:7c:97:4a:cf:f3:c8:cb:79:9e:9c:
|
|
||||||
c3:71:da:a6:94:97:f5:95:fd:61:06:44:e2:3f:12:
|
|
||||||
43:0b:1d:33:48:91:d2:ce:4f:97:a1:ed:6a:30:c7:
|
|
||||||
5d:98:b5:6e:0a:b7:4f:d9:03:ec:80:76:09:b0:40:
|
|
||||||
a1:a1:af:ab:2a:59:c4:0f:56:22:bc:be:14:be:18:
|
|
||||||
df:10:7d:5d:22:bf:e5:04:77:7a:75:6b:3e:eb:6d:
|
|
||||||
20:a1:a7:60:d4:f1:87:9d:9f:60:b9:d3:db:2c:25:
|
|
||||||
f4:91:4a:f1:d2:40:e5:a1:10:88:a0:41:5a:98:40:
|
|
||||||
ca:15:d7:e3:e6:3e:c0:6a:d5:46:b2:b4:90:b4:ae:
|
|
||||||
3b:e3
|
|
||||||
Exponent: 65537 (0x10001)
|
|
||||||
X509v3 extensions:
|
|
||||||
X509v3 Extended Key Usage:
|
|
||||||
TLS Web Server Authentication
|
|
||||||
X509v3 CRL Distribution Points:
|
|
||||||
|
|
||||||
Full Name:
|
|
||||||
URI:http://www.example.com/example_ca.crl
|
|
||||||
|
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
|
||||||
a4:25:21:51:0b:22:6c:63:8d:a9:c1:4f:04:33:69:79:34:f0:
|
|
||||||
36:dd:8f:6a:27:5f:07:a2:1d:ef:8b:f0:96:e6:e7:a3:b8:3b:
|
|
||||||
85:5e:3f:26:43:8a:8e:95:58:9c:a6:db:9c:51:bf:ea:53:16:
|
|
||||||
3e:c1:a8:11:1a:c6:cf:0e:a1:17:18:64:d2:05:f1:c0:9c:a6:
|
|
||||||
2b:16:c4:29:54:03:d2:17:bd:15:74:d6:ad:8a:8f:2d:cc:27:
|
|
||||||
3b:88:88:f2:ea:d0:a2:cb:e9:42:57:df:26:9f:8a:a2:02:2f:
|
|
||||||
35:b6:19:1d:26:43:44:af:12:4b:bc:b9:84:50:02:fd:1d:fa:
|
|
||||||
50:e8
|
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIDWTCCAsKgAwIBAgIBLzANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UEBhMCRlIx
|
MIICAzCCAaagAwIBAgIJANqCHDjOKHh+MAwGCCqGSM49BAMCBQAwWjEOMAwGA1UE
|
||||||
DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRUwEwYDVQQKDAxF
|
AxMFY2YtY2ExFDASBgNVBAsTC0NhbGlmb3JuaXVtMRQwEgYDVQQKEwtFY2xpcHNl
|
||||||
eGFtcGxlIEluYy4xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMSYw
|
IElvVDEPMA0GA1UEBxMGT3R0YXdhMQswCQYDVQQGEwJDQTAeFw0yMDExMTExMDMw
|
||||||
JAYDVQQDDB1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA2MDcw
|
MzRaFw0yMTExMTExMDMwMzRaMF4xEjAQBgNVBAMTCWNmLXNlcnZlcjEUMBIGA1UE
|
||||||
ODA2NDlaFw0yNzA2MDUwODA2NDlaMHwxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZS
|
CxMLQ2FsaWZvcm5pdW0xFDASBgNVBAoTC0VjbGlwc2UgSW9UMQ8wDQYDVQQHEwZP
|
||||||
YWRpdXMxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEjMCEGA1UEAwwaRXhhbXBsZSBT
|
dHRhd2ExCzAJBgNVBAYTAkNBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+obM
|
||||||
ZXJ2ZXIgQ2VydGlmaWNhdGUxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUu
|
gHmMB7zS4KArciXPD7CrvgEYqlnAf7NOTdb54RbTr4qEpPL+OJ6Pg8VhrF4hGEne
|
||||||
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydji4HWRg4fYyIDG
|
T6Aa4qqpmTkxmfT0vqNPME0wHQYDVR0OBBYEFE4XpfFad+F3+RcwI+s1cmJbTZWG
|
||||||
IE3pFCQwmDNT+lYO7JpDf4epIpQmBsestdnsVQaBtw3JJFFJ+kf7S0787XWK4Sgy
|
MAsGA1UdDwQEAwIHgDAfBgNVHSMEGDAWgBRL3+e1HCYWGJMdeLcJHorXevdX1TAM
|
||||||
vMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSL
|
BggqhkjOPQQDAgUAA0kAMEYCIQCEo+O5zqYKdwi/ElB4wfNVIf76P1OhIXAT5CHc
|
||||||
D60eyU98EZg3iRXeJLERGnyXSs/zyMt5npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHS
|
3ebBPQIhAN6UhCgQ0av6kf7INCazV3KmN7HmPXARaY4YKWsRwsg+
|
||||||
zk+Xoe1qMMddmLVuCrdP2QPsgHYJsEChoa+rKlnED1YivL4UvhjfEH1dIr/lBHd6
|
|
||||||
dWs+620goadg1PGHnZ9gudPbLCX0kUrx0kDloRCIoEFamEDKFdfj5j7AatVGsrSQ
|
|
||||||
tK474wIDAQABo08wTTATBgNVHSUEDDAKBggrBgEFBQcDATA2BgNVHR8ELzAtMCug
|
|
||||||
KaAnhiVodHRwOi8vd3d3LmV4YW1wbGUuY29tL2V4YW1wbGVfY2EuY3JsMA0GCSqG
|
|
||||||
SIb3DQEBBQUAA4GBAKQlIVELImxjjanBTwQzaXk08Dbdj2onXweiHe+L8Jbm56O4
|
|
||||||
O4VePyZDio6VWJym25xRv+pTFj7BqBEaxs8OoRcYZNIF8cCcpisWxClUA9IXvRV0
|
|
||||||
1q2Kjy3MJzuIiPLq0KLL6UJX3yafiqICLzW2GR0mQ0SvEku8uYRQAv0d+lDo
|
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
@ -1,27 +1,4 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
-----BEGIN PRIVATE KEY-----
|
||||||
MIIEpAIBAAKCAQEAydji4HWRg4fYyIDGIE3pFCQwmDNT+lYO7JpDf4epIpQmBses
|
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCLBQT66xp2w4+1K+Ai
|
||||||
tdnsVQaBtw3JJFFJ+kf7S0787XWK4SgyvMXgTEXEWGAVZx5rQBk/8KuSYZItcRAu
|
/TXEC8tQZBxl9brFyK4F7AQNGw==
|
||||||
8uu8gS9aO3TKX/3g7tHZB2psIMAHiLSLD60eyU98EZg3iRXeJLERGnyXSs/zyMt5
|
-----END PRIVATE KEY-----
|
||||||
npzDcdqmlJf1lf1hBkTiPxJDCx0zSJHSzk+Xoe1qMMddmLVuCrdP2QPsgHYJsECh
|
|
||||||
oa+rKlnED1YivL4UvhjfEH1dIr/lBHd6dWs+620goadg1PGHnZ9gudPbLCX0kUrx
|
|
||||||
0kDloRCIoEFamEDKFdfj5j7AatVGsrSQtK474wIDAQABAoIBAQC2kGDEPBJdMSW2
|
|
||||||
VCLfXRiPixwYzXQLXIMrJWwfkQg9qlmqkDd6U50aWkRA2UswegW7RhfYSZ0i+cmf
|
|
||||||
VMhvTVpOIlwwwtcY6b5/v1bBy60eaySGuuh79xQMlFO8qynQIMStvUfbGTqrdIRb
|
|
||||||
9VBB4YeS9T12fILejtTZwv2BQ2dj1Y1SCay6Ri85UzJqSClRKgHISybvVdLNjPvP
|
|
||||||
0TRFBr57zyjL6WE8teKiKchzQko2u86No5uBCdKGsrAkrsdcR0YqlM/pZxd3VKNm
|
|
||||||
+eny0k+dZZlvcPxzkzP4hEp9+Rw5rP9/s3s/cCwvuuC5JO32ATBWKCbTvPv/XPDb
|
|
||||||
MdSJtOshAoGBAPzk0eswkcbFYtpnpBNmBAr1dtAdW1lfjUI2ucMMwt7Wns0P/tt+
|
|
||||||
gq6Hi1wTaGP0l/dIECgeHwjtWj31ZJjQtFJ1y/kafxo4o9cA8vCydpdvSZaldAfg
|
|
||||||
sbLlDTDYzEpelaDIbNQBBXFoC5U9JlBhBsIFCL5Z8ZuIeFPsb7t5wwuHAoGBAMxT
|
|
||||||
jyWfNm1uNxp1xgCnrRsLPQPVnURrSFAqcHrECqRu3F7sozTN7q/cZViemxPvVDGQ
|
|
||||||
p9c+9bHwaYvW4trO5qDHJ++gGwm5L52bMAY1VUfeTt67fqrey43XpdmzcTX1V9Uj
|
|
||||||
QWawPUCSDzFjL1MjfCIejtyYf5ash53vj+T8r/vFAoGAA/OPVB1uKazr3n3AEo2F
|
|
||||||
gqZTNO1AgCT+EArK3EFWyiSQVqPpV4SihheYFdg3yVgJB9QYbIgL9BfBUTaEW97m
|
|
||||||
8mLkzP+c/Mvlw3ZAVYJ0V+llPPVY2saoACOUES9SAdd4fwqiqK1baGo3xB0wfBEI
|
|
||||||
CgAKIu9E1ylKuAT5ufQtGAECgYEAtP/kU5h5N3El4QupTdU7VDSdZTMqsHw0v8cI
|
|
||||||
gsf9AXKvRmtrnBA8u46KPHmruHoO5CVXeSZtsaXdaaH+rYQQ6yXg67WxnehtFLlv
|
|
||||||
TmCaXiLBTS9cYvMf8FOyuGnsBLeEietEOTov2G5KhR5uwsAxa2wUc7endor5S9/2
|
|
||||||
YQuyvV0CgYALbiFpILd5l1ip65eE6JdA3hfttUbV2j2NSW12ej69vqbeOfaSgNse
|
|
||||||
uYCcXFsBbQPhNPwA+4d1oCe8SyXZg1f7gE812z2Tyr/3vdVnNZlitoxhsHmGiyS7
|
|
||||||
gZdaTYCb78l9z0EBdaCVvA16owEle4SR6f9eCwzSI0WPOUra+x/hrA==
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
|
@ -29,15 +29,10 @@
|
|||||||
|
|
||||||
#include "protocol_examples_common.h"
|
#include "protocol_examples_common.h"
|
||||||
|
|
||||||
#if 1
|
#include "coap3/coap.h"
|
||||||
/* Needed until coap_dtls.h becomes a part of libcoap proper */
|
|
||||||
#include "libcoap.h"
|
|
||||||
#include "coap_dtls.h"
|
|
||||||
#endif
|
|
||||||
#include "coap.h"
|
|
||||||
|
|
||||||
/* The examples use simple Pre-Shared-Key configuration that you can set via
|
/* The examples use simple Pre-Shared-Key configuration that you can set via
|
||||||
'make menuconfig'.
|
'idf.py menuconfig'.
|
||||||
|
|
||||||
If you'd rather not, just change the below entries to strings with
|
If you'd rather not, just change the below entries to strings with
|
||||||
the config you want - ie #define EXAMPLE_COAP_PSK_KEY "some-agreed-preshared-key"
|
the config you want - ie #define EXAMPLE_COAP_PSK_KEY "some-agreed-preshared-key"
|
||||||
@ -49,7 +44,7 @@
|
|||||||
#define EXAMPLE_COAP_PSK_KEY CONFIG_EXAMPLE_COAP_PSK_KEY
|
#define EXAMPLE_COAP_PSK_KEY CONFIG_EXAMPLE_COAP_PSK_KEY
|
||||||
|
|
||||||
/* The examples use CoAP Logging Level that
|
/* The examples use CoAP Logging Level that
|
||||||
you can set via 'make menuconfig'.
|
you can set via 'idf.py menuconfig'.
|
||||||
|
|
||||||
If you'd rather not, just change the below entry to a value
|
If you'd rather not, just change the below entry to a value
|
||||||
that is between 0 and 7 with
|
that is between 0 and 7 with
|
||||||
@ -67,8 +62,10 @@ static int espressif_data_len = 0;
|
|||||||
Server cert, taken from coap_server.crt
|
Server cert, taken from coap_server.crt
|
||||||
Server key, taken from coap_server.key
|
Server key, taken from coap_server.key
|
||||||
|
|
||||||
The PEM, CRT and KEY file are examples taken from the wpa2 enterprise
|
The PEM, CRT and KEY file are examples taken from
|
||||||
example.
|
https://github.com/eclipse/californium/tree/master/demo-certs/src/main/resources
|
||||||
|
as the Certificate test (by default) for the coap_client is against the
|
||||||
|
californium server.
|
||||||
|
|
||||||
To embed it in the app binary, the PEM, CRT and KEY file is named
|
To embed it in the app binary, the PEM, CRT and KEY file is named
|
||||||
in the component.mk COMPONENT_EMBED_TXTFILES variable.
|
in the component.mk COMPONENT_EMBED_TXTFILES variable.
|
||||||
@ -87,39 +84,42 @@ extern uint8_t server_key_end[] asm("_binary_coap_server_key_end");
|
|||||||
* The resource handler
|
* The resource handler
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
hnd_espressif_get(coap_context_t *ctx, coap_resource_t *resource,
|
hnd_espressif_get(coap_resource_t *resource,
|
||||||
coap_session_t *session,
|
coap_session_t *session,
|
||||||
coap_pdu_t *request, coap_binary_t *token,
|
const coap_pdu_t *request,
|
||||||
coap_string_t *query, coap_pdu_t *response)
|
const coap_string_t *query,
|
||||||
|
coap_pdu_t *response)
|
||||||
{
|
{
|
||||||
coap_add_data_blocked_response(resource, session, request, response, token,
|
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
|
||||||
COAP_MEDIATYPE_TEXT_PLAIN, 0,
|
coap_add_data_large_response(resource, session, request, response,
|
||||||
(size_t)espressif_data_len,
|
query, COAP_MEDIATYPE_TEXT_PLAIN, 60, 0,
|
||||||
(const u_char *)espressif_data);
|
(size_t)espressif_data_len,
|
||||||
|
(const u_char *)espressif_data,
|
||||||
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hnd_espressif_put(coap_context_t *ctx,
|
hnd_espressif_put(coap_resource_t *resource,
|
||||||
coap_resource_t *resource,
|
|
||||||
coap_session_t *session,
|
coap_session_t *session,
|
||||||
coap_pdu_t *request,
|
const coap_pdu_t *request,
|
||||||
coap_binary_t *token,
|
const coap_string_t *query,
|
||||||
coap_string_t *query,
|
|
||||||
coap_pdu_t *response)
|
coap_pdu_t *response)
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
unsigned char *data;
|
size_t offset;
|
||||||
|
size_t total;
|
||||||
|
const unsigned char *data;
|
||||||
|
|
||||||
coap_resource_notify_observers(resource, NULL);
|
coap_resource_notify_observers(resource, NULL);
|
||||||
|
|
||||||
if (strcmp (espressif_data, INITIAL_DATA) == 0) {
|
if (strcmp (espressif_data, INITIAL_DATA) == 0) {
|
||||||
response->code = COAP_RESPONSE_CODE(201);
|
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
|
||||||
} else {
|
} else {
|
||||||
response->code = COAP_RESPONSE_CODE(204);
|
coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* coap_get_data() sets size to 0 on error */
|
/* coap_get_data_large() sets size to 0 on error */
|
||||||
(void)coap_get_data(request, &size, &data);
|
(void)coap_get_data_large(request, &size, &data, &offset, &total);
|
||||||
|
|
||||||
if (size == 0) { /* re-init */
|
if (size == 0) { /* re-init */
|
||||||
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
|
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
|
||||||
@ -131,18 +131,16 @@ hnd_espressif_put(coap_context_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hnd_espressif_delete(coap_context_t *ctx,
|
hnd_espressif_delete(coap_resource_t *resource,
|
||||||
coap_resource_t *resource,
|
|
||||||
coap_session_t *session,
|
coap_session_t *session,
|
||||||
coap_pdu_t *request,
|
const coap_pdu_t *request,
|
||||||
coap_binary_t *token,
|
const coap_string_t *query,
|
||||||
coap_string_t *query,
|
|
||||||
coap_pdu_t *response)
|
coap_pdu_t *response)
|
||||||
{
|
{
|
||||||
coap_resource_notify_observers(resource, NULL);
|
coap_resource_notify_observers(resource, NULL);
|
||||||
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
|
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
|
||||||
espressif_data_len = strlen(espressif_data);
|
espressif_data_len = strlen(espressif_data);
|
||||||
response->code = COAP_RESPONSE_CODE(202);
|
coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
||||||
@ -163,6 +161,18 @@ verify_cn_callback(const char *cn,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
#endif /* CONFIG_COAP_MBEDTLS_PKI */
|
||||||
|
|
||||||
|
static void
|
||||||
|
coap_log_handler (coap_log_t level, const char *message)
|
||||||
|
{
|
||||||
|
uint32_t esp_level = ESP_LOG_INFO;
|
||||||
|
char *cp = strchr(message, '\n');
|
||||||
|
|
||||||
|
if (cp)
|
||||||
|
ESP_LOG_LEVEL(esp_level, TAG, "%.*s", (int)(cp-message), message);
|
||||||
|
else
|
||||||
|
ESP_LOG_LEVEL(esp_level, TAG, "%s", message);
|
||||||
|
}
|
||||||
|
|
||||||
static void coap_example_server(void *p)
|
static void coap_example_server(void *p)
|
||||||
{
|
{
|
||||||
coap_context_t *ctx = NULL;
|
coap_context_t *ctx = NULL;
|
||||||
@ -171,6 +181,7 @@ static void coap_example_server(void *p)
|
|||||||
|
|
||||||
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
|
snprintf(espressif_data, sizeof(espressif_data), INITIAL_DATA);
|
||||||
espressif_data_len = strlen(espressif_data);
|
espressif_data_len = strlen(espressif_data);
|
||||||
|
coap_set_log_handler(coap_log_handler);
|
||||||
coap_set_log_level(EXAMPLE_COAP_LOG_DEFAULT_LEVEL);
|
coap_set_log_level(EXAMPLE_COAP_LOG_DEFAULT_LEVEL);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -179,15 +190,16 @@ static void coap_example_server(void *p)
|
|||||||
|
|
||||||
/* Prepare the CoAP server socket */
|
/* Prepare the CoAP server socket */
|
||||||
coap_address_init(&serv_addr);
|
coap_address_init(&serv_addr);
|
||||||
serv_addr.addr.sin.sin_family = AF_INET;
|
serv_addr.addr.sin6.sin6_family = AF_INET6;
|
||||||
serv_addr.addr.sin.sin_addr.s_addr = INADDR_ANY;
|
serv_addr.addr.sin6.sin6_port = htons(COAP_DEFAULT_PORT);
|
||||||
serv_addr.addr.sin.sin_port = htons(COAP_DEFAULT_PORT);
|
|
||||||
|
|
||||||
ctx = coap_new_context(NULL);
|
ctx = coap_new_context(NULL);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
ESP_LOGE(TAG, "coap_new_context() failed");
|
ESP_LOGE(TAG, "coap_new_context() failed");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
coap_context_set_block_mode(ctx,
|
||||||
|
COAP_BLOCK_USE_LIBCOAP|COAP_BLOCK_SINGLE_BODY);
|
||||||
#ifdef CONFIG_COAP_MBEDTLS_PSK
|
#ifdef CONFIG_COAP_MBEDTLS_PSK
|
||||||
/* Need PSK setup before we set up endpoints */
|
/* Need PSK setup before we set up endpoints */
|
||||||
coap_context_set_psk(ctx, "CoAP",
|
coap_context_set_psk(ctx, "CoAP",
|
||||||
@ -196,6 +208,7 @@ static void coap_example_server(void *p)
|
|||||||
#endif /* CONFIG_COAP_MBEDTLS_PSK */
|
#endif /* CONFIG_COAP_MBEDTLS_PSK */
|
||||||
|
|
||||||
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
#ifdef CONFIG_COAP_MBEDTLS_PKI
|
||||||
|
/* Need PKI setup before we set up endpoints */
|
||||||
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
|
unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start;
|
||||||
unsigned int server_crt_bytes = server_crt_end - server_crt_start;
|
unsigned int server_crt_bytes = server_crt_end - server_crt_start;
|
||||||
unsigned int server_key_bytes = server_key_end - server_key_start;
|
unsigned int server_key_bytes = server_key_end - server_key_start;
|
||||||
@ -214,7 +227,7 @@ static void coap_example_server(void *p)
|
|||||||
* define what checking actually takes place.
|
* define what checking actually takes place.
|
||||||
*/
|
*/
|
||||||
dtls_pki.verify_peer_cert = 1;
|
dtls_pki.verify_peer_cert = 1;
|
||||||
dtls_pki.require_peer_cert = 1;
|
dtls_pki.check_common_ca = 1;
|
||||||
dtls_pki.allow_self_signed = 1;
|
dtls_pki.allow_self_signed = 1;
|
||||||
dtls_pki.allow_expired_certs = 1;
|
dtls_pki.allow_expired_certs = 1;
|
||||||
dtls_pki.cert_chain_validation = 1;
|
dtls_pki.cert_chain_validation = 1;
|
||||||
@ -256,7 +269,7 @@ static void coap_example_server(void *p)
|
|||||||
/* This is not critical as unencrypted support is still available */
|
/* This is not critical as unencrypted support is still available */
|
||||||
ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured");
|
ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured");
|
||||||
#else /* CONFIG_MBEDTLS_TLS_SERVER */
|
#else /* CONFIG_MBEDTLS_TLS_SERVER */
|
||||||
serv_addr.addr.sin.sin_port = htons(COAPS_DEFAULT_PORT);
|
serv_addr.addr.sin6.sin6_port = htons(COAPS_DEFAULT_PORT);
|
||||||
ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_DTLS);
|
ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_DTLS);
|
||||||
if (!ep) {
|
if (!ep) {
|
||||||
ESP_LOGE(TAG, "dtls: coap_new_endpoint() failed");
|
ESP_LOGE(TAG, "dtls: coap_new_endpoint() failed");
|
||||||
@ -267,7 +280,7 @@ static void coap_example_server(void *p)
|
|||||||
/* This is not critical as unencrypted support is still available */
|
/* This is not critical as unencrypted support is still available */
|
||||||
ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured");
|
ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured");
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_COAP_MBEDTLS_PSK CONFIG_COAP_MBEDTLS_PKI */
|
#endif /* CONFIG_COAP_MBEDTLS_PSK || CONFIG_COAP_MBEDTLS_PKI */
|
||||||
resource = coap_resource_init(coap_make_str_const("Espressif"), 0);
|
resource = coap_resource_init(coap_make_str_const("Espressif"), 0);
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
ESP_LOGE(TAG, "coap_resource_init() failed");
|
ESP_LOGE(TAG, "coap_resource_init() failed");
|
||||||
@ -280,10 +293,26 @@ static void coap_example_server(void *p)
|
|||||||
coap_resource_set_get_observable(resource, 1);
|
coap_resource_set_get_observable(resource, 1);
|
||||||
coap_add_resource(ctx, resource);
|
coap_add_resource(ctx, resource);
|
||||||
|
|
||||||
|
#if defined(CONFIG_EXAMPLE_COAP_MCAST_IPV4) || defined(CONFIG_EXAMPLE_COAP_MCAST_IPV6)
|
||||||
|
esp_netif_t *netif = NULL;
|
||||||
|
for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) {
|
||||||
|
char buf[8];
|
||||||
|
netif = esp_netif_next(netif);
|
||||||
|
esp_netif_get_netif_impl_name(netif, buf);
|
||||||
|
#if defined(CONFIG_EXAMPLE_COAP_MCAST_IPV4)
|
||||||
|
coap_join_mcast_group_intf(ctx, CONFIG_EXAMPLE_COAP_MULTICAST_IPV4_ADDR, buf);
|
||||||
|
#endif /* CONFIG_EXAMPLE_COAP_MCAST_IPV4 */
|
||||||
|
#if defined(CONFIG_EXAMPLE_COAP_MCAST_IPV6)
|
||||||
|
/* When adding IPV6 esp-idf requires ifname param to be filled in */
|
||||||
|
coap_join_mcast_group_intf(ctx, CONFIG_EXAMPLE_COAP_MULTICAST_IPV6_ADDR, buf);
|
||||||
|
#endif /* CONFIG_EXAMPLE_COAP_MCAST_IPV6 */
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_EXAMPLE_COAP_MCAST_IPV4 || CONFIG_EXAMPLE_COAP_MCAST_IPV6 */
|
||||||
|
|
||||||
wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
|
wait_ms = COAP_RESOURCE_CHECK_TIME * 1000;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int result = coap_run_once(ctx, wait_ms);
|
int result = coap_io_process(ctx, wait_ms);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
break;
|
break;
|
||||||
} else if (result && (unsigned)result < wait_ms) {
|
} else if (result && (unsigned)result < wait_ms) {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
|
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
|
||||||
CONFIG_MBEDTLS_PSK_MODES=y
|
CONFIG_MBEDTLS_PSK_MODES=y
|
||||||
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
|
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
|
||||||
|
CONFIG_LWIP_NETBUF_RECVINFO=y
|
||||||
|
Loading…
Reference in New Issue
Block a user