1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #15760 from maribu/sock-aux-rssi

sys/net/sock: add sock_aux_rssi
This commit is contained in:
benpicco 2021-01-25 18:51:11 +01:00 committed by GitHub
commit 83201ddb00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 277 additions and 5 deletions

View File

@ -122,6 +122,7 @@ PSEUDOMODULES += slipdev_stdio
PSEUDOMODULES += sock
PSEUDOMODULES += sock_async
PSEUDOMODULES += sock_aux_local
PSEUDOMODULES += sock_aux_rssi
PSEUDOMODULES += sock_aux_timestamp
PSEUDOMODULES += sock_dtls
PSEUDOMODULES += sock_ip

View File

@ -286,6 +286,22 @@ enum {
* @ref sock_ip_aux_tx_t::timestamp, or @ref sock_dtls_aux_tx_t::timestamp.
*/
SOCK_AUX_GET_TIMESTAMP = (1LU << 1),
/**
* @brief Flag to request the RSSI value of received frame
*
* @note Select module `sock_aux_rssi` and a compatible network stack to
* use this
*
* Set this flag in the auxiliary data structure prior to the call of
* @ref sock_udp_recv_aux / @ref sock_ip_recv_aux / etc. to request the
* RSSI value of a received frame. This flag will be cleared if the
* timestamp was stored, otherwise it remains set.
*
* Depending on the family of the socket, the RSSI value will be stored in
* @ref sock_udp_aux_rx_t::rssi, @ref sock_ip_aux_rx_t::rssi, or
* @ref sock_dtls_aux_rx_t::rssi.
*/
SOCK_AUX_GET_RSSI = (1LU << 2),
};
/**

View File

@ -316,7 +316,15 @@ typedef struct {
* @see SOCK_AUX_GET_TIMESTAMP
*/
uint64_t timestamp;
#endif /* MODULE_SOCK_AUX_TIMESTAP*/
#endif /* MODULE_SOCK_AUX_TIMESTAP */
#if defined(MODULE_SOCK_AUX_RSSI) || defined(DOXYGEN)
/**
* @brief RSSI value of the received frame
*
* @see SOCK_AUX_GET_RSSI
*/
int16_t rssi;
#endif /* MODULE_SOCK_AUX_RSSI */
sock_aux_flags_t flags; /**< Flags used request information */
} sock_ip_aux_rx_t;

View File

@ -318,7 +318,15 @@ typedef struct {
* @see SOCK_AUX_GET_TIMESTAMP
*/
uint64_t timestamp;
#endif /* MODULE_SOCK_AUX_TIMESTAP*/
#endif /* MODULE_SOCK_AUX_TIMESTAP */
#if defined(MODULE_SOCK_AUX_RSSI) || defined(DOXYGEN)
/**
* @brief RSSI value of the received frame
*
* @see SOCK_AUX_GET_RSSI
*/
int16_t rssi;
#endif /* MODULE_SOCK_AUX_RSSI */
sock_aux_flags_t flags; /**< Flags used request information */
} sock_udp_aux_rx_t;

View File

@ -174,6 +174,12 @@ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out,
}
}
#endif /* MODULE_SOCK_AUX_TIMESTAMP */
#if IS_USED(MODULE_SOCK_AUX_RSSI)
if ((aux->rssi) && (netif_hdr->rssi != GNRC_NETIF_HDR_NO_RSSI)) {
aux->flags |= GNRC_SOCK_RECV_AUX_FLAG_RSSI;
*aux->rssi = netif_hdr->rssi;
}
#endif /* MODULE_SOCK_AUX_RSSI */
}
*pkt_out = pkt; /* set out parameter */

View File

@ -72,6 +72,9 @@ typedef struct {
#endif
#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) || DOXYGEN
uint64_t *timestamp; /**< timestamp PDU was received at in nanoseconds */
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI) || DOXYGEN
int16_t *rssi; /**< RSSI value of received PDU */
#endif
/**
* @brief Flags
@ -80,6 +83,7 @@ typedef struct {
} gnrc_sock_recv_aux_t;
#define GNRC_SOCK_RECV_AUX_FLAG_TIMESTAMP 0x01 /**< Timestamp valid */
#define GNRC_SOCK_RECV_AUX_FLAG_RSSI 0x02 /**< RSSI valid */
/**
* @brief Internal helper functions for GNRC

View File

@ -139,6 +139,11 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx,
if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TIMESTAMP)) {
_aux.timestamp = &aux->timestamp;
}
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI)
if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_RSSI)) {
_aux.rssi = &aux->rssi;
}
#endif
res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, &_aux);
if (res < 0) {
@ -166,6 +171,11 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx,
if ((aux != NULL) && (_aux.flags & GNRC_SOCK_RECV_AUX_FLAG_TIMESTAMP)) {
aux->flags &= ~(SOCK_AUX_GET_TIMESTAMP);
}
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI)
if ((aux != NULL) && (_aux.flags & GNRC_SOCK_RECV_AUX_FLAG_RSSI)) {
aux->flags &= ~(SOCK_AUX_GET_RSSI);
}
#endif
*data = pkt->data;
*buf_ctx = pkt;

View File

@ -228,6 +228,11 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx,
if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TIMESTAMP)) {
_aux.timestamp = &aux->timestamp;
}
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI)
if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_RSSI)) {
_aux.rssi = &aux->rssi;
}
#endif
res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, &_aux);
if (res < 0) {
@ -261,6 +266,11 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx,
if ((aux != NULL) && (_aux.flags & GNRC_SOCK_RECV_AUX_FLAG_TIMESTAMP)) {
aux->flags &= ~SOCK_AUX_GET_TIMESTAMP;
}
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI)
if ((aux != NULL) && (_aux.flags & GNRC_SOCK_RECV_AUX_FLAG_RSSI)) {
aux->flags &= ~SOCK_AUX_GET_RSSI;
}
#endif
*data = pkt->data;
*buf_ctx = pkt;

View File

@ -2,6 +2,7 @@ include ../Makefile.tests_common
AUX_LOCAL ?= 1
AUX_TIMESTAMP ?= 1
AUX_RSSI ?= 1
ifeq (1, $(AUX_LOCAL))
USEMODULE += sock_aux_local
@ -11,6 +12,10 @@ ifeq (1, $(AUX_TIMESTAMP))
USEMODULE += sock_aux_timestamp
endif
ifeq (1, $(AUX_RSSI))
USEMODULE += sock_aux_rssi
endif
USEMODULE += sock_ip
USEMODULE += gnrc_ipv6
USEMODULE += ps

View File

@ -352,7 +352,7 @@ static void test_sock_ip_recv__aux(void)
static const inject_aux_t inject_aux = { .timestamp = 42 };
sock_ip_ep_t result;
sock_ip_aux_rx_t aux = {
.flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP
.flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP | SOCK_AUX_GET_RSSI
};
expect(0 == sock_ip_create(&_sock, &local, NULL, _TEST_PROTO,
@ -376,6 +376,12 @@ static void test_sock_ip_recv__aux(void)
expect(aux.timestamp == inject_aux.timestamp);
#else
expect(aux.flags & SOCK_AUX_GET_TIMESTAMP);
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI)
expect(!(aux.flags & SOCK_AUX_GET_RSSI));
expect(aux.rssi == inject_aux.rssi);
#else
expect(aux.flags & SOCK_AUX_GET_RSSI);
#endif
expect(_check_net());
}

View File

@ -72,6 +72,7 @@ static gnrc_pktsnip_t *_build_ipv6_packet(const ipv6_addr_t *src,
netif_hdr->if_pid = (kernel_pid_t)netif;
if (aux) {
gnrc_netif_hdr_set_timestamp(netif_hdr, aux->timestamp);
netif_hdr->rssi = aux->rssi;
}
return gnrc_pkt_append(payload, netif_hdr_snip);
}

View File

@ -44,6 +44,7 @@ void _prepare_send_checks(void);
*/
typedef struct {
uint64_t timestamp; /**< Timestamp of reception */
int16_t rssi; /**< Fake RSSI value */
} inject_aux_t;
/**

View File

@ -2,6 +2,7 @@ include ../Makefile.tests_common
AUX_LOCAL ?= 1
AUX_TIMESTAMP ?= 1
AUX_RSSI ?= 1
ifeq (1, $(AUX_LOCAL))
USEMODULE += sock_aux_local
@ -11,6 +12,10 @@ ifeq (1, $(AUX_TIMESTAMP))
USEMODULE += sock_aux_timestamp
endif
ifeq (1, $(AUX_RSSI))
USEMODULE += sock_aux_rssi
endif
USEMODULE += gnrc_sock_check_reuse
USEMODULE += sock_udp
USEMODULE += gnrc_ipv6

View File

@ -429,10 +429,10 @@ static void test_sock_udp_recv__aux(void)
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 inject_aux_t inject_aux = { .timestamp = 1337 };
static const inject_aux_t inject_aux = { .timestamp = 1337, .rssi = -11 };
sock_udp_ep_t result;
sock_udp_aux_rx_t aux = {
.flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP
.flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP | SOCK_AUX_GET_RSSI
};
expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP));
@ -458,6 +458,12 @@ static void test_sock_udp_recv__aux(void)
expect(inject_aux.timestamp == aux.timestamp);
#else
expect(aux.flags & SOCK_AUX_GET_TIMESTAMP);
#endif
#if IS_USED(MODULE_SOCK_AUX_RSSI)
expect(!(aux.flags & SOCK_AUX_GET_RSSI));
expect(inject_aux.rssi == aux.rssi);
#else
expect(aux.flags & SOCK_AUX_GET_RSSI);
#endif
expect(_check_net());
}

View File

@ -95,6 +95,7 @@ static gnrc_pktsnip_t *_build_udp_packet(const ipv6_addr_t *src,
netif_hdr->if_pid = (kernel_pid_t)netif;
if (aux) {
gnrc_netif_hdr_set_timestamp(netif_hdr, aux->timestamp);
netif_hdr->rssi = aux->rssi;
}
return gnrc_pkt_append(udp, netif_hdr_snip);
}

View File

@ -44,6 +44,7 @@ void _prepare_send_checks(void);
*/
typedef struct {
uint64_t timestamp; /**< Timestamp of reception */
int16_t rssi; /**< Fake RSSI value */
} inject_aux_t;
/**

View File

@ -0,0 +1,23 @@
BOARD ?= nucleo-f767zi
include ../Makefile.tests_common
# Enable hardware timestamping, if possible
FEATURES_OPTIONAL += periph_ptp periph_eth
USEMODULE += auto_init_gnrc_netif
USEMODULE += fmt
USEMODULE += gnrc_icmpv6_echo
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_netdev_default
USEMODULE += gnrc_sock_udp
USEMODULE += netstats_ipv6
USEMODULE += netstats_l2
USEMODULE += ps
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += sock_aux_local
USEMODULE += sock_aux_rssi
USEMODULE += sock_aux_timestamp
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,35 @@
BOARD_INSUFFICIENT_MEMORY := \
arduino-duemilanove \
arduino-leonardo \
arduino-mega2560 \
arduino-nano \
arduino-nano-33-iot \
arduino-uno \
atmega1284p \
atmega328p \
calliope-mini \
derfmega128 \
i-nucleo-lrwan1 \
mega-xplained \
microduino-corerf \
msb-430 \
msb-430h \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-f410rb \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
samd10-xmini \
slstk3400a \
stk3200 \
stm32f030f4-demo \
stm32f0discovery \
stm32l0538-disco \
telosb \
waspmote-pro \
z1 \
#

125
tests/sock_udp_aux/main.c Normal file
View File

@ -0,0 +1,125 @@
/*
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
*
* 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 application for accessing auxiliary data using the UDP SOCK API
*
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*
* @}
*/
#include <stdio.h>
#include <string.h>
#include "fmt.h"
#include "net/sock/udp.h"
#include "shell.h"
#include "shell_commands.h"
#include "net/ipv6/addr.h"
#define MAIN_QUEUE_SIZE (8)
#define PORT_UDP 12345
#define _QUOTE(x) #x
#define QUOTE(x) _QUOTE(x)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
char server_thread_stack[THREAD_STACKSIZE_DEFAULT];
static const sock_aux_flags_t flags_rx = SOCK_AUX_GET_LOCAL
| SOCK_AUX_GET_TIMESTAMP
| SOCK_AUX_GET_RSSI;
static const sock_aux_flags_t flags_tx = SOCK_AUX_GET_TIMESTAMP;
static void *server_thread(void *arg)
{
(void)arg;
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
sock_udp_t sock;
local.port = PORT_UDP;
if (sock_udp_create(&sock, &local, NULL, 0) < 0) {
print_str("Error creating UDP sock\n");
return NULL;
}
print_str("UDP echo server listening at port " QUOTE(PORT_UDP) "\n");
while (1) {
sock_udp_ep_t remote;
ssize_t res;
sock_udp_aux_rx_t rx_aux = { .flags = flags_rx };
sock_udp_aux_tx_t tx_aux = { .flags = flags_tx };
char buf[128];
if (0 <= (res = sock_udp_recv_aux(&sock, buf, sizeof(buf),
SOCK_NO_TIMEOUT, &remote, &rx_aux)))
{
print_str("Received a message via: [");
if (!(rx_aux.flags & SOCK_AUX_GET_LOCAL)) {
char tmp[IPV6_ADDR_MAX_STR_LEN + 1];
ipv6_addr_to_str(tmp, (ipv6_addr_t *)rx_aux.local.addr.ipv6,
sizeof(tmp));
print_str(tmp);
print_str("]:");
print_u32_dec(rx_aux.local.port);
print_str("\n");
}
else {
print_str("Unknown endpoint\n");
}
print_str("Received a message at: ");
if (!(rx_aux.flags & SOCK_AUX_GET_TIMESTAMP)) {
print_u64_dec(rx_aux.timestamp);
print_str(" ns\n");
}
else {
print_str("No timestamp\n");
}
print_str("Received a message with: ");
if (!(rx_aux.flags & SOCK_AUX_GET_RSSI)) {
print_s32_dec(rx_aux.rssi);
print_str(" dBm\n");
}
else {
print_str("No RSSI value\n");
}
if (sock_udp_send_aux(&sock, buf, res, &remote, &tx_aux) < 0) {
print_str("Error sending reply\n");
}
else {
print_str("Sent echo at: ");
if (!(tx_aux.flags & SOCK_AUX_GET_TIMESTAMP)) {
print_u64_dec(tx_aux.timestamp);
print_str(" ns\n");
}
else {
print_str("No timestamp\n");
}
}
}
}
return 0;
}
int main(void)
{
/* we need a message queue for the thread running the shell in order to
* receive potentially fast incoming networking packets */
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
thread_create(server_thread_stack, sizeof(server_thread_stack),
THREAD_PRIORITY_MAIN - 1, THREAD_CREATE_STACKTEST,
server_thread, NULL, "UDP echo server");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}