diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c65f08c..c4a17e84 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -127,7 +127,7 @@ jobs: $GITHUB_WORKSPACE/configure --disable-documentation --disable-examples --disable-tests --disable-dtls - name: compile run: | - make -C examples/${{matrix.OS}} + make -C examples/${{matrix.OS}} EXTRA_CFLAGS=-Werror ms-build: runs-on: windows-latest diff --git a/examples/lwip/Makefile b/examples/lwip/Makefile index c255795e..b03e10ea 100644 --- a/examples/lwip/Makefile +++ b/examples/lwip/Makefile @@ -22,8 +22,23 @@ WITH_LWIP_CONTRIB_BRANCH=STABLE-2_1_0_RELEASE LDLIBS := $(shell if [ -f $(libcoap_dir)/config.log ] ; then \ grep ac_cv_search_clock_gettime=- $(libcoap_dir)/config.log|cut -d= -f2 ; fi) -all: lib-server lib-client lwip lwip-contrib check-version \ - $(coap_include_dir)/coap.h server client +# +# Remove the 4 -dtls checks from "all" if you do not want DTLS included in +# some of the built objects. +# +all: lwip \ + lwip-contrib \ + check-version \ + check-tinydtls \ + $(coap_include_dir)/coap.h \ + lib-server \ + server \ + lib-client \ + client \ + lib-server-dtls \ + server-dtls \ + lib-client-dtls \ + client-dtls lwip: git clone --depth 1 git://git.savannah.nongnu.org/lwip.git -b $(WITH_LWIP_BRANCH) @@ -61,11 +76,37 @@ check-version: fi ; \ fi) +# base libcoap git has empty ext/tinydtls +check-tinydtls: + @(if [ ! -d $(libcoap_dir)/ext/tinydtls ] ; then \ + mkdir -p $(libcoap_dir)/ext ; \ + (cd $(libcoap_dir)/ext ; git clone https://github.com/eclipse/tinydtls.git) ; \ + fi ; \ + if [ ! -f $(libcoap_dir)/ext/tinydtls/dtls.c ] ; then \ + IN_GIT=`git rev-parse --is-inside-work-tree` ; \ + if [ "$$IN_GIT" = "true" ] ; then \ + (cd $(libcoap_dir) ; git submodule init ; git submodule update) ; \ + else \ + (cd $(libcoap_dir)/ext ; git clone https://github.com/eclipse/tinydtls.git) ; \ + fi ; \ + if [ ! -f $(libcoap_dir)/ext/tinydtls/dtls.c ] ; then \ + exit 1 ; \ + fi ; \ + fi ; \ + if [ ! -f $(libcoap_dir)/ext/tinydtls/dtls_config.h ] ; then \ + (cd $(libcoap_dir)/ext/tinydtls ; ./autogen.sh ; ./configure) ; \ + ${MAKE} ; \ + fi) + # lwip and coap opts (include early to shadow the lwip-contrib/ports/unix/proj/minimal/ file and any ../../config.h) -CFLAGS += -DWITH_LWIP -iquote./config +CFLAGS += -DWITH_LWIP -iquote./config $(EXTRA_CFLAGS) # lwip library +CFLAGS += -Ilwip/src/include/ -Ilwip/src/include/ipv4/ \ + -Ilwip-contrib/ports/unix/port/include/ \ + -Ilwip-contrib/ports/unix/proj/minimal/ + LWIP_SRC = def.c init.c tapif.c etharp.c netif.c timeouts.c stats.c udp.c \ tcp.c pbuf.c ip4_addr.c ip4.c inet_chksum.c tcp_in.c tcp_out.c \ icmp.c raw.c ip4_frag.c sys_arch.c ethernet.c ip.c mem.c memp.c @@ -78,8 +119,11 @@ vpath %.c lwip/src/core/ lwip-contrib/ports/unix/proj/minimal/ \ vpath %.c lwip/src/core/ipv6/ LWIP_SRC += mld6.c ip6.c icmp6.c ethip6.c nd6.c ip6_addr.c ip6_frag.c -C_LWIP_OBJ =$(patsubst %.c,lib-client/%.o,$(LWIP_SRC)) -S_LWIP_OBJ =$(patsubst %.c,lib-server/%.o,$(LWIP_SRC)) +CN_LWIP_OBJ =$(patsubst %.c,lib-client/%.o,$(LWIP_SRC)) +SN_LWIP_OBJ =$(patsubst %.c,lib-server/%.o,$(LWIP_SRC)) +CD_LWIP_OBJ =$(patsubst %.c,lib-client-dtls/%.o,$(LWIP_SRC)) +SD_LWIP_OBJ =$(patsubst %.c,lib-server-dtls/%.o,$(LWIP_SRC)) + # coap library CFLAGS += -std=gnu99 @@ -89,6 +133,7 @@ CFLAGS += -I$(libcoap_dir)/include vpath %.c $(libcoap_dir)/src COAP_SRC = coap_address.c \ + coap_asn1.c \ coap_async.c \ block.c \ coap_cache.c \ @@ -104,34 +149,76 @@ COAP_SRC = coap_address.c \ resource.c \ coap_session.c \ coap_subscribe.c \ + coap_tinydtls.c \ str.c \ coap_tcp.c \ uri.c -C_COAP_OBJ =$(patsubst %.c,lib-client/%.o,$(COAP_SRC)) -S_COAP_OBJ =$(patsubst %.c,lib-server/%.o,$(COAP_SRC)) +CN_COAP_OBJ =$(patsubst %.c,lib-client/%.o,$(COAP_SRC)) +SN_COAP_OBJ =$(patsubst %.c,lib-server/%.o,$(COAP_SRC)) +CD_COAP_OBJ =$(patsubst %.c,lib-client-dtls/%.o,$(COAP_SRC)) +SD_COAP_OBJ =$(patsubst %.c,lib-server-dtls/%.o,$(COAP_SRC)) + +# tinydtls library + +vpath %.c $(libcoap_dir)/ext/tinydtls $(libcoap_dir)/ext/tinydtls/sha2 $(libcoap_dir)/ext/tinydtls/aes $(libcoap_dir)/ext/tinydtls/ecc + +TINYDTLS_CFLAGS = -I. -I$(libcoap_dir)/ext -I$(libcoap_dir)/ext/tinydtls -DDTLSv12 -DWITH_SHA256 -DSHA2_USE_INTTYPES_H -DDTLS_CHECK_CONTENTTYPE -DHAVE_LIBTINYDTLS -DHAVE_DTLS_SET_LOG_HANDLER=1 + +DTLS_SRC = dtls.c \ + dtls_debug.c \ + crypto.c \ + dtls_time.c \ + hmac.c \ + sha2.c \ + session.c \ + peer.c \ + netq.c \ + rijndael_wrap.c \ + rijndael.c \ + ecc.c \ + ccm.c \ + dtls_prng.c + +CN_DTLS_OBJ =$(patsubst %.c,lib-client/%.o,$(DTLS_SRC)) +SN_DTLS_OBJ =$(patsubst %.c,lib-server/%.o,$(DTLS_SRC)) +CD_DTLS_OBJ =$(patsubst %.c,lib-client-dtls/%.o,$(DTLS_SRC)) +SD_DTLS_OBJ =$(patsubst %.c,lib-server-dtls/%.o,$(DTLS_SRC)) CFLAGS += -g3 -Wall -Wextra -pedantic -O0 -CFLAGS += -Ilwip/src/include/ -Ilwip/src/include/ipv4/ \ - -Ilwip-contrib/ports/unix/port/include/ \ - -Ilwip-contrib/ports/unix/proj/minimal/ +CN_APP_OBJ =$(patsubst %.c,lib-client/%.o,client.c client-coap.c) +SN_APP_OBJ =$(patsubst %.c,lib-server/%.o,server.c server-coap.c) +CD_APP_OBJ =$(patsubst %.c,lib-client-dtls/%.o,client.c client-coap.c) +SD_APP_OBJ =$(patsubst %.c,lib-server-dtls/%.o,server.c server-coap.c) -SOBJS = server.o server-coap.o ${S_LWIP_OBJ} ${S_COAP_OBJ} -COBJS = client.o client-coap.o ${C_LWIP_OBJ} ${C_COAP_OBJ} +CN_OBJS = ${CN_APP_OBJ} ${CN_LWIP_OBJ} ${CN_COAP_OBJ} +SN_OBJS = ${SN_APP_OBJ} ${SN_LWIP_OBJ} ${SN_COAP_OBJ} +CD_OBJS = ${CD_APP_OBJ} ${CD_LWIP_OBJ} ${CD_COAP_OBJ} ${CD_DTLS_OBJ} +SD_OBJS = ${SD_APP_OBJ} ${SD_LWIP_OBJ} ${SD_COAP_OBJ} ${SD_DTLS_OBJ} $(coap_include_dir)/coap.h: - @echo "Error: $@ not present. Run the autotools chain (\`./autogen.sh && ./configure\`) in the project root directory to build the required coap.h file." - @exit 1 + @(if [ ! -f $(coap_include_dir)/coap.h ] ; then \ + (cd $(libcoap_dir) ; ./autogen.sh ; ./configure --disable-dtls --disable-man) ; \ + ${MAKE}; \ + fi) -${SOBJS}: $(coap_include_dir)/coap.h server-coap.h +${SN_OBJS} ${SD_OBJS}: $(coap_include_dir)/coap.h server-coap.h -server: ${SOBJS} +server: ${SN_OBJS} + $(CC) $(CFLAGS) ${SN_OBJS} -o server ${LDLIBS} -${COBJS}: $(coap_include_dir)/coap.h client-coap.h +server-dtls: ${SD_OBJS} + $(CC) $(CFLAGS) ${SD_OBJS} -o server-dtls ${LDLIBS} -client: ${COBJS} +${CN_OBJS} ${CD_OBJS}: $(coap_include_dir)/coap.h client-coap.h + +client: ${CN_OBJS} + $(CC) $(CFLAGS) ${CN_OBJS} -o client ${LDLIBS} + +client-dtls: ${CD_OBJS} + $(CC) $(CFLAGS) ${CD_OBJS} -o client-dtls ${LDLIBS} lib-server: @mkdir -p $@ @@ -139,13 +226,27 @@ lib-server: lib-server/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h $(CC) ${CFLAGS} -DCOAP_SERVER_SUPPORT -c $< -o $@ +lib-server-dtls: + @mkdir -p $@ + +lib-server-dtls/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h + $(CC) ${CFLAGS} ${TINYDTLS_CFLAGS} -DCOAP_SERVER_SUPPORT -c $< -o $@ + lib-client: @mkdir -p $@ lib-client/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h $(CC) ${CFLAGS} -DCOAP_CLIENT_SUPPORT -c $< -o $@ +lib-client-dtls: + @mkdir -p $@ + +lib-client-dtls/%.o: %.c config/lwipopts.h config/lwippools.h config/coap_config.h + $(CC) ${CFLAGS} ${TINYDTLS_CFLAGS} -DCOAP_CLIENT_SUPPORT -c $< -o $@ + clean: - rm -rf server client ${COBJS} ${SOBJS} lib-server lib-client + rm -rf server server-dtls client client-dtls \ + ${CN_OBJS} ${SN_OBJS} ${CD_OBJS} ${SD_OBJS} \ + lib-server lib-server-dtls lib-client lib-client-dtls .PHONY: all clean diff --git a/examples/lwip/README b/examples/lwip/README index 76e8276e..be74eb30 100644 --- a/examples/lwip/README +++ b/examples/lwip/README @@ -4,14 +4,17 @@ Example of libcoap running on lwIP To run the server example, do $ make - $ sudo ./server + $ sudo ./server # No TinyDTLS support + or + $ sudo ./server-dtls # With TinyDTLS support (and in a second terminal) $ sudo ip a a dev tap0 192.168.113.1/24 and query `coap://192.168.113.2/time?ticks` with any coap tool, -or query `coap://192.168.113.2/.well-known/core` +or query `coap://192.168.113.2/.well-known/core`. +(If server-dtls is running, you can use coaps:// as appropriate.) This will @@ -23,7 +26,12 @@ This will * return the appropriate response from the server to the client. -The server supports the "-v level" option where logging "level" can be 0 to 7. +The server supports the following options +"-k PSK" option where PSK defines the DTLS PSK to use (default is "secretPSK"). + (Only works for server-dtls.) +"-v level" option where logging "level" can be 0 to 7 (default is 4). +"-V level" option where DTLS logging "level" can be 0 to 7 (default is 3). + (Only works for server-dtls.) The server creates a resource for 'time' with a query 'ticks'. This is reported for `.well-known/core`. The work flow for adding more resources does @@ -34,20 +42,38 @@ in `config/lwippools.h`. To run the client example $ make - $ sudo ./client + $ sudo ./client # No TinyDTLS support + or + $ sudo ./client-dtls # With TinyDTLS support -As this tries to connect to coap://libcoap.net/, the tap0 interface will need IP -forwarding enabled +As client (or client-dtls) tries to connect to coap://libcoap.net/, the tap0 +interface will need IP forwarding enabled $ sudo sysctl -w net.ipv4.conf.default.forwarding=1 +Then you will need IP forwarding enabled on your public interface +(where eth0 is replaced by your public facing interface name) +for response packets + + $ sudo sysctl -w net.eth0.conf.default.forwarding=1 + As well as the interface connecting to the internet will need a NAT rule to masquerade the internal IP address (192.168.114.2) to the IP of the outgoing interface (where eth0 is replaced by your public facing interface name) $ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE -The client supports the "-v level" option where logging "level" can be 0 to 7. +The client supports the following options +"-k PSK" option where PSK defines the DTLS PSK to use (default is "secretPSK"). + (Only works for client-dtls.) +"-u id" option where id defines the DTLS id to use (default is "abc"). + (Only works for client-dtls.) +"-v level" option where logging "level" can be 0 to 7 (default is 4). +"-V level" option where DTLS logging "level" can be 0 to 7 (default is 3). + (Only works for client-dtls.) + The client supports an optional parameter which is the CoAP URI to connect to .e.g "coap://libcoap.net/.well-known/core". The default -is "coap://libcoap.net/". +is "coap://libcoap.net/" for client and client-dtls. +Using "coaps://libcoap.net" will establish a DTLS session if there is +DTLS support compiled in (client-dtls). diff --git a/examples/lwip/client-coap.c b/examples/lwip/client-coap.c index c0968f2f..554c33d1 100644 --- a/examples/lwip/client-coap.c +++ b/examples/lwip/client-coap.c @@ -17,6 +17,14 @@ #include #include "client-coap.h" +#ifndef COAP_URI +#define COAP_URI "coap://libcoap.net" +#endif /* COAP_URI */ + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + static coap_context_t *main_coap_context = NULL; static coap_optlist_t *optlist = NULL; @@ -115,8 +123,7 @@ resolve_address(const char *host, const char *service, coap_address_t *dst) { void client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg, - int log_level, const char* do_uri) -{ + int argc, char **argv) { coap_session_t *session = NULL; coap_pdu_t *pdu; coap_address_t dst; @@ -127,13 +134,45 @@ client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg, #define BUFSIZE 100 unsigned char buf[BUFSIZE]; int res; + const char *use_uri = COAP_URI; + int opt; + coap_log_t log_level = LOG_WARNING; + coap_log_t dtls_log_level = LOG_ERR; + const char *use_psk = "secretPSK"; + const char *use_id = "abc"; + + while ((opt = getopt(argc, argv, ":k:u:v:V:")) != -1) { + switch (opt) { + case 'k': + use_psk = optarg; + break; + case 'u': + use_id = optarg; + break; + case 'v': + log_level = atoi(optarg); + break; + case 'V': + dtls_log_level = atoi(optarg); + break; + default: + printf("%s [-k PSK] [-u id] [-v level] [ -V level] [URI]\n", argv[0]); + exit(1); + } + } + + if (optind < argc) { + use_uri = argv[optind]; + } coap_set_log_level(log_level); + coap_dtls_set_log_level(dtls_log_level); /* Parse the URI */ - len = coap_split_uri((const unsigned char *)do_uri, strlen(do_uri), &uri); + len = coap_split_uri((const unsigned char *)use_uri, strlen(use_uri), &uri); LWIP_ASSERT("Failed to parse uri", len == 0); - LWIP_ASSERT("Unsupported URI type", uri.scheme == COAP_URI_SCHEME_COAP); + LWIP_ASSERT("Unsupported URI type", uri.scheme == COAP_URI_SCHEME_COAP || + uri.scheme == COAP_URI_SCHEME_COAPS); snprintf(portbuf, sizeof(portbuf), "%d", uri.port); snprintf((char *)buf, sizeof(buf), "%*.*s", (int)uri.host.length, @@ -148,8 +187,30 @@ client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg, coap_context_set_block_mode(main_coap_context, COAP_BLOCK_USE_LIBCOAP); coap_lwip_set_input_wait_handler(main_coap_context, input_wait, input_arg); - session = coap_new_client_session(main_coap_context, NULL, &dst, - COAP_PROTO_UDP); + if (uri.scheme == COAP_URI_SCHEME_COAP) { + session = coap_new_client_session(main_coap_context, NULL, &dst, + COAP_PROTO_UDP); + } else { + static coap_dtls_cpsk_t dtls_psk; + 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; + 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 *)use_id; + dtls_psk.psk_info.identity.length = strlen(use_id); + dtls_psk.psk_info.key.s = (const uint8_t *)use_psk; + dtls_psk.psk_info.key.length = strlen(use_psk); + + session = coap_new_client_session_psk2(main_coap_context, NULL, &dst, + COAP_PROTO_DTLS, &dtls_psk); + } LWIP_ASSERT("Failed to create session", session != NULL); @@ -185,8 +246,7 @@ client_coap_finished(void) { } int -client_coap_poll(void) -{ +client_coap_poll(void) { coap_io_process(main_coap_context, 1000); return quit; } diff --git a/examples/lwip/client-coap.h b/examples/lwip/client-coap.h index 5abd9094..4f47ace5 100644 --- a/examples/lwip/client-coap.h +++ b/examples/lwip/client-coap.h @@ -15,7 +15,7 @@ /* Start up the CoAP Client */ void client_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg, - coap_log_t log_level, const char* do_uri); + int argc, char **argv); /* Close down CoAP activity */ diff --git a/examples/lwip/client.c b/examples/lwip/client.c index 693e7935..9c90c85b 100644 --- a/examples/lwip/client.c +++ b/examples/lwip/client.c @@ -47,10 +47,6 @@ static ip4_addr_t ipaddr, netmask, gw; static int quit = 0; -#ifndef COAP_URI -#define COAP_URI "coap://libcoap.net" -#endif /* COAP_URI */ - static void handle_sigint(int signum) { (void)signum; @@ -60,6 +56,10 @@ handle_sigint(int signum) { exit(0); } +/* + * This function is called internally by coap_io_process() to check + * for input. + */ static int wait_for_input(void *arg, uint32_t milli_secs) { struct netif *netif = (struct netif *)arg; @@ -73,30 +73,12 @@ wait_for_input(void *arg, uint32_t milli_secs) { } int -main(int argc, char **argv) -{ +main(int argc, char **argv) { struct netif netif; #ifndef _WIN32 struct sigaction sa; #endif int no_more = 0; - int opt; - int log_level = 4; /* LOG_WARNING */ - const char *use_uri = COAP_URI; - - while ((opt = getopt(argc, argv, "v:")) != -1) { - switch (opt) { - case 'v': - log_level = atoi(optarg); - break; - default: - exit(1); - } - } - - if (optind < argc) { - use_uri = argv[optind]; - } /* startup defaults (may be overridden by one or more opts). this is * hard-coded v4 even in presence of v6, which does auto-discovery and @@ -134,7 +116,7 @@ main(int argc, char **argv) sigaction (SIGPIPE, &sa, NULL); #endif - client_coap_init(wait_for_input, &netif, log_level, use_uri); + client_coap_init(wait_for_input, &netif, argc, argv); printf("Client Application started.\n"); diff --git a/examples/lwip/config/lwipopts.h b/examples/lwip/config/lwipopts.h index 0fe7c446..c19b0c44 100644 --- a/examples/lwip/config/lwipopts.h +++ b/examples/lwip/config/lwipopts.h @@ -2,7 +2,7 @@ * lwipopts.h -- LwIP example * * Copyright (C) 2013-2016 Christian Amsüss - * Copyright (C) 2018 John Shallow + * Copyright (C) 2018-2022 Jon Shallow * * SPDX-License-Identifier: BSD-2-Clause * @@ -18,6 +18,9 @@ #define LWIP_IPV6 1 #define LWIP_IPV6_REASS 0 +#define LWIP_IPV6_MLD 0 +#define LWIP_ICMP6 1 + #ifndef LWIP_RAND #define LWIP_RAND() ((u32_t)rand()) #endif diff --git a/examples/lwip/config/lwippools.h b/examples/lwip/config/lwippools.h index 1c8e2ccf..54e348d1 100644 --- a/examples/lwip/config/lwippools.h +++ b/examples/lwip/config/lwippools.h @@ -15,13 +15,39 @@ #include "coap3/net.h" #include "coap3/resource.h" #include "coap3/coap_subscribe.h" +#ifdef HAVE_LIBTINYDTLS +#ifndef LWIP_TINYDTLS_LOCAL_FIX +#define LWIP_TINYDTLS_LOCAL_FIX +#include +/* Local copies of struct to simplify #include nightmare */ +typedef struct { + unsigned char size; /**< size of session_t::addr */ + unsigned short port; /**< transport layer port */ + ip_addr_t addr; /**< session IP address */ + int ifindex; /**< network interface index */ +} l_session_t; + +typedef struct l_coap_tiny_context_t { + struct dtls_context_t *dtls_context; + coap_context_t *coap_context; + coap_dtls_pki_t setup_data; + coap_binary_t *priv_key; + coap_binary_t *pub_key; +} l_coap_tiny_context_t; + +#endif /* LWIP_TINYDTLS_LOCAL_FIX */ +#endif /* HAVE_LIBTINYDTLS */ #ifndef MEMP_NUM_COAPCONTEXT #define MEMP_NUM_COAPCONTEXT 1 #endif #ifndef MEMP_NUM_COAPENDPOINT +#ifdef HAVE_LIBTINYDTLS +#define MEMP_NUM_COAPENDPOINT 2 +#else /* ! HAVE_LIBTINYDTLS */ #define MEMP_NUM_COAPENDPOINT 1 +#endif /* ! HAVE_LIBTINYDTLS */ #endif /* 1 is sufficient as this is very short-lived */ @@ -101,6 +127,14 @@ #define MEMP_NUM_COAPDIGESTCTX 4 #endif +#ifndef MEMP_NUM_COAPDTLS_SESSION +#define MEMP_NUM_COAPDTLS_SESSION 1 +#endif + +#ifndef MEMP_NUM_COAPDTLS_CONTEXT +#define MEMP_NUM_COAPDTLS_CONTEXT 1 +#endif + LWIP_MEMPOOL(COAP_CONTEXT, MEMP_NUM_COAPCONTEXT, sizeof(coap_context_t), "COAP_CONTEXT") #ifdef COAP_SERVER_SUPPORT LWIP_MEMPOOL(COAP_ENDPOINT, MEMP_NUM_COAPENDPOINT, sizeof(coap_endpoint_t), "COAP_ENDPOINT") @@ -110,7 +144,7 @@ LWIP_MEMPOOL(COAP_NODE, MEMP_NUM_COAPNODE, sizeof(coap_queue_t), "COAP_NODE") LWIP_MEMPOOL(COAP_PDU, MEMP_NUM_COAPPDU, sizeof(coap_pdu_t), "COAP_PDU") LWIP_MEMPOOL(COAP_SESSION, MEMP_NUM_COAPSESSION, sizeof(coap_session_t), "COAP_SESSION") #ifdef COAP_SERVER_SUPPORT -LWIP_MEMPOOL(COAP_subscription, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_SUBSCRIPTION") +LWIP_MEMPOOL(COAP_SUBSCRIPTION, MEMP_NUM_COAP_SUBSCRIPTION, sizeof(coap_subscription_t), "COAP_SUBSCRIPTION") LWIP_MEMPOOL(COAP_RESOURCE, MEMP_NUM_COAPRESOURCE, sizeof(coap_resource_t), "COAP_RESOURCE") LWIP_MEMPOOL(COAP_RESOURCEATTR, MEMP_NUM_COAPRESOURCEATTR, sizeof(coap_attr_t), "COAP_RESOURCEATTR") #endif /* COAP_SERVER_SUPPORT */ @@ -129,3 +163,7 @@ LWIP_MEMPOOL(COAP_LG_CRCV, MEMP_NUM_COAPLGCRCV, sizeof(coap_lg_crcv_t), "COAP_LG LWIP_MEMPOOL(COAP_LG_SRCV, MEMP_NUM_COAPLGSRCV, sizeof(coap_lg_srcv_t), "COAP_LG_SRCV") LWIP_MEMPOOL(COAP_DIGEST_CTX, MEMP_NUM_COAPDIGESTCTX, sizeof(coap_digest_t) + sizeof(size_t), "COAP_DIGEST_CTX") #endif /* COAP_SERVER_SUPPORT */ +#ifdef HAVE_LIBTINYDTLS +LWIP_MEMPOOL(COAP_DTLS_SESSION, MEMP_NUM_COAPDTLS_SESSION, sizeof(l_session_t), "COAP_DTLS_SESSION") +LWIP_MEMPOOL(COAP_DTLS_CONTEXT, MEMP_NUM_COAPDTLS_CONTEXT, sizeof(l_coap_tiny_context_t), "COAP_DTLS_CONTEXT") +#endif /* HAVE_LIBTINYDTLS */ diff --git a/examples/lwip/server-coap.c b/examples/lwip/server-coap.c index 48fea40a..365c1909 100644 --- a/examples/lwip/server-coap.c +++ b/examples/lwip/server-coap.c @@ -116,9 +116,29 @@ init_coap_resources(coap_context_t *ctx) { } void server_coap_init(coap_lwip_input_wait_handler_t input_wait, - void *input_arg, int log_level) -{ + void *input_arg, int argc, char **argv) { coap_address_t listenaddress; + int opt; + coap_log_t log_level = LOG_WARNING; + coap_log_t dtls_log_level = LOG_ERR; + const char *use_psk = "secretPSK"; + + while ((opt = getopt(argc, argv, ":k:v:V:")) != -1) { + switch (opt) { + case 'k': + use_psk = optarg; + break; + case 'v': + log_level = atoi(optarg); + break; + case 'V': + dtls_log_level = atoi(optarg); + break; + default: + printf("%s [-k PSK] [-v level] [ -V level]\n", argv[0]); + exit(1); + } + } coap_address_init(&listenaddress); @@ -127,11 +147,27 @@ void server_coap_init(coap_lwip_input_wait_handler_t input_wait, listenaddress.port = COAP_DEFAULT_PORT; coap_set_log_level(log_level); + coap_dtls_set_log_level(dtls_log_level); main_coap_context = coap_new_context(&listenaddress); LWIP_ASSERT("Failed to initialize context", main_coap_context != NULL); + if (coap_dtls_is_supported()) { + coap_dtls_spsk_t setup_data; + coap_endpoint_t *ep; + + listenaddress.port = COAP_DEFAULT_PORT + 1; + ep = coap_new_endpoint(main_coap_context, &listenaddress, COAP_PROTO_DTLS); + LWIP_ASSERT("Failed to initialize dtls endpoint", ep != NULL); + memset(&setup_data, 0, sizeof(setup_data)); + setup_data.version = COAP_DTLS_SPSK_SETUP_VERSION; + setup_data.psk_info.key.s = (const uint8_t *)use_psk; + setup_data.psk_info.key.length = strlen(use_psk); + coap_context_set_psk2(main_coap_context, &setup_data); + } + /* Limit the number of idle sessions to save RAM (MEMP_NUM_COAPSESSION) */ - coap_context_set_max_idle_sessions(main_coap_context, MEMP_NUM_COAPSESSION); + LWIP_ASSERT("Need a minimum of 2 for MEMP_NUM_COAPSESSION", MEMP_NUM_COAPSESSION > 1); + coap_context_set_max_idle_sessions(main_coap_context, MEMP_NUM_COAPSESSION -1); clock_offset = 1; /* Need a non-zero value */ init_coap_resources(main_coap_context); coap_lwip_set_input_wait_handler(main_coap_context, input_wait, input_arg); @@ -143,8 +179,7 @@ server_coap_finished(void) { main_coap_context = NULL; } -void server_coap_poll(void) -{ +void server_coap_poll(void) { static coap_time_t last_time = 0; coap_tick_t ticks_now; coap_time_t time_now; diff --git a/examples/lwip/server-coap.h b/examples/lwip/server-coap.h index 027559cf..e1c65153 100644 --- a/examples/lwip/server-coap.h +++ b/examples/lwip/server-coap.h @@ -14,7 +14,7 @@ /* Start up the CoAP Server */ void server_coap_init(coap_lwip_input_wait_handler_t input_wait, void *input_arg, - coap_log_t log_level); + int argc, char **argv); /* Close down CoAP activity */ diff --git a/examples/lwip/server.c b/examples/lwip/server.c index 65648acf..dfcc4f52 100644 --- a/examples/lwip/server.c +++ b/examples/lwip/server.c @@ -55,6 +55,10 @@ handle_sigint(int signum) { exit(0); } +/* + * This function is called internally by coap_io_process() to check + * for input. + */ static int wait_for_input(void *arg, uint32_t milli_secs) { struct netif *netif = (struct netif *)arg; @@ -68,24 +72,11 @@ wait_for_input(void *arg, uint32_t milli_secs) { } int -main(int argc, char **argv) -{ +main(int argc, char **argv) { struct netif netif; #ifndef _WIN32 struct sigaction sa; #endif - int opt; - int log_level = 4; /* LOG_WARNING */ - - while ((opt = getopt(argc, argv, "v:")) != -1) { - switch (opt) { - case 'v': - log_level = atoi(optarg); - break; - default: - exit(1); - } - } /* startup defaults (may be overridden by one or more opts). this is * hard-coded v4 even in presence of v6, which does auto-discovery and @@ -103,8 +94,10 @@ main(int argc, char **argv) netif.flags |= NETIF_FLAG_ETHARP; netif_set_default(&netif); netif_set_up(&netif); + printf("IP4 %s\n", ip4addr_ntoa(&netif.ip_addr.u_addr.ip4)); #if LWIP_IPV6 netif_create_ip6_linklocal_address(&netif, 1); + printf("IP6 [%s]\n", ip6addr_ntoa(&netif.ip6_addr[0].u_addr.ip6)); #endif /* start applications here */ @@ -123,7 +116,7 @@ main(int argc, char **argv) sigaction (SIGPIPE, &sa, NULL); #endif - server_coap_init(wait_for_input, &netif, log_level); + server_coap_init(wait_for_input, &netif, argc, argv); printf("Server Application started.\n"); diff --git a/include/coap3/mem.h b/include/coap3/mem.h index af13c956..5123659c 100644 --- a/include/coap3/mem.h +++ b/include/coap3/mem.h @@ -54,6 +54,8 @@ typedef enum { COAP_LG_CRCV, COAP_LG_SRCV, COAP_DIGEST_CTX, + COAP_SUBSCRIPTION, + COAP_DTLS_CONTEXT, } coap_memory_tag_t; #ifndef WITH_LWIP @@ -124,7 +126,9 @@ COAP_STATIC_INLINE void coap_memory_init(void) {} * declaration, but i currently don't see a standard way to check that without * sourcing the custom memp pools and becoming dependent of its syntax */ -#define coap_malloc_type(type, size) memp_malloc(MEMP_ ## type) +#define coap_malloc_type(type, asize) \ + (((asize) <= memp_pools[MEMP_ ## type]->size) ? \ + memp_malloc(MEMP_ ## type) : NULL) #define coap_free_type(type, p) memp_free(MEMP_ ## type, p) /* Those are just here to make uri.c happy where string allocation has not been diff --git a/scripts/github_dist.sh b/scripts/github_dist.sh index fe2ad76f..3bab4296 100755 --- a/scripts/github_dist.sh +++ b/scripts/github_dist.sh @@ -20,7 +20,7 @@ if test $err = 0 -a "x$ARCHIVE" != "x"; then make EXTRA_CFLAGS=-Werror && make install EXTRA_CFLAGS=-Werror err=$? if [ $err = 0 ] ; then - make -C $DIR/examples/lwip + make -C $DIR/examples/lwip EXTRA_CFLAGS=-Werror err=$? fi if [ $err = 0 ] ; then diff --git a/src/coap_debug.c b/src/coap_debug.c index b9ab209f..2d89613c 100644 --- a/src/coap_debug.c +++ b/src/coap_debug.c @@ -288,9 +288,67 @@ coap_print_addr(const coap_address_t *addr, unsigned char *buf, size_t len) { #endif /* HAVE_SNPRINTF */ return strlen((char *)p); -# else /* WITH_CONTIKI */ + +# elif WITH_LWIP + + unsigned char *p = buf; +#ifndef HAVE_SNPRINTF + uint8_t i; + const uint8_t hex[] = "0123456789ABCDEF"; + unsigned char *b = (unsigned char *)addr->addr.u_addr.ip6.addr; +#endif /* ! HAVE_SNPRINTF */ + + assert(buf); + assert(len); + buf[0] = '\000'; + if (len < 42) + return 0; + + switch (addr->addr.type) { + case IPADDR_TYPE_V4: +#ifdef HAVE_SNPRINTF + p += snprintf((char *)p, len, "%s", ip4addr_ntoa(&addr->addr.u_addr.ip4)); +#endif /* HAVE_SNPRINTF */ + break; + case IPADDR_TYPE_V6: + case IPADDR_TYPE_ANY: +#ifdef HAVE_SNPRINTF + p+= snprintf((char *)p, len, "[%s]", ip6addr_ntoa(&addr->addr.u_addr.ip6)); +#else /* ! HAVE_SNPRINTF */ + *p++ = '['; + for (i=0; i < 16; i += 2) { + if (i) { + *p++ = ':'; + } + *p++ = hex[(b[i] & 0xf0) >> 4]; + *p++ = hex[(b[i] & 0x0f)]; + *p++ = hex[(b[i+1] & 0xf0) >> 4]; + *p++ = hex[(b[i+1] & 0x0f)]; + } + *p++ = ']'; + if (buf + len - p < 6) { + *p = '\000'; + return p - buf; + } +#endif /* ! HAVE_SNPRINTF */ + break; + } + +#ifdef HAVE_SNPRINTF + /* Cannot rely on snprintf() return value for short buffers */ + snprintf((char *)p, buf + len - p, ":%d", addr->port); +#else /* ! HAVE_SNPRINTF */ + /* @todo manual conversion of port number */ + *p = '\000'; +#endif /* ! HAVE_SNPRINTF */ + + return strlen((char *)p); + +# else /* ! WITH_CONTIKI && ! WITH_LWIP */ + (void)addr; (void)len; + /* TODO: output addresses manually */ # warning "inet_ntop() not available, network addresses will not be included in debug output" # endif /* WITH_CONTIKI */ diff --git a/src/coap_io.c b/src/coap_io.c index 4ed895f9..4fe84187 100644 --- a/src/coap_io.c +++ b/src/coap_io.c @@ -145,8 +145,6 @@ void coap_socket_close(coap_socket_t *sock) { #else -#ifndef WITH_LWIP - #if COAP_SERVER_SUPPORT coap_endpoint_t * coap_malloc_endpoint(void) { @@ -159,6 +157,8 @@ coap_mfree_endpoint(coap_endpoint_t *ep) { } #endif /* COAP_SERVER_SUPPORT */ +#ifndef WITH_LWIP + int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, diff --git a/src/coap_io_lwip.c b/src/coap_io_lwip.c index 93ea24ed..97c52abd 100644 --- a/src/coap_io_lwip.c +++ b/src/coap_io_lwip.c @@ -100,10 +100,11 @@ coap_io_process(coap_context_t *context, uint32_t timeout_ms) { coap_log(LOG_INFO, "****** Next wakeup msecs %u (2)\n", timeout); #endif /* COAP_DEBUG_WAKEUP_TIMES */ + sys_timeout(timeout, coap_io_process_timeout, context); + context->timer_configured = 1; if (context->input_wait) { context->input_wait(context->input_arg, timeout); } - context->timer_configured = 1; sys_check_timeouts(); coap_ticks(&now); return (int)(((now - before) * 1000) / COAP_TICKS_PER_SECOND); @@ -151,8 +152,10 @@ coap_recvc(void *arg, struct udp_pcb *upcb, struct pbuf *p, coap_pdu_t *pdu = NULL; coap_session_t *session = (coap_session_t*)arg; coap_packet_t *packet; + int result = -1; assert(session); + LWIP_ASSERT("Proto not supported for LWIP", COAP_PROTO_NOT_RELIABLE(session->proto)); if (p->len < 4) { /* Minimum size of CoAP header - ignore runt */ @@ -161,7 +164,8 @@ coap_recvc(void *arg, struct udp_pcb *upcb, struct pbuf *p, packet = coap_malloc_type(COAP_PACKET, sizeof(coap_packet_t)); - /* this is fatal because due to the short life of the packet, never should there be more than one coap_packet_t required */ + /* this is fatal because due to the short life of the packet, never should + * there be more than one coap_packet_t required */ LWIP_ASSERT("Insufficient coap_packet_t resources.", packet != NULL); packet->pbuf = p; /* Need to do this as there may be holes in addr_info */ @@ -172,17 +176,25 @@ coap_recvc(void *arg, struct udp_pcb *upcb, struct pbuf *p, packet->addr_info.local.addr = *ip_current_dest_addr(); packet->ifindex = netif_get_index(ip_current_netif()); - pdu = coap_pdu_from_pbuf(p); - if (!pdu) - goto error; + coap_log(LOG_DEBUG, "* %s: received %d bytes\n", + coap_session_str(session), p->len); + if (session->proto == COAP_PROTO_DTLS) { + if (session->tls) { + result = coap_dtls_receive(session, p->payload, p->len); + if (result < 0) + goto error; + } + pbuf_free(p); + } else { + pdu = coap_pdu_from_pbuf(p); + if (!pdu) + goto error; - if (!coap_pdu_parse(session->proto, p->payload, p->len, pdu)) { - goto error; + if (!coap_pdu_parse(session->proto, p->payload, p->len, pdu)) { + goto error; + } + coap_dispatch(session->context, session, pdu); } - - LWIP_ASSERT("Proto not supported for LWIP", COAP_PROTO_NOT_RELIABLE(session->proto)); - coap_dispatch(session->context, session, pdu); - coap_delete_pdu(pdu); packet->pbuf = NULL; coap_free_packet(packet); @@ -221,6 +233,7 @@ coap_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p, coap_session_t *session = NULL; coap_tick_t now; coap_packet_t *packet; + int result = -1; if (p->len < 4) { /* Minimum size of CoAP header - ignore runt */ @@ -229,7 +242,8 @@ coap_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p, packet = coap_malloc_type(COAP_PACKET, sizeof(coap_packet_t)); - /* this is fatal because due to the short life of the packet, never should there be more than one coap_packet_t required */ + /* this is fatal because due to the short life of the packet, never should + there be more than one coap_packet_t required */ LWIP_ASSERT("Insufficient coap_packet_t resources.", packet != NULL); packet->pbuf = p; /* Need to do this as there may be holes in addr_info */ @@ -240,28 +254,34 @@ coap_recvs(void *arg, struct udp_pcb *upcb, struct pbuf *p, packet->addr_info.local.addr = *ip_current_dest_addr(); packet->ifindex = netif_get_index(ip_current_netif()); - pdu = coap_pdu_from_pbuf(p); - if (!pdu) - goto error; - - if (!coap_pdu_parse(ep->proto, p->payload, p->len, pdu)) { - goto error; - } - coap_ticks(&now); - if ((upcb->local_port == COAP_DEFAULT_PORT) || - (upcb->local_port == COAPS_DEFAULT_PORT)) { - /* packet for local server */ - session = coap_endpoint_get_session(ep, packet, now); - } else { - session = coap_session_get_by_peer(ep->context, &packet->addr_info.remote, - packet->ifindex); - } + session = coap_endpoint_get_session(ep, packet, now); if (!session) goto error; LWIP_ASSERT("Proto not supported for LWIP", COAP_PROTO_NOT_RELIABLE(session->proto)); - coap_dispatch(ep->context, session, pdu); + + coap_log(LOG_DEBUG, "* %s: received %d bytes\n", + coap_session_str(session), p->len); + + if (session->proto == COAP_PROTO_DTLS) { + if (session->type == COAP_SESSION_TYPE_HELLO) + result = coap_dtls_hello(session, p->payload, p->len); + else if (session->tls) + result = coap_dtls_receive(session, p->payload, p->len); + if (session->type == COAP_SESSION_TYPE_HELLO && result == 1) + coap_session_new_dtls_session(session, now); + pbuf_free(p); + } else { + pdu = coap_pdu_from_pbuf(p); + if (!pdu) + goto error; + + if (!coap_pdu_parse(ep->proto, p->payload, p->len, pdu)) { + goto error; + } + coap_dispatch(ep->context, session, pdu); + } coap_delete_pdu(pdu); packet->pbuf = NULL; @@ -283,42 +303,6 @@ error: return; } -coap_endpoint_t * -coap_new_endpoint(coap_context_t *context, const coap_address_t *addr, coap_proto_t proto) { - coap_endpoint_t *result; - err_t err; - - LWIP_ASSERT("Proto not supported for LWIP endpoints", proto == COAP_PROTO_UDP); - - result = coap_malloc_type(COAP_ENDPOINT, sizeof(coap_endpoint_t)); - if (!result) return NULL; - - result->sock.pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (result->sock.pcb == NULL) goto error; - - udp_recv(result->sock.pcb, coap_recvs, (void*)result); - err = udp_bind(result->sock.pcb, &addr->addr, addr->port); - if (err) { - udp_remove(result->sock.pcb); - goto error; - } - - result->default_mtu = COAP_DEFAULT_MTU; - result->context = context; - result->proto = proto; - - return result; - -error: - coap_free_type(COAP_ENDPOINT, result); - return NULL; -} - -void coap_free_endpoint(coap_endpoint_t *ep) -{ - udp_remove(ep->sock.pcb); - coap_free_type(COAP_ENDPOINT, ep); -} #endif /* ! COAP_SERVER_SUPPORT */ ssize_t @@ -328,6 +312,7 @@ coap_socket_send_pdu(coap_socket_t *sock, coap_session_t *session, * should actually check that the pdu is not held by anyone but us. the * respective pbuf is already exclusively owned by the pdu. */ struct pbuf *pbuf; + int err; pbuf_realloc(pdu->pbuf, pdu->used_size + coap_pdu_parse_header_size(session->proto, pdu->pbuf->payload)); @@ -336,35 +321,57 @@ coap_socket_send_pdu(coap_socket_t *sock, coap_session_t *session, pbuf = pbuf_clone(PBUF_TRANSPORT, PBUF_RAM, pdu->pbuf); if (pbuf == NULL) return -1; - udp_sendto(sock->pcb, pbuf, &session->addr_info.remote.addr, - session->addr_info.remote.port); - + err = udp_sendto(sock->pcb, pbuf, &session->addr_info.remote.addr, + session->addr_info.remote.port); pbuf_free(pbuf); + if (err < 0) + return -1; } return pdu->used_size; } ssize_t coap_socket_send(coap_socket_t *sock, coap_session_t *session, - const uint8_t *data, size_t data_len ) { + const uint8_t *data, size_t data_len ) { + struct pbuf *pbuf; + int err; - (void)sock; - (void)session; - (void)data; - (void)data_len; - /* Not implemented, use coap_socket_send_pdu instead */ - return -1; + if (coap_debug_send_packet()) { + pbuf = pbuf_alloc(PBUF_TRANSPORT, data_len, PBUF_RAM); + if (pbuf == NULL) + return -1; + memcpy(pbuf->payload, data, data_len); + err = udp_sendto(sock->pcb, pbuf, &session->addr_info.remote.addr, + session->addr_info.remote.port); + + pbuf_free(pbuf); + if (err < 0) + return -1; + } + return data_len; } +#if COAP_SERVER_SUPPORT int coap_socket_bind_udp(coap_socket_t *sock, - const coap_address_t *listen_addr, - coap_address_t *bound_addr) { - (void)sock; - (void)listen_addr; - (void)bound_addr; - return 0; + const coap_address_t *listen_addr, + coap_address_t *bound_addr) { + int err; + + sock->pcb = udp_new_ip_type(IPADDR_TYPE_ANY); + if (sock->pcb == NULL) + return 0; + + udp_recv(sock->pcb, coap_recvs, (void*)sock->endpoint); + err = udp_bind(sock->pcb, &listen_addr->addr, listen_addr->port); + if (err) { + udp_remove(sock->pcb); + sock->pcb = NULL; + } + *bound_addr = *listen_addr; + return err ? 0 : 1; } +#endif /* COAP_SERVER_SUPPORT */ #if COAP_CLIENT_SUPPORT int diff --git a/src/coap_session.c b/src/coap_session.c index ab5a9d84..dead6489 100644 --- a/src/coap_session.c +++ b/src/coap_session.c @@ -265,11 +265,11 @@ void coap_session_mfree(coap_session_t *session) { if (session->sock.flags != COAP_SOCKET_EMPTY) coap_socket_close(&session->sock); if (session->psk_identity) - coap_free(session->psk_identity); + coap_delete_bin_const(session->psk_identity); if (session->psk_key) - coap_free(session->psk_key); + coap_delete_bin_const(session->psk_key); if (session->psk_hint) - coap_free(session->psk_hint); + coap_delete_bin_const(session->psk_hint); #if COAP_SERVER_SUPPORT coap_cache_entry_t *cp, *ctmp; @@ -567,18 +567,7 @@ void coap_session_connected(coap_session_t *session) { coap_log(LOG_DEBUG, "** %s: mid=0x%x: transmitted after delay\n", coap_session_str(session), (int)q->pdu->mid); -#ifdef WITH_LWIP - coap_socket_t *sock = &session->sock; -#if COAP_SERVER_SUPPORT - if (sock->flags == COAP_SOCKET_EMPTY) { - assert(session->endpoint != NULL); - sock = &session->endpoint->sock; - } -#endif /* COAP_SERVER_SUPPORT */ - bytes_written = coap_socket_send_pdu(sock, session, q->pdu); -#else /* WITH_LWIP */ bytes_written = coap_session_send_pdu(session, q->pdu); -#endif /* WITH_LWIP */ if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) { if (coap_wait_ack(session->context, session, q) >= 0) q = NULL; @@ -1517,7 +1506,6 @@ void *coap_session_get_tls(const coap_session_t *session, return NULL; } -#ifndef WITH_LWIP #if COAP_SERVER_SUPPORT coap_endpoint_t * coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto) { @@ -1560,6 +1548,7 @@ coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, co memset(ep, 0, sizeof(coap_endpoint_t)); ep->context = context; ep->proto = proto; + ep->sock.endpoint = ep; if (proto==COAP_PROTO_UDP || proto==COAP_PROTO_DTLS) { if (!coap_socket_bind_udp(&ep->sock, listen_addr, &ep->bind_addr)) @@ -1649,7 +1638,6 @@ coap_free_endpoint(coap_endpoint_t *ep) { } } #endif /* COAP_SERVER_SUPPORT */ -#endif /* WITH_LWIP */ coap_session_t * coap_session_get_by_peer(const coap_context_t *ctx, diff --git a/src/coap_tinydtls.c b/src/coap_tinydtls.c index ebff84ed..ce944747 100644 --- a/src/coap_tinydtls.c +++ b/src/coap_tinydtls.c @@ -83,10 +83,10 @@ coap_dtls_get_log_level(void) { } static void get_session_addr(const session_t *s, coap_address_t *a) { -#ifdef WITH_CONTIKI +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) a->addr = s->addr; a->port = s->port; -#else +#else /* ! WITH_CONTIKI && ! WITH_LWIP */ if (s->addr.sa.sa_family == AF_INET6) { a->size = (socklen_t)sizeof(a->addr.sin6); a->addr.sin6 = s->addr.sin6; @@ -97,15 +97,15 @@ static void get_session_addr(const session_t *s, coap_address_t *a) { a->size = (socklen_t)s->size; a->addr.sa = s->addr.sa; } -#endif +#endif /* ! WITH_CONTIKI && ! WITH_LWIP */ } static void put_session_addr(const coap_address_t *a, session_t *s) { -#ifdef WITH_CONTIKI +#if defined(WITH_CONTIKI) || defined(WITH_LWIP) s->size = (unsigned char)sizeof(s->addr); s->addr = a->addr; s->port = a->port; -#else +#else /* ! WITH_CONTIKI && ! WITH_LWIP */ if (a->addr.sa.sa_family == AF_INET6) { s->size = (socklen_t)sizeof(s->addr.sin6); s->addr.sin6 = a->addr.sin6; @@ -116,7 +116,7 @@ static void put_session_addr(const coap_address_t *a, session_t *s) { s->size = (socklen_t)a->size; s->addr.sa = a->addr.sa; } -#endif +#endif /* ! WITH_CONTIKI && ! WITH_LWIP */ } static int @@ -481,7 +481,7 @@ static dtls_handler_t psk_cb = { void * coap_dtls_new_context(coap_context_t *coap_context) { - coap_tiny_context_t *t_context = coap_malloc(sizeof(coap_tiny_context_t)); + coap_tiny_context_t *t_context = coap_malloc_type(COAP_DTLS_CONTEXT, sizeof(coap_tiny_context_t)); struct dtls_context_t *dtls_context = t_context ? dtls_new_context(t_context) : NULL; if (!dtls_context) goto error; @@ -492,7 +492,7 @@ coap_dtls_new_context(coap_context_t *coap_context) { return t_context; error: if (t_context) - coap_free(t_context); + coap_free_type(COAP_DTLS_CONTEXT, t_context); if (dtls_context) coap_dtls_free_context(dtls_context); return NULL; @@ -514,7 +514,7 @@ coap_dtls_free_context(void *handle) { #endif /* DTLS_ECC */ if (t_context->dtls_context) dtls_free_context(t_context->dtls_context); - coap_free(t_context); + coap_free_type(COAP_DTLS_CONTEXT, t_context); } } @@ -609,7 +609,6 @@ coap_dtls_send(coap_session_t *session, dtls_context_t *dtls_context = t_context ? t_context->dtls_context : NULL; assert(dtls_context); - coap_log(LOG_DEBUG, "call dtls_write\n"); coap_event_dtls = -1; /* Need to do this to not get a compiler warning about const parameters */ diff --git a/src/net.c b/src/net.c index 5e00cc4a..35194b3f 100644 --- a/src/net.c +++ b/src/net.c @@ -99,7 +99,7 @@ /** creates a Qx.FRAC_BITS from session's 'ack_timeout' */ #define ACK_TIMEOUT Q(FRAC_BITS, session->ack_timeout) -#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) +#if !defined(WITH_CONTIKI) COAP_STATIC_INLINE coap_queue_t * coap_malloc_node(void) { @@ -110,23 +110,8 @@ COAP_STATIC_INLINE void coap_free_node(coap_queue_t *node) { coap_free_type(COAP_NODE, node); } -#endif /* !defined(WITH_LWIP) && !defined(WITH_CONTIKI) */ +#endif /* ! WITH_CONTIKI */ -#ifdef WITH_LWIP - -#include - -COAP_STATIC_INLINE coap_queue_t * -coap_malloc_node() { - return (coap_queue_t *)memp_malloc(MEMP_COAP_NODE); -} - -COAP_STATIC_INLINE void -coap_free_node(coap_queue_t *node) { - memp_free(MEMP_COAP_NODE, node); -} - -#endif /* WITH_LWIP */ #ifdef WITH_CONTIKI # ifndef DEBUG # define DEBUG DEBUG_PRINT @@ -806,34 +791,6 @@ static ssize_t coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { ssize_t bytes_written; -#ifdef WITH_LWIP - - coap_socket_t *sock = &session->sock; -#if COAP_SERVER_SUPPORT - if (sock->flags == COAP_SOCKET_EMPTY) { - assert(session->endpoint != NULL); - sock = &session->endpoint->sock; - } -#endif /* COAP_SERVER_SUPPORT */ - - if (session->state != COAP_SESSION_STATE_ESTABLISHED || - (pdu->type == COAP_MESSAGE_CON && - session->con_active >= COAP_NSTART(session))) { - return coap_session_delay_pdu(session, pdu, node); - } - - bytes_written = coap_socket_send_pdu(sock, session, pdu); - if (bytes_written >= 0 && pdu->type == COAP_MESSAGE_CON && - COAP_PROTO_NOT_RELIABLE(session->proto)) - session->con_active++; - - if (LOG_DEBUG <= coap_get_log_level()) { - coap_show_pdu(LOG_DEBUG, pdu); - } - coap_ticks(&session->last_rx_tx); - -#else - if (session->state == COAP_SESSION_STATE_NONE) { #if ! COAP_CLIENT_SUPPORT return -1; @@ -913,8 +870,6 @@ coap_send_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node) { COAP_PROTO_NOT_RELIABLE(session->proto)) session->con_active++; -#endif /* WITH_LWIP */ - return bytes_written; } diff --git a/src/pdu.c b/src/pdu.c index c8a9f6ed..741c3fe6 100644 --- a/src/pdu.c +++ b/src/pdu.c @@ -1186,9 +1186,8 @@ coap_pdu_parse(coap_proto_t proto, return 0; if (!coap_pdu_resize(pdu, length - hdr_size)) return 0; -#ifndef WITH_LWIP - memcpy(pdu->token - hdr_size, data, length); -#endif + if (pdu->token - hdr_size != data) + memcpy(pdu->token - hdr_size, data, length); pdu->hdr_size = (uint8_t)hdr_size; pdu->used_size = length - hdr_size; return coap_pdu_parse_header(pdu, proto) && coap_pdu_parse_opt(pdu); diff --git a/src/resource.c b/src/resource.c index c6fef703..8ff28175 100644 --- a/src/resource.c +++ b/src/resource.c @@ -24,25 +24,9 @@ #include #endif /* COAP_EPOLL_SUPPORT */ -#if defined(WITH_LWIP) -/* mem.h is only needed for the string free calls for - * COAP_ATTR_FLAGS_RELEASE_NAME / COAP_ATTR_FLAGS_RELEASE_VALUE / - * COAP_RESOURCE_FLAGS_RELEASE_URI. not sure what those lines should actually - * do on lwip. */ - -#include - -#define COAP_MALLOC_TYPE(Type) \ - ((coap_##Type##_t *)memp_malloc(MEMP_COAP_##Type)) -#define COAP_FREE_TYPE(Type, Object) memp_free(MEMP_COAP_##Type, Object) - -#elif defined(WITH_CONTIKI) +#if defined(WITH_CONTIKI) #include "memb.h" -#define COAP_MALLOC_TYPE(Type) \ - ((coap_##Type##_t *)memb_alloc(&(Type##_storage))) -#define COAP_FREE_TYPE(Type, Object) memb_free(&(Type##_storage), (Object)) - MEMB(subscription_storage, coap_subscription_t, COAP_MAX_SUBSCRIBERS); void @@ -60,10 +44,6 @@ coap_free_subscription(coap_subscription_t *subscription) { memb_free(&subscription_storage, subscription); } -#else -#define COAP_MALLOC_TYPE(Type) \ - ((coap_##Type##_t *)coap_malloc(sizeof(coap_##Type##_t))) -#define COAP_FREE_TYPE(Type, Object) coap_free(Object) #endif #define COAP_PRINT_STATUS_MAX (~COAP_PRINT_STATUS_MASK) @@ -530,7 +510,7 @@ coap_free_resource(coap_resource_t *resource) { coap_session_release( obs->session ); coap_delete_pdu(obs->pdu); coap_delete_cache_key(obs->cache_key); - COAP_FREE_TYPE( subscription, obs ); + coap_free_type(COAP_SUBSCRIPTION, obs); } if (resource->proxy_name_count && resource->proxy_name_list) { size_t i; @@ -784,7 +764,7 @@ static const uint16_t cache_ignore_options[] = { COAP_OPTION_ETAG }; } /* Create a new subscription */ - s = COAP_MALLOC_TYPE(subscription); + s = coap_malloc_type(COAP_SUBSCRIPTION, sizeof(coap_subscription_t)); if (!s) { coap_delete_cache_key(cache_key); @@ -796,7 +776,7 @@ static const uint16_t cache_ignore_options[] = { COAP_OPTION_ETAG }; request->token, NULL); if (s->pdu == NULL) { coap_delete_cache_key(cache_key); - COAP_FREE_TYPE(subscription, s); + coap_free_type(COAP_SUBSCRIPTION, s); return NULL; } if (coap_get_data(request, &len, &data)) { @@ -810,7 +790,7 @@ static const uint16_t cache_ignore_options[] = { COAP_OPTION_ETAG }; if (cache_key == NULL) { coap_delete_pdu(s->pdu); coap_delete_cache_key(cache_key); - COAP_FREE_TYPE(subscription, s); + coap_free_type(COAP_SUBSCRIPTION, s); return NULL; } } @@ -863,7 +843,7 @@ coap_delete_observer(coap_resource_t *resource, coap_session_t *session, coap_session_release( session ); coap_delete_pdu(s->pdu); coap_delete_cache_key(s->cache_key); - COAP_FREE_TYPE(subscription,s); + coap_free_type(COAP_SUBSCRIPTION, s); } return s != NULL; @@ -879,7 +859,7 @@ coap_delete_observers(coap_context_t *context, coap_session_t *session) { coap_session_release(session); coap_delete_pdu(s->pdu); coap_delete_cache_key(s->cache_key); - COAP_FREE_TYPE(subscription, s); + coap_free_type(COAP_SUBSCRIPTION, s); } } }