From 5c26f5382815480a02fb5ae415953fcb7e1af43a Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Wed, 5 Aug 2020 17:13:38 +0200 Subject: [PATCH] pkg/openwsn: add openwsn_sock_udp module Co-authored-by: Timothy Claeys --- pkg/openwsn/Makefile | 12 +- pkg/openwsn/Makefile.dep | 34 +- pkg/openwsn/Makefile.include | 48 +- pkg/openwsn/contrib/eui64.c | 4 +- pkg/openwsn/doc.txt | 2 +- ...clude-RIOT-OpenWSN-board-definitions.patch | Bin 1432 -> 1434 bytes ...penserial-rename-include-for-RIOT-Op.patch | Bin 717 -> 719 bytes ...Chigh-neighbors.c-expose-neighbors_v.patch | Bin 800 -> 803 bytes ...heduler-use-thread-flags-restore-irq.patch | Bin 2344 -> 2551 bytes ...hain_defs.h-comment-out-conflict-ISR.patch | Bin 1459 -> 1461 bytes ...nstack-openstack-dont-init-idmanager.patch | Bin 848 -> 850 bytes ...007-openstack-openapps-add-debugging.patch | Bin 6670 -> 6672 bytes ...penserial-add-flag-to-echo-badcrc-fr.patch | Bin 932 -> 935 bytes ...g-skip-checking-board-unused-in-RIOT.patch | Bin 753 -> 755 bytes .../0010-inc-config.h-use-kerneldefines.patch | Bin 0 -> 2101 bytes ...11-treewide-changes-to-use-RIOT-sock.patch | Bin 0 -> 6874 bytes ...-rename-conflicting-coap_find_option.patch | Bin 0 -> 6528 bytes ...c-config-make-coap-port-configurable.patch | Bin 0 -> 1192 bytes pkg/openwsn/sock/Makefile | 3 + pkg/openwsn/sock/openwsn_sock_udp.c | 557 ++++++++++++++++++ pkg/openwsn/sock/sock_types.h | 95 +++ sys/Makefile.dep | 7 +- 22 files changed, 713 insertions(+), 49 deletions(-) create mode 100644 pkg/openwsn/patches/0010-inc-config.h-use-kerneldefines.patch create mode 100644 pkg/openwsn/patches/0011-treewide-changes-to-use-RIOT-sock.patch create mode 100644 pkg/openwsn/patches/0012-openweb-opencoap-rename-conflicting-coap_find_option.patch create mode 100644 pkg/openwsn/patches/0013-inc-config-make-coap-port-configurable.patch create mode 100644 pkg/openwsn/sock/Makefile create mode 100644 pkg/openwsn/sock/openwsn_sock_udp.c create mode 100644 pkg/openwsn/sock/sock_types.h diff --git a/pkg/openwsn/Makefile b/pkg/openwsn/Makefile index 953c5c3e9c..7417188850 100644 --- a/pkg/openwsn/Makefile +++ b/pkg/openwsn/Makefile @@ -1,6 +1,6 @@ PKG_NAME=openwsn PKG_URL=https://github.com/openwsn-berkeley/openwsn-fw.git -PKG_VERSION=028db872c0c60f756e16880a0c86d6282e421c71 +PKG_VERSION=e2958a031ad50a6f3eeca3a98ad1ae85aa773a48 PKG_LICENSE=BSD-3-Clause include $(RIOTBASE)/pkg/pkg.mk @@ -8,11 +8,14 @@ include $(RIOTBASE)/pkg/pkg.mk # openwsn_% RIOT Modules or PSEUDOMODULES that don't have custom rules IGNORE_MODULES := openwsn_leds \ openwsn_debugpins \ - openwsn_6lo_frag \ + openwsn_6lo_fragmentation \ openwsn_icmpv6_echo \ openwsn_iee802154e_security \ openwsn_radio \ openwsn_riotos \ + openwsn_sock \ + openwsn_sock_async \ + openwsn_sock_udp \ openwsn_serial \ openwsn_sctimer \ openwsn_sctimer_rtt \ @@ -42,14 +45,13 @@ OPENWSN_PATH_openapps = openapps OPENWSN_PATH_openweb = openweb OPENWSN_PATH_drivers = drivers/common OPENWSN_PATH_crypto = drivers/common/crypto -OPENWSN_PATH_openos = kernel/openos OPENWSN_PATH_cjoin = openapps/cjoin -OPENWSN_PATH_opencoap = openweb/opencoap +OPENWSN_PATH_coap = openweb/opencoap OPENWSN_PATH_mac_low = openstack/02a-MAClow OPENWSN_PATH_mac_high = openstack/02b-MAChigh OPENWSN_PATH_iphc = openstack/03a-IPHC OPENWSN_PATH_ipv6 = openstack/03b-IPv6 -OPENWSN_PATH_transport = openstack/04-TRAN +OPENWSN_PATH_udp = openstack/04-TRAN OPENWSN_PATH_crosslayers = openstack/cross-layers all: $(OPENWSN_MODULES) diff --git a/pkg/openwsn/Makefile.dep b/pkg/openwsn/Makefile.dep index 26f6cdc870..8d3d073bf2 100644 --- a/pkg/openwsn/Makefile.dep +++ b/pkg/openwsn/Makefile.dep @@ -3,9 +3,7 @@ ifneq (,$(filter openwsn_openstack,$(USEMODULE))) USEMODULE += openwsn_ipv6 USEMODULE += openwsn_mac_low USEMODULE += openwsn_mac_high - USEMODULE += openwsn_transport USEMODULE += openwsn_crosslayers - USEMODULE += openwsn_drivers USEMODULE += openwsn_sctimer USEMODULE += openwsn_radio @@ -19,13 +17,7 @@ ifneq (,$(filter openwsn_openstack,$(USEMODULE))) endif ifneq (,$(filter openwsn_scheduler,$(USEMODULE))) - ifeq (,$(filter openwsn_openos,$(USEMODULE))) - USEMODULE += openwsn_riotos - endif -endif - -ifneq (,$(filter openwsn_openos,$(USEMODULE))) - USEMODULE += core_thread_flags + USEMODULE += openwsn_riotos endif ifneq (,$(filter openwsn_riotos,$(USEMODULE))) @@ -39,10 +31,15 @@ ifneq (,$(filter openwsn_ipv6,$(USEMODULE))) endif ifneq (,$(filter openwsn_cjoin,$(USEMODULE))) - USEMODULE += openwsn_opencoap + USEMODULE += openwsn_coap USEMODULE += openwsn_crypto endif +ifneq (,$(filter openwsn_coap,$(USEMODULE))) + # The implementation of sock_udp used by openwsn_coap is asynchronous + USEMODULE += openwsn_sock_async +endif + ifneq (,$(filter openwsn_crypto,$(USEMODULE))) USEMODULE += crypto_3des USEMODULE += cipher_modes @@ -99,9 +96,24 @@ ifneq (,$(filter openwsn_debugpins,$(USEMODULE))) FEATURES_REQUIRED += periph_gpio_irq endif +ifneq (,$(filter sock_udp,$(USEMODULE))) + USEMODULE += ipv6_addr + USEMODULE += openwsn_udp + USEMODULE += openwsn_sock_udp +endif + +ifneq (,$(filter openwsn_sock%,$(USEMODULE))) + USEMODULE += openwsn_sock + USEMODULE += core_mbox + USEMODULE += ztimer_usec +endif + +ifneq (,$(filter openwsn_sock_async,$(USEMODULE))) + USEMODULE += sock_async +endif + ifneq (,$(filter shell_commands,$(USEMODULE))) USEMODULE += l2util endif - # This port currently requires setting ISR_STACKSIZE FEATURES_BLACKLIST += arch_esp32 arch_esp8266 arch_riscv arch_avr8 diff --git a/pkg/openwsn/Makefile.include b/pkg/openwsn/Makefile.include index 471d9bb67b..5b70c175cd 100644 --- a/pkg/openwsn/Makefile.include +++ b/pkg/openwsn/Makefile.include @@ -1,9 +1,11 @@ PSEUDOMODULES += openwsn_serial \ openwsn_debugpins \ - openwsn_6lo_frag \ + openwsn_6lo_fragmentation \ openwsn_icmpv6_echo \ openwsn_iee802154e_security \ openwsn_leds \ + openwsn_sock \ + openwsn_sock_async \ openwsn_scheduler \ openwsn_sctimer \ openwsn_sctimer_rtt \ @@ -32,44 +34,30 @@ INCLUDES += -I$(PKGDIRBASE)/openwsn \ -I$(PKGDIRBASE)/openwsn/openweb/opencoap \ -I$(RIOTBASE)/pkg/openwsn/include \ -ifneq (,$(filter openwsn_openos,$(USEMODULE))) - INCLUDES += -I$(PKGDIRBASE)/openwsn/kernel/openos -endif - ifneq (,$(filter openwsn_riotos,$(USEMODULE))) INCLUDES += -I$(RIOTBASE)/pkg/openwsn/scheduler DIRS += $(RIOTBASE)/pkg/openwsn/scheduler endif +ifneq (,$(filter openwsn_sock_udp,$(USEMODULE))) + INCLUDES += -I$(RIOTBASE)/pkg/openwsn/sock + DIRS += $(RIOTBASE)/pkg/openwsn/sock +endif + # Set OpenWSN configurations flags, see $(PKG_SOURCE_DIR)/openwsn-fw/inc/config.h - ifneq (,$(filter openwsn_cjoin,$(USEMODULE))) - CFLAGS += -DOPENWSN_CJOIN_C - CFLAGS += -DBOARD_CRYPTOENGINE_ENABLED + CFLAGS += -DBOARD_CRYPTOENGINE_ENABLED=1 endif -ifneq (,$(filter openwsn_transport,$(USEMODULE))) - CFLAGS += -DOPENWSN_UDP_C -endif - -ifneq (,$(filter openwsn_opencoap,$(USEMODULE))) - CFLAGS += -DOPENWSN_COAP_C -endif - -ifneq (,$(filter openwsn_6lo_frag,$(USEMODULE))) - CFLAGS += -DOPENWSN_6LO_FRAGMENTATION_C -endif - -ifneq (,$(filter openwsn_icmpv6_echo,$(USEMODULE))) - CFLAGS += -DOPENWSN_ICMPV6ECHO_C -endif - -ifneq (,$(filter openwsn_iee802154e_security,$(USEMODULE))) - CFLAGS += -DOPENWSN_IEEE802154E_SECURITY_C -endif - -ifneq (,$(filter openwsn_adaptive_msf,$(USEMODULE))) - CFLAGS += -DOPENWSN_ADAPTIVE_MSF +ifneq (,$(filter openwsn_sock%,$(USEMODULE))) + CFLAGS += -DSOCK_HAS_IPV6 + ifneq (,$(filter openwsn_sock_async,$(USEMODULE))) + CFLAGS += -DSOCK_HAS_ASYNC + endif + ifneq (,$(filter sock_async_event,$(USEMODULE))) + # Needed only if using event and not simple callbacks + CFLAGS += -DSOCK_HAS_ASYNC_CTX + endif endif # In OpenWSN the ISR stack is shared with the network stack. OpenWSN stack is diff --git a/pkg/openwsn/contrib/eui64.c b/pkg/openwsn/contrib/eui64.c index 60af85c34c..3762dfb83a 100644 --- a/pkg/openwsn/contrib/eui64.c +++ b/pkg/openwsn/contrib/eui64.c @@ -43,7 +43,7 @@ void eui64_get(uint8_t *addressToWrite) _eui64_is_set = true; } memcpy(addressToWrite, _eui64.uint8, sizeof(_eui64.uint8)); -#else +#elif MODULE_OPENWSN_RADIO_NETDEV eui64_t eui64; if (openwsn_radio.dev->driver->get(openwsn_radio.dev, NETOPT_ADDRESS_LONG, @@ -54,5 +54,7 @@ void eui64_get(uint8_t *addressToWrite) else { luid_get_eui64((eui64_t *) addressToWrite); } +#else + memset(addressToWrite, 0, sizeof(eui64_t)); #endif } diff --git a/pkg/openwsn/doc.txt b/pkg/openwsn/doc.txt index 5c43457222..c6c3a5491b 100644 --- a/pkg/openwsn/doc.txt +++ b/pkg/openwsn/doc.txt @@ -288,7 +288,7 @@ lower the stack footprint. - `openwsn_cjoin`: this enabled the use of Constrained Join Protocol (CoJP) - - `openwsn_6lo_frag`: this enable 6LoWPAN fragmentation + - `openwsn_6lo_fragmentation`: this enable 6LoWPAN fragmentation - `openwsn_iee802154e_security`: enable link layer security - `openwsn_adaptive_msf`: allow the MSF algorithm to dynamically remove and allocate slots diff --git a/pkg/openwsn/patches/0001-bsp-kernel-include-RIOT-OpenWSN-board-definitions.patch b/pkg/openwsn/patches/0001-bsp-kernel-include-RIOT-OpenWSN-board-definitions.patch index 190cba7ac486e15513dbe478e20b5494a3703061..e38c6dcc6b0244a3ceb13a1229b5ead5a0ff78ab 100644 GIT binary patch delta 63 zcmbQiJ&Rk{ttdZN!6?PZGC3{H(9poxILXw|GQ~VODa|4^)i62P&>|@{%_PkzDbXO+ SXrgW_tAU}uq2b1@k68d)trLX+ delta 61 zcmbQmJ%d}1d%sAD|%rq@6F)_`;$THE$Al1aw#L^_iAT=q~ uVxn#ZtC7BCtit3%M#+gs&j}?a8z)($nI`M$r5U6oCmC9%ZeGf$#RvebHX6eK diff --git a/pkg/openwsn/patches/0003-openstack-02b-MAChigh-neighbors.c-expose-neighbors_v.patch b/pkg/openwsn/patches/0003-openstack-02b-MAChigh-neighbors.c-expose-neighbors_v.patch index 325ac93e6841ec165a7c59e1d45f16bdcbd4c4b5..d72bb8d90e890b532ff9f190494c88ac1422f75b 100644 GIT binary patch delta 79 zcmZ3$wwO)VttdZNAuZ9|#4_2^EXBkiHPO&K(JVP7%`z#;+{nNn&Ct}$$Ry3e(8R^j%ojttdZNAvrnK(A>n-#4OR&BGDklASKz*+#o60%)~Iw!ZI<*!Ys|$!qmh( zd7^Fwn}LbGp<(RgL`JQRmpK_(O%$}Xbtm6v6csX2$jmEFEh@>(&nwo@*3?lj-pt0- zz{-(oVv=TVX==8)kG+qv-oZgZ*VI(UTtOR50=cD`c_kL{B?`sK8L26yIjKeQDXB@N z>GA2QCGjDN#o5Kqr9~QL`I#x2)?9=Y`zBUE74vc_D5vJ7WTpWbyj;4c8N{bttdZN!5}d)*)YY_*dW!&Aj!bo+}PaQG}Xi)Ez!cz%+e&y$RI5_G10`t vc%p6vyMdX$p<%4TggpL0X18srER{5B*ntiG|9p| oaiVSovzfl-##K^`g62j^$;O7}dU`3zsfH$&W{I1xGS)Hz0QqMa1poj5 diff --git a/pkg/openwsn/patches/0007-openstack-openapps-add-debugging.patch b/pkg/openwsn/patches/0007-openstack-openapps-add-debugging.patch index 6b25fc3f9b9cb597844ac4ea84eeb83f9d886844..fdcdbff2fb40067acca5d5baeda43bc173d2dac7 100644 GIT binary patch delta 94 zcmeA(nP8&pR+OKsker-ql$@MmY?x$eY?xx0WNvJkYG9gbXk?O@W^Q1aYHDU|YME$i yIZ?NQ)xcce&~W35dLBWGR8zx5^Hd8xy;O@-EG&f>nHeon4VrF7xWn(llW;HlAGc__XFgIp5H)CWp zWH~uEW|1v-2QWA{rlh6Sfk-`}P3X$8h5;$QnI5IafGA=G;Fk&}kW@2KKpaD?{ RG&n3dAS*XCIJ5czssSr%Am0E0 delta 107 zcmZ3^zJy)ZttdZNA<@h%)yUk?I5o-KEYUF8BFWU$)ZEM<&D=OS)!f9;!r0I#$*eu1|(!e||HObh}JT=K8#Uwd7HPtfN#M~&+ qc%p6vtAVAyq2a_8hlNs%(oB*q&CK=m5)G3Lj8hDZH`g+jFaiLHfEn!o delta 84 zcmey&`jJ)FttdZNAvrbG+}zT@*f=f8%+x5+Jk{7T(J(pLz&JI{B*{F{!XVWw$t=yn oY@%)jv!%Y}#8rod(o7AKEK|*s_4Ldv5>pe+Ow2adGnOy{09@!9vj6}9 diff --git a/pkg/openwsn/patches/0010-inc-config.h-use-kerneldefines.patch b/pkg/openwsn/patches/0010-inc-config.h-use-kerneldefines.patch new file mode 100644 index 0000000000000000000000000000000000000000..fce0b57828cb9979915c89912152194a895b87b6 GIT binary patch literal 2101 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 literal 0 HcmV?d00001 diff --git a/pkg/openwsn/patches/0013-inc-config-make-coap-port-configurable.patch b/pkg/openwsn/patches/0013-inc-config-make-coap-port-configurable.patch new file mode 100644 index 0000000000000000000000000000000000000000..aedd2159bdf5ed78cb19ed1eecc5819769749ab9 GIT binary patch literal 1192 zcmaJ=+in^$5Pi3le;6q*kY!nWf#sr7K?5kLfkgq7N^OOV*A8xBjrP*CYCfvp&@bzl zB+Vu?wGcbkGh?5bQDSx=cu-S}Nx#jbb|ARot$L$I10hA=`%%5ol$@!c2@?~;T<(E2 zfzr<52R@~Yj1Z;+qlCvor@~<1R>vIPD7iaGywJDTh%IKyeWiKSb_%ix^4Oe0>O4) zqV#&;`Yfmf;MfmqK(9yO6tAIU3E^xwy`E23=V5=gI*0LmwVV$JrAatgUJh49ZyA&D z_F54jj(2uO95{nd2=g3c7G5n@gW;&Zyj<9jL)hR@EQM?%@hue3x7j@lnSnf&piBa` zgU1AqIHy|Kr~V)KKkrbik0h2FL913qxX0GP^Pv0cfqBNoSJ;^-x1_!r*X`mf91&R< zk9#Vg3=d=m+z)Dk(`uF0>wY7st&hnpBt6ktFj_*}?Mf4z!#}Dr&Uf&W*sI<0B-SyG zyV6OT;l@nn@4zVVfBym_GMV8X{J`PIxzmw^Tb*rSpU7|8 literal 0 HcmV?d00001 diff --git a/pkg/openwsn/sock/Makefile b/pkg/openwsn/sock/Makefile new file mode 100644 index 0000000000..7503afa6ce --- /dev/null +++ b/pkg/openwsn/sock/Makefile @@ -0,0 +1,3 @@ +MODULE = openwsn_sock_udp + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/openwsn/sock/openwsn_sock_udp.c b/pkg/openwsn/sock/openwsn_sock_udp.c new file mode 100644 index 0000000000..9e7d2980e8 --- /dev/null +++ b/pkg/openwsn/sock/openwsn_sock_udp.c @@ -0,0 +1,557 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * @author Timothy Claeys + * @author Francisco Molina + */ + +#include + +#ifdef SOCK_HAS_ASYNC +#include "net/sock/async.h" +#endif +#include "net/ipv6/addr.h" +#include "net/iana/portrange.h" +#include "net/sock/udp.h" +#ifdef MODULE_ZTIMER_USEC +#include "ztimer.h" +#endif +#include "utlist.h" +#include "log.h" + +#include "openwsn.h" +#include "opendefs.h" +#include "kernel/scheduler.h" +#include "cross-layers/packetfunctions.h" +#include "cross-layers/openqueue.h" +#include "cross-layers/openrandom.h" +#include "cross-layers/idmanager.h" +#include "04-TRAN/udp.h" + +#define _MSG_TYPE_RECV_PKT (0x1601) +#ifdef MODULE_ZTIMER_USEC +#define _TIMEOUT_MAGIC (0xF38A0B63U) +#define _TIMEOUT_MSG_TYPE (0x8474) +#endif /* MODULE_ZTIMER_USEC */ + +static sock_udp_t *_udp_socket_list; + +#ifdef MODULE_ZTIMER_USEC +static void _timeout_cb(void *arg) +{ + msg_t timeout_msg = { .sender_pid = KERNEL_PID_UNDEF, + .type = _TIMEOUT_MSG_TYPE, + .content = { .value = _TIMEOUT_MAGIC } }; + mbox_t *mbox = arg; + + /* should be safe, because otherwise if mbox were filled this callback is + * senseless */ + mbox_try_put(mbox, &timeout_msg); +} +#endif /* MODULE_ZTIMER_USEC */ + +static void _sock_transmit_internal(void) +{ + OpenQueueEntry_t *pkt; + + pkt = openqueue_getPacketByComponent(COMPONENT_SOCK_TO_UDP); + + if (pkt == NULL) { + LOG_ERROR("%s: not pkt in queue\n", __FUNCTION__); + return; + } + + udp_transmit(pkt); +} + +static bool _sock_valid_af(uint8_t af) +{ + /* only AF_INET6 is supported*/ + return (af == AF_INET6); +} + +static bool _sock_valid_addr(sock_udp_ep_t *ep) +{ + assert(ep != NULL); + const uint8_t *p = (uint8_t *)&ep->addr; + for (uint8_t i = 0; i < sizeof(ep->addr); i++) { + if (p[i] != 0) { + return true; + } + } + return false; +} + +static bool _sock_port_in_use(uint16_t port) +{ + for (sock_udp_t *ptr = _udp_socket_list; ptr != NULL; + ptr = (sock_udp_t *)ptr->next) { + if (ptr->gen_sock.local.port == port) { + return true; + } + } + return false; +} + +/** + * @brief returns a UDP port, and checks for reuse if required + * + * implements "Another Simple Port Randomization Algorithm" as specified in + * RFC 6056, see https://tools.ietf.org/html/rfc6056#section-3.3.2 + */ +static uint16_t _get_dyn_port(void) +{ + unsigned num = (IANA_DYNAMIC_PORTRANGE_MAX - IANA_DYNAMIC_PORTRANGE_MIN); + unsigned count = num; + + do { + uint16_t port = IANA_DYNAMIC_PORTRANGE_MIN + + (openrandom_get16b() % num); + if (!_sock_port_in_use(port)) { + return port; + } + --count; + } while (count > 0); + return 0; +} + +void sock_udp_init(void) +{ + _udp_socket_list = NULL; +} + +int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local, + const sock_udp_ep_t *remote, uint16_t flags) +{ + /* sanity checks */ + assert(sock); + assert(remote == NULL || remote->port != 0); + /* check that if set netifs match */ + if ((local != NULL) && (remote != NULL) && + (local->netif != SOCK_ADDR_ANY_NETIF) && + (remote->netif != SOCK_ADDR_ANY_NETIF) && + (local->netif != remote->netif)) { + return -EINVAL; + } + /* if set netifs should match the only one available in OpenWSN*/ + if ((local != NULL) && + (local->netif != SOCK_ADDR_ANY_NETIF) && + (local->netif != openwsn_get_netif())) { + return -EINVAL; + } + if ((remote != NULL) && + (remote->netif != SOCK_ADDR_ANY_NETIF) && + (remote->netif != openwsn_get_netif())) { + return -EINVAL; + } + + /* check local */ + memset(&sock->gen_sock.local, 0, sizeof(sock_udp_ep_t)); + if (local != NULL) { + uint16_t port = local->port; + if (!_sock_valid_af(local->family)) { + return -EAFNOSUPPORT; + } + if (port == 0U) { + port = _get_dyn_port(); + if (port == 0U) { + return -EADDRINUSE; + } + } + else if (!(flags & SOCK_FLAGS_REUSE_EP)) { + /* a single IPV6 address is possible in OpenWSN, so only check + if port is in use */ + if (_sock_port_in_use(port)) { + return -EADDRINUSE; + } + } + memcpy(&sock->gen_sock.local, local, sizeof(sock_udp_ep_t)); + sock->gen_sock.local.port = port; + } + + /* check and set remote */ + memset(&sock->gen_sock.remote, 0, sizeof(sock_udp_ep_t)); + if (remote != NULL) { + if (!_sock_valid_af(remote->family)) { + return -EAFNOSUPPORT; + } + + if (!_sock_valid_addr((sock_udp_ep_t *)remote)) { + return -EINVAL; + } + memcpy(&sock->gen_sock.remote, remote, sizeof(sock_udp_ep_t)); + } + + /* if all ok and local != NULL, listen */ + if (local != NULL) { + /* start mailbox */ + mbox_init(&sock->mbox, sock->mbox_queue, OPENWSN_SOCK_MBOX_SIZE); +#ifdef SOCK_HAS_ASYNC + sock->async_cb = NULL; +#endif + /* update socket list */ + LL_PREPEND(_udp_socket_list, sock); + } + + /* set flags */ + sock->gen_sock.flags = flags; + + return 0; +} + +ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len, + const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux) +{ + (void)aux; + OpenQueueEntry_t *pkt; + open_addr_t dst_addr, src_addr; + + memset(&dst_addr, 0, sizeof(open_addr_t)); + memset(&src_addr, 0, sizeof(open_addr_t)); + uint16_t src_port = 0, dst_port; + + /* asserts for sock_udp_send "pre" */ + assert((sock != NULL) || (remote != NULL)); + assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */ + + /* check remote */ + if (remote != NULL) { + if (remote->port == 0) { + return -EINVAL; + } + else if (!_sock_valid_af(remote->family)) { + return -EAFNOSUPPORT; + } + else if (!_sock_valid_addr((sock_udp_ep_t *)remote)) { + return -EINVAL; + } + else if ((sock != NULL) && + (sock->gen_sock.local.netif != SOCK_ADDR_ANY_NETIF) && + (remote->netif != SOCK_ADDR_ANY_NETIF) && + (sock->gen_sock.local.netif != remote->netif)) { + return -EINVAL; + } + /* if set netifs should match the only one available in OpenWSN*/ + if ((sock != NULL) && + (((sock->gen_sock.local.netif != SOCK_ADDR_ANY_NETIF) && + (sock->gen_sock.local.netif != openwsn_get_netif())) || + ((remote->netif != SOCK_ADDR_ANY_NETIF) && + (remote->netif != openwsn_get_netif())))) { + return -EINVAL; + } + dst_addr.type = ADDR_128B; + memcpy(&dst_addr.addr_128b, &remote->addr, LENGTH_ADDR128b); + dst_port = remote->port; + } + /* if remote is null then check that sock has a remote */ + else if (sock->gen_sock.remote.family == AF_UNSPEC) { + return -ENOTCONN; + } + /* set destination port and address based on sock remote */ + else { + dst_port = sock->gen_sock.remote.port; + dst_addr.type = ADDR_128B; + memcpy(&dst_addr.addr_128b, &sock->gen_sock.remote.addr, + LENGTH_ADDR128b); + } + + if ((sock == NULL) || (sock->gen_sock.local.family == AF_UNSPEC)) { + /* if no sock or unbound get a random port */ + if ((src_port = _get_dyn_port()) == 0) { + return -EADDRINUSE; + } + } + else { + /* set src port from sock */ + src_port = sock->gen_sock.local.port; + /* set addr if sock is not null or bound */ + src_addr.type = ADDR_128B; + memcpy(&src_addr.addr_128b, &sock->gen_sock.local.addr, + LENGTH_ADDR128b); + } + + /* get pkt buffer and take owner ship */ + if ((pkt = openqueue_getFreePacketBuffer(COMPONENT_SOCK_TO_UDP)) == NULL) { + return -ENOMEM; + } + pkt->owner = COMPONENT_SOCK_TO_UDP; + pkt->creator = COMPONENT_SOCK_TO_UDP; + + /* set addresses and ports */ + pkt->l3_destinationAdd.type = ADDR_128B; + pkt->l3_sourceAdd.type = ADDR_128B; + memcpy(&pkt->l3_sourceAdd.addr_128b, &src_addr.addr_128b, LENGTH_ADDR128b); + memcpy(&pkt->l3_destinationAdd.addr_128b, &dst_addr.addr_128b, + LENGTH_ADDR128b); + pkt->l4_destination_port = dst_port; + pkt->l4_sourcePortORicmpv6Type = src_port; + + /* set payload */ + if (packetfunctions_reserveHeader(&pkt, len)) { + openqueue_freePacketBuffer(pkt); + return -ENOMEM; + } + memcpy(pkt->payload, data, len); + pkt->l4_payload = pkt->payload; + pkt->l4_length = pkt->length; + + /* push task to scheduler send */ + scheduler_push_task(_sock_transmit_internal, TASKPRIO_UDP); + + return len; +} + +void sock_udp_close(sock_udp_t *sock) +{ + if (_udp_socket_list == NULL) { + return; + } + if (sock) { + LL_DELETE(_udp_socket_list, sock); + sock->next = NULL; + } +} + +int sock_udp_get_local(sock_udp_t *sock, sock_udp_ep_t *ep) +{ + if (sock->gen_sock.local.family == AF_UNSPEC) { + return -EADDRNOTAVAIL; + } + + memcpy(ep, &sock->gen_sock.local, sizeof(sock_udp_ep_t)); + + return 0; +} + +int sock_udp_get_remote(sock_udp_t *sock, sock_udp_ep_t *ep) +{ + if (sock->gen_sock.remote.family == AF_UNSPEC) { + return -ENOTCONN; + } + + memcpy(ep, &sock->gen_sock.remote, sizeof(sock_udp_ep_t)); + + return 0; +} + +ssize_t sock_udp_recv_aux(sock_udp_t *sock, void *data, size_t max_len, + uint32_t timeout, sock_udp_ep_t *remote, + sock_udp_aux_rx_t *aux) +{ + void *pkt = NULL, *ctx = NULL; + ssize_t res; + + assert((sock != NULL) && (data != NULL) && (max_len > 0)); + res = sock_udp_recv_buf_aux(sock, &pkt, &ctx, timeout, remote, aux); + /* set data to copy, check if enough buffer space */ + if (res >= 0) { + ssize_t tmp; + if ((ssize_t)max_len >= res) { + memset(data, 0, max_len); + if (res > 0) { + /* copy received data */ + memcpy(data, pkt, res); + /* free packet */ + tmp = sock_udp_recv_buf_aux(sock, &pkt, &ctx, timeout, remote, + aux); + assert(tmp == 0); + } + (void) tmp; + } + else { + res = -ENOBUFS; + /* free packet */ + tmp = sock_udp_recv_buf_aux(sock, &pkt, &ctx, timeout, remote, aux); + assert(tmp == 0); + } + } + return res; +} + +ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, + uint32_t timeout, sock_udp_ep_t *remote, + sock_udp_aux_rx_t *aux) +{ + (void) aux; + sock_udp_ep_t ep; + OpenQueueEntry_t *pkt = NULL; + msg_t msg; + + assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL)); + + if (*buf_ctx != NULL) { + *data = NULL; + openqueue_freePacketBuffer(*buf_ctx); + *buf_ctx = NULL; + return 0; + } + if (sock->gen_sock.local.family == AF_UNSPEC) { + return -EADDRNOTAVAIL; + } + +#ifdef MODULE_ZTIMER_USEC + ztimer_t timer; + + if ((timeout != SOCK_NO_TIMEOUT) && (timeout != 0)) { + timer.callback = _timeout_cb; + timer.arg = &sock->mbox; + ztimer_set(ZTIMER_USEC, &timer, timeout); + } +#endif /* MODULE_ZTIMER_USEC */ + if (timeout != 0) { + mbox_get(&sock->mbox, &msg); + } + else { + if (!mbox_try_get(&sock->mbox, &msg)) { + return -EAGAIN; + } + } +#ifdef MODULE_ZTIMER_USEC + if ((timeout != SOCK_NO_TIMEOUT) && (timeout != 0)) { + ztimer_remove(ZTIMER_USEC, &timer); + } +#endif /* MODULE_ZTIMER_USEC */ + switch (msg.type) { + case _MSG_TYPE_RECV_PKT: + pkt = msg.content.ptr; + break; +#ifdef MODULE_ZTIMER_USEC + case _TIMEOUT_MSG_TYPE: + if (msg.content.value == _TIMEOUT_MAGIC) { + return -ETIMEDOUT; + } +#endif /* MODULE_ZTIMER_USEC */ + /* Falls Through. */ + default: + return -EINVAL; + } + + if (pkt == NULL) { + return -EINVAL; + } + + /* copy source port and address to end point */ + ep.family = AF_INET6; + ep.port = pkt->l4_sourcePortORicmpv6Type; + ep.netif = openwsn_get_netif(); + memcpy(&ep.addr, pkt->l3_sourceAdd.addr_128b, LENGTH_ADDR128b); + + if (remote != NULL) { + /* return remote if requested */ + memcpy(remote, &ep, sizeof(sock_udp_ep_t)); + } + + if ((sock->gen_sock.remote.family != AF_UNSPEC) && + /* check remote end-point if set */ + ((sock->gen_sock.remote.port != pkt->l4_sourcePortORicmpv6Type) || + /* We only have IPv6 for now, so just comparing the whole end point + * should suffice */ + ((memcmp(&sock->gen_sock.remote.addr, &ipv6_addr_unspecified, + sizeof(ipv6_addr_t)) != 0) && + (memcmp(&sock->gen_sock.remote.addr, &ep.addr, + sizeof(ipv6_addr_t)) != 0)))) { + openqueue_freePacketBuffer(pkt); + return -EPROTO; + } + + *data = pkt->l4_payload; + *buf_ctx = pkt; + + return pkt->l4_length; +} + +#ifdef SOCK_HAS_ASYNC +void sock_udp_set_cb(sock_udp_t *sock, sock_udp_cb_t cb, void *cb_arg) +{ + sock->async_cb = cb; + sock->async_cb_arg = cb_arg; +} + +#ifdef SOCK_HAS_ASYNC_CTX +sock_async_ctx_t *sock_udp_get_async_ctx(sock_udp_t *sock) +{ + return &sock->async_ctx; +} +#endif /* SOCK_HAS_ASYNC_CTX*/ +#endif /* SOCK_HAS_ASYNC */ + +void sock_receive_internal(void) +{ + OpenQueueEntry_t *pkt; + sock_udp_t *current; + + pkt = openqueue_getPacketByComponent(COMPONENT_UDP_TO_SOCK); + + if (pkt == NULL) { + LOG_ERROR("%s: not pkt in queue\n", __FUNCTION__); + return; + } + current = _udp_socket_list; + while (current != NULL) { + if (current->gen_sock.local.port == pkt->l4_destination_port && + idmanager_isMyAddress(&pkt->l3_destinationAdd)) { + msg_t msg; + msg.type = _MSG_TYPE_RECV_PKT; + msg.content.ptr = pkt; + int ret = mbox_try_put(¤t->mbox, &msg); + if (ret < 1) { + LOG_ERROR( + "openwsn_sock: dropped message to %p (was full)\n", + (void *)¤t->mbox); + } +#ifdef SOCK_HAS_ASYNC + if (current->async_cb != NULL) { + current->async_cb(current, SOCK_ASYNC_MSG_RECV, NULL); + } +#endif /* SOCK_HAS_ASYNC */ + break; + } + + current = current->next; + } + + if (current == NULL) { + openqueue_freePacketBuffer(pkt); + LOG_ERROR("%s: no associated socket found\n", __FUNCTION__); + } +} + +void sock_senddone_internal(OpenQueueEntry_t *msg, owerror_t error) +{ + /* In RIOT we can't know what message was sent... */ + (void)msg; +#ifdef SOCK_HAS_ASYNC + OpenQueueEntry_t *pkt; + sock_udp_t *current; + + pkt = openqueue_getPacketByComponent(COMPONENT_UDP); + + if (pkt == NULL) { + LOG_ERROR("%s: not pkt in queue\n", __FUNCTION__); + return; + } + + current = _udp_socket_list; + + while (current != NULL) { + if (current->gen_sock.local.port == pkt->l4_sourcePortORicmpv6Type && + current->async_cb != NULL) { + current->async_cb(current, SOCK_ASYNC_MSG_SENT, &error); + break; + } + + current = current->next; + } +#else /* SOCK_HAS_ASYNC */ + (void)error; +#endif /*SOCK_HAS_ASYNC */ +} diff --git a/pkg/openwsn/sock/sock_types.h b/pkg/openwsn/sock/sock_types.h new file mode 100644 index 0000000000..af2c0ec124 --- /dev/null +++ b/pkg/openwsn/sock/sock_types.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup pkg_openwsn_sock + * @{ + * + * @file + * @brief OpenWSN-specific types + * + * @author Timothy Claeys + * @author Francisco Molina + */ + +#ifndef SOCK_TYPES_H +#define SOCK_TYPES_H + +#include "mbox.h" +#include "net/af.h" +#ifdef SOCK_HAS_ASYNC +#include "net/sock/async/types.h" +#endif +#include "net/sock/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Default size for OpenWSN sock_udp_t::mbox_queue (as exponent of 2^n). + * + * As the queue size ALWAYS needs to be power of two, this option + * represents the exponent of 2^n, which will be used as the size of + * the queue. + */ +#ifndef CONFIG_OPENWSN_SOCK_MBOX_SIZE_EXP +#define CONFIG_OPENWSN_SOCK_MBOX_SIZE_EXP (3) +#endif + +/** + * @brief Size for OpenWSN sock_udp_t::mbox_queue + */ +#ifndef OPENWSN_SOCK_MBOX_SIZE +#define OPENWSN_SOCK_MBOX_SIZE (1 << CONFIG_OPENWSN_SOCK_MBOX_SIZE_EXP) +#endif + +/** + * @brief Forward declaration + * @internal + */ +typedef struct openwsn_gen_sock openwsn_gen_sock_t; + +/** + * @brief Generic openwsn sock type + * @warning For network stack internal purposes only. Do not access members + * externally. + * @internal + */ +struct openwsn_gen_sock { + sock_udp_ep_t local; /**< local end-point */ + sock_udp_ep_t remote; /**< remote end-point */ + uint16_t flags; /**< option flags */ +}; + +/** + * @brief UDP sock type + * @warning For network stack internal purposes only. Do not access members + * externally. + * @internal + */ +struct sock_udp { + struct sock_udp *next; /**< sock liked list */ + openwsn_gen_sock_t gen_sock; /**< Generic socket */ + mbox_t mbox; /**< @ref core_mbox target for the sock */ + msg_t mbox_queue[OPENWSN_SOCK_MBOX_SIZE]; /**< queue for gnrc_sock_reg_t::mbox */ +#ifdef MODULE_SOCK_ASYNC_EVENT + sock_async_ctx_t async_ctx; /**< asynchronous event context */ +#endif +#ifdef SOCK_HAS_ASYNC + sock_udp_cb_t async_cb; /**< asynchronous callback */ + void* async_cb_arg; +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif /* SOCK_TYPES_H */ +/** @} */ diff --git a/sys/Makefile.dep b/sys/Makefile.dep index c2f557cb6b..22f67c9ea0 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -837,12 +837,17 @@ endif ifneq (,$(filter gcoap,$(USEMODULE))) USEMODULE += nanocoap - USEMODULE += sock_async USEMODULE += sock_async_event USEMODULE += sock_udp USEMODULE += sock_util USEMODULE += event_callback USEMODULE += event_timeout +ifneq (,$(filter gnrc%,$(USEMODULE))) + USEMODULE += gnrc_sock_async +endif +ifneq (,$(filter openwsn%,$(USEMODULE))) + USEMODULE += openwsn_sock_udp +endif endif ifneq (,$(filter luid,$(USEMODULE)))