sys/net: iolist updates

This commit is contained in:
Kaspar Schleiser 2018-01-18 14:51:57 +01:00
parent 23b414b732
commit 1faa845d8e
7 changed files with 94 additions and 119 deletions

View File

@ -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. * CSMA/CA, this feature is used. Otherwise, a software procedure is used.
* *
* @param[in] dev netdev device, needs to be already initialized * @param[in] dev netdev device, needs to be already initialized
* @param[in] vector pointer to the data * @param[in] iolist pointer to the data
* @param[in] count number of elements in @p vector
* @param[in] conf configuration for the backoff; * @param[in] conf configuration for the backoff;
* will be set to @ref CSMA_SENDER_CONF_DEFAULT if NULL. * 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 * @return -EBUSY if radio medium never was available
* to send the given data * to send the given data
*/ */
int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, int csma_sender_csma_ca_send(netdev_t *dev, iolist_t *iolist,
unsigned count, const csma_sender_conf_t *conf); const csma_sender_conf_t *conf);
/** /**
* @brief Sends a 802.15.4 frame when medium is avaiable. * @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(). * @ref csma_sender_csma_ca_send().
* *
* @param[in] dev netdev device, needs to be already initialized * @param[in] dev netdev device, needs to be already initialized
* @param[in] vector pointer to the data * @param[in] iolist pointer to the data
* @param[in] count number of elements in @p vector
* *
* @return number of bytes that were actually send out * @return number of bytes that were actually send out
* @return -ENODEV if @p dev is invalid * @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 * @return -EBUSY if radio medium was not available
* to send the given data * 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 #ifdef __cplusplus

View File

@ -33,11 +33,10 @@
* static uint32_t sum = 0; * static uint32_t sum = 0;
* static mutex_t wait = MUTEX_INIT; * 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)dev;
* (void)vector; * (void)iolist;
* (void)count;
* *
* sum += (xtimer_now_usec() - last_start); * sum += (xtimer_now_usec() - last_start);
* mutex_unlock(&wait); * mutex_unlock(&wait);
@ -95,15 +94,12 @@ extern "C" {
* @brief Callback type to handle send command * @brief Callback type to handle send command
* *
* @param[in] dev network device descriptor * @param[in] dev network device descriptor
* @param[in] vector io vector array to send * @param[in] iolist io vector list to send
* @param[in] count number of entries in vector
* *
* @return number of bytes sent * @return number of bytes sent
* @return <= 0 on error * @return <= 0 on error
*/ */
typedef int (*netdev_test_send_cb_t)(netdev_t *dev, typedef int (*netdev_test_send_cb_t)(netdev_t *dev, const iolist_t *iolist);
const struct iovec *vector,
int count);
/** /**
* @brief Callback type to handle receive command * @brief Callback type to handle receive command

View File

@ -50,10 +50,9 @@ int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
netdev_t *dev = netif->dev; netdev_t *dev = netif->dev;
netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
gnrc_netif_hdr_t *netif_hdr; gnrc_netif_hdr_t *netif_hdr;
gnrc_pktsnip_t *vec_snip;
const uint8_t *src, *dst = NULL; const uint8_t *src, *dst = NULL;
int res = 0; 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 mhr[IEEE802154_MAX_HDR_LEN];
uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK);
le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan));
@ -93,15 +92,14 @@ int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
DEBUG("_send_ieee802154: Error preperaring frame\n"); DEBUG("_send_ieee802154: Error preperaring frame\n");
return -EINVAL; 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 */ /* prepare packet for sending */
vector = (struct iovec *)pkt->data; iolist_t iolist = {
vector[0].iov_base = mhr; .iol_next = (iolist_t *)pkt->next,
vector[0].iov_len = (size_t)res; .iol_base = mhr,
.iol_len = (size_t)res
};
#ifdef MODULE_NETSTATS_L2 #ifdef MODULE_NETSTATS_L2
if (netif_hdr->flags & if (netif_hdr->flags &
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
@ -113,18 +111,15 @@ int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
#endif #endif
#ifdef MODULE_GNRC_MAC #ifdef MODULE_GNRC_MAC
if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) {
res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf); res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf);
} }
else { else {
res = dev->driver->send(dev, vector, n); res = dev->driver->send(dev, &iolist);
} }
#else #else
res = dev->driver->send(dev, vector, n); res = dev->driver->send(dev, &iolist);
#endif #endif
}
else {
return -ENOBUFS;
}
/* release old data */ /* release old data */
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return res; return res;

View File

@ -37,10 +37,9 @@ int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
netdev_t *dev = netif->dev; netdev_t *dev = netif->dev;
netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
gnrc_netif_hdr_t *netif_hdr; gnrc_netif_hdr_t *netif_hdr;
gnrc_pktsnip_t *vec_snip;
const uint8_t *src, *dst = NULL; const uint8_t *src, *dst = NULL;
int res = 0; 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 mhr[IEEE802154_MAX_HDR_LEN];
uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK);
le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan));
@ -80,15 +79,14 @@ int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
DEBUG("_send_ieee802154: Error preperaring frame\n"); DEBUG("_send_ieee802154: Error preperaring frame\n");
return -EINVAL; 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 */ /* prepare packet for sending */
vector = (struct iovec *)pkt->data; iolist_t iolist = {
vector[0].iov_base = mhr; .iol_next = (iolist_t *)pkt->next,
vector[0].iov_len = (size_t)res; .iol_base = mhr,
.iol_len = (size_t)res
};
#ifdef MODULE_NETSTATS_L2 #ifdef MODULE_NETSTATS_L2
if (netif_hdr->flags & if (netif_hdr->flags &
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
@ -100,18 +98,15 @@ int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
#endif #endif
#ifdef MODULE_GNRC_MAC #ifdef MODULE_GNRC_MAC
if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) {
res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf); res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf);
} }
else { else {
res = dev->driver->send(dev, vector, n); res = dev->driver->send(dev, &iolist);
} }
#else #else
res = dev->driver->send(dev, vector, n); res = dev->driver->send(dev, &iolist);
#endif #endif
}
else {
return -ENOBUFS;
}
/* release old data */ /* release old data */
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return res; return res;

View File

@ -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 * @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] device netdev device, needs to be already initialized
* @param[in] vector pointer to the data * @param[in] iolist pointer to the data
* @param[in] count number of elements in @p vector
* *
* @return the return value of device driver's * @return the return value of device driver's
* netdev_driver_t::send() function if medium was * 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 * @return -EBUSY if radio medium was not available
* to send the given data * 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; 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 medium is clear, send the packet and return */
if (hwfeat == NETOPT_ENABLE) { if (hwfeat == NETOPT_ENABLE) {
DEBUG("csma: Radio medium available: sending packet.\n"); 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 */ /* 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 -------------------------*/ /*------------------------- "EXPORTED" FUNCTIONS -------------------------*/
int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector, int csma_sender_csma_ca_send(netdev_t *dev, iolist_t *iolist,
unsigned count, const csma_sender_conf_t *conf) const csma_sender_conf_t *conf)
{ {
netopt_enable_t hwfeat; netopt_enable_t hwfeat;
@ -153,7 +152,7 @@ int csma_sender_csma_ca_send(netdev_t *dev, struct iovec *vector,
if (ok) { if (ok) {
/* device does CSMA/CA all by itself: let it do its job */ /* device does CSMA/CA all by itself: let it do its job */
DEBUG("csma: Network device does hardware CSMA/CA\n"); 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 /* 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); xtimer_usleep(bp);
/* try to send after a CCA */ /* try to send after a CCA */
res = send_if_cca(dev, vector, count); res = send_if_cca(dev, iolist);
if (res >= 0) { if (res >= 0) {
/* TX done */ /* TX done */
return res; 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; netopt_enable_t hwfeat;
@ -226,12 +225,12 @@ int csma_sender_cca_send(netdev_t *dev, struct iovec *vector, unsigned count)
if (ok) { if (ok) {
/* device does auto-CCA: let him do its job */ /* device does auto-CCA: let him do its job */
DEBUG("csma: Network device does auto-CCA checking.\n"); 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 /* if we arrive here, we must do CCA ourselves to see if radio medium
is clear before sending */ is clear before sending */
res = send_if_cca(dev, vector, count); res = send_if_cca(dev, iolist);
if (res == -EBUSY) { if (res == -EBUSY) {
DEBUG("csma: Transmission cancelled!\n"); DEBUG("csma: Transmission cancelled!\n");
} }

View File

@ -19,32 +19,6 @@
#include "net/netdev_test.h" #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) void netdev_test_reset(netdev_test_t *dev)
{ {
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
@ -57,14 +31,14 @@ void netdev_test_reset(netdev_test_t *dev)
mutex_unlock(&dev->mutex); 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; netdev_test_t *dev = (netdev_test_t *)netdev;
int res = (int)count; /* assume everything would be fine */ int res = -EINVAL;
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
if (dev->send_cb != NULL) { if (dev->send_cb != NULL) {
res = dev->send_cb(netdev, vector, count); res = dev->send_cb(netdev, iolist);
} }
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
return res; return res;
@ -140,5 +114,23 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t value_
return res; 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);
}
/** @} */ /** @} */

View File

@ -61,7 +61,7 @@ static uint8_t _tmp_len = 0;
static void _dev_isr(netdev_t *dev); static void _dev_isr(netdev_t *dev);
static int _dev_recv(netdev_t *dev, char *buf, int len, void *info); 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_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); 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; int idx = 0;
(void)dev; (void)dev;
/* check packet content with expected data */ /* check packet content with expected data */
for (int i = 0; i < count; i++) { for (; iolist; iolist = iolist->iol_next) {
if (memcmp(&(_tmp[idx]), vector[i].iov_base, vector[i].iov_len) != 0) { if (memcmp(&(_tmp[idx]), iolist->iol_base, iolist->iol_len) != 0) {
printf("Unexpected send data (vector index = %d)\n", i); puts("Unexpected send data:");
puts("==========================================================="); puts("===========================================================");
puts("expected"); puts("expected");
puts("==========================================================="); 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("===========================================================");
puts("send data"); puts("send data");
puts("==========================================================="); 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; return -EINVAL;
} }
idx += vector[i].iov_len; idx += iolist->iol_len;
} }
if (idx != _tmp_len) { if (idx != _tmp_len) {
printf("Unexpected send length: %d (expected: %d)\n", idx, _tmp_len); printf("Unexpected send length: %d (expected: %d)\n", idx, _tmp_len);