diff --git a/sys/include/net/gnrc/pkt.h b/sys/include/net/gnrc/pkt.h index 647d8ca776b4f83a60389bc010909fa0c3eb848f..07eb593c4cbea0a143ef25847c0237b7fbbd7b6e 100644 --- a/sys/include/net/gnrc/pkt.h +++ b/sys/include/net/gnrc/pkt.h @@ -96,20 +96,25 @@ extern "C" { * | * L2 header 3 * * L2 header 4 * + * The first three fields (next, data, size) match iolist_t (named iol_next, + * iol_base and iol_len there). That means that any pktsnip can be casted to + * iolist_t for direct passing to e.g., netdev send() functions. + * * @note This type has no initializer on purpose. Please use @ref net_gnrc_pktbuf * as factory. */ /* packed to be aligned correctly in the static packet buffer */ typedef struct gnrc_pktsnip { + /* the first three fields *MUST* match iolist_t! */ + struct gnrc_pktsnip *next; /**< next snip in the packet */ + void *data; /**< pointer to the data of the snip */ + size_t size; /**< the length of the snip in byte */ /** * @brief Counter of threads currently having control over this packet. * * @internal */ unsigned int users; - struct gnrc_pktsnip *next; /**< next snip in the packet */ - void *data; /**< pointer to the data of the snip */ - size_t size; /**< the length of the snip in byte */ gnrc_nettype_t type; /**< protocol of the packet snip */ #ifdef MODULE_GNRC_NETERR kernel_pid_t err_sub; /**< subscriber to errors related to this diff --git a/tests/unittests/tests-pkt/tests-pkt.c b/tests/unittests/tests-pkt/tests-pkt.c index 2e48bd626eaa693661578d52e76ab56a931d13bb..ac8e123a8b8011641a8a90131fbc86da562a41ee 100644 --- a/tests/unittests/tests-pkt/tests-pkt.c +++ b/tests/unittests/tests-pkt/tests-pkt.c @@ -13,21 +13,27 @@ * @file */ #include <errno.h> +#include <stddef.h> #include <stdint.h> +#include <string.h> #include "embUnit/embUnit.h" #include "net/gnrc/pkt.h" #include "net/gnrc/nettype.h" +#include "iolist.h" + #include "unittests-constants.h" #include "tests-pkt.h" -#define _INIT_ELEM(len, data, next) \ - { 1, (next), (data), (len), GNRC_NETTYPE_UNDEF } +#define _INIT_ELEM(len, _data, _next) \ + { .users = 1, .next = (_next), .data = (_data), \ + .size = (len), .type = GNRC_NETTYPE_UNDEF \ + } #define _INIT_ELEM_STATIC_DATA(data, next) _INIT_ELEM(sizeof(data), data, next) -#define _INIT_ELEM_STATIC_TYPE(type, next) \ - { 1, (next), NULL, 0, (type) } +#define _INIT_ELEM_STATIC_TYPE(_type, _next) \ + { .users = 1, .next = (_next), .data = NULL, .size = 0, .type = (_type) } static void test_pkt_len__NULL(void) { @@ -129,6 +135,40 @@ static void test_pktsnip_search_type(void) TEST_ASSERT_NULL(gnrc_pktsnip_search_type(&snip3, GNRC_NETTYPE_NUMOF)); } +static void test_pkt_equals_iolist(void) +{ + iolist_t iol; + gnrc_pktsnip_t pkt; + + memset(&iol, '\0', sizeof(iol)); + memset(&pkt, '\0', sizeof(pkt)); + + /* compare empty structs */ + TEST_ASSERT_EQUAL_INT(0, memcmp(&iol, &pkt, sizeof(iol))); + + /* check next pointer position */ + iol.iol_next = (void *)0xAAAAAAAA; + pkt.next = (void *)0xAAAAAAAA; + + TEST_ASSERT_EQUAL_INT(0, memcmp(&iol, &pkt, sizeof(iol))); + + /* check data pointer position */ + iol.iol_base = &iol; + pkt.data = &iol; + + TEST_ASSERT_EQUAL_INT(0, memcmp(&iol, &pkt, sizeof(iol))); + + /* check size position */ + iol.iol_len = 0x12345678; + pkt.size = 0x12345678; + + TEST_ASSERT_EQUAL_INT(0, memcmp(&iol, &pkt, sizeof(iol))); + + TEST_ASSERT_EQUAL_INT(offsetof(iolist_t, iol_next), offsetof(gnrc_pktsnip_t, next)); + TEST_ASSERT_EQUAL_INT(offsetof(iolist_t, iol_base), offsetof(gnrc_pktsnip_t, data)); + TEST_ASSERT_EQUAL_INT(offsetof(iolist_t, iol_len), offsetof(gnrc_pktsnip_t, size)); +} + Test *tests_pkt_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -143,6 +183,7 @@ Test *tests_pkt_tests(void) new_TestFixture(test_pkt_count__5_elem), new_TestFixture(test_pkt_count__null), new_TestFixture(test_pktsnip_search_type), + new_TestFixture(test_pkt_equals_iolist), }; EMB_UNIT_TESTCALLER(pkt_tests, NULL, NULL, fixtures);