drivers: net: adapt to iolist-using netdev

This commit is contained in:
Kaspar Schleiser 2018-01-12 00:19:03 +01:00
parent 2f179f26bb
commit 23b414b732
25 changed files with 222 additions and 275 deletions

View File

@ -14,6 +14,7 @@ ifneq (,$(filter can,$(USEMODULE)))
endif endif
ifneq (,$(filter socket_zep,$(USEMODULE))) ifneq (,$(filter socket_zep,$(USEMODULE)))
USEMODULE += iolist
USEMODULE += netdev_ieee802154 USEMODULE += netdev_ieee802154
USEMODULE += checksum USEMODULE += checksum
USEMODULE += random USEMODULE += random

View File

@ -33,22 +33,6 @@
#define _MAX_MHR_OVERHEAD (25) #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 */ /* Reference pointer for the IRQ handler */
static netdev_t *_dev; 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; 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; (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 */ start of the FIFO, so we can come back and update it later */
rfcore_write_byte(0); rfcore_write_byte(0);
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
pkt_len += vector[i].iov_len; pkt_len += iol->iol_len;
if (pkt_len > CC2538_RF_MAX_DATA_LEN) { if (pkt_len > CC2538_RF_MAX_DATA_LEN) {
DEBUG("cc2538_rf: packet too large (%u > %u)\n", 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; 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 #ifdef MODULE_NETSTATS_L2
@ -407,3 +391,12 @@ static int _init(netdev_t *netdev)
return 0; return 0;
} }
const netdev_driver_t cc2538_rf_driver = {
.get = _get,
.set = _set,
.send = _send,
.recv = _recv,
.isr = _isr,
.init = _init,
};

View File

@ -36,23 +36,6 @@
#define _UNIX_NTP_ERA_OFFSET (2208988800U) #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, static size_t _zep_hdr_fill_v2_data(socket_zep_t *dev, zep_v2_data_hdr_t *hdr,
size_t payload_len) 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); 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) unsigned n, struct iovec *out)
{ {
size_t bytes = 0; size_t bytes;
dev->chksum_buf = 0; dev->chksum_buf = 0;
for (unsigned i = 0; i < n; i++) { bytes = iolist_size(iolist);
bytes += vector[i].iov_len;
}
bytes += sizeof(uint16_t); /* FCS field */ bytes += sizeof(uint16_t); /* FCS field */
out[0].iov_base = &dev->snd_hdr_buf; out[0].iov_base = &dev->snd_hdr_buf;
out[0].iov_len = _zep_hdr_fill(dev, out[0].iov_base, bytes); out[0].iov_len = _zep_hdr_fill(dev, out[0].iov_base, bytes);
for (unsigned i = 0; i < n; i++) { for (unsigned i = 0; i < n; i++) {
/* discard const qualifier, we won't change anything. Promise! */ /* discard const qualifier, we won't change anything. Promise! */
out[i + 1].iov_base = vector[i].iov_base; out[i + 1].iov_base = iolist->iol_base;
out[i + 1].iov_len = vector[i].iov_len; out[i + 1].iov_len = iolist->iol_len;
dev->chksum_buf = ucrc16_calc_le(out[i + 1].iov_base, out[i + 1].iov_len, dev->chksum_buf = ucrc16_calc_le(out[i + 1].iov_base, out[i + 1].iov_len,
UCRC16_CCITT_POLY_LE, dev->chksum_buf); UCRC16_CCITT_POLY_LE, dev->chksum_buf);
iolist = iolist->iol_next;
} }
dev->chksum_buf = byteorder_btols(byteorder_htons(dev->chksum_buf)).u16; dev->chksum_buf = byteorder_btols(byteorder_htons(dev->chksum_buf)).u16;
out[n + 1].iov_base = &dev->chksum_buf; 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; 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; socket_zep_t *dev = (socket_zep_t *)netdev;
unsigned n = iolist_count(iolist);
struct iovec v[n + 2]; struct iovec v[n + 2];
size_t bytes; size_t bytes;
int res; int res;
assert((dev != NULL) && (dev->sock_fd != 0)); assert((dev != NULL) && (dev->sock_fd != 0));
bytes = _prep_vector(dev, vector, n, v); bytes = _prep_vector(dev, iolist, n, v);
DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)vector, n); DEBUG("socket_zep::send(%p, %p, %u)\n", (void *)netdev, (void *)iolist, n);
/* simulate TX_STARTED interrupt */ /* simulate TX_STARTED interrupt */
if (netdev->event_callback) { if (netdev->event_callback) {
dev->last_event = NETDEV_EVENT_TX_STARTED; 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); 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) void socket_zep_setup(socket_zep_t *dev, const socket_zep_params_t *params)
{ {

View File

@ -325,11 +325,11 @@ void isr_radio(void)
cortexm_isr_end(); 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; (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 */ /* wait for any ongoing transmission to finish and go into idle state */
while (state == STATE_TX) {} 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 */ /* copy packet data into the transmit buffer */
int pos = 0; int pos = 0;
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
if ((pos + vector[i].iov_len) > NRFMIN_PKT_MAX) { if ((pos + iol->iol_len) > NRFMIN_PKT_MAX) {
DEBUG("[nrfmin] send: unable to do so, packet is too large!\n"); DEBUG("[nrfmin] send: unable to do so, packet is too large!\n");
return -EOVERFLOW; return -EOVERFLOW;
} }
memcpy(&tx_buf.raw[pos], vector[i].iov_base, vector[i].iov_len); memcpy(&tx_buf.raw[pos], iol->iol_base, iol->iol_len);
pos += vector[i].iov_len; pos += iol->iol_len;
} }
/* set output buffer and destination address */ /* 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->PACKETPTR = (uint32_t)(&tx_buf);
NRF_RADIO->BASE0 = (CONF_ADDR_BASE | hdr->dst_addr); 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; state = STATE_TX;
NRF_RADIO->TASKS_TXEN = 1; 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) static int nrfmin_recv(netdev_t *dev, void *buf, size_t len, void *info)

View File

@ -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) static int gnrc_nrfmin_send(gnrc_netif_t *dev, gnrc_pktsnip_t *pkt)
{ {
int res; int res;
struct iovec *vec;
size_t vec_len;
gnrc_pktsnip_t *vec_snip;
nrfmin_hdr_t nrfmin_hdr; nrfmin_hdr_t nrfmin_hdr;
assert(pkt); 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); res = hdr_netif_to_nrfmin(&nrfmin_hdr, pkt);
if (res < 0) { if (res < 0) {
DEBUG("[nrfmin_gnrc] send: failed to build nrfmin header\n"); DEBUG("[nrfmin_gnrc] send: failed to build nrfmin header\n");
gnrc_pktbuf_release(pkt); goto out;
return res;
} }
/* create iovec of data */ /* link first entry after netif hdr of the pkt to the nrfmin header */
vec_snip = gnrc_pktbuf_get_iovec(pkt, &vec_len); iolist_t iolist = {
if (vec_snip == NULL) { .iol_next = (iolist_t *)pkt->next,
DEBUG("[nrfmin_gnrc] send: failed to create IO vector\n"); .iol_base = &nrfmin_hdr,
gnrc_pktbuf_release(pkt); .iol_len = NRFMIN_HDR_LEN
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;
/* and finally send out the data and release the packet */ /* and finally send out the data and release the packet */
res = dev->dev->driver->send(dev->dev, vec, vec_len); res = dev->dev->driver->send(dev->dev, &iolist);
gnrc_pktbuf_release(vec_snip);
out:
gnrc_pktbuf_release(pkt);
return res; return res;
} }

View File

@ -112,6 +112,7 @@ ifneq (,$(filter encx24j600,$(USEMODULE)))
endif endif
ifneq (,$(filter ethos,$(USEMODULE))) ifneq (,$(filter ethos,$(USEMODULE)))
USEMODULE += iolist
USEMODULE += netdev_eth USEMODULE += netdev_eth
USEMODULE += random USEMODULE += random
USEMODULE += tsrb USEMODULE += tsrb
@ -306,6 +307,7 @@ endif
ifneq (,$(filter sx127%,$(USEMODULE))) ifneq (,$(filter sx127%,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_spi FEATURES_REQUIRED += periph_spi
USEMODULE += iolist
USEMODULE += xtimer USEMODULE += xtimer
USEMODULE += sx127x USEMODULE += sx127x
USEMODULE += netif USEMODULE += netif

View File

@ -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 * 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 * 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 Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Kévin Roussel <Kevin.Roussel@inria.fr> * @author Kévin Roussel <Kevin.Roussel@inria.fr>
* @author Martine Lenders <mlenders@inf.fu-berlin.de> * @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Kaspar Schleiser <kaspar@schleiser.de>
* *
* @} * @}
*/ */
@ -25,6 +27,8 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include "iolist.h"
#include "net/eui64.h" #include "net/eui64.h"
#include "net/ieee802154.h" #include "net/ieee802154.h"
#include "net/netdev.h" #include "net/netdev.h"
@ -40,7 +44,7 @@
#define _MAX_MHR_OVERHEAD (25) #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 _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *netdev); static int _init(netdev_t *netdev);
static void _isr(netdev_t *netdev); static void _isr(netdev_t *netdev);
@ -93,18 +97,17 @@ static int _init(netdev_t *netdev)
return 0; 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; at86rf2xx_t *dev = (at86rf2xx_t *)netdev;
const struct iovec *ptr = vector;
size_t len = 0; size_t len = 0;
at86rf2xx_tx_prepare(dev); at86rf2xx_tx_prepare(dev);
/* load packet data into FIFO */ /* 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 */ /* 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", DEBUG("[at86rf2xx] error: packet too large (%u byte) to be send\n",
(unsigned)len + 2); (unsigned)len + 2);
return -EOVERFLOW; return -EOVERFLOW;
@ -112,7 +115,7 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
#ifdef MODULE_NETSTATS_L2 #ifdef MODULE_NETSTATS_L2
netdev->stats.tx_bytes += len; netdev->stats.tx_bytes += len;
#endif #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 */ /* send data out directly if pre-loading id disabled */

View File

@ -37,14 +37,12 @@
#define ENABLE_DEBUG (0) #define ENABLE_DEBUG (0)
#include "debug.h" #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__); DEBUG("%s:%u\n", __func__, __LINE__);
(void)count; netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t *)dev;
cc110x_pkt_t *cc110x_pkt = iolist->iol_base;
netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t*) dev;
cc110x_pkt_t *cc110x_pkt = vector[0].iov_base;
return cc110x_send(&netdev_cc110x->cc110x, cc110x_pkt); return cc110x_send(&netdev_cc110x->cc110x, cc110x_pkt);
} }

View File

@ -71,9 +71,10 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
cc110x_pkt.flags = 0; cc110x_pkt.flags = 0;
} }
struct iovec vector; iolist_t iolist = {
vector.iov_base = (char*)&cc110x_pkt; .iol_base = (char *)&cc110x_pkt,
vector.iov_len = sizeof(cc110x_pkt_t); .iol_len = sizeof(cc110x_pkt_t)
};
unsigned payload_len = 0; unsigned payload_len = 0;
uint8_t *pos = cc110x_pkt.data; uint8_t *pos = cc110x_pkt.data;
@ -93,7 +94,7 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
payload = payload->next; 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); gnrc_pktbuf_release(pkt);
cc110x_pkt.length = (uint8_t) payload_len + CC110X_HEADER_LENGTH; 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.address,
(unsigned)cc110x_pkt.length); (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) static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)

View File

@ -114,9 +114,9 @@ bool cc2420_cca(cc2420_t *dev)
return gpio_read(dev->params.pin_cca); 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)) { if ((n > 0) && !(dev->options & CC2420_OPT_PRELOADING)) {
cc2420_tx_exec(dev); cc2420_tx_exec(dev);
@ -125,7 +125,7 @@ size_t cc2420_send(cc2420_t *dev, const struct iovec *data, unsigned count)
return n; 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) */ 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) {} while (cc2420_get_state(dev) & NETOPT_STATE_TX) {}
/* get and check the length of the packet */ /* get and check the length of the packet */
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
pkt_len += data[i].iov_len; pkt_len += iol->iol_len;
} }
if (pkt_len >= CC2420_PKT_MAXLEN) { if (pkt_len >= CC2420_PKT_MAXLEN) {
DEBUG("cc2420: tx_prep: unable to send, pkt too large\n"); 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 */ /* push packet length to TX FIFO */
cc2420_fifo_write(dev, (uint8_t *)&pkt_len, 1); cc2420_fifo_write(dev, (uint8_t *)&pkt_len, 1);
/* push packet to TX FIFO */ /* push packet to TX FIFO */
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
cc2420_fifo_write(dev, (uint8_t *)data[i].iov_base, data[i].iov_len); 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); DEBUG("cc2420: tx_prep: loaded %i byte into the TX FIFO\n", (int)pkt_len);

View File

@ -39,7 +39,7 @@
#include "debug.h" #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 _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *netdev); static int _init(netdev_t *netdev);
static void _isr(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); 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; 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) static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)

View File

@ -240,7 +240,7 @@ static void on_int(void *arg)
netdev->event_callback(arg, NETDEV_EVENT_ISR); 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; enc28j60_t *dev = (enc28j60_t *)netdev;
uint8_t ctrl = 0; 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); cmd_w_addr(dev, ADDR_WRITE_PTR, BUF_TX_START);
/* write control byte and the actual data into the buffer */ /* write control byte and the actual data into the buffer */
cmd_wbm(dev, &ctrl, 1); cmd_wbm(dev, &ctrl, 1);
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
c += data[i].iov_len; c += iol->iol_len;
cmd_wbm(dev, (uint8_t *)data[i].iov_base, data[i].iov_len); cmd_wbm(dev, iol->iol_base, iol->iol_len);
} }
/* set TX end pointer */ /* set TX end pointer */
cmd_w_addr(dev, ADDR_TX_END, cmd_r_addr(dev, ADDR_WRITE_PTR) - 1); cmd_w_addr(dev, ADDR_TX_END, cmd_r_addr(dev, ADDR_WRITE_PTR) - 1);

View File

@ -64,7 +64,7 @@ static inline int _packets_available(encx24j600_t *dev);
static void _get_mac_addr(netdev_t *dev, uint8_t* buf); static void _get_mac_addr(netdev_t *dev, uint8_t* buf);
/* netdev interface */ /* 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 _recv(netdev_t *netdev, void *buf, size_t len, void *info);
static int _init(netdev_t *dev); static int _init(netdev_t *dev);
static void _isr(netdev_t *dev); static void _isr(netdev_t *dev);
@ -291,7 +291,7 @@ static int _init(netdev_t *encdev)
return 0; 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; encx24j600_t * dev = (encx24j600_t *) netdev;
lock(dev); lock(dev);
@ -301,9 +301,9 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count) {
/* copy packet to SRAM */ /* copy packet to SRAM */
size_t len = 0; size_t len = 0;
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
sram_op(dev, ENC_WGPDATA, (i ? 0xFFFF : TX_BUFFER_START), vector[i].iov_base, vector[i].iov_len); sram_op(dev, ENC_WGPDATA, ((iol == iolist) ? TX_BUFFER_START : 0xFFFF), iol->iol_base, iol->iol_len);
len += vector[i].iov_len; len += iol->iol_len;
} }
/* set start of TX packet and length */ /* set start of TX packet and length */

View File

@ -189,12 +189,11 @@ static int _init(netdev_t *encdev)
return 0; 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; size_t result = 0;
while(count--) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
result += vector->iov_len; result += iol->iol_len;
vector++;
} }
return result; 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; ethos_t * dev = (ethos_t *) netdev;
(void)dev; (void)dev;
/* count total packet length */ /* 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 */ /* lock line in order to prevent multiple writes */
mutex_lock(&dev->out_mutex); 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; uint8_t frame_delim = ETHOS_FRAME_DELIMITER;
uart_write(dev->uart, &frame_delim, 1); uart_write(dev->uart, &frame_delim, 1);
/* send iovec */ /* send iolist */
while(count--) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
size_t n = vector->iov_len; size_t n = iol->iol_len;
uint8_t *ptr = vector->iov_base; uint8_t *ptr = iol->iol_base;
while(n--) { while(n--) {
_write_escaped(dev->uart, *ptr++); _write_escaped(dev->uart, *ptr++);
} }
vector++;
} }
uart_write(dev->uart, &frame_delim, 1); uart_write(dev->uart, &frame_delim, 1);

View File

@ -263,13 +263,12 @@ netopt_state_t cc2420_get_state(cc2420_t *dev);
* @note This function ignores the PRELOADING option * @note This function ignores the PRELOADING option
* *
* @param[in] dev device to use for sending * @param[in] dev device to use for sending
* @param[in] data data to send (must include IEEE802.15.4 header) * @param[in] iolist data to send (must include IEEE802.15.4 header)
* @param[in] count length of @p data
* *
* @return number of bytes that were actually send * @return number of bytes that were actually send
* @return 0 on error * @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 * @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. * data is possible after it was called.
* *
* @param[in] dev device to prepare for sending * @param[in] dev device to prepare for sending
* @param[in] data data to prepare (must include IEEE802.15.4 header) * @param[in] iolist data to prepare (must include IEEE802.15.4 header)
* @param[in] count length of @p data
*/ */
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 * @brief Trigger sending of data previously loaded into transmit buffer

View File

@ -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; kw2xrf_t *dev = (kw2xrf_t *)netdev;
const struct iovec *ptr = vector;
uint8_t *pkt_buf = &(dev->buf[1]); uint8_t *pkt_buf = &(dev->buf[1]);
size_t len = 0; size_t len = 0;
@ -149,14 +148,14 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
kw2xrf_wait_idle(dev); kw2xrf_wait_idle(dev);
/* load packet data into buffer */ /* 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 */ /* 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", LOG_ERROR("[kw2xrf] packet too large (%u byte) to be send\n",
(unsigned)len + IEEE802154_FCS_LEN); (unsigned)len + IEEE802154_FCS_LEN);
return -EOVERFLOW; 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); kw2xrf_set_sequence(dev, XCVSEQ_IDLE);

View File

@ -39,22 +39,6 @@
#define _MAX_MHR_OVERHEAD (25) #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) static void _irq_handler(void *arg)
{ {
netdev_t *dev = (netdev_t *) arg; netdev_t *dev = (netdev_t *) arg;
@ -83,18 +67,17 @@ static int _init(netdev_t *netdev)
return 0; 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; mrf24j40_t *dev = (mrf24j40_t *)netdev;
const struct iovec *ptr = vector;
size_t len = 0; size_t len = 0;
mrf24j40_tx_prepare(dev); mrf24j40_tx_prepare(dev);
/* load packet data into FIFO */ /* 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 */ /* 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", DEBUG("[mrf24j40] error: packet too large (%u byte) to be send\n",
(unsigned)len + 2); (unsigned)len + 2);
return -EOVERFLOW; return -EOVERFLOW;
@ -103,11 +86,12 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
#ifdef MODULE_NETSTATS_L2 #ifdef MODULE_NETSTATS_L2
netdev->stats.tx_bytes += len; netdev->stats.tx_bytes += len;
#endif #endif
len = mrf24j40_tx_load(dev, ptr->iov_base, ptr->iov_len, len); len = mrf24j40_tx_load(dev, iol->iol_base, iol->iol_len, len);
if (i == 0) { /* only on first iteration: */
if (iol == iolist) {
dev->header_len = len; dev->header_len = len;
/* Grab the FCF bits from the frame header */ /* 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"); DEBUG("[mrf24j40] END IRQ\n");
} }
const netdev_driver_t mrf24j40_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};

View File

@ -27,31 +27,6 @@
#define SLIP_END_ESC (0xdcU) #define SLIP_END_ESC (0xdcU)
#define SLIP_ESC_ESC (0xddU) #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) static void _slip_rx_cb(void *arg, uint8_t byte)
{ {
slipdev_t *dev = arg; 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); 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; slipdev_t *dev = (slipdev_t *)netdev;
int bytes = 0; int bytes = 0;
DEBUG("slipdev: sending vector of length %u\n", count); DEBUG("slipdev: sending iolist\n");
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
uint8_t *data = vector[i].iov_base; 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) { switch(*data) {
case SLIP_END: case SLIP_END:
/* escaping END byte*/ /* escaping END byte*/
@ -223,4 +198,21 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value,
return -ENOTSUP; 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;
}
/** @} */ /** @} */

View File

@ -34,7 +34,6 @@
#include "debug.h" #include "debug.h"
/* Internal helper functions */ /* 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 _set_state(sx127x_t *dev, netopt_state_t state);
static int _get_state(sx127x_t *dev, void *val); static int _get_state(sx127x_t *dev, void *val);
void _on_dio0_irq(void *arg); void _on_dio0_irq(void *arg);
@ -42,24 +41,7 @@ void _on_dio1_irq(void *arg);
void _on_dio2_irq(void *arg); void _on_dio2_irq(void *arg);
void _on_dio3_irq(void *arg); void _on_dio3_irq(void *arg);
/* Netdev driver api functions */ static int _send(netdev_t *netdev, const iolist_t *iolist)
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)
{ {
sx127x_t *dev = (sx127x_t*) netdev; sx127x_t *dev = (sx127x_t*) netdev;
@ -69,8 +51,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
return -ENOTSUP; return -ENOTSUP;
} }
uint8_t size; uint8_t size = iolist_size(iolist);
size = _get_tx_len(vector, count);
switch (dev->settings.modem) { switch (dev->settings.modem) {
case SX127X_MODEM_FSK: case SX127X_MODEM_FSK:
/* todo */ /* todo */
@ -91,8 +73,8 @@ static int _send(netdev_t *netdev, const struct iovec *vector, unsigned count)
} }
/* Write payload buffer */ /* Write payload buffer */
for (size_t i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
sx127x_write_fifo(dev, vector[i].iov_base, vector[i].iov_len); sx127x_write_fifo(dev, iol->iol_base, iol->iol_len);
} }
break; break;
default: default:
@ -489,17 +471,6 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
return res; 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) static int _set_state(sx127x_t *dev, netopt_state_t state)
{ {
switch (state) { switch (state) {
@ -717,3 +688,12 @@ void _on_dio3_irq(void *arg)
break; break;
} }
} }
const netdev_driver_t sx127x_driver = {
.send = _send,
.recv = _recv,
.init = _init,
.isr = _isr,
.get = _get,
.set = _set,
};

View File

@ -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; w5100_t *dev = (w5100_t *)netdev;
int sum = 0; int sum = 0;
@ -210,9 +210,10 @@ static int send(netdev_t *netdev, const struct iovec *vector, unsigned count)
pos = S0_TX_BASE; pos = S0_TX_BASE;
} }
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
pos = tx_upload(dev, pos, vector[i].iov_base, vector[i].iov_len); size_t len = iol->iol_len;
sum += vector[i].iov_len; pos = tx_upload(dev, pos, iol->iol_base, len);
sum += len;
} }
waddr(dev, S0_TX_WR0, S0_TX_WR1, pos); waddr(dev, S0_TX_WR0, S0_TX_WR1, pos);

View File

@ -104,8 +104,6 @@ static int xbee_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{ {
int res; int res;
size_t size; size_t size;
size_t count;
gnrc_pktsnip_t *vec;
gnrc_netif_hdr_t *hdr; gnrc_netif_hdr_t *hdr;
uint8_t xhdr[XBEE_MAX_TXHDR_LENGTH]; 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 */ /* now let's send out the stuff */
vec = gnrc_pktbuf_get_iovec(pkt, &count); iolist_t iolist = {
if (vec != NULL) { .iol_next = (iolist_t *)pkt->next,
pkt = vec; .iol_base = xhdr,
struct iovec *vector = (struct iovec *)pkt->data; .iol_len = res
vector[0].iov_base = xhdr; };
vector[0].iov_len = res;
#ifdef MODULE_NETSTATS_L2 #ifdef MODULE_NETSTATS_L2
if (hdr->flags & BCAST) { if (hdr->flags & BCAST) {
netif->dev->stats.tx_mcast_count++; 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);
} }
else { 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); gnrc_pktbuf_release(pkt);

View File

@ -634,21 +634,23 @@ int xbee_init(netdev_t *dev)
return 0; 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; xbee_t *xbee = (xbee_t *)dev;
size_t size; size_t size;
uint8_t csum; uint8_t csum;
assert(xbee && vector && (count > 0)); assert(xbee && iolist);
/* calculate the checksum and the packet size */ /* calculate the checksum and the packet size */
size = vector[0].iov_len; size = iolist->iol_len;
csum = _cksum(3, (uint8_t *)vector[0].iov_base, size); csum = _cksum(3, (uint8_t *)iolist->iol_base, size);
for (unsigned i = 1; i < count; i++) { for (const iolist_t *iol = iolist->iol_next; iol; iol = iol->iol_next) {
size += vector[i].iov_len; size_t len = iol->iol_len;
for (size_t p = 0; p < vector[i].iov_len; p++) {
csum -= ((uint8_t *)vector[i].iov_base)[p]; 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 */ /* send the actual data packet */
DEBUG("[xbee] send: now sending out %i byte\n", (int)size); DEBUG("[xbee] send: now sending out %i byte\n", (int)size);
mutex_lock(&(xbee->tx_lock)); mutex_lock(&(xbee->tx_lock));
for (unsigned i = 0; i < count; i++) { for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
uart_write(xbee->p.uart, vector[i].iov_base, vector[i].iov_len); uart_write(xbee->p.uart, iol->iol_base, iol->iol_len);
} }
uart_write(xbee->p.uart, &csum, 1); uart_write(xbee->p.uart, &csum, 1);
mutex_unlock(&(xbee->tx_lock)); mutex_unlock(&(xbee->tx_lock));
/* return number of payload byte */ /* return number of payload bytes */
return (int)size; return (int)size;
} }

View File

@ -250,7 +250,6 @@ static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len,
{ {
int res; int res;
netdev_ieee802154_t *dev; netdev_ieee802154_t *dev;
struct iovec vector[MAC_VECTOR_SIZE];
uint8_t *src; uint8_t *src;
size_t src_len; size_t src_len;
uint8_t mhr[IEEE802154_MAX_HDR_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; return 1;
} }
iolist_t iol_data = {
.iol_base = data,
.iol_len = strlen(data)
};
dev = (netdev_ieee802154_t *)&devs[iface]; dev = (netdev_ieee802154_t *)&devs[iface];
flags = (uint8_t)(dev->flags & NETDEV_IEEE802154_SEND_MASK); flags = (uint8_t)(dev->flags & NETDEV_IEEE802154_SEND_MASK);
flags |= IEEE802154_FCF_TYPE_DATA; flags |= IEEE802154_FCF_TYPE_DATA;
vector[1].iov_base = data;
vector[1].iov_len = strlen(data);
src_pan = byteorder_btols(byteorder_htons(dev->pan)); src_pan = byteorder_btols(byteorder_htons(dev->pan));
if (dst_pan.u16 == 0) { if (dst_pan.u16 == 0) {
dst_pan = src_pan; 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"); puts("txtsnd: Error preperaring frame");
return 1; return 1;
} }
vector[0].iov_base = mhr;
vector[0].iov_len = (size_t)res; iolist_t iol_hdr = {
res = dev->netdev.driver->send((netdev_t *)dev, vector, MAC_VECTOR_SIZE); .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) { if (res < 0) {
puts("txtsnd: Error on sending"); puts("txtsnd: Error on sending");
return 1; return 1;
} }
else { 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); print_addr(dst, dst_len);
printf(" (PAN: "); printf(" (PAN: ");
print_addr((uint8_t *)&dst_pan, sizeof(dst_pan)); print_addr((uint8_t *)&dst_pan, sizeof(dst_pan));

View File

@ -224,10 +224,12 @@ int send_cmd(int argc, char **argv)
printf("sending \"%s\" payload (%d bytes)\n", printf("sending \"%s\" payload (%d bytes)\n",
argv[1], strlen(argv[1]) + 1); argv[1], strlen(argv[1]) + 1);
struct iovec vec[1]; iolist_t iolist = {
vec[0].iov_base = argv[1]; .iol_base = argv[1],
vec[0].iov_len = strlen(argv[1]) + 1; .iol_len = (strlen(argv[1]) + 1)
if (netdev->driver->send(netdev, vec, 1) == -ENOTSUP) { };
if (netdev->driver->send(netdev, &iolist) == -ENOTSUP) {
puts("Cannot send: radio is still transmitting"); puts("Cannot send: radio is still transmitting");
} }

View File

@ -56,29 +56,29 @@ static void test_init(void)
_print_info(netdev); _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); netdev_t *netdev = (netdev_t *)(&_dev);
int res;
puts("Send zero-length packet"); puts("Send zero-length packet");
res = netdev->driver->send(netdev, NULL, 0); int res = netdev->driver->send(netdev, NULL);
assert((res < 0) || (res == 0)); assert((res < 0) || (res == 0));
if ((res < 0) && (errno == ECONNREFUSED)) { if ((res < 0) && (errno == ECONNREFUSED)) {
puts("No remote socket exists (use scripts in `tests/` to have proper tests)"); 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") }, iolist_t iolist[] = { { .iol_base = "Hello", .iol_len = sizeof("Hello") },
{ .iov_base = "World", .iov_len = sizeof("World") } }; { .iol_base = "World", .iol_len = sizeof("World") } };
iolist[0].iol_next = &iolist[1];
netdev_t *netdev = (netdev_t *)(&_dev); netdev_t *netdev = (netdev_t *)(&_dev);
int res;
puts("Send 'Hello\\0World\\0'"); puts("Send 'Hello\\0World\\0'");
res = netdev->driver->send(netdev, vector, int res = netdev->driver->send(netdev, iolist);
sizeof(vector) / sizeof(struct iovec));
assert((res < 0) || (res == (sizeof("Hello")) + sizeof("World"))); assert((res < 0) || (res == (sizeof("Hello")) + sizeof("World")));
if ((res < 0) && (errno == ECONNREFUSED)) { if ((res < 0) && (errno == ECONNREFUSED)) {
puts("No remote socket exists (use scripts in `tests/` to have proper tests)"); 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; _main_pid = sched_active_pid;
test_init(); test_init();
test_send__vector_NULL__count_0(); test_send__iolist_NULL();
test_send__vector_not_NULL__count_2(); test_send__iolist_not_NULL();
test_recv(); /* does not return */ test_recv(); /* does not return */
puts("ALL TESTS SUCCESSFUL"); puts("ALL TESTS SUCCESSFUL");
return 0; return 0;