diff --git a/sys/include/net/ng_nettype.h b/sys/include/net/ng_nettype.h index fa79b070b04a4fcbe35bd9523105d7b7d9fb2e57..7706ec4a3f527d1a349b0e6690f411ea99c78132 100644 --- a/sys/include/net/ng_nettype.h +++ b/sys/include/net/ng_nettype.h @@ -37,6 +37,11 @@ extern "C" { * @note Expand at will. */ typedef enum { + /** + * @brief Not so much protocol but data type that is passed to network + * devices using the netdev interface + */ + NG_NETTYPE_IOVEC = -2, /** * @brief Protocol is as defined in @ref ng_netif_hdr_t. Not usable with * @ref net_ng_netreg diff --git a/sys/include/net/ng_pkt.h b/sys/include/net/ng_pkt.h index 08ae84c0b33b0ad7a3ac5ffd089098e987352051..497bbf195e0635c7ea4e6287f314b3517cd70820 100644 --- a/sys/include/net/ng_pkt.h +++ b/sys/include/net/ng_pkt.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2014, 2015 Martine Lenders <mlenders@inf.fu-berlin.de> + * 2015 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 @@ -16,6 +17,7 @@ * @brief General definitions for network packets * * @author Martine Lenders <mlenders@inf.fu-berlin.de> + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> */ #ifndef NG_PKT_H_ #define NG_PKT_H_ @@ -129,6 +131,25 @@ static inline size_t ng_pkt_len(ng_pktsnip_t *pkt) return len; } +/** + * @brief Count the numbers of snips in the given packet + * + * @param[in] pkt first snip in the packet + * + * @return number of snips in the given packet + */ +static inline size_t ng_pkt_count(const ng_pktsnip_t *pkt) +{ + size_t count = 0; + + while (pkt) { + ++count; + pkt = pkt->next; + } + + return count; +} + #ifdef __cplusplus } #endif diff --git a/sys/include/net/ng_pktbuf.h b/sys/include/net/ng_pktbuf.h index f790399865a2a1f87144627547ee7950d9dbd1c2..32655d266d1d6dbe62994714d503fe71e107c12a 100644 --- a/sys/include/net/ng_pktbuf.h +++ b/sys/include/net/ng_pktbuf.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de> + * 2015 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 @@ -24,6 +25,7 @@ * and layers can allocate space for packets here. * * @author Martine Lenders <mlenders@inf.fu-berlin.de> + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> */ #ifndef NG_PKTBUF_H_ #define NG_PKTBUF_H_ @@ -156,11 +158,26 @@ void ng_pktbuf_release(ng_pktsnip_t *pkt); * @param[in] pkt The packet you want to write into. * * @return The (new) pointer to the pkt. - * @return NULL, if ng_pktsnip_t::users of @p pkt > 1 and if there is not enough - * space in the packet buffer. + * @return NULL, if ng_pktsnip_t::users of @p pkt > 1 and if there is not + * enough space in the packet buffer. */ ng_pktsnip_t *ng_pktbuf_start_write(ng_pktsnip_t *pkt); +/** + * @brief Create a IOVEC representation of the packet pointed to by *pkt* + * + * @details This function will create a new packet snip in the packet buffer, + * which points to the given *pkt* and contains a IOVEC representation + * of the referenced packet in its data section. + * + * @param[in] pkt Packet to export as IOVEC + * @param[out] len Number of elements in the IOVEC + * + * @return Pointer to the 'IOVEC packet snip' + * @return NULL, if packet is empty of the packet buffer is full + */ +ng_pktsnip_t *ng_pktbuf_get_iovec(ng_pktsnip_t *pkt, size_t *len); + /** * @brief Deletes a snip from a packet and the packet buffer. * diff --git a/sys/libc/include/sys/uio.h b/sys/libc/include/sys/uio.h index 8ee74b0f429923adbd60426158035597cdb39624..c3e4d8e23486f011d2bf4e13f3c6ecd33914aa66 100644 --- a/sys/libc/include/sys/uio.h +++ b/sys/libc/include/sys/uio.h @@ -20,6 +20,7 @@ #ifndef UIO_H #define UIO_H +#include <stdlib.h> #include <sys/types.h> #ifdef __cplusplus diff --git a/sys/net/crosslayer/ng_pktbuf_static/ng_pktbuf_static.c b/sys/net/crosslayer/ng_pktbuf_static/ng_pktbuf_static.c index 20cc35a7b17ae54e1190114177cca118c369e889..7a1fe9ef0165a76ac12fe950eaa007a562b0a40d 100644 --- a/sys/net/crosslayer/ng_pktbuf_static/ng_pktbuf_static.c +++ b/sys/net/crosslayer/ng_pktbuf_static/ng_pktbuf_static.c @@ -22,6 +22,7 @@ #include <string.h> #include <stdio.h> #include <sys/types.h> +#include <sys/uio.h> #include "mutex.h" #include "od.h" @@ -232,6 +233,37 @@ ng_pktsnip_t *ng_pktbuf_start_write(ng_pktsnip_t *pkt) return pkt; } +ng_pktsnip_t *ng_pktbuf_get_iovec(ng_pktsnip_t *pkt, size_t *len) +{ + size_t length; + ng_pktsnip_t *head; + struct iovec *vec; + + if (pkt == NULL) { + *len = 0; + return NULL; + } + + /* count the number of snips in the packet and allocate the IOVEC */ + length = ng_pkt_count(pkt); + head = ng_pktbuf_add(pkt, NULL, (length * sizeof(struct iovec)), + NG_NETTYPE_IOVEC); + if (head == NULL) { + *len = 0; + return NULL; + } + vec = (struct iovec *)(head->data); + /* fill the IOVEC */ + while (pkt != NULL) { + vec->iov_base = pkt->data; + vec->iov_len = pkt->size; + ++vec; + pkt = pkt->next; + } + *len = length; + return head; +} + #ifdef DEVELHELP #ifdef MODULE_OD static inline void _print_chunk(void *chunk, size_t size, int num) diff --git a/tests/unittests/tests-pkt/tests-pkt.c b/tests/unittests/tests-pkt/tests-pkt.c index 51f3295317bda83f670cdf354057c9c0b37c30ad..424bab237f5bbbc6f05bed81d3ad043beaed01ed 100644 --- a/tests/unittests/tests-pkt/tests-pkt.c +++ b/tests/unittests/tests-pkt/tests-pkt.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2014, 2015 Martine Lenders <mail@martine-lenders.eu> + * * 2015 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 @@ -82,6 +83,28 @@ static void test_pkt_len__3_elem(void) TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8) + sizeof(TEST_STRING12), ng_pkt_len(&snip2)); TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8), ng_pkt_len(&snip1)); } +static void test_pkt_count__1_elem(void) +{ + ng_pktsnip_t snip1 = _INIT_ELEM_STATIC_DATA(TEST_STRING8, NULL); + + TEST_ASSERT_EQUAL_INT(1, ng_pkt_count(&snip1)); +} + +static void test_pkt_count__5_elem(void) +{ + ng_pktsnip_t snip1 = _INIT_ELEM_STATIC_DATA(TEST_STRING8, NULL); + ng_pktsnip_t snip2 = _INIT_ELEM_STATIC_DATA(TEST_STRING12, &snip1); + ng_pktsnip_t snip3 = _INIT_ELEM(sizeof("a"), "a", &snip2); + ng_pktsnip_t snip4 = _INIT_ELEM_STATIC_DATA(TEST_STRING8, &snip3); + ng_pktsnip_t snip5 = _INIT_ELEM_STATIC_DATA(TEST_STRING8, &snip4); + + TEST_ASSERT_EQUAL_INT(5, ng_pkt_count(&snip5)); +} + +static void test_pkt_count__null(void) +{ + TEST_ASSERT_EQUAL_INT(0, ng_pkt_count(NULL)); +} Test *tests_pkt_tests(void) { @@ -93,6 +116,9 @@ Test *tests_pkt_tests(void) new_TestFixture(test_pkt_len__2_elem), new_TestFixture(test_pkt_len__2_elem__overflow), new_TestFixture(test_pkt_len__3_elem), + new_TestFixture(test_pkt_count__1_elem), + new_TestFixture(test_pkt_count__5_elem), + new_TestFixture(test_pkt_count__null), }; EMB_UNIT_TESTCALLER(pkt_tests, NULL, NULL, fixtures); diff --git a/tests/unittests/tests-pktbuf/tests-pktbuf.c b/tests/unittests/tests-pktbuf/tests-pktbuf.c index 4abe42907aa68508a9bd18b1596c7faae7c76aee..b44845d3abbfa598b9623681fc1ba0fda87c8679 100644 --- a/tests/unittests/tests-pktbuf/tests-pktbuf.c +++ b/tests/unittests/tests-pktbuf/tests-pktbuf.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Martine Lenders <mail@martine-lenders.eu> + * 2015 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 @@ -13,6 +14,7 @@ */ #include <errno.h> #include <stdint.h> +#include <sys/uio.h> #include "embUnit.h" @@ -644,6 +646,59 @@ static void test_pktbuf_start_write__pkt_users_2(void) TEST_ASSERT(ng_pktbuf_is_empty()); } +static void test_pktbuf_get_iovec__1_elem(void) +{ + struct iovec *vec; + size_t len; + ng_pktsnip_t *snip = ng_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16), + NG_NETTYPE_UNDEF); + snip = ng_pktbuf_get_iovec(snip, &len); + vec = (struct iovec *)snip->data; + + TEST_ASSERT_EQUAL_INT(sizeof(struct iovec), snip->size); + TEST_ASSERT_EQUAL_INT(1, len); + TEST_ASSERT(snip->next->data == vec[0].iov_base); + TEST_ASSERT_EQUAL_INT(snip->next->size, vec[0].iov_len); + + ng_pktbuf_release(snip); + TEST_ASSERT(ng_pktbuf_is_empty()); +} + +static void test_pktbuf_get_iovec__3_elem(void) +{ + struct iovec *vec; + size_t len; + ng_pktsnip_t *snip = ng_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16), + NG_NETTYPE_UNDEF); + snip = ng_pktbuf_add(snip, TEST_STRING8, sizeof(TEST_STRING8), NG_NETTYPE_UNDEF); + snip = ng_pktbuf_add(snip, TEST_STRING4, sizeof(TEST_STRING4), NG_NETTYPE_UNDEF); + snip = ng_pktbuf_get_iovec(snip, &len); + vec = (struct iovec *)snip->data; + + TEST_ASSERT_EQUAL_INT((sizeof(struct iovec) * 3), snip->size); + TEST_ASSERT_EQUAL_INT(3, len); + TEST_ASSERT(snip->next->data == vec[0].iov_base); + TEST_ASSERT(snip->next->next->data == vec[1].iov_base); + TEST_ASSERT(snip->next->next->next->data == vec[2].iov_base); + TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING4), vec[0].iov_len); + TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING8), vec[1].iov_len); + TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING16), vec[2].iov_len); + + ng_pktbuf_release(snip); + TEST_ASSERT(ng_pktbuf_is_empty()); +} + +static void test_pktbuf_get_iovec__null(void) +{ + ng_pktsnip_t *res; + size_t len; + + res = ng_pktbuf_get_iovec(NULL, &len); + + TEST_ASSERT(res == NULL); + TEST_ASSERT_EQUAL_INT(0, len); +} + Test *tests_pktbuf_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -684,6 +739,9 @@ Test *tests_pktbuf_tests(void) new_TestFixture(test_pktbuf_start_write__NULL), new_TestFixture(test_pktbuf_start_write__pkt_users_1), new_TestFixture(test_pktbuf_start_write__pkt_users_2), + new_TestFixture(test_pktbuf_get_iovec__1_elem), + new_TestFixture(test_pktbuf_get_iovec__3_elem), + new_TestFixture(test_pktbuf_get_iovec__null), }; EMB_UNIT_TESTCALLER(ng_pktbuf_tests, set_up, NULL, fixtures);