mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #15536 from fjmolinas/pr_openwsn_sock_selfhosted
pkg/openwsn: add sock_udp
This commit is contained in:
commit
b6bf67114b
@ -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)
|
||||
|
@ -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,15 +17,12 @@ ifneq (,$(filter openwsn_openstack,$(USEMODULE)))
|
||||
endif
|
||||
|
||||
ifneq (,$(filter openwsn_scheduler,$(USEMODULE)))
|
||||
ifeq (,$(filter openwsn_openos,$(USEMODULE)))
|
||||
# allow to mock the scheduler as needed
|
||||
ifeq (,$(filter openwsn_scheduler_mock,$(USEMODULE)))
|
||||
USEMODULE += openwsn_riotos
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter openwsn_openos,$(USEMODULE)))
|
||||
USEMODULE += core_thread_flags
|
||||
endif
|
||||
|
||||
ifneq (,$(filter openwsn_riotos,$(USEMODULE)))
|
||||
USEMODULE += event
|
||||
USEMODULE += event_callback
|
||||
@ -39,10 +34,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 +99,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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -33,6 +33,15 @@ extern "C" {
|
||||
#define OPENWSN_PANID (0xCAFE)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default NID for OpenWSN network
|
||||
*
|
||||
* @note Only one netif is currently possible in OpenWSN.
|
||||
*/
|
||||
#ifndef CONFIG_OPENWSN_NETIF_ID
|
||||
#define CONFIG_OPENWSN_NETIF_ID (0x0001)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initializes OpenWSN thread
|
||||
*
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
pkg/openwsn/patches/0010-inc-config.h-use-kerneldefines.patch
Normal file
BIN
pkg/openwsn/patches/0010-inc-config.h-use-kerneldefines.patch
Normal file
Binary file not shown.
BIN
pkg/openwsn/patches/0011-treewide-changes-to-use-RIOT-sock.patch
Normal file
BIN
pkg/openwsn/patches/0011-treewide-changes-to-use-RIOT-sock.patch
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
3
pkg/openwsn/sock/Makefile
Normal file
3
pkg/openwsn/sock/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = openwsn_sock_udp
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
557
pkg/openwsn/sock/openwsn_sock_udp.c
Normal file
557
pkg/openwsn/sock/openwsn_sock_udp.c
Normal file
@ -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 <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#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 != CONFIG_OPENWSN_NETIF_ID)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((remote != NULL) &&
|
||||
(remote->netif != SOCK_ADDR_ANY_NETIF) &&
|
||||
(remote->netif != CONFIG_OPENWSN_NETIF_ID)) {
|
||||
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 != CONFIG_OPENWSN_NETIF_ID)) ||
|
||||
((remote->netif != SOCK_ADDR_ANY_NETIF) &&
|
||||
(remote->netif != CONFIG_OPENWSN_NETIF_ID)))) {
|
||||
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 = CONFIG_OPENWSN_NETIF_ID;
|
||||
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 */
|
||||
}
|
95
pkg/openwsn/sock/sock_types.h
Normal file
95
pkg/openwsn/sock/sock_types.h
Normal file
@ -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 <timothy.claeys@inria.fr>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*/
|
||||
|
||||
#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 */
|
||||
/** @} */
|
@ -578,6 +578,7 @@ ifneq (,$(filter shell_commands,$(USEMODULE)))
|
||||
endif
|
||||
ifneq (,$(filter openwsn_%,$(USEMODULE)))
|
||||
USEMODULE += netif
|
||||
USEMODULE += ipv6_addr
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -813,6 +814,15 @@ ifneq (,$(filter sock_async_event,$(USEMODULE)))
|
||||
USEMODULE += event
|
||||
endif
|
||||
|
||||
ifneq (,$(filter sock_async,$(USEMODULE)))
|
||||
ifneq (,$(filter gnrc%,$(USEMODULE)))
|
||||
USEMODULE += gnrc_sock_async
|
||||
endif
|
||||
ifneq (,$(filter openwsn%,$(USEMODULE)))
|
||||
USEMODULE += openwsn_sock_async
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter sock_dns,$(USEMODULE)))
|
||||
USEMODULE += sock_udp
|
||||
USEMODULE += sock_util
|
||||
@ -846,12 +856,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)))
|
||||
|
@ -73,7 +73,9 @@ static const struct {
|
||||
{ "icmpv6echo", COMPONENT_ICMPv6ECHO },
|
||||
{ "icmpv6router", COMPONENT_ICMPv6ROUTER },
|
||||
{ "icmpv6rpl", COMPONENT_ICMPv6RPL },
|
||||
{ "udp", COMPONENT_OPENUDP },
|
||||
{ "udp", COMPONENT_UDP },
|
||||
{ "sock-udp", COMPONENT_SOCK_TO_UDP },
|
||||
{ "udp-sock", COMPONENT_UDP_TO_SOCK },
|
||||
{ "coap", COMPONENT_OPENCOAP },
|
||||
{ "cjoin", COMPONENT_CJOIN },
|
||||
{ "oscore", COMPONENT_OSCORE },
|
||||
|
@ -34,16 +34,19 @@ BOARD_WHITELIST = \
|
||||
# OpenWSN Modules
|
||||
USEPKG += openwsn
|
||||
USEMODULE += openwsn_openstack
|
||||
USEMODULE += sock_udp
|
||||
# This example uses async
|
||||
USEMODULE += sock_async
|
||||
|
||||
# Optional OpenWSN Modules
|
||||
## Enable Constrained Join Protocol (CoJP)
|
||||
USEMODULE += openwsn_cjoin
|
||||
## Enable 6lowpan fragmentation
|
||||
USEMODULE += openwsn_6lo_frag
|
||||
USEMODULE += openwsn_6lo_fragmentation
|
||||
## Enable link layer security
|
||||
# USEMODULE += openwsn_iee802154e_security
|
||||
## Enable MSF dynamic slot allocation
|
||||
# USEMODULE += openwsn_adaptive_msf
|
||||
# USEMODULE += openwsn_adaptive_msf
|
||||
|
||||
## Optional Module, but required for root nodes
|
||||
# USEMODULE += openwsn_serial
|
||||
@ -75,11 +78,11 @@ endif
|
||||
# export OPENWSN_LOG_LEVEL ?= LOG_ERROR
|
||||
|
||||
## Test application Modules
|
||||
USEMODULE += ipv6_addr
|
||||
USEMODULE += ps
|
||||
USEMODULE += od_string
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
|
||||
# ztimer is used instead of xtimer because it's a dependency of some
|
||||
# OpenWSN modules.
|
||||
USEMODULE += ztimer_usec
|
||||
|
@ -21,41 +21,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "od.h"
|
||||
#include "shell.h"
|
||||
|
||||
#include "opendefs.h"
|
||||
#include "04-TRAN/udp.h"
|
||||
#include "cross-layers/openqueue.h"
|
||||
|
||||
udp_resource_desc_t uinject_vars;
|
||||
|
||||
void uinject_sendDone(OpenQueueEntry_t *msg, owerror_t error)
|
||||
{
|
||||
(void)error;
|
||||
|
||||
printf("msg.l2_sendDoneError: %x\n", msg->l2_sendDoneError);
|
||||
openqueue_freePacketBuffer(msg);
|
||||
puts("Send success");
|
||||
}
|
||||
|
||||
void uinject_receive(OpenQueueEntry_t *pkt)
|
||||
{
|
||||
printf("Received %i bytes on port %i\n", (int)pkt->length,
|
||||
pkt->l4_destination_port);
|
||||
od_hex_dump(pkt->payload, pkt->length, OD_WIDTH_DEFAULT);
|
||||
openqueue_freePacketBuffer(pkt);
|
||||
}
|
||||
|
||||
void uinject_init(void)
|
||||
{
|
||||
uinject_vars.port = WKP_UDP_INJECT;
|
||||
uinject_vars.callbackReceive = &uinject_receive;
|
||||
uinject_vars.callbackSendDone = &uinject_sendDone;
|
||||
openudp_register(&uinject_vars);
|
||||
}
|
||||
|
||||
extern int udp_cmd(int argc, char **argv);
|
||||
extern void udp_cli_init(void);
|
||||
|
||||
static const shell_command_t shell_commands[] = {
|
||||
{ "udp", "Send data over UDP and listen on UDP ports", udp_cmd },
|
||||
@ -69,7 +38,7 @@ int main(void)
|
||||
printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
|
||||
printf("This board features a(n) %s MCU.\n", RIOT_MCU);
|
||||
|
||||
uinject_init();
|
||||
udp_cli_init();
|
||||
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
* Copyright (C) 2018 Hamburg University of Applied Sciences
|
||||
* 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
|
||||
@ -15,9 +16,11 @@
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -25,30 +28,61 @@
|
||||
|
||||
#include "ztimer.h"
|
||||
#include "net/ipv6.h"
|
||||
#include "net/sock/udp.h"
|
||||
#ifdef SOCK_HAS_ASYNC
|
||||
#include "net/sock/async.h"
|
||||
#endif
|
||||
#include "od.h"
|
||||
|
||||
#include "opendefs.h"
|
||||
#include "scheduler.h"
|
||||
#include "02a-MAClow/IEEE802154E.h"
|
||||
#include "03b-IPv6/icmpv6rpl.h"
|
||||
#include "04-TRAN/udp.h"
|
||||
#include "cross-layers/openqueue.h"
|
||||
|
||||
#include "cross-layers/idmanager.h"
|
||||
#include "cross-layers/packetfunctions.h"
|
||||
|
||||
extern udp_resource_desc_t uinject_vars;
|
||||
extern idmanager_vars_t idmanager_vars;
|
||||
extern openudp_vars_t openudp_vars;
|
||||
|
||||
static uint16_t counter = 0;
|
||||
static sock_udp_t _sock_udp;
|
||||
|
||||
OpenQueueEntry_t *pkt;
|
||||
void _sock_udp_handler(sock_udp_t *sock, sock_async_flags_t type, void *arg)
|
||||
{
|
||||
if (type & SOCK_ASYNC_MSG_RECV) {
|
||||
char buf[50];
|
||||
sock_udp_ep_t remote;
|
||||
int16_t res;
|
||||
|
||||
void push_pkt_cb(void){
|
||||
owerror_t ret = openudp_send(pkt);
|
||||
if (ret == E_FAIL) {
|
||||
puts("could not send");
|
||||
openqueue_freePacketBuffer(pkt);
|
||||
if ((res = sock_udp_recv(sock, buf, sizeof(buf), 0, &remote)) >= 0) {
|
||||
printf("Received %i bytes on port %i\n", res, remote.port);
|
||||
od_hex_dump(buf, res, OD_WIDTH_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if (type & SOCK_ASYNC_MSG_SENT) {
|
||||
if (*((uint8_t *)arg) == E_FAIL) {
|
||||
puts("Failed to Send");
|
||||
}
|
||||
else {
|
||||
puts("Send Success");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void udp_cli_init(void)
|
||||
{
|
||||
memset(&_sock_udp, 0, sizeof(sock_udp_t));
|
||||
sock_udp_ep_t local;
|
||||
|
||||
local.family = AF_INET6;
|
||||
local.netif = SOCK_ADDR_ANY_NETIF;
|
||||
local.port = WKP_UDP_ECHO;
|
||||
|
||||
if (sock_udp_create(&_sock_udp, &local, NULL, 0) < 0) {
|
||||
puts("Could not create socket");
|
||||
return;
|
||||
}
|
||||
|
||||
sock_udp_set_cb(&_sock_udp, _sock_udp_handler, NULL);
|
||||
}
|
||||
|
||||
static int udp_send(char *addr_str, char *port_str, char *data,
|
||||
@ -59,7 +93,6 @@ static int udp_send(char *addr_str, char *port_str, char *data,
|
||||
ipv6_addr_t addr;
|
||||
|
||||
data_len = strlen(data);
|
||||
uint8_t asnArray[data_len];
|
||||
|
||||
/* parse destination address */
|
||||
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
|
||||
@ -70,58 +103,45 @@ static int udp_send(char *addr_str, char *port_str, char *data,
|
||||
for (unsigned int i = 0; i < num; i++) {
|
||||
|
||||
printf("Send %u byte over UDP to [%s]:%s\n",
|
||||
(unsigned)data_len, addr_str, port_str);
|
||||
(unsigned)data_len, addr_str, port_str);
|
||||
|
||||
/* don't run if not in synch */
|
||||
if (ieee154e_isSynch() == FALSE) {
|
||||
puts("Error: Node not in sync, exit");
|
||||
puts("Error: node is not synchronized, exit");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* don't run on dagroot */
|
||||
if (idmanager_getIsDAGroot()) {
|
||||
puts("Error: Node is DAGROOT, exit");
|
||||
puts("Error: node is DAGROOT, exit");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool foundNeighbor = icmpv6rpl_getPreferredParentEui64(&parentNeighbor);
|
||||
if (foundNeighbor==FALSE) {
|
||||
puts("Error: No preferred parent EUI64, exit");
|
||||
if (foundNeighbor == FALSE) {
|
||||
puts("Error: no preferred parent EUI64, exit");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get a free packet buffer */
|
||||
pkt = openqueue_getFreePacketBuffer(COMPONENT_UINJECT);
|
||||
if (pkt == NULL) {
|
||||
puts("Error: could not create packet buffer, exit");
|
||||
return 1;
|
||||
sock_udp_ep_t remote;
|
||||
remote.family = AF_INET6;
|
||||
remote.netif = SOCK_ADDR_ANY_NETIF;
|
||||
remote.port = atoi(port_str);
|
||||
memcpy(&remote.addr.ipv6[0], &addr.u8[0], sizeof(addr.u8));
|
||||
|
||||
int res = sock_udp_send(&_sock_udp, data, data_len, &remote);
|
||||
if (res == -EINVAL) {
|
||||
puts("Error: EINVAL");
|
||||
}
|
||||
else if (res == -EAFNOSUPPORT) {
|
||||
puts("Error: EAFNOSUPPORT");
|
||||
}
|
||||
else if (res == -ENOMEM) {
|
||||
puts("Error: ENOMEM");
|
||||
}
|
||||
else if (res == -ENOBUFS) {
|
||||
puts("Error: ENOBUFS");
|
||||
}
|
||||
|
||||
pkt->owner = COMPONENT_UINJECT;
|
||||
pkt->creator = COMPONENT_UINJECT;
|
||||
pkt->l4_protocol = IANA_UDP;
|
||||
pkt->l4_destination_port = atoi(port_str);
|
||||
pkt->l4_sourcePortORicmpv6Type = uinject_vars.port;
|
||||
pkt->l3_destinationAdd.type = ADDR_128B;
|
||||
memcpy(&pkt->l3_destinationAdd.addr_128b[0], (void *)&addr, 16);
|
||||
/* add payload */
|
||||
packetfunctions_reserveHeader(&pkt, data_len);
|
||||
memcpy(&pkt->payload[0], data, data_len);
|
||||
|
||||
packetfunctions_reserveHeader(&pkt, sizeof(uint16_t));
|
||||
pkt->payload[1] = (uint8_t)((counter & 0xff00) >> 8);
|
||||
pkt->payload[0] = (uint8_t)(counter & 0x00ff);
|
||||
counter++;
|
||||
|
||||
packetfunctions_reserveHeader(&pkt, sizeof(asn_t));
|
||||
ieee154e_getAsn(asnArray);
|
||||
pkt->payload[0] = asnArray[0];
|
||||
pkt->payload[1] = asnArray[1];
|
||||
pkt->payload[2] = asnArray[2];
|
||||
pkt->payload[3] = asnArray[3];
|
||||
pkt->payload[4] = asnArray[4];
|
||||
|
||||
scheduler_push_task(push_pkt_cb, TASKPRIO_COAP);
|
||||
|
||||
ztimer_sleep(ZTIMER_USEC, delay);
|
||||
}
|
||||
@ -140,12 +160,13 @@ int udp_cmd(int argc, char **argv)
|
||||
uint32_t delay = 1000000LU;
|
||||
/* don't send as root */
|
||||
if (idmanager_vars.isDAGroot) {
|
||||
puts("Error: Node is root, exit");
|
||||
puts("Error: node is root, exit");
|
||||
return 1;
|
||||
}
|
||||
if (argc < 5) {
|
||||
printf("usage: %s send <addr> <port> <hex data> [<num> [<delay in us>]]\n",
|
||||
argv[0]);
|
||||
printf(
|
||||
"Usage: %s send <addr> <port> <hex data> [<num> [<delay in us>]]\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (argc > 5) {
|
||||
@ -158,35 +179,33 @@ int udp_cmd(int argc, char **argv)
|
||||
}
|
||||
else if (strcmp(argv[1], "server") == 0) {
|
||||
if (argc < 3) {
|
||||
printf("usage: %s server [start|list]\n", argv[0]);
|
||||
printf("Usage: %s server [start|show]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[2], "start") == 0) {
|
||||
if (argc < 4) {
|
||||
printf("usage %s server start <port>\n", argv[0]);
|
||||
printf("Usage %s server start <port>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
uint16_t port = atoi(argv[3]);
|
||||
uinject_vars.port = port;
|
||||
sock_udp_ep_t local;
|
||||
sock_udp_get_local(&_sock_udp, &local);
|
||||
local.port = port;
|
||||
printf("Set UDP server port to %" PRIu16 "\n", port);
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[2], "list") == 0) {
|
||||
udp_resource_desc_t* resource = openudp_vars.resources;
|
||||
printf("Open UDP Ports: ");
|
||||
while (NULL != resource) {
|
||||
printf("%i ", resource->port);
|
||||
resource = resource->next;
|
||||
}
|
||||
puts("");
|
||||
else if (strcmp(argv[2], "show") == 0) {
|
||||
sock_udp_ep_t local;
|
||||
sock_udp_get_local(&_sock_udp, &local);
|
||||
printf("Udp port: %i\n", local.port);
|
||||
}
|
||||
else {
|
||||
puts("error: invalid command");
|
||||
puts("Error: invalid command");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
puts("error: invalid command");
|
||||
puts("Error: invalid command");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
49
tests/pkg_openwsn_sock_udp/Makefile
Normal file
49
tests/pkg_openwsn_sock_udp/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
BOARD ?= samr21-xpro
|
||||
|
||||
include ../Makefile.tests_common
|
||||
|
||||
# list of arm boards that provide at86rf2xx radios, cc2538_rf or nrf52840
|
||||
# radios
|
||||
BOARD_WHITELIST = \
|
||||
adafruit-clue \
|
||||
adafruit-itsybitsy-nrf52 \
|
||||
arduino-nano-33-ble \
|
||||
cc2538dk \
|
||||
feather-nrf52840 \
|
||||
firefly \
|
||||
fox \
|
||||
iotlab-m3 \
|
||||
iotlab-a8-m3 \
|
||||
nrf52840-mdk \
|
||||
nrf52840dk \
|
||||
nrf52840dongle \
|
||||
omote \
|
||||
openmote-b \
|
||||
openmote-cc2538 \
|
||||
particle-argon \
|
||||
particle-boron \
|
||||
particle-xenon \
|
||||
samr21-xpro \
|
||||
samr30-xpro \
|
||||
reel \
|
||||
remote-pa \
|
||||
remote-reva \
|
||||
remote-revb \
|
||||
#
|
||||
|
||||
USEPKG += openwsn
|
||||
USEMODULE += openwsn_openstack
|
||||
USEMODULE += openwsn_scheduler
|
||||
USEMODULE += sock_udp
|
||||
|
||||
# Mock OpenWSN scheduler to handle the udp_transmit task.
|
||||
USEMODULE += openwsn_scheduler_mock
|
||||
EXTERNAL_MODULE_DIRS += $(CURDIR)/scheduler
|
||||
|
||||
# Explicitly include ztimer to enable timeout
|
||||
USEMODULE += ztimer_usec
|
||||
DISABLE_MODULE += auto_init_openwsn
|
||||
|
||||
CFLAGS +=-DCONFIG_OPENWSN_NETIF_ID=31
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
44
tests/pkg_openwsn_sock_udp/constants.h
Normal file
44
tests/pkg_openwsn_sock_udp/constants.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @brief
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
#include "openwsn.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _TEST_NETIF (CONFIG_OPENWSN_NETIF_ID)
|
||||
#define _TEST_PORT_LOCAL (0x2c94)
|
||||
#define _TEST_PORT_REMOTE (0xa615)
|
||||
#define _TEST_TIMEOUT (1000000U)
|
||||
#define _TEST_ADDR_LOCAL { 0x7f, 0xc4, 0x11, 0x5a, 0xe6, 0x91, 0x8d, 0x5d, \
|
||||
0x8c, 0xd1, 0x47, 0x07, 0xb7, 0x6f, 0x9b, 0x48 }
|
||||
#define _TEST_ADDR_REMOTE { 0xe8, 0xb3, 0xb2, 0xe6, 0x70, 0xd4, 0x55, 0xba, \
|
||||
0x93, 0xcf, 0x11, 0xe1, 0x72, 0x44, 0xc5, 0x9d }
|
||||
#define _TEST_ADDR_WRONG { 0x2a, 0xce, 0x5d, 0x4e, 0xc8, 0xbf, 0x86, 0xf7, \
|
||||
0x85, 0x49, 0xb4, 0x19, 0xf2, 0x28, 0xde, 0x9b }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONSTANTS_H */
|
793
tests/pkg_openwsn_sock_udp/main.c
Normal file
793
tests/pkg_openwsn_sock_udp/main.c
Normal file
@ -0,0 +1,793 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test for UDP socks
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net/sock/udp.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
|
||||
#include "test_utils/expect.h"
|
||||
|
||||
#include "stack.h"
|
||||
#include "constants.h"
|
||||
|
||||
#define _TEST_BUFFER_SIZE (128)
|
||||
|
||||
static uint8_t _test_buffer[_TEST_BUFFER_SIZE];
|
||||
static sock_udp_t _sock, _sock2;
|
||||
|
||||
#define CALL(fn) puts("Calling " # fn); fn; tear_down()
|
||||
|
||||
static void tear_down(void)
|
||||
{
|
||||
sock_udp_close(&_sock);
|
||||
memset(&_sock, 0, sizeof(_sock));
|
||||
memset(&_sock2, 0, sizeof(_sock2));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__EADDRINUSE(void)
|
||||
{
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, 0));
|
||||
expect(-EADDRINUSE == sock_udp_create(&_sock2, &local, NULL, 0));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__EAFNOSUPPORT(void)
|
||||
{
|
||||
/* port may not be NULL according to doc */
|
||||
static const sock_udp_ep_t local = { .family = AF_UNSPEC,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
/* port may not be NULL according to doc */
|
||||
static const sock_udp_ep_t remote = { .family = AF_UNSPEC,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(-EAFNOSUPPORT ==
|
||||
sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(-EAFNOSUPPORT ==
|
||||
sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__EINVAL_addr(void)
|
||||
{
|
||||
/* port may not be NULL according to doc */
|
||||
static const sock_udp_ep_t local =
|
||||
{ .family = AF_INET6, .netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
/* port may not be NULL according to doc */
|
||||
static const sock_udp_ep_t remote = { .family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(-EINVAL ==
|
||||
sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__EINVAL_netif(void)
|
||||
{
|
||||
/* port may not be NULL according to doc */
|
||||
static const sock_udp_ep_t local_1 =
|
||||
{ .family = AF_INET6, .netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
/* port may not be NULL according to doc */
|
||||
static const sock_udp_ep_t remote = { .family = AF_INET6,
|
||||
.netif = (_TEST_NETIF + 1),
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.addr =
|
||||
{ .ipv6 = _TEST_ADDR_REMOTE } };
|
||||
|
||||
expect(-EINVAL ==
|
||||
sock_udp_create(&_sock, &local_1, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
static const sock_udp_ep_t local_2 = { .family = AF_INET6,
|
||||
.netif = _TEST_NETIF + 1,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
expect(-EINVAL ==
|
||||
sock_udp_create(&_sock, &local_2, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__no_endpoints(void)
|
||||
{
|
||||
sock_udp_ep_t ep;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(-EADDRNOTAVAIL == sock_udp_get_local(&_sock, &ep));
|
||||
expect(-ENOTCONN == sock_udp_get_remote(&_sock, &ep));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__only_local(void)
|
||||
{
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
sock_udp_ep_t ep;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(0 == sock_udp_get_local(&_sock, &ep));
|
||||
expect(AF_INET6 == ep.family);
|
||||
expect(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6,
|
||||
sizeof(ipv6_addr_t)) == 0);
|
||||
expect(SOCK_ADDR_ANY_NETIF == ep.netif);
|
||||
expect(_TEST_PORT_LOCAL == ep.port);
|
||||
expect(-ENOTCONN == sock_udp_get_remote(&_sock, &ep));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__only_local_port0(void)
|
||||
{
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = 0U };
|
||||
sock_udp_ep_t ep;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(0 == sock_udp_get_local(&_sock, &ep));
|
||||
expect(AF_INET6 == ep.family);
|
||||
expect(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6,
|
||||
sizeof(ipv6_addr_t)) == 0);
|
||||
expect(SOCK_ADDR_ANY_NETIF == ep.netif);
|
||||
expect(0U != ep.port);
|
||||
expect(-ENOTCONN == sock_udp_get_remote(&_sock, &ep));
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__only_local_reuse_ep(void)
|
||||
{
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
sock_udp_ep_t ep, ep2;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(0 == sock_udp_create(&_sock2, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(0 == sock_udp_get_local(&_sock, &ep));
|
||||
expect(0 == sock_udp_get_local(&_sock2, &ep2));
|
||||
expect(AF_INET6 == ep.family);
|
||||
expect(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6,
|
||||
sizeof(ipv6_addr_t)) == 0);
|
||||
expect(SOCK_ADDR_ANY_NETIF == ep.netif);
|
||||
expect(_TEST_PORT_LOCAL == ep.port);
|
||||
expect(-ENOTCONN == sock_udp_get_remote(&_sock, &ep));
|
||||
expect(AF_INET6 == ep2.family);
|
||||
expect(memcmp(&ipv6_addr_unspecified, &ep2.addr.ipv6,
|
||||
sizeof(ipv6_addr_t)) == 0);
|
||||
expect(SOCK_ADDR_ANY_NETIF == ep2.netif);
|
||||
expect(_TEST_PORT_LOCAL == ep2.port);
|
||||
expect(-ENOTCONN == sock_udp_get_remote(&_sock, &ep2));
|
||||
sock_udp_close(&_sock2);
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__only_remote(void)
|
||||
{
|
||||
static const ipv6_addr_t remote_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.addr =
|
||||
{ .ipv6 = _TEST_ADDR_REMOTE } };
|
||||
sock_udp_ep_t ep;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(-EADDRNOTAVAIL == sock_udp_get_local(&_sock, &ep));
|
||||
expect(0 == sock_udp_get_remote(&_sock, &ep));
|
||||
expect(AF_INET6 == ep.family);
|
||||
expect(memcmp(&remote_addr, &ep.addr.ipv6, sizeof(ipv6_addr_t)) == 0);
|
||||
expect(SOCK_ADDR_ANY_NETIF == ep.netif);
|
||||
expect(_TEST_PORT_REMOTE == ep.port);
|
||||
}
|
||||
|
||||
static void test_sock_udp_create__full(void)
|
||||
{
|
||||
static const ipv6_addr_t remote_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local =
|
||||
{ .family = AF_INET6, .netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.addr =
|
||||
{ .ipv6 = _TEST_ADDR_REMOTE } };
|
||||
sock_udp_ep_t ep;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(0 == sock_udp_get_local(&_sock, &ep));
|
||||
expect(AF_INET6 == ep.family);
|
||||
expect(memcmp(&ipv6_addr_unspecified, &ep.addr.ipv6,
|
||||
sizeof(ipv6_addr_t)) == 0);
|
||||
expect(_TEST_NETIF == ep.netif);
|
||||
expect(_TEST_PORT_LOCAL == ep.port);
|
||||
expect(0 == sock_udp_get_remote(&_sock, &ep));
|
||||
expect(AF_INET6 == ep.family);
|
||||
expect(memcmp(&remote_addr, &ep.addr.ipv6, sizeof(ipv6_addr_t)) == 0);
|
||||
expect(SOCK_ADDR_ANY_NETIF == ep.netif);
|
||||
expect(_TEST_PORT_REMOTE == ep.port);
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__EADDRNOTAVAIL(void)
|
||||
{
|
||||
expect(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
|
||||
expect(-EADDRNOTAVAIL == sock_udp_recv(&_sock, _test_buffer,
|
||||
sizeof(_test_buffer),
|
||||
SOCK_NO_TIMEOUT, NULL));
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__EAGAIN(void)
|
||||
{
|
||||
static const sock_udp_ep_t local =
|
||||
{ .family = AF_INET6, .netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
|
||||
expect(-EAGAIN == sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer),
|
||||
0, NULL));
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__ENOBUFS(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"),
|
||||
_TEST_NETIF));
|
||||
expect(-ENOBUFS == sock_udp_recv(&_sock, _test_buffer, 2, SOCK_NO_TIMEOUT,
|
||||
NULL));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__EPROTO(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_WRONG };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"),
|
||||
_TEST_NETIF));
|
||||
expect(-EPROTO == sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer),
|
||||
SOCK_NO_TIMEOUT, NULL));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__ETIMEDOUT(void)
|
||||
{
|
||||
static const sock_udp_ep_t local =
|
||||
{ .family = AF_INET6, .netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
|
||||
puts(" * Calling sock_udp_recv()");
|
||||
expect(-ETIMEDOUT == sock_udp_recv(&_sock, _test_buffer,
|
||||
sizeof(_test_buffer), _TEST_TIMEOUT,
|
||||
NULL));
|
||||
printf(" * (timed out with timeout %lu)\n", (long unsigned)_TEST_TIMEOUT);
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__socketed(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), SOCK_NO_TIMEOUT,
|
||||
NULL);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__socketed_with_remote(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
sock_udp_ep_t result;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), SOCK_NO_TIMEOUT,
|
||||
&result);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
expect(AF_INET6 == result.family);
|
||||
expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0);
|
||||
expect(_TEST_PORT_REMOTE == result.port);
|
||||
expect(_TEST_NETIF == result.netif);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__socketed_with_port0(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static sock_udp_ep_t local = { .family = AF_INET6, .port = 0 };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
sock_udp_ep_t result;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(0 == sock_udp_get_local(&_sock, &local));
|
||||
expect(0 != local.port);
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
local.port, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), SOCK_NO_TIMEOUT,
|
||||
&result);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
expect(AF_INET6 == result.family);
|
||||
expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0);
|
||||
expect(_TEST_PORT_REMOTE == result.port);
|
||||
expect(_TEST_NETIF == result.netif);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__unsocketed(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), SOCK_NO_TIMEOUT,
|
||||
NULL);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__unsocketed_with_remote(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
sock_udp_ep_t result;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), SOCK_NO_TIMEOUT,
|
||||
&result);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
expect(AF_INET6 == result.family);
|
||||
expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0);
|
||||
expect(_TEST_PORT_REMOTE == result.port);
|
||||
expect(_TEST_NETIF == result.netif);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__with_timeout(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
sock_udp_ep_t result;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), _TEST_TIMEOUT,
|
||||
&result);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
expect(AF_INET6 == result.family);
|
||||
expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0);
|
||||
expect(_TEST_PORT_REMOTE == result.port);
|
||||
expect(_TEST_NETIF == result.netif);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv__non_blocking(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
sock_udp_ep_t result;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv(&_sock, _test_buffer, sizeof(_test_buffer), 0, &result);
|
||||
expect(memcmp(test_data, _test_buffer, sizeof(test_data)) == 0);
|
||||
expect(AF_INET6 == result.family);
|
||||
expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0);
|
||||
expect(_TEST_PORT_REMOTE == result.port);
|
||||
expect(_TEST_NETIF == result.netif);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_recv_buf__success(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const sock_udp_ep_t local = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
static uint8_t test_data[] = "ABCD";
|
||||
void *data = NULL, *ctx = NULL;
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE,
|
||||
_TEST_PORT_LOCAL, &test_data, sizeof(test_data),
|
||||
_TEST_NETIF));
|
||||
sock_udp_recv_buf(&_sock, &data, &ctx, SOCK_NO_TIMEOUT, NULL);
|
||||
expect(data != NULL);
|
||||
expect(memcmp(test_data, data, sizeof(test_data)) == 0);
|
||||
expect(ctx != NULL);
|
||||
expect(0 == sock_udp_recv_buf(&_sock, &data, &ctx, SOCK_NO_TIMEOUT, NULL));
|
||||
expect(data == NULL);
|
||||
expect(ctx == NULL);
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__EAFNOSUPPORT(void)
|
||||
{
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(-EAFNOSUPPORT == sock_udp_send(NULL, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__EINVAL_addr(void)
|
||||
{
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.netif = _TEST_NETIF };
|
||||
static const sock_udp_ep_t remote = { .family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.netif = _TEST_NETIF };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(-EINVAL == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), &remote));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__EINVAL_netif(void)
|
||||
{
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.netif = _TEST_NETIF };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE,
|
||||
.netif = _TEST_NETIF + 1 };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(-EINVAL == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), &remote));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__EINVAL_port(void)
|
||||
{
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6 };
|
||||
|
||||
expect(-EINVAL == sock_udp_send(NULL, "ABCD", sizeof("ABCD"), &remote));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__ENOTCONN(void)
|
||||
{
|
||||
expect(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(-ENOTCONN == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"), NULL));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__socketed_no_local_no_netif(void)
|
||||
{
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
NULL));
|
||||
expect(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
SOCK_ADDR_ANY_NETIF, true));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__socketed_no_netif(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
NULL));
|
||||
expect(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
SOCK_ADDR_ANY_NETIF, false));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__socketed_no_local(void)
|
||||
{
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, NULL, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
NULL));
|
||||
expect(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), _TEST_NETIF,
|
||||
true));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__socketed(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
NULL));
|
||||
expect(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
_TEST_NETIF, false));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__socketed_other_remote(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t sock_remote =
|
||||
{ .addr = { .ipv6 = _TEST_ADDR_WRONG },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE +
|
||||
_TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 ==
|
||||
sock_udp_create(&_sock, &local, &sock_remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
_TEST_NETIF, false));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__unsocketed_no_local_no_netif(void)
|
||||
{
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
SOCK_ADDR_ANY_NETIF, true));
|
||||
expect(_check_net());
|
||||
}
|
||||
static void test_sock_udp_send__unsocketed_no_netif(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
SOCK_ADDR_ANY_NETIF, false));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__unsocketed_no_local(void)
|
||||
{
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, NULL, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"), _TEST_NETIF,
|
||||
true));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__unsocketed(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCD") == sock_udp_send(&_sock, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
_TEST_NETIF, false));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__no_sock_no_netif(void)
|
||||
{
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(sizeof("ABCD") == sock_udp_send(NULL, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
SOCK_ADDR_ANY_NETIF, true));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__no_sock(void)
|
||||
{
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
expect(sizeof("ABCD") == sock_udp_send(NULL, "ABCD", sizeof("ABCD"),
|
||||
&remote));
|
||||
expect(_check_packet(&ipv6_addr_unspecified, &dst_addr, 0,
|
||||
_TEST_PORT_REMOTE, "ABCD", sizeof("ABCD"),
|
||||
_TEST_NETIF, true));
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
_net_init();
|
||||
tear_down();
|
||||
|
||||
CALL(test_sock_udp_create__EADDRINUSE());
|
||||
CALL(test_sock_udp_create__EAFNOSUPPORT());
|
||||
CALL(test_sock_udp_create__EINVAL_addr());
|
||||
CALL(test_sock_udp_create__EINVAL_netif());
|
||||
CALL(test_sock_udp_create__no_endpoints());
|
||||
CALL(test_sock_udp_create__only_local());
|
||||
CALL(test_sock_udp_create__only_local_port0());
|
||||
CALL(test_sock_udp_create__only_local_reuse_ep());
|
||||
CALL(test_sock_udp_create__only_remote());
|
||||
CALL(test_sock_udp_create__full());
|
||||
/* sock_udp_close() is tested in tear_down() */
|
||||
/* sock_udp_get_local() is tested in sock_udp_create() tests */
|
||||
/* sock_udp_get_remote() is tested in sock_udp_create() tests */
|
||||
CALL(test_sock_udp_recv__EADDRNOTAVAIL());
|
||||
CALL(test_sock_udp_recv__EAGAIN());
|
||||
CALL(test_sock_udp_recv__ENOBUFS());
|
||||
CALL(test_sock_udp_recv__EPROTO());
|
||||
CALL(test_sock_udp_recv__ETIMEDOUT());
|
||||
CALL(test_sock_udp_recv__socketed());
|
||||
CALL(test_sock_udp_recv__socketed_with_remote());
|
||||
CALL(test_sock_udp_recv__socketed_with_port0());
|
||||
CALL(test_sock_udp_recv__unsocketed());
|
||||
CALL(test_sock_udp_recv__unsocketed_with_remote());
|
||||
CALL(test_sock_udp_recv__with_timeout());
|
||||
CALL(test_sock_udp_recv__non_blocking());
|
||||
CALL(test_sock_udp_recv_buf__success());
|
||||
CALL(test_sock_udp_send__EAFNOSUPPORT());
|
||||
CALL(test_sock_udp_send__EINVAL_addr());
|
||||
CALL(test_sock_udp_send__EINVAL_netif());
|
||||
CALL(test_sock_udp_send__EINVAL_port());
|
||||
CALL(test_sock_udp_send__ENOTCONN());
|
||||
CALL(test_sock_udp_send__socketed_no_local_no_netif());
|
||||
CALL(test_sock_udp_send__socketed_no_netif());
|
||||
CALL(test_sock_udp_send__socketed_no_local());
|
||||
CALL(test_sock_udp_send__socketed());
|
||||
CALL(test_sock_udp_send__socketed_other_remote());
|
||||
CALL(test_sock_udp_send__unsocketed_no_local_no_netif());
|
||||
CALL(test_sock_udp_send__unsocketed_no_netif());
|
||||
CALL(test_sock_udp_send__unsocketed_no_local());
|
||||
CALL(test_sock_udp_send__unsocketed());
|
||||
CALL(test_sock_udp_send__no_sock_no_netif());
|
||||
CALL(test_sock_udp_send__no_sock());
|
||||
|
||||
puts("ALL TESTS SUCCESSFUL");
|
||||
|
||||
return 0;
|
||||
}
|
3
tests/pkg_openwsn_sock_udp/scheduler/Makefile
Normal file
3
tests/pkg_openwsn_sock_udp/scheduler/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := openwsn_scheduler_mock
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
3
tests/pkg_openwsn_sock_udp/scheduler/Makefile.include
Normal file
3
tests/pkg_openwsn_sock_udp/scheduler/Makefile.include
Normal file
@ -0,0 +1,3 @@
|
||||
# Use an immediate variable to evaluate `MAKEFILE_LIST` now
|
||||
USEMODULE_INCLUDES_openwsn_scheduler_mock := $(LAST_MAKEFILEDIR)/include
|
||||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_openwsn_scheduler_mock)
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_openwsn
|
||||
* @{
|
||||
*
|
||||
*
|
||||
* @file
|
||||
* @brief RIOT mock scheduler types variable declaration
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef SCHEDULER_TYPES_H
|
||||
#define SCHEDULER_TYPES_H
|
||||
|
||||
#include "scheduler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief OpenWSN scheduler variables structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t last_task;
|
||||
} scheduler_vars_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SCHEDULER_TYPES_H */
|
39
tests/pkg_openwsn_sock_udp/scheduler/scheduler.c
Normal file
39
tests/pkg_openwsn_sock_udp/scheduler/scheduler.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_openwsn
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief OpenWSN scheduler mock
|
||||
*
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
#include "scheduler.h"
|
||||
|
||||
scheduler_vars_t scheduler_mock_vars;
|
||||
|
||||
void scheduler_init(void)
|
||||
{
|
||||
/* nothing to do here */
|
||||
scheduler_mock_vars.last_task = TASKPRIO_NONE;
|
||||
}
|
||||
|
||||
void scheduler_start(unsigned state)
|
||||
{
|
||||
irq_restore(state);
|
||||
}
|
||||
|
||||
void scheduler_push_task(task_cbt cb, task_prio_t prio)
|
||||
{
|
||||
(void) cb;
|
||||
scheduler_mock_vars.last_task = prio;
|
||||
}
|
152
tests/pkg_openwsn_sock_udp/stack.c
Normal file
152
tests/pkg_openwsn_sock_udp/stack.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @author Francisco Molina <francois-xavier.molina@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "net/ipv6/addr.h"
|
||||
|
||||
#include "openwsn.h"
|
||||
#include "cross-layers/openqueue.h"
|
||||
#include "cross-layers/openrandom.h"
|
||||
#include "cross-layers/packetfunctions.h"
|
||||
#include "cross-layers/idmanager.h"
|
||||
#include "04-TRAN/udp.h"
|
||||
#include "04-TRAN/sock_internal.h"
|
||||
#include "02a-MAClow/IEEE802154E.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
extern openqueue_vars_t openqueue_vars;
|
||||
extern ieee154e_vars_t ieee154e_vars;
|
||||
extern scheduler_vars_t scheduler_mock_vars;
|
||||
|
||||
extern void sock_udp_init(void);
|
||||
|
||||
bool _inject_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||
uint16_t src_port, uint16_t dst_port,
|
||||
void *data, size_t data_len, uint16_t netif)
|
||||
{
|
||||
(void) netif;
|
||||
OpenQueueEntry_t *pkt;
|
||||
|
||||
if ((pkt = openqueue_getFreePacketBuffer(COMPONENT_UDP_TO_SOCK)) == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pkt->owner = COMPONENT_UDP_TO_SOCK;
|
||||
pkt->creator = COMPONENT_UDP_TO_SOCK;
|
||||
|
||||
/* set address*/
|
||||
pkt->l3_destinationAdd.type = ADDR_128B;
|
||||
pkt->l3_sourceAdd.type = ADDR_128B;
|
||||
memcpy(&pkt->l3_destinationAdd.addr_128b, dst, LENGTH_ADDR128b);
|
||||
memcpy(&pkt->l3_sourceAdd.addr_128b, src, LENGTH_ADDR128b);
|
||||
|
||||
/* set port */
|
||||
pkt->l4_destination_port = dst_port;
|
||||
pkt->l4_sourcePortORicmpv6Type = src_port;
|
||||
|
||||
/* set payload */
|
||||
if (packetfunctions_reserveHeader(&pkt, data_len)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(pkt->payload, data, data_len);
|
||||
pkt->l4_payload = pkt->payload;
|
||||
pkt->l4_length = pkt->length;
|
||||
|
||||
/* set remaining fields */
|
||||
pkt->l4_protocol_compressed = FALSE;
|
||||
pkt->l4_protocol = IANA_UDP;
|
||||
packetfunctions_reserveHeader(&pkt, sizeof(udp_ht));
|
||||
packetfunctions_htons(pkt->l4_sourcePortORicmpv6Type, &(pkt->payload[0]));
|
||||
packetfunctions_htons(pkt->l4_destination_port, &(pkt->payload[2]));
|
||||
packetfunctions_htons(pkt->length, &(pkt->payload[4]));
|
||||
packetfunctions_calculateChecksum(pkt,
|
||||
(uint8_t * )&(((udp_ht *)pkt->payload)->
|
||||
checksum));
|
||||
|
||||
/* set ID to match destination */
|
||||
open_addr_t addr;
|
||||
addr.type = ADDR_PREFIX;
|
||||
memcpy(&addr.prefix, &dst->u8[0], sizeof(addr.prefix));
|
||||
idmanager_setMyID(&addr);
|
||||
addr.type = ADDR_64B;
|
||||
memcpy(&addr.addr_64b, &dst->u8[8], sizeof(addr.addr_64b));
|
||||
idmanager_setMyID(&addr);
|
||||
|
||||
/* mock receive push pkt to mailbox */
|
||||
sock_receive_internal();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void _net_init(void)
|
||||
{
|
||||
openrandom_init();
|
||||
openqueue_init();
|
||||
sock_udp_init();
|
||||
scheduler_init();
|
||||
ieee154e_vars.isSync = true;
|
||||
}
|
||||
|
||||
bool _check_net(void)
|
||||
{
|
||||
/* queue must me empty */
|
||||
for (uint8_t i = 0; i < QUEUELENGTH; i++) {
|
||||
if (openqueue_vars.queue[i].owner != COMPONENT_NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _check_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||
uint16_t src_port, uint16_t dst_port,
|
||||
void *data, size_t data_len, uint16_t netif,
|
||||
bool random_src_port)
|
||||
{
|
||||
/* get packet from queue, there should be one! */
|
||||
OpenQueueEntry_t *pkt;
|
||||
|
||||
pkt = openqueue_getPacketByComponent(COMPONENT_SOCK_TO_UDP);
|
||||
if (pkt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check that UDP task was pushed */
|
||||
if (scheduler_mock_vars.last_task != TASKPRIO_UDP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ignore checking the interface, there is only one possible interface*/
|
||||
(void)netif;
|
||||
|
||||
/* check data matches, won't check the formed pkg its assumed that
|
||||
OpenWSN writes this correctly to the payload buffer */
|
||||
int ret = 0;
|
||||
ret =
|
||||
((memcmp(src, &pkt->l3_sourceAdd.addr_128b,
|
||||
sizeof(ipv6_addr_t)) == 0) &&
|
||||
(memcmp(dst, &pkt->l3_destinationAdd.addr_128b,
|
||||
sizeof(ipv6_addr_t)) == 0) &&
|
||||
(dst_port == pkt->l4_destination_port) &&
|
||||
(random_src_port || (src_port == pkt->l4_sourcePortORicmpv6Type)) &&
|
||||
(memcmp(data, pkt->l4_payload, data_len) == 0));
|
||||
openqueue_freePacketBuffer(pkt);
|
||||
return ret;
|
||||
}
|
88
tests/pkg_openwsn_sock_udp/stack.h
Normal file
88
tests/pkg_openwsn_sock_udp/stack.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @brief
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
#ifndef STACK_H
|
||||
#define STACK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "net/ipv6/addr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initializes networking for tests
|
||||
*/
|
||||
void _net_init(void);
|
||||
|
||||
/**
|
||||
* @brief Injects a received UDP packet into the stack
|
||||
*
|
||||
* @param[in] src The source address of the UDP packet
|
||||
* @param[in] dst The destination address of the UDP packet
|
||||
* @param[in] src_port The source port of the UDP packet
|
||||
* @param[in] dst_port The destination port of the UDP packet
|
||||
* @param[in] data The payload of the UDP packet
|
||||
* @param[in] data_len The payload length of the UDP packet
|
||||
* @param[in] netif The interface the packet came over, currently ignored
|
||||
*
|
||||
* @return true, if packet was successfully injected
|
||||
* @return false, if an error occurred during injection
|
||||
*/
|
||||
bool _inject_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||
uint16_t src_port, uint16_t dst_port,
|
||||
void *data, size_t data_len, uint16_t netif);
|
||||
|
||||
/**
|
||||
* @brief Checks networking state (e.g. packet buffer state)
|
||||
*
|
||||
* @return true, if networking component is still in valid state
|
||||
* @return false, if networking component is in an invalid state
|
||||
*/
|
||||
bool _check_net(void);
|
||||
|
||||
/**
|
||||
* @brief Checks if a UDP packet was sent by the networking component
|
||||
*
|
||||
* @param[in] src Expected source address of the UDP packet
|
||||
* @param[in] dst Expected destination address of the UDP packet
|
||||
* @param[in] src_port Expected source port of the UDP packet
|
||||
* @param[in] dst_port Expected destination port of the UDP packet
|
||||
* @param[in] data Expected payload of the UDP packet
|
||||
* @param[in] data_len Expected payload length of the UDP packet
|
||||
* @param[in] netif Expected interface the packet is supposed to
|
||||
* be send over
|
||||
* @param[in] random_src_port Do not check source port, it might be random
|
||||
*
|
||||
* @return true, if all parameters match as expected
|
||||
* @return false, if not.
|
||||
*/
|
||||
bool _check_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||
uint16_t src_port, uint16_t dst_port,
|
||||
void *data, size_t data_len, uint16_t netif,
|
||||
bool random_src_port);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STACK_H */
|
56
tests/pkg_openwsn_sock_udp/tests/01-run.py
Executable file
56
tests/pkg_openwsn_sock_udp/tests/01-run.py
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
#
|
||||
# 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.
|
||||
|
||||
import sys
|
||||
from testrunner import run
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
child.expect_exact(u"Calling test_sock_udp_create__EADDRINUSE()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__EAFNOSUPPORT()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__EINVAL_addr()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__EINVAL_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__no_endpoints()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__only_local()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__only_local_reuse_ep()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__only_remote()")
|
||||
child.expect_exact(u"Calling test_sock_udp_create__full()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__EADDRNOTAVAIL()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__EAGAIN()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__ENOBUFS()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__EPROTO()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__ETIMEDOUT()")
|
||||
child.expect_exact(u" * Calling sock_udp_recv()")
|
||||
child.expect(r" \* \(timed out with timeout \d+\)")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__socketed()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__socketed_with_remote()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__unsocketed()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__unsocketed_with_remote()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__with_timeout()")
|
||||
child.expect_exact(u"Calling test_sock_udp_recv__non_blocking()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__EAFNOSUPPORT()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__EINVAL_addr()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__EINVAL_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__EINVAL_port()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__ENOTCONN()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_no_local_no_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_no_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_no_local()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__socketed_other_remote()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed_no_local_no_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed_no_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed_no_local()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__unsocketed()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__no_sock_no_netif()")
|
||||
child.expect_exact(u"Calling test_sock_udp_send__no_sock()")
|
||||
child.expect_exact(u"ALL TESTS SUCCESSFUL")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc))
|
Loading…
Reference in New Issue
Block a user