diff --git a/Makefile.dep b/Makefile.dep index aafc7540b39faec5f9bb8e3bc9f3a402d8642776..eb0e4c67af39b73e6205f1936b9305d329ce8ff9 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -110,6 +110,7 @@ endif ifneq (,$(filter netdev_tap,$(USEMODULE))) USEMODULE += netif USEMODULE += netdev_eth + USEMODULE += iolist endif ifneq (,$(filter gnrc_tftp,$(USEMODULE))) diff --git a/boards/native/Makefile.dep b/boards/native/Makefile.dep index 2639777a1d2d82234ff36e87173df57079a83a13..8eec472da082e4b1542813c6f8600c7bffa1eb40 100644 --- a/boards/native/Makefile.dep +++ b/boards/native/Makefile.dep @@ -14,6 +14,7 @@ ifneq (,$(filter can,$(USEMODULE))) endif ifneq (,$(filter socket_zep,$(USEMODULE))) + USEMODULE += iolist USEMODULE += netdev_ieee802154 USEMODULE += checksum USEMODULE += random diff --git a/cpu/cc2538/radio/cc2538_rf_netdev.c b/cpu/cc2538/radio/cc2538_rf_netdev.c index ad071120fa812f1994ddd9df160f89f4a10e65fa..71f6206c86a7b9a341e4e1f7f54fa7708dbe2dc4 100644 --- a/cpu/cc2538/radio/cc2538_rf_netdev.c +++ b/cpu/cc2538/radio/cc2538_rf_netdev.c @@ -33,22 +33,6 @@ #define _MAX_MHR_OVERHEAD (25) -static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len); -static int _set(netdev_t *dev, netopt_t opt, const void *value, size_t value_len); -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); -static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); -static void _isr(netdev_t *netdev); -static int _init(netdev_t *dev); - -const netdev_driver_t cc2538_rf_driver = { - .get = _get, - .set = _set, - .send = _send, - .recv = _recv, - .isr = _isr, - .init = _init, -}; - /* Reference pointer for the IRQ handler */ static netdev_t *_dev; @@ -253,7 +237,7 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t value_ return res; } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { (void) netdev; @@ -268,8 +252,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) start of the FIFO, so we can come back and update it later */ rfcore_write_byte(0); - for (unsigned i = 0; i < count; i++) { - pkt_len += vector[i].iov_len; + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + pkt_len += iol->iol_len; if (pkt_len > CC2538_RF_MAX_DATA_LEN) { DEBUG("cc2538_rf: packet too large (%u > %u)\n", @@ -277,7 +261,7 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) return -EOVERFLOW; } - rfcore_write_fifo(vector[i].iov_base, vector[i].iov_len); + rfcore_write_fifo(iol->iol_base, iol->iol_len); } #ifdef MODULE_NETSTATS_L2 @@ -407,3 +391,12 @@ static int _init(netdev_t *netdev) return 0; } + +const netdev_driver_t cc2538_rf_driver = { + .get = _get, + .set = _set, + .send = _send, + .recv = _recv, + .isr = _isr, + .init = _init, +}; diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c index 1416a77793b141299a874192e47b26d1ff994d86..2330e64f4f06acfd467614932c773165a97b401c 100644 --- a/cpu/native/netdev_tap/netdev_tap.c +++ b/cpu/native/netdev_tap/netdev_tap.c @@ -26,6 +26,7 @@ #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> +#include <sys/uio.h> #include <unistd.h> /* needs to be included before native's declarations of ntohl etc. */ @@ -51,6 +52,7 @@ #include "async_read.h" +#include "iolist.h" #include "net/eui64.h" #include "net/netdev.h" #include "net/netdev/eth.h" @@ -64,7 +66,7 @@ /* netdev interface */ static int _init(netdev_t *netdev); -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned n); +static int _send(netdev_t *netdev, const iolist_t *iolist); static int _recv(netdev_t *netdev, void *buf, size_t n, void *info); static inline void _get_mac_addr(netdev_t *netdev, uint8_t *dst) @@ -273,17 +275,20 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) return -1; } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned n) +static int _send(netdev_t *netdev, const iolist_t *iolist) { netdev_tap_t *dev = (netdev_tap_t*)netdev; - int res = _native_writev(dev->tap_fd, vector, n); + + struct iovec iov[iolist_count(iolist)]; + + unsigned n; + size_t bytes = iolist_to_iovec(iolist, iov, &n); + + int res = _native_writev(dev->tap_fd, iov, n); #ifdef MODULE_NETSTATS_L2 - size_t bytes = 0; - for (unsigned i = 0; i < n; i++) { - bytes += vector->iov_len; - vector++; - } netdev->stats.tx_bytes += bytes; +#else + (void)bytes; #endif if (netdev->event_callback) { netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE); diff --git a/cpu/native/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index d3e51c69ed27079c7efbf567055e11755b1fcb63..162d55ad02914fcd500a9393b110141017c30d8a 100644 --- a/cpu/native/socket_zep/socket_zep.c +++ b/cpu/native/socket_zep/socket_zep.c @@ -36,23 +36,6 @@ #define _UNIX_NTP_ERA_OFFSET (2208988800U) -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned n); -static int _recv(netdev_t *netdev, void *buf, size_t n, void *info); -static void _isr(netdev_t *netdev); -static int _init(netdev_t *netdev); -static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len); -static int _set(netdev_t *netdev, netopt_t opt, const void *value, - size_t value_len); - -static const netdev_driver_t socket_zep_driver = { - .send = _send, - .recv = _recv, - .init = _init, - .isr = _isr, - .get = _get, - .set = _set, -}; - static size_t _zep_hdr_fill_v2_data(socket_zep_t *dev, zep_v2_data_hdr_t *hdr, size_t payload_len) { @@ -85,24 +68,23 @@ static inline size_t _zep_hdr_fill(socket_zep_t *dev, zep_hdr_t *hdr, payload_len); } -static size_t _prep_vector(socket_zep_t *dev, const struct iovec *vector, +static size_t _prep_vector(socket_zep_t *dev, const iolist_t *iolist, unsigned n, struct iovec *out) { - size_t bytes = 0; + size_t bytes; dev->chksum_buf = 0; - for (unsigned i = 0; i < n; i++) { - bytes += vector[i].iov_len; - } + bytes = iolist_size(iolist); bytes += sizeof(uint16_t); /* FCS field */ out[0].iov_base = &dev->snd_hdr_buf; out[0].iov_len = _zep_hdr_fill(dev, out[0].iov_base, bytes); for (unsigned i = 0; i < n; i++) { /* discard const qualifier, we won't change anything. Promise! */ - out[i + 1].iov_base = vector[i].iov_base; - out[i + 1].iov_len = vector[i].iov_len; + out[i + 1].iov_base = iolist->iol_base; + out[i + 1].iov_len = iolist->iol_len; dev->chksum_buf = ucrc16_calc_le(out[i + 1].iov_base, out[i + 1].iov_len, UCRC16_CCITT_POLY_LE, dev->chksum_buf); + iolist = iolist->iol_next; } dev->chksum_buf = byteorder_btols(byteorder_htons(dev->chksum_buf)).u16; out[n + 1].iov_base = &dev->chksum_buf; @@ -110,16 +92,17 @@ static size_t _prep_vector(socket_zep_t *dev, const struct iovec *vector, return bytes; } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned n) +static int _send(netdev_t *netdev, const iolist_t *iolist) { socket_zep_t *dev = (socket_zep_t *)netdev; + unsigned n = iolist_count(iolist); struct iovec v[n + 2]; size_t bytes; int res; assert((dev != NULL) && (dev->sock_fd != 0)); - bytes = _prep_vector(dev, vector, n, v); - DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)vector, n); + bytes = _prep_vector(dev, iolist, n, v); + DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)iolist, n); /* simulate TX_STARTED interrupt */ if (netdev->event_callback) { dev->last_event = NETDEV_EVENT_TX_STARTED; @@ -350,6 +333,14 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value, value, value_len); } +static const netdev_driver_t socket_zep_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params) { diff --git a/cpu/nrf5x_common/radio/nrfmin/nrfmin.c b/cpu/nrf5x_common/radio/nrfmin/nrfmin.c index 1d1d127869c6202e97fb10cbc993b998311a37d6..c473594572b3f66fe685a26a1ed340f0247a0266 100644 --- a/cpu/nrf5x_common/radio/nrfmin/nrfmin.c +++ b/cpu/nrf5x_common/radio/nrfmin/nrfmin.c @@ -325,11 +325,11 @@ void isr_radio(void) cortexm_isr_end(); } -static int nrfmin_send(netdev_t *dev, const struct iovec *vector, unsigned count) +static int nrfmin_send(netdev_t *dev, const iolist_t *iolist) { (void)dev; - assert((vector != NULL) && (count > 0) && (state != STATE_OFF)); + assert((iolist) && (state != STATE_OFF)); /* wait for any ongoing transmission to finish and go into idle state */ while (state == STATE_TX) {} @@ -337,17 +337,17 @@ static int nrfmin_send(netdev_t *dev, const struct iovec *vector, unsigned count /* copy packet data into the transmit buffer */ int pos = 0; - for (unsigned i = 0; i < count; i++) { - if ((pos + vector[i].iov_len) > NRFMIN_PKT_MAX) { + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + if ((pos + iol->iol_len) > NRFMIN_PKT_MAX) { DEBUG("[nrfmin] send: unable to do so, packet is too large!\n"); return -EOVERFLOW; } - memcpy(&tx_buf.raw[pos], vector[i].iov_base, vector[i].iov_len); - pos += vector[i].iov_len; + memcpy(&tx_buf.raw[pos], iol->iol_base, iol->iol_len); + pos += iol->iol_len; } /* set output buffer and destination address */ - nrfmin_hdr_t *hdr = (nrfmin_hdr_t *)vector[0].iov_base; + nrfmin_hdr_t *hdr = (nrfmin_hdr_t *)iolist->iol_base; NRF_RADIO->PACKETPTR = (uint32_t)(&tx_buf); NRF_RADIO->BASE0 = (CONF_ADDR_BASE | hdr->dst_addr); @@ -356,7 +356,7 @@ static int nrfmin_send(netdev_t *dev, const struct iovec *vector, unsigned count state = STATE_TX; NRF_RADIO->TASKS_TXEN = 1; - return (int)count; + return (int)pos; } static int nrfmin_recv(netdev_t *dev, void *buf, size_t len, void *info) diff --git a/cpu/nrf5x_common/radio/nrfmin/nrfmin_gnrc.c b/cpu/nrf5x_common/radio/nrfmin/nrfmin_gnrc.c index 7bbe1424c212d8b4331b216874dba801db79b16d..5002385802ff15b3456fd9f26e29fb907a43adc7 100644 --- a/cpu/nrf5x_common/radio/nrfmin/nrfmin_gnrc.c +++ b/cpu/nrf5x_common/radio/nrfmin/nrfmin_gnrc.c @@ -79,9 +79,6 @@ static int hdr_netif_to_nrfmin(nrfmin_hdr_t *nrfmin, gnrc_pktsnip_t *pkt) static int gnrc_nrfmin_send(gnrc_netif_t *dev, gnrc_pktsnip_t *pkt) { int res; - struct iovec *vec; - size_t vec_len; - gnrc_pktsnip_t *vec_snip; nrfmin_hdr_t nrfmin_hdr; assert(pkt); @@ -95,26 +92,21 @@ static int gnrc_nrfmin_send(gnrc_netif_t *dev, gnrc_pktsnip_t *pkt) res = hdr_netif_to_nrfmin(&nrfmin_hdr, pkt); if (res < 0) { DEBUG("[nrfmin_gnrc] send: failed to build nrfmin header\n"); - gnrc_pktbuf_release(pkt); - return res; + goto out; } - /* create iovec of data */ - vec_snip = gnrc_pktbuf_get_iovec(pkt, &vec_len); - if (vec_snip == NULL) { - DEBUG("[nrfmin_gnrc] send: failed to create IO vector\n"); - gnrc_pktbuf_release(pkt); - return -ENOBUFS; - } - - /* link first entry of the vector to the nrfmin header */ - vec = (struct iovec *)vec_snip->data; - vec[0].iov_base = &nrfmin_hdr; - vec[0].iov_len = NRFMIN_HDR_LEN; + /* link first entry after netif hdr of the pkt to the nrfmin header */ + iolist_t iolist = { + .iol_next = (iolist_t *)pkt->next, + .iol_base = &nrfmin_hdr, + .iol_len = NRFMIN_HDR_LEN + }; /* and finally send out the data and release the packet */ - res = dev->dev->driver->send(dev->dev, vec, vec_len); - gnrc_pktbuf_release(vec_snip); + res = dev->dev->driver->send(dev->dev, &iolist); + +out: + gnrc_pktbuf_release(pkt); return res; } diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 5392a1c03383784a84fdecef5a08e4a940c0bf35..de911d403b4a5e28b46aee9e605fd5fa2f4e4057 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -112,6 +112,7 @@ ifneq (,$(filter encx24j600,$(USEMODULE))) endif ifneq (,$(filter ethos,$(USEMODULE))) + USEMODULE += iolist USEMODULE += netdev_eth USEMODULE += random USEMODULE += tsrb @@ -306,6 +307,7 @@ endif ifneq (,$(filter sx127%,$(USEMODULE))) FEATURES_REQUIRED += periph_gpio FEATURES_REQUIRED += periph_spi + USEMODULE += iolist USEMODULE += xtimer USEMODULE += sx127x USEMODULE += netif diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 54fbd9d9bba2102317e0fdb26dca17c312e2edd3..dd697483dcc2372e2eb0eda2b9b19ca220ab70b3 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2015 Freie Universität Berlin + * Copyright (C) 2018 Kaspar Schleiser <kaspar@schleiser.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 @@ -17,6 +18,7 @@ * @author Hauke Petersen <hauke.petersen@fu-berlin.de> * @author Kévin Roussel <Kevin.Roussel@inria.fr> * @author Martine Lenders <mlenders@inf.fu-berlin.de> + * @author Kaspar Schleiser <kaspar@schleiser.de> * * @} */ @@ -25,6 +27,8 @@ #include <assert.h> #include <errno.h> +#include "iolist.h" + #include "net/eui64.h" #include "net/ieee802154.h" #include "net/netdev.h" @@ -40,7 +44,7 @@ #define _MAX_MHR_OVERHEAD (25) -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); +static int _send(netdev_t *netdev, const iolist_t *iolist); static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); static int _init(netdev_t *netdev); static void _isr(netdev_t *netdev); @@ -93,18 +97,17 @@ static int _init(netdev_t *netdev) return 0; } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { at86rf2xx_t *dev = (at86rf2xx_t *)netdev; - const struct iovec *ptr = vector; size_t len = 0; at86rf2xx_tx_prepare(dev); /* load packet data into FIFO */ - for (unsigned i = 0; i < count; ++i, ++ptr) { + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { /* current packet data + FCS too long */ - if ((len + ptr->iov_len + 2) > AT86RF2XX_MAX_PKT_LENGTH) { + if ((len + iol->iol_len + 2) > AT86RF2XX_MAX_PKT_LENGTH) { DEBUG("[at86rf2xx] error: packet too large (%u byte) to be send\n", (unsigned)len + 2); return -EOVERFLOW; @@ -112,7 +115,7 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) #ifdef MODULE_NETSTATS_L2 netdev->stats.tx_bytes += len; #endif - len = at86rf2xx_tx_load(dev, ptr->iov_base, ptr->iov_len, len); + len = at86rf2xx_tx_load(dev, iol->iol_base, iol->iol_len, len); } /* send data out directly if pre-loading id disabled */ diff --git a/drivers/cc110x/cc110x-netdev.c b/drivers/cc110x/cc110x-netdev.c index 016c2bfba84f6ed4743ceb5cb185fba5682f5d43..a1b42c59da4817305f70d2d08b3c40703bf3954b 100644 --- a/drivers/cc110x/cc110x-netdev.c +++ b/drivers/cc110x/cc110x-netdev.c @@ -37,14 +37,12 @@ #define ENABLE_DEBUG (0) #include "debug.h" -static int _send(netdev_t *dev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *dev, const iolist_t *iolist) { DEBUG("%s:%u\n", __func__, __LINE__); - (void)count; - - netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t*) dev; - cc110x_pkt_t *cc110x_pkt = vector[0].iov_base; + netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t *)dev; + cc110x_pkt_t *cc110x_pkt = iolist->iol_base; return cc110x_send(&netdev_cc110x->cc110x, cc110x_pkt); } diff --git a/drivers/cc110x/gnrc_cc110x/gnrc_cc110x.c b/drivers/cc110x/gnrc_cc110x/gnrc_cc110x.c index abbad5703a12bd14a71e081c0fd2a9bbfb40c7cb..83db2cef2cc51dac1f6c3ca27a45f25ab717c7ed 100644 --- a/drivers/cc110x/gnrc_cc110x/gnrc_cc110x.c +++ b/drivers/cc110x/gnrc_cc110x/gnrc_cc110x.c @@ -71,9 +71,10 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) cc110x_pkt.flags = 0; } - struct iovec vector; - vector.iov_base = (char*)&cc110x_pkt; - vector.iov_len = sizeof(cc110x_pkt_t); + iolist_t iolist = { + .iol_base = (char *)&cc110x_pkt, + .iol_len = sizeof(cc110x_pkt_t) + }; unsigned payload_len = 0; uint8_t *pos = cc110x_pkt.data; @@ -93,7 +94,7 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) payload = payload->next; } - /* pkt has been copied into iovec, we're done with it. */ + /* pkt has been copied into cc110x_pkt, we're done with it. */ gnrc_pktbuf_release(pkt); cc110x_pkt.length = (uint8_t) payload_len + CC110X_HEADER_LENGTH; @@ -104,7 +105,7 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) (unsigned)cc110x_pkt.address, (unsigned)cc110x_pkt.length); - return dev->driver->send(dev, &vector, 1); + return dev->driver->send(dev, &iolist); } static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) diff --git a/drivers/cc2420/cc2420.c b/drivers/cc2420/cc2420.c index eca7ef945e1ecc9e91fd15a4a697b1922e054d9b..a0b0600b53152835bd29fc4fa7543515b447ebe8 100644 --- a/drivers/cc2420/cc2420.c +++ b/drivers/cc2420/cc2420.c @@ -114,9 +114,9 @@ bool cc2420_cca(cc2420_t *dev) return gpio_read(dev->params.pin_cca); } -size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count) +size_t cc2420_send(cc2420_t *dev, const iolist_t *iolist) { - size_t n = cc2420_tx_prepare(dev, data, count); + size_t n = cc2420_tx_prepare(dev, iolist); if ((n > 0) && !(dev->options & CC2420_OPT_PRELOADING)) { cc2420_tx_exec(dev); @@ -125,7 +125,7 @@ size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count) return n; } -size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count) +size_t cc2420_tx_prepare(cc2420_t *dev, const iolist_t *iolist) { size_t pkt_len = 2; /* include the FCS (frame check sequence) */ @@ -134,8 +134,8 @@ size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count while (cc2420_get_state(dev) & NETOPT_STATE_TX) {} /* get and check the length of the packet */ - for (unsigned i = 0; i < count; i++) { - pkt_len += data[i].iov_len; + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + pkt_len += iol->iol_len; } if (pkt_len >= CC2420_PKT_MAXLEN) { DEBUG("cc2420: tx_prep: unable to send, pkt too large\n"); @@ -147,8 +147,8 @@ size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count /* push packet length to TX FIFO */ cc2420_fifo_write(dev, (uint8_t *)&pkt_len, 1); /* push packet to TX FIFO */ - for (unsigned i = 0; i < count; i++) { - cc2420_fifo_write(dev, (uint8_t *)data[i].iov_base, data[i].iov_len); + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + cc2420_fifo_write(dev, iol->iol_base, iol->iol_len); } DEBUG("cc2420: tx_prep: loaded %i byte into the TX FIFO\n", (int)pkt_len); diff --git a/drivers/cc2420/cc2420_netdev.c b/drivers/cc2420/cc2420_netdev.c index 5514e35c88bcd48a5539cb6e74fecb9c1fa25175..fe1f42ccd300662f1445111ae7a9d577c140d985 100644 --- a/drivers/cc2420/cc2420_netdev.c +++ b/drivers/cc2420/cc2420_netdev.c @@ -39,7 +39,7 @@ #include "debug.h" -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); +static int _send(netdev_t *netdev, const iolist_t *iolist); static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); static int _init(netdev_t *netdev); static void _isr(netdev_t *netdev); @@ -150,10 +150,10 @@ static void _isr(netdev_t *netdev) netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { cc2420_t *dev = (cc2420_t *)netdev; - return (int)cc2420_send(dev, vector, count); + return (int)cc2420_send(dev, iolist); } static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) diff --git a/drivers/enc28j60/enc28j60.c b/drivers/enc28j60/enc28j60.c index 2b9dd9312dd25f1fb542085d2d5131152d718327..2f55e699a0392b68a1cfac1491ab562511c98ba9 100644 --- a/drivers/enc28j60/enc28j60.c +++ b/drivers/enc28j60/enc28j60.c @@ -240,7 +240,7 @@ static void on_int(void *arg) netdev->event_callback(arg, NETDEV_EVENT_ISR); } -static int nd_send(netdev_t *netdev, const struct iovec *data, unsigned count) +static int nd_send(netdev_t *netdev, const iolist_t *iolist) { enc28j60_t *dev = (enc28j60_t *)netdev; uint8_t ctrl = 0; @@ -256,9 +256,9 @@ static int nd_send(netdev_t *netdev, const struct iovec *data, unsigned count) cmd_w_addr(dev, ADDR_WRITE_PTR, BUF_TX_START); /* write control byte and the actual data into the buffer */ cmd_wbm(dev, &ctrl, 1); - for (unsigned i = 0; i < count; i++) { - c += data[i].iov_len; - cmd_wbm(dev, (uint8_t *)data[i].iov_base, data[i].iov_len); + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + c += iol->iol_len; + cmd_wbm(dev, iol->iol_base, iol->iol_len); } /* set TX end pointer */ cmd_w_addr(dev, ADDR_TX_END, cmd_r_addr(dev, ADDR_WRITE_PTR) - 1); diff --git a/drivers/encx24j600/encx24j600.c b/drivers/encx24j600/encx24j600.c index 491fdcbdd0ba65f7b8bd540150fa74c0ad7703d3..47c5d3d32f41416eaee10451f297a20864f214fb 100644 --- a/drivers/encx24j600/encx24j600.c +++ b/drivers/encx24j600/encx24j600.c @@ -64,7 +64,7 @@ static inline int _packets_available(encx24j600_t *dev); static void _get_mac_addr(netdev_t *dev, uint8_t* buf); /* netdev interface */ -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); +static int _send(netdev_t *netdev, const iolist_t *iolist); static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); static int _init(netdev_t *dev); static void _isr(netdev_t *dev); @@ -291,7 +291,7 @@ static int _init(netdev_t *encdev) return 0; } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) { +static int _send(netdev_t *netdev, const iolist_t *iolist) { encx24j600_t * dev = (encx24j600_t *) netdev; lock(dev); @@ -301,9 +301,9 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) { /* copy packet to SRAM */ size_t len = 0; - for (unsigned i = 0; i < count; i++) { - sram_op(dev, ENC_WGPDATA, (i ? 0xFFFF : TX_BUFFER_START), vector[i].iov_base, vector[i].iov_len); - len += vector[i].iov_len; + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + sram_op(dev, ENC_WGPDATA, ((iol == iolist) ? TX_BUFFER_START : 0xFFFF), iol->iol_base, iol->iol_len); + len += iol->iol_len; } /* set start of TX packet and length */ diff --git a/drivers/ethos/ethos.c b/drivers/ethos/ethos.c index 1d7c816144b534ac5e0a7b0963e0618305a39a20..511eec2865b0efe497276f4e40a1d7fc0a71b453 100644 --- a/drivers/ethos/ethos.c +++ b/drivers/ethos/ethos.c @@ -189,12 +189,11 @@ static int _init(netdev_t *encdev) return 0; } -static size_t iovec_count_total(const struct iovec *vector, int count) +static size_t iolist_count_total(const iolist_t *iolist) { size_t result = 0; - while(count--) { - result += vector->iov_len; - vector++; + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + result += iol->iol_len; } return result; } @@ -256,13 +255,13 @@ void ethos_send_frame(ethos_t *dev, const uint8_t *data, size_t len, unsigned fr } } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { ethos_t * dev = (ethos_t *) netdev; (void)dev; /* count total packet length */ - size_t pktlen = iovec_count_total(vector, count); + size_t pktlen = iolist_count_total(iolist); /* lock line in order to prevent multiple writes */ mutex_lock(&dev->out_mutex); @@ -271,14 +270,13 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) uint8_t frame_delim = ETHOS_FRAME_DELIMITER; uart_write(dev->uart, &frame_delim, 1); - /* send iovec */ - while(count--) { - size_t n = vector->iov_len; - uint8_t *ptr = vector->iov_base; + /* send iolist */ + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + size_t n = iol->iol_len; + uint8_t *ptr = iol->iol_base; while(n--) { _write_escaped(dev->uart, *ptr++); } - vector++; } uart_write(dev->uart, &frame_delim, 1); diff --git a/drivers/include/cc2420.h b/drivers/include/cc2420.h index a2d6f77be447b320a7930a6db29f98b6b3e20f9f..b8d21767227006a896e0cd5341f41fa627739e0e 100644 --- a/drivers/include/cc2420.h +++ b/drivers/include/cc2420.h @@ -263,13 +263,12 @@ netopt_state_t cc2420_get_state(cc2420_t *dev); * @note This function ignores the PRELOADING option * * @param[in] dev device to use for sending - * @param[in] data data to send (must include IEEE802.15.4 header) - * @param[in] count length of @p data + * @param[in] iolist data to send (must include IEEE802.15.4 header) * * @return number of bytes that were actually send * @return 0 on error */ -size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count); +size_t cc2420_send(cc2420_t *dev, const iolist_t *iolist); /** * @brief Prepare for sending of data @@ -278,10 +277,9 @@ size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count); * data is possible after it was called. * * @param[in] dev device to prepare for sending - * @param[in] data data to prepare (must include IEEE802.15.4 header) - * @param[in] count length of @p data + * @param[in] iolist data to prepare (must include IEEE802.15.4 header) */ -size_t cc2420_tx_prepare(cc2420_t *dev, const struct iovec *data, unsigned count); +size_t cc2420_tx_prepare(cc2420_t *dev, const iolist_t *iolist); /** * @brief Trigger sending of data previously loaded into transmit buffer diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index 7df1c6b4ee4d7675f22ff29e1ae3e63164c3261b..9d12d232c1d7ea8fe9c00ff95bc122fb4fbd8789 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -195,8 +195,8 @@ extern "C" { #endif #include <stdint.h> -#include <sys/uio.h> +#include "iolist.h" #include "net/netopt.h" #ifdef MODULE_NETSTATS_L2 @@ -294,17 +294,14 @@ typedef struct netdev_driver { /** * @brief Send frame * - * @pre `(dev != NULL)` - * @pre `(count == 0) || (vector != NULL)` - * (`(count != 0) => (vector != NULL)`) + * @pre `(dev != NULL) && (iolist != NULL` * * @param[in] dev network device descriptor - * @param[in] vector io vector array to send - * @param[in] count nr of entries in vector + * @param[in] iolist io vector list to send * * @return number of bytes sent, or `< 0` on error */ - int (*send)(netdev_t *dev, const struct iovec *vector, unsigned count); + int (*send)(netdev_t *dev, const iolist_t *iolist); /** * @brief Get a received frame diff --git a/drivers/kw2xrf/kw2xrf_netdev.c b/drivers/kw2xrf/kw2xrf_netdev.c index 4d8a0dd3bec3f7caf4527be8dbd9504ee0f8db6e..e22ab31fdbcc6b5492175f59f04402a890b65d0b 100644 --- a/drivers/kw2xrf/kw2xrf_netdev.c +++ b/drivers/kw2xrf/kw2xrf_netdev.c @@ -138,10 +138,9 @@ static void kw2xrf_wait_idle(kw2xrf_t *dev) } } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { kw2xrf_t *dev = (kw2xrf_t *)netdev; - const struct iovec *ptr = vector; uint8_t *pkt_buf = &(dev->buf[1]); size_t len = 0; @@ -149,14 +148,14 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) kw2xrf_wait_idle(dev); /* load packet data into buffer */ - for (unsigned i = 0; i < count; i++, ptr++) { + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { /* current packet data + FCS too long */ - if ((len + ptr->iov_len + IEEE802154_FCS_LEN) > KW2XRF_MAX_PKT_LENGTH) { + if ((len + iol->iol_len + IEEE802154_FCS_LEN) > KW2XRF_MAX_PKT_LENGTH) { LOG_ERROR("[kw2xrf] packet too large (%u byte) to be send\n", (unsigned)len + IEEE802154_FCS_LEN); return -EOVERFLOW; } - len = kw2xrf_tx_load(pkt_buf, ptr->iov_base, ptr->iov_len, len); + len = kw2xrf_tx_load(pkt_buf, iol->iol_base, iol->iol_len, len); } kw2xrf_set_sequence(dev, XCVSEQ_IDLE); diff --git a/drivers/mrf24j40/mrf24j40_netdev.c b/drivers/mrf24j40/mrf24j40_netdev.c index 02598c1b4965dd2b4f4179495e7bbe69ffec500f..10f534689b771cf128a4e8ac4be617b47efc0294 100644 --- a/drivers/mrf24j40/mrf24j40_netdev.c +++ b/drivers/mrf24j40/mrf24j40_netdev.c @@ -39,22 +39,6 @@ #define _MAX_MHR_OVERHEAD (25) -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); -static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); -static int _init(netdev_t *netdev); -static void _isr(netdev_t *netdev); -static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len); -static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len); - -const netdev_driver_t mrf24j40_driver = { - .send = _send, - .recv = _recv, - .init = _init, - .isr = _isr, - .get = _get, - .set = _set, -}; - static void _irq_handler(void *arg) { netdev_t *dev = (netdev_t *) arg; @@ -83,18 +67,17 @@ static int _init(netdev_t *netdev) return 0; } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { mrf24j40_t *dev = (mrf24j40_t *)netdev; - const struct iovec *ptr = vector; size_t len = 0; mrf24j40_tx_prepare(dev); /* load packet data into FIFO */ - for (unsigned i = 0; i < count; i++, ptr++) { + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { /* current packet data + FCS too long */ - if ((len + ptr->iov_len + 2) > IEEE802154_FRAME_LEN_MAX) { + if ((len + iol->iol_len + 2) > IEEE802154_FRAME_LEN_MAX) { DEBUG("[mrf24j40] error: packet too large (%u byte) to be send\n", (unsigned)len + 2); return -EOVERFLOW; @@ -103,11 +86,12 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) #ifdef MODULE_NETSTATS_L2 netdev->stats.tx_bytes += len; #endif - len = mrf24j40_tx_load(dev, ptr->iov_base, ptr->iov_len, len); - if (i == 0) { + len = mrf24j40_tx_load(dev, iol->iol_base, iol->iol_len, len); + /* only on first iteration: */ + if (iol == iolist) { dev->header_len = len; /* Grab the FCF bits from the frame header */ - dev->fcf_low = *(uint8_t*)(ptr->iov_base); + dev->fcf_low = *(uint8_t*)(iol->iol_base); } } @@ -581,3 +565,12 @@ static void _isr(netdev_t *netdev) } DEBUG("[mrf24j40] END IRQ\n"); } + +const netdev_driver_t mrf24j40_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; diff --git a/drivers/slipdev/slipdev.c b/drivers/slipdev/slipdev.c index 073ab4019e9a14180154207af545e07fec4a8d30..9d0a15ac3e0c86a36e332d9ea96c91f3ff424dd6 100644 --- a/drivers/slipdev/slipdev.c +++ b/drivers/slipdev/slipdev.c @@ -27,31 +27,6 @@ #define SLIP_END_ESC (0xdcU) #define SLIP_ESC_ESC (0xddU) -static int _send(netdev_t *dev, const struct iovec *vector, unsigned count); -static int _recv(netdev_t *dev, void *buf, size_t len, void *info); -static int _init(netdev_t *dev); -static void _isr(netdev_t *dev); -static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len); -static int _set(netdev_t *dev, netopt_t opt, const void *value, - size_t value_len); - -static const netdev_driver_t slip_driver = { - .send = _send, - .recv = _recv, - .init = _init, - .isr = _isr, - .get = _get, - .set = _set, -}; - -void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params) -{ - /* set device descriptor fields */ - memcpy(&dev->config, params, sizeof(dev->config)); - dev->inesc = 0U; - dev->netdev.driver = &slip_driver; -} - static void _slip_rx_cb(void *arg, uint8_t byte) { slipdev_t *dev = arg; @@ -84,16 +59,16 @@ static inline void _write_byte(slipdev_t *dev, uint8_t byte) uart_write(dev->config.uart, &byte, 1); } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { slipdev_t *dev = (slipdev_t *)netdev; int bytes = 0; - DEBUG("slipdev: sending vector of length %u\n", count); - for (unsigned i = 0; i < count; i++) { - uint8_t *data = vector[i].iov_base; + DEBUG("slipdev: sending iolist\n"); + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + uint8_t *data = iol->iol_base; - for (unsigned j = 0; j < vector[i].iov_len; j++, data++) { + for (unsigned j = 0; j < iol->iol_len; j++, data++) { switch(*data) { case SLIP_END: /* escaping END byte*/ @@ -223,4 +198,21 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value, return -ENOTSUP; } +static const netdev_driver_t slip_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; + +void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params) +{ + /* set device descriptor fields */ + memcpy(&dev->config, params, sizeof(dev->config)); + dev->inesc = 0U; + dev->netdev.driver = &slip_driver; +} + /** @} */ diff --git a/drivers/sx127x/sx127x_netdev.c b/drivers/sx127x/sx127x_netdev.c index 30c6e7ef7313c3e8ada45d9196210ad9eda74310..60723573113d7d0adc4db36df0a694b85d193a11 100644 --- a/drivers/sx127x/sx127x_netdev.c +++ b/drivers/sx127x/sx127x_netdev.c @@ -34,7 +34,6 @@ #include "debug.h" /* Internal helper functions */ -static uint8_t _get_tx_len(const struct iovec *vector, unsigned count); static int _set_state(sx127x_t *dev, netopt_state_t state); static int _get_state(sx127x_t *dev, void *val); void _on_dio0_irq(void *arg); @@ -42,24 +41,7 @@ void _on_dio1_irq(void *arg); void _on_dio2_irq(void *arg); void _on_dio3_irq(void *arg); -/* Netdev driver api functions */ -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); -static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); -static int _init(netdev_t *netdev); -static void _isr(netdev_t *netdev); -static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len); -static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len); - -const netdev_driver_t sx127x_driver = { - .send = _send, - .recv = _recv, - .init = _init, - .isr = _isr, - .get = _get, - .set = _set, -}; - -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { sx127x_t *dev = (sx127x_t*) netdev; @@ -69,8 +51,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) return -ENOTSUP; } - uint8_t size; - size = _get_tx_len(vector, count); + uint8_t size = iolist_size(iolist); + switch (dev->settings.modem) { case SX127X_MODEM_FSK: /* todo */ @@ -91,8 +73,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) } /* Write payload buffer */ - for (size_t i = 0; i < count; i++) { - sx127x_write_fifo(dev, vector[i].iov_base, vector[i].iov_len); + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + sx127x_write_fifo(dev, iol->iol_base, iol->iol_len); } break; default: @@ -489,17 +471,6 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) return res; } -static uint8_t _get_tx_len(const struct iovec *vector, unsigned count) -{ - uint8_t len = 0; - - for (unsigned i = 0 ; i < count ; i++) { - len += vector[i].iov_len; - } - - return len; -} - static int _set_state(sx127x_t *dev, netopt_state_t state) { switch (state) { @@ -717,3 +688,12 @@ void _on_dio3_irq(void *arg) break; } } + +const netdev_driver_t sx127x_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; diff --git a/drivers/w5100/w5100.c b/drivers/w5100/w5100.c index 8cc6e92b7b6e0c4fc49299335a978c659e61d194..e391752fa99692aa94b6fcb9ba56e8dfdfe5088a 100644 --- a/drivers/w5100/w5100.c +++ b/drivers/w5100/w5100.c @@ -194,7 +194,7 @@ static uint16_t tx_upload(w5100_t *dev, uint16_t start, void *data, size_t len) } } -static int send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int send(netdev_t *netdev, const iolist_t *iolist) { w5100_t *dev = (w5100_t *)netdev; int sum = 0; @@ -210,9 +210,10 @@ static int send(netdev_t *netdev, const struct iovec *vector, unsigned count) pos = S0_TX_BASE; } - for (unsigned i = 0; i < count; i++) { - pos = tx_upload(dev, pos, vector[i].iov_base, vector[i].iov_len); - sum += vector[i].iov_len; + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + size_t len = iol->iol_len; + pos = tx_upload(dev, pos, iol->iol_base, len); + sum += len; } waddr(dev, S0_TX_WR0, S0_TX_WR1, pos); diff --git a/drivers/xbee/gnrc_xbee.c b/drivers/xbee/gnrc_xbee.c index be78de2aee81acf9abf4847cc0d91c74fd356e3b..8d66233c64d6551f45d648eb70a0e6f730cececa 100644 --- a/drivers/xbee/gnrc_xbee.c +++ b/drivers/xbee/gnrc_xbee.c @@ -104,8 +104,6 @@ static int xbee_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) { int res; size_t size; - size_t count; - gnrc_pktsnip_t *vec; gnrc_netif_hdr_t *hdr; uint8_t xhdr[XBEE_MAX_TXHDR_LENGTH]; @@ -146,27 +144,23 @@ static int xbee_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) } } - /* now let's extract the iovector and send out the stuff */ - vec = gnrc_pktbuf_get_iovec(pkt, &count); - if (vec != NULL) { - pkt = vec; - struct iovec *vector = (struct iovec *)pkt->data; - vector[0].iov_base = xhdr; - vector[0].iov_len = res; + /* now let's send out the stuff */ + iolist_t iolist = { + .iol_next = (iolist_t *)pkt->next, + .iol_base = xhdr, + .iol_len = res + }; + #ifdef MODULE_NETSTATS_L2 - if (hdr->flags & BCAST) { - netif->dev->stats.tx_mcast_count++; - } - else { - netif->dev->stats.tx_unicast_count++; - } -#endif - DEBUG("[xbee-gnrc] send: triggering the drivers send function\n"); - res = netif->dev->driver->send(netif->dev, vector, count); + if (hdr->flags & BCAST) { + netif->dev->stats.tx_mcast_count++; } else { - DEBUG("[xbee-gnrc] send: unable to create iovec\n"); + netif->dev->stats.tx_unicast_count++; } +#endif + DEBUG("[xbee-gnrc] send: triggering the drivers send function\n"); + res = netif->dev->driver->send(netif->dev, &iolist); gnrc_pktbuf_release(pkt); diff --git a/drivers/xbee/xbee.c b/drivers/xbee/xbee.c index 93df3ab782a459070d8e296b2e5c8000fc4c542a..fb9985896d0739c1e177a9922a2612f7b9c80291 100644 --- a/drivers/xbee/xbee.c +++ b/drivers/xbee/xbee.c @@ -634,21 +634,23 @@ int xbee_init(netdev_t *dev) return 0; } -static int xbee_send(netdev_t *dev, const struct iovec *vector, unsigned count) +static int xbee_send(netdev_t *dev, const iolist_t *iolist) { xbee_t *xbee = (xbee_t *)dev; size_t size; uint8_t csum; - assert(xbee && vector && (count > 0)); + assert(xbee && iolist); /* calculate the checksum and the packet size */ - size = vector[0].iov_len; - csum = _cksum(3, (uint8_t *)vector[0].iov_base, size); - for (unsigned i = 1; i < count; i++) { - size += vector[i].iov_len; - for (size_t p = 0; p < vector[i].iov_len; p++) { - csum -= ((uint8_t *)vector[i].iov_base)[p]; + size = iolist->iol_len; + csum = _cksum(3, (uint8_t *)iolist->iol_base, size); + for (const iolist_t *iol = iolist->iol_next; iol; iol = iol->iol_next) { + size_t len = iol->iol_len; + + size += len; + for (size_t p = 0; p < len; p++) { + csum -= ((uint8_t *)iol->iol_base)[p]; } } @@ -661,13 +663,13 @@ static int xbee_send(netdev_t *dev, const struct iovec *vector, unsigned count) /* send the actual data packet */ DEBUG("[xbee] send: now sending out %i byte\n", (int)size); mutex_lock(&(xbee->tx_lock)); - for (unsigned i = 0; i < count; i++) { - uart_write(xbee->p.uart, vector[i].iov_base, vector[i].iov_len); + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + uart_write(xbee->p.uart, iol->iol_base, iol->iol_len); } uart_write(xbee->p.uart, &csum, 1); mutex_unlock(&(xbee->tx_lock)); - /* return number of payload byte */ + /* return number of payload bytes */ return (int)size; } diff --git a/pkg/emb6/contrib/netdev/emb6_netdev.c b/pkg/emb6/contrib/netdev/emb6_netdev.c index 217a2b620376b4847791d601c5dd865a270f7e56..67143c33a351b588cea8d82388ad8fb6a7539636 100644 --- a/pkg/emb6/contrib/netdev/emb6_netdev.c +++ b/pkg/emb6/contrib/netdev/emb6_netdev.c @@ -138,11 +138,11 @@ static int8_t _netdev_init(s_ns_t *p_ns) static int8_t _netdev_send(const void *pr_payload, uint8_t c_len) { if (_dev != NULL) { - const struct iovec vector = { - .iov_base = (void *)pr_payload, - .iov_len = c_len + iolist_t iolist = { + .iol_base = (void *)pr_payload, + .iol_len = c_len, }; - if (_dev->driver->send(_dev, &vector, 1) < 0) { + if (_dev->driver->send(_dev, &iolist) < 0) { DEBUG("Error on send\n"); return RADIO_TX_ERR; } diff --git a/pkg/lwip/contrib/netdev/lwip_netdev.c b/pkg/lwip/contrib/netdev/lwip_netdev.c index ffc86384419623d8814968e2fbddf66ec375aec1..cb9246aa8aa13a1558ecdda65a5fdf3a87fa0f55 100644 --- a/pkg/lwip/contrib/netdev/lwip_netdev.c +++ b/pkg/lwip/contrib/netdev/lwip_netdev.c @@ -185,15 +185,24 @@ static err_t _eth_link_output(struct netif *netif, struct pbuf *p) pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif LL_COUNT(p, q, count); - struct iovec pkt[count]; + iolist_t iolist[count]; + + /* make last point to the last entry of iolist[] */ + iolist_t *last = &iolist[count]; + last--; + for (q = p, count = 0; q != NULL; q = q->next, count++) { - pkt[count].iov_base = q->payload; - pkt[count].iov_len = (size_t)q->len; + iolist_t *iol = &iolist[count]; + + iol->iol_next = (iol == last) ? NULL : &iolist[count + 1]; + + iol->iol_base = q->payload; + iol->iol_len = (size_t)q->len; } #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif - return (netdev->driver->send(netdev, pkt, count) > 0) ? ERR_OK : ERR_BUF; + return (netdev->driver->send(netdev, iolist) > 0) ? ERR_OK : ERR_BUF; } #endif @@ -202,12 +211,12 @@ static err_t _ieee802154_link_output(struct netif *netif, struct pbuf *p) { LWIP_ASSERT("p->next == NULL", p->next == NULL); netdev_t *netdev = (netdev_t *)netif->state; - struct iovec pkt = { - .iov_base = p->payload, - .iov_len = (p->len - IEEE802154_FCS_LEN), /* FCS is written by driver */ + iolist_t pkt = { + .iol_base = p->payload, + .iol_len = (p->len - IEEE802154_FCS_LEN), /* FCS is written by driver */ }; - return (netdev->driver->send(netdev, &pkt, 1) > 0) ? ERR_OK : ERR_BUF; + return (netdev->driver->send(netdev, &pkt) > 0) ? ERR_OK : ERR_BUF; } #endif diff --git a/pkg/openthread/contrib/platform_radio.c b/pkg/openthread/contrib/platform_radio.c index 27487e36708b8516eea93aafa6b058799975d41a..8095bb658089dabfe1375442dc4d023ad8c0a6f2 100644 --- a/pkg/openthread/contrib/platform_radio.c +++ b/pkg/openthread/contrib/platform_radio.c @@ -297,14 +297,15 @@ void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower) ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket) { (void) aInstance; - struct iovec pkt; - /* Populate iovec with transmit data + /* Populate iolist with transmit data * Unlike RIOT, OpenThread includes two bytes FCS (0x00 0x00) so * these bytes are removed */ - pkt.iov_base = aPacket->mPsdu; - pkt.iov_len = aPacket->mLength - RADIO_IEEE802154_FCS_LEN; + iolist_t iolist = { + .iol_base = aPacket->mPsdu, + .iol_len = (aPacket->mLength - RADIO_IEEE802154_FCS_LEN) + }; /*Set channel and power based on transmit frame */ DEBUG("otPlatRadioTransmit->channel: %i, length %d\n", (int) aPacket->mChannel, (int)aPacket->mLength); @@ -316,7 +317,7 @@ ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket) _set_power(aPacket->mPower); /* send packet though netdev */ - _dev->driver->send(_dev, &pkt, 1); + _dev->driver->send(_dev, &iolist); return kThreadError_None; } diff --git a/pkg/semtech-loramac/contrib/semtech_loramac_radio.c b/pkg/semtech-loramac/contrib/semtech_loramac_radio.c index 84072a5658e0adc36443d52798869a96a0b4df57..8d2d8cb8e0481b8bb8fb12f829537e99309d8779 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac_radio.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac_radio.c @@ -136,10 +136,11 @@ uint32_t SX127XGetTimeOnAir(RadioModems_t modem, uint8_t pktLen) void SX127XSend(uint8_t *buffer, uint8_t size) { netdev_t *dev = (netdev_t *)&sx127x; - struct iovec vec[1]; - vec[0].iov_base = buffer; - vec[0].iov_len = size; - dev->driver->send(dev, vec, 1); + iolist_t iol = { + .iol_base = buffer, + .iol_len = size + }; + dev->driver->send(dev, &iol); } void SX127XSetSleep(void) diff --git a/sys/include/iolist.h b/sys/include/iolist.h new file mode 100644 index 0000000000000000000000000000000000000000..e5d8d753e75cc62b3cf1203f76d12a56362874c2 --- /dev/null +++ b/sys/include/iolist.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 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. + */ + +/** + * @defgroup sys_util_iolist iolist scatter / gather IO + * @ingroup sys_util + * @brief Provides linked-list scatter / gather IO + * + * @{ + * + * @file + * @brief iolist scatter / gather IO + * + * @author Kaspar Schleiser <kaspar@schleiser.de> + */ + +#ifndef IOLIST_H +#define IOLIST_H + +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief iolist forward declaration */ +typedef struct iolist iolist_t; + +/** + * @brief iolist structure definition + */ +struct iolist { + iolist_t *iol_next; /**< ptr to next list entry */ + void *iol_base; /**< ptr to this list entries data */ + size_t iol_len; /**< size of data pointet to by ptr */ +}; + +/** + * @brief Count number of entries in an iolist_t + * + * @param[in] iolist iolist to count + * + * @returns number of entries (zero for NULL parameter) + */ +unsigned iolist_count(const iolist_t *iolist); + +/** + * @brief Sum up number of bytes in iolist + * + * This function returns the summed ip lenght values of all entries in @p + * iolist. + * + * @param[in] iolist iolist to sum up + * + * @returns summed up number of bytes or zero if @p iolist == NULL + */ +size_t iolist_size(const iolist_t *iolist); + +/** @brief struct iovec anonymous declaration */ +struct iovec; + +/** + * @brief Create struct iovec from iolist + * + * This function fills an array of struct iovecs with the contents of @p + * iolist. It will write the number of used array entries into @p count. + * + * The caller *must* ensure that @p iov p points to an array of size >= count! + * + * @param[in] iolist iolist to read from + * @param[out] iov ptr to array of struct iovec that will be filled + * @param[out] count number of elements in @p iolist + * + * @returns iolist_size(iolist) + */ +size_t iolist_to_iovec(const iolist_t *iolist, struct iovec *iov, unsigned *count); + +#ifdef __cplusplus +} +#endif +#endif /* IOLIST_H */ +/** @} */ diff --git a/sys/include/net/csma_sender.h b/sys/include/net/csma_sender.h index 0928215f780f860368ffec79a80693a2b4402546..b7183c0325890c494b684b54bb1fc74999d87e32 100644 --- a/sys/include/net/csma_sender.h +++ b/sys/include/net/csma_sender.h @@ -87,8 +87,7 @@ extern const csma_sender_conf_t CSMA_SENDER_CONF_DEFAULT; * CSMA/CA, this feature is used. Otherwise, a software procedure is used. * * @param[in] dev netdev device, needs to be already initialized - * @param[in] vector pointer to the data - * @param[in] count number of elements in @p vector + * @param[in] iolist pointer to the data * @param[in] conf configuration for the backoff; * will be set to @ref CSMA_SENDER_CONF_DEFAULT if NULL. * @@ -101,8 +100,8 @@ extern const csma_sender_conf_t CSMA_SENDER_CONF_DEFAULT; * @return -EBUSY if radio medium never was available * to send the given data */ -int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, - unsigned count, const csma_sender_conf_t *conf); +int csma_sender_csma_ca_send(netdev_t *dev, iolist_t *iolist, + const csma_sender_conf_t *conf); /** * @brief Sends a 802.15.4 frame when medium is avaiable. @@ -121,8 +120,7 @@ int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, * @ref csma_sender_csma_ca_send(). * * @param[in] dev netdev device, needs to be already initialized - * @param[in] vector pointer to the data - * @param[in] count number of elements in @p vector + * @param[in] iolist pointer to the data * * @return number of bytes that were actually send out * @return -ENODEV if @p dev is invalid @@ -133,7 +131,7 @@ int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, * @return -EBUSY if radio medium was not available * to send the given data */ -int csma_sender_cca_send(netdev_t *dev, struct iovec *vector, unsigned count); +int csma_sender_cca_send(netdev_t *dev, iolist_t *iolist); #ifdef __cplusplus 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/sys/include/net/netdev_test.h b/sys/include/net/netdev_test.h index 016db2d55bb107a2b2b494e59b56d383f54f7c19..6260b610eeb752096e3acb68a9ab5b60f27783df 100644 --- a/sys/include/net/netdev_test.h +++ b/sys/include/net/netdev_test.h @@ -33,11 +33,10 @@ * static uint32_t sum = 0; * static mutex_t wait = MUTEX_INIT; * - * int _send_timer(netdev_t *dev, const struct iovec *vector, int count) + * int _send_timer(netdev_t *dev, const iolist_t *iolist) * { * (void)dev; - * (void)vector; - * (void)count; + * (void)iolist; * * sum += (xtimer_now_usec() - last_start); * mutex_unlock(&wait); @@ -95,15 +94,12 @@ extern "C" { * @brief Callback type to handle send command * * @param[in] dev network device descriptor - * @param[in] vector io vector array to send - * @param[in] count number of entries in vector + * @param[in] iolist io vector list to send * * @return number of bytes sent * @return <= 0 on error */ -typedef int (*netdev_test_send_cb_t)(netdev_t *dev, - const struct iovec *vector, - int count); +typedef int (*netdev_test_send_cb_t)(netdev_t *dev, const iolist_t *iolist); /** * @brief Callback type to handle receive command diff --git a/sys/iolist/Makefile b/sys/iolist/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2 --- /dev/null +++ b/sys/iolist/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/iolist/iolist.c b/sys/iolist/iolist.c new file mode 100644 index 0000000000000000000000000000000000000000..b64f0139e251d7fbc72fcb1cbd7c0127f28e8b9b --- /dev/null +++ b/sys/iolist/iolist.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2018 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. + */ + +/** + * @ingroup sys_util + * @{ + * + * @file + * @brief iolist scatter / gather IO + * + * @author Kaspar Schleiser <kaspar@schleiser.de> + * @} + */ + +#include <sys/uio.h> + +#include "iolist.h" + +unsigned iolist_count(const iolist_t *iolist) +{ + unsigned count = 0; + while (iolist) { + count++; + iolist = iolist->iol_next; + } + return count; +} + +size_t iolist_size(const iolist_t *iolist) +{ + size_t result = 0; + while (iolist) { + result += iolist->iol_len; + iolist = iolist->iol_next; + } + return result; +} + +size_t iolist_to_iovec(const iolist_t *iolist, struct iovec *iov, unsigned *count) +{ + size_t bytes = 0; + unsigned _count = 0; + + while (iolist) { + iov->iov_base = iolist->iol_base; + iov->iov_len = iolist->iol_len; + bytes += iov->iov_len; + _count++; + iolist = iolist->iol_next; + iov++; + } + + *count = _count; + + return bytes; +} diff --git a/sys/net/gnrc/link_layer/gomach/gomach_internal.c b/sys/net/gnrc/link_layer/gomach/gomach_internal.c index 3b30d4fb67292ef3e03fe2c82c516047485c9143..3b6618324509a85ea2f1338a81a8744494fce8bb 100644 --- a/sys/net/gnrc/link_layer/gomach/gomach_internal.c +++ b/sys/net/gnrc/link_layer/gomach/gomach_internal.c @@ -50,10 +50,9 @@ int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) netdev_t *dev = netif->dev; netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; gnrc_netif_hdr_t *netif_hdr; - gnrc_pktsnip_t *vec_snip; const uint8_t *src, *dst = NULL; int res = 0; - size_t n, src_len, dst_len; + size_t src_len, dst_len; uint8_t mhr[IEEE802154_MAX_HDR_LEN]; uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); @@ -93,38 +92,34 @@ int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) DEBUG("_send_ieee802154: Error preperaring frame\n"); return -EINVAL; } + /* prepare packet for sending */ - vec_snip = gnrc_pktbuf_get_iovec(pkt, &n); - if (vec_snip != NULL) { - struct iovec *vector; - - pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */ - vector = (struct iovec *)pkt->data; - vector[0].iov_base = mhr; - vector[0].iov_len = (size_t)res; + iolist_t iolist = { + .iol_next = (iolist_t *)pkt->next, + .iol_base = mhr, + .iol_len = (size_t)res + }; + #ifdef MODULE_NETSTATS_L2 - if (netif_hdr->flags & + if (netif_hdr->flags & (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { - netif->dev->stats.tx_mcast_count++; - } - else { - netif->dev->stats.tx_unicast_count++; - } + netif->dev->stats.tx_mcast_count++; + } + else { + netif->dev->stats.tx_unicast_count++; + } #endif #ifdef MODULE_GNRC_MAC - if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { - res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf); - } - else { - res = dev->driver->send(dev, vector, n); - } -#else - res = dev->driver->send(dev, vector, n); -#endif + if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { + res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf); } else { - return -ENOBUFS; + res = dev->driver->send(dev, &iolist); } +#else + res = dev->driver->send(dev, &iolist); +#endif + /* release old data */ gnrc_pktbuf_release(pkt); return res; diff --git a/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c b/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c index a4668e746ca136d292eaac339b69c139ced8a9d1..181b1c029719b94028a79acf7d60a5eb8768f716 100644 --- a/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c +++ b/sys/net/gnrc/link_layer/lwmac/lwmac_internal.c @@ -37,10 +37,9 @@ int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) netdev_t *dev = netif->dev; netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; gnrc_netif_hdr_t *netif_hdr; - gnrc_pktsnip_t *vec_snip; const uint8_t *src, *dst = NULL; int res = 0; - size_t n, src_len, dst_len; + size_t src_len, dst_len; uint8_t mhr[IEEE802154_MAX_HDR_LEN]; uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); @@ -80,38 +79,34 @@ int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) DEBUG("_send_ieee802154: Error preperaring frame\n"); return -EINVAL; } + /* prepare packet for sending */ - vec_snip = gnrc_pktbuf_get_iovec(pkt, &n); - if (vec_snip != NULL) { - struct iovec *vector; + iolist_t iolist = { + .iol_next = (iolist_t *)pkt->next, + .iol_base = mhr, + .iol_len = (size_t)res + }; - pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */ - vector = (struct iovec *)pkt->data; - vector[0].iov_base = mhr; - vector[0].iov_len = (size_t)res; #ifdef MODULE_NETSTATS_L2 - if (netif_hdr->flags & + if (netif_hdr->flags & (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { - netif->dev->stats.tx_mcast_count++; - } - else { - netif->dev->stats.tx_unicast_count++; - } + netif->dev->stats.tx_mcast_count++; + } + else { + netif->dev->stats.tx_unicast_count++; + } #endif #ifdef MODULE_GNRC_MAC - if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { - res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf); - } - else { - res = dev->driver->send(dev, vector, n); - } -#else - res = dev->driver->send(dev, vector, n); -#endif + if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { + res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf); } else { - return -ENOBUFS; + res = dev->driver->send(dev, &iolist); } +#else + res = dev->driver->send(dev, &iolist); +#endif + /* release old data */ gnrc_pktbuf_release(pkt); return res; diff --git a/sys/net/gnrc/netif/gnrc_netif_ethernet.c b/sys/net/gnrc/netif/gnrc_netif_ethernet.c index a5b0be4038c4b4b67f4e8f7a1d3d8a580c9aac8a..7aafc78808346bd52b92159b1981791e58e37caf 100644 --- a/sys/net/gnrc/netif/gnrc_netif_ethernet.c +++ b/sys/net/gnrc/netif/gnrc_netif_ethernet.c @@ -135,26 +135,22 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) hdr.dst[0], hdr.dst[1], hdr.dst[2], hdr.dst[3], hdr.dst[4], hdr.dst[5]); - size_t n; - payload = gnrc_pktbuf_get_iovec(pkt, &n); /* use payload as temporary - * variable */ - res = -ENOBUFS; - if (payload != NULL) { - pkt = payload; /* reassign for later release; vec_snip is prepended to pkt */ - struct iovec *vector = (struct iovec *)pkt->data; - vector[0].iov_base = (char *)&hdr; - vector[0].iov_len = sizeof(ethernet_hdr_t); + iolist_t iolist = { + .iol_next = (iolist_t *)payload, + .iol_base = &hdr, + .iol_len = sizeof(ethernet_hdr_t) + }; + #ifdef MODULE_NETSTATS_L2 - if ((netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) || - (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST)) { - dev->stats.tx_mcast_count++; - } - else { - dev->stats.tx_unicast_count++; - } -#endif - res = dev->driver->send(dev, vector, n); + if ((netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) || + (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST)) { + dev->stats.tx_mcast_count++; } + else { + dev->stats.tx_unicast_count++; + } +#endif + res = dev->driver->send(dev, &iolist); gnrc_pktbuf_release(pkt); diff --git a/sys/net/gnrc/netif/gnrc_netif_ieee802154.c b/sys/net/gnrc/netif/gnrc_netif_ieee802154.c index a482c64c1154708c10f38e6d318b49194fd9de27..f72f6ff1d4849c40288aa27c467a6c9ec652bf10 100644 --- a/sys/net/gnrc/netif/gnrc_netif_ieee802154.c +++ b/sys/net/gnrc/netif/gnrc_netif_ieee802154.c @@ -168,10 +168,9 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) netdev_t *dev = netif->dev; netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; gnrc_netif_hdr_t *netif_hdr; - gnrc_pktsnip_t *vec_snip; const uint8_t *src, *dst = NULL; int res = 0; - size_t n, src_len, dst_len; + size_t src_len, dst_len; uint8_t mhr[IEEE802154_MAX_HDR_LEN]; uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); @@ -211,38 +210,34 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) DEBUG("_send_ieee802154: Error preperaring frame\n"); return -EINVAL; } - /* prepare packet for sending */ - vec_snip = gnrc_pktbuf_get_iovec(pkt, &n); - if (vec_snip != NULL) { - struct iovec *vector; - - pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */ - vector = (struct iovec *)pkt->data; - vector[0].iov_base = mhr; - vector[0].iov_len = (size_t)res; + + /* prepare iolist for netdev / mac layer */ + iolist_t iolist = { + .iol_next = (iolist_t *)pkt->next, + .iol_base = mhr, + .iol_len = (size_t)res + }; + #ifdef MODULE_NETSTATS_L2 if (netif_hdr->flags & - (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { - netif->dev->stats.tx_mcast_count++; - } - else { - netif->dev->stats.tx_unicast_count++; - } + (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { + netif->dev->stats.tx_mcast_count++; + } + else { + netif->dev->stats.tx_unicast_count++; + } #endif #ifdef MODULE_GNRC_MAC - if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { - res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf); - } - else { - res = dev->driver->send(dev, vector, n); - } -#else - res = dev->driver->send(dev, vector, n); -#endif + if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { + res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf); } else { - return -ENOBUFS; + res = dev->driver->send(dev, &iolist); } +#else + res = dev->driver->send(dev, &iolist); +#endif + /* release old data */ gnrc_pktbuf_release(pkt); return res; diff --git a/sys/net/gnrc/netif/gnrc_netif_raw.c b/sys/net/gnrc/netif/gnrc_netif_raw.c index 53be2147cf1d19de00d90b98cf62e6b24ad61ab7..cc8760b4ce7cef2c5cdb23af59b03526c0f3ac30 100644 --- a/sys/net/gnrc/netif/gnrc_netif_raw.c +++ b/sys/net/gnrc/netif/gnrc_netif_raw.c @@ -92,27 +92,20 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) { - gnrc_pktsnip_t *vector; int res = -ENOBUFS; - size_t n; if (pkt->type == GNRC_NETTYPE_NETIF) { /* we don't need the netif snip: remove it */ pkt = gnrc_pktbuf_remove_snip(pkt, pkt); } - /* prepare packet for sending */ - vector = gnrc_pktbuf_get_iovec(pkt, &n); - if (vector != NULL) { - /* reassign for later release; vector is prepended to pkt */ - pkt = vector; - struct iovec *v = (struct iovec *)vector->data; - netdev_t *dev = netif->dev; + + netdev_t *dev = netif->dev; #ifdef MODULE_NETSTATS_L2 - dev->stats.tx_unicast_count++; + dev->stats.tx_unicast_count++; #endif - res = dev->driver->send(dev, v, n); - } + + res = dev->driver->send(dev, (iolist_t *)pkt); /* release old data */ gnrc_pktbuf_release(pkt); return res; diff --git a/sys/net/link_layer/csma_sender/csma_sender.c b/sys/net/link_layer/csma_sender/csma_sender.c index 1530f7832e3f5afe8bce6f95fb731cd7c9e99806..49c470ab5eeee8f5cc6ce032e3e428f1919eba8b 100644 --- a/sys/net/link_layer/csma_sender/csma_sender.c +++ b/sys/net/link_layer/csma_sender/csma_sender.c @@ -78,8 +78,7 @@ static inline uint32_t choose_backoff_period(int be, * @brief Perform a CCA and send the given packet if medium is available * * @param[in] device netdev device, needs to be already initialized - * @param[in] vector pointer to the data - * @param[in] count number of elements in @p vector + * @param[in] iolist pointer to the data * * @return the return value of device driver's * netdev_driver_t::send() function if medium was @@ -88,7 +87,7 @@ static inline uint32_t choose_backoff_period(int be, * @return -EBUSY if radio medium was not available * to send the given data */ -static int send_if_cca(netdev_t *device, struct iovec *vector, unsigned count) +static int send_if_cca(netdev_t *device, iolist_t *iolist) { netopt_enable_t hwfeat; @@ -107,7 +106,7 @@ static int send_if_cca(netdev_t *device, struct iovec *vector, unsigned count) /* if medium is clear, send the packet and return */ if (hwfeat == NETOPT_ENABLE) { DEBUG("csma: Radio medium available: sending packet.\n"); - return device->driver->send(device, vector, count); + return device->driver->send(device, iolist); } /* if we arrive here, medium was not available for transmission */ @@ -117,8 +116,8 @@ static int send_if_cca(netdev_t *device, struct iovec *vector, unsigned count) /*------------------------- "EXPORTED" FUNCTIONS -------------------------*/ -int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, - unsigned count, const csma_sender_conf_t *conf) +int csma_sender_csma_ca_send(netdev_t *dev, iolist_t *iolist, + const csma_sender_conf_t *conf) { netopt_enable_t hwfeat; @@ -153,7 +152,7 @@ int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, if (ok) { /* device does CSMA/CA all by itself: let it do its job */ DEBUG("csma: Network device does hardware CSMA/CA\n"); - return dev->driver->send(dev, vector, count); + return dev->driver->send(dev, iolist); } /* if we arrive here, then we must perform the CSMA/CA procedure @@ -169,7 +168,7 @@ int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, xtimer_usleep(bp); /* try to send after a CCA */ - res = send_if_cca(dev, vector, count); + res = send_if_cca(dev, iolist); if (res >= 0) { /* TX done */ return res; @@ -195,7 +194,7 @@ int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, } -int csma_sender_cca_send(netdev_t *dev, struct iovec *vector, unsigned count) +int csma_sender_cca_send(netdev_t *dev, iolist_t *iolist) { netopt_enable_t hwfeat; @@ -226,12 +225,12 @@ int csma_sender_cca_send(netdev_t *dev, struct iovec *vector, unsigned count) if (ok) { /* device does auto-CCA: let him do its job */ DEBUG("csma: Network device does auto-CCA checking.\n"); - return dev->driver->send(dev, vector, count); + return dev->driver->send(dev, iolist); } /* if we arrive here, we must do CCA ourselves to see if radio medium is clear before sending */ - res = send_if_cca(dev, vector, count); + res = send_if_cca(dev, iolist); if (res == -EBUSY) { DEBUG("csma: Transmission cancelled!\n"); } diff --git a/sys/net/netdev_test/netdev_test.c b/sys/net/netdev_test/netdev_test.c index 0dba17a6b704f5805fa65eef046e769f864ce36b..69883c1be2b62e3e221d43fb8e5e1b821c7bc3d2 100644 --- a/sys/net/netdev_test/netdev_test.c +++ b/sys/net/netdev_test/netdev_test.c @@ -19,32 +19,6 @@ #include "net/netdev_test.h" -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count); -static int _recv(netdev_t *netdev, void *buf, size_t len, void *info); -static int _init(netdev_t *dev); -static void _isr(netdev_t *dev); -static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len); -static int _set(netdev_t *dev, netopt_t opt, const void *value, size_t value_len); - -static const netdev_driver_t _driver = { - .send = _send, - .recv = _recv, - .init = _init, - .isr = _isr, - .get = _get, - .set = _set, -}; - -void netdev_test_setup(netdev_test_t *dev, void *state) -{ - netdev_t *netdev = (netdev_t *)dev; - - netdev->driver = &_driver; - dev->state = state; - mutex_init(&dev->mutex); - netdev_test_reset(dev); -} - void netdev_test_reset(netdev_test_t *dev) { mutex_lock(&dev->mutex); @@ -57,14 +31,14 @@ void netdev_test_reset(netdev_test_t *dev) mutex_unlock(&dev->mutex); } -static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) +static int _send(netdev_t *netdev, const iolist_t *iolist) { netdev_test_t *dev = (netdev_test_t *)netdev; - int res = (int)count; /* assume everything would be fine */ + int res = -EINVAL; mutex_lock(&dev->mutex); if (dev->send_cb != NULL) { - res = dev->send_cb(netdev, vector, count); + res = dev->send_cb(netdev, iolist); } mutex_unlock(&dev->mutex); return res; @@ -140,5 +114,23 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t value_ return res; } +static const netdev_driver_t _driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; + +void netdev_test_setup(netdev_test_t *dev, void *state) +{ + netdev_t *netdev = (netdev_t *)dev; + + netdev->driver = &_driver; + dev->state = state; + mutex_init(&dev->mutex); + netdev_test_reset(dev); +} /** @} */ diff --git a/tests/driver_at86rf2xx/cmd.c b/tests/driver_at86rf2xx/cmd.c index 58c34630804d3674675fc94a1bc6db113517a12f..6105cfe95cbe13deed0c7d89f0f5f82c9d281a9b 100644 --- a/tests/driver_at86rf2xx/cmd.c +++ b/tests/driver_at86rf2xx/cmd.c @@ -250,7 +250,6 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len, { int res; netdev_ieee802154_t *dev; - struct iovec vector[MAC_VECTOR_SIZE]; uint8_t *src; size_t src_len; uint8_t mhr[IEEE802154_MAX_HDR_LEN]; @@ -262,11 +261,14 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len, return 1; } + iolist_t iol_data = { + .iol_base = data, + .iol_len = strlen(data) + }; + dev = (netdev_ieee802154_t *)&devs[iface]; flags = (uint8_t)(dev->flags & NETDEV_IEEE802154_SEND_MASK); flags |= IEEE802154_FCF_TYPE_DATA; - vector[1].iov_base = data; - vector[1].iov_len = strlen(data); src_pan = byteorder_btols(byteorder_htons(dev->pan)); if (dst_pan.u16 == 0) { dst_pan = src_pan; @@ -287,15 +289,20 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len, puts("txtsnd: Error preperaring frame"); return 1; } - vector[0].iov_base = mhr; - vector[0].iov_len = (size_t)res; - res = dev->netdev.driver->send((netdev_t *)dev, vector, MAC_VECTOR_SIZE); + + iolist_t iol_hdr = { + .iol_next = &iol_data, + .iol_base = mhr, + .iol_len = (size_t)res + }; + + res = dev->netdev.driver->send((netdev_t *)dev, &iol_hdr); if (res < 0) { puts("txtsnd: Error on sending"); return 1; } else { - printf("txtsnd: send %u bytes to ", (unsigned)vector[1].iov_len); + printf("txtsnd: send %u bytes to ", (unsigned)iol_data.iol_len); print_addr(dst, dst_len); printf(" (PAN: "); print_addr((uint8_t *)&dst_pan, sizeof(dst_pan)); diff --git a/tests/driver_sx127x/main.c b/tests/driver_sx127x/main.c index e978cf4e1f26e0d071244ef5968f3a0b83df3fa6..961c145edf2eaa4df72b11a1f57ad54b3d23ef9e 100644 --- a/tests/driver_sx127x/main.c +++ b/tests/driver_sx127x/main.c @@ -224,10 +224,12 @@ int send_cmd(int argc, char **argv) printf("sending \"%s\" payload (%d bytes)\n", argv[1], strlen(argv[1]) + 1); - struct iovec vec[1]; - vec[0].iov_base = argv[1]; - vec[0].iov_len = strlen(argv[1]) + 1; - if (netdev->driver->send(netdev, vec, 1) == -ENOTSUP) { + iolist_t iolist = { + .iol_base = argv[1], + .iol_len = (strlen(argv[1]) + 1) + }; + + if (netdev->driver->send(netdev, &iolist) == -ENOTSUP) { puts("Cannot send: radio is still transmitting"); } diff --git a/tests/gnrc_netif/common.c b/tests/gnrc_netif/common.c index 7d0bf93ce08dc380a42fc3171ebc30f033299c8a..5a29d29391982954e473bda7669f0c1c5c2fb6b2 100644 --- a/tests/gnrc_netif/common.c +++ b/tests/gnrc_netif/common.c @@ -37,8 +37,7 @@ static msg_t _main_msg_queue[MSG_QUEUE_SIZE]; static uint8_t tmp_buffer[ETHERNET_DATA_LEN]; static size_t tmp_buffer_bytes = 0; -static int _dump_send_packet(netdev_t *netdev, const struct iovec *vector, - int count) +static int _dump_send_packet(netdev_t *netdev, const iolist_t *iolist) { int res; @@ -55,13 +54,13 @@ static int _dump_send_packet(netdev_t *netdev, const struct iovec *vector, printf("unknown "); } puts("device:"); - for (int i = 0; i < count; i++) { - if ((tmp_buffer_bytes + vector[i].iov_len) > ETHERNET_DATA_LEN) { + for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) { + size_t len = iol->iol_len; + if ((tmp_buffer_bytes + len) > ETHERNET_DATA_LEN) { return -ENOBUFS; } - memcpy(&tmp_buffer[tmp_buffer_bytes], vector[i].iov_base, - vector[i].iov_len); - tmp_buffer_bytes += vector[i].iov_len; + memcpy(&tmp_buffer[tmp_buffer_bytes], iol->iol_base, len); + tmp_buffer_bytes += len; } od_hex_dump(tmp_buffer, tmp_buffer_bytes, OD_WIDTH_DEFAULT); res = (int)tmp_buffer_bytes; diff --git a/tests/lwip_sock_ip/stack.c b/tests/lwip_sock_ip/stack.c index 52e58a3f526db4c7aee55018e55940d27810d592..23ee9cabf99ac891c059f85de1ae4fb9b3568eed 100644 --- a/tests/lwip_sock_ip/stack.c +++ b/tests/lwip_sock_ip/stack.c @@ -141,16 +141,16 @@ static int _netdev_recv(netdev_t *dev, char *buf, int len, void *info) return res; } -static int _netdev_send(netdev_t *dev, const struct iovec *vector, int count) +static int _netdev_send(netdev_t *dev, const iolist_t *iolist) { msg_t done = { .type = _SEND_DONE }; unsigned offset = 0; (void)dev; mutex_lock(&_netdev_buffer_mutex); - for (int i = 0; i < count; i++) { - memcpy(&_netdev_buffer[offset], vector[i].iov_base, vector[i].iov_len); - offset += vector[i].iov_len; + for (; iolist; iolist = iolist->iol_next) { + memcpy(&_netdev_buffer[offset], iolist->iol_base, iolist->iol_len); + offset += iolist->iol_len; if (offset > sizeof(_netdev_buffer)) { mutex_unlock(&_netdev_buffer_mutex); return -ENOBUFS; diff --git a/tests/lwip_sock_udp/stack.c b/tests/lwip_sock_udp/stack.c index 45539cb478e7a10c45c764231e6a0c94167f656c..cdde693b293c0b09bb378892d66256684aaa2687 100644 --- a/tests/lwip_sock_udp/stack.c +++ b/tests/lwip_sock_udp/stack.c @@ -143,16 +143,16 @@ static int _netdev_recv(netdev_t *dev, char *buf, int len, void *info) return res; } -static int _netdev_send(netdev_t *dev, const struct iovec *vector, int count) +static int _netdev_send(netdev_t *dev, const iolist_t *iolist) { msg_t done = { .type = _SEND_DONE }; unsigned offset = 0; (void)dev; mutex_lock(&_netdev_buffer_mutex); - for (int i = 0; i < count; i++) { - memcpy(&_netdev_buffer[offset], vector[i].iov_base, vector[i].iov_len); - offset += vector[i].iov_len; + for (; iolist; iolist = iolist->iol_next) { + memcpy(&_netdev_buffer[offset], iolist->iol_base, iolist->iol_len); + offset += iolist->iol_len; if (offset > sizeof(_netdev_buffer)) { mutex_unlock(&_netdev_buffer_mutex); return -ENOBUFS; diff --git a/tests/netdev_test/main.c b/tests/netdev_test/main.c index ae1bb37e3be659622cc6b094c657b50079403e96..2ba913765fd5b2b88dc647f754bfbf7b6125cbe8 100644 --- a/tests/netdev_test/main.c +++ b/tests/netdev_test/main.c @@ -61,7 +61,7 @@ static uint8_t _tmp_len = 0; static void _dev_isr(netdev_t *dev); static int _dev_recv(netdev_t *dev, char *buf, int len, void *info); -static int _dev_send(netdev_t *dev, const struct iovec *vector, int count); +static int _dev_send(netdev_t *dev, const iolist_t *iolist); static int _dev_get_addr(netdev_t *dev, void *value, size_t max_len); static int _dev_set_addr(netdev_t *dev, const void *value, size_t max_len); @@ -296,26 +296,26 @@ static int _dev_recv(netdev_t *dev, char *buf, int len, void *info) } } -static int _dev_send(netdev_t *dev, const struct iovec *vector, int count) +static int _dev_send(netdev_t *dev, const iolist_t *iolist) { int idx = 0; (void)dev; /* check packet content with expected data */ - for (int i = 0; i < count; i++) { - if (memcmp(&(_tmp[idx]), vector[i].iov_base, vector[i].iov_len) != 0) { - printf("Unexpected send data (vector index = %d)\n", i); + for (; iolist; iolist = iolist->iol_next) { + if (memcmp(&(_tmp[idx]), iolist->iol_base, iolist->iol_len) != 0) { + puts("Unexpected send data:"); puts("==========================================================="); puts("expected"); puts("==========================================================="); - od_hex_dump(&_tmp[idx], vector[i].iov_len, OD_WIDTH_DEFAULT); + od_hex_dump(&_tmp[idx], iolist->iol_len, OD_WIDTH_DEFAULT); puts("==========================================================="); puts("send data"); puts("==========================================================="); - od_hex_dump(vector[i].iov_base, vector[i].iov_len, OD_WIDTH_DEFAULT); + od_hex_dump(iolist->iol_base, iolist->iol_len, OD_WIDTH_DEFAULT); return -EINVAL; } - idx += vector[i].iov_len; + idx += iolist->iol_len; } if (idx != _tmp_len) { printf("Unexpected send length: %d (expected: %d)\n", idx, _tmp_len); diff --git a/tests/socket_zep/main.c b/tests/socket_zep/main.c index faac4e172ee8ba04a4c1feb5bd1be8f5f6298a16..d5e9ee382303635de505d14cd1cba4fb9abd7d25 100644 --- a/tests/socket_zep/main.c +++ b/tests/socket_zep/main.c @@ -56,29 +56,29 @@ static void test_init(void) _print_info(netdev); } -static void test_send__vector_NULL__count_0(void) +static void test_send__iolist_NULL(void) { netdev_t *netdev = (netdev_t *)(&_dev); - int res; puts("Send zero-length packet"); - res = netdev->driver->send(netdev, NULL, 0); + int res = netdev->driver->send(netdev, NULL); assert((res < 0) || (res == 0)); if ((res < 0) && (errno == ECONNREFUSED)) { puts("No remote socket exists (use scripts in `tests/` to have proper tests)"); } } -static void test_send__vector_not_NULL__count_2(void) +static void test_send__iolist_not_NULL(void) { - struct iovec vector[] = { { .iov_base = "Hello", .iov_len = sizeof("Hello") }, - { .iov_base = "World", .iov_len = sizeof("World") } }; + iolist_t iolist[] = { { .iol_base = "Hello", .iol_len = sizeof("Hello") }, + { .iol_base = "World", .iol_len = sizeof("World") } }; + + iolist[0].iol_next = &iolist[1]; + netdev_t *netdev = (netdev_t *)(&_dev); - int res; puts("Send 'Hello\\0World\\0'"); - res = netdev->driver->send(netdev, vector, - sizeof(vector) / sizeof(struct iovec)); + int res = netdev->driver->send(netdev, iolist); assert((res < 0) || (res == (sizeof("Hello")) + sizeof("World"))); if ((res < 0) && (errno == ECONNREFUSED)) { puts("No remote socket exists (use scripts in `tests/` to have proper tests)"); @@ -109,8 +109,8 @@ int main(void) _main_pid = sched_active_pid; test_init(); - test_send__vector_NULL__count_0(); - test_send__vector_not_NULL__count_2(); + test_send__iolist_NULL(); + test_send__iolist_not_NULL(); test_recv(); /* does not return */ puts("ALL TESTS SUCCESSFUL"); return 0; 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); diff --git a/tests/unittests/tests-pktbuf/tests-pktbuf.c b/tests/unittests/tests-pktbuf/tests-pktbuf.c index 959736022cfbe89e77227e4cb2cdea1b84a5cf3d..dbf8e8c98e41658aae6161a2af6ddc1225854bc9 100644 --- a/tests/unittests/tests-pktbuf/tests-pktbuf.c +++ b/tests/unittests/tests-pktbuf/tests-pktbuf.c @@ -321,7 +321,7 @@ static void test_pktbuf_mark__pkt_NOT_NULL__size_greater_than_pkt_size(void) static void test_pktbuf_mark__pkt_NOT_NULL__pkt_data_NULL(void) { - gnrc_pktsnip_t pkt = { 1, NULL, NULL, sizeof(TEST_STRING16), GNRC_NETTYPE_TEST }; + gnrc_pktsnip_t pkt = { NULL, NULL, sizeof(TEST_STRING16), 1, GNRC_NETTYPE_TEST }; TEST_ASSERT_NULL(gnrc_pktbuf_mark(&pkt, sizeof(TEST_STRING16) - 1, GNRC_NETTYPE_TEST)); @@ -661,7 +661,7 @@ static void test_pktbuf_hold__pkt_null(void) static void test_pktbuf_hold__pkt_external(void) { - gnrc_pktsnip_t pkt = { 1, NULL, TEST_STRING8, sizeof(TEST_STRING8), GNRC_NETTYPE_TEST }; + gnrc_pktsnip_t pkt = { NULL, TEST_STRING8, sizeof(TEST_STRING8), 1, GNRC_NETTYPE_TEST }; gnrc_pktbuf_hold(&pkt, 1); TEST_ASSERT(gnrc_pktbuf_is_empty()); diff --git a/tests/unittests/tests-pktqueue/tests-pktqueue.c b/tests/unittests/tests-pktqueue/tests-pktqueue.c index 31ef4fa8e541c29daf7ff6067832f4383d95855c..6d10f6ee2ce617fda2a3ba40e4de0258ecb711bf 100644 --- a/tests/unittests/tests-pktqueue/tests-pktqueue.c +++ b/tests/unittests/tests-pktqueue/tests-pktqueue.c @@ -22,7 +22,7 @@ #include "tests-pktqueue.h" #define PKT_INIT_ELEM(len, data, next) \ - { 1, (next), (data), (len), GNRC_NETTYPE_UNDEF } + { (next), (data), (len), 1, GNRC_NETTYPE_UNDEF } #define PKT_INIT_ELEM_STATIC_DATA(data, next) PKT_INIT_ELEM(sizeof(data), data, next) #define PKTQUEUE_INIT_ELEM(pkt) { NULL, pkt } diff --git a/tests/unittests/tests-priority_pktqueue/tests-priority_pktqueue.c b/tests/unittests/tests-priority_pktqueue/tests-priority_pktqueue.c index 3673fa7f2a9f3559b337edcca4b904deed1afc89..3f90257857679f0dd80749194ed9ea5fddb0b6cb 100644 --- a/tests/unittests/tests-priority_pktqueue/tests-priority_pktqueue.c +++ b/tests/unittests/tests-priority_pktqueue/tests-priority_pktqueue.c @@ -23,7 +23,7 @@ #include "tests-priority_pktqueue.h" #define PKT_INIT_ELEM(len, data, next) \ - { 1, (next), (data), (len), GNRC_NETTYPE_UNDEF } + { (next), (data), (len), 1, GNRC_NETTYPE_UNDEF } #define PKT_INIT_ELEM_STATIC_DATA(data, next) PKT_INIT_ELEM(sizeof(data), data, next) #define PKTQUEUE_INIT_ELEM(pkt) { NULL, pkt }