From 3db4338beb542b96b06cb1ff450c0da64aae2f51 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Mon, 11 Nov 2019 14:27:21 +0100 Subject: [PATCH 1/7] net/netbuf: introduce network buffer abstraction --- sys/include/net/netbuf.h | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 sys/include/net/netbuf.h diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h new file mode 100644 index 000000000000..8b4d36a0d1f5 --- /dev/null +++ b/sys/include/net/netbuf.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup net_netbuf Network buffer abstraction + * @ingroup net + * @brief Provides an abstraction for network stack buffers + * @{ + * + * @file + * @brief Network buffer abstraction definition + * + * @author Jose I. Alamos + */ +#ifndef NET_NETBUF_H +#define NET_NETBUF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Netbuf descriptor + */ +typedef void netbuf_t; + +/** + * @brief Allocate a network buffer with a given size. + * + * @note Supposed to be implemented by the networking module. + * + * @param[in] size size of the buffer to be allocated. + * + * @return pointer to the netbuf with the allocated buffer. + * @return NULL if there's not enough memory for allocation. + */ +netbuf_t *netbuf_alloc(size_t size); + +/** + * @brief Get the @ref iolist_t representation of the network buffer. + * + * @pre @p netbuf not NULL. + * @pre @p iol not NULL. + * + * @note Supposed to be implemented by the networking module. + * + * @param[in] netbuf pointer to the netbuf. + * @param[out] iol iolist representation of the netbuf. + * + * @return @ref iolist_t representation on @p iol. + */ +void netbuf_get_iolist(netbuf_t *netbuf, iolist_t *iol); + +/** + * @brief Free the resources of a network buffer + * + * @note Supposed to be implemented by the networking module. + * + * @param[in] netbuf pointer to the netbuf descriptor. + */ +void netbuf_free(netbuf_t *netbuf); + +#ifdef __cplusplus +} +#endif + +#endif /* NET_NETBUF_H */ +/** @} */ From f04e546a0f974828a2b5be3399b8397b7231470f Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Fri, 15 Nov 2019 15:54:18 +0100 Subject: [PATCH 2/7] temporal commit --- drivers/include/net/netdev/ieee802154.h | 25 ++ sys/include/net/netbuf.h | 22 +- sys/include/net/netif.h | 16 + sys/net/gnrc/netif/_netif.c | 40 +++ sys/net/gnrc/netif/gnrc_netif.c | 20 +- .../netif/ieee802154/gnrc_netif_ieee802154.c | 285 ++++-------------- sys/net/link_layer/ieee802154/ieee802154.c | 5 + .../link_layer/ieee802154/ieee802154_mac.c | 158 ++++++++++ .../link_layer/ieee802154/ieee802154_netif.c | 48 +++ .../link_layer/ieee802154/ieee802154_phy.c | 42 +++ 10 files changed, 417 insertions(+), 244 deletions(-) create mode 100644 sys/net/link_layer/ieee802154/ieee802154_mac.c create mode 100644 sys/net/link_layer/ieee802154/ieee802154_netif.c create mode 100644 sys/net/link_layer/ieee802154/ieee802154_phy.c diff --git a/drivers/include/net/netdev/ieee802154.h b/drivers/include/net/netdev/ieee802154.h index e47483213fed..0bec28e23924 100644 --- a/drivers/include/net/netdev/ieee802154.h +++ b/drivers/include/net/netdev/ieee802154.h @@ -194,6 +194,31 @@ int netdev_ieee802154_set(netdev_ieee802154_t *dev, netopt_t opt, const void *va */ int netdev_ieee802154_dst_filter(netdev_ieee802154_t *dev, const uint8_t *mhr); +typedef struct { + uint8_t *psdu; + size_t psdu_len; + uint8_t lqi; + int16_t rssi; + void *ctx; +} ieee802154_phy_ind_t; + +typedef struct { + iolist_t msdu; + uint8_t *src; + size_t src_len; + uint8_t *dst; + size_t dst_len; + uint8_t frame_pending; +} ieee802154_mac_ind_t; + +void ieee802154_rf_rx_done(netdev_t *netdev); +void ieee802154_mac_recv(netdev_ieee802154_t *dev, ieee802154_phy_ind_t *ind); +void ieee802154_mac_ind(netdev_ieee802154_t *netdev, ieee802154_mac_ind_t *ind, ieee802154_phy_ind_t *phy_ind); +void ieee802154_phy_ind(netdev_t *netdev, ieee802154_phy_ind_t *ind); +int ieee802154_mac_send(netdev_ieee802154_t *netdev, iolist_t *msdu, int frame_pending, + uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len); + + #ifdef __cplusplus } #endif diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h index 8b4d36a0d1f5..2e31503c0c57 100644 --- a/sys/include/net/netbuf.h +++ b/sys/include/net/netbuf.h @@ -21,6 +21,7 @@ #define NET_NETBUF_H #include +#include "iolist.h" #ifdef __cplusplus extern "C" { @@ -29,7 +30,7 @@ extern "C" { /** * @brief Netbuf descriptor */ -typedef void netbuf_t; +typedef void netbuf_ctx_t; /** * @brief Allocate a network buffer with a given size. @@ -41,22 +42,7 @@ typedef void netbuf_t; * @return pointer to the netbuf with the allocated buffer. * @return NULL if there's not enough memory for allocation. */ -netbuf_t *netbuf_alloc(size_t size); - -/** - * @brief Get the @ref iolist_t representation of the network buffer. - * - * @pre @p netbuf not NULL. - * @pre @p iol not NULL. - * - * @note Supposed to be implemented by the networking module. - * - * @param[in] netbuf pointer to the netbuf. - * @param[out] iol iolist representation of the netbuf. - * - * @return @ref iolist_t representation on @p iol. - */ -void netbuf_get_iolist(netbuf_t *netbuf, iolist_t *iol); +netbuf_ctx_t *netbuf_alloc(size_t size, void **buf); /** * @brief Free the resources of a network buffer @@ -65,7 +51,7 @@ void netbuf_get_iolist(netbuf_t *netbuf, iolist_t *iol); * * @param[in] netbuf pointer to the netbuf descriptor. */ -void netbuf_free(netbuf_t *netbuf); +void netbuf_free(netbuf_ctx_t *ctx); #ifdef __cplusplus } diff --git a/sys/include/net/netif.h b/sys/include/net/netif.h index f4593548dff8..9fcef11ad8cf 100644 --- a/sys/include/net/netif.h +++ b/sys/include/net/netif.h @@ -37,6 +37,7 @@ #include "list.h" #include "net/netopt.h" +#include "net/netbuf.h" #ifdef __cplusplus extern "C" { @@ -58,6 +59,21 @@ typedef struct { list_node_t node; /**< Pointer to the next interface */ } netif_t; +typedef struct { + iolist_t msdu; + netbuf_ctx_t *ctx; + uint8_t *src_l2addr; + uint8_t *dst_l2addr; + int16_t rssi; + uint8_t lqi; + uint8_t src_l2addr_len; + uint8_t dst_l2addr_len; + uint8_t flags; +} netif_pkt_t; + + +int netif_recv(netif_t *netif, netif_pkt_t *pkt); + /** * @brief Iterator for the interfaces * diff --git a/sys/net/gnrc/netif/_netif.c b/sys/net/gnrc/netif/_netif.c index 2cc064158742..f2769ffbd546 100644 --- a/sys/net/gnrc/netif/_netif.c +++ b/sys/net/gnrc/netif/_netif.c @@ -18,11 +18,51 @@ #include #include "fmt.h" +#include "net/gnrc.h" #include "net/gnrc/netapi.h" #include "net/gnrc/netif/internal.h" #include "net/netif.h" +#define ENABLE_DEBUG (0) +#include "debug.h" + +int netif_recv(netif_t *netif, netif_pkt_t *pkt) +{ + gnrc_pktsnip_t *gnrc_pkt = pkt->ctx; + gnrc_netif_t *gnrc_netif = (gnrc_netif_t*) netif; + netdev_t *dev = gnrc_netif->dev; + + gnrc_pktsnip_t *netif_snip = gnrc_netif_hdr_build(pkt->src_l2addr, pkt->src_l2addr_len, pkt->dst_l2addr, pkt->dst_l2addr_len); + + if (netif_snip == NULL) { + DEBUG("_recv_ieee802154: no space left in packet buffer\n"); + gnrc_pktbuf_release(gnrc_pkt); + return 0; + } + + gnrc_pktsnip_t *ieee802154_hdr = gnrc_pktbuf_mark(gnrc_pkt, ((uint8_t*) pkt->msdu.iol_base) - ((uint8_t*) gnrc_pkt->data), GNRC_NETTYPE_UNDEF); + + gnrc_pktbuf_remove_snip(gnrc_pkt, ieee802154_hdr); + gnrc_pktbuf_realloc_data(gnrc_pkt, pkt->msdu.iol_len); + gnrc_netif_hdr_t *hdr = netif_snip->data; + hdr->lqi = pkt->lqi; + hdr->rssi = pkt->rssi; + gnrc_netif_hdr_set_netif(hdr, (gnrc_netif_t*) netif); + dev->driver->get(dev, NETOPT_PROTO, &gnrc_pkt->type, sizeof(gnrc_pkt->type)); + + hdr->flags |= pkt->flags; + + LL_APPEND(gnrc_pkt, netif_snip); + + if (!gnrc_netapi_dispatch_receive(gnrc_pkt->type, GNRC_NETREG_DEMUX_CTX_ALL, gnrc_pkt)) + { + return 0; + } + + return 1; +} + int netif_get_name(netif_t *iface, char *name) { gnrc_netif_t *netif = (gnrc_netif_t*) iface; diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index a6053073e5a7..a07e889a1672 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -33,6 +33,7 @@ #include "sched.h" #include "xtimer.h" +#include "net/netbuf.h" #include "net/gnrc/netif.h" #include "net/gnrc/netif/internal.h" @@ -46,6 +47,22 @@ static void _configure_netdev(netdev_t *dev); static void *_gnrc_netif_thread(void *args); static void _event_cb(netdev_t *dev, netdev_event_t event); +netbuf_ctx_t *netbuf_alloc(size_t size, void **buf) +{ + gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, size, GNRC_NETTYPE_UNDEF); + + if(pkt) { + *buf = pkt->data; + } + + return pkt; +} + +void netbuf_free(netbuf_ctx_t *netbuf) +{ + gnrc_pktbuf_release(netbuf); +} + gnrc_netif_t *gnrc_netif_create(char *stack, int stacksize, char priority, const char *name, netdev_t *netdev, const gnrc_netif_ops_t *ops) @@ -1332,6 +1349,7 @@ void gnrc_netif_default_init(gnrc_netif_t *netif) #endif } +extern int gnrc_netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt); static void *_gnrc_netif_thread(void *args) { gnrc_netapi_opt_t *opt; @@ -1388,7 +1406,7 @@ static void *_gnrc_netif_thread(void *args) break; case GNRC_NETAPI_MSG_TYPE_SND: DEBUG("gnrc_netif: GNRC_NETDEV_MSG_TYPE_SND received\n"); - res = netif->ops->send(netif, msg.content.ptr); + res = gnrc_netif_send(netif, msg.content.ptr); if (res < 0) { DEBUG("gnrc_netif: error sending packet %p (code: %i)\n", msg.content.ptr, res); diff --git a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c index ad15ec080ab0..295c4bdcc5af 100644 --- a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c +++ b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c @@ -17,6 +17,8 @@ #include "net/gnrc/netif/ieee802154.h" #include "net/netdev/ieee802154.h" +#include "net/netbuf.h" + #ifdef MODULE_GNRC_IPV6 #include "net/ipv6/hdr.h" #endif @@ -28,12 +30,11 @@ #include "od.h" #endif -static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt); static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif); static const gnrc_netif_ops_t ieee802154_ops = { .init = gnrc_netif_default_init, - .send = _send, + .send = NULL, /* to be migrated to netif->ops */ .recv = _recv, .get = gnrc_netif_get_from_netdev, .set = gnrc_netif_set_from_netdev, @@ -47,236 +48,40 @@ gnrc_netif_t *gnrc_netif_ieee802154_create(char *stack, int stacksize, &ieee802154_ops); } -static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr) -{ - gnrc_netif_hdr_t *hdr; - gnrc_pktsnip_t *snip; - uint8_t src[IEEE802154_LONG_ADDRESS_LEN], dst[IEEE802154_LONG_ADDRESS_LEN]; - int src_len, dst_len; - le_uint16_t _pan_tmp; /* TODO: hand-up PAN IDs to GNRC? */ - - dst_len = ieee802154_get_dst(mhr, dst, &_pan_tmp); - src_len = ieee802154_get_src(mhr, src, &_pan_tmp); - if ((dst_len < 0) || (src_len < 0)) { - DEBUG("_make_netif_hdr: unable to get addresses\n"); - return NULL; - } - /* allocate space for header */ - snip = gnrc_netif_hdr_build(src, (size_t)src_len, dst, (size_t)dst_len); - if (snip == NULL) { - DEBUG("_make_netif_hdr: no space left in packet buffer\n"); - return NULL; - } - hdr = snip->data; - /* set broadcast flag for broadcast destination */ - if ((dst_len == 2) && (dst[0] == 0xff) && (dst[1] == 0xff)) { - hdr->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST; - } - /* set flags for pending frames */ - if (mhr[0] & IEEE802154_FCF_FRAME_PEND) { - hdr->flags |= GNRC_NETIF_HDR_FLAGS_MORE_DATA; - } - return snip; -} - -#if MODULE_GNRC_NETIF_DEDUP -static inline bool _already_received(gnrc_netif_t *netif, - gnrc_netif_hdr_t *netif_hdr, - uint8_t *mhr) -{ - const uint8_t seq = ieee802154_get_seq(mhr); - - return (netif->last_pkt.seq == seq) && - (netif->last_pkt.src_len == netif_hdr->src_l2addr_len) && - (memcmp(netif->last_pkt.src, gnrc_netif_hdr_get_src_addr(netif_hdr), - netif_hdr->src_l2addr_len) == 0); -} -#endif /* MODULE_GNRC_NETIF_DEDUP */ - static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) { - netdev_t *dev = netif->dev; - netdev_ieee802154_rx_info_t rx_info; - gnrc_pktsnip_t *pkt = NULL; - int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL); - - if (bytes_expected >= (int)IEEE802154_MIN_FRAME_LEN) { - int nread; - - pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF); - if (pkt == NULL) { - DEBUG("_recv_ieee802154: cannot allocate pktsnip.\n"); - /* Discard packet on netdev device */ - dev->driver->recv(dev, NULL, bytes_expected, NULL); - return NULL; - } - nread = dev->driver->recv(dev, pkt->data, bytes_expected, &rx_info); - if (nread <= 0) { - gnrc_pktbuf_release(pkt); - return NULL; - } -#ifdef MODULE_NETSTATS_L2 - netif->stats.rx_count++; - netif->stats.rx_bytes += nread; -#endif - - if (netif->flags & GNRC_NETIF_FLAGS_RAWMODE) { - /* Raw mode, skip packet processing, but provide rx_info via - * GNRC_NETTYPE_NETIF */ - gnrc_pktsnip_t *netif_snip = gnrc_netif_hdr_build(NULL, 0, NULL, 0); - if (netif_snip == NULL) { - DEBUG("_recv_ieee802154: no space left in packet buffer\n"); - gnrc_pktbuf_release(pkt); - return NULL; - } - gnrc_netif_hdr_t *hdr = netif_snip->data; - hdr->lqi = rx_info.lqi; - hdr->rssi = rx_info.rssi; - gnrc_netif_hdr_set_netif(hdr, netif); - LL_APPEND(pkt, netif_snip); - } - else { - /* Normal mode, try to parse the frame according to IEEE 802.15.4 */ - gnrc_pktsnip_t *ieee802154_hdr, *netif_hdr; - gnrc_netif_hdr_t *hdr; -#if ENABLE_DEBUG - char src_str[GNRC_NETIF_HDR_L2ADDR_PRINT_LEN]; -#endif - size_t mhr_len = ieee802154_get_frame_hdr_len(pkt->data); - - /* nread was checked for <= 0 before so we can safely cast it to - * unsigned */ - if ((mhr_len == 0) || ((size_t)nread < mhr_len)) { - DEBUG("_recv_ieee802154: illegally formatted frame received\n"); - gnrc_pktbuf_release(pkt); - return NULL; - } - nread -= mhr_len; - /* mark IEEE 802.15.4 header */ - ieee802154_hdr = gnrc_pktbuf_mark(pkt, mhr_len, GNRC_NETTYPE_UNDEF); - if (ieee802154_hdr == NULL) { - DEBUG("_recv_ieee802154: no space left in packet buffer\n"); - gnrc_pktbuf_release(pkt); - return NULL; - } - netif_hdr = _make_netif_hdr(ieee802154_hdr->data); - if (netif_hdr == NULL) { - DEBUG("_recv_ieee802154: no space left in packet buffer\n"); - gnrc_pktbuf_release(pkt); - return NULL; - } - - hdr = netif_hdr->data; - -#ifdef MODULE_L2FILTER - if (!l2filter_pass(dev->filter, gnrc_netif_hdr_get_src_addr(hdr), - hdr->src_l2addr_len)) { - gnrc_pktbuf_release(pkt); - gnrc_pktbuf_release(netif_hdr); - DEBUG("_recv_ieee802154: packet dropped by l2filter\n"); - return NULL; - } -#endif -#ifdef MODULE_GNRC_NETIF_DEDUP - if (_already_received(netif, hdr, ieee802154_hdr->data)) { - gnrc_pktbuf_release(pkt); - gnrc_pktbuf_release(netif_hdr); - DEBUG("_recv_ieee802154: packet dropped by deduplication\n"); - return NULL; - } - memcpy(netif->last_pkt.src, gnrc_netif_hdr_get_src_addr(hdr), - hdr->src_l2addr_len); - netif->last_pkt.src_len = hdr->src_l2addr_len; - netif->last_pkt.seq = ieee802154_get_seq(ieee802154_hdr->data); -#endif /* MODULE_GNRC_NETIF_DEDUP */ - - hdr->lqi = rx_info.lqi; - hdr->rssi = rx_info.rssi; - gnrc_netif_hdr_set_netif(hdr, netif); - dev->driver->get(dev, NETOPT_PROTO, &pkt->type, sizeof(pkt->type)); -#if ENABLE_DEBUG - DEBUG("_recv_ieee802154: received packet from %s of length %u\n", - gnrc_netif_addr_to_str(gnrc_netif_hdr_get_src_addr(hdr), - hdr->src_l2addr_len, - src_str), - nread); -#if defined(MODULE_OD) - od_hex_dump(pkt->data, nread, OD_WIDTH_DEFAULT); -#endif -#endif - gnrc_pktbuf_remove_snip(pkt, ieee802154_hdr); - LL_APPEND(pkt, netif_hdr); - } - - DEBUG("_recv_ieee802154: reallocating.\n"); - gnrc_pktbuf_realloc_data(pkt, nread); - } else if (bytes_expected > 0) { - DEBUG("_recv_ieee802154: received frame is too short\n"); - dev->driver->recv(dev, NULL, bytes_expected, NULL); - } - - return pkt; + ieee802154_rf_rx_done(netif->dev); + return NULL; } -static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) +/* Implementation of netif_ieee802144 send function. + * This function sits on top of the IEEE802154 MAC layer. + * Nothe this functions is (mostly) GNRC agnostic! */ +void netif_ieee802154_send(netif_t *netif, netif_pkt_t *pkt) { - netdev_t *dev = netif->dev; - netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; - gnrc_netif_hdr_t *netif_hdr; - const uint8_t *src, *dst = NULL; - int res = 0; + //const uint8_t *src, *dst = NULL; + uint8_t *src, *dst = NULL; size_t src_len, dst_len; - uint8_t mhr[IEEE802154_MAX_HDR_LEN]; - uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); - le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); - flags |= IEEE802154_FCF_TYPE_DATA; - if (pkt == NULL) { - DEBUG("_send_ieee802154: pkt was NULL\n"); - return -EINVAL; - } - if (pkt->type != GNRC_NETTYPE_NETIF) { - DEBUG("_send_ieee802154: first header is not generic netif header\n"); - return -EBADMSG; - } - netif_hdr = pkt->data; - if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MORE_DATA) { - /* Set frame pending field */ - flags |= IEEE802154_FCF_FRAME_PEND; - } /* prepare destination address */ - if (netif_hdr->flags & /* If any of these flags is set assume broadcast */ + if (pkt->flags & /* If any of these flags is set assume broadcast */ (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { - dst = ieee802154_addr_bcast; + dst = (uint8_t*) ieee802154_addr_bcast; dst_len = IEEE802154_ADDR_BCAST_LEN; } else { - dst = gnrc_netif_hdr_get_dst_addr(netif_hdr); - dst_len = netif_hdr->dst_l2addr_len; + dst = pkt->dst_l2addr; + dst_len = pkt->dst_l2addr_len; } - src_len = netif_hdr->src_l2addr_len; + src_len = pkt->src_l2addr_len; if (src_len > 0) { - src = gnrc_netif_hdr_get_src_addr(netif_hdr); + src = pkt->src_l2addr; } else { - src_len = netif->l2addr_len; - src = netif->l2addr; - } - /* fill MAC header, seq should be set by device */ - if ((res = ieee802154_set_frame_hdr(mhr, src, src_len, - dst, dst_len, dev_pan, - dev_pan, flags, state->seq++)) == 0) { - DEBUG("_send_ieee802154: Error preperaring frame\n"); - return -EINVAL; + src_len = ((gnrc_netif_t*) netif)->l2addr_len; + src = ((gnrc_netif_t*) netif)->l2addr; } - /* prepare iolist for netdev / mac layer */ - iolist_t iolist = { - .iol_next = (iolist_t *)pkt->next, - .iol_base = mhr, - .iol_len = (size_t)res - }; - #ifdef MODULE_NETSTATS_L2 if (netif_hdr->flags & (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { @@ -286,19 +91,49 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) netif->stats.tx_unicast_count++; } #endif -#ifdef MODULE_GNRC_MAC - if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { - res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf); + + + gnrc_netif_t *gnrc_netif = (gnrc_netif_t*) netif; + ieee802154_mac_send((netdev_ieee802154_t*) gnrc_netif->dev, &pkt->msdu, pkt->flags & GNRC_NETIF_HDR_FLAGS_MORE_DATA, + src, src_len, dst, dst_len); + + /* release old data */ + netbuf_free(pkt->ctx); +} + +void netif_send(netif_t *netif, netif_pkt_t *pkt) +{ + /* netif->ops->send(netif, pkt); */ + netif_ieee802154_send(netif, pkt); /* We use this one, since there's no netif->ops yet :( */ +} + +int gnrc_netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) +{ + /* ========== BEGIN GNRC_NETIF_GLUE_CODE ========== */ + gnrc_netif_hdr_t *netif_hdr; + netif_pkt_t netif_pkt = {0}; + + if (pkt->type != GNRC_NETTYPE_NETIF) { + DEBUG("_send_ieee802154: first header is not generic netif header\n"); + return -EBADMSG; } - else { - res = dev->driver->send(dev, &iolist); + if (pkt == NULL) { + DEBUG("_send_ieee802154: pkt was NULL\n"); + return -EINVAL; } -#else - res = dev->driver->send(dev, &iolist); -#endif - /* release old data */ - gnrc_pktbuf_release(pkt); - return res; + netif_hdr = pkt->data; + + netif_pkt.flags = netif_hdr->flags; + netif_pkt.src_l2addr = gnrc_netif_hdr_get_src_addr(netif_hdr); + netif_pkt.src_l2addr_len = netif_hdr->src_l2addr_len; + netif_pkt.dst_l2addr = gnrc_netif_hdr_get_dst_addr(netif_hdr); + netif_pkt.dst_l2addr_len = netif_hdr->dst_l2addr_len; + memcpy(&netif_pkt.msdu, pkt->next, sizeof(iolist_t)); + netif_pkt.ctx = pkt; + + netif_send((netif_t*) netif, &netif_pkt); + /* ========== END GNRC_NETIF_GLUE_CODE ========== */ + return 0; } /** @} */ diff --git a/sys/net/link_layer/ieee802154/ieee802154.c b/sys/net/link_layer/ieee802154/ieee802154.c index ae687703d683..79a2a2002df9 100644 --- a/sys/net/link_layer/ieee802154/ieee802154.c +++ b/sys/net/link_layer/ieee802154/ieee802154.c @@ -17,7 +17,12 @@ #include #include +#include "net/netbuf.h" + #include "net/ieee802154.h" +#include "net/netdev/ieee802154.h" + +#include "net/gnrc/netif.h" const uint8_t ieee802154_addr_bcast[IEEE802154_ADDR_BCAST_LEN] = IEEE802154_ADDR_BCAST; diff --git a/sys/net/link_layer/ieee802154/ieee802154_mac.c b/sys/net/link_layer/ieee802154/ieee802154_mac.c new file mode 100644 index 000000000000..b129d5a916a5 --- /dev/null +++ b/sys/net/link_layer/ieee802154/ieee802154_mac.c @@ -0,0 +1,158 @@ +#include "net/netdev/ieee802154.h" +#include "net/netbuf.h" +#include "net/netif.h" +#include "net/gnrc/netif.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/* Note all IEEE802.15.4 MAC layers will have this signature. + * There's probably no need for an interface here, unless there are co-existent + * IEEE802.15.4 MAC layers. */ +void ieee802154_mac_recv(netdev_ieee802154_t *dev, ieee802154_phy_ind_t *ind) +{ + ieee802154_mac_ind_t mac_ind; + if (ind->psdu_len < (int)IEEE802154_MIN_FRAME_LEN) { + DEBUG("_recv_ieee802154: received frame is too short\n"); + netbuf_free(ind->ctx); + return; + } + + /* Normal mode, try to parse the frame according to IEEE 802.15.4 */ +#if ENABLE_DEBUG + char src_str[GNRC_NETIF_HDR_L2ADDR_PRINT_LEN]; +#endif + uint8_t *mhr = ind->psdu; + size_t mhr_len = ieee802154_get_frame_hdr_len(mhr); + + /* nread was checked for <= 0 before so we can safely cast it to + * unsigned */ + if ((mhr_len == 0) || ((size_t)ind->psdu_len < mhr_len)) { + DEBUG("_recv_ieee802154: illegally formatted frame received\n"); + netbuf_free(ind->ctx); + return; + } + /* mark IEEE 802.15.4 header */ + mac_ind.msdu.iol_base = mhr + mhr_len; + mac_ind.msdu.iol_len = ind->psdu_len-mhr_len; + + uint8_t src[IEEE802154_LONG_ADDRESS_LEN], dst[IEEE802154_LONG_ADDRESS_LEN]; + int src_len, dst_len; + le_uint16_t _pan_tmp; /* TODO: hand-up PAN IDs to GNRC? */ + + dst_len = ieee802154_get_dst(mhr, dst, &_pan_tmp); + src_len = ieee802154_get_src(mhr, src, &_pan_tmp); + + if ((dst_len < 0) || (src_len < 0)) { + DEBUG("_make_netif_hdr: unable to get addresses\n"); + netbuf_free(ind->ctx); + return; + } + mac_ind.src = src; + mac_ind.src_len = src_len; + mac_ind.dst = dst; + mac_ind.dst_len = dst_len; + +#ifdef MODULE_L2FILTER + if (!l2filter_pass(dev->filter, src, + src_len)) { + netbuf_free(ind->ctx); + DEBUG("_recv_ieee802154: packet dropped by l2filter\n"); + return NULL; + } +#endif +#ifdef MODULE_GNRC_NETIF_DEDUP + /* NOTE!!: This should be implemented by the IEEE802.15.4 layer! */ + const uint8_t seq = ieee802154_get_seq(mhr); + + int received = (netif->last_pkt.seq == seq) && + (netif->last_pkt.src_len == src_len) && + (memcmp(netif->last_pkt.src, src, + src_len) == 0); + + if (received) { + netbuf_free(ind->ctx); + DEBUG("_recv_ieee802154: packet dropped by deduplication\n"); + return NULL; + } + + memcpy(netif->last_pkt.src, src, + src_len); + netif->last_pkt.src_len = src_len; + netif->last_pkt.seq = ieee802154_get_seq(mhr); +#endif /* MODULE_GNRC_NETIF_DEDUP */ + ieee802154_mac_ind(dev, &mac_ind, ind); +} + +/* Interface here? */ +void ieee802154_phy_ind(netdev_t *netdev, ieee802154_phy_ind_t *ind) +{ +#ifdef MODULE_NETSTATS_L2 + netif->stats.rx_count++; + netif->stats.rx_bytes += nread; +#endif + + if (((gnrc_netif_t*) netdev->context)->flags & GNRC_NETIF_FLAGS_RAWMODE) { + /* Raw mode, skip packet processing, but provide rx_info via + * GNRC_NETTYPE_NETIF */ + netif_pkt_t pkt = {0}; + pkt.lqi = ind->lqi; + pkt.rssi = ind->rssi; + pkt.ctx = ind->ctx; + pkt.msdu.iol_base = ind->psdu; + pkt.msdu.iol_len = ind->psdu_len; + if(!netif_recv((netif_t*) netdev->context, &pkt)) { + netbuf_free(ind->ctx); + } + } + else { + ieee802154_mac_recv((netdev_ieee802154_t*) netdev, ind); + } +} + +int ieee802154_mac_send(netdev_ieee802154_t *netdev, iolist_t *msdu, int frame_pending, + uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len) +{ + netdev_ieee802154_t *state = netdev; + netdev_t *dev = &netdev->netdev; + + int res = 0; + uint8_t mhr[IEEE802154_MAX_HDR_LEN]; + le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); + uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); + + flags |= IEEE802154_FCF_TYPE_DATA; + + if (frame_pending) { + /* Set frame pending field */ + flags |= IEEE802154_FCF_FRAME_PEND; + } + /* fill MAC header, seq should be set by device */ + if ((res = ieee802154_set_frame_hdr(mhr, src, src_len, + dst, dst_len, dev_pan, + dev_pan, flags, state->seq++)) == 0) { + DEBUG("_send_ieee802154: Error preperaring frame\n"); + return -EINVAL; + } + + /* prepare iolist for netdev / mac layer */ + iolist_t iolist = { + .iol_next = msdu, + .iol_base = mhr, + .iol_len = (size_t)res + }; + +#ifdef MODULE_GNRC_MAC + if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { + res = csma_sender_csma_ca_send(dev, &iolist, &netif->mac.csma_conf); + } + else { + res = dev->driver->send(dev, &iolist); + } +#else + res = dev->driver->send(dev, &iolist); +#endif + + return res; +} + diff --git a/sys/net/link_layer/ieee802154/ieee802154_netif.c b/sys/net/link_layer/ieee802154/ieee802154_netif.c new file mode 100644 index 000000000000..8b63c74ffeff --- /dev/null +++ b/sys/net/link_layer/ieee802154/ieee802154_netif.c @@ -0,0 +1,48 @@ +#include "net/netdev.h" +#include "net/netdev/ieee802154.h" +#include "net/netif.h" +#include "net/gnrc/netif.h" +#include "net/gnrc/netif/hdr.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +void ieee802154_mac_ind(netdev_ieee802154_t *netdev, ieee802154_mac_ind_t *ind, ieee802154_phy_ind_t *phy_ind) +{ + netif_pkt_t pkt = {0}; + + /* set broadcast flag for broadcast destination */ + if ((ind->dst_len == 2) && (ind->dst[0] == 0xff) && (ind->dst[1] == 0xff)) { + pkt.flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST; + } + + /* set flags for pending frames */ + if (ind->frame_pending & IEEE802154_FCF_FRAME_PEND) { + pkt.flags |= GNRC_NETIF_HDR_FLAGS_MORE_DATA; + } + + pkt.lqi = phy_ind->lqi; + pkt.rssi = phy_ind->rssi; + pkt.ctx = phy_ind->ctx; + pkt.msdu = ind->msdu; + pkt.src_l2addr = ind->src; + pkt.src_l2addr_len = ind->src_len; + pkt.dst_l2addr = ind->dst; + pkt.dst_l2addr_len = ind->dst_len; + +#if ENABLE_DEBUG + DEBUG("_recv_ieee802154: received packet from %s of length %u\n", + gnrc_netif_addr_to_str(src, + src_len, + src_str), + pkt.msdu.iol_len); +#if defined(MODULE_OD) + od_hex_dump(mhr, pkt.msdu.iol_len, OD_WIDTH_DEFAULT); +#endif +#endif + + netif_t *netif = ((netdev_t*) netdev)->context; + if(!netif_recv(netif, &pkt)) { + netbuf_free(phy_ind->ctx); + } +} diff --git a/sys/net/link_layer/ieee802154/ieee802154_phy.c b/sys/net/link_layer/ieee802154/ieee802154_phy.c new file mode 100644 index 000000000000..1bdacf3ba73a --- /dev/null +++ b/sys/net/link_layer/ieee802154/ieee802154_phy.c @@ -0,0 +1,42 @@ +#include "net/netdev.h" +#include "net/netdev/ieee802154.h" + +#include "net/netbuf.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/* This function is the same for all IEEE802154 devices! */ +void ieee802154_rf_rx_done(netdev_t *dev) +{ + netdev_ieee802154_rx_info_t rx_info; + int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL); + void *psdu; + netbuf_ctx_t *ctx = netbuf_alloc(bytes_expected, &psdu); + + if (ctx == NULL) { + DEBUG("_recv_ieee802154: cannot allocate netbuf.\n"); + + /* Discard packet on netdev device */ + dev->driver->recv(dev, NULL, bytes_expected, NULL); + return; + } + + int nread = dev->driver->recv(dev, psdu, bytes_expected, &rx_info); + + if (nread <= 0) { + netbuf_free(ctx); + return; + } + + ieee802154_phy_ind_t ind; + ind.lqi = rx_info.lqi; + ind.rssi = rx_info.rssi; + ind.psdu = psdu; + ind.psdu_len = nread; + ind.ctx = ctx; + + /* Interface here? */ + ieee802154_phy_ind(dev, &ind); +} + From 8ec3ba2934a0cb78465850828f8b2d53eec91671 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Mon, 18 Nov 2019 18:44:56 +0100 Subject: [PATCH 3/7] add comments --- sys/net/gnrc/netif/_netif.c | 27 ++++++++++++++ sys/net/gnrc/netif/gnrc_netif.c | 2 ++ .../netif/ieee802154/gnrc_netif_ieee802154.c | 22 ++++++++++-- .../link_layer/ieee802154/ieee802154_mac.c | 36 ++++++++++++++++--- .../link_layer/ieee802154/ieee802154_netif.c | 8 +++++ .../link_layer/ieee802154/ieee802154_phy.c | 21 +++++++++-- 6 files changed, 107 insertions(+), 9 deletions(-) diff --git a/sys/net/gnrc/netif/_netif.c b/sys/net/gnrc/netif/_netif.c index f2769ffbd546..5c09e110471c 100644 --- a/sys/net/gnrc/netif/_netif.c +++ b/sys/net/gnrc/netif/_netif.c @@ -27,6 +27,26 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/* GNRC implementation of netif_recv. + * + * This function converts the `netif_pkt` representation + * into a `gnrc_pkt` representation. Note that the + * netbuf implementation of GNRC uses the gnrc_pktsnip_t + * pointer as netbuf context, so we can get fetch the packet + * from there. + * + * Also, we need to create the gnrc_netif_hdr to pass the + * L2 metadata to the upper layers. And also remove the + * L2 header. + * + * Note that if a PHY layer didn't call the netbuf allocation + * function (e.g the PHY layer had a static framebuffer like + * the ESP-WIFI implementation), it's possible to set the + * allocation context (netif_pkt->ctx) to NULL. + * So, it's possible to only allocate the MSDU + * and not the full packet!! This would reduce the number + * of memcpy in those cases. + */ int netif_recv(netif_t *netif, netif_pkt_t *pkt) { gnrc_pktsnip_t *gnrc_pkt = pkt->ctx; @@ -41,6 +61,13 @@ int netif_recv(netif_t *netif, netif_pkt_t *pkt) return 0; } + /* We can avoid the following logic if we know the PHY layer + * didn't allocate the packet (see the description of this function). + * + * In that case, we would need to call + * `gnrc_pktbuf_add(pkt->msdu.iol_base, pkt->msdu.iol_len, GNRC_NETTYPE_UNDEF)` + * instead of removing the snip and reallocating data. + */ gnrc_pktsnip_t *ieee802154_hdr = gnrc_pktbuf_mark(gnrc_pkt, ((uint8_t*) pkt->msdu.iol_base) - ((uint8_t*) gnrc_pkt->data), GNRC_NETTYPE_UNDEF); gnrc_pktbuf_remove_snip(gnrc_pkt, ieee802154_hdr); diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index a07e889a1672..a8963411189a 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -47,6 +47,7 @@ static void _configure_netdev(netdev_t *dev); static void *_gnrc_netif_thread(void *args); static void _event_cb(netdev_t *dev, netdev_event_t event); +/* GNRC implementation of the netbuf_allocate function */ netbuf_ctx_t *netbuf_alloc(size_t size, void **buf) { gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, size, GNRC_NETTYPE_UNDEF); @@ -58,6 +59,7 @@ netbuf_ctx_t *netbuf_alloc(size_t size, void **buf) return pkt; } +/* GNRC implementation of the netbuf_free function */ void netbuf_free(netbuf_ctx_t *netbuf) { gnrc_pktbuf_release(netbuf); diff --git a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c index 295c4bdcc5af..a104775f392f 100644 --- a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c +++ b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c @@ -56,7 +56,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) /* Implementation of netif_ieee802144 send function. * This function sits on top of the IEEE802154 MAC layer. - * Nothe this functions is (mostly) GNRC agnostic! */ + * Note this functions is intended to be GNRC agnostic! */ void netif_ieee802154_send(netif_t *netif, netif_pkt_t *pkt) { //const uint8_t *src, *dst = NULL; @@ -94,19 +94,34 @@ void netif_ieee802154_send(netif_t *netif, netif_pkt_t *pkt) gnrc_netif_t *gnrc_netif = (gnrc_netif_t*) netif; + /* We don't need any MAC interface here since we know gnrc_netif_ieee802154 + * talks to a IEEE802.15.4 MAC layer... */ ieee802154_mac_send((netdev_ieee802154_t*) gnrc_netif->dev, &pkt->msdu, pkt->flags & GNRC_NETIF_HDR_FLAGS_MORE_DATA, src, src_len, dst, dst_len); - /* release old data */ + /* This is usually handled by the MAC layer. + * But anyway, we release the old data */ netbuf_free(pkt->ctx); } +/* Send a `netif_pkt` via the given interface- + * + * Note this function is GNRC independent! + */ void netif_send(netif_t *netif, netif_pkt_t *pkt) { - /* netif->ops->send(netif, pkt); */ + /* Of course, this will be: + * netif->ops->send(netif, pkt); */ netif_ieee802154_send(netif, pkt); /* We use this one, since there's no netif->ops yet :( */ } +/* Function to be called when GNRC needs to send a + * pkt snip that contains the netif hdr. + * + * This function should build the `netif_pkt` and + * call the `netif_send` function. From there, all + * functions are GNRC independent. + */ int gnrc_netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) { /* ========== BEGIN GNRC_NETIF_GLUE_CODE ========== */ @@ -132,6 +147,7 @@ int gnrc_netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) memcpy(&netif_pkt.msdu, pkt->next, sizeof(iolist_t)); netif_pkt.ctx = pkt; + /* We call this function to send the packet via the interface */ netif_send((netif_t*) netif, &netif_pkt); /* ========== END GNRC_NETIF_GLUE_CODE ========== */ return 0; diff --git a/sys/net/link_layer/ieee802154/ieee802154_mac.c b/sys/net/link_layer/ieee802154/ieee802154_mac.c index b129d5a916a5..696b0475b275 100644 --- a/sys/net/link_layer/ieee802154/ieee802154_mac.c +++ b/sys/net/link_layer/ieee802154/ieee802154_mac.c @@ -6,9 +6,17 @@ #define ENABLE_DEBUG (0) #include "debug.h" -/* Note all IEEE802.15.4 MAC layers will have this signature. - * There's probably no need for an interface here, unless there are co-existent - * IEEE802.15.4 MAC layers. */ +/* Receive function of the IEEE802.15.4 MAC. + * This function parses the packet and does handles MAC duties + * (packet filtering, handle ACK, security, etc). + * + * This function interacts with the IEEE802.15.4 PHY (represented by + * the `netdev_ieee802154_t` structure). + * + * It will generate a MAC indication with the MSDU (MAC Service Data Unit, + * L2 payload) and L2 information (source and destination addresses, + * frame pending, etc). + */ void ieee802154_mac_recv(netdev_ieee802154_t *dev, ieee802154_phy_ind_t *ind) { ieee802154_mac_ind_t mac_ind; @@ -81,10 +89,23 @@ void ieee802154_mac_recv(netdev_ieee802154_t *dev, ieee802154_phy_ind_t *ind) netif->last_pkt.src_len = src_len; netif->last_pkt.seq = ieee802154_get_seq(mhr); #endif /* MODULE_GNRC_NETIF_DEDUP */ + + /* IEEE802.15.4 indication with L1 + L2 data */ + /* We could think of having an interface here + * E.g ieee802154_mac->ind(dev, &mac_ind, ind) + */ ieee802154_mac_ind(dev, &mac_ind, ind); } -/* Interface here? */ +/* Implementation of the PHY indication. + * This PHY indication implementation checks if the packet has to be processed + * by the IEEE802.15.4 MAC layer. If so, it calls the receive function + * of the IEEE802.15.4 MAC. Otherwise, it calls `netif_recv` directly + * with the `netif_pkt`. + * + * Note the PHY indication contains all the data required by the MAC layer + * (PSDU, RSSI, LQI, etc). + */ void ieee802154_phy_ind(netdev_t *netdev, ieee802154_phy_ind_t *ind) { #ifdef MODULE_NETSTATS_L2 @@ -110,6 +131,12 @@ void ieee802154_phy_ind(netdev_t *netdev, ieee802154_phy_ind_t *ind) } } +/* IEEE802.15.4 send function. + * Note this functions is GNRC independent! + * + * This function interacts with the PHY layer (represented by + * `netdev_ieee802154_t`) in order to send a IEEE802.15.4 packet + */ int ieee802154_mac_send(netdev_ieee802154_t *netdev, iolist_t *msdu, int frame_pending, uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len) { @@ -150,6 +177,7 @@ int ieee802154_mac_send(netdev_ieee802154_t *netdev, iolist_t *msdu, int frame_p res = dev->driver->send(dev, &iolist); } #else + /* We call our PHY layer send function */ res = dev->driver->send(dev, &iolist); #endif diff --git a/sys/net/link_layer/ieee802154/ieee802154_netif.c b/sys/net/link_layer/ieee802154/ieee802154_netif.c index 8b63c74ffeff..de7169894d79 100644 --- a/sys/net/link_layer/ieee802154/ieee802154_netif.c +++ b/sys/net/link_layer/ieee802154/ieee802154_netif.c @@ -7,6 +7,10 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/* Implementation of the MAC indication. + * This function generates the `netif_pkt` from the MAC layer output, + * and calls the `netif_recv` function. + */ void ieee802154_mac_ind(netdev_ieee802154_t *netdev, ieee802154_mac_ind_t *ind, ieee802154_phy_ind_t *phy_ind) { netif_pkt_t pkt = {0}; @@ -42,6 +46,10 @@ void ieee802154_mac_ind(netdev_ieee802154_t *netdev, ieee802154_mac_ind_t *ind, #endif netif_t *netif = ((netdev_t*) netdev)->context; + + /* We call the `netif_recv` function to pass the packet + * to the stack. If the stack doesn't want the packet, + * we release it via the netbuf API. */ if(!netif_recv(netif, &pkt)) { netbuf_free(phy_ind->ctx); } diff --git a/sys/net/link_layer/ieee802154/ieee802154_phy.c b/sys/net/link_layer/ieee802154/ieee802154_phy.c index 1bdacf3ba73a..b0800b1700aa 100644 --- a/sys/net/link_layer/ieee802154/ieee802154_phy.c +++ b/sys/net/link_layer/ieee802154/ieee802154_phy.c @@ -6,7 +6,18 @@ #define ENABLE_DEBUG (0) #include "debug.h" -/* This function is the same for all IEEE802154 devices! */ +/* The transceiver HAL will call this function when there's a packet + * in the framebuffer of the transceiver. The role of the PHY layer + * is to use the transceiver HAL and the netbuf API to: + * - Allocate a buffer from the network stack + * - Read L1 data (LQI, RSSI, etc). + * - Generate a PHY indication with the packet + L1 data. + * + * Here we use some components of `netdev` as our transceiver + * HAL. + * Note this function is the same for all IEEE802154 devices, + * as seen, we reuse the PHY layer for those :) + */ void ieee802154_rf_rx_done(netdev_t *dev) { netdev_ieee802154_rx_info_t rx_info; @@ -30,13 +41,19 @@ void ieee802154_rf_rx_done(netdev_t *dev) } ieee802154_phy_ind_t ind; + + /* Here we populate the indication with the Physical Service + * Data Unit (PSDU, full L2 frame), allocation context and + * L1 info + */ ind.lqi = rx_info.lqi; ind.rssi = rx_info.rssi; ind.psdu = psdu; ind.psdu_len = nread; ind.ctx = ctx; - /* Interface here? */ + /* We have to decide if we need an interface here + * E.g ieee802154_phy->ind(dev, &ind); */ ieee802154_phy_ind(dev, &ind); } From 2eb4b52ddcd9b30fea4d4cf277313259001c3830 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Tue, 19 Nov 2019 16:17:36 +0100 Subject: [PATCH 4/7] address netbuf feedback --- sys/include/net/netbuf.h | 9 +++++++-- sys/net/gnrc/netif/gnrc_netif.c | 7 ++++--- sys/net/link_layer/ieee802154/ieee802154_phy.c | 12 +++++------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h index 2e31503c0c57..51674d37ed27 100644 --- a/sys/include/net/netbuf.h +++ b/sys/include/net/netbuf.h @@ -36,13 +36,18 @@ typedef void netbuf_ctx_t; * @brief Allocate a network buffer with a given size. * * @note Supposed to be implemented by the networking module. + * @note @p ctx must be NOT NULL if the function returns a valid pointer. + * If this function returns NULL, the value of @p ctx + * is undefined. * * @param[in] size size of the buffer to be allocated. + * @param[out] ctx allocation context. * - * @return pointer to the netbuf with the allocated buffer. + * @return pointer to the buffer. + * @return packet context in @p ctx. * @return NULL if there's not enough memory for allocation. */ -netbuf_ctx_t *netbuf_alloc(size_t size, void **buf); +void *netbuf_alloc(size_t size, netbuf_ctx_t **ctx); /** * @brief Free the resources of a network buffer diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index a8963411189a..c971f27ac6b0 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -48,15 +48,16 @@ static void *_gnrc_netif_thread(void *args); static void _event_cb(netdev_t *dev, netdev_event_t event); /* GNRC implementation of the netbuf_allocate function */ -netbuf_ctx_t *netbuf_alloc(size_t size, void **buf) +void *netbuf_alloc(size_t size, netbuf_ctx_t **ctx) { gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, size, GNRC_NETTYPE_UNDEF); if(pkt) { - *buf = pkt->data; + *ctx = pkt; + return pkt->data; } - return pkt; + return NULL; } /* GNRC implementation of the netbuf_free function */ diff --git a/sys/net/link_layer/ieee802154/ieee802154_phy.c b/sys/net/link_layer/ieee802154/ieee802154_phy.c index b0800b1700aa..820838dc5d6f 100644 --- a/sys/net/link_layer/ieee802154/ieee802154_phy.c +++ b/sys/net/link_layer/ieee802154/ieee802154_phy.c @@ -22,10 +22,11 @@ void ieee802154_rf_rx_done(netdev_t *dev) { netdev_ieee802154_rx_info_t rx_info; int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL); - void *psdu; - netbuf_ctx_t *ctx = netbuf_alloc(bytes_expected, &psdu); + ieee802154_phy_ind_t ind = {0}; - if (ctx == NULL) { + void *psdu = netbuf_alloc(bytes_expected, &ind.ctx); + + if (ind.ctx == NULL) { DEBUG("_recv_ieee802154: cannot allocate netbuf.\n"); /* Discard packet on netdev device */ @@ -36,12 +37,10 @@ void ieee802154_rf_rx_done(netdev_t *dev) int nread = dev->driver->recv(dev, psdu, bytes_expected, &rx_info); if (nread <= 0) { - netbuf_free(ctx); + netbuf_free(ind.ctx); return; } - ieee802154_phy_ind_t ind; - /* Here we populate the indication with the Physical Service * Data Unit (PSDU, full L2 frame), allocation context and * L1 info @@ -50,7 +49,6 @@ void ieee802154_rf_rx_done(netdev_t *dev) ind.rssi = rx_info.rssi; ind.psdu = psdu; ind.psdu_len = nread; - ind.ctx = ctx; /* We have to decide if we need an interface here * E.g ieee802154_phy->ind(dev, &ind); */ From f21f8e32e755613825e33a76f99f0034cbef3d4f Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Wed, 20 Nov 2019 11:39:29 +0100 Subject: [PATCH 5/7] addess comments by @miri64 --- sys/include/net/netbuf.h | 11 +++-------- sys/include/net/netif.h | 2 +- sys/net/gnrc/netif/gnrc_netif.c | 4 ++-- sys/net/link_layer/ieee802154/ieee802154_phy.c | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h index 51674d37ed27..1b9a0d4165c9 100644 --- a/sys/include/net/netbuf.h +++ b/sys/include/net/netbuf.h @@ -27,11 +27,6 @@ extern "C" { #endif -/** - * @brief Netbuf descriptor - */ -typedef void netbuf_ctx_t; - /** * @brief Allocate a network buffer with a given size. * @@ -47,16 +42,16 @@ typedef void netbuf_ctx_t; * @return packet context in @p ctx. * @return NULL if there's not enough memory for allocation. */ -void *netbuf_alloc(size_t size, netbuf_ctx_t **ctx); +void *netbuf_alloc(size_t size, void **ctx); /** * @brief Free the resources of a network buffer * * @note Supposed to be implemented by the networking module. * - * @param[in] netbuf pointer to the netbuf descriptor. + * @param[in] ctx pointer to the allocation context. */ -void netbuf_free(netbuf_ctx_t *ctx); +void netbuf_free(void *ctx); #ifdef __cplusplus } diff --git a/sys/include/net/netif.h b/sys/include/net/netif.h index 9fcef11ad8cf..c571b8ca16f0 100644 --- a/sys/include/net/netif.h +++ b/sys/include/net/netif.h @@ -61,7 +61,7 @@ typedef struct { typedef struct { iolist_t msdu; - netbuf_ctx_t *ctx; + void *ctx; uint8_t *src_l2addr; uint8_t *dst_l2addr; int16_t rssi; diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index c971f27ac6b0..75a4f1f4c743 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -48,7 +48,7 @@ static void *_gnrc_netif_thread(void *args); static void _event_cb(netdev_t *dev, netdev_event_t event); /* GNRC implementation of the netbuf_allocate function */ -void *netbuf_alloc(size_t size, netbuf_ctx_t **ctx) +void *netbuf_alloc(size_t size, void **ctx) { gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, size, GNRC_NETTYPE_UNDEF); @@ -61,7 +61,7 @@ void *netbuf_alloc(size_t size, netbuf_ctx_t **ctx) } /* GNRC implementation of the netbuf_free function */ -void netbuf_free(netbuf_ctx_t *netbuf) +void netbuf_free(void *netbuf) { gnrc_pktbuf_release(netbuf); } diff --git a/sys/net/link_layer/ieee802154/ieee802154_phy.c b/sys/net/link_layer/ieee802154/ieee802154_phy.c index 820838dc5d6f..50e842a140d0 100644 --- a/sys/net/link_layer/ieee802154/ieee802154_phy.c +++ b/sys/net/link_layer/ieee802154/ieee802154_phy.c @@ -26,7 +26,7 @@ void ieee802154_rf_rx_done(netdev_t *dev) void *psdu = netbuf_alloc(bytes_expected, &ind.ctx); - if (ind.ctx == NULL) { + if (psdu == NULL) { DEBUG("_recv_ieee802154: cannot allocate netbuf.\n"); /* Discard packet on netdev device */ From 567624f19d6d8042ed957286a2c46580aca86d70 Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Wed, 20 Nov 2019 14:50:30 +0100 Subject: [PATCH 6/7] rename netbuf_alloc --- sys/include/net/netbuf.h | 6 +++--- sys/net/gnrc/netif/gnrc_netif.c | 4 ++-- sys/net/link_layer/ieee802154/ieee802154_phy.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h index 1b9a0d4165c9..455a5a57e974 100644 --- a/sys/include/net/netbuf.h +++ b/sys/include/net/netbuf.h @@ -28,7 +28,7 @@ extern "C" { #endif /** - * @brief Allocate a network buffer with a given size. + * @brief Get a network buffer with a given size. * * @note Supposed to be implemented by the networking module. * @note @p ctx must be NOT NULL if the function returns a valid pointer. @@ -40,9 +40,9 @@ extern "C" { * * @return pointer to the buffer. * @return packet context in @p ctx. - * @return NULL if there's not enough memory for allocation. + * @return NULL on failure (e.g there's not enough memory for allocation) */ -void *netbuf_alloc(size_t size, void **ctx); +void *netbuf_get(size_t size, void **ctx); /** * @brief Free the resources of a network buffer diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index 75a4f1f4c743..690f8c677f0c 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -47,8 +47,8 @@ static void _configure_netdev(netdev_t *dev); static void *_gnrc_netif_thread(void *args); static void _event_cb(netdev_t *dev, netdev_event_t event); -/* GNRC implementation of the netbuf_allocate function */ -void *netbuf_alloc(size_t size, void **ctx) +/* GNRC implementation of the netbuf_get function */ +void *netbuf_get(size_t size, void **ctx) { gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, size, GNRC_NETTYPE_UNDEF); diff --git a/sys/net/link_layer/ieee802154/ieee802154_phy.c b/sys/net/link_layer/ieee802154/ieee802154_phy.c index 50e842a140d0..800a4a261bb0 100644 --- a/sys/net/link_layer/ieee802154/ieee802154_phy.c +++ b/sys/net/link_layer/ieee802154/ieee802154_phy.c @@ -24,7 +24,7 @@ void ieee802154_rf_rx_done(netdev_t *dev) int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL); ieee802154_phy_ind_t ind = {0}; - void *psdu = netbuf_alloc(bytes_expected, &ind.ctx); + void *psdu = netbuf_get(bytes_expected, &ind.ctx); if (psdu == NULL) { DEBUG("_recv_ieee802154: cannot allocate netbuf.\n"); From ee1b95ff9db459a64c4407db001f64a2fdbf785b Mon Sep 17 00:00:00 2001 From: Jose Alamos Date: Fri, 22 Nov 2019 15:35:44 +0100 Subject: [PATCH 7/7] change documentation --- sys/include/net/netbuf.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h index 455a5a57e974..4fe14add2a65 100644 --- a/sys/include/net/netbuf.h +++ b/sys/include/net/netbuf.h @@ -31,9 +31,6 @@ extern "C" { * @brief Get a network buffer with a given size. * * @note Supposed to be implemented by the networking module. - * @note @p ctx must be NOT NULL if the function returns a valid pointer. - * If this function returns NULL, the value of @p ctx - * is undefined. * * @param[in] size size of the buffer to be allocated. * @param[out] ctx allocation context.