From 23b414b732dba2ea2ac4452a35990978348b88bd Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser <kaspar@schleiser.de> Date: Fri, 12 Jan 2018 00:19:03 +0100 Subject: [PATCH] drivers: net: adapt to iolist-using netdev --- boards/native/Makefile.dep | 1 + cpu/cc2538/radio/cc2538_rf_netdev.c | 33 ++++++------- cpu/native/socket_zep/socket_zep.c | 45 +++++++----------- cpu/nrf5x_common/radio/nrfmin/nrfmin.c | 16 +++---- cpu/nrf5x_common/radio/nrfmin/nrfmin_gnrc.c | 30 +++++------- drivers/Makefile.dep | 2 + drivers/at86rf2xx/at86rf2xx_netdev.c | 17 ++++--- drivers/cc110x/cc110x-netdev.c | 8 ++-- drivers/cc110x/gnrc_cc110x/gnrc_cc110x.c | 11 +++-- drivers/cc2420/cc2420.c | 14 +++--- drivers/cc2420/cc2420_netdev.c | 6 +-- drivers/enc28j60/enc28j60.c | 8 ++-- drivers/encx24j600/encx24j600.c | 10 ++-- drivers/ethos/ethos.c | 20 ++++---- drivers/include/cc2420.h | 10 ++-- drivers/kw2xrf/kw2xrf_netdev.c | 9 ++-- drivers/mrf24j40/mrf24j40_netdev.c | 39 +++++++--------- drivers/slipdev/slipdev.c | 52 +++++++++------------ drivers/sx127x/sx127x_netdev.c | 48 ++++++------------- drivers/w5100/w5100.c | 9 ++-- drivers/xbee/gnrc_xbee.c | 32 ++++++------- drivers/xbee/xbee.c | 24 +++++----- tests/driver_at86rf2xx/cmd.c | 21 ++++++--- tests/driver_sx127x/main.c | 10 ++-- tests/socket_zep/main.c | 22 ++++----- 25 files changed, 222 insertions(+), 275 deletions(-) diff --git a/boards/native/Makefile.dep b/boards/native/Makefile.dep index 2639777a1d..8eec472da0 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 ad071120fa..71f6206c86 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/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index d3e51c69ed..162d55ad02 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 1d1d127869..c473594572 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 7bbe1424c2..5002385802 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 5392a1c033..de911d403b 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 54fbd9d9bb..dd697483dc 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 016c2bfba8..a1b42c59da 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 abbad5703a..83db2cef2c 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 eca7ef945e..a0b0600b53 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 5514e35c88..fe1f42ccd3 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 2b9dd9312d..2f55e699a0 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 491fdcbdd0..47c5d3d32f 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 1d7c816144..511eec2865 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 a2d6f77be4..b8d2176722 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/kw2xrf/kw2xrf_netdev.c b/drivers/kw2xrf/kw2xrf_netdev.c index 4d8a0dd3be..e22ab31fdb 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 02598c1b49..10f534689b 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 073ab4019e..9d0a15ac3e 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 30c6e7ef73..6072357311 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 8cc6e92b7b..e391752fa9 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 be78de2aee..8d66233c64 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 93df3ab782..fb9985896d 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/tests/driver_at86rf2xx/cmd.c b/tests/driver_at86rf2xx/cmd.c index 58c3463080..6105cfe95c 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 e978cf4e1f..961c145edf 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/socket_zep/main.c b/tests/socket_zep/main.c index faac4e172e..d5e9ee3823 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; -- GitLab