From d95192e97b33a78079d8c4c35ebbcf513b23bd7b Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Fri, 4 Dec 2020 11:11:46 +0100 Subject: [PATCH 1/3] sys/net/gnrc/sock: Add support for RX timestamp --- makefiles/pseudomodules.inc.mk | 1 + sys/Makefile.dep | 3 + sys/include/net/gnrc/netif/hdr.h | 73 +++++++++++++++++++ sys/net/gnrc/sock/gnrc_sock.c | 15 +++- .../gnrc/sock/include/gnrc_sock_internal.h | 19 +++-- sys/net/gnrc/sock/ip/gnrc_sock_ip.c | 17 ++++- sys/net/gnrc/sock/udp/gnrc_sock_udp.c | 17 ++++- 7 files changed, 129 insertions(+), 16 deletions(-) diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index a40e41d80c..c992c3d375 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -43,6 +43,7 @@ PSEUDOMODULES += gnrc_netapi_callbacks PSEUDOMODULES += gnrc_netapi_mbox PSEUDOMODULES += gnrc_netif_bus PSEUDOMODULES += gnrc_netif_events +PSEUDOMODULES += gnrc_netif_timestamp PSEUDOMODULES += gnrc_pktbuf_cmd PSEUDOMODULES += gnrc_netif_6lo PSEUDOMODULES += gnrc_netif_ipv6 diff --git a/sys/Makefile.dep b/sys/Makefile.dep index c2f557cb6b..78d70c00dc 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -179,6 +179,9 @@ endif ifneq (,$(filter gnrc_sock_%,$(USEMODULE))) USEMODULE += gnrc_sock + ifneq (,$(filter sock_aux_timestamp,$(USEMODULE))) + USEMODULE += gnrc_netif_timestamp + endif endif ifneq (,$(filter gnrc_sock_async,$(USEMODULE))) diff --git a/sys/include/net/gnrc/netif/hdr.h b/sys/include/net/gnrc/netif/hdr.h index 3652565ee9..bc8e32ac5d 100644 --- a/sys/include/net/gnrc/netif/hdr.h +++ b/sys/include/net/gnrc/netif/hdr.h @@ -88,6 +88,17 @@ extern "C" { * @ref IEEE802154_FCF_FRAME_PEND */ #define GNRC_NETIF_HDR_FLAGS_MORE_DATA (0x10) + +/** + * @brief Indicate presence of a valid timestamp + * + * @details If (and only if) module `gnrc_netif_timestamp` is used and the + * network device supplied the timestamp of reception of a frame, this + * timestamp is passed up the network stack through + * @ref gnrc_netif_hdr_t::timestamp and this flag is set. This flag + * can be used to check for presence of a valid timestamp. + */ +#define GNRC_NETIF_HDR_FLAGS_TIMESTAMP (0x08) /** * @} */ @@ -105,6 +116,24 @@ typedef struct { uint8_t flags; /**< flags as defined above */ uint8_t lqi; /**< lqi of received packet (optional) */ int16_t rssi; /**< rssi of received packet in dBm (optional) */ +#if IS_USED(MODULE_GNRC_NETIF_TIMESTAMP) || defined(DOXYGEN) + /** + * @brief Timestamp of reception in nanoseconds since epoch + * + * @note Only when @ref GNRC_NETIF_HDR_FLAGS_TIMESTAMP is set, this + * field contains valid info. + * + * This field is only provided if module `gnrc_netif_timestamp` is used. + * Keep in mind that when the hardware does not provide timestamping, the + * network device driver could choose to provide this in software, which + * adds the delay and jitter of the ISR handling to the timestamp. Please + * keep also in mind that a hardware implementation might not be able to + * reliable timestamp every frame - e.g. a full-duplex wired interface might + * be unable to timestamp a received frame while timestamping an outgoing + * frame. + */ + uint64_t timestamp; +#endif /* MODULE_GNRC_NETIF_TIMESTAMP */ } gnrc_netif_hdr_t; /** @@ -201,6 +230,50 @@ static inline void gnrc_netif_hdr_set_dst_addr(gnrc_netif_hdr_t *hdr, memcpy(((uint8_t *)(hdr + 1)) + hdr->src_l2addr_len, addr, addr_len); } +/** + * @brief Set the timestamp in the netif header + * @param[out] hdr Header to set the timestamp in + * @param[in] timestamp Timestamp to set (nanoseconds since epoch) + * + * @details If the module gnrc_netif_timestamp is not used, a call to this + * function become a non-op (and will be fully optimized out by the + * compiler) + */ +static inline void gnrc_netif_hdr_set_timestamp(gnrc_netif_hdr_t *hdr, + uint64_t timestamp) +{ + (void)hdr; + (void)timestamp; +#if IS_USED(MODULE_GNRC_NETIF_TIMESTAMP) + hdr->timestamp = timestamp; + hdr->flags |= GNRC_NETIF_HDR_FLAGS_TIMESTAMP; +#endif +} + +/** + * @brief Get the timestamp of the frame in nanoseconds since epoch + * @param[in] hdr Header to read the timestamp from + * @param[out] dest The timestamp will be stored here + * @retval 0 The timestamp was stored in @p dest + * @retval -1 No timestamp available, @p dest is unchanged + * + * @details If the module gnrc_netif_timestamp is not used, this will always + * return 0 + */ +static inline int gnrc_netif_hdr_get_timestamp(const gnrc_netif_hdr_t *hdr, + uint64_t *dest) +{ + (void)hdr; + (void)dest; +#if IS_USED(MODULE_GNRC_NETIF_TIMESTAMP) + if (hdr->flags & GNRC_NETIF_HDR_FLAGS_TIMESTAMP) { + *dest = hdr->timestamp; + return 0; + } +#endif + return -1; +} + #if defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) /** * @brief Converts the source address of a given @ref net_gnrc_netif_hdr to diff --git a/sys/net/gnrc/sock/gnrc_sock.c b/sys/net/gnrc/sock/gnrc_sock.c index 1b7e15886e..aabee4c349 100644 --- a/sys/net/gnrc/sock/gnrc_sock.c +++ b/sys/net/gnrc/sock/gnrc_sock.c @@ -90,7 +90,7 @@ void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out, uint32_t timeout, sock_ip_ep_t *remote, - gnrc_sock_recv_aux_t aux) + gnrc_sock_recv_aux_t *aux) { /* only used when some sock_aux_% module is used */ (void)aux; @@ -154,9 +154,9 @@ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out, memcpy(&remote->addr, &ipv6_hdr->src, sizeof(ipv6_addr_t)); remote->family = AF_INET6; #if IS_USED(MODULE_SOCK_AUX_LOCAL) - if (aux.local != NULL) { - memcpy(&aux.local->addr, &ipv6_hdr->dst, sizeof(ipv6_addr_t)); - aux.local->family = AF_INET6; + if (aux->local != NULL) { + memcpy(&aux->local->addr, &ipv6_hdr->dst, sizeof(ipv6_addr_t)); + aux->local->family = AF_INET6; } #endif /* MODULE_SOCK_AUX_LOCAL */ netif = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF); @@ -167,6 +167,13 @@ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out, gnrc_netif_hdr_t *netif_hdr = netif->data; /* TODO: use API in #5511 */ remote->netif = (uint16_t)netif_hdr->if_pid; +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + if (aux->timestamp != NULL) { + if (gnrc_netif_hdr_get_timestamp(netif_hdr, aux->timestamp) == 0) { + aux->flags |= GNRC_SOCK_RECV_AUX_FLAG_TIMESTAMP; + } + } +#endif /* MODULE_SOCK_AUX_TIMESTAMP */ } *pkt_out = pkt; /* set out parameter */ diff --git a/sys/net/gnrc/sock/include/gnrc_sock_internal.h b/sys/net/gnrc/sock/include/gnrc_sock_internal.h index df38e233de..485278f742 100644 --- a/sys/net/gnrc/sock/include/gnrc_sock_internal.h +++ b/sys/net/gnrc/sock/include/gnrc_sock_internal.h @@ -70,18 +70,17 @@ typedef struct { */ sock_ip_ep_t *local; #endif -#if !IS_USED(MODULE_SOCK_AUX_LOCAL) || DOXYGEN - /** - * @brief Workaround in case no `sock_aux_%` module is used - * - * Empty structures are only allowed with a GNU extension. For portability, - * this member is present if and only if this structure would be otherwise - * empty. - */ - uint8_t this_struct_is_not_empty; +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) || DOXYGEN + uint64_t *timestamp; /**< timestamp PDU was received at in nanoseconds */ #endif + /** + * @brief Flags + */ + uint8_t flags; } gnrc_sock_recv_aux_t; +#define GNRC_SOCK_RECV_AUX_FLAG_TIMESTAMP 0x01 /**< Timestamp valid */ + /** * @brief Internal helper functions for GNRC * @internal @@ -143,7 +142,7 @@ void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_ * @internal */ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt, uint32_t timeout, - sock_ip_ep_t *remote, gnrc_sock_recv_aux_t aux); + sock_ip_ep_t *remote, gnrc_sock_recv_aux_t *aux); /** * @brief Send a packet internally diff --git a/sys/net/gnrc/sock/ip/gnrc_sock_ip.c b/sys/net/gnrc/sock/ip/gnrc_sock_ip.c index e10a19021b..86521f45c6 100644 --- a/sys/net/gnrc/sock/ip/gnrc_sock_ip.c +++ b/sys/net/gnrc/sock/ip/gnrc_sock_ip.c @@ -135,7 +135,12 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx, _aux.local = &aux->local; } #endif - res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, _aux); +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TIMESTAMP)) { + _aux.timestamp = &aux->timestamp; + } +#endif + res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, &_aux); if (res < 0) { return res; } @@ -156,6 +161,16 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx, if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) { aux->flags &= ~(SOCK_AUX_GET_LOCAL); } +#endif +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TIMESTAMP)) { + /* check if network interface did provide a timestamp; this depends on + * hardware support. A timestamp of zero is used to indicate a missing + * timestamp */ + if (aux->timestamp > 0) { + aux->flags &= ~SOCK_AUX_GET_TIMESTAMP; + } + } #endif *data = pkt->data; *buf_ctx = pkt; diff --git a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c index fd81ec83d2..dbfa9cbcc5 100644 --- a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c +++ b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c @@ -224,7 +224,12 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, _aux.local = (sock_ip_ep_t *)&aux->local; } #endif - res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, _aux); +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TIMESTAMP)) { + _aux.timestamp = &aux->timestamp; + } +#endif + res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, &_aux); if (res < 0) { return res; } @@ -251,6 +256,16 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, aux->flags &= ~SOCK_AUX_GET_LOCAL; aux->local.port = sock->local.port; } +#endif +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_TIMESTAMP)) { + /* check if network interface did provide a timestamp; this depends on + * hardware support. A timestamp of zero is used to indicate a missing + * timestamp */ + if (_aux.flags & GNRC_SOCK_RECV_AUX_FLAG_TIMESTAMP) { + aux->flags &= ~SOCK_AUX_GET_TIMESTAMP; + } + } #endif *data = pkt->data; *buf_ctx = pkt; From 5b3d862ef76aa2fa7bbf646fed69bf4d0a25c38f Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Fri, 4 Dec 2020 21:19:10 +0100 Subject: [PATCH 2/3] tests/gnrc_sock_udp: also test sock_aux_timestamp --- tests/gnrc_sock_udp/Makefile | 5 +++++ tests/gnrc_sock_udp/main.c | 17 +++++++++++++---- tests/gnrc_sock_udp/stack.c | 27 +++++++++++++++----------- tests/gnrc_sock_udp/stack.h | 37 +++++++++++++++++++++++++++++++++--- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/tests/gnrc_sock_udp/Makefile b/tests/gnrc_sock_udp/Makefile index 4dbc8d4065..ac0652b55a 100644 --- a/tests/gnrc_sock_udp/Makefile +++ b/tests/gnrc_sock_udp/Makefile @@ -1,11 +1,16 @@ include ../Makefile.tests_common AUX_LOCAL ?= 1 +AUX_TIMESTAMP ?= 1 ifeq (1, $(AUX_LOCAL)) USEMODULE += sock_aux_local endif +ifeq (1, $(AUX_LOCAL)) + USEMODULE += sock_aux_timestamp +endif + USEMODULE += gnrc_sock_check_reuse USEMODULE += sock_udp USEMODULE += gnrc_ipv6 diff --git a/tests/gnrc_sock_udp/main.c b/tests/gnrc_sock_udp/main.c index ae8bf75d9e..c12e06d893 100644 --- a/tests/gnrc_sock_udp/main.c +++ b/tests/gnrc_sock_udp/main.c @@ -429,13 +429,16 @@ 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 }; sock_udp_ep_t result; - sock_udp_aux_rx_t aux = { .flags = SOCK_AUX_GET_LOCAL }; + sock_udp_aux_rx_t aux = { + .flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP + }; 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(_inject_packet_aux(&src_addr, &dst_addr, _TEST_PORT_REMOTE, + _TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), + _TEST_NETIF, &inject_aux)); expect(sizeof("ABCD") == sock_udp_recv_aux(&_sock, _test_buffer, sizeof(_test_buffer), 0, &result, &aux)); @@ -449,6 +452,12 @@ static void test_sock_udp_recv__aux(void) expect(_TEST_PORT_LOCAL == aux.local.port); #else expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + expect(!(aux.flags & SOCK_AUX_GET_TIMESTAMP)); + expect(inject_aux.timestamp == aux.timestamp); +#else + expect(aux.flags & SOCK_AUX_GET_TIMESTAMP); #endif expect(_check_net()); } diff --git a/tests/gnrc_sock_udp/stack.c b/tests/gnrc_sock_udp/stack.c index 90305d5076..a5c7556117 100644 --- a/tests/gnrc_sock_udp/stack.c +++ b/tests/gnrc_sock_udp/stack.c @@ -47,9 +47,10 @@ static gnrc_pktsnip_t *_build_udp_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) + uint16_t netif, + const inject_aux_t *aux) { - gnrc_pktsnip_t *netif_hdr, *ipv6, *udp; + gnrc_pktsnip_t *netif_hdr_snip, *ipv6, *udp; udp_hdr_t *udp_hdr; ipv6_hdr_t *ipv6_hdr; uint16_t csum = 0; @@ -86,21 +87,25 @@ static gnrc_pktsnip_t *_build_udp_packet(const ipv6_addr_t *src, udp_hdr->checksum = byteorder_htons(~csum); } udp = gnrc_pkt_append(udp, ipv6); - netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0); - if (netif_hdr == NULL) { + netif_hdr_snip = gnrc_netif_hdr_build(NULL, 0, NULL, 0); + if (netif_hdr_snip == NULL) { return NULL; } - ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = (kernel_pid_t)netif; - return gnrc_pkt_append(udp, netif_hdr); + gnrc_netif_hdr_t *netif_hdr = netif_hdr_snip->data; + netif_hdr->if_pid = (kernel_pid_t)netif; + if (aux) { + gnrc_netif_hdr_set_timestamp(netif_hdr, aux->timestamp); + } + return gnrc_pkt_append(udp, netif_hdr_snip); } - -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) +bool _inject_packet_aux(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, + const inject_aux_t *aux) { gnrc_pktsnip_t *pkt = _build_udp_packet(src, dst, src_port, dst_port, - data, data_len, netif); + data, data_len, netif, aux); if (pkt == NULL) { return false; diff --git a/tests/gnrc_sock_udp/stack.h b/tests/gnrc_sock_udp/stack.h index 73aaf6b3e5..6975c1c01e 100644 --- a/tests/gnrc_sock_udp/stack.h +++ b/tests/gnrc_sock_udp/stack.h @@ -39,6 +39,13 @@ void _net_init(void); */ void _prepare_send_checks(void); +/** + * @brief Auxiliary data to inject + */ +typedef struct { + uint64_t timestamp; /**< Timestamp of reception */ +} inject_aux_t; + /** * @brief Injects a received UDP packet into the stack * @@ -53,9 +60,33 @@ void _prepare_send_checks(void); * @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); +bool _inject_packet_aux(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, + const inject_aux_t *aux); + +/** + * @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 + * + * @return true, if packet was successfully injected + * @return false, if an error occurred during injection + */ +static inline 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) +{ + return _inject_packet_aux(src, dst, src_port, dst_port, data, data_len, + netif, NULL); +} /** * @brief Checks networking state (e.g. packet buffer state) From 14e0f5b06469f1b97128948f9077befefa71a7c8 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Fri, 4 Dec 2020 21:28:24 +0100 Subject: [PATCH 3/3] tests/gnrc_sock_ip: also test sock_aux_timestamp --- tests/gnrc_sock_ip/Makefile | 5 +++++ tests/gnrc_sock_ip/main.c | 15 ++++++++++++--- tests/gnrc_sock_ip/stack.c | 25 +++++++++++++++---------- tests/gnrc_sock_ip/stack.h | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/tests/gnrc_sock_ip/Makefile b/tests/gnrc_sock_ip/Makefile index 968ea0fdd3..20888afa0d 100644 --- a/tests/gnrc_sock_ip/Makefile +++ b/tests/gnrc_sock_ip/Makefile @@ -1,11 +1,16 @@ include ../Makefile.tests_common AUX_LOCAL ?= 1 +AUX_TIMESTAMP ?= 1 ifeq (1, $(AUX_LOCAL)) USEMODULE += sock_aux_local endif +ifeq (1, $(AUX_LOCAL)) + USEMODULE += sock_aux_timestamp +endif + USEMODULE += sock_ip USEMODULE += gnrc_ipv6 USEMODULE += ps diff --git a/tests/gnrc_sock_ip/main.c b/tests/gnrc_sock_ip/main.c index a37365a423..fb8c3ae66b 100644 --- a/tests/gnrc_sock_ip/main.c +++ b/tests/gnrc_sock_ip/main.c @@ -349,13 +349,16 @@ static void test_sock_ip_recv__aux(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_ip_ep_t local = { .family = AF_INET6 }; + 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_ip_aux_rx_t aux = { + .flags = SOCK_AUX_GET_LOCAL | SOCK_AUX_GET_TIMESTAMP + }; expect(0 == sock_ip_create(&_sock, &local, NULL, _TEST_PROTO, SOCK_FLAGS_REUSE_EP)); - expect(_inject_packet(&src_addr, &dst_addr, _TEST_PROTO, "ABCD", - sizeof("ABCD"), _TEST_NETIF)); + expect(_inject_packet_aux(&src_addr, &dst_addr, _TEST_PROTO, "ABCD", + sizeof("ABCD"), _TEST_NETIF, &inject_aux)); expect(sizeof("ABCD") == sock_ip_recv_aux(&_sock, _test_buffer, sizeof(_test_buffer), 0, &result, &aux)); @@ -367,6 +370,12 @@ static void test_sock_ip_recv__aux(void) expect(memcmp(&aux.local.addr, &dst_addr, sizeof(dst_addr)) == 0); #else expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif +#if IS_USED(MODULE_SOCK_AUX_TIMESTAMP) + expect(!(aux.flags & SOCK_AUX_GET_TIMESTAMP)); + expect(aux.timestamp == inject_aux.timestamp); +#else + expect(aux.flags & SOCK_AUX_GET_TIMESTAMP); #endif expect(_check_net()); } diff --git a/tests/gnrc_sock_ip/stack.c b/tests/gnrc_sock_ip/stack.c index 79af2cee8c..5fa35c787f 100644 --- a/tests/gnrc_sock_ip/stack.c +++ b/tests/gnrc_sock_ip/stack.c @@ -41,9 +41,10 @@ void _prepare_send_checks(void) static gnrc_pktsnip_t *_build_ipv6_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst, uint8_t nh, void *data, size_t data_len, - uint16_t netif) + uint16_t netif, + const inject_aux_t *aux) { - gnrc_pktsnip_t *netif_hdr, *ipv6, *payload; + gnrc_pktsnip_t *netif_hdr_snip, *ipv6, *payload; ipv6_hdr_t *ipv6_hdr; if ((netif > INT16_MAX) || (data_len > UINT16_MAX)) { @@ -63,21 +64,25 @@ static gnrc_pktsnip_t *_build_ipv6_packet(const ipv6_addr_t *src, ipv6_hdr->nh = nh; ipv6_hdr->hl = 64; payload = gnrc_pkt_append(payload, ipv6); - netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0); - if (netif_hdr == NULL) { + netif_hdr_snip = gnrc_netif_hdr_build(NULL, 0, NULL, 0); + if (netif_hdr_snip == NULL) { return NULL; } - ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = (kernel_pid_t)netif; - return gnrc_pkt_append(payload, netif_hdr); + gnrc_netif_hdr_t *netif_hdr = netif_hdr_snip->data; + netif_hdr->if_pid = (kernel_pid_t)netif; + if (aux) { + gnrc_netif_hdr_set_timestamp(netif_hdr, aux->timestamp); + } + return gnrc_pkt_append(payload, netif_hdr_snip); } -bool _inject_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst, - uint8_t proto, void *data, size_t data_len, - uint16_t netif) +bool _inject_packet_aux(const ipv6_addr_t *src, const ipv6_addr_t *dst, + uint8_t proto, void *data, size_t data_len, + uint16_t netif, const inject_aux_t *aux) { gnrc_pktsnip_t *pkt = _build_ipv6_packet(src, dst, proto, data, data_len, - netif); + netif, aux); if (pkt == NULL) { return false; diff --git a/tests/gnrc_sock_ip/stack.h b/tests/gnrc_sock_ip/stack.h index 4438096171..b2e3e804dc 100644 --- a/tests/gnrc_sock_ip/stack.h +++ b/tests/gnrc_sock_ip/stack.h @@ -39,6 +39,31 @@ void _net_init(void); */ void _prepare_send_checks(void); +/** + * @brief Structure containing auxiliary data to inject + */ +typedef struct { + uint64_t timestamp; /**< Timestamp of reception */ +} inject_aux_t; + +/** + * @brief Injects a received IPv6 packet into the stack + * + * @param[in] src The source address of the IPv6 packet + * @param[in] dst The destination address of the IPv6 packet + * @param[in] proto The next header field of the IPv6 packet + * @param[in] data The payload of the IPv6 packet + * @param[in] data_len The payload length of the IPv6 packet + * @param[in] netif The interface the packet came over + * @param[in] aux Auxiliary data to inject + * + * @return true, if packet was successfully injected + * @return false, if an error occurred during injection + */ +bool _inject_packet_aux(const ipv6_addr_t *src, const ipv6_addr_t *dst, + uint8_t proto, void *data, size_t data_len, + uint16_t netif, const inject_aux_t *aux); + /** * @brief Injects a received IPv6 packet into the stack * @@ -52,9 +77,13 @@ void _prepare_send_checks(void); * @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, - uint8_t proto, void *data, size_t data_len, - uint16_t netif); +static inline bool _inject_packet(const ipv6_addr_t *src, + const ipv6_addr_t *dst, + uint8_t proto, void *data, size_t data_len, + uint16_t netif) +{ + return _inject_packet_aux(src, dst, proto, data, data_len, netif, NULL); +} /** * @brief Checks networking state (e.g. packet buffer state)