1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #7925 from RIOT-OS/gnrc_netif2_integration/master

gnrc_netif2: gnrc_ipv6_nib: full integration into GNRC
This commit is contained in:
Koen Zandberg 2017-11-27 21:12:14 +01:00 committed by GitHub
commit 8a6d04ce52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
210 changed files with 10902 additions and 15933 deletions

View File

@ -36,9 +36,8 @@ ifneq (,$(filter sntp,$(USEMODULE)))
endif
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
USEMODULE += gnrc_netif
USEMODULE += gnrc_netdev
USEMODULE += netdev_default
USEMODULE += gnrc_netif
endif
ifneq (,$(filter netdev_ieee802154,$(USEMODULE)))
@ -51,6 +50,10 @@ ifneq (,$(filter gnrc_uhcpc,$(USEMODULE)))
USEMODULE += fmt
endif
ifneq (,$(filter uhcpc,$(USEMODULE)))
USEMODULE += posix
endif
ifneq (,$(filter nordic_softdevice_ble,$(USEPKG)))
USEMODULE += softdevice_handler
USEMODULE += ble_common
@ -58,8 +61,6 @@ ifneq (,$(filter nordic_softdevice_ble,$(USEPKG)))
USEMODULE += gnrc_sixlowpan
USEMODULE += gnrc_sixlowpan_iphc
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_netdev
USEMODULE += gnrc_ipv6_netif
endif
ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pkt%,$(USEMODULE))))
@ -92,9 +93,6 @@ endif
ifneq (,$(filter netdev_tap,$(USEMODULE)))
USEMODULE += netif
USEMODULE += netdev_eth
ifneq (,$(filter gnrc_%,$(USEMODULE)))
USEMODULE += gnrc_netdev
endif
endif
ifneq (,$(filter gnrc_tftp,$(USEMODULE)))
@ -107,7 +105,6 @@ ifneq (,$(filter gnrc_rpl_p2p,$(USEMODULE)))
endif
ifneq (,$(filter gnrc_rpl,$(USEMODULE)))
USEMODULE += fib
USEMODULE += gnrc_ipv6_router_default
USEMODULE += trickle
USEMODULE += xtimer
@ -138,29 +135,30 @@ endif
ifneq (,$(filter gnrc_sixlowpan_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_ipv6_nib_6ln
USEMODULE += gnrc_sixlowpan
USEMODULE += gnrc_sixlowpan_nd
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_ipv6_nib_6lr
USEMODULE += gnrc_sixlowpan_router
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_nib_6lbr
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_sixlowpan_nd_border_router
USEMODULE += gnrc_sixlowpan_router
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd_router
USEMODULE += gnrc_ipv6_router
endif
ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE)))
@ -176,7 +174,6 @@ endif
ifneq (,$(filter gnrc_sixlowpan,$(USEMODULE)))
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_sixlowpan_netif
USEMODULE += sixlowpan
endif
@ -185,80 +182,19 @@ ifneq (,$(filter gnrc_sixlowpan_ctx,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_sixlowpan_nd_border_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd_router
endif
ifneq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd
endif
ifneq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
USEMODULE += gnrc_ndp
USEMODULE += gnrc_ndp_internal
USEMODULE += gnrc_sixlowpan_ctx
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ipv6_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_icmpv6
ifeq (1,$(GNRC_NETIF_NUMOF))
ifeq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
USEMODULE += gnrc_ndp_host
endif
else
USEMODULE += gnrc_ndp_host
endif
endif
ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_router
USEMODULE += gnrc_icmpv6
ifeq (1,$(GNRC_NETIF_NUMOF))
ifeq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
USEMODULE += gnrc_ndp_router
endif
else
USEMODULE += gnrc_ndp_router
endif
endif
ifneq (,$(filter gnrc_ndp_host,$(USEMODULE)))
USEMODULE += gnrc_ndp_node
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
USEMODULE += gnrc_ndp_node
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ndp_node,$(USEMODULE)))
USEMODULE += gnrc_ndp_internal
endif
ifneq (,$(filter gnrc_ndp_%,$(USEMODULE)))
USEMODULE += gnrc_ndp
endif
ifneq (,$(filter gnrc_ndp,$(USEMODULE)))
ifneq (,$(filter gnrc_sixlowpan,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd
else
USEMODULE += gnrc_ndp_node
endif
USEMODULE += gnrc_ndp_internal
USEMODULE += gnrc_icmpv6
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ndp2,$(USEMODULE)))
USEMODULE += gnrc_icmpv6
USEMODULE += gnrc_netif
endif
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
@ -297,14 +233,15 @@ endif
ifneq (,$(filter gnrc_ipv6_router,$(USEMODULE)))
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_ipv6_nib_router
endif
ifneq (,$(filter gnrc_ipv6,$(USEMODULE)))
USEMODULE += inet_csum
USEMODULE += ipv6_addr
USEMODULE += gnrc_ipv6_hdr
USEMODULE += gnrc_ipv6_nc
USEMODULE += gnrc_ipv6_netif
USEMODULE += gnrc_ipv6_nib
USEMODULE += gnrc_netif
endif
ifneq (,$(filter gnrc_ipv6_hdr,$(USEMODULE)))
@ -321,10 +258,6 @@ ifneq (,$(filter ipv6_hdr,$(USEMODULE)))
USEMODULE += ipv6_addr
endif
ifneq (,$(filter gnrc_ipv6_nc,$(USEMODULE)))
USEMODULE += ipv6_addr
endif
ifneq (,$(filter gnrc_ipv6_nib_6lbr,$(USEMODULE)))
USEMODULE += gnrc_ipv6_nib_6lr
endif
@ -345,18 +278,12 @@ endif
ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE)))
USEMODULE += evtimer
USEMODULE += gnrc_ndp2
USEMODULE += gnrc_ndp
USEMODULE += gnrc_netif
USEMODULE += ipv6_addr
USEMODULE += random
endif
ifneq (,$(filter gnrc_ipv6_netif,$(USEMODULE)))
USEMODULE += ipv6_addr
USEMODULE += gnrc_netif
USEMODULE += bitfield
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_udp,$(USEMODULE)))
USEMODULE += inet_csum
USEMODULE += udp
@ -576,8 +503,8 @@ ifneq (,$(filter netstats_%, $(USEMODULE)))
endif
ifneq (,$(filter gnrc_lwmac,$(USEMODULE)))
USEMODULE += gnrc_netif
USEMODULE += gnrc_mac
USEMODULE += gnrc_netdev
FEATURES_REQUIRED += periph_rtt
endif

View File

@ -1,6 +1,5 @@
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
USEMODULE += netif
USEMODULE += cc2538_rf
USEMODULE += gnrc_netdev
USEMODULE += netdev_ieee802154
endif

View File

@ -1,6 +1,5 @@
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
USEMODULE += netif
USEMODULE += cc2538_rf
USEMODULE += gnrc_netdev
USEMODULE += netdev_ieee802154
endif

View File

@ -1,7 +1,6 @@
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
USEMODULE += netif
USEMODULE += cc2538_rf
USEMODULE += gnrc_netdev
USEMODULE += netdev_ieee802154
endif

View File

@ -20,11 +20,7 @@
#include "net/gnrc.h"
#include "thread.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2.h"
#else
#include "net/gnrc/netdev.h"
#endif
#include "net/gnrc/netif.h"
#include "nrfmin_gnrc.h"
@ -36,11 +32,7 @@
* @{
*/
#ifndef NRFMIN_GNRC_THREAD_PRIO
#ifdef MODULE_GNRC_NETIF2
#define NRFMIN_GNRC_THREAD_PRIO GNRC_NETIF2_PRIO
#else
#define NRFMIN_GNRC_THREAD_PRIO GNRC_NETDEV_MAC_PRIO
#endif
#define NRFMIN_GNRC_THREAD_PRIO GNRC_NETIF_PRIO
#endif
#ifndef NRFMIN_GNRC_STACKSIZE
@ -58,14 +50,6 @@
*/
static char stack[NRFMIN_GNRC_STACKSIZE];
#ifndef MODULE_GNRC_NETIF2
/**
* @brief Allocate the GNRC netdev data structure.
*/
static gnrc_netdev_t plug;
#endif
static int hdr_netif_to_nrfmin(nrfmin_hdr_t *nrfmin, gnrc_pktsnip_t *pkt)
{
gnrc_netif_hdr_t *netif = (gnrc_netif_hdr_t *)pkt->data;
@ -92,11 +76,7 @@ static int hdr_netif_to_nrfmin(nrfmin_hdr_t *nrfmin, gnrc_pktsnip_t *pkt)
return 0;
}
#ifdef MODULE_GNRC_NETIF2
static int gnrc_nrfmin_send(gnrc_netif2_t *dev, gnrc_pktsnip_t *pkt)
#else
static int gnrc_nrfmin_send(gnrc_netdev_t *dev, gnrc_pktsnip_t *pkt)
#endif
static int gnrc_nrfmin_send(gnrc_netif_t *dev, gnrc_pktsnip_t *pkt)
{
int res;
struct iovec *vec;
@ -139,11 +119,7 @@ static int gnrc_nrfmin_send(gnrc_netdev_t *dev, gnrc_pktsnip_t *pkt)
return res;
}
#ifdef MODULE_GNRC_NETIF2
static gnrc_pktsnip_t *gnrc_nrfmin_recv(gnrc_netif2_t *dev)
#else
static gnrc_pktsnip_t *gnrc_nrfmin_recv(gnrc_netdev_t *dev)
#endif
static gnrc_pktsnip_t *gnrc_nrfmin_recv(gnrc_netif_t *dev)
{
int pktsize;
nrfmin_hdr_t *nrfmin;
@ -204,30 +180,17 @@ static gnrc_pktsnip_t *gnrc_nrfmin_recv(gnrc_netdev_t *dev)
return pkt_snip;
}
#ifdef MODULE_GNRC_NETIF2
static const gnrc_netif2_ops_t gnrc_nrfmin_ops = {
static const gnrc_netif_ops_t gnrc_nrfmin_ops = {
.send = gnrc_nrfmin_send,
.recv = gnrc_nrfmin_recv,
.get = gnrc_netif2_get_from_netdev,
.set = gnrc_netif2_set_from_netdev,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
#endif
void gnrc_nrfmin_init(void)
{
/* setup the NRFMIN driver */
nrfmin_setup();
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_create(stack, sizeof(stack), NRFMIN_GNRC_THREAD_PRIO, "nrfmin",
(netdev_t *)&nrfmin_dev, &gnrc_nrfmin_ops);
#else
/* initialize the GNRC plug struct */
plug.send = gnrc_nrfmin_send;
plug.recv = gnrc_nrfmin_recv;
plug.dev = &nrfmin_dev;
gnrc_netdev_init(stack, sizeof(stack),
NRFMIN_GNRC_THREAD_PRIO,
"nrfmin", &plug);
#endif
gnrc_netif_create(stack, sizeof(stack), NRFMIN_GNRC_THREAD_PRIO, "nrfmin",
(netdev_t *)&nrfmin_dev, &gnrc_nrfmin_ops);
}

View File

@ -14,16 +14,16 @@
#include "net/gnrc.h"
#include "cc110x.h"
#include "cc110x-netdev.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif.h"
#include "od.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
static int _send(gnrc_netdev_t *gnrc_netdev, gnrc_pktsnip_t *pkt)
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
cc110x_pkt_t cc110x_pkt;
netdev_t *dev = gnrc_netdev->dev;
netdev_t *dev = netif->dev;
netdev_cc110x_t *netdev_cc110x = (netdev_cc110x_t *) dev;
cc110x_t *cc110x = &netdev_cc110x->cc110x;
@ -36,7 +36,7 @@ static int _send(gnrc_netdev_t *gnrc_netdev, gnrc_pktsnip_t *pkt)
payload = pkt->next;
if (pkt->type != GNRC_NETTYPE_NETIF) {
DEBUG("gnrc_netdev_cc110x: First header was not generic netif header\n");
DEBUG("gnrc_cc110x: First header was not generic netif header\n");
gnrc_pktbuf_release(pkt);
return -EBADMSG;
}
@ -82,7 +82,7 @@ static int _send(gnrc_netdev_t *gnrc_netdev, gnrc_pktsnip_t *pkt)
payload_len += payload->size;
if (payload_len > CC110X_MAX_DATA_LENGTH) {
DEBUG("gnrc_netdev_cc110x: payload length exceeds maximum"
DEBUG("gnrc_cc110x: payload length exceeds maximum"
"(%u>%u)\n", payload_len, CC110X_MAX_DATA_LENGTH);
gnrc_pktbuf_release(pkt);
return -EBADMSG;
@ -98,7 +98,7 @@ static int _send(gnrc_netdev_t *gnrc_netdev, gnrc_pktsnip_t *pkt)
cc110x_pkt.length = (uint8_t) payload_len + CC110X_HEADER_LENGTH;
DEBUG("gnrc_netdev_cc110x: sending packet from %u to %u with payload "
DEBUG("gnrc_cc110x: sending packet from %u to %u with payload "
"length %u\n",
(unsigned)cc110x_pkt.phy_src,
(unsigned)cc110x_pkt.address,
@ -107,9 +107,9 @@ static int _send(gnrc_netdev_t *gnrc_netdev, gnrc_pktsnip_t *pkt)
return dev->driver->send(dev, &vector, 1);
}
static gnrc_pktsnip_t *_recv(gnrc_netdev_t *gnrc_netdev)
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)
{
netdev_t *dev = gnrc_netdev->dev;
netdev_t *dev = netif->dev;
cc110x_t *cc110x = &((netdev_cc110x_t*) dev)->cc110x;
cc110x_pkt_t *cc110x_pkt = &cc110x->pkt_buf.packet;
@ -182,11 +182,16 @@ static gnrc_pktsnip_t *_recv(gnrc_netdev_t *gnrc_netdev)
return pkt;
}
int gnrc_netdev_cc110x_init(gnrc_netdev_t *gnrc_netdev, netdev_t *dev)
{
gnrc_netdev->send = _send;
gnrc_netdev->recv = _recv;
gnrc_netdev->dev = dev;
static const gnrc_netif_ops_t _cc110x_ops = {
.send = _send,
.recv = _recv,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
return 0;
gnrc_netif_t *gnrc_netif_cc110x_create(char *stack, int stacksize, char priority,
char *name, netdev_t *dev)
{
return gnrc_netif_create(stack, stacksize, priority, name, dev,
&_cc110x_ops);
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief CC110x adaption for @ref net_gnrc_netif
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef GNRC_NETIF_CC110X_H
#define GNRC_NETIF_CC110X_H
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
gnrc_netif_t *gnrc_netif_cc110x_create(char *stack, int stacksize, char priority,
char *name, netdev_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* GNRC_NETIF_CC110X_H */
/** @} */

189
drivers/xbee/gnrc_xbee.c Normal file
View File

@ -0,0 +1,189 @@
/*
* Copyright (C) 2016-17 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup net_gnrc_netif
* @{
*
* @file
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Martine Lenders <m.lenders@fu-berlin.de>
*
* @}
*/
#include "assert.h"
#include "xbee.h"
#include "net/gnrc.h"
#include "gnrc_netif_xbee.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define BCAST (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)
static gnrc_pktsnip_t *xbee_adpt_recv(gnrc_netif_t *netif)
{
netdev_t *dev = netif->dev;
int pktlen;
int xhdr_len;
gnrc_pktsnip_t *payload;
gnrc_pktsnip_t *netif_snip;
gnrc_pktsnip_t *xhdr_snip;
gnrc_netif_hdr_t *netif_hdr;
xbee_l2hdr_t l2hdr;
assert(dev);
/* see how much data there is to process */
pktlen = dev->driver->recv(dev, NULL, 0, NULL);
if (pktlen <= 0) {
DEBUG("[xbee-gnrc] recv: no data available to process\n");
return NULL;
}
/* allocate space for the packet in the pktbuf */
payload = gnrc_pktbuf_add(NULL, NULL, pktlen, XBEE_DEFAULT_PROTOCOL);
if (payload == NULL) {
DEBUG("[xbee-gnrc] recv: unable to allocate space in the pktbuf\n");
/* tell the driver to drop the packet */
dev->driver->recv(dev, NULL, 1, NULL);
return NULL;
}
/* copy the complete including the XBee header into the packet buffer */
dev->driver->recv(dev, payload->data, pktlen, NULL);
/* try to parse the L2 header data from the XBee header */
xhdr_len = xbee_parse_hdr((xbee_t *)dev, (uint8_t *)payload->data, &l2hdr);
if (xhdr_len < 0) {
DEBUG("[xbee-gnrc] recv: unable to parse XBee header\n");
gnrc_pktbuf_release(payload);
return NULL;
}
/* crop the XBee header from the payload */
xhdr_snip = gnrc_pktbuf_mark(payload, xhdr_len, GNRC_NETTYPE_UNDEF);
if (xhdr_snip == NULL) {
DEBUG("[xbee-gnrc] recv: unable to mark XBee header snip\n");
gnrc_pktbuf_release(payload);
return NULL;
}
gnrc_pktbuf_remove_snip(payload, xhdr_snip);
/* create a netif hdr from the obtained data */
netif_snip = gnrc_netif_hdr_build(l2hdr.src_addr, l2hdr.addr_len,
l2hdr.dst_addr, l2hdr.addr_len);
if (netif_snip == NULL) {
DEBUG("[xbee-gnrc] recv: unable to allocate netif header\n");
gnrc_pktbuf_release(payload);
return NULL;
}
netif_hdr = (gnrc_netif_hdr_t *)netif_snip->data;
netif_hdr->if_pid = netif->pid;
netif_hdr->rssi = l2hdr.rssi;
if (l2hdr.bcast) {
netif_hdr->flags = GNRC_NETIF_HDR_FLAGS_BROADCAST;
}
DEBUG("[xbee-gnrc] recv: successfully parsed packet\n");
/* and append the netif header */
LL_APPEND(payload, netif_snip);
return payload;
}
static int xbee_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
int res;
size_t size;
size_t count;
gnrc_pktsnip_t *vec;
gnrc_netif_hdr_t *hdr;
uint8_t xhdr[XBEE_MAX_TXHDR_LENGTH];
/* check device descriptor and packet */
assert(netif && pkt);
/* get the payload size and the dst address details */
size = gnrc_pkt_len(pkt->next);
DEBUG("[xbee-gnrc] send: payload of packet is %i\n", (int)size);
hdr = (gnrc_netif_hdr_t *)pkt->data;
if (hdr->flags & BCAST) {
uint16_t addr = 0xffff;
res = xbee_build_hdr((xbee_t *)netif, xhdr, size, &addr, 2);
DEBUG("[xbee-gnrc] send: preparing to send broadcast\n");
}
else {
uint8_t *addr = gnrc_netif_hdr_get_dst_addr(hdr);
res = xbee_build_hdr((xbee_t *)netif, xhdr, size, addr,
hdr->dst_l2addr_len);
if (res < 0) {
if (res == -EOVERFLOW) {
DEBUG("[xbee-gnrc] send: payload length exceeds max limit\n");
}
else if (res == -ENOMSG) {
DEBUG("[xbee-gnrc] send: invalid destination l2 address\n");
}
return res;
}
if (hdr->dst_l2addr_len == IEEE802154_SHORT_ADDRESS_LEN) {
DEBUG("[xbee-gnrc] send: preparing to send unicast to %02x:%02x\n",
(int)addr[0], (int)addr[1]);
}
else {
DEBUG("[xbee-gnrc] send: preparing to send unicast to "
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
(int)addr[0], (int)addr[1], (int)addr[2], (int)addr[3],
(int)addr[4], (int)addr[5], (int)addr[6], (int)addr[7]);
}
}
/* now let's extract the iovector and send out the stuff */
vec = gnrc_pktbuf_get_iovec(pkt, &count);
if (vec != NULL) {
pkt = vec;
struct iovec *vector = (struct iovec *)pkt->data;
vector[0].iov_base = xhdr;
vector[0].iov_len = res;
#ifdef MODULE_NETSTATS_L2
if (hdr->flags & BCAST) {
netif->dev->stats.tx_mcast_count++;
}
else {
netif->dev->stats.tx_unicast_count++;
}
#endif
DEBUG("[xbee-gnrc] send: triggering the drivers send function\n");
res = netif->dev->driver->send(netif->dev, vector, count);
}
else {
DEBUG("[xbee-gnrc] send: unable to create iovec\n");
}
gnrc_pktbuf_release(pkt);
return res;
}
static const gnrc_netif_ops_t _xbee_ops = {
.send = xbee_adpt_send,
.recv = xbee_adpt_recv,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
gnrc_netif_t *gnrc_netif_xbee_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
{
return gnrc_netif_create(stack, stacksize, priority, name,
dev, &_xbee_ops);
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief XBee adaption for @ref net_gnrc_netif
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef GNRC_NETIF_XBEE_H
#define GNRC_NETIF_XBEE_H
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
gnrc_netif_t *gnrc_netif_xbee_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* GNRC_NETIF_XBEE_H */
/** @} */

View File

@ -749,6 +749,10 @@ static int xbee_get(netdev_t *ndev, netopt_t opt, void *value, size_t max_len)
*((uint16_t *)value) = IEEE802154_SHORT_ADDRESS_LEN;
}
return sizeof(uint16_t);
case NETOPT_DEVICE_TYPE:
assert(max_len == sizeof(uint16_t));
*((uint16_t *)value) = NETDEV_TYPE_IEEE802154;
return sizeof(uint16_t);
case NETOPT_IPV6_IID:
if (max_len < sizeof(eui64_t)) {
return -EOVERFLOW;

View File

@ -46,10 +46,11 @@ int main(void)
ccnl_start();
/* get the default interface */
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
gnrc_netif_t *netif;
/* set the relay's PID, configure the interface to use CCN nettype */
if ((gnrc_netif_get(ifs) == 0) || (ccnl_open_netif(ifs[0], GNRC_NETTYPE_CCN) < 0)) {
if (((netif = gnrc_netif_iter(NULL)) == NULL) ||
(ccnl_open_netif(netif->pid, GNRC_NETTYPE_CCN) < 0)) {
puts("Error registering at network interface!");
return -1;
}

View File

@ -25,9 +25,12 @@
#include "net/gnrc.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/udp.h"
#include "net/gnrc/pktdump.h"
#include "timex.h"
#include "utlist.h"
#include "xtimer.h"
#define ENABLE_DEBUG (0)
@ -228,9 +231,15 @@ static int peer_verify_ecdsa_key(struct dtls_context_t *ctx,
*/
static int gnrc_sending(char *addr_str, char *data, size_t data_len )
{
int iface;
ipv6_addr_t addr;
gnrc_pktsnip_t *payload, *udp, *ip;
/* get interface, if available */
iface = ipv6_addr_split_iface(addr_str);
if ((iface < 0) && (gnrc_netif_numof() == 1)) {
iface = gnrc_netif_iter(NULL)->pid;
}
/* parse destination address */
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
puts("Error: unable to parse destination address");
@ -260,6 +269,13 @@ static int gnrc_sending(char *addr_str, char *data, size_t data_len )
gnrc_pktbuf_release(udp);
return -1;
}
/* add netif header, if interface was given */
if (iface > 0) {
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
((gnrc_netif_hdr_t *)netif->data)->if_pid = (kernel_pid_t)iface;
LL_PREPEND(ip, netif);
}
/*
* WARNING: Too fast and the nodes dies in middle of retransmissions.

View File

@ -26,8 +26,11 @@
#include "net/gnrc.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/udp.h"
#include "timex.h"
#include "utlist.h"
#include "xtimer.h"
#include "msg.h"
@ -142,10 +145,15 @@ static int read_from_peer(struct dtls_context_t *ctx,
*/
static int gnrc_sending(char *addr_str, char *data, size_t data_len, unsigned short rem_port )
{
int iface;
ipv6_addr_t addr;
gnrc_pktsnip_t *payload, *udp, *ip;
/* get interface, if available */
iface = ipv6_addr_split_iface(addr_str);
if ((iface < 0) && (gnrc_netif_numof() == 1)) {
iface = gnrc_netif_iter(NULL)->pid;
}
/* parse destination address */
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
puts("Error: unable to parse destination address");
@ -174,6 +182,13 @@ static int gnrc_sending(char *addr_str, char *data, size_t data_len, unsigned sh
gnrc_pktbuf_release(udp);
return -1;
}
/* add netif header, if interface was given */
if (iface > 0) {
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
((gnrc_netif_hdr_t *)netif->data)->if_pid = (kernel_pid_t)iface;
LL_PREPEND(ip, netif);
}
/* send packet */
DEBUG("DBG-Server: Sending record to peer\n");

View File

@ -13,7 +13,7 @@ BOARD_INSUFFICIENT_MEMORY := airfy-beacon b-l072z-lrwan1 bluepill calliope-mini
nucleo32-f031 nucleo32-f042 nucleo32-f303 nucleo32-l031 \
nucleo-f030 nucleo-f070 nucleo-f072 nucleo-f103 nucleo-f302 \
nucleo-f334 nucleo-l053 nucleo-l073 opencm904 pca10000 \
pca10005 spark-core stm32f0discovery telosb wsn430-v1_3b \
pca10005 spark-core stm32f0discovery telosb weio wsn430-v1_3b \
wsn430-v1_4 yunjia-nrf51822 z1
BOARD_BLACKLIST += mips-malta pic32-wifire pic32-clicker# No full UART available.
@ -22,7 +22,7 @@ BOARD_BLACKLIST += mips-malta pic32-wifire pic32-clicker# No full UART available
# UART, but not on native, as native has a tap interface towards the host.
ifeq (,$(filter native,$(BOARD)))
GNRC_NETIF_NUMOF := 2
USEMODULE += ethos gnrc_netdev
USEMODULE += ethos
# ethos baudrate can be configured from make command
ETHOS_BAUDRATE ?= 115200

View File

@ -20,13 +20,13 @@ USEMODULE += gnrc_netdev_default
USEMODULE += auto_init_gnrc_netif
# Specify the minimum networking modules for IPv6
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_ndp
# Additional networking modules that can be dropped if not needed
USEMODULE += gnrc_icmpv6_echo
# Use minimal standard PRNG
USEMODULE += prng_minstd
CFLAGS += -DGNRC_PKTBUF_SIZE=512 -DGNRC_IPV6_NETIF_ADDR_NUMOF=4 -DGNRC_IPV6_NC_SIZE=1
CFLAGS += -DGNRC_PKTBUF_SIZE=512 -DGNRC_NETIF_IPV6_ADDRS_NUMOF=2 \
-DGNRC_NETIF_IPV6_GROUPS_NUMOF=2 -DGNRC_IPV6_NC_SIZE=1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

View File

@ -22,25 +22,29 @@
#include "msg.h"
#include "net/ipv6/addr.h"
#include "net/gnrc.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/ipv6/netif.h"
int main(void)
{
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
puts("RIOT network stack example application");
/* get the first IPv6 interface and prints its address */
size_t numof = gnrc_netif_get(ifs);
if (numof > 0) {
gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(ifs[0]);
for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
if ((ipv6_addr_is_link_local(&entry->addrs[i].addr)) && !(entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST)) {
char ipv6_addr[IPV6_ADDR_MAX_STR_LEN];
ipv6_addr_to_str(ipv6_addr, &entry->addrs[i].addr, IPV6_ADDR_MAX_STR_LEN);
printf("My address is %s\n", ipv6_addr);
}
/* get interfaces and print their addresses */
gnrc_netif_t *netif = NULL;
while ((netif = gnrc_netif_iter(netif))) {
ipv6_addr_t ipv6_addrs[GNRC_NETIF_IPV6_ADDRS_NUMOF];
int res = gnrc_netapi_get(netif->pid, NETOPT_IPV6_ADDR, 0, ipv6_addrs,
sizeof(ipv6_addrs));
if (res < 0) {
continue;
}
for (unsigned i = 0; i < (unsigned)(res / sizeof(ipv6_addr_t)); i++) {
char ipv6_addr[IPV6_ADDR_MAX_STR_LEN];
ipv6_addr_to_str(ipv6_addr, &ipv6_addrs[i], IPV6_ADDR_MAX_STR_LEN);
printf("My address is %s\n", ipv6_addr);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Freie Universität Berlin
* Copyright (C) 2015-17 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -14,6 +14,7 @@
* @brief Demonstrating the sending and receiving of UDP data
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Martine Lenders <m.lenders@fu-berlin.de>
*
* @}
*/
@ -23,9 +24,12 @@
#include "net/gnrc.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/udp.h"
#include "net/gnrc/pktdump.h"
#include "timex.h"
#include "utlist.h"
#include "xtimer.h"
static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL,
@ -35,9 +39,15 @@ static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX
static void send(char *addr_str, char *port_str, char *data, unsigned int num,
unsigned int delay)
{
int iface;
uint16_t port;
ipv6_addr_t addr;
/* get interface, if available */
iface = ipv6_addr_split_iface(addr_str);
if ((iface < 0) && (gnrc_netif_numof() == 1)) {
iface = gnrc_netif_iter(NULL)->pid;
}
/* parse destination address */
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
puts("Error: unable to parse destination address");
@ -75,6 +85,13 @@ static void send(char *addr_str, char *port_str, char *data, unsigned int num,
gnrc_pktbuf_release(udp);
return;
}
/* add netif header, if interface was given */
if (iface > 0) {
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
((gnrc_netif_hdr_t *)netif->data)->if_pid = (kernel_pid_t)iface;
LL_PREPEND(ip, netif);
}
/* send packet */
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) {
puts("Error: unable to locate UDP thread");

View File

@ -23,9 +23,12 @@
#include "net/gnrc.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/udp.h"
#include "net/gnrc/pktdump.h"
#include "timex.h"
#include "utlist.h"
#include "xtimer.h"
static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL,
@ -35,9 +38,15 @@ static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX
static void send(char *addr_str, char *port_str, char *data, unsigned int num,
unsigned int delay)
{
int iface;
uint16_t port;
ipv6_addr_t addr;
/* get interface, if available */
iface = ipv6_addr_split_iface(addr_str);
if ((iface < 0) && (gnrc_netif_numof() == 1)) {
iface = gnrc_netif_iter(NULL)->pid;
}
/* parse destination address */
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
puts("Error: unable to parse destination address");
@ -75,6 +84,13 @@ static void send(char *addr_str, char *port_str, char *data, unsigned int num,
gnrc_pktbuf_release(udp);
return;
}
/* add netif header, if interface was given */
if (iface > 0) {
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
((gnrc_netif_hdr_t *)netif->data)->if_pid = (kernel_pid_t)iface;
LL_PREPEND(ip, netif);
}
/* send packet */
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) {
puts("Error: unable to locate UDP thread");

View File

@ -7,8 +7,8 @@ BOARD ?= native
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
BOARD_INSUFFICIENT_MEMORY := airfy-beacon calliope-mini chronos microbit msb-430 \
msb-430h nrf51dongle nrf6310 nucleo32-f031 \
BOARD_INSUFFICIENT_MEMORY := airfy-beacon bluepill calliope-mini chronos \
microbit msb-430 msb-430h nrf51dongle nrf6310 nucleo32-f031 \
nucleo32-f042 nucleo32-f303 nucleo32-l031 nucleo-f030 \
nucleo-f070 nucleo-f072 nucleo-f103 nucleo-f302 nucleo-f334 \
nucleo-l053 spark-core stm32f0discovery \

View File

@ -9,7 +9,7 @@ RIOTBASE ?= $(CURDIR)/../..
BOARD_INSUFFICIENT_MEMORY := chronos msb-430 msb-430h nucleo32-f031 nucleo32-f042 \
nucleo32-l031 nucleo-f030 nucleo-l053 stm32f0discovery \
telosb
telosb z1
# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present

View File

@ -30,7 +30,7 @@
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
/* import "ifconfig" shell command, used for printing addresses */
extern int _netif_config(int argc, char **argv);
extern int _gnrc_netif_config(int argc, char **argv);
int main(void)
{
@ -44,7 +44,7 @@ int main(void)
/* print network addresses */
puts("Configured network interfaces:");
_netif_config(0, NULL);
_gnrc_netif_config(0, NULL);
/* initialize nanocoap server instance */
uint8_t buf[COAP_INBUF_SIZE];

View File

@ -35,6 +35,7 @@
* @brief Glue for Nordic's SoftDevice BLE 6lowpan blob to netapi
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Martine Lenders <m.lenders@fu-berlin.de>
* @}
*/
@ -45,6 +46,7 @@
#include "thread.h"
#include "net/gnrc.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/nettype.h"
#include "ble-core.h"
@ -59,13 +61,11 @@
#include "od.h"
#endif
#define BLE_NETAPI_MSG_QUEUE_SIZE (8U)
#define BLE_PRIO (THREAD_PRIORITY_MAIN - 1)
#define BLE_PRIO (GNRC_NETIF_PRIO)
kernel_pid_t gnrc_nordic_ble_6lowpan_pid;
static char _stack[(THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)];
static uint8_t _own_mac_addr[BLE_SIXLOWPAN_L2_ADDR_LEN];
static gnrc_netif_t *_ble_netif = NULL;
static uint8_t _sendbuf[BLE_SIXLOWPAN_MTU];
@ -73,7 +73,7 @@ static void _ble_mac_callback(ble_mac_event_enum_t event, void* arg)
{
msg_t m = { .type=event, .content.ptr=arg };
if (!msg_send_int(&m, gnrc_nordic_ble_6lowpan_pid)) {
if ((_ble_netif != NULL) || !msg_send_int(&m, _ble_netif->pid)) {
puts("_ble_mac_callback(): possibly lost interrupt");
}
}
@ -103,8 +103,8 @@ static void _handle_raw_sixlowpan(ble_mac_inbuf_t *inbuf)
gnrc_netif_hdr_init(netif_hdr->data, BLE_SIXLOWPAN_L2_ADDR_LEN, BLE_SIXLOWPAN_L2_ADDR_LEN);
gnrc_netif_hdr_set_src_addr(netif_hdr->data, inbuf->src, BLE_SIXLOWPAN_L2_ADDR_LEN);
gnrc_netif_hdr_set_dst_addr(netif_hdr->data, _own_mac_addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = gnrc_nordic_ble_6lowpan_pid;
gnrc_netif_hdr_set_dst_addr(netif_hdr->data, _ble_netif->l2addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = _ble_netif->pid;
DEBUG("_handle_raw_sixlowpan(): received packet from %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
"of length %d\n",
@ -188,7 +188,7 @@ static int _handle_get(gnrc_netapi_opt_t *_opt)
break;
case NETOPT_ADDRESS_LONG:
assert(_opt->data_len >= BLE_SIXLOWPAN_L2_ADDR_LEN);
memcpy(value, _own_mac_addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
memcpy(value, _ble_netif->l2addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
value[0] = IPV6_IID_FLIP_VALUE;
res = BLE_SIXLOWPAN_L2_ADDR_LEN;
break;
@ -211,7 +211,7 @@ static int _handle_get(gnrc_netapi_opt_t *_opt)
res = sizeof(uint16_t);
break;*/
case NETOPT_IPV6_IID:
memcpy(value, _own_mac_addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
memcpy(value, _ble_netif->l2addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
value[0] = IPV6_IID_FLIP_VALUE;
res = BLE_SIXLOWPAN_L2_ADDR_LEN;
break;
@ -221,97 +221,69 @@ static int _handle_get(gnrc_netapi_opt_t *_opt)
return res;
}
/**
* @brief Startup code and event loop of the gnrc_nordic_ble_6lowpan layer
*
* @return never returns
*/
static void *_gnrc_nordic_ble_6lowpan_thread(void *args)
static void _netif_init(gnrc_netif_t *netif)
{
(void)args;
DEBUG("gnrc_nordic_ble_6lowpan: starting thread\n");
gnrc_nordic_ble_6lowpan_pid = thread_getpid();
gnrc_netapi_opt_t *opt;
int res;
msg_t msg, reply, msg_queue[BLE_NETAPI_MSG_QUEUE_SIZE];
/* setup the message queue */
msg_init_queue(msg_queue, BLE_NETAPI_MSG_QUEUE_SIZE);
/* initialize BLE stack */
assert((unsigned)softdevice_handler_isEnabled());
ble_stack_init();
ble_get_mac(_own_mac_addr);
ble_mac_init(_ble_mac_callback);
netif->l2addr_len = BLE_SIXLOWPAN_L2_ADDR_LEN;
ble_get_mac(netif->l2addr);
ble_advertising_init("RIOT BLE");
ble_advertising_start();
}
/* register the device to the network stack*/
gnrc_netif_add(thread_getpid());
static int _netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
(void)netif;
assert(netif != _ble_netif);
return _send(pkt);
}
/* start the event loop */
while (1) {
// DEBUG("gnrc_nordic_ble_6lowpan: waiting for incoming messages\n");
msg_receive(&msg);
/* dispatch NETDEV and NETAPI messages */
switch (msg.type) {
case BLE_EVENT_RX_DONE:
{
DEBUG("ble rx:\n");
_handle_raw_sixlowpan(msg.content.ptr);
ble_mac_busy_rx = 0;
break;
}
case GNRC_NETAPI_MSG_TYPE_SND:
DEBUG("gnrc_nordic_ble_6lowpan: GNRC_NETAPI_MSG_TYPE_SND received\n");
_send(msg.content.ptr);
break;
case GNRC_NETAPI_MSG_TYPE_SET:
/* read incoming options */
opt = msg.content.ptr;
DEBUG("gnrc_nordic_ble_6lowpan: GNRC_NETAPI_MSG_TYPE_SET received. opt=%s\n",
netopt2str(opt->opt));
/* set option for device driver */
res = ENOTSUP;
DEBUG("gnrc_nordic_ble_6lowpan: response of netdev->set: %i\n", res);
/* send reply to calling thread */
reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
reply.content.value = (uint32_t)res;
msg_reply(&msg, &reply);
break;
case GNRC_NETAPI_MSG_TYPE_GET:
/* read incoming options */
opt = msg.content.ptr;
DEBUG("gnrc_nordic_ble_6lowpan: GNRC_NETAPI_MSG_TYPE_GET received. opt=%s\n",
netopt2str(opt->opt));
res = _handle_get(opt);
DEBUG("gnrc_nordic_ble_6lowpan: response of netdev->get: %i\n", res);
/* send reply to calling thread */
reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
reply.content.value = (uint32_t)res;
msg_reply(&msg, &reply);
break;
default:
DEBUG("gnrc_nordic_ble_6lowpan: Unknown command %" PRIu16 "\n", msg.type);
break;
}
}
/* never reached */
static gnrc_pktsnip_t *_netif_recv(gnrc_netif_t *netif)
{
(void)netif;
/* not supported */
return NULL;
}
static int _netif_get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt)
{
(void)netif;
assert(netif != _ble_netif);
return _handle_get(opt);
}
static int _netif_set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt)
{
(void)netif;
(void)opt;
/* not supported */
return -ENOTSUP;
}
static void _netif_msg_handler(gnrc_netif_t *netif, msg_t *msg)
{
switch (msg->type) {
case BLE_EVENT_RX_DONE:
{
DEBUG("ble rx:\n");
_handle_raw_sixlowpan(msg->content.ptr);
ble_mac_busy_rx = 0;
break;
}
}
}
static const gnrc_netif_ops_t _ble_ops = {
.init = _netif_init,
.send = _netif_send,
.recv = _netif_recv,
.get = _netif_get,
.set = _netif_set,
.msg_handler = _netif_msg_handler,
};
void gnrc_nordic_ble_6lowpan_init(void)
{
kernel_pid_t res = thread_create(_stack, sizeof(_stack), BLE_PRIO,
THREAD_CREATE_STACKTEST,
_gnrc_nordic_ble_6lowpan_thread, NULL,
"ble");
assert(res > 0);
(void)res;
_ble_netif = gnrc_netif_create(_stack, sizeof(_stack), BLE_PRIO,
"ble", NULL, &_ble_ops);
}

View File

@ -40,10 +40,6 @@
#include "net/gnrc/ipv6.h"
#endif
#ifdef MODULE_GNRC_IPV6_NETIF
#include "net/gnrc/ipv6/netif.h"
#endif
#ifdef MODULE_L2_PING
#include "l2_ping.h"
#endif
@ -236,10 +232,6 @@ void auto_init(void)
#endif /* MODULE_AUTO_INIT_GNRC_NETIF */
#ifdef MODULE_GNRC_IPV6_NETIF
gnrc_ipv6_netif_init_by_dev();
#endif
#ifdef MODULE_GNRC_UHCPC
extern void auto_init_gnrc_uhcpc(void);
auto_init_gnrc_uhcpc();

View File

@ -21,12 +21,7 @@
#include "log.h"
#include "board.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ieee802154.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/ieee802154.h"
#endif
#include "net/gnrc/netif/ieee802154.h"
#include "net/gnrc/lwmac/lwmac.h"
#include "net/gnrc.h"
@ -39,19 +34,12 @@
*/
#define AT86RF2XX_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef AT86RF2XX_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define AT86RF2XX_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define AT86RF2XX_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define AT86RF2XX_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
#define AT86RF2XX_NUM (sizeof(at86rf2xx_params) / sizeof(at86rf2xx_params[0]))
static at86rf2xx_t at86rf2xx_devs[AT86RF2XX_NUM];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt[AT86RF2XX_NUM];
#endif
static char _at86rf2xx_stacks[AT86RF2XX_NUM][AT86RF2XX_MAC_STACKSIZE];
void auto_init_at86rf2xx(void)
@ -60,33 +48,16 @@ void auto_init_at86rf2xx(void)
LOG_DEBUG("[auto_init_netif] initializing at86rf2xx #%u\n", i);
at86rf2xx_setup(&at86rf2xx_devs[i], &at86rf2xx_params[i]);
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ieee802154_create(_at86rf2xx_stacks[i],
AT86RF2XX_MAC_STACKSIZE,
AT86RF2XX_MAC_PRIO, "at86rf2xx",
(netdev_t *)&at86rf2xx_devs[i]);
#else
int res = gnrc_netdev_ieee802154_init(&gnrc_adpt[i],
(netdev_ieee802154_t *)&at86rf2xx_devs[i]);
if (res < 0) {
LOG_ERROR("[auto_init_netif] error initializing at86rf2xx radio #%u\n", i);
}
else {
#ifdef MODULE_GNRC_LWMAC
gnrc_lwmac_init(_at86rf2xx_stacks[i],
AT86RF2XX_MAC_STACKSIZE,
AT86RF2XX_MAC_PRIO,
"at86rf2xx-lwmac",
&gnrc_adpt[i]);
gnrc_netif_lwmac_create(_at86rf2xx_stacks[i],
AT86RF2XX_MAC_STACKSIZE,
AT86RF2XX_MAC_PRIO, "at86rf2xx-lwmac",
(netdev_t *)&at86rf2xx_devs[i]);
#else
gnrc_netdev_init(_at86rf2xx_stacks[i],
AT86RF2XX_MAC_STACKSIZE,
AT86RF2XX_MAC_PRIO,
"at86rf2xx",
&gnrc_adpt[i]);
#endif
}
gnrc_netif_ieee802154_create(_at86rf2xx_stacks[i],
AT86RF2XX_MAC_STACKSIZE,
AT86RF2XX_MAC_PRIO, "at86rf2xx",
(netdev_t *)&at86rf2xx_devs[i]);
#endif
}
}

View File

@ -22,8 +22,8 @@
#include "log.h"
#include "debug.h"
#include "board.h"
#include "net/gnrc/netdev.h"
#include "gnrc_netdev_cc110x.h"
#include "gnrc_netif_cc110x.h"
#include "cc110x-netdev.h"
#include "net/gnrc.h"
#include "cc110x.h"
@ -35,7 +35,7 @@
*/
#define CC110X_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)
#ifndef CC110X_MAC_PRIO
#define CC110X_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#define CC110X_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
#define CC110X_NUM (sizeof(cc110x_params)/sizeof(cc110x_params[0]))
@ -43,8 +43,6 @@
static netdev_cc110x_t cc110x_devs[CC110X_NUM];
static char _stacks[CC110X_NUM][CC110X_MAC_STACKSIZE];
static gnrc_netdev_t _gnrc_netdev_devs[CC110X_NUM];
void auto_init_cc110x(void)
{
for (unsigned i = 0; i < CC110X_NUM; i++) {
@ -57,12 +55,9 @@ void auto_init_cc110x(void)
LOG_ERROR("[auto_init_netif] error initializing cc110x #%u\n", i);
}
else {
gnrc_netdev_cc110x_init(&_gnrc_netdev_devs[i], &cc110x_devs[i]);
res = gnrc_netdev_init(_stacks[i], CC110X_MAC_STACKSIZE,
CC110X_MAC_PRIO, "cc110x", &_gnrc_netdev_devs[i]);
if (res < 0) {
LOG_ERROR("[auto_init_netif] error starting gnrc_cc110x thread\n");
}
gnrc_netif_cc110x_create(_stacks[i], CC110X_MAC_STACKSIZE,
CC110X_MAC_PRIO, "cc110x",
(netdev_t *)&cc110x_devs[i]);
}
}
}

View File

@ -23,12 +23,7 @@
#include "log.h"
#include "board.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ieee802154.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/ieee802154.h"
#endif
#include "net/gnrc/netif/ieee802154.h"
#include "net/gnrc.h"
#include "cc2420.h"
@ -40,11 +35,7 @@
*/
#define CC2420_MAC_STACKSIZE (THREAD_STACKSIZE_MAIN)
#ifndef CC2420_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define CC2420_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define CC2420_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define CC2420_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
/** @} */
@ -58,9 +49,6 @@
* @{
*/
static cc2420_t cc2420_devs[CC2420_NUMOF];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt[CC2420_NUMOF];
#endif
static char _cc2420_stacks[CC2420_NUMOF][CC2420_MAC_STACKSIZE];
/** @} */
@ -70,24 +58,9 @@ void auto_init_cc2420(void)
LOG_DEBUG("[auto_init_netif] initializing cc2420 #%u\n", i);
cc2420_setup(&cc2420_devs[i], &cc2420_params[i]);
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ieee802154_create(_cc2420_stacks[i], CC2420_MAC_STACKSIZE,
CC2420_MAC_PRIO, "cc2420",
(netdev_t *)&cc2420_devs[i]);
#else
int res = gnrc_netdev_ieee802154_init(&gnrc_adpt[i],
(netdev_ieee802154_t *)&cc2420_devs[i]);
if (res < 0) {
LOG_ERROR("[auto_init_netif] error initializing cc2420 #%u\n", i);
}
else {
gnrc_netdev_init(_cc2420_stacks[i],
CC2420_MAC_STACKSIZE,
CC2420_MAC_PRIO,
"cc2420", &gnrc_adpt[i]);
}
#endif
gnrc_netif_ieee802154_create(_cc2420_stacks[i], CC2420_MAC_STACKSIZE,
CC2420_MAC_PRIO, "cc2420",
(netdev_t *)&cc2420_devs[i]);
}
}

View File

@ -20,12 +20,7 @@
#ifdef MODULE_CC2538_RF
#include "log.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ieee802154.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/ieee802154.h"
#endif
#include "net/gnrc/netif/ieee802154.h"
#include "cc2538_rf.h"
@ -35,17 +30,10 @@
*/
#define CC2538_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef CC2538_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define CC2538_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define CC2538_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define CC2538_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
static cc2538_rf_t cc2538_rf_dev;
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt;
#endif
static char _cc2538_rf_stack[CC2538_MAC_STACKSIZE];
void auto_init_cc2538_rf(void)
@ -53,28 +41,10 @@ void auto_init_cc2538_rf(void)
LOG_DEBUG("[auto_init_netif] initializing cc2538 radio\n");
cc2538_setup(&cc2538_rf_dev);
#ifdef MODULE_GNRC_NETIF2
if (!gnrc_netif2_ieee802154_create(_cc2538_rf_stack,
CC2538_MAC_STACKSIZE,
CC2538_MAC_PRIO, "cc2538_rf",
(netdev_t *)&cc2538_rf_dev)) {
LOG_ERROR("[auto_init_netif] error initializing cc2538 radio\n");
}
#else
int res = gnrc_netdev_ieee802154_init(&gnrc_adpt,
(netdev_ieee802154_t *)&cc2538_rf_dev);
if (res < 0) {
LOG_ERROR("[auto_init_netif] error initializing cc2538 radio\n");
}
else {
gnrc_netdev_init(_cc2538_rf_stack,
CC2538_MAC_STACKSIZE,
CC2538_MAC_PRIO,
"cc2538_rf",
&gnrc_adpt);
}
#endif
gnrc_netif_ieee802154_create(_cc2538_rf_stack,
CC2538_MAC_STACKSIZE,
CC2538_MAC_PRIO, "cc2538_rf",
(netdev_t *)&cc2538_rf_dev);
}
#else

View File

@ -24,12 +24,7 @@
#include "log.h"
#include "enc28j60.h"
#include "enc28j60_params.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ethernet.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/eth.h"
#endif
#include "net/gnrc/netif/ethernet.h"
/**
* @brief Define stack parameters for the MAC layer thread
@ -37,11 +32,7 @@
*/
#define ENC28J60_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef ENC28J60_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define ENC28J60_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define ENC28J60_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define ENC28J60_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
/*** @} */
@ -55,9 +46,6 @@
* @{
*/
static enc28j60_t dev[ENC28J60_NUM];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt[ENC28J60_NUM];
#endif
/** @} */
/**
@ -73,17 +61,9 @@ void auto_init_enc28j60(void)
/* setup netdev device */
enc28j60_setup(&dev[i], &enc28j60_params[i]);
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ethernet_create(stack[i], ENC28J60_MAC_STACKSIZE,
ENC28J60_MAC_PRIO, "enc28j60",
(netdev_t *)&dev[i]);
#else
/* initialize netdev <-> gnrc adapter state */
gnrc_netdev_eth_init(&gnrc_adpt[i], (netdev_t *)&dev[i]);
/* start gnrc netdev thread */
gnrc_netdev_init(stack[i], ENC28J60_MAC_STACKSIZE, ENC28J60_MAC_PRIO,
"gnrc_enc28j60", &gnrc_adpt[i]);
#endif
gnrc_netif_ethernet_create(stack[i], ENC28J60_MAC_STACKSIZE,
ENC28J60_MAC_PRIO, "enc28j60",
(netdev_t *)&dev[i]);
}
}

View File

@ -22,12 +22,7 @@
#include "log.h"
#include "debug.h"
#include "encx24j600.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ethernet.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/eth.h"
#endif
#include "net/gnrc/netif/ethernet.h"
static encx24j600_t encx24j600;
@ -37,20 +32,13 @@ static encx24j600_t encx24j600;
*/
#define ENCX24J600_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)
#ifndef ENCX24J600_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define ENCX24J600_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define ENCX24J600_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define ENCX24J600_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
/**
* @brief Stacks for the MAC layer threads
*/
static char _netdev_eth_stack[ENCX24J600_MAC_STACKSIZE];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t _gnrc_encx24j600;
#endif
void auto_init_encx24j600(void)
{
@ -64,18 +52,9 @@ void auto_init_encx24j600(void)
encx24j600_setup(&encx24j600, &p);
/* initialize netdev<->gnrc adapter state */
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ethernet_create(_netdev_eth_stack, ENCX24J600_MAC_STACKSIZE,
ENCX24J600_MAC_PRIO, "encx24j600",
(netdev_t *)&encx24j600);
#else
gnrc_netdev_eth_init(&_gnrc_encx24j600, (netdev_t*)&encx24j600);
/* start gnrc netdev thread */
gnrc_netdev_init(_netdev_eth_stack, ENCX24J600_MAC_STACKSIZE,
ENCX24J600_MAC_PRIO, "gnrc_encx24j600",
&_gnrc_encx24j600);
#endif
gnrc_netif_ethernet_create(_netdev_eth_stack, ENCX24J600_MAC_STACKSIZE,
ENCX24J600_MAC_PRIO, "encx24j600",
(netdev_t *)&encx24j600);
}
#else

View File

@ -23,12 +23,7 @@
#include "debug.h"
#include "ethos.h"
#include "periph/uart.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ethernet.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/eth.h"
#endif
#include "net/gnrc/netif/ethernet.h"
/**
* @brief global ethos object, used by uart_stdio
@ -41,20 +36,13 @@ ethos_t ethos;
*/
#define ETHOS_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)
#ifndef ETHOS_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define ETHOS_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define ETHOS_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define ETHOS_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
/**
* @brief Stacks for the MAC layer threads
*/
static char _netdev_eth_stack[ETHOS_MAC_STACKSIZE];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t _gnrc_ethos;
#endif
static uint8_t _inbuf[2048];
@ -71,16 +59,8 @@ void auto_init_ethos(void)
ethos_setup(&ethos, &p);
/* initialize netdev<->gnrc adapter state */
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ethernet_create(_netdev_eth_stack, ETHOS_MAC_STACKSIZE,
ETHOS_MAC_PRIO, "ethos", (netdev_t *)&ethos);
#else
gnrc_netdev_eth_init(&_gnrc_ethos, (netdev_t*)&ethos);
/* start gnrc netdev thread */
gnrc_netdev_init(_netdev_eth_stack, ETHOS_MAC_STACKSIZE, ETHOS_MAC_PRIO,
"gnrc_ethos", &_gnrc_ethos);
#endif
gnrc_netif_ethernet_create(_netdev_eth_stack, ETHOS_MAC_STACKSIZE,
ETHOS_MAC_PRIO, "ethos", (netdev_t *)&ethos);
}
#else

View File

@ -24,12 +24,7 @@
#include "log.h"
#include "board.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ieee802154.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/ieee802154.h"
#endif
#include "net/gnrc/netif/ieee802154.h"
#include "net/gnrc.h"
#include "kw2xrf.h"
@ -41,19 +36,12 @@
*/
#define KW2XRF_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef KW2XRF_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define KW2XRF_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define KW2XRF_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define KW2XRF_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
#define KW2XRF_NUM (sizeof(kw2xrf_params)/sizeof(kw2xrf_params[0]))
static kw2xrf_t kw2xrf_devs[KW2XRF_NUM];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt[KW2XRF_NUM];
#endif
static char _kw2xrf_stacks[KW2XRF_NUM][KW2XRF_MAC_STACKSIZE];
void auto_init_kw2xrf(void)
@ -63,19 +51,9 @@ void auto_init_kw2xrf(void)
LOG_DEBUG("[auto_init_netif] initializing kw2xrf #%u\n", i);
kw2xrf_setup(&kw2xrf_devs[i], (kw2xrf_params_t*) p);
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ieee802154_create(_kw2xrf_stacks[i], KW2XRF_MAC_STACKSIZE,
KW2XRF_MAC_PRIO, "kw2xrf",
(netdev_t *)&kw2xrf_devs[i]);
#else
if (gnrc_netdev_ieee802154_init(&gnrc_adpt[i], (netdev_ieee802154_t *)&kw2xrf_devs[i]) < 0) {
LOG_ERROR("[auto_init_netif] error, initializing kw2xrf #%u\n", i);
}
else {
gnrc_netdev_init(_kw2xrf_stacks[i], KW2XRF_MAC_STACKSIZE,
KW2XRF_MAC_PRIO, "kw2xrf", &gnrc_adpt[i]);
}
#endif
gnrc_netif_ieee802154_create(_kw2xrf_stacks[i], KW2XRF_MAC_STACKSIZE,
KW2XRF_MAC_PRIO, "kw2xrf",
(netdev_t *)&kw2xrf_devs[i]);
}
}
#else

View File

@ -21,12 +21,7 @@
#include "log.h"
#include "board.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ieee802154.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/ieee802154.h"
#endif
#include "net/gnrc/netif/ieee802154.h"
#include "net/gnrc.h"
#include "mrf24j40.h"
@ -38,19 +33,12 @@
*/
#define MRF24J40_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef MRF24J40_MAC_PRIO
#ifdef MODULE_GNRC_NETIF2
#define MRF24J40_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define MRF24J40_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#endif
#define MRF24J40_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
#define MRF24J40_NUM (sizeof(mrf24j40_params) / sizeof(mrf24j40_params[0]))
static mrf24j40_t mrf24j40_devs[MRF24J40_NUM];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt[MRF24J40_NUM];
#endif
static char _mrf24j40_stacks[MRF24J40_NUM][MRF24J40_MAC_STACKSIZE];
void auto_init_mrf24j40(void)
@ -59,26 +47,10 @@ void auto_init_mrf24j40(void)
LOG_DEBUG("[auto_init_netif] initializing mrf24j40 #%u\n", i);
mrf24j40_setup(&mrf24j40_devs[i], &mrf24j40_params[i]);
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ieee802154_create(_mrf24j40_stacks[i],
MRF24J40_MAC_STACKSIZE, MRF24J40_MAC_PRIO,
"mrf24j40",
(netdev_t *)&mrf24j40_devs[i]);
#else
int res = gnrc_netdev_ieee802154_init(&gnrc_adpt[i],
(netdev_ieee802154_t *)&mrf24j40_devs[i]);
if (res < 0) {
LOG_ERROR("[auto_init_netif] error initializing mrf24j40 #%u\n", i);
}
else {
gnrc_netdev_init(_mrf24j40_stacks[i],
MRF24J40_MAC_STACKSIZE,
MRF24J40_MAC_PRIO,
"mrf24j40",
&gnrc_adpt[i]);
}
#endif
gnrc_netif_ieee802154_create(_mrf24j40_stacks[i],
MRF24J40_MAC_STACKSIZE, MRF24J40_MAC_PRIO,
"mrf24j40",
(netdev_t *)&mrf24j40_devs[i]);
}
}
#else

View File

@ -22,24 +22,13 @@
#include "log.h"
#include "debug.h"
#include "netdev_tap_params.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ethernet.h"
#else
#include "net/gnrc/netdev/eth.h"
#endif
#include "net/gnrc/netif/ethernet.h"
#define TAP_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)
#ifdef MODULE_GNRC_NETIF2
#define TAP_MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define TAP_MAC_PRIO (THREAD_PRIORITY_MAIN - 3)
#endif
#define TAP_MAC_PRIO (GNRC_NETIF_PRIO)
static netdev_tap_t netdev_tap[NETDEV_TAP_MAX];
static char _netdev_eth_stack[NETDEV_TAP_MAX][TAP_MAC_STACKSIZE + DEBUG_EXTRA_STACKSIZE];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t _gnrc_netdev_tap[NETDEV_TAP_MAX];
#endif
void auto_init_netdev_tap(void)
{
@ -50,17 +39,9 @@ void auto_init_netdev_tap(void)
i, *(p->tap_name));
netdev_tap_setup(&netdev_tap[i], p);
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ethernet_create(_netdev_eth_stack[i], TAP_MAC_STACKSIZE,
TAP_MAC_PRIO, "gnrc_netdev_tap",
&netdev_tap[i].netdev);
#else
gnrc_netdev_eth_init(&_gnrc_netdev_tap[i], (netdev_t*)&netdev_tap[i]);
gnrc_netdev_init(_netdev_eth_stack[i], TAP_MAC_STACKSIZE,
TAP_MAC_PRIO, "gnrc_netdev_tap",
&_gnrc_netdev_tap[i]);
#endif
gnrc_netif_ethernet_create(_netdev_eth_stack[i], TAP_MAC_STACKSIZE,
TAP_MAC_PRIO, "gnrc_netdev_tap",
&netdev_tap[i].netdev);
}
}

View File

@ -21,8 +21,7 @@
#include "log.h"
#include "board.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/raw.h"
#include "net/gnrc/netif/raw.h"
#include "net/gnrc.h"
#include "slipdev.h"
@ -36,11 +35,10 @@
*/
#define SLIPDEV_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef SLIPDEV_PRIO
#define SLIPDEV_PRIO (GNRC_NETDEV_MAC_PRIO)
#define SLIPDEV_PRIO (GNRC_NETIF_PRIO)
#endif
static slipdev_t slipdevs[SLIPDEV_NUM];
static gnrc_netdev_t gnrc_adpt[SLIPDEV_NUM];
static char _slipdev_stacks[SLIPDEV_NUM][SLIPDEV_STACKSIZE];
void auto_init_slipdev(void)
@ -51,16 +49,9 @@ void auto_init_slipdev(void)
LOG_DEBUG("[auto_init_netif] initializing slip #%u\n", i);
slipdev_setup(&slipdevs[i], p);
kernel_pid_t res = gnrc_netdev_raw_init(&gnrc_adpt[i],
(netdev_t *)&slipdevs[i]);
if (res < 0) {
LOG_ERROR("[auto_init_netif] error initializing slipdev #%u\n", i);
}
else {
gnrc_netdev_init(_slipdev_stacks[i], SLIPDEV_STACKSIZE,
SLIPDEV_PRIO, "slipdev", &gnrc_adpt[i]);
}
gnrc_netif_raw_create(_slipdev_stacks[i], SLIPDEV_STACKSIZE,
SLIPDEV_PRIO, "slipdev",
(netdev_t *)&slipdevs[i]);
}
}
#else

View File

@ -22,23 +22,14 @@
#include "log.h"
#include "w5100.h"
#include "w5100_params.h"
#ifdef MODULE_GNRC_NETIF2
#include "net/gnrc/netif2/ethernet.h"
#else
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/eth.h"
#endif
#include "net/gnrc/netif/ethernet.h"
/**
* @brief Define stack parameters for the MAC layer thread
* @{
*/
#define MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifdef MODULE_GNRC_NETIF2
#define MAC_PRIO (GNRC_NETIF2_PRIO)
#else
#define MAC_PRIO (THREAD_PRIORITY_MAIN - 4)
#endif
#define MAC_PRIO (GNRC_NETIF_PRIO)
/*** @} */
/**
@ -51,9 +42,6 @@
* @{
*/
static w5100_t dev[W5100_NUM];
#ifndef MODULE_GNRC_NETIF2
static gnrc_netdev_t gnrc_adpt[W5100_NUM];
#endif
/** @} */
/**
@ -70,15 +58,8 @@ void auto_init_w5100(void)
/* setup netdev device */
w5100_setup(&dev[i], &w5100_params[i]);
/* initialize netdev <-> gnrc adapter state */
#ifdef MODULE_GNRC_NETIF2
gnrc_netif2_ethernet_create(stack[i], MAC_STACKSIZE, MAC_PRIO, "w5100",
(netdev_t *)&dev[i]);
#else
gnrc_netdev_eth_init(&gnrc_adpt[i], (netdev_t *)&dev[i]);
/* start gnrc netdev thread */
gnrc_netdev_init(stack[i], MAC_STACKSIZE, MAC_PRIO,
"gnrc_w5100", &gnrc_adpt[i]);
#endif
gnrc_netif_ethernet_create(stack[i], MAC_STACKSIZE, MAC_PRIO, "w5100",
(netdev_t *)&dev[i]);
}
}

View File

@ -23,7 +23,8 @@
#include "log.h"
#include "board.h"
#include "net/gnrc/netdev/xbee_adpt.h"
#include "gnrc_netif_xbee.h"
#include "xbee.h"
#include "xbee_params.h"
/**
@ -36,14 +37,13 @@
*/
#define XBEE_MAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef XBEE_MAC_PRIO
#define XBEE_MAC_PRIO (GNRC_NETDEV_MAC_PRIO)
#define XBEE_MAC_PRIO (GNRC_NETIF_PRIO)
#endif
/**
* @brief Allocate memory for device descriptors, stacks, and GNRC adaption
*/
static xbee_t xbee_devs[XBEE_NUM];
static gnrc_netdev_t gnrc_adpt[XBEE_NUM];
static char stacks[XBEE_NUM][XBEE_MAC_STACKSIZE];
void auto_init_xbee(void)
@ -52,9 +52,8 @@ void auto_init_xbee(void)
LOG_DEBUG("[auto_init_netif] initializing xbee #%u\n", i);
xbee_setup(&xbee_devs[i], &xbee_params[i]);
gnrc_netdev_xbee_init(&gnrc_adpt[i], &xbee_devs[i]);
gnrc_netdev_init(stacks[i], XBEE_MAC_STACKSIZE, XBEE_MAC_PRIO,
"xbee", &gnrc_adpt[i]);
gnrc_netif_xbee_create(stacks[i], XBEE_MAC_STACKSIZE, XBEE_MAC_PRIO,
"xbee", (netdev_t *)&xbee_devs[i]);
}
}

View File

@ -203,6 +203,11 @@
* please refer to @ref gnrc_udp_hdr_build(), @ref gnrc_ipv6_hdr_build()
* etc. for more information.
*
* @note GNRC is implemented according to the respective standards. So please
* note, that sending to a IPv6 link-local address always requires you
* by definition to also provide the interface you want to send to,
* otherwise address resolution might fail.
*
* How To Use
* ==========
* @ref net_gnrc is highly modular and can be adjusted to include only the
@ -241,11 +246,10 @@
* USEMODULE += gnrc_ipv6_router
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* respectively. Those modules provide the bare minimum of IPv6
* functionalities (no @ref net_gnrc_icmpv6, no @ref net_gnrc_ndp). Because
* of that, the @ref net_gnrc_ipv6_nc needs to be configured manually. If an
* IEEE 802.15.4 device is present @ref net_gnrc_sixlowpan will be included
* automatically, but no fragmentation or header compression support will be
* provided.
* functionalities (no @ref net_gnrc_icmpv6). Because of that, the
* @ref net_gnrc_ipv6_nib needs to be configured manually. If an IEEE 802.15.4
* device is present @ref net_gnrc_sixlowpan will be included automatically,
* but no fragmentation or header compression support will be provided.
*
* - For @ref net_gnrc_icmpv6_echo "ICMPv6 echo request/reply (ping)"
* functionality:

View File

@ -36,10 +36,7 @@
#include "net/ipv6.h"
#include "net/gnrc/ipv6/ext.h"
#include "net/gnrc/ipv6/hdr.h"
#ifndef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nc.h"
#endif
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/ipv6/nib.h"
#ifdef MODULE_FIB
#include "net/fib.h"

View File

@ -1,319 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
* more details.
*/
/**
* @defgroup net_gnrc_ipv6_nc IPv6 neighbor cache
* @ingroup net_gnrc_ipv6
* @brief Translates IPv6 addresses to link layer addresses.
* @{
*
* @file
* @brief Neighbor cache definitions.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_IPV6_NC_H
#define NET_GNRC_IPV6_NC_H
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "kernel_types.h"
#include "net/eui64.h"
#include "net/ipv6/addr.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/pktqueue.h"
#include "xtimer.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GNRC_IPV6_NC_SIZE
/**
* @brief The size of the neighbor cache
*/
#define GNRC_IPV6_NC_SIZE (GNRC_NETIF_NUMOF * 8)
#endif
#ifndef GNRC_IPV6_NC_L2_ADDR_MAX
/**
* @brief The maximum size of a link layer address
*/
#define GNRC_IPV6_NC_L2_ADDR_MAX (8)
#endif
/**
* @{
* @name Flag definitions for gnrc_ipv6_nc_t
*/
/**
* @{
* @brief States of a neighbor cache entry.
*
* @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.2">
* RFC 4861, section 7.3.2
* </a>
*/
#define GNRC_IPV6_NC_STATE_MASK (0x07) /**< Mask for neighbor cache state */
#define GNRC_IPV6_NC_STATE_POS (0) /**< Shift of neighbor cache state */
#define GNRC_IPV6_NC_STATE_UNMANAGED (0x00) /**< The entry is not manage by NDP */
/**
* @brief The entry is unreachable
*
* @see <a href="http://tools.ietf.org/html/rfc7048#section-3">
* RFC 7048, section 3
* </a>
*/
#define GNRC_IPV6_NC_STATE_UNREACHABLE (0x01)
#define GNRC_IPV6_NC_STATE_INCOMPLETE (0x02) /**< Address resolution is performed */
#define GNRC_IPV6_NC_STATE_STALE (0x03) /**< The entry is stale */
#define GNRC_IPV6_NC_STATE_DELAY (0x04) /**< The entry was stale but packet was sent out */
#define GNRC_IPV6_NC_STATE_PROBE (0x05) /**< Periodic reachabality confirmation */
#define GNRC_IPV6_NC_STATE_REACHABLE (0x07) /**< The entry is reachable */
/**
* @}
*/
#define GNRC_IPV6_NC_IS_ROUTER (0x08) /**< The neighbor is a router */
#define GNRC_IPV6_NC_TYPE_MASK (0x30) /**< Mask for neighbor cache state */
/**
* @{
* @brief States of a neighbor cache entry.
*
* @see <a href="http://tools.ietf.org/html/rfc6775#section-3.5">
* RFC 6775, section 3.5
* </a>
*/
/**
* @brief The entry has no type
*
* @details The node sents multicast Neighbor Solicitations for hosts.
*/
#define GNRC_IPV6_NC_TYPE_NONE (0x00)
#define GNRC_IPV6_NC_TYPE_GC (0x10) /**< The entry is marked for removal */
#define GNRC_IPV6_NC_TYPE_TENTATIVE (0x20) /**< The entry is temporary */
#define GNRC_IPV6_NC_TYPE_REGISTERED (0x30) /**< The entry is registered */
/**
* @}
*/
/**
* @}
*/
/**
* @brief Neighbor cache entry as defined in
* <a href="http://tools.ietf.org/html/rfc4861#section-5.1">
* RFC 4861, section 5.1
* </a>.
*/
typedef struct {
#ifdef MODULE_GNRC_NDP_NODE
gnrc_pktqueue_t *pkts; /**< Packets waiting for address resolution */
#endif
ipv6_addr_t ipv6_addr; /**< IPv6 address of the neighbor */
uint8_t l2_addr[GNRC_IPV6_NC_L2_ADDR_MAX]; /**< Link layer address of the neighbor */
uint8_t l2_addr_len; /**< Length of gnrc_ipv6_nc_t::l2_addr */
uint8_t flags; /**< Flags as defined above */
kernel_pid_t iface; /**< PID to the interface where the neighbor is */
xtimer_t rtr_timeout; /**< timeout timer for router flag */
msg_t rtr_timeout_msg; /**< msg_t for gnrc_ipv6_nc_t::rtr_timeout */
/**
* @brief (Re)Transmission timer for neighbor solicitations of this entry and
* timeout for states.
*/
xtimer_t nbr_sol_timer;
msg_t nbr_sol_msg; /**< msg_t for gnrc_ipv6_nc_t::nbr_sol_timer */
/**
* @brief Delay timer for neighbor advertisements of this entry.
*
* @note Only needed for delayed anycast neighbor advertisements
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-7.2.7">
* RFC 4861, section 7.2.7
* </a>
*/
xtimer_t nbr_adv_timer;
msg_t nbr_adv_msg; /**< msg_t for gnrc_ipv6_nc_t::nbr_adv_timer */
#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER)
xtimer_t rtr_adv_timer; /**< Timer for periodic router advertisements */
msg_t rtr_adv_msg; /**< msg_t for gnrc_ipv6_nc_t::rtr_adv_timer */
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
xtimer_t type_timeout; /**< Timer for type transmissions */
msg_t type_timeout_msg; /**< msg_t for gnrc_ipv6_nc_t::type_timeout */
eui64_t eui64; /**< the unique EUI-64 of the neighbor (might be
* different from L2 address, if l2_addr_len == 2) */
#endif
uint8_t probes_remaining; /**< remaining number of unanswered probes */
/**
* @}
*/
} gnrc_ipv6_nc_t;
/**
* @brief Initializes neighbor cache
*/
void gnrc_ipv6_nc_init(void);
/**
* @brief Adds a neighbor to the neighbor cache
*
* @param[in] iface PID to the interface where the neighbor is.
* @param[in] ipv6_addr IPv6 address of the neighbor. Must not be NULL.
* @param[in] l2_addr Link layer address of the neighbor. NULL if unknown.
* @param[in] l2_addr_len Length of @p l2_addr, must be lesser than or equal
* to GNRC_IPV6_L2_ADDR_MAX. 0 if unknown.
* @param[in] flags Flags for the entry
*
* @return Pointer to new neighbor cache entry on success
* @return NULL, on failure
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_add(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr,
const void *l2_addr, size_t l2_addr_len, uint8_t flags);
/**
* @brief Removes a neighbor from the neighbor cache
*
* @param[in] iface PID to the interface where the neighbor is. If it
* is KERNEL_PID_UNDEF it will be removed for all
* interfaces.
* @param[in] ipv6_addr IPv6 address of the neighbor
*/
void gnrc_ipv6_nc_remove(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr);
/**
* @brief Searches for any neighbor cache entry fitting the @p ipv6_addr.
*
* @param[in] iface PID to the interface where the neighbor is. If it
* is KERNEL_PID_UNDEF it will be searched on all
* interfaces.
* @param[in] ipv6_addr An IPv6 address
*
* @return The neighbor cache entry, if one is found.
* @return NULL, if none is found.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_get(kernel_pid_t iface, const ipv6_addr_t *ipv6_addr);
/**
* @brief Gets next entry in neighbor cache after @p prev.
*
* @param[in] prev Previous entry. NULL to start iteration.
*
* @return The next entry in neighbor cache.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next(gnrc_ipv6_nc_t *prev);
/**
* @brief Gets next reachable router entry in neighbor cache after @p prev.
*
* @param[in] prev Previous router entry. NULL to start iteration.
*
* @return The next reachable router entry in neighbor cache.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_get_next_router(gnrc_ipv6_nc_t *prev);
/**
* @brief Returns the state of a neighbor cache entry.
*
* @param[in] entry A neighbor cache entry
*
* @return The state of the neighbor cache entry as defined by its flags.
*/
static inline uint8_t gnrc_ipv6_nc_get_state(const gnrc_ipv6_nc_t *entry)
{
return (entry->flags & GNRC_IPV6_NC_STATE_MASK);
}
/**
* @brief Returns the type of a neighbor cache entry.
*
* @param[in] entry A neighbor cache entry
*
* @return The type of the neighbor cache entry as defined by its flags.
*/
static inline uint8_t gnrc_ipv6_nc_get_type(const gnrc_ipv6_nc_t *entry)
{
return (entry->flags & GNRC_IPV6_NC_TYPE_MASK);
}
/**
* @brief Checks if an entry is reachable (do not confuse with
* @ref GNRC_IPV6_NC_STATE_REACHABLE).
*
* @param[in] entry A neighbor cache entry
*
* @return true, if you can send packets to @p entry
* @return false, if you can't send packets to @p entry
*/
static inline bool gnrc_ipv6_nc_is_reachable(const gnrc_ipv6_nc_t *entry)
{
switch (gnrc_ipv6_nc_get_state(entry)) {
case GNRC_IPV6_NC_STATE_UNREACHABLE:
case GNRC_IPV6_NC_STATE_INCOMPLETE:
return false;
default:
return true;
}
}
/**
* @brief Marks an entry as still reachable, if one with a fitting @p ipv6_addr
* can be found.
*
* @details This function can be used by upper layer protocols for neighbor
* discovery optimization to confirm that there was a reachability
* confirmation (e. g. an ACK in TCP) from the neighbor.
*
* @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.1">
* RFC 4861, section 7.3.1
* </a>
*
* @param[in] ipv6_addr An IPv6 address
*
* @return The neighbor cache entry, if one is found.
* @return NULL, if none is found.
*/
gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr);
/**
* @brief Gets link-layer address from neighbor cache entry if neighbor is reachable.
*
* @pre (l2_addr != NULL) && (l2_addr_len != NULL)
*
* @param[out] l2_addr The link layer address of @p entry. Must not be NULL.
* @param[out] l2_addr_len Length of @p l2_addr. Must not be NULL.
* @param[in] entry A neighbor cache entry
*
* @return PID to the interface where the neighbor is.
* @return KERNEL_PID_UNDEF, if @p entry == NULL or the neighbor is not reachable.
*/
kernel_pid_t gnrc_ipv6_nc_get_l2_addr(uint8_t *l2_addr, uint8_t *l2_addr_len,
const gnrc_ipv6_nc_t *entry);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_IPV6_NC_H */
/**
* @}
*/

View File

@ -1,622 +0,0 @@
/*
* Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
* more details.
*/
/**
* @defgroup net_gnrc_ipv6_netif IPv6 network interfaces
* @ingroup net_gnrc_ipv6
* @brief IPv6 specific information on @ref net_gnrc_netif.
* @{
*
* @file
* @brief Definitions for IPv6 specific information of network interfaces.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_IPV6_NETIF_H
#define NET_GNRC_IPV6_NETIF_H
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "kernel_defines.h"
#include "kernel_types.h"
#include "mutex.h"
#include "net/ipv6.h"
#include "net/ipv6/addr.h"
#include "xtimer.h"
#ifdef MODULE_NETSTATS_IPV6
#include "net/netstats.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @cond INTERNAL
*/
#ifdef MODULE_GNRC_RPL
/* RPL needs all-RPL-nodes multicast address */
# define GNRC_IPV6_NETIF_RPL_ADDR (1)
#else
# define GNRC_IPV6_NETIF_RPL_ADDR (0)
#endif
#ifdef MODULE_GNRC_IPV6_ROUTER
/* routers need all-routers multicast address */
# define GNRC_IPV6_NETIF_RTR_ADDR (1)
#else
# define GNRC_IPV6_NETIF_RTR_ADDR (0)
#endif
/**
* @endcond
*/
/**
* @brief Number of IPv6 addresses per interface.
*/
#ifndef GNRC_IPV6_NETIF_ADDR_NUMOF
#define GNRC_IPV6_NETIF_ADDR_NUMOF (6 + GNRC_IPV6_NETIF_RPL_ADDR + GNRC_IPV6_NETIF_RTR_ADDR)
#endif
/**
* @brief Default MTU
*
* An interface will choose this MTU if the link-layer's maximum packet size
* (see @ref NETOPT_MAX_PACKET_SIZE) is lesser than the @ref IPV6_MIN_MTU or if it just not
* provide it. For RFC-compatible communication it must be at least @ref IPV6_MIN_MTU.
*
* @note If the scenario the node is used in allows for it and the packet size is predictable,
* a user might choose to set @ref GNRC_IPV6_NETIF_DEFAULT_MTU to a lesser value than
* @ref IPV6_MIN_MTU to optimize for code size (e.g. because it is then possible to omit
* @ref net_gnrc_sixlowpan_frag) and memory usage (e.g. because @ref GNRC_PKTBUF_SIZE
* can be much smaller).
*/
#ifndef GNRC_IPV6_NETIF_DEFAULT_MTU
#define GNRC_IPV6_NETIF_DEFAULT_MTU (IPV6_MIN_MTU)
#endif
/**
* @brief Default hop limit
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.2">
* RFC 4861, section 6.3.2
* </a>
* @see <a href="http://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml#ip-parameters-2">
* IANA, IP TIME TO LIVE PARAMETER
* </a>
*/
#define GNRC_IPV6_NETIF_DEFAULT_HL (64)
/**
* @name Default values for router configuration
* @{
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
/**
* @brief Maximum time in seconds between sending unsolicited multicast router advertisements.
*/
#define GNRC_IPV6_NETIF_DEFAULT_MAX_ADV_INT (600U)
/**
* @brief Minimum time in seconds between sending unsolicited multicast router advertisements.
*/
#define GNRC_IPV6_NETIF_DEFAULT_MIN_ADV_INT (200U)
/**
* @brief The router lifetime to propagate in router advertisements.
*/
#define GNRC_IPV6_NETIF_DEFAULT_ROUTER_LTIME (1800U)
/** @} */
/**
* @{
* @name Flags for a registered IPv6 address.
* @brief Needed primarily to identify addresses as either anycast or unicast.
*
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6">
* RFC 4291, section 2.6
* </a>
*/
#define GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST (0x00) /**< unicast address */
#define GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST (0x01) /**< non-unicast address */
/**
* @brief A prefix information option that propagates the prefix of this
* address should set the autonomous flag.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
#define GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_AUTO (0x40)
/**
* @brief A prefix information option that propagates the prefix of this
* address should set the on-link flag.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
#define GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK (0x80)
/**
* @}
*/
/**
* @{
* @name Flags for the interfaces
*
* @note The most-significant byte of these flags is identical to the flags in
* IPv6 router advertisements. See <a
* href="https://tools.ietf.org/html/rfc4861#section-4.2">RFC4861,
* section 4.2</a>, <a
* href="https://tools.ietf.org/html/rfc6275#section-7.1">RFC6275,
* section 7.1</a>, <a
* href="https://tools.ietf.org/html/rfc4191#section-2.2">RFC4191,
* section 2.2</a>, and <a
* href="https://tools.ietf.org/html/rfc4389#section-4.1.3.3">RFC4389,
* section 4.1.3.3</a>.
*/
/**
* @brief Interface is 6LoWPAN interface.
*/
#define GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN (0x0001)
/**
* @brief Flag to indicate that routing is enabled on the interface.
*/
#define GNRC_IPV6_NETIF_FLAGS_ROUTER (0x0002)
/**
* @brief Flag to indicate that the interface sends periodic router
* advertisements and in response to router solicitations.
*/
#define GNRC_IPV6_NETIF_FLAGS_RTR_ADV (0x0004)
/**
* @brief Flag to indicate that gnrc_ipv6_netif_t::mtu shall be propagated
* with the MTU options in router advertisements.
*/
#define GNRC_IPV6_NETIF_FLAGS_ADV_MTU (0x0008)
/**
* @brief Flag to indicate that gnrc_ipv6_netif_t::cur_hl shall be propagated
* in router advertisements.
*/
#define GNRC_IPV6_NETIF_FLAGS_ADV_CUR_HL (0x0010)
/**
* @brief Flag to indicate that gnrc_ipv6_netif_t::reach_time shall be propagated
* in router advertisements.
*/
#define GNRC_IPV6_NETIF_FLAGS_ADV_REACH_TIME (0x0020)
/**
* @brief Flag to indicate that gnrc_ipv6_netif_t::retrans_timer shall be propagated
* in router advertisements.
*/
#define GNRC_IPV6_NETIF_FLAGS_ADV_RETRANS_TIMER (0x0040)
/**
* @brief Flag to indicate if the interface is operating over a wired link
*/
#define GNRC_IPV6_NETIF_FLAGS_IS_WIRED (0x0080)
/**
* @brief Offset of the router advertisement flags compared to the position in router
* advertisements.
*/
#define GNRC_IPV6_NETIF_FLAGS_RTR_ADV_POS (8U)
/**
* @brief Mask for flags intended for router advertisements.
* @note Please expand if more router advertisement flags are introduced.
*/
#define GNRC_IPV6_NETIF_FLAGS_RTR_ADV_MASK (0xc000)
/**
* @brief Flag to indicate that the interface has other address
* configuration.
*/
#define GNRC_IPV6_NETIF_FLAGS_OTHER_CONF (0x4000)
/**
* @brief Flag to indicate that the interface has managed address
* configuration (e.g. via DHCPv6).
*/
#define GNRC_IPV6_NETIF_FLAGS_MANAGED (0x8000)
/**
* @}
*/
/**
* @brief Type to represent an IPv6 address registered to an interface.
*/
typedef struct {
ipv6_addr_t addr; /**< The address data */
uint8_t flags; /**< flags */
uint8_t prefix_len; /**< length of the prefix of the address */
/**
* @{
* @name Neigbour discovery variables for prefixes
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.1">
* RFC 4861, section 6.2.1
* </a>
*/
/**
* @brief The time in seconds this address is valid. If it is UINT32_MAX
* the lifetime is infinite.
*/
uint32_t valid;
/**
* @brief The length of time that this address remains preferred.
* If it is UINT32_MAX the lifetime is infinite.
* It **must** be < gnrc_ipv6_netif_addr_t::valid.
*/
uint32_t preferred;
/**
* @brief Validity timeout timer.
*/
xtimer_t valid_timeout;
msg_t valid_timeout_msg; /**< msg_t for gnrc_ipv6_netif_addr_t::valid_timeout */
/**
* @}
*/
} gnrc_ipv6_netif_addr_t;
/**
* @brief Definition of IPv6 interface type.
*/
typedef struct {
/**
* @brief addresses registered to the interface
*/
gnrc_ipv6_netif_addr_t addrs[GNRC_IPV6_NETIF_ADDR_NUMOF];
mutex_t mutex; /**< mutex for the interface */
kernel_pid_t pid; /**< PID of the interface */
uint16_t flags; /**< flags for 6LoWPAN and Neighbor Discovery */
uint16_t mtu; /**< Maximum Transmission Unit (MTU) of the interface */
uint8_t cur_hl; /**< current hop limit for the interface */
#if defined(MODULE_GNRC_NDP_HOST) || defined(MODULE_GNRC_SIXLOWPAN_ND)
/**
* @brief Counter for send router solicitations.
*/
uint8_t rtr_sol_count;
#endif
#ifdef MODULE_GNRC_NDP_ROUTER
/**
* @brief Counter for initial router advertisements.
*/
uint8_t rtr_adv_count;
/**
* @brief Maximum time in seconds between sending unsolicited multicast
* router advertisements. Must be between 4 and 1800 seconds.
* The default value is @ref GNRC_IPV6_NETIF_DEFAULT_MAX_ADV_INT.
*/
uint16_t max_adv_int;
/**
* @brief Minimum time in seconds between sending unsolicited multicast
* router advertisements. Must be between 3 and
* 3/4 * gnrc_ipv6_netif_t::max_adv_int seconds.
* The default value is @ref GNRC_IPV6_NETIF_DEFAULT_MIN_ADV_INT.
*/
uint16_t min_adv_int;
#endif
#if defined (MODULE_GNRC_NDP_ROUTER) || defined (MODULE_GNRC_SIXLOWPAN_ND_ROUTER)
/**
* @brief The router lifetime to propagate in router advertisements.
* Must be either 0 or between gnrc_ipv6_netif_t::max_adv_int and
* 9000 seconds. 0 means this router is not to be used as a default
* router. The default value is @ref GNRC_IPV6_NETIF_DEFAULT_ROUTER_LTIME.
*/
uint16_t adv_ltime;
#endif
/**
* @brief Base value in microseconds for computing random
* gnrc_ipv6_netif_t::reach_time.
* The default value is @ref GNRC_NDP_REACH_TIME.
*/
uint32_t reach_time_base;
/**
* @brief The time a neighbor is considered reachable after receiving
* a reachability confirmation.
* Should be uniformly distributed between @ref GNRC_NDP_MIN_RAND
* and GNRC_NDP_MAX_RAND multiplied with
* gnrc_ipv6_netif_t::reach_time_base microseconds devided by 10.
* Can't be greater than 1 hour.
*/
uint32_t reach_time;
/**
* @brief Time between retransmissions of neighbor solicitations to a
* neighbor.
* The default value is @ref GNRC_NDP_RETRANS_TIMER.
*/
uint32_t retrans_timer;
xtimer_t rtr_sol_timer; /**< Timer for periodic router solicitations */
msg_t rtr_sol_msg; /**< msg_t for gnrc_ipv6_netif_t::rtr_sol_timer */
#if defined (MODULE_GNRC_NDP_ROUTER) || defined (MODULE_GNRC_SIXLOWPAN_ND_ROUTER)
xtimer_t rtr_adv_timer; /**< Timer for periodic router advertisements */
msg_t rtr_adv_msg; /**< msg_t for gnrc_ipv6_netif_t::rtr_adv_timer */
#endif
#ifdef MODULE_NETSTATS_IPV6
netstats_t stats; /**< transceiver's statistics */
#endif
} gnrc_ipv6_netif_t;
/**
* @brief Initializes the module.
*/
void gnrc_ipv6_netif_init(void);
/**
* @brief Add interface to IPv6.
*
* @details This function will be called by @ref gnrc_netif_add().
*
* @param[in] pid The PID to the interface.
*/
void gnrc_ipv6_netif_add(kernel_pid_t pid);
/**
* @brief Remove interface from IPv6.
*
* @details This function will be called by @ref gnrc_netif_remove().
*
* @param[in] pid The PID to the interface.
*/
void gnrc_ipv6_netif_remove(kernel_pid_t pid);
/**
* @brief Get interface.
*
* @param[in] pid The PID to the interface.
*
* @return The interface describing structure, on success.
* @return NULL, if there is no interface with PID @p pid.
*/
gnrc_ipv6_netif_t *gnrc_ipv6_netif_get(kernel_pid_t pid);
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Set interface to router mode.
*
* @details This sets/unsets the GNRC_IPV6_NETIF_FLAGS_ROUTER and initializes
* or ceases router behavior for neighbor discovery.
*
* @param[in] netif The interface.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_ROUTER flag.
*/
void gnrc_ipv6_netif_set_router(gnrc_ipv6_netif_t *netif, bool enable);
/**
* @brief Set interface to router advertisement mode.
*
* @details If GNRC_IPV6_NETIF_FLAGS_ROUTER is set this sets/unsets the
* GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases router
* advertising behavior for neighbor discovery.
*
* @param[in] netif The interface.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_RTR flag.
*/
void gnrc_ipv6_netif_set_rtr_adv(gnrc_ipv6_netif_t *netif, bool enable);
#else
/* dummy macros to be able to "call" these functions when none of the relevant modules
* is implemented */
#define gnrc_ipv6_netif_set_router(netif, enable)
#define gnrc_ipv6_netif_set_rtr_adv(netif, enable)
#endif
/**
* @brief Adds an address to an interface.
*
* @param[in] pid The PID to the interface.
* @param[in] addr An address you want to add to the interface.
* @param[in] prefix_len Length of the prefix of the address.
* Must be between 1 and 128.
* @param[in] flags Flags for the address entry
* If @p addr should be an anycast address, @p flags
* must have @ref GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST
* set. Otherwise leave it unset.
* If @p addr is a multicast address, the status of
* @ref GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST will be
* ignored and set in either case.
*
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.6">
* RFC 4291, section 2.6
* </a>
*
* @return The address on the interface, on success.
* @return NULL, on failure
*/
ipv6_addr_t *gnrc_ipv6_netif_add_addr(kernel_pid_t pid, const ipv6_addr_t *addr, uint8_t prefix_len,
uint8_t flags);
/**
* @brief Remove an address from the interface.
*
* @param[in] pid The PID to the interface. If @p pid is KERNEL_PID_UNDEF
* it will be removed from all interfaces.
* @param[in] addr An address you want to remove from interface.
*/
void gnrc_ipv6_netif_remove_addr(kernel_pid_t pid, ipv6_addr_t *addr);
/**
* @brief Removes all addresses from the interface.
*
* @param[in] pid The PID to the interface.
*/
void gnrc_ipv6_netif_reset_addr(kernel_pid_t pid);
/**
* @brief Searches for an address on all interfaces.
*
* @param[out] out The reference to the address on the interface.
* @param[in] addr The address you want to search for.
*
* @return The PID to the interface the address is registered to.
* @return KERNEL_PID_UNDEF, if the address can not be found on any interface.
*/
kernel_pid_t gnrc_ipv6_netif_find_by_addr(ipv6_addr_t **out, const ipv6_addr_t *addr);
/**
* @brief Searches for an address on an interface.
*
* @param[in] pid The PID to the interface.
* @param[in] addr The address you want to search for.
*
* @return The reference to the address on the interface.
* @return NULL, if the address can not be found on the interface.
* @return NULL, if @p pid is no interface.
*/
ipv6_addr_t *gnrc_ipv6_netif_find_addr(kernel_pid_t pid, const ipv6_addr_t *addr);
/**
* @brief Searches for the first address matching a prefix best on all
* interfaces.
*
* @param[out] out The reference to the found address on the interface.
* Must be a pointer to NULL on calling and may stay
* unchanged if no match can be found.
*
* @param[in] prefix The prefix you want to search for.
*
* @pre @p out must not be NULL.
*
* @return The PID to the interface the address is registered to.
* @return KERNEL_PID_UNDEF, if no matching address can not be found on any
* interface.
*/
kernel_pid_t gnrc_ipv6_netif_find_by_prefix(ipv6_addr_t **out, const ipv6_addr_t *prefix);
/**
* @brief Searches for the first address matching a prefix best on an
* interface.
*
* @param[in] pid The PID to the interface.
* @param[in] prefix The prefix you want to search for.
*
* @return The reference to the found address on the interface.
* @return NULL, if no matching address can be found on the interface.
* @return NULL, if @p pid is no interface.
*/
ipv6_addr_t *gnrc_ipv6_netif_match_prefix(kernel_pid_t pid, const ipv6_addr_t *prefix);
/**
* @brief Searches for the best address on an interface usable as a
* source address for a given destination address.
*
* @param[in] pid The PID to the interface.
* @param[in] dest The destination address you want to find a destination
* address for.
* @param[in] ll_only If only link local addresses qualify
*
* @todo Rule 4 from RFC 6724 is currently not implemented. Has to updated as
* soon as gnrc supports Mobile IP.
*
* @todo Rule 6 from RFC 6724 is currently not implemented. Has to updated as
* soon as gnrc supports flow labels.
*
* @todo Rule 7 from RFC 6724 is currently not implemented. Has to updated as
* soon as gnrc supports temporary addresses.
*
* @return The reference to the found address on the interface.
* @return NULL, if no matching address can be found on the interface.
* @return NULL, if @p pid is no interface.
*/
ipv6_addr_t *gnrc_ipv6_netif_find_best_src_addr(kernel_pid_t pid, const ipv6_addr_t *dest, bool ll_only);
/**
* @brief Get interface specific meta-information on an address
*
* @details This only works with addresses you retrieved via the following
* functions:
*
* * gnrc_ipv6_netif_add_addr()
* * gnrc_ipv6_find_addr()
* * gnrc_ipv6_find_addr_local()
* * gnrc_ipv6_find_prefix_match()
* * gnrc_ipv6_find_prefix_match_local()
* * gnrc_ipv6_find_best_src_address()
*
* The behaviour for other addresses is undefined.
*
* @param[in] addr The address you want to get the meta-information for.
*
* @return Interface specific meta-information on @p addr
*/
static inline gnrc_ipv6_netif_addr_t *gnrc_ipv6_netif_addr_get(const ipv6_addr_t *addr)
{
return container_of(addr, gnrc_ipv6_netif_addr_t, addr);
}
/**
* @brief Checks if an address is non-unicast.
*
* @details This only works with addresses you retrieved via the following
* functions:
*
* * gnrc_ipv6_netif_add_addr()
* * gnrc_ipv6_find_addr()
* * gnrc_ipv6_find_addr_local()
* * gnrc_ipv6_find_prefix_match()
* * gnrc_ipv6_find_prefix_match_local()
* * gnrc_ipv6_find_best_src_address()
*
* The behaviour for other addresses is undefined.
*
* @param[in] addr The address you want to check.
*
* @return true, if address is anycast or multicast.
* @return false, if address is unicast.
*/
static inline bool gnrc_ipv6_netif_addr_is_non_unicast(const ipv6_addr_t *addr)
{
return (bool)(container_of(addr, gnrc_ipv6_netif_addr_t, addr)->flags &
GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST);
}
/**
* @brief Initializes an interface with device-dependent values.
*
* @note Must be called after all interfaces were initialized and must not
* be called in an interface's thread (will otherwise hang up).
*/
void gnrc_ipv6_netif_init_by_dev(void);
/**
* @brief Get sent and received statistics about IPv6 traffic on this interface.
*
* @note This function is only available if compiled with module `netstats_ipv6`.
*
* @param[in] pid The PID to the interface.
*
* @return A @ref netstats_t pointer to the statistics.
* @return NULL if no statistics are available.
*/
#if defined(MODULE_NETSTATS_IPV6) || DOXYGEN
netstats_t *gnrc_ipv6_netif_get_stats(kernel_pid_t pid);
#endif
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_IPV6_NETIF_H */
/**
* @}
*/

View File

@ -14,6 +14,7 @@
* @todo Add detailed description
* @todo Implement multihop DAD
* @todo Implement classic SLAAC
* @todo Implement MLD
* @{
*
* @file
@ -33,6 +34,7 @@
#include "net/ipv6/addr.h"
#include "net/ipv6/hdr.h"
#include "net/gnrc/ipv6/nib/nc.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/pkt.h"
#ifdef __cplusplus
@ -85,16 +87,6 @@ extern "C" {
*/
#define GNRC_IPV6_NIB_SEARCH_RTR (0x4fc3U)
/**
* @brief Reconfirm router event.
*
* This message type is for the event the reconfirmation of a router (which
* implies sending a unicast Router Solicitation). The expected message context
* is a pointer to a valid on-link entry representing the router that is to be
* confirmed.
*/
#define GNRC_IPV6_NIB_RECONFIRM_RTR (0x4fc4U)
/**
* @brief Reply Router Solicitation event.
*
@ -152,17 +144,6 @@ extern "C" {
*/
#define GNRC_IPV6_NIB_ADDR_REG_TIMEOUT (0x4fc9U)
/**
* @brief 6LoWPAN context timeout event.
*
* This message type is for the event of a 6LoWPAN compression context timeout.
* The expected message context is the compression context's numerical
* identifier.
*
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_6LN != 0
*/
#define GNRC_IPV6_NIB_6LO_CTX_TIMEOUT (0x4fcaU)
/**
* @brief Authoritative border router timeout event.
*
@ -194,13 +175,88 @@ extern "C" {
* @brief Recalculate reachability timeout time.
*
* This message type is for the event of recalculating the reachability timeout
* time. The expected message context is a valid interface.
* time. The expected message context is a valid
* [interface](@ref net_gnrc_netif).
*
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ARSM != 0
*/
#define GNRC_IPV6_NIB_RECALC_REACH_TIME (0x4fceU)
/**
* @brief Reregister address.
*
* This message type is for the event of reregistering an IPv6 address to the
* upstream router. The expected message context is an IPv6 address assigned to
* one of the nodes interfaces.
*
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_6LN != 0
*/
#define GNRC_IPV6_NIB_REREG_ADDRESS (0x4fcfU)
/**
* @brief Route timeout event.
*
* This message type is for the event of a route timeout. The expected message
* context is a valid off-link entry representing the route.
*
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ROUTER != 0
*/
#define GNRC_IPV6_NIB_ROUTE_TIMEOUT (0x4fd0U)
/** @} */
/**
* @brief Types for gnrc_netif_ipv6_t::route_info_cb
* @anchor net_gnrc_ipv6_nib_route_info_type
*/
enum {
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_UNDEF = 0, /**< undefined */
/**
* @brief reactive routing query
*
* A reactive routing query is issued when a route is unknown to the NIB.
* A reactive routing protocol can use this call to search for a route in a
* reactive manner.
*
* The `ctx_addr` will be the destination address of the unknown route,
* `ctx` a pointer to the packet as `gnrc_pktsnip_t` that caused the route
* look-up (to possibly queue it for later sending).
*/
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_RRQ,
/**
* @brief route notification
*
* A route notification is issued when an already established route is
* taken. A routing protocol can use this call to update its information on
* the route.
*
* The `ctx_addr` is the prefix of the route, `ctx` is set to a value equal
* to the length of the prefix in bits.
*/
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_RN,
/**
* @brief neighbor state change
*
* A neighbor state change is issued when ever the NUD state of a neighbor
* changes. A routing protocol can use this call to update its information
* on routes via this neighbor.
*
* The `ctx_addr` is the address of the neighbor, `ctx` is a value equal
* to the new NUD state as defined in [the NC info flags](@ref
* net_gnrc_ipv6_nib_nc_info). If the entry is deleted, `ctx` will be set
* to @ref GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE (except if it was
* already in the `UNREACHABLE` state). This does not include cache-outs,
* since they give no information about the neighbor's reachability (you
* might however get an INCOMPLETE or STALE notification due to that, as
* soon as the neighbor enters the neighbor cache again).
*
* Be adviced to only use `ctx_addr` in the context of the callback, since
* it might be overwritten, after the callback was left.
*/
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC,
};
/**
* @brief Initialize NIB
*/
@ -209,11 +265,11 @@ void gnrc_ipv6_nib_init(void);
/**
* @brief Adds an interface to be managed by the NIB.
*
* @pre `(KERNEL_PID_UNDEF < iface)`
* @pre `netif != NULL`
*
* @param[in] iface The interface to be managed by the NIB
* @param[in,out] netif The interface to be managed by the NIB
*/
void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
void gnrc_ipv6_nib_init_iface(gnrc_netif_t *netif);
/**
* @brief Gets link-layer address of next hop to a destination address
@ -221,8 +277,8 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
* @pre `(dst != NULL) && (nce != NULL)`
*
* @param[in] dst Destination address of a packet.
* @param[in] iface Restrict search to this interface. May be
* `KERNEL_PID_UNDEF` for any interface.
* @param[in] netif Restrict search to this interface. May be `NULL` for any
* interface.
* @param[in] pkt The IPv6 packet in sending order for which the next hop
* is searched. Needed for queuing for with reactive
* routing or address resolution. May be `NULL`.
@ -237,13 +293,13 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
* solicitation sent).
*/
int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst,
kernel_pid_t iface, gnrc_pktsnip_t *pkt,
gnrc_netif_t *netif, gnrc_pktsnip_t *pkt,
gnrc_ipv6_nib_nc_t *nce);
/**
* @brief Handles a received ICMPv6 packet
*
* @pre `iface != KERNEL_PID_UNDEF`
* @pre `netif != NULL`
* @pre `ipv6 != NULL`
* @pre `icmpv6 != NULL`
* @pre `icmpv6_len > sizeof(icmpv6_hdr_t)`
@ -274,13 +330,13 @@ int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst,
* @see [RFC 6775, section 8.2.4](https://tools.ietf.org/html/rfc6775#section-8.2.4)
* @see [RFC 6775, section 8.2.5](https://tools.ietf.org/html/rfc6775#section-8.2.5)
*
* @param[in] iface The interface the packet came over.
* @param[in] netif The interface the packet came over.
* @param[in] ipv6 The IPv6 header of the received packet.
* @param[in] icmpv6 The ICMPv6 header and payload of the received
* packet.
* @param[in] icmpv6_len The number of bytes at @p icmpv6.
*/
void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
void gnrc_ipv6_nib_handle_pkt(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6, size_t icmpv6_len);
/**
@ -292,6 +348,25 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
*/
void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type);
#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN)
/**
* @brief Changes the state if an interface advertises itself as a router
* or not
*
* @param[in] netif The interface for which the state should be changed.
* @param[in] enable `true`, to enable advertising the interface as a router.
* `false`, to disable advertising the interface as a
* router.
*/
void gnrc_ipv6_nib_change_rtr_adv_iface(gnrc_netif_t *netif, bool enable);
#else
/**
* @brief Optimization to NOP for non-routers
*/
#define gnrc_ipv6_nib_change_rtr_adv_iface(netif, enable) \
(void)netif; (void)enable
#endif
#ifdef __cplusplus
}
#endif

View File

@ -29,6 +29,9 @@ extern "C" {
#ifndef GNRC_IPV6_NIB_CONF_6LBR
#define GNRC_IPV6_NIB_CONF_6LBR (1)
#endif
#ifndef GNRC_IPV6_NIB_NUMOF
#define GNRC_IPV6_NIB_NUMOF (16)
#endif
#endif
#ifdef MODULE_GNRC_IPV6_NIB_6LR
@ -174,8 +177,12 @@ extern "C" {
* @see [RFC 6775, section 8.1](https://tools.ietf.org/html/rfc6775#section-8.1)
*/
#ifndef GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
#if GNRC_IPV6_NIB_CONF_6LN
#define GNRC_IPV6_NIB_CONF_MULTIHOP_P6C (1)
#else
#define GNRC_IPV6_NIB_CONF_MULTIHOP_P6C (0)
#endif
#endif
/**
* @brief Multihop duplicate address detection
@ -199,10 +206,8 @@ extern "C" {
/**
* @brief Maximum link-layer address length (aligned)
*/
#if (GNRC_NETIF_HDR_L2ADDR_MAX_LEN % 8)
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (((GNRC_NETIF_HDR_L2ADDR_MAX_LEN >> 3) + 1) << 3)
#else
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (GNRC_NETIF_HDR_L2ADDR_MAX_LEN)
#ifndef GNRC_IPV6_NIB_L2ADDR_MAX_LEN
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (8U)
#endif
/**

View File

@ -62,6 +62,9 @@ int gnrc_ipv6_nib_ft_get(const ipv6_addr_t *dst, gnrc_pktsnip_t *pkt,
/**
* @brief Adds a new route to the forwarding table
*
* If @p dst is the default route, the route will be configured to be the
* default route.
*
* @param[in] dst The destination to the route. May be NULL or `::` for
* default route.
* @param[in] dst_len The prefix length of @p dst in bits. May be 0 for
@ -69,17 +72,23 @@ int gnrc_ipv6_nib_ft_get(const ipv6_addr_t *dst, gnrc_pktsnip_t *pkt,
* @param[in] next_hop The next hop to @p dst/@p dst_len. May be NULL, if
* @p dst/@p dst_len is no the default route.
* @param[in] iface The interface to @p next_hop. May not be 0.
* @param[in] lifetime Lifetime of the route in seconds. 0 for infinite
* lifetime.
*
* @return 0, on success.
* @return -EINVAL, if a parameter was of invalid value.
* @return -ENOMEM, if there was no space left in forwarding table.
*/
int gnrc_ipv6_nib_ft_add(const ipv6_addr_t *dst, unsigned dst_len,
const ipv6_addr_t *next_hop, unsigned iface);
const ipv6_addr_t *next_hop, unsigned iface,
uint16_t lifetime);
/**
* @brief Deletes a route from forwarding table.
*
* If @p dst is the default route, the function assures, that the current
* primary default route is removed first.
*
* @param[in] dst The destination of the route. May be NULL or `::` for
* default route.
* @param[in] dst_len The prefix length of @p dst in bits. May be 0 for

View File

@ -235,11 +235,12 @@ int gnrc_ipv6_nib_nc_set(const ipv6_addr_t *ipv6, unsigned iface,
*
* @pre `ipv6 != NULL`
*
* @param[in] ipv6 The neighbor's IPv6 address.
* @param[in] ipv6 The neighbor's IPv6 address.
* @param[in] iface The interface to the neighbor.
*
* If the @p ipv6 can't be found for a neighbor in the NIB nothing happens.
*/
void gnrc_ipv6_nib_nc_del(const ipv6_addr_t *ipv6);
void gnrc_ipv6_nib_nc_del(const ipv6_addr_t *ipv6, unsigned iface);
/**
* @brief Mark neighbor with address @p ipv6 as reachable

View File

@ -59,8 +59,8 @@ extern "C" {
* @brief LWMAC internal L2 address structure
*/
typedef struct {
uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< address of node */
uint8_t len; /**< address */
uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< address of node */
uint8_t len; /**< address */
} gnrc_lwmac_l2_addr_t;
/**
@ -79,25 +79,25 @@ typedef struct {
* @brief LWMAC WR (wake-up request packet, i.e., preamble packet) frame
*/
typedef struct __attribute__((packed)) {
gnrc_lwmac_hdr_t header; /**< WR packet header type */
gnrc_lwmac_l2_addr_t dst_addr; /**< WR is broadcast, so destination address needed */
gnrc_lwmac_hdr_t header; /**< WR packet header type */
gnrc_lwmac_l2_addr_t dst_addr; /**< WR is broadcast, so destination address needed */
} gnrc_lwmac_frame_wr_t;
/**
* @brief LWMAC WA (wake-up answer packet, i.e., preamble-ACK packet) frame
*/
typedef struct __attribute__((packed)) {
gnrc_lwmac_hdr_t header; /**< WA packet header type */
gnrc_lwmac_l2_addr_t dst_addr; /**< WA is broadcast, so destination address needed */
uint32_t current_phase; /**< Node's current phase value */
gnrc_lwmac_hdr_t header; /**< WA packet header type */
gnrc_lwmac_l2_addr_t dst_addr; /**< WA is broadcast, so destination address needed */
uint32_t current_phase; /**< Node's current phase value */
} gnrc_lwmac_frame_wa_t;
/**
* @brief LWMAC broadcast data frame
*/
typedef struct __attribute__((packed)) {
gnrc_lwmac_hdr_t header; /**< Broadcast packet header type */
uint8_t seq_nr; /**< Broadcast sequence */
gnrc_lwmac_hdr_t header; /**< Broadcast packet header type */
uint8_t seq_nr; /**< Broadcast sequence */
} gnrc_lwmac_frame_broadcast_t;
/**

View File

@ -74,7 +74,7 @@
#define NET_GNRC_LWMAC_LWMAC_H
#include "kernel_types.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
@ -95,7 +95,7 @@ extern "C" {
* In LWMAC, by default, we regard the wake-up period as the beginning of a cycle.
*/
#ifndef GNRC_LWMAC_WAKEUP_INTERVAL_US
#define GNRC_LWMAC_WAKEUP_INTERVAL_US (100LU * US_PER_MS)
#define GNRC_LWMAC_WAKEUP_INTERVAL_US (200LU *US_PER_MS)
#endif
/**
@ -110,7 +110,7 @@ extern "C" {
* @ref GNRC_LWMAC_WAKEUP_INTERVAL_US.
*/
#ifndef GNRC_LWMAC_PREAMBLE_DURATION_US
#define GNRC_LWMAC_PREAMBLE_DURATION_US ((13LU * GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
#define GNRC_LWMAC_PREAMBLE_DURATION_US ((13LU *GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
#endif
/**
@ -129,7 +129,7 @@ extern "C" {
* send a WR with the given hardware (including processor) and data rate.
*/
#ifndef GNRC_LWMAC_TIME_BETWEEN_WR_US
#define GNRC_LWMAC_TIME_BETWEEN_WR_US (5U * US_PER_MS)
#define GNRC_LWMAC_TIME_BETWEEN_WR_US (5U *US_PER_MS)
#endif
/**
@ -187,7 +187,7 @@ extern "C" {
* period of the receiver, otherwise will lead to a long WR procedure.
*/
#ifndef GNRC_LWMAC_WR_PREPARATION_US
#define GNRC_LWMAC_WR_PREPARATION_US ((3U * US_PER_MS))
#define GNRC_LWMAC_WR_PREPARATION_US ((3U *US_PER_MS))
#endif
/**
@ -207,7 +207,7 @@ extern "C" {
* supports @ref NETDEV_EVENT_RX_STARTED event (this can be important for big packets).
*/
#ifndef GNRC_LWMAC_DATA_DELAY_US
#define GNRC_LWMAC_DATA_DELAY_US (10U * US_PER_MS)
#define GNRC_LWMAC_DATA_DELAY_US (10U *US_PER_MS)
#endif
/**
@ -298,24 +298,22 @@ extern "C" {
#endif
/**
* @brief Initialize an instance of the LWMAC layer
* @brief Creates an IEEE 802.15.4 LWMAC network interface
*
* The initialization starts a new thread that connects to the given netdev
* device and starts a link layer event loop.
* @param[in] stack The stack for the LWMAC network interface's thread.
* @param[in] stacksize Size of @p stack.
* @param[in] priority Priority for the LWMAC network interface's thread.
* @param[in] name Name for the LWMAC network interface. May be NULL.
* @param[in] dev Device for the interface
*
* @param[in] stack stack for the control thread
* @param[in] stacksize size of *stack*
* @param[in] priority priority for the thread housing the LWMAC instance
* @param[in] name name of the thread housing the LWMAC instance
* @param[in] dev netdev device, needs to be already initialized
* @see @ref gnrc_netif_create()
*
* @return PID of LWMAC thread on success
* @return -EINVAL if creation of thread fails
* @return -ENODEV if *dev* is invalid
* @return The network interface on success.
* @return NULL, on error.
*/
kernel_pid_t gnrc_lwmac_init(char *stack, int stacksize, char priority,
const char *name, gnrc_netdev_t *dev);
gnrc_netif_t *gnrc_netif_lwmac_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev);
#ifdef __cplusplus
}
#endif

View File

@ -25,7 +25,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/lwmac/types.h"
#ifdef __cplusplus
@ -40,52 +40,52 @@ extern "C" {
/**
* @brief Set LWMAC timeout of type @p type of offset @p offset.
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif the network interface
* @param[in] type LWMAC timeout type
* @param[in] offset timeout offset
*/
void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
void gnrc_lwmac_set_timeout(gnrc_netif_t *netif,
gnrc_lwmac_timeout_type_t type,
uint32_t offset);
/**
* @brief Clear LWMAC timeout of type @p type.
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif the network interface
* @param[in] type LWMAC timeout type
*/
void gnrc_lwmac_clear_timeout(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type);
void gnrc_lwmac_clear_timeout(gnrc_netif_t *netif, gnrc_lwmac_timeout_type_t type);
/**
* @brief Check whether LWMAC timeout of type @p type is running.
*
* @param[in] gnrc_netdev gnrc_netdev structure
* @param[in] netif the network interface
* @param[in] type LWMAC timeout type
*
* @return true, if timeout of type @p type is running.
* @return false, if timeout of type @p type is not running.
*/
bool gnrc_lwmac_timeout_is_running(gnrc_netdev_t *gnrc_netdev,
bool gnrc_lwmac_timeout_is_running(gnrc_netif_t *netif,
gnrc_lwmac_timeout_type_t type);
/**
* @brief Check whether LWMAC timeout of type @p type is expired. It will clear
* the timeout once it is found expired.
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif the network interface
* @param[in] type LWMAC timeout type
*
* @return true, if timeout of type @p type is expired.
* @return false, if timeout of type @p type is not expired, or not exist.
*/
bool gnrc_lwmac_timeout_is_expired(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type);
bool gnrc_lwmac_timeout_is_expired(gnrc_netif_t *netif, gnrc_lwmac_timeout_type_t type);
/**
* @brief Reset all LWMAC timeouts.
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif the network interface
*/
void gnrc_lwmac_reset_timeouts(gnrc_netdev_t *gnrc_netdev);
void gnrc_lwmac_reset_timeouts(gnrc_netif_t *netif);
/**
* @brief Make a specific LWMAC timeout expired.

View File

@ -109,32 +109,32 @@ extern "C" {
* @brief Internal states of LWMAC
*/
typedef enum {
GNRC_LWMAC_UNDEF = -1, /**< Undefined state of LWMAC */
GNRC_LWMAC_STOPPED, /**< LWMAC's main state machine has been stopped */
GNRC_LWMAC_START, /**< Start LWMAC's main state machine */
GNRC_LWMAC_STOP, /**< Stop LWMAC's main state machine */
GNRC_LWMAC_RESET, /**< Reset LWMAC's main state machine */
GNRC_LWMAC_LISTENING, /**< Listen the channel for receiving packets */
GNRC_LWMAC_RECEIVING, /**< RX is handled in own state machine */
GNRC_LWMAC_TRANSMITTING, /**< TX is handled in own state machine */
GNRC_LWMAC_SLEEPING, /**< Turn off radio to conserve power */
GNRC_LWMAC_STATE_COUNT /**< Count of LWMAC's states */
GNRC_LWMAC_UNDEF = -1, /**< Undefined state of LWMAC */
GNRC_LWMAC_STOPPED, /**< LWMAC's main state machine has been stopped */
GNRC_LWMAC_START, /**< Start LWMAC's main state machine */
GNRC_LWMAC_STOP, /**< Stop LWMAC's main state machine */
GNRC_LWMAC_RESET, /**< Reset LWMAC's main state machine */
GNRC_LWMAC_LISTENING, /**< Listen the channel for receiving packets */
GNRC_LWMAC_RECEIVING, /**< RX is handled in own state machine */
GNRC_LWMAC_TRANSMITTING, /**< TX is handled in own state machine */
GNRC_LWMAC_SLEEPING, /**< Turn off radio to conserve power */
GNRC_LWMAC_STATE_COUNT /**< Count of LWMAC's states */
} gnrc_lwmac_state_t;
/**
* @brief TX states of LWMAC
*/
typedef enum {
GNRC_LWMAC_TX_STATE_STOPPED, /**< Tx schedule stopped, stop sending packet */
GNRC_LWMAC_TX_STATE_INIT, /**< Initiate transmission */
GNRC_LWMAC_TX_STATE_SEND_BROADCAST, /**< directly goes to SUCCESSFUL or FAILED when finished */
GNRC_LWMAC_TX_STATE_SEND_WR, /**< Send a wakeup request */
GNRC_LWMAC_TX_STATE_WAIT_WR_SENT, /**< Wait until WR sent to set timeout */
GNRC_LWMAC_TX_STATE_WAIT_FOR_WA, /**< Wait for dest node's wakeup ackknowledge */
GNRC_LWMAC_TX_STATE_SEND_DATA, /**< Send the actual payload data */
GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK, /**< Wait if packet was ACKed */
GNRC_LWMAC_TX_STATE_SUCCESSFUL, /**< Transmission has finished successfully */
GNRC_LWMAC_TX_STATE_FAILED /**< Payload data couldn't be delivered to dest */
GNRC_LWMAC_TX_STATE_STOPPED, /**< Tx schedule stopped, stop sending packet */
GNRC_LWMAC_TX_STATE_INIT, /**< Initiate transmission */
GNRC_LWMAC_TX_STATE_SEND_BROADCAST, /**< directly goes to SUCCESSFUL or FAILED when finished */
GNRC_LWMAC_TX_STATE_SEND_WR, /**< Send a wakeup request */
GNRC_LWMAC_TX_STATE_WAIT_WR_SENT, /**< Wait until WR sent to set timeout */
GNRC_LWMAC_TX_STATE_WAIT_FOR_WA, /**< Wait for dest node's wakeup ackknowledge */
GNRC_LWMAC_TX_STATE_SEND_DATA, /**< Send the actual payload data */
GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK, /**< Wait if packet was ACKed */
GNRC_LWMAC_TX_STATE_SUCCESSFUL, /**< Transmission has finished successfully */
GNRC_LWMAC_TX_STATE_FAILED /**< Payload data couldn't be delivered to dest */
} gnrc_lwmac_tx_state_t;
/**
@ -146,14 +146,14 @@ typedef enum {
* @brief RX states of LWMAC
*/
typedef enum {
GNRC_LWMAC_RX_STATE_STOPPED, /**< Rx schedule stopped */
GNRC_LWMAC_RX_STATE_INIT, /**< Initiate reception */
GNRC_LWMAC_RX_STATE_WAIT_FOR_WR, /**< Wait for a wakeup request */
GNRC_LWMAC_RX_STATE_SEND_WA, /**< Send wakeup ackknowledge to requesting node */
GNRC_LWMAC_RX_STATE_WAIT_WA_SENT, /**< Wait until WA sent to set timeout */
GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA, /**< Wait for actual payload data */
GNRC_LWMAC_RX_STATE_SUCCESSFUL, /**< Recption has finished successfully */
GNRC_LWMAC_RX_STATE_FAILED /**< Reception over, but nothing received */
GNRC_LWMAC_RX_STATE_STOPPED, /**< Rx schedule stopped */
GNRC_LWMAC_RX_STATE_INIT, /**< Initiate reception */
GNRC_LWMAC_RX_STATE_WAIT_FOR_WR, /**< Wait for a wakeup request */
GNRC_LWMAC_RX_STATE_SEND_WA, /**< Send wakeup ackknowledge to requesting node */
GNRC_LWMAC_RX_STATE_WAIT_WA_SENT, /**< Wait until WA sent to set timeout */
GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA, /**< Wait for actual payload data */
GNRC_LWMAC_RX_STATE_SUCCESSFUL, /**< Recption has finished successfully */
GNRC_LWMAC_RX_STATE_FAILED /**< Reception over, but nothing received */
} gnrc_lwmac_rx_state_t;
/**
@ -175,14 +175,14 @@ typedef enum {
* @brief LWMAC timeout types
*/
typedef enum {
GNRC_LWMAC_TIMEOUT_DISABLED, /**< Timeout is diabled */
GNRC_LWMAC_TIMEOUT_WR, /**< WR timeout, waiting WA */
GNRC_LWMAC_TIMEOUT_NO_RESPONSE, /**< Maximum WR duration timeout awaiting WA */
GNRC_LWMAC_TIMEOUT_DATA, /**< Timeout awaiting data packet from receiver */
GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, /**< Timeout for waiting receiver's wake-up phase */
GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD, /**< Wake up period timeout for going to sleep */
GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST, /**< Timeout for waiting to send the next broadcast packet */
GNRC_LWMAC_TIMEOUT_BROADCAST_END, /**< Timeout awaiting the end of the whole broadcast period */
GNRC_LWMAC_TIMEOUT_DISABLED, /**< Timeout is diabled */
GNRC_LWMAC_TIMEOUT_WR, /**< WR timeout, waiting WA */
GNRC_LWMAC_TIMEOUT_NO_RESPONSE, /**< Maximum WR duration timeout awaiting WA */
GNRC_LWMAC_TIMEOUT_DATA, /**< Timeout awaiting data packet from receiver */
GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, /**< Timeout for waiting receiver's wake-up phase */
GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD, /**< Wake up period timeout for going to sleep */
GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST, /**< Timeout for waiting to send the next broadcast packet */
GNRC_LWMAC_TIMEOUT_BROADCAST_END, /**< Timeout awaiting the end of the whole broadcast period */
} gnrc_lwmac_timeout_type_t;
/**
@ -199,19 +199,19 @@ typedef struct {
* @brief LWMAC specific structure for storing internal states.
*/
typedef struct lwmac {
gnrc_lwmac_state_t state; /**< Internal state of MAC layer */
uint32_t last_wakeup; /**< Used to calculate wakeup times */
uint8_t lwmac_info; /**< LWMAC's internal informations (flags) */
gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
gnrc_lwmac_state_t state; /**< Internal state of MAC layer */
uint32_t last_wakeup; /**< Used to calculate wakeup times */
uint8_t lwmac_info; /**< LWMAC's internal informations (flags) */
gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
#if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
/* Parameters for recording duty-cycle */
uint32_t last_radio_on_time_ticks; /**< The last time in ticks when radio is on */
uint32_t radio_off_time_ticks; /**< The time in ticks when radio is off */
uint32_t system_start_time_ticks; /**< The time in ticks when chip is started */
uint32_t awake_duration_sum_ticks; /**< The sum of time in ticks when radio is on */
uint32_t pkt_start_sending_time_ticks; /**< The time in ticks when the packet is started
to be sent */
uint32_t last_radio_on_time_ticks; /**< The last time in ticks when radio is on */
uint32_t radio_off_time_ticks; /**< The time in ticks when radio is off */
uint32_t system_start_time_ticks; /**< The time in ticks when chip is started */
uint32_t awake_duration_sum_ticks; /**< The sum of time in ticks when radio is on */
uint32_t pkt_start_sending_time_ticks; /**< The time in ticks when the packet is started
to be sent */
#endif
} gnrc_lwmac_t;

View File

@ -24,12 +24,76 @@
#include <stdint.h>
#include "net/ieee802154.h"
#include "net/gnrc/mac/types.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief get the 'rx_started' state of the device
*
* This function checks whether the device has started receiving a packet.
*
* @param[in] netif the network interface
*
* @return the rx_started state
*/
static inline bool gnrc_netif_get_rx_started(gnrc_netif_t *netif)
{
return (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_RX_STARTED);
}
/**
* @brief set the rx_started state of the device
*
* This function is intended to be called only in netdev_t::event_callback().
*
* @param[in] netif the network interface
* @param[in] rx_started the rx_started state
*/
static inline void gnrc_netif_set_rx_started(gnrc_netif_t *netif, bool rx_started)
{
if (rx_started) {
netif->mac.mac_info |= GNRC_NETIF_MAC_INFO_RX_STARTED;
}
else {
netif->mac.mac_info &= ~GNRC_NETIF_MAC_INFO_RX_STARTED;
}
}
/**
* @brief get the transmission feedback of the device
*
* @param[in] netif the network interface
*
* @return the transmission feedback
*/
static inline gnrc_mac_tx_feedback_t gnrc_netif_get_tx_feedback(gnrc_netif_t *netif)
{
return (gnrc_mac_tx_feedback_t)(netif->mac.mac_info &
GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK);
}
/**
* @brief set the transmission feedback of the device
*
* This function is intended to be called only in netdev_t::event_callback().
*
* @param[in] netif the network interface
* @param[in] txf the transmission feedback
*/
static inline void gnrc_netif_set_tx_feedback(gnrc_netif_t *netif,
gnrc_mac_tx_feedback_t txf)
{
/* check if gnrc_mac_tx_feedback does not collide with
* GNRC_NETIF_MAC_INFO_RX_STARTED */
assert(!(txf & GNRC_NETIF_MAC_INFO_RX_STARTED));
/* unset previous value */
netif->mac.mac_info &= ~GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK;
netif->mac.mac_info |= (uint16_t)(txf & GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK);
}
#if (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN)
/**
* @brief Queues the packet into the related transmission packet queue in netdev_t::tx.

View File

@ -1,401 +1,124 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
* more details.
* 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_gnrc_ndp IPv6 Neighbor discovery
* @ingroup net_gnrc_icmpv6
* @brief GNRC's IPv6 Neighbor Discovery implementation
* @defgroup net_gnrc_ndp IPv6 neighbor discovery (v2)
* @ingroup net_gnrc_ipv6
* @brief Provides build and send functions for neighbor discovery packets
* @{
*
* @file
* @brief Definitions for GNRC's IPv6 Neighbor Discovery
* @brief GNRC-specific neighbor discovery definitions
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NDP_H
#define NET_GNRC_NDP_H
#include <inttypes.h>
#include <stdlib.h>
#include <stdint.h>
#include "byteorder.h"
#include "net/ndp.h"
#include "kernel_types.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/icmpv6.h"
#include "net/gnrc/netif.h"
#include "net/ipv6/addr.h"
#include "net/gnrc/ipv6/nc.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/ndp/host.h"
#include "net/gnrc/ndp/internal.h"
#include "net/gnrc/ndp/router.h"
#include "net/gnrc/ndp/node.h"
#include "net/ipv6/hdr.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Message type for router timeouts */
#define GNRC_NDP_MSG_RTR_TIMEOUT (0x0210)
/** Message type for address timeouts */
#define GNRC_NDP_MSG_ADDR_TIMEOUT (0x0211)
/** Message type for multicast neighbor solicitation retransmissions */
#define GNRC_NDP_MSG_NBR_SOL_RETRANS (0x0212)
/** Message type for periodic router advertisements */
#define GNRC_NDP_MSG_RTR_ADV_RETRANS (0x0213)
/** Message type for delayed router advertisements */
#define GNRC_NDP_MSG_RTR_ADV_DELAY (0x0214)
/** Message type for delayed router advertisements in a 6LoWPAN
* 6LoWPAN needs a special handling, because router advertisements are only
* sent after a short randomized delay, but not periodically. */
#define GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY (0x0215)
/** Message type for periodic router solicitations */
#define GNRC_NDP_MSG_RTR_SOL_RETRANS (0x0216)
/** Message type for neighbor cache state timeouts */
#define GNRC_NDP_MSG_NC_STATE_TIMEOUT (0x0217)
/**
* @name Host constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc4861#section-10">
* RFC 4861, section 10
* </a>
* @brief @ref net_gnrc_nettype to send NDP packets to
*/
/**
* @brief Upper bound for randomised delay in seconds for initial
* router solicitation transmissions
*/
#define GNRC_NDP_MAX_RTR_SOL_DELAY (1U)
/**
* @brief Interval in seconds between initial router solicitation
* transmissions
*/
#define GNRC_NDP_MAX_RTR_SOL_INT (4U)
/**
* @brief Maximum number of initial router solicitation transmissions
*/
#define GNRC_NDP_MAX_RTR_SOL_NUMOF (3U)
/** @} */
/**
* @name Node constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc4861#section-10">
* RFC 4861, section 10
* </a>
*/
/**
* @brief Maximum number of unanswered multicast neighbor solicitations
* before address resolution is considered failed.
*/
#define GNRC_NDP_MAX_MC_NBR_SOL_NUMOF (3U)
/**
* @brief Maximum number of unanswered unicast neighbor solicitations before
* an address is considered unreachable.
*/
#define GNRC_NDP_MAX_UC_NBR_SOL_NUMOF (3U)
/**
* @brief Upper bound of randomized delay in seconds for a solicited
* neighbor advertisement transmission for an anycast target.
*/
#define GNRC_NDP_MAX_AC_TGT_DELAY (1U)
/**
* @brief Maximum number of unsolicited neighbor advertisements before on
* link-layer address change.
*/
#define GNRC_NDP_MAX_NBR_ADV_NUMOF (3U)
/**
* @brief Base value in mircoseconds for computing randomised
* reachable time.
*/
#define GNRC_NDP_REACH_TIME (30U * US_PER_SEC)
/**
* @brief Time in mircoseconds between retransmissions of neighbor
* solicitations to a neighbor.
*/
#define GNRC_NDP_RETRANS_TIMER (1U * US_PER_SEC)
/**
* @brief Delay in seconds for neighbor cache entry between entering
* DELAY state and entering PROBE state if no reachability
* confirmation has been received.
*/
#define GNRC_NDP_FIRST_PROBE_DELAY (5U)
/**
* @brief Lower bound for randomised reachable time calculation.
*/
#define GNRC_NDP_MIN_RAND (5U)
/**
* @brief Upper bound for randomised reachable time calculation.
*/
#define GNRC_NDP_MAX_RAND (15U)
/** @} */
/**
* @name Router constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc4861#section-10">
* RFC 4861, section 10
* </a>
*/
/**
* @brief Initial router advertisement interval in seconds
*/
#define GNRC_NDP_MAX_INIT_RTR_ADV_INT (16U)
/**
* @brief Maximum number of initial router advertisement transmissions
*/
#define GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF (3U)
/**
* @brief Maximum number of final router advertisement transmissions
*/
#define GNRC_NDP_MAX_FIN_RTR_ADV_NUMOF (3U)
/**
* @brief Minimum delay in seconds between router advertisement
* transmissions
*/
#define GNRC_NDP_MIN_RTR_ADV_DELAY (3U)
/**
* @brief Upper bound for randomised delay in microseconds between router
* solicitation reception and responding router advertisement
* transmission.
*/
#define GNRC_NDP_MAX_RTR_ADV_DELAY (500U * US_PER_MS)
/** @} */
/**
* @brief Handles received neighbor solicitations.
*
* @param[in] iface The receiving interface.
* @param[in] pkt The received packet.
* @param[in] ipv6 The IPv6 header in @p pkt.
* @param[in] nbr_sol The neighbor solicitation in @p pkt.
* @param[in] icmpv6_size The overall size of the neighbor solicitation.
*/
void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
ipv6_hdr_t *ipv6, ndp_nbr_sol_t *nbr_sol,
size_t icmpv6_size);
/**
* @brief Handles received neighbor advertisements.
*
* @param[in] iface The receiving interface.
* @param[in] pkt The received packet.
* @param[in] ipv6 The IPv6 header in @p pkt.
* @param[in] nbr_adv The neighbor advertisement in @p pkt.
* @param[in] icmpv6_size The overall size of the neighbor advertisement.
*/
void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
ipv6_hdr_t *ipv6, ndp_nbr_adv_t *nbr_adv,
size_t icmpv6_size);
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Handles received router solicitations.
*
* @param[in] iface The receiving interface.
* @param[in] pkt The received packet.
* @param[in] ipv6 The IPv6 header in @p pkt.
* @param[in] rtr_sol The router solicitation in @p pkt.
* @param[in] icmpv6_size The overall size of the router solicitation.
*/
void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
ipv6_hdr_t *ipv6, ndp_rtr_sol_t *rtr_sol,
size_t icmpv6_size);
#else
/**
* @brief A host *must* silently discard all received router solicitations.
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.6">
* RFC 4861, section 6.2.6
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6, rtr_sol, size)
#endif
/**
* @brief Handles received router advertisements
*
* @todo As router check consistency as described in RFC 4861, section 6.2.3
*
* @param[in] iface The receiving interface.
* @param[in] pkt The received packet.
* @param[in] ipv6 The IPv6 header in @p pkt.
* @param[in] rtr_adv The router advertisement in @p pkt.
* @param[in] icmpv6_size The overall size of the router advertisement.
*/
void gnrc_ndp_rtr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
ipv6_hdr_t *ipv6, ndp_rtr_adv_t *rtr_adv,
size_t icmpv6_size);
/**
* @brief Retransmits a multicast neighbor solicitation for an incomplete or
* probing neighbor cache entry @p nc_entry,
* if nc_entry::probes_remaining > 0.
*
* @details If nc_entry::probes_remaining > 0 it will be decremented. If it
* reaches 0 it the entry @p nc_entry will be removed from the
* neighbor cache.
*
* @param[in] nc_entry A neighbor cache entry. Will be ignored if its state
* is not @ref GNRC_IPV6_NC_STATE_INCOMPLETE or
* @ref GNRC_IPV6_NC_STATE_PROBE.
*/
void gnrc_ndp_retrans_nbr_sol(gnrc_ipv6_nc_t *nc_entry);
/**
* @brief Event handler for a neighbor cache state timeout.
*
* @param[in] nc_entry A neighbor cache entry.
*/
void gnrc_ndp_state_timeout(gnrc_ipv6_nc_t *nc_entry);
/**
* @brief NDP interface initialization.
*
* @param[in] iface An IPv6 interface descriptor. Must not be NULL.
*/
void gnrc_ndp_netif_add(gnrc_ipv6_netif_t *iface);
/**
* @brief NDP interface removal.
*
* @param[in] iface An IPv6 interface descriptor. Must not be NULL.
*/
void gnrc_ndp_netif_remove(gnrc_ipv6_netif_t *iface);
/**
* @brief Get link-layer address and interface for next hop to destination
* IPv6 address.
*
* @param[out] l2addr The link-layer for the next hop to @p dst.
* @param[out] l2addr_len Length of @p l2addr.
* @param[in] iface The interface to search the next hop on.
* May be @ref KERNEL_PID_UNDEF if not specified.
* @param[in] dst An IPv6 address to search the next hop for.
* @param[in] pkt Packet to send to @p dst. Leave NULL if you
* just want to get the addresses.
*
* @return The PID of the interface, on success.
* @return -EHOSTUNREACH, if @p dst is not reachable.
* @return -ENOBUFS, if @p l2addr_len was smaller than the resulting @p l2addr
* would be long.
*/
kernel_pid_t gnrc_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
kernel_pid_t iface, ipv6_addr_t *dst,
gnrc_pktsnip_t *pkt);
#ifndef GNRC_NETTYPE_NDP
# if defined(MODULE_GNRC_IPV6) || DOXYGEN
# define GNRC_NETTYPE_NDP (GNRC_NETTYPE_IPV6) /* usual configuration */
# else
# define GNRC_NETTYPE_NDP (GNRC_NETTYPE_UNDEF) /* for testing */
# endif
#endif /* GNRC_NETTYPE_NDP */
/**
* @brief Builds a neighbor solicitation message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.3">
* RFC 4861, section 4.3
* </a>
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
*
* @param[in] tgt The target address.
* @param[in] options Options to append to the router solicitation.
* @see [RFC 4861, section 4.3](https://tools.ietf.org/html/rfc4861#section-4.3)
*
* @param[in] tgt The target address of the neighbor solicitation.
* May not be NULL and **MUST NOT** be multicast.
* @param[in] options Options to append to the neighbor solicitation.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp_nbr_sol_build(ipv6_addr_t *tgt, gnrc_pktsnip_t *options);
gnrc_pktsnip_t *gnrc_ndp_nbr_sol_build(const ipv6_addr_t *tgt,
gnrc_pktsnip_t *options);
/**
* @brief Builds a neighbor advertisement message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.4">
* RFC 4861, section 4.4
* </a>
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
*
* @see [RFC 4861, section 4.4](https://tools.ietf.org/html/rfc4861#section-4.4")
*
* @param[in] flags Neighbor advertisement flags:
* @ref NDP_NBR_ADV_FLAGS_R == 1 indicates, that the
* sender is a router,
* @ref NDP_NBR_ADV_FLAGS_S == 1 indicates that the
* advertisement was sent in response to a neighbor
* solicitation,
* @ref NDP_NBR_ADV_FLAGS_O == 1 indicates that the
* advertisement should override an existing cache entry
* and update the cached link-layer address.
* @param[in] tgt For solicited advertisements, the Target Address field
* in the neighbor solicitaton.
* For and unsolicited advertisement, the address whose
* link-layer address has changed.
* MUST NOT be multicast.
* May not be NULL and **MUST NOT** be multicast.
* @param[in] flags Neighbor advertisement flags:
* - @ref NDP_NBR_ADV_FLAGS_R == 1 indicates, that the
* sender is a router,
* - @ref NDP_NBR_ADV_FLAGS_S == 1 indicates that the
* advertisement was sent in response to a neighbor
* solicitation,
* - @ref NDP_NBR_ADV_FLAGS_O == 1 indicates that the
* advertisement should override an existing cache entry
* and update the cached link-layer address.
* @param[in] options Options to append to the neighbor advertisement.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp_nbr_adv_build(uint8_t flags, ipv6_addr_t *tgt,
gnrc_pktsnip_t *gnrc_ndp_nbr_adv_build(const ipv6_addr_t *tgt, uint8_t flags,
gnrc_pktsnip_t *options);
/**
* @brief Builds a router solicitation message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1">
* RFC 4861, section 4.1
* </a>
* @see `[RFC 4861, section 4.1](https://tools.ietf.org/html/rfc4861#section-4.1")
*
* @param[in] options Options to append to the router solicitation.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);
/**
* @brief Builds a router solicitation message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.1">
* RFC 4861, section 4.1
* </a>
*
* @param[in] options Options to append to the router solicitation.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
*/
gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Builds a router advertisement message for sending.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.2">
* RFC 4861, section 4.2
* </a>
* @see `[RFC 4861, section 4.2](https://tools.ietf.org/html/rfc4861#section-4.2")
*
* @note The source address for the packet MUST be the link-local address
* of the interface.
*
* @param[in] cur_hl Default hop limit for outgoing IP packets, 0 if
* unspecified by this router.
* @param[in] flags Flags as defined above.
* @ref NDP_RTR_ADV_FLAGS_M == 1 indicates, that the
* addresses are managed by DHCPv6,
* @ref NDP_RTR_ADV_FLAGS_O == 1 indicates that other
* configuration information is available via DHCPv6.
* @param[in] flags Flags as defined in net/ndp.h.
* - @ref NDP_RTR_ADV_FLAGS_M == 1 indicates, that the
* addresses are managed by DHCPv6,
* - @ref NDP_RTR_ADV_FLAGS_O == 1 indicates that other
* configuration information is available via DHCPv6.
* @param[in] ltime Lifetime of the default router in seconds.
* @param[in] reach_time Time in milliseconds a node should assume a neighbor
* reachable. 0 means unspecified by the router.
@ -403,25 +126,15 @@ gnrc_pktsnip_t *gnrc_ndp_rtr_sol_build(gnrc_pktsnip_t *options);
* neighbor solicitations. 0 means unspecified by
* the router.
* @param[in] options Options to append to the router advertisement.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, on failure.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags, uint16_t ltime,
uint32_t reach_time, uint32_t retrans_timer,
gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags,
uint16_t ltime, uint32_t reach_time,
uint32_t retrans_timer,
gnrc_pktsnip_t *options);
#else
/**
* @brief A host *must not* send router advertisements at any time (so why build them?)
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
* RFC 4861, section 6.3.4
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_rtr_adv_build(cur_hl, flags, ltime, reach_time, retrans_timer, options) (NULL)
#endif
/**
* @brief Builds a generic NDP option.
@ -434,92 +147,99 @@ gnrc_pktsnip_t *gnrc_ndp_rtr_adv_build(uint8_t cur_hl, uint8_t flags, uint16_t l
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_build(uint8_t type, size_t size, gnrc_pktsnip_t *next);
gnrc_pktsnip_t *gnrc_ndp_opt_build(uint8_t type, size_t size,
gnrc_pktsnip_t *next);
/**
* @brief Builds the source link-layer address option.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.1">
* RFC 4861, section 4.6.1
* </a>
* @pre `(l2addr != NULL) && (l2addr_len != 0)`
*
* @note Must only be used with neighbor solicitations, router solicitations,
* @see [RFC 4861, section 4.6.1](https://tools.ietf.org/html/rfc4861#section-4.6.1)
*
* @note Should only be used with neighbor solicitations, router solicitations,
* and router advertisements. This is not checked however, since
* hosts should silently ignore it in other NDP messages.
*
* @param[in] l2addr A link-layer address of variable length.
* @param[in] l2addr_len Length of @p l2addr.
* May not be NULL.
* @param[in] l2addr_len Length of @p l2addr. May not be 0.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_sl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
gnrc_pktsnip_t *gnrc_ndp_opt_sl2a_build(const uint8_t *l2addr,
uint8_t l2addr_len,
gnrc_pktsnip_t *next);
/**
* @brief Builds the target link-layer address option.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.1">
* RFC 4861, section 4.6.1
* </a>
* @pre `(l2addr != NULL) && (l2addr_len != 0)`
*
* @note Must only be used with neighbor advertisemnents and redirect packets.
* @see [RFC 4861, section 4.6.1](https://tools.ietf.org/html/rfc4861#section-4.6.1)
*
* @note Should only be used with neighbor advertisemnents and redirect packets.
* This is not checked however, since hosts should silently ignore it
* in other NDP messages.
*
* @param[in] l2addr A link-layer address of variable length.
* @param[in] l2addr_len Length of @p l2addr.
* May not be NULL.
* @param[in] l2addr_len Length of @p l2addr. May not be 0.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The pkt snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_tl2a_build(const uint8_t *l2addr, uint8_t l2addr_len,
gnrc_pktsnip_t *gnrc_ndp_opt_tl2a_build(const uint8_t *l2addr,
uint8_t l2addr_len,
gnrc_pktsnip_t *next);
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Builds the prefix information option.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.2">
* RFC 4861, section 4.6.2
* </a>
* @pre `prefix != NULL`
* @pre `!ipv6_addr_is_link_local(prefix) && !ipv6_addr_is_multicast(prefix)`
* @pre `prefix_len <= 128`
*
* @note Must only be used with router advertisemnents. This is not checked
* @see [RFC 4861, section 4.6.2](https://tools.ietf.org/html/rfc4861#section-4.6.2)
*
* @note Should only be used with router advertisemnents. This is not checked
* however, since nodes should silently ignore it in other NDP messages.
*
* @param[in] prefix An IPv6 address or a prefix of an IPv6 address.
* May not be NULL and must not be link-local or
* multicast.
* @param[in] prefix_len The length of @p prefix in bits. Must be between
* 0 and 128.
* @param[in] flags Flags as defined above.
* @ref NDP_OPT_PI_FLAGS_L == 1 indicates, that
* @p prefix can be used for on-link determination,
* @ref NDP_OPT_PI_FLAGS_A == 1 indicates, that
* @p prefix can be used for stateless address
* configuration.
* @param[in] valid_ltime Length of time in seconds that @p prefix is valid.
* UINT32_MAX represents infinity.
* @param[in] pref_ltime Length of time in seconds that addresses using
* @p prefix remain prefered. UINT32_MAX represents
* infinity.
* @param[in] prefix An IPv6 address or a prefix of an IPv6 address.
* @param[in] flags Flags as defined in net/ndp.h.
* - @ref NDP_OPT_PI_FLAGS_L == 1 indicates, that
* @p prefix can be used for on-link determination,
* - @ref NDP_OPT_PI_FLAGS_A == 1 indicates, that
* @p prefix can be used for stateless address
* configuration.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(uint8_t prefix_len, uint8_t flags,
gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(const ipv6_addr_t *prefix,
uint8_t prefix_len,
uint32_t valid_ltime, uint32_t pref_ltime,
ipv6_addr_t *prefix, gnrc_pktsnip_t *next);
uint8_t flags, gnrc_pktsnip_t *next);
/**
* @brief Builds the MTU option.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-4.6.4">
* RFC 4861, section 4.6.4
* </a>
* @see [RFC 4861, section 4.6.4](https://tools.ietf.org/html/rfc4861#section-4.6.4)
*
* @note Must only be used with router advertisemnents. This is not checked
* @note Should only be used with router advertisemnents. This is not checked
* however, since nodes should silently ignore it in other NDP messages.
*
* @param[in] mtu The recommended MTU for the link.
@ -529,35 +249,120 @@ gnrc_pktsnip_t *gnrc_ndp_opt_pi_build(uint8_t prefix_len, uint8_t flags,
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next);
#else
/**
* @brief A host *must not* send router advertisements at any time (so why build their options?)
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
* RFC 4861, section 6.3.4
* </a>
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_opt_pi_build(prefix_len, flags, valid_ltime, pref_ltime, prefix, next) (NULL)
/**
* @brief A host *must not* send router advertisements at any time (so why build their options?)
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.4">
* RFC 4861, section 6.3.4
* </a>
* @brief Send pre-compiled neighbor solicitation depending on a given network
* interface.
*
* This macro is primarily an optimization to not go into the function defined
* above.
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
* @pre `(netif != NULL) && (dst != NULL)`
*
* @param[in] tgt The target address of the neighbor solicitation.
* May not be NULL and **MUST NOT** be multicast.
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] src Source address for the neighbor solicitation. Will be
* chosen from the interface according to @p dst, if NULL.
* @param[in] dst Destination address for neighbor solicitation. May not
* be NULL.
* @param[in] ext_opts External options for the neighbor advertisement.
* Leave NULL for none.
* **Warning:** these are not tested if they are suitable
* for a neighbor solicitation so be sure to check that.
* **Will be released** in an error case.
*/
#define gnrc_ndp_opt_mtu_build(mtu, next) (NULL)
#endif
void gnrc_ndp_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst,
gnrc_pktsnip_t *ext_opts);
/**
* @brief Send pre-compiled neighbor advertisement depending on a given
* network interface.
*
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
* @pre `(netif != NULL) && (dst != NULL)`
*
* If @p netif is a forwarding interface and router advertisements are
* activated the @ref NDP_NBR_ADV_FLAGS_R is set in the neighbor advertisement.
* If @p dst is @ref IPV6_ADDR_UNSPECIFIED it will be replaced with
* @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL and* @p supply_tl2a is set to true
* implicitly. Otherwise, the @ref NDP_NBR_ADV_FLAGS_S will be set. If @p tgt
* is an anycast address on @p netif the @ref NDP_NBR_ADV_FLAGS_O flag will be
* set.
*
* The source address of the IPv6 packet will be left unspecified, so the
* @ref net_gnrc_ipv6 "IPv6 module" selects a fitting IPv6 address.
*
* @param[in] tgt Target address for the neighbor advertisement. May
* not be NULL and **MUST NOT** be multicast.
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] dst Destination address for neighbor advertisement. May
* not be NULL. Is set to
* @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL when equal to
* @ref IPV6_ADDR_UNSPECIFIED (to allow for simple
* reply mechanisms to neighbor solicitations). This
* also implies that @p supply_tl2a **must** be true
* and the parameter will be reset accordingly. If
* @p dst is not @ref IPV6_ADDR_UNSPECIFIED, the
* @ref NDP_NBR_ADV_FLAGS_S flag will be set
* implicitly.
* @param[in] supply_tl2a Add target link-layer address option to neighbor
* advertisement if link-layer has addresses.
* If @p dst is @ref IPV6_ADDR_UNSPECIFIED, it will be
* set to true.
* @param[in] ext_opts External options for the neighbor advertisement.
* Leave NULL for none.
* **Warning:** these are not tested if they are
* suitable for a neighbor advertisement so be sure to
* check that.
* **Will be released** in an error case.
*/
void gnrc_ndp_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_netif_t *netif,
const ipv6_addr_t *dst, bool supply_tl2a,
gnrc_pktsnip_t *ext_opts);
/**
* @brief Send pre-compiled router solicitation depending on a given
* network interface.
*
* @pre `(netif != NULL)`
*
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] dst Destination for the router solicitation. ff02::2 if NULL.
*/
void gnrc_ndp_rtr_sol_send(gnrc_netif_t *netif, const ipv6_addr_t *dst);
/**
* @brief Send pre-compiled router advertisement depending on a given network
* interface.
*
* @pre `(netif != NULL)`
*
* This function does not add the PIOs to the router, since they are highly
* dependent on external set-ups (e.g. if multihop prefix distribution is used).
* Provide them via @p ext_opts
*
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] src Source address for the router advertisement. May be
* NULL to be determined by source address selection
* (:: if @p netif has no address).
* @param[in] dst Destination address for router advertisement.
* ff02::1 if NULL.
* @param[in] fin This is part of the router's final batch of router
* advertisements before ceising to be a router (set's
* router lifetime field to 0).
* @param[in] ext_opts External options for the neighbor advertisement.
* Leave NULL for none.
* **Warning:** these are not tested if they are suitable
* for a neighbor advertisement so be sure to check that.
* **Will be released** in an error case.
*/
void gnrc_ndp_rtr_adv_send(gnrc_netif_t *netif, const ipv6_addr_t *src,
const ipv6_addr_t *dst, bool fin,
gnrc_pktsnip_t *ext_opts);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NDP_H */
/**
* @}
*/
/** @} */

View File

@ -1,54 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_ndp_host Host-specific part of router discovery.
* @ingroup net_gnrc_ndp
* @brief Host-specific part for the router discovery in IPv6
* neighbor discovery.
* @{
*
* @file
* @brief Host-specific router discovery definitions
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NDP_HOST_H
#define NET_GNRC_NDP_HOST_H
#include "net/gnrc/ipv6/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes interface @p iface as host.
*
* @pre iface != NULL
*
* @param[in] iface An IPv6 interface
*/
void gnrc_ndp_host_init(gnrc_ipv6_netif_t *iface);
/**
* @brief Sends a router solicitation over interface @p iface
* and reset the timer for the next one.
*
* @pre iface != NULL
*
* @param[in] iface An IPv6 interface
*/
void gnrc_ndp_host_retrans_rtr_sol(gnrc_ipv6_netif_t *iface);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NDP_HOST_H */
/** @} */

View File

@ -1,215 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_ndp_internal Internal functions for neighbor discovery.
* @ingroup net_gnrc_ndp
* @brief Internal functions for neighbor discovery.
* @internal
* @note Only for use with a neighbor discovery implementations.
* @{
*
* @file
* @brief Internal neighbor discovery functions for neighbor discovery.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NDP_INTERNAL_H
#define NET_GNRC_NDP_INTERNAL_H
#include "kernel_types.h"
#include "net/gnrc/ipv6/nc.h"
#include "net/ipv6/addr.h"
#include "net/ipv6/hdr.h"
#include "net/ndp.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get best match from default router list.
*
* @internal
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.3.6">
* RFC 4861, section 6.3.6
* </a>
*
* @return Address to a default router.
* @return NULL, if the default router list is empty.
*/
ipv6_addr_t *gnrc_ndp_internal_default_router(void);
/**
* @brief Sets state of a neighbor cache entry and triggers required actions.
*
* @internal
*
* @param[in] nc_entry A neighbor cache entry.
* @param[in] state The new state for the neighbor cache entry.
*/
void gnrc_ndp_internal_set_state(gnrc_ipv6_nc_t *nc_entry, uint8_t state);
/**
* @brief Send precompiled neighbor solicitation.
*
* @internal
*
* @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF.
* @param[in] src Source address for the neighbor solicitation. Will be chosen from the
* interface according to @p dst, if NULL.
* @param[in] tgt Target address for the neighbor solicitation. May not be
* NULL.
* @param[in] dst Destination address for neighbor solicitation. May not be
* NULL.
*/
void gnrc_ndp_internal_send_nbr_sol(kernel_pid_t iface, ipv6_addr_t *src, ipv6_addr_t *tgt,
ipv6_addr_t *dst);
/**
* @brief Send precompiled neighbor advertisement.
*
* @internal
*
* @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF.
* @param[in] tgt Target address for the neighbor solicitation. May
* not be NULL.
* @param[in] dst Destination address for neighbor solicitation. May
* not be NULL.
* @param[in] supply_tl2a Add target link-layer address option to neighbor
* advertisement if link-layer has addresses.
* @param[in] ext_opts External options for the neighbor advertisement. Leave NULL for none.
* **Warning:** these are not tested if they are suitable for a
* neighbor advertisement so be sure to check that.
* **Will be released** in an error case.
*/
void gnrc_ndp_internal_send_nbr_adv(kernel_pid_t iface, ipv6_addr_t *tgt, ipv6_addr_t *dst,
bool supply_tl2a, gnrc_pktsnip_t *ext_opts);
/**
* @brief Send precompiled router solicitation to @p dst.
*
* @internal
*
* @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF.
* @param[in] dst Destination for the router solicitation. ff02::2 if NULL.
*/
void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst);
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
/**
* @brief Handles received router solicitations.
*
* @param[in] iface Interface to send over. May not be KERNEL_PID_UNDEF.
* @param[in] src Source address for the router advertisement. May be NULL to be determined
* by source address selection (:: if no @p iface has no address).
* @param[in] dst Destination address for router advertisement.
* @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL if NULL.
* @param[in] fin This is part of the router's final batch of router advertisements
* before ceising to be a router (set's router lifetime field to 0).
*/
void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src,
ipv6_addr_t *dst, bool fin);
#else
/**
* @brief A host *must not* send router advertisements at any time.
*
* This macro is primarily an optimization to not go into the function defined
* above.
*/
#define gnrc_ndp_internal_send_rtr_adv(iface, src, dst, fin)
#endif
/**
* @brief Handles a SL2A option.
*
* @param[in] pkt Packet the option was received in.
* @param[in] ipv6 IPv6 header of @p pkt
* @param[in] icmpv6_type ICMPv6 type of the message carrying the option.
* @param[in] tl2a_opt The TL2A option.
* @param[out] l2addr The L2 address carried in the SL2A option.
*
* @return length of the L2 address, on success.
* @return -EINVAL, if SL2A was not valid.
* @return -ENOTSUP, if node should silently ignore the option.
*/
int gnrc_ndp_internal_sl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6, uint8_t icmpv6_type,
ndp_opt_t *sl2a_opt, uint8_t *l2addr);
/**
* @brief Handles a TL2A option.
*
* @param[in] pkt Packet the option was received in.
* @param[in] ipv6 IPv6 header of @p pkt
* @param[in] icmpv6_type ICMPv6 type of the message carrying the option.
* @param[in] tl2a_opt The TL2A option.
* @param[out] l2addr The L2 address carried in the TL2A option.
*
* @return length of the L2 address, on success.
* @return -EINVAL, if TL2A was not valid.
* @return -ENOTSUP, if node should silently ignore the option.
*/
int gnrc_ndp_internal_tl2a_opt_handle(gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6,
uint8_t icmpv6_type, ndp_opt_t *tl2a_opt,
uint8_t *l2addr);
/**
* @brief Handles a MTU option.
*
* @internal
*
* @param[in] iface Interface the MTU option was received on.
* @param[in] icmpv6_type ICMPv6 type of the message carrying the option.
* @param[in] mtu_opt A MTU option.
*
* @return true, on success (or if the node should silently ignore the option).
* @return false, if MTU option was not valid.
*/
bool gnrc_ndp_internal_mtu_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type,
ndp_opt_mtu_t *mtu_opt);
/**
* @brief Handles a PI option.
*
* @internal
*
* @param[in] iface Interface the PI option was received on.
* @param[in] icmpv6_type ICMPv6 type of the message carrying the option.
* @param[in] pi_opt A PI option.
*
* @return true, on success (or if the node should silently ignore the option).
* @return false, if PIO was not valid.
*/
bool gnrc_ndp_internal_pi_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type,
ndp_opt_pi_t *pi_opt);
/**
* @brief Resets the gnrc_ipv6_nc_t::nbr_sol_timer.
*
* @internal
*
* @param[in] nc_entry A neighbor cache entry.
* @param[in] delay The delay when the timer should fire.
* @param[in] type The msg_t::type for the timer.
* @param[in] pid The pid of the receiver thread of the msg_t
*/
static inline void gnrc_ndp_internal_reset_nbr_sol_timer(gnrc_ipv6_nc_t *nc_entry, uint32_t delay,
uint16_t type, kernel_pid_t pid)
{
xtimer_remove(&nc_entry->nbr_sol_timer);
nc_entry->nbr_sol_msg.type = type;
xtimer_set_msg(&nc_entry->nbr_sol_timer, delay, &nc_entry->nbr_sol_msg, pid);
}
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NDP_INTERNAL_H */
/** @} */

View File

@ -1,53 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_ndp_node Neighbor discovery for pure IPv6 nodes
* @ingroup net_gnrc_ndp
* @brief Used for pure IPv6 nodes (without 6LoWPAN).
* @{
*
* @file
* @brief IPv6-node neighbor discovery definitions
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NDP_NODE_H
#define NET_GNRC_NDP_NODE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get link-layer address and interface for next hop to destination
* IPv6 address.
*
* @param[out] l2addr The link-layer for the next hop to @p dst.
* @param[out] l2addr_len Length of @p l2addr.
* @param[in] iface The interface to search the next hop on.
* May be @ref KERNEL_PID_UNDEF if not specified.
* @param[in] dst An IPv6 address to search the next hop for.
* @param[in] pkt Packet to send to @p dst. Leave NULL if you
* just want to get the addresses.
*
* @return The PID of the interface, on success.
* @return -EHOSTUNREACH, if @p dst is not reachable.
* @return -ENOBUFS, if @p l2addr_len was smaller than the resulting @p l2addr
* would be long.
*/
kernel_pid_t gnrc_ndp_node_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
kernel_pid_t iface, ipv6_addr_t *dst,
gnrc_pktsnip_t *pkt);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NDP_NODE_H */
/** @} */

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_ndp_router Router-specific part of router discovery.
* @ingroup net_gnrc_ndp
* @brief Router-specific part for the router discovery in IPv6
* neighbor discovery.
* @{
*
* @file
* @brief Router-specific router discovery definitions
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NDP_ROUTER_H
#define NET_GNRC_NDP_ROUTER_H
#include <stdbool.h>
#include "kernel_types.h"
#include "net/ipv6/hdr.h"
#include "net/ndp.h"
#include "net/gnrc/ipv6/nc.h"
#include "timex.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set @p iface to router mode.
*
* @details This sets/unsets the GNRC_IPV6_NETIF_FLAGS_ROUTER and
* GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases router
* behavior for neighbor discovery.
*
* @param[in] iface An IPv6 interface. Must not be NULL.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_ROUTER and
* GNRC_IPV6_NETIF_FLAGS_RTR_ADV flags.
*/
void gnrc_ndp_router_set_router(gnrc_ipv6_netif_t *iface, bool enable);
/**
* @brief Set/Unset GNRC_IPV6_NETIF_FLAGS_RTR_ADV flag for @p iface.
*
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.2">
* RFC 4861, section 6.2.2
* </a>
* @see <a href="https://tools.ietf.org/html/rfc4861#section-6.2.5">
* RFC 4861, section 6.2.5
* </a>
*
* @details GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases
* periodic router advertising behavior for neighbor discovery.
*
* @param[in] iface An IPv6 interface. Must not be NULL.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_RTR_ADV flags.
*/
void gnrc_ndp_router_set_rtr_adv(gnrc_ipv6_netif_t *iface, bool enable);
/**
* @brief Send an unsolicited router advertisement over @p iface
* and reset the timer for the next one if necessary.
*
* @param[in] iface An IPv6 interface.
*/
void gnrc_ndp_router_retrans_rtr_adv(gnrc_ipv6_netif_t *iface);
/**
* @brief Send an solicited router advertisement to IPv6 address of
* @p neighbor.
*
* @param[in] neighbor A neighbor cache entry.
*/
void gnrc_ndp_router_send_rtr_adv(gnrc_ipv6_nc_t *neighbor);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NDP_ROUTER_H */
/** @} */

View File

@ -1,367 +0,0 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_ndp2 IPv6 neighbor discovery (v2)
* @ingroup net_gnrc_ipv6
* @brief Provides build and send functions for neighbor discovery packets
* @{
*
* @file
* @brief GNRC-specific neighbor discovery definitions
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NDP2_H
#define NET_GNRC_NDP2_H
#include <stdint.h>
#include "kernel_types.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/ipv6/addr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief @ref net_gnrc_nettype to send NDP packets to
*/
#ifndef GNRC_NETTYPE_NDP2
# if defined(MODULE_GNRC_IPV6) || DOXYGEN
# define GNRC_NETTYPE_NDP2 (GNRC_NETTYPE_IPV6) /* usual configuration */
# else
# define GNRC_NETTYPE_NDP2 (GNRC_NETTYPE_UNDEF) /* for testing */
# endif
#endif /* GNRC_NETTYPE_NDP2 */
/**
* @brief Builds a neighbor solicitation message for sending.
*
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
*
* @see [RFC 4861, section 4.3](https://tools.ietf.org/html/rfc4861#section-4.3)
*
* @param[in] tgt The target address of the neighbor solicitation.
* May not be NULL and **MUST NOT** be multicast.
* @param[in] options Options to append to the neighbor solicitation.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp2_nbr_sol_build(const ipv6_addr_t *tgt,
gnrc_pktsnip_t *options);
/**
* @brief Builds a neighbor advertisement message for sending.
*
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
*
* @see [RFC 4861, section 4.4](https://tools.ietf.org/html/rfc4861#section-4.4")
*
* @param[in] tgt For solicited advertisements, the Target Address field
* in the neighbor solicitaton.
* For and unsolicited advertisement, the address whose
* link-layer address has changed.
* May not be NULL and **MUST NOT** be multicast.
* @param[in] flags Neighbor advertisement flags:
* - @ref NDP_NBR_ADV_FLAGS_R == 1 indicates, that the
* sender is a router,
* - @ref NDP_NBR_ADV_FLAGS_S == 1 indicates that the
* advertisement was sent in response to a neighbor
* solicitation,
* - @ref NDP_NBR_ADV_FLAGS_O == 1 indicates that the
* advertisement should override an existing cache entry
* and update the cached link-layer address.
* @param[in] options Options to append to the neighbor advertisement.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp2_nbr_adv_build(const ipv6_addr_t *tgt, uint8_t flags,
gnrc_pktsnip_t *options);
/**
* @brief Builds a router solicitation message for sending.
*
* @see `[RFC 4861, section 4.1](https://tools.ietf.org/html/rfc4861#section-4.1")
*
* @param[in] options Options to append to the router solicitation.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp2_rtr_sol_build(gnrc_pktsnip_t *options);
/**
* @brief Builds a router advertisement message for sending.
*
* @see `[RFC 4861, section 4.2](https://tools.ietf.org/html/rfc4861#section-4.2")
*
* @note The source address for the packet MUST be the link-local address
* of the interface.
*
* @param[in] cur_hl Default hop limit for outgoing IP packets, 0 if
* unspecified by this router.
* @param[in] flags Flags as defined in net/ndp.h.
* - @ref NDP_RTR_ADV_FLAGS_M == 1 indicates, that the
* addresses are managed by DHCPv6,
* - @ref NDP_RTR_ADV_FLAGS_O == 1 indicates that other
* configuration information is available via DHCPv6.
* @param[in] ltime Lifetime of the default router in seconds.
* @param[in] reach_time Time in milliseconds a node should assume a neighbor
* reachable. 0 means unspecified by the router.
* @param[in] retrans_timer Time in milliseconds between retransmitted
* neighbor solicitations. 0 means unspecified by
* the router.
* @param[in] options Options to append to the router advertisement.
* May be NULL for none.
*
* @return The resulting ICMPv6 packet on success.
* @return NULL, if packet buffer is full.
*/
gnrc_pktsnip_t *gnrc_ndp2_rtr_adv_build(uint8_t cur_hl, uint8_t flags,
uint16_t ltime, uint32_t reach_time,
uint32_t retrans_timer,
gnrc_pktsnip_t *options);
/**
* @brief Builds a generic NDP option.
*
* @param[in] type Type of the option.
* @param[in] size Size in byte of the option (will be rounded up to the next
* multiple of 8).
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp2_opt_build(uint8_t type, size_t size,
gnrc_pktsnip_t *next);
/**
* @brief Builds the source link-layer address option.
*
* @pre `(l2addr != NULL) && (l2addr_len != 0)`
*
* @see [RFC 4861, section 4.6.1](https://tools.ietf.org/html/rfc4861#section-4.6.1)
*
* @note Should only be used with neighbor solicitations, router solicitations,
* and router advertisements. This is not checked however, since
* hosts should silently ignore it in other NDP messages.
*
* @param[in] l2addr A link-layer address of variable length.
* May not be NULL.
* @param[in] l2addr_len Length of @p l2addr. May not be 0.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp2_opt_sl2a_build(const uint8_t *l2addr,
uint8_t l2addr_len,
gnrc_pktsnip_t *next);
/**
* @brief Builds the target link-layer address option.
*
* @pre `(l2addr != NULL) && (l2addr_len != 0)`
*
* @see [RFC 4861, section 4.6.1](https://tools.ietf.org/html/rfc4861#section-4.6.1)
*
* @note Should only be used with neighbor advertisemnents and redirect packets.
* This is not checked however, since hosts should silently ignore it
* in other NDP messages.
*
* @param[in] l2addr A link-layer address of variable length.
* May not be NULL.
* @param[in] l2addr_len Length of @p l2addr. May not be 0.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The pkt snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp2_opt_tl2a_build(const uint8_t *l2addr,
uint8_t l2addr_len,
gnrc_pktsnip_t *next);
/**
* @brief Builds the prefix information option.
*
* @pre `prefix != NULL`
* @pre `!ipv6_addr_is_link_local(prefix) && !ipv6_addr_is_multicast(prefix)`
* @pre `prefix_len <= 128`
*
* @see [RFC 4861, section 4.6.2](https://tools.ietf.org/html/rfc4861#section-4.6.2)
*
* @note Should only be used with router advertisemnents. This is not checked
* however, since nodes should silently ignore it in other NDP messages.
*
* @param[in] prefix An IPv6 address or a prefix of an IPv6 address.
* May not be NULL and must not be link-local or
* multicast.
* @param[in] prefix_len The length of @p prefix in bits. Must be between
* 0 and 128.
* @param[in] valid_ltime Length of time in seconds that @p prefix is valid.
* UINT32_MAX represents infinity.
* @param[in] pref_ltime Length of time in seconds that addresses using
* @p prefix remain prefered. UINT32_MAX represents
* infinity.
* @param[in] flags Flags as defined in net/ndp.h.
* - @ref NDP_OPT_PI_FLAGS_L == 1 indicates, that
* @p prefix can be used for on-link determination,
* - @ref NDP_OPT_PI_FLAGS_A == 1 indicates, that
* @p prefix can be used for stateless address
* configuration.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp2_opt_pi_build(const ipv6_addr_t *prefix,
uint8_t prefix_len,
uint32_t valid_ltime, uint32_t pref_ltime,
uint8_t flags, gnrc_pktsnip_t *next);
/**
* @brief Builds the MTU option.
*
* @see [RFC 4861, section 4.6.4](https://tools.ietf.org/html/rfc4861#section-4.6.4)
*
* @note Should only be used with router advertisemnents. This is not checked
* however, since nodes should silently ignore it in other NDP messages.
*
* @param[in] mtu The recommended MTU for the link.
* @param[in] next More options in the packet. NULL, if there are none.
*
* @return The packet snip list of options, on success
* @return NULL, if packet buffer is full
*/
gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next);
/**
* @brief Send pre-compiled neighbor solicitation depending on a given network
* interface.
*
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
* @pre `(netif != NULL) && (dst != NULL)`
*
* @param[in] tgt The target address of the neighbor solicitation.
* May not be NULL and **MUST NOT** be multicast.
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] src Source address for the neighbor solicitation. Will be
* chosen from the interface according to @p dst, if NULL.
* @param[in] dst Destination address for neighbor solicitation. May not
* be NULL.
* @param[in] ext_opts External options for the neighbor advertisement.
* Leave NULL for none.
* **Warning:** these are not tested if they are suitable
* for a neighbor solicitation so be sure to check that.
* **Will be released** in an error case.
*/
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst,
gnrc_pktsnip_t *ext_opts);
/**
* @brief Send pre-compiled neighbor advertisement depending on a given
* network interface.
*
* @pre `(tgt != NULL) && !ipv6_addr_is_multicast(tgt)`
* @pre `(netif != NULL) && (dst != NULL)`
*
* If @p netif is a forwarding interface and router advertisements are
* activated the @ref NDP_NBR_ADV_FLAGS_R is set in the neighbor advertisement.
* If @p dst is @ref IPV6_ADDR_UNSPECIFIED it will be replaced with
* @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL and* @p supply_tl2a is set to true
* implicitly. Otherwise, the @ref NDP_NBR_ADV_FLAGS_S will be set. If @p tgt
* is an anycast address on @p netif the @ref NDP_NBR_ADV_FLAGS_O flag will be
* set.
*
* The source address of the IPv6 packet will be left unspecified, so the
* @ref net_gnrc_ipv6 "IPv6 module" selects a fitting IPv6 address.
*
* @param[in] tgt Target address for the neighbor advertisement. May
* not be NULL and **MUST NOT** be multicast.
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] dst Destination address for neighbor advertisement. May
* not be NULL. Is set to
* @ref IPV6_ADDR_ALL_NODES_LINK_LOCAL when equal to
* @ref IPV6_ADDR_UNSPECIFIED (to allow for simple
* reply mechanisms to neighbor solicitations). This
* also implies that @p supply_tl2a **must** be true
* and the parameter will be reset accordingly. If
* @p dst is not @ref IPV6_ADDR_UNSPECIFIED, the
* @ref NDP_NBR_ADV_FLAGS_S flag will be set
* implicitly.
* @param[in] supply_tl2a Add target link-layer address option to neighbor
* advertisement if link-layer has addresses.
* If @p dst is @ref IPV6_ADDR_UNSPECIFIED, it will be
* set to true.
* @param[in] ext_opts External options for the neighbor advertisement.
* Leave NULL for none.
* **Warning:** these are not tested if they are
* suitable for a neighbor advertisement so be sure to
* check that.
* **Will be released** in an error case.
*/
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
const ipv6_addr_t *dst, bool supply_tl2a,
gnrc_pktsnip_t *ext_opts);
/**
* @brief Send pre-compiled router solicitation depending on a given
* network interface.
*
* @pre `(netif != NULL)`
*
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] dst Destination for the router solicitation. ff02::2 if NULL.
*/
void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst);
/**
* @brief Send pre-compiled router advertisement depending on a given network
* interface.
*
* @pre `(netif != NULL)`
*
* This function does not add the PIOs to the router, since they are highly
* dependent on external set-ups (e.g. if multihop prefix distribution is used).
* Provide them via @p ext_opts
*
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] src Source address for the router advertisement. May be
* NULL to be determined by source address selection
* (:: if @p netif has no address).
* @param[in] dst Destination address for router advertisement.
* ff02::1 if NULL.
* @param[in] fin This is part of the router's final batch of router
* advertisements before ceising to be a router (set's
* router lifetime field to 0).
* @param[in] ext_opts External options for the neighbor advertisement.
* Leave NULL for none.
* **Warning:** these are not tested if they are suitable
* for a neighbor advertisement so be sure to check that.
* **Will be released** in an error case.
*/
void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
const ipv6_addr_t *dst, bool fin,
gnrc_pktsnip_t *ext_opts);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NDP2_H */
/** @} */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -7,7 +7,7 @@
*/
/**
* @defgroup net_gnrc_netif Network interfaces
* @defgroup net_gnrc_netif New network interface API
* @ingroup net_gnrc
* @brief Abstraction layer for GNRC's network interfaces
*
@ -17,90 +17,267 @@
* @{
*
* @file
* @brief Definitions for GNRC's network interfaces
* @brief Definition for GNRC's network interfaces
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#ifndef NET_GNRC_NETIF_H
#define NET_GNRC_NETIF_H
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "kernel_types.h"
#include "msg.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/netif/conf.h"
#ifdef MODULE_GNRC_SIXLOWPAN
#include "net/gnrc/netif/6lo.h"
#endif
#include "net/gnrc/netif/flags.h"
#ifdef MODULE_GNRC_IPV6
#include "net/gnrc/netif/ipv6.h"
#endif
#ifdef MODULE_GNRC_MAC
#include "net/gnrc/netif/mac.h"
#endif
#include "net/netdev.h"
#include "rmutex.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Maximum number of network interfaces
* @brief Operations to an interface
*/
#ifndef GNRC_NETIF_NUMOF
#define GNRC_NETIF_NUMOF (1)
#endif
typedef struct gnrc_netif_ops gnrc_netif_ops_t;
/**
* @brief The add/remove operation to set network layer protocol
* specific options for an interface.
*
* @param[in] pid The PID to the new interface.
*/
typedef void (*gnrc_netif_op_t)(kernel_pid_t pid);
/**
* @brief The add and remove handlers to set network layer protocol
* specific options for an interface.
*
* @details If you implement a pair, please add it to the list in gnrc_netif.c
* statically.
* @brief Representation of a network interface
*/
typedef struct {
gnrc_netif_op_t add; /**< The add operation */
gnrc_netif_op_t remove; /**< The remove operation */
} gnrc_netif_handler_t;
const gnrc_netif_ops_t *ops; /**< Operations of the network interface */
netdev_t *dev; /**< Network device of the network interface */
rmutex_t mutex; /**< Mutex of the interface */
#if defined(MODULE_GNRC_IPV6) || DOXYGEN
gnrc_netif_ipv6_t ipv6; /**< IPv6 component */
#endif
#if defined(MODULE_GNRC_MAC) || DOXYGEN
gnrc_netif_mac_t mac; /**< @ref net_gnrc_mac component */
#endif /* MODULE_GNRC_MAC */
/**
* @brief Flags for the interface
*
* @see net_gnrc_netif_flags
*/
uint32_t flags;
#if (GNRC_NETIF_L2ADDR_MAXLEN > 0)
/**
* @brief The link-layer address currently used as the source address
* on this interface.
*
* @note Only available if @ref GNRC_NETIF_L2ADDR_MAXLEN > 0
*/
uint8_t l2addr[GNRC_NETIF_L2ADDR_MAXLEN];
/**
* @brief Length in bytes of gnrc_netif_t::l2addr
*
* @note Only available if @ref GNRC_NETIF_L2ADDR_MAXLEN > 0
*/
uint8_t l2addr_len;
#endif
#if defined(MODULE_GNRC_SIXLOWPAN) || DOXYGEN
gnrc_netif_6lo_t sixlo; /**< 6Lo component */
#endif
uint8_t cur_hl; /**< Current hop-limit for out-going packets */
uint8_t device_type; /**< Device type */
kernel_pid_t pid; /**< PID of the network interface's thread */
} gnrc_netif_t;
/**
* @brief Initializes module.
* @see gnrc_netif_ops_t
*/
void gnrc_netif_init(void);
struct gnrc_netif_ops {
/**
* @brief Initializes network interface beyond the default settings
*
* @pre `netif != NULL`
*
* @param[in] netif The network interface.
*
* This is called after the default settings were set, right before the
* interface's thread starts receiving messages. It is not necessary to lock
* the interface's mutex gnrc_netif_t::mutex, since the thread will already
* lock it. Leave NULL if you do not need any special initialization.
*/
void (*init)(gnrc_netif_t *netif);
/**
* @brief Send a @ref net_gnrc_pkt "packet" over the network interface
*
* @pre `netif != NULL && pkt != NULL`
*
* @note The function re-formats the content of @p pkt to a format expected
* by the netdev_driver_t::send() method of gnrc_netif_t::dev and
* releases the packet before returning (so no additional release
* should be required after calling this method).
*
* @param[in] netif The network interface.
* @param[in] pkt A packet to send.
*
* @return The number of bytes actually sent on success
* @return -EBADMSG, if the @ref net_gnrc_netif_hdr in @p pkt is missing
* or is in an unexpected format.
* @return -ENOTSUP, if sending @p pkt in the given format isn't supported
* (e.g. empty payload with Ethernet).
* @return Any negative error code reported by gnrc_netif_t::dev.
*/
int (*send)(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
/**
* @brief Receives a @ref net_gnrc_pkt "packet" from the network interface
*
* @pre `netif != NULL`
*
* @note The function takes the bytes received via netdev_driver_t::recv()
* from gnrc_netif_t::dev and re-formats it to a
* @ref net_gnrc_pkt "packet" containing a @ref net_gnrc_netif_hdr
* and a payload header in receive order.
*
* @param[in] netif The network interface.
*
* @return The packet received. Contains the payload (with the type marked
* accordingly) and a @ref net_gnrc_netif_hdr in receive order.
* @return NULL, if @ref net_gnrc_pktbuf was full.
*/
gnrc_pktsnip_t *(*recv)(gnrc_netif_t *netif);
/**
* @brief Gets an option from the network interface
*
* Use gnrc_netif_get_from_netdev() to just get options from
* gnrc_netif_t::dev.
*
* @param[in] netif The network interface.
* @param[in] opt The option parameters.
*
* @return Number of bytes in @p data.
* @return -EOVERFLOW, if @p max_len is lesser than the required space.
* @return -ENOTSUP, if @p opt is not supported to be set.
* @return Any negative error code reported by gnrc_netif_t::dev.
*/
int (*get)(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt);
/**
* @brief Sets an option from the network interface
*
* Use gnrc_netif_set_from_netdev() to just set options from
* gnrc_netif_t::dev.
*
* @param[in] netif The network interface.
* @param[in] opt The option parameters.
*
* @return Number of bytes written to gnrc_netif_t::dev.
* @return -EOVERFLOW, if @p data_len is greater than the allotted space in
* gnrc_netif_t::dev or gnrc_netif_t.
* @return -ENOTSUP, if @p opt is not supported to be set.
* @return Any negative error code reported by gnrc_netif_t::dev.
*/
int (*set)(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt);
/**
* @brief Message handler for network interface
*
* This message handler is used, when the network interface needs to handle
* message types beyond the ones defined in @ref net_gnrc_netapi "netapi".
* Leave NULL if this is not the case.
*
* @param[in] netif The network interface.
* @param[in] msg Message to be handled.
*/
void (*msg_handler)(gnrc_netif_t *netif, msg_t *msg);
};
/**
* @brief Adds a thread as interface.
* @brief Creates a network interface
*
* @param[in] pid PID of the added thread.
* @param[in] stack The stack for the network interface's thread.
* @param[in] stacksize Size of @p stack.
* @param[in] priority Priority for the network interface's thread.
* @param[in] name Name for the network interface. May be NULL.
* @param[in] dev Device for the interface.
* @param[in] ops Operations for the network interface.
*
* @return 0, on success,
* @return -ENOMEM, if maximum number of interfaces has been exceeded.
* @note If @ref DEVELHELP is defined netif_params_t::name is used as the
* name of the network interface's thread.
*
* @attention Fails and crashes (assertion error with @ref DEVELHELP or
* segmentation fault without) if `GNRC_NETIF_NUMOF` is lower than
* the number of calls to this function.
*
* @return The network interface on success.
*/
int gnrc_netif_add(kernel_pid_t pid);
gnrc_netif_t *gnrc_netif_create(char *stack, int stacksize, char priority,
const char *name, netdev_t *dev,
const gnrc_netif_ops_t *ops);
/**
* @brief Removes a thread as interface.
* @brief Get number of network interfaces actually allocated
*
* @param[in] pid PID of the removed thread.
* @return Number of network interfaces actually allocated
*/
void gnrc_netif_remove(kernel_pid_t pid);
unsigned gnrc_netif_numof(void);
/**
* @brief Get all active interfaces.
* @brief Iterate over all network interfaces.
*
* @param[out] netifs List of all active interfaces. There is no order ensured.
* It must at least fit @ref GNRC_NETIF_NUMOF elements.
* @param[in] prev previous interface in iteration. NULL to start iteration.
*
* @return The number of active interfaces.
* @return The next network interface after @p prev.
* @return NULL, if @p prev was the last network interface.
*/
size_t gnrc_netif_get(kernel_pid_t *netifs);
gnrc_netif_t *gnrc_netif_iter(const gnrc_netif_t *prev);
/**
* @brief Check if an interface exist.
* @brief Get network interface by PID
*
* @param[in] pid The PID to be checked.
* @param[in] pid A PID of a network interface.
*
* @return True, if an interface @p pid exists.
* @return False, otherwise
* @return The network interface on success.
* @return NULL, if no network interface with PID exists.
*/
bool gnrc_netif_exist(kernel_pid_t pid);
gnrc_netif_t *gnrc_netif_get_by_pid(kernel_pid_t pid);
/**
* @brief Default operation for gnrc_netif_ops_t::get()
*
* @note Can also be used to be called *after* a custom operation.
*
* @param[in] netif The network interface.
* @param[out] opt The option parameters.
*
* @return Return value of netdev_driver_t::get() of gnrc_netif_t::dev of
* @p netif.
*/
int gnrc_netif_get_from_netdev(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt);
/**
* @brief Default operation for gnrc_netif_ops_t::set()
*
* @note Can also be used to be called *after* a custom operation.
*
* @param[in] netif The network interface.
* @param[in] opt The option parameters.
*
* @return Return value of netdev_driver_t::set() of gnrc_netif_t::dev of
* @p netif.
*/
int gnrc_netif_set_from_netdev(gnrc_netif_t *netif,
const gnrc_netapi_opt_t *opt);
/**
* @brief Converts a hardware address to a human readable string.
@ -108,19 +285,17 @@ bool gnrc_netif_exist(kernel_pid_t pid);
* @details The format will be like `xx:xx:xx:xx` where `xx` are the bytes
* of @p addr in hexadecimal representation.
*
* @pre @p out_len >= 3 * @p addr_len
* @pre `(out != NULL) && ((addr != NULL) || (addr_len == 0))`
* @pre @p out **MUST** have allocated at least 3 * @p addr_len bytes.
*
* @param[out] out A string to store the output in.
* @param[out] out_len Length of @p out. Must be at least
* 3 * @p addr_len long.
* @param[in] addr A hardware address.
* @param[in] addr_len Length of @p addr.
* @param[out] out A string to store the output in. Must at least have
* 3 * @p addr_len bytes allocated.
*
* @return Copy of @p out on success.
* @return NULL, if @p out_len < 3 * @p addr_len.
* @return @p out.
*/
char *gnrc_netif_addr_to_str(char *out, size_t out_len, const uint8_t *addr,
size_t addr_len);
char *gnrc_netif_addr_to_str(const uint8_t *addr, size_t addr_len, char *out);
/**
* @brief Parses a string of colon-separated hexadecimals to a hardware
@ -129,14 +304,18 @@ char *gnrc_netif_addr_to_str(char *out, size_t out_len, const uint8_t *addr,
* @details The input format must be like `xx:xx:xx:xx` where `xx` will be the
* bytes of @p addr in hexadecimal representation.
*
* @param[out] out The resulting hardware address.
* @param[out] out_len Length of @p out.
* @pre `(out != NULL)`
* @pre @p out **MUST** have allocated at least
* @ref GNRC_NETIF_L2ADDR_MAXLEN bytes.
*
* @param[in] str A string of colon-separated hexadecimals.
* @param[out] out The resulting hardware address. Must at least have
* @ref GNRC_NETIF_L2ADDR_MAXLEN bytes allocated.
*
* @return Actual length of @p out on success.
* @return 0, on failure.
*/
size_t gnrc_netif_addr_from_str(uint8_t *out, size_t out_len, const char *str);
size_t gnrc_netif_addr_from_str(const char *str, uint8_t *out);
#ifdef __cplusplus
}

View File

@ -7,16 +7,16 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief 6LoWPAN definitions for @ref net_gnrc_netif2
* @brief 6LoWPAN definitions for @ref net_gnrc_netif
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_6LO_H
#define NET_GNRC_NETIF2_6LO_H
#ifndef NET_GNRC_NETIF_6LO_H
#define NET_GNRC_NETIF_6LO_H
#include <stdint.h>
@ -25,7 +25,7 @@ extern "C" {
#endif
/**
* @brief 6Lo component of @ref gnrc_netif2_t
* @brief 6Lo component of @ref gnrc_netif_t
*/
typedef struct {
/**
@ -35,11 +35,11 @@ typedef struct {
* @ref net_gnrc_sixlowpan_frag "gnrc_sixlowpan_frag".
*/
uint8_t max_frag_size;
} gnrc_netif2_6lo_t;
} gnrc_netif_6lo_t;
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_6LO_H */
#endif /* NET_GNRC_NETIF_6LO_H */
/** @} */

View File

@ -7,19 +7,20 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief Configuration macros for @ref net_gnrc_netif2
* @brief Configuration macros for @ref net_gnrc_netif
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_CONF_H
#define NET_GNRC_NETIF2_CONF_H
#ifndef NET_GNRC_NETIF_CONF_H
#define NET_GNRC_NETIF_CONF_H
#include "net/ieee802154.h"
#include "net/ethernet/hdr.h"
#include "net/gnrc/ipv6/nib/conf.h"
#include "thread.h"
#ifdef __cplusplus
@ -29,7 +30,7 @@ extern "C" {
/**
* @brief Maximum number of network interfaces
*
* @note Intentionally not calling it `GNRC_NETIF2_NUMOF` to not require
* @note Intentionally not calling it `GNRC_NETIF_NUMOF` to not require
* rewrites throughout the stack.
*/
#ifndef GNRC_NETIF_NUMOF
@ -39,31 +40,31 @@ extern "C" {
/**
* @brief Default priority for network interface threads
*/
#ifndef GNRC_NETIF2_PRIO
#define GNRC_NETIF2_PRIO (THREAD_PRIORITY_MAIN - 5)
#ifndef GNRC_NETIF_PRIO
#define GNRC_NETIF_PRIO (THREAD_PRIORITY_MAIN - 5)
#endif
/**
* @brief Number of multicast addresses needed for @ref net_gnrc_rpl "RPL".
*
* @note Used for calculation of @ref GNRC_NETIF2_IPV6_GROUPS_NUMOF
* @note Used for calculation of @ref GNRC_NETIF_IPV6_GROUPS_NUMOF
*/
#ifdef MODULE_GNRC_RPL
#define GNRC_NETIF2_RPL_ADDR (1)
#define GNRC_NETIF_RPL_ADDR (1)
#else
#define GNRC_NETIF2_RPL_ADDR (0)
#define GNRC_NETIF_RPL_ADDR (0)
#endif
/**
* @brief Number of multicast addresses needed for a @ref net_gnrc_ipv6 "IPv6"
* router
*
* @note Used for calculation of @ref GNRC_NETIF2_IPV6_GROUPS_NUMOF
* @note Used for calculation of @ref GNRC_NETIF_IPV6_GROUPS_NUMOF
*/
#ifdef MODULE_GNRC_IPV6_ROUTER
#define GNRC_NETIF2_IPV6_RTR_ADDR (1)
#if GNRC_IPV6_NIB_CONF_ROUTER
#define GNRC_NETIF_IPV6_RTR_ADDR (1)
#else
#define GNRC_NETIF2_IPV6_RTR_ADDR (0)
#define GNRC_NETIF_IPV6_RTR_ADDR (0)
#endif
/**
@ -71,18 +72,18 @@ extern "C" {
*
* Default: 2 (link-local + corresponding global address)
*/
#ifndef GNRC_NETIF2_IPV6_ADDRS_NUMOF
#define GNRC_NETIF2_IPV6_ADDRS_NUMOF (2)
#ifndef GNRC_NETIF_IPV6_ADDRS_NUMOF
#define GNRC_NETIF_IPV6_ADDRS_NUMOF (2)
#endif
/**
* @brief Maximum number of multicast groups per interface
*
* Default: 2 (all-nodes + solicited-nodes of link-local and global unicast
* address) + @ref GNRC_NETIF2_RPL_ADDR + @ref GNRC_NETIF2_IPV6_RTR_ADDR
* address) + @ref GNRC_NETIF_RPL_ADDR + @ref GNRC_NETIF_IPV6_RTR_ADDR
*/
#ifndef GNRC_NETIF2_IPV6_GROUPS_NUMOF
#define GNRC_NETIF2_IPV6_GROUPS_NUMOF (2 + GNRC_NETIF2_RPL_ADDR + GNRC_NETIF2_IPV6_RTR_ADDR)
#ifndef GNRC_NETIF_IPV6_GROUPS_NUMOF
#define GNRC_NETIF_IPV6_GROUPS_NUMOF (2 + GNRC_NETIF_RPL_ADDR + GNRC_NETIF_IPV6_RTR_ADDR)
#endif
/**
@ -101,25 +102,25 @@ extern "C" {
* @note Implementers note: From longest to shortest extend, if new link-layer
* address types are included
*/
#ifndef GNRC_NETIF2_L2ADDR_MAXLEN
#ifndef GNRC_NETIF_L2ADDR_MAXLEN
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
#define GNRC_NETIF2_L2ADDR_MAXLEN (IEEE802154_LONG_ADDRESS_LEN)
#define GNRC_NETIF_L2ADDR_MAXLEN (IEEE802154_LONG_ADDRESS_LEN)
#elif MODULE_NETDEV_ETH
#define GNRC_NETIF2_L2ADDR_MAXLEN (ETHERNET_ADDR_LEN)
#define GNRC_NETIF_L2ADDR_MAXLEN (ETHERNET_ADDR_LEN)
#elif MODULE_CC110X
#define GNRC_NETIF2_L2ADDR_MAXLEN (1U)
#define GNRC_NETIF_L2ADDR_MAXLEN (1U)
#else
#define GNRC_NETIF2_L2ADDR_MAXLEN (8U)
#define GNRC_NETIF_L2ADDR_MAXLEN (GNRC_IPV6_NIB_L2ADDR_MAX_LEN)
#endif
#endif
#ifndef GNRC_NETIF2_DEFAULT_HL
#define GNRC_NETIF2_DEFAULT_HL (64U) /**< default hop limit */
#ifndef GNRC_NETIF_DEFAULT_HL
#define GNRC_NETIF_DEFAULT_HL (64U) /**< default hop limit */
#endif
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_CONF_H */
#endif /* NET_GNRC_NETIF_CONF_H */
/** @} */

View File

@ -7,18 +7,18 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief Ethernet adaption for @ref net_gnrc_netif2
* @brief Ethernet adaption for @ref net_gnrc_netif
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_ETHERNET_H
#define NET_GNRC_NETIF2_ETHERNET_H
#ifndef NET_GNRC_NETIF_ETHERNET_H
#define NET_GNRC_NETIF_ETHERNET_H
#include "net/gnrc/netif2.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
@ -33,7 +33,7 @@ extern "C" {
* @param[in] name Name for the network interface. May be NULL.
* @param[in] dev Device for the interface.
*
* @see @ref gnrc_netif2_create()
* @see @ref gnrc_netif_create()
*
* @attention Fails and crashes (assertion error with @ref DEVELHELP or
* segmentation fault without) if `GNRC_NETIF_NUMOF` is lower than
@ -41,12 +41,12 @@ extern "C" {
*
* @return The network interface on success.
*/
gnrc_netif2_t *gnrc_netif2_ethernet_create(char *stack, int stacksize, char priority,
char *name, netdev_t *dev);
gnrc_netif_t *gnrc_netif_ethernet_create(char *stack, int stacksize, char priority,
char *name, netdev_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_ETHERNET_H */
#endif /* NET_GNRC_NETIF_ETHERNET_H */
/** @} */

View File

@ -7,16 +7,16 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief Flag definitions for @ref net_gnrc_netif2
* @brief Flag definitions for @ref net_gnrc_netif
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_FLAGS_H
#define NET_GNRC_NETIF2_FLAGS_H
#ifndef NET_GNRC_NETIF_FLAGS_H
#define NET_GNRC_NETIF_FLAGS_H
#ifdef __cplusplus
extern "C" {
@ -24,18 +24,18 @@ extern "C" {
/**
* @brief Auto-address configuration modes
* @anchor net_gnrc_netif2_aac
* @anchor net_gnrc_netif_aac
*/
enum {
GNRC_NETIF2_AAC_NONE = 0, /**< no configuration */
GNRC_NETIF2_AAC_AUTO, /**< Use some automatic bootstrapping (e.g. SLAAC with IPv6) */
GNRC_NETIF2_AAC_DHCP, /**< Use DHCP(v6) */
GNRC_NETIF_AAC_NONE = 0, /**< no configuration */
GNRC_NETIF_AAC_AUTO, /**< Use some automatic bootstrapping (e.g. SLAAC with IPv6) */
GNRC_NETIF_AAC_DHCP, /**< Use DHCP(v6) */
/* extend if needed */
};
/**
* @name Network interface flags
* @anchor net_gnrc_netif2_flags
* @anchor net_gnrc_netif_flags
* @{
*/
/**
@ -44,69 +44,69 @@ enum {
* There are link-layers (e.g. SLIP) that do not have (nor require) link-layer
* addresses. This flag signifies this fact to upper layers by leaving it unset.
*/
#define GNRC_NETIF2_FLAGS_HAS_L2ADDR (0x00000001U)
#define GNRC_NETIF_FLAGS_HAS_L2ADDR (0x00000001U)
/**
* @brief Network interface is enabled for IPv6 forwarding
*/
#define GNRC_NETIF2_FLAGS_IPV6_FORWARDING (0x00000002U)
#define GNRC_NETIF_FLAGS_IPV6_FORWARDING (0x00000002U)
/**
* @brief Network interface advertises itself as an IPv6 router
* (implies @ref GNRC_NETIF2_FLAGS_IPV6_FORWARDING to be set)
* (implies @ref GNRC_NETIF_FLAGS_IPV6_FORWARDING to be set)
*/
#define GNRC_NETIF2_FLAGS_IPV6_RTR_ADV (0x00000004U)
#define GNRC_NETIF_FLAGS_IPV6_RTR_ADV (0x00000004U)
/**
* @brief This interface advertises its gnrc_netif2_t::mtu to other nodes
* (implies @ref GNRC_NETIF2_FLAGS_IPV6_RTR_ADV to be set)
* @brief This interface advertises its gnrc_netif_t::mtu to other nodes
* (implies @ref GNRC_NETIF_FLAGS_IPV6_RTR_ADV to be set)
*/
#define GNRC_NETIF2_FLAGS_IPV6_ADV_MTU (0x00000008U)
#define GNRC_NETIF_FLAGS_IPV6_ADV_MTU (0x00000008U)
/**
* @brief This interface advertises its gnrc_netif2_t::cur_hl to other nodes
* (implies @ref GNRC_NETIF2_FLAGS_IPV6_RTR_ADV to be set)
* @brief This interface advertises its gnrc_netif_t::cur_hl to other nodes
* (implies @ref GNRC_NETIF_FLAGS_IPV6_RTR_ADV to be set)
*/
#define GNRC_NETIF2_FLAGS_IPV6_ADV_CUR_HL (0x00000010U)
#define GNRC_NETIF_FLAGS_IPV6_ADV_CUR_HL (0x00000010U)
/**
* @brief This interface advertises its reachable time to other nodes
* (implies @ref GNRC_NETIF2_FLAGS_IPV6_RTR_ADV to be set)
* (implies @ref GNRC_NETIF_FLAGS_IPV6_RTR_ADV to be set)
*/
#define GNRC_NETIF2_FLAGS_IPV6_ADV_REACH_TIME (0x00000020U)
#define GNRC_NETIF_FLAGS_IPV6_ADV_REACH_TIME (0x00000020U)
/**
* @brief This interface advertises its retransmission timer to other nodes
* (implies @ref GNRC_NETIF2_FLAGS_IPV6_RTR_ADV to be set)
* (implies @ref GNRC_NETIF_FLAGS_IPV6_RTR_ADV to be set)
*/
#define GNRC_NETIF2_FLAGS_IPV6_ADV_RETRANS_TIMER (0x00000040U)
#define GNRC_NETIF_FLAGS_IPV6_ADV_RETRANS_TIMER (0x00000040U)
/**
* @brief If gnrc_netif2_t::ipv6::aac_mode == GNRC_NETIF2_AAC_DHCP then this
* @brief If gnrc_netif_t::ipv6::aac_mode == GNRC_NETIF_AAC_DHCP then this
* flag indicates that other configuration information is available via
* DHCPv6 (e.g. DNS-related information)
*
* @see [RFC 4861, section 4.2](https://tools.ietf.org/html/rfc4861#section-4.2)
*/
#define GNRC_NETIF2_FLAGS_IPV6_ADV_O_FLAG (0x00000080U)
#define GNRC_NETIF_FLAGS_IPV6_ADV_O_FLAG (0x00000080U)
/**
* @brief This interface uses 6Lo header compression
*
* @see [RFC 6282](https://tools.ietf.org/html/rfc6282)
*/
#define GNRC_NETIF2_FLAGS_6LO_HC (0x00000100U)
#define GNRC_NETIF_FLAGS_6LO_HC (0x00000100U)
/**
* @brief This interface acts as a 6Lo border router to the LLN
*/
#define GNRC_NETIF2_FLAGS_6LO_ABR (0x00000200U)
#define GNRC_NETIF_FLAGS_6LO_ABR (0x00000200U)
/**
* @brief This interface acts as a mesh-under node (route-over topology when
* unset)
*/
#define GNRC_NETIF2_FLAGS_6LO_MESH (0x00000400U)
#define GNRC_NETIF_FLAGS_6LO_MESH (0x00000400U)
/**
* @brief Interface supports 6LoWPAN general header compression
@ -116,29 +116,29 @@ enum {
* @see [draft-ietf-6lo-rfc6775-update-09, section 6.3]
* (https://tools.ietf.org/html/draft-ietf-6lo-rfc6775-update-09#section-6.3)
*/
#define GNRC_NETIF2_FLAGS_6LO_BACKBONE (0x00000800U)
#define GNRC_NETIF_FLAGS_6LO_BACKBONE (0x00000800U)
/**
* @brief Marks if the addresses of the interface were already registered
* to an interface or not
*/
#define GNRC_NETIF2_FLAGS_6LO_ADDRS_REG (0x00001000U)
#define GNRC_NETIF_FLAGS_6LO_ADDRS_REG (0x00001000U)
/**
* @brief Mask for @ref gnrc_mac_tx_feedback_t
*/
#define GNRC_NETIF2_FLAGS_MAC_TX_FEEDBACK_MASK (0x00006000U)
#define GNRC_NETIF_FLAGS_MAC_TX_FEEDBACK_MASK (0x00006000U)
/**
* @brief Flag to track if a transmission might have corrupted a received
* packet
*/
#define GNRC_NETIF2_FLAGS_MAC_RX_STARTED (0x00008000U)
#define GNRC_NETIF_FLAGS_MAC_RX_STARTED (0x00008000U)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_FLAGS_H */
#endif /* NET_GNRC_NETIF_FLAGS_H */
/** @} */

View File

@ -7,18 +7,18 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief IEEE 802.15.4 adaption for @ref net_gnrc_netif2
* @brief IEEE 802.15.4 adaption for @ref net_gnrc_netif
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_IEEE802154_H
#define NET_GNRC_NETIF2_IEEE802154_H
#ifndef NET_GNRC_NETIF_IEEE802154_H
#define NET_GNRC_NETIF_IEEE802154_H
#include "net/gnrc/netif2.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
@ -33,18 +33,18 @@ extern "C" {
* @param[in] name Name for the network interface. May be NULL.
* @param[in] dev Device for the interface
*
* @see @ref gnrc_netif2_create()
* @see @ref gnrc_netif_create()
*
* @return The network interface on success.
* @return NULL, on error.
*/
gnrc_netif2_t *gnrc_netif2_ieee802154_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev);
gnrc_netif_t *gnrc_netif_ieee802154_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_IEEE802154_H */
#endif /* NET_GNRC_NETIF_IEEE802154_H */
/** @} */

View File

@ -18,10 +18,10 @@
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_INTERNAL_H
#define NET_GNRC_NETIF2_INTERNAL_H
#ifndef NET_GNRC_NETIF_INTERNAL_H
#define NET_GNRC_NETIF_INTERNAL_H
#include "net/gnrc/netif2.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
@ -39,12 +39,7 @@ extern "C" {
*
* @internal
*/
static inline void gnrc_netif2_acquire(gnrc_netif2_t *netif)
{
if (netif && (netif->ops)) {
rmutex_lock(&netif->mutex);
}
}
void gnrc_netif_acquire(gnrc_netif_t *netif);
/**
* @brief Releases exclusive access to the interface
@ -53,12 +48,7 @@ static inline void gnrc_netif2_acquire(gnrc_netif2_t *netif)
*
* @internal
*/
static inline void gnrc_netif2_release(gnrc_netif2_t *netif)
{
if (netif && (netif->ops)) {
rmutex_unlock(&netif->mutex);
}
}
void gnrc_netif_release(gnrc_netif_t *netif);
#if defined(MODULE_GNRC_IPV6) || DOXYGEN
/**
@ -77,12 +67,12 @@ static inline void gnrc_netif2_release(gnrc_netif2_t *netif)
* @param[in] pfx_len length in bits of the prefix of @p addr
* @param[in] flags initial flags for the address.
* - Setting the address' state to
* @ref GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_TENTATIVE
* @ref GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE
* means that this address is assumed to be added due to
* stateless auto-address configuration and actions
* related to that may be performed in the background.
* - Setting the address' state to
* @ref GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID means
* @ref GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID means
* that the address is assumed to be manually configured
* and its prefix will be added to the node's prefix
* list (valid and preferred lifetime will be set to
@ -95,8 +85,8 @@ static inline void gnrc_netif2_release(gnrc_netif2_t *netif)
* @return >= 0, on success
* @return -ENOMEM, when no space for new addresses is left on the interface
*/
int gnrc_netif2_ipv6_addr_add(gnrc_netif2_t *netif, const ipv6_addr_t *addr,
unsigned pfx_len, uint8_t flags);
int gnrc_netif_ipv6_addr_add(gnrc_netif_t *netif, const ipv6_addr_t *addr,
unsigned pfx_len, uint8_t flags);
/**
* @brief Removes an IPv6 address from the interface
@ -108,12 +98,12 @@ int gnrc_netif2_ipv6_addr_add(gnrc_netif2_t *netif, const ipv6_addr_t *addr,
*
* @note Only available with @ref net_gnrc_ipv6 "gnrc_ipv6".
*/
void gnrc_netif2_ipv6_addr_remove(gnrc_netif2_t *netif,
const ipv6_addr_t *addr);
void gnrc_netif_ipv6_addr_remove(gnrc_netif_t *netif,
const ipv6_addr_t *addr);
/**
* @brief Returns the index of @p addr in gnrc_netif2_t::ipv6_addrs of @p
* @brief Returns the index of @p addr in gnrc_netif_t::ipv6_addrs of @p
* netif
*
* @pre `(netif != NULL) && (addr != NULL)`
@ -125,11 +115,11 @@ void gnrc_netif2_ipv6_addr_remove(gnrc_netif2_t *netif,
*
* @note Only available with @ref net_gnrc_ipv6 "gnrc_ipv6".
*
* @return index of @p addr in gnrc_netif2_t::ipv6_addrs of @p netif
* @return index of @p addr in gnrc_netif_t::ipv6_addrs of @p netif
* @return -1, if @p addr isn't assigned to @p netif
*/
int gnrc_netif2_ipv6_addr_idx(gnrc_netif2_t *netif,
const ipv6_addr_t *addr);
int gnrc_netif_ipv6_addr_idx(gnrc_netif_t *netif,
const ipv6_addr_t *addr);
/**
* @brief Gets state from address flags
@ -139,10 +129,10 @@ int gnrc_netif2_ipv6_addr_idx(gnrc_netif2_t *netif,
*
* @return the state of the address at @p idx
*/
static inline uint8_t gnrc_netif2_ipv6_addr_get_state(const gnrc_netif2_t *netif,
int idx)
static inline uint8_t gnrc_netif_ipv6_addr_get_state(const gnrc_netif_t *netif,
int idx)
{
return netif->ipv6.addrs_flags[idx] & GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_MASK;
return netif->ipv6.addrs_flags[idx] & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_MASK;
}
/**
@ -155,14 +145,14 @@ static inline uint8_t gnrc_netif2_ipv6_addr_get_state(const gnrc_netif2_t *netif
* @return the number of duplicate address detection transmissions already
* performed
*/
static inline uint8_t gnrc_netif2_ipv6_addr_dad_trans(const gnrc_netif2_t *netif,
int idx)
static inline uint8_t gnrc_netif_ipv6_addr_dad_trans(const gnrc_netif_t *netif,
int idx)
{
return netif->ipv6.addrs_flags[idx] & GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_TENTATIVE;
return netif->ipv6.addrs_flags[idx] & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE;
}
/**
* @brief Returns the index of an address in gnrc_netif2_t::ipv6_addrs of @p
* @brief Returns the index of an address in gnrc_netif_t::ipv6_addrs of @p
* netif that matches @p addr best
*
* @pre `(netif != NULL) && (addr != NULL)`
@ -175,12 +165,12 @@ static inline uint8_t gnrc_netif2_ipv6_addr_dad_trans(const gnrc_netif2_t *netif
*
* @note Only available with @ref net_gnrc_ipv6 "gnrc_ipv6".
*
* @return index of an address in gnrc_netif2_t::ipv6_addrs of @p netif that
* @return index of an address in gnrc_netif_t::ipv6_addrs of @p netif that
* best matches @p addr.
* @return -1, if no address on @p netif matches @p addr
*/
int gnrc_netif2_ipv6_addr_match(gnrc_netif2_t *netif,
const ipv6_addr_t *addr);
int gnrc_netif_ipv6_addr_match(gnrc_netif_t *netif,
const ipv6_addr_t *addr);
/**
* @brief Searches for the best address on an interface usable as a source
@ -208,9 +198,9 @@ int gnrc_netif2_ipv6_addr_match(gnrc_netif2_t *netif,
* @return The best source address for a packet addressed to @p dst
* @return NULL, if no matching address can be found on the interface.
*/
ipv6_addr_t *gnrc_netif2_ipv6_addr_best_src(gnrc_netif2_t *netif,
const ipv6_addr_t *dst,
bool ll_only);
ipv6_addr_t *gnrc_netif_ipv6_addr_best_src(gnrc_netif_t *netif,
const ipv6_addr_t *dst,
bool ll_only);
/**
* @brief Gets an interface by an address (incl. multicast groups) assigned
@ -223,7 +213,7 @@ ipv6_addr_t *gnrc_netif2_ipv6_addr_best_src(gnrc_netif2_t *netif,
* @return The network interface that has @p addr assigned
* @return NULL, if no interface has @p addr assigned
*/
gnrc_netif2_t *gnrc_netif2_get_by_ipv6_addr(const ipv6_addr_t *addr);
gnrc_netif_t *gnrc_netif_get_by_ipv6_addr(const ipv6_addr_t *addr);
/**
* @brief Gets an interface by an address matching a given prefix best
@ -234,7 +224,7 @@ gnrc_netif2_t *gnrc_netif2_get_by_ipv6_addr(const ipv6_addr_t *addr);
* @p prefix best
* @return NULL, if there is no address on any interface that matches @prefix
*/
gnrc_netif2_t *gnrc_netif2_get_by_prefix(const ipv6_addr_t *prefix);
gnrc_netif_t *gnrc_netif_get_by_prefix(const ipv6_addr_t *prefix);
/**
* @brief Joins interface to an IPv6 multicast group
@ -250,8 +240,8 @@ gnrc_netif2_t *gnrc_netif2_get_by_prefix(const ipv6_addr_t *prefix);
* @return 0, on success
* @return -ENOMEM, when no space for new addresses is left on the interface
*/
int gnrc_netif2_ipv6_group_join(gnrc_netif2_t *netif,
const ipv6_addr_t *addr);
int gnrc_netif_ipv6_group_join(gnrc_netif_t *netif,
const ipv6_addr_t *addr);
/**
* @brief Let interface leave from an IPv6 multicast group
@ -263,11 +253,11 @@ int gnrc_netif2_ipv6_group_join(gnrc_netif2_t *netif,
*
* @note Only available with @ref net_gnrc_ipv6 "gnrc_ipv6".
*/
void gnrc_netif2_ipv6_group_leave(gnrc_netif2_t *netif,
const ipv6_addr_t *addr);
void gnrc_netif_ipv6_group_leave(gnrc_netif_t *netif,
const ipv6_addr_t *addr);
/**
* @brief Returns the index of @p addr in gnrc_netif2_t::ipv6_groups of @p
* @brief Returns the index of @p addr in gnrc_netif_t::ipv6_groups of @p
* netif
*
* @pre `(netif != NULL) && (addr != NULL)`
@ -279,11 +269,11 @@ void gnrc_netif2_ipv6_group_leave(gnrc_netif2_t *netif,
*
* @note Only available with @ref net_gnrc_ipv6 "gnrc_ipv6".
*
* @return index of @p addr in gnrc_netif2_t::ipv6_groups of @p netif
* @return index of @p addr in gnrc_netif_t::ipv6_groups of @p netif
* @return -1, if @p netif is not in group @p addr
*/
int gnrc_netif2_ipv6_group_idx(gnrc_netif2_t *netif,
const ipv6_addr_t *addr);
int gnrc_netif_ipv6_group_idx(gnrc_netif_t *netif,
const ipv6_addr_t *addr);
/**
* @brief Gets interface identifier (IID) of an interface's link-layer address
@ -293,9 +283,9 @@ int gnrc_netif2_ipv6_group_idx(gnrc_netif2_t *netif,
*
* @return 0, on success
* @return -ENOTSUP, if interface has no link-layer address or if
* gnrc_netif2_t::device_type is not supported.
* gnrc_netif_t::device_type is not supported.
*/
int gnrc_netif2_ipv6_get_iid(gnrc_netif2_t *netif, eui64_t *eui64);
int gnrc_netif_ipv6_get_iid(gnrc_netif_t *netif, eui64_t *eui64);
#endif /* MODULE_GNRC_IPV6 */
/**
@ -310,9 +300,9 @@ int gnrc_netif2_ipv6_get_iid(gnrc_netif2_t *netif, eui64_t *eui64);
* @return true, if the interface represents a router
* @return false, if the interface does not represent a router
*/
static inline bool gnrc_netif2_is_rtr(const gnrc_netif2_t *netif)
static inline bool gnrc_netif_is_rtr(const gnrc_netif_t *netif)
{
return (netif->flags & GNRC_NETIF2_FLAGS_IPV6_FORWARDING);
return (netif->flags & GNRC_NETIF_FLAGS_IPV6_FORWARDING);
}
/**
@ -326,9 +316,9 @@ static inline bool gnrc_netif2_is_rtr(const gnrc_netif2_t *netif)
* @return false, if the interface is not allowed to send out router
* advertisements
*/
static inline bool gnrc_netif2_is_rtr_adv(const gnrc_netif2_t *netif)
static inline bool gnrc_netif_is_rtr_adv(const gnrc_netif_t *netif)
{
return (netif->flags & GNRC_NETIF2_FLAGS_IPV6_RTR_ADV);
return (netif->flags & GNRC_NETIF_FLAGS_IPV6_RTR_ADV);
}
/**
@ -344,17 +334,7 @@ static inline bool gnrc_netif2_is_rtr_adv(const gnrc_netif2_t *netif)
* @return true, if the interface represents a 6LN
* @return false, if the interface does not represent a 6LN
*/
static inline bool gnrc_netif2_is_6ln(const gnrc_netif2_t *netif)
{
switch (netif->device_type) {
case NETDEV_TYPE_IEEE802154:
case NETDEV_TYPE_CC110X:
case NETDEV_TYPE_NRFMIN:
return true;
default:
return false;
}
}
bool gnrc_netif_is_6ln(const gnrc_netif_t *netif);
/**
* @brief Checks if the interface represents a 6Lo router (6LR) according to
@ -369,9 +349,9 @@ static inline bool gnrc_netif2_is_6ln(const gnrc_netif2_t *netif)
* @return true, if the interface represents a 6LR
* @return false, if the interface does not represent a 6LR
*/
static inline bool gnrc_netif2_is_6lr(const gnrc_netif2_t *netif)
static inline bool gnrc_netif_is_6lr(const gnrc_netif_t *netif)
{
return gnrc_netif2_is_rtr(netif) && gnrc_netif2_is_6ln(netif);
return gnrc_netif_is_rtr(netif) && gnrc_netif_is_6ln(netif);
}
/**
@ -387,15 +367,15 @@ static inline bool gnrc_netif2_is_6lr(const gnrc_netif2_t *netif)
* @return true, if the interface represents a 6LBR
* @return false, if the interface does not represent a 6LBR
*/
static inline bool gnrc_netif2_is_6lbr(const gnrc_netif2_t *netif)
static inline bool gnrc_netif_is_6lbr(const gnrc_netif_t *netif)
{
return (netif->flags & GNRC_NETIF2_FLAGS_6LO_ABR) &&
gnrc_netif2_is_6lr(netif);
return (netif->flags & GNRC_NETIF_FLAGS_6LO_ABR) &&
gnrc_netif_is_6lr(netif);
}
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_INTERNAL_H */
#endif /* NET_GNRC_NETIF_INTERNAL_H */
/** @} */

View File

@ -7,23 +7,23 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief IPv6 defintions for @ref net_gnrc_netif2
* @brief IPv6 defintions for @ref net_gnrc_netif
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_IPV6_H
#define NET_GNRC_NETIF2_IPV6_H
#ifndef NET_GNRC_NETIF_IPV6_H
#define NET_GNRC_NETIF_IPV6_H
#include "evtimer_msg.h"
#include "net/ipv6/addr.h"
#ifdef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nib/conf.h"
#endif
#include "net/gnrc/netif2/conf.h"
#include "net/gnrc/netif/conf.h"
#ifdef MODULE_NETSTATS_IPV6
#include "net/netstats.h"
#endif
@ -34,67 +34,67 @@ extern "C" {
/**
* @name IPv6 unicast and anycast address flags
* @anchor net_gnrc_netif2_ipv6_addrs_flags
* @anchor net_gnrc_netif_ipv6_addrs_flags
* @{
*/
/**
* @brief Mask for the address' state
*/
#define GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_MASK (0x1fU)
#define GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_MASK (0x1fU)
/**
* @brief Tentative states (with encoded DAD retransmissions)
*
* The retransmissions of DAD transmits can be decoded from this state by
* applying it as a mask to the [flags](gnrc_netif2_ipv6_t::addrs_flags) of the
* applying it as a mask to the [flags](gnrc_netif_ipv6_t::addrs_flags) of the
* address.
*/
#define GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_TENTATIVE (0x07U)
#define GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE (0x07U)
/**
* @brief Deprecated address state (still valid, but not preferred)
*/
#define GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_DEPRECATED (0x08U)
#define GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_DEPRECATED (0x08U)
/**
* @brief Valid address state
*/
#define GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID (0x10U)
#define GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID (0x10U)
/**
* @brief Address is an anycast address
*/
#define GNRC_NETIF2_IPV6_ADDRS_FLAGS_ANYCAST (0x20U)
#define GNRC_NETIF_IPV6_ADDRS_FLAGS_ANYCAST (0x20U)
/** @} */
/**
* @brief IPv6 component for @ref gnrc_netif2_t
* @brief IPv6 component for @ref gnrc_netif_t
*
* @note only available with @ref net_gnrc_ipv6.
*/
typedef struct {
/**
* @brief Flags for gnrc_netif2_t::ipv6_addrs
* @brief Flags for gnrc_netif_t::ipv6_addrs
*
* @see net_gnrc_netif2_ipv6_addrs_flags
* @see net_gnrc_netif_ipv6_addrs_flags
*
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6".
*/
uint8_t addrs_flags[GNRC_NETIF2_IPV6_ADDRS_NUMOF];
uint8_t addrs_flags[GNRC_NETIF_IPV6_ADDRS_NUMOF];
/**
* @brief IPv6 unicast and anycast addresses of the interface
*
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6".
*/
ipv6_addr_t addrs[GNRC_NETIF2_IPV6_ADDRS_NUMOF];
ipv6_addr_t addrs[GNRC_NETIF_IPV6_ADDRS_NUMOF];
/**
* @brief IPv6 multicast groups of the interface
*
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6".
*/
ipv6_addr_t groups[GNRC_NETIF2_IPV6_GROUPS_NUMOF];
ipv6_addr_t groups[GNRC_NETIF_IPV6_GROUPS_NUMOF];
#ifdef MODULE_NETSTATS_IPV6
/**
* @brief IPv6 packet statistics
@ -115,9 +115,8 @@ typedef struct {
* The callback may be `NULL` if no such behavior is required by the routing
* protocol (or no routing protocol is present).
*
* @todo Define types (RRQ, RRN, NSC) in NIB
*
* @param[in] type Type of the route info.
* @param[in] type [Type](@ref net_gnrc_ipv6_nib_route_info_type) of
* the route info.
* @param[in] ctx_addr Context address of the route info.
* @param[in] ctx Further context of the route info.
*/
@ -149,6 +148,18 @@ typedef struct {
* and @ref net_gnrc_ipv6_nib "NIB"
*/
evtimer_msg_event_t search_rtr;
#if GNRC_IPV6_NIB_CONF_6LN || DOXYGEN
/**
* @brief Timers for address re-registration
*
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6" and
* @ref net_gnrc_ipv6_nib "NIB" and if
* @ref GNRC_IPV6_NIB_CONF_6LN != 0
* @note Might also be usable in the later default SLAAC implementation
* for NS retransmission timers.
*/
evtimer_msg_event_t addrs_timers[GNRC_NETIF_IPV6_ADDRS_NUMOF];
#endif
#if GNRC_IPV6_NIB_CONF_ROUTER || DOXYGEN
/**
@ -164,7 +175,7 @@ typedef struct {
#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN)
/**
* @brief Base for random reachable time calculation and advertised
* reachable time in ms (if @ref GNRC_NETIF2_FLAGS_IPV6_RTR_ADV is
* reachable time in ms (if @ref GNRC_NETIF_FLAGS_IPV6_RTR_ADV is
* set)
*
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6".
@ -211,16 +222,13 @@ typedef struct {
*/
uint8_t ra_sent;
#endif
#if GNRC_IPV6_NIB_CONF_6LN || DOXYGEN
/**
* @brief number of unsolicited router solicitations scheduled
*
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6" and
* @ref net_gnrc_ipv6_nib "NIB" and if
* @ref GNRC_IPV6_NIB_CONF_6LN != 0
* @ref net_gnrc_ipv6_nib "NIB"
*/
uint8_t rs_sent;
#endif
/**
* @brief number of unsolicited neighbor advertisements scheduled
*
@ -243,11 +251,11 @@ typedef struct {
* @note Only available with module @ref net_gnrc_ipv6 "gnrc_ipv6".
*/
uint16_t mtu;
} gnrc_netif2_ipv6_t;
} gnrc_netif_ipv6_t;
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_IPV6_H */
#endif /* NET_GNRC_NETIF_IPV6_H */
/** @} */

View File

@ -7,27 +7,58 @@
*/
/**
* @ingroup net_gnrc_netif2
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief @ref net_gnrc_mac definitions for @ref net_gnrc_netif2
* @brief @ref net_gnrc_mac definitions for @ref net_gnrc_netif
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_MAC_H
#define NET_GNRC_NETIF2_MAC_H
#ifndef NET_GNRC_NETIF_MAC_H
#define NET_GNRC_NETIF_MAC_H
#include "net/gnrc/mac/types.h"
#include "net/csma_sender.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief @ref net_gnrc_mac component of @ref gnrc_netif2_mac_t
* @brief Mask for @ref gnrc_mac_tx_feedback_t
*/
#define GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK (0x0003U)
/**
* @brief Flag to track if a transmission might have corrupted a received
* packet
*/
#define GNRC_NETIF_MAC_INFO_RX_STARTED (0x0004U)
/**
* @brief Flag to track if a device has enabled CSMA for transmissions
*
* In case the device doesn't support on-chip CSMA and this flag is set for
* requiring CSMA transmission, then, the device will run software CSMA
* using `csma_sender` APIs.
*/
#define GNRC_NETIF_MAC_INFO_CSMA_ENABLED (0x0100U)
/**
* @brief @ref net_gnrc_mac component of @ref gnrc_netif_mac_t
*/
typedef struct {
/**
* @brief general information for the MAC protocol
*/
uint16_t mac_info;
/**
* @brief device's software CSMA configuration
*/
csma_sender_conf_t csma_conf;
#if ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || DOXYGEN
/**
* @brief MAC internal object which stores reception parameters, queues, and
@ -48,11 +79,18 @@ typedef struct {
*/
gnrc_mac_tx_t tx;
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_NEIGHBOR_COUNT == 0)) || DOXYGEN */
} gnrc_netif2_mac_t;
#ifdef MODULE_GNRC_LWMAC
/**
* @brief LWMAC specific structure object for storing LWMAC internal states.
*/
gnrc_lwmac_t lwmac;
#endif
} gnrc_netif_mac_t;
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_MAC_H */
#endif /* NET_GNRC_NETIF_MAC_H */
/** @} */

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief Raw (i.e. raw IP packets without link-layer information) adaptation
* for @ref net_gnrc_netif
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF_RAW_H
#define NET_GNRC_NETIF_RAW_H
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Creates a raw network interface
*
* @param[in] stack The stack for the network interface's thread.
* @param[in] stacksize Size of @p stack.
* @param[in] priority Priority for the network interface's thread.
* @param[in] name Name for the network interface. May be NULL.
* @param[in] dev Device for the interface.
*
* @see @ref gnrc_netif_create()
*
* @return The network interface on success.
* @return NULL, on error.
*/
gnrc_netif_t *gnrc_netif_raw_create(char *stack, int stacksize, char priority,
char *name, netdev_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF_RAW_H */
/** @} */

View File

@ -1,325 +0,0 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_netif2 New network interface API
* @ingroup net_gnrc
* @brief Abstraction layer for GNRC's network interfaces
*
* Network interfaces in the context of GNRC are threads for protocols that are
* below the network layer.
*
* @{
*
* @file
* @brief Definition for GNRC's network interfaces
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF2_H
#define NET_GNRC_NETIF2_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "kernel_types.h"
#include "msg.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/netif2/conf.h"
#ifdef MODULE_GNRC_SIXLOWPAN
#include "net/gnrc/netif2/6lo.h"
#endif
#include "net/gnrc/netif2/flags.h"
#ifdef MODULE_GNRC_IPV6
#include "net/gnrc/netif2/ipv6.h"
#endif
#ifdef MODULE_GNRC_MAC
#include "net/gnrc/netif2/mac.h"
#endif
#include "net/netdev.h"
#include "rmutex.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Operations to an interface
*/
typedef struct gnrc_netif2_ops gnrc_netif2_ops_t;
/**
* @brief Representation of a network interface
*/
typedef struct {
const gnrc_netif2_ops_t *ops; /**< Operations of the network interface */
netdev_t *dev; /**< Network device of the network interface */
rmutex_t mutex; /**< Mutex of the interface */
#if defined(MODULE_GNRC_IPV6) || DOXYGEN
gnrc_netif2_ipv6_t ipv6; /**< IPv6 component */
#endif
#if defined(MODULE_GNRC_MAC) || DOXYGEN
gnrc_netif2_mac_t mac; /**< @ref net_gnrc_mac component */
#endif /* MODULE_GNRC_MAC */
/**
* @brief Flags for the interface
*
* @see net_gnrc_netif2_flags
*/
uint32_t flags;
#if (GNRC_NETIF2_L2ADDR_MAXLEN > 0)
/**
* @brief The link-layer address currently used as the source address
* on this interface.
*
* @note Only available if @ref GNRC_NETIF2_L2ADDR_MAXLEN > 0
*/
uint8_t l2addr[GNRC_NETIF2_L2ADDR_MAXLEN];
/**
* @brief Length in bytes of gnrc_netif2_t::l2addr
*
* @note Only available if @ref GNRC_NETIF2_L2ADDR_MAXLEN > 0
*/
uint8_t l2addr_len;
#endif
#if defined(MODULE_GNRC_SIXLOWPAN) || DOXYGEN
gnrc_netif2_6lo_t sixlo; /**< 6Lo component */
#endif
uint8_t cur_hl; /**< Current hop-limit for out-going packets */
uint8_t device_type; /**< Device type */
kernel_pid_t pid; /**< PID of the network interface's thread */
} gnrc_netif2_t;
/**
* @see gnrc_netif2_ops_t
*/
struct gnrc_netif2_ops {
/**
* @brief Initializes network interface beyond the default settings
*
* @pre `netif != NULL`
*
* @param[in] netif The network interface.
*
* This is called after the default settings were set, right before the
* interface's thread starts receiving messages. It is not necessary to lock
* the interface's mutex gnrc_netif_t::mutex, since the thread will already
* lock it. Leave NULL if you do not need any special initialization.
*/
void (*init)(gnrc_netif2_t *netif);
/**
* @brief Send a @ref net_gnrc_pkt "packet" over the network interface
*
* @pre `netif != NULL && pkt != NULL`
*
* @note The function re-formats the content of @p pkt to a format expected
* by the netdev_driver_t::send() method of gnrc_netif_t::dev and
* releases the packet before returning (so no additional release
* should be required after calling this method).
*
* @param[in] netif The network interface.
* @param[in] pkt A packet to send.
*
* @return The number of bytes actually sent on success
* @return -EBADMSG, if the @ref net_gnrc_netif_hdr in @p pkt is missing
* or is in an unexpected format.
* @return -ENOTSUP, if sending @p pkt in the given format isn't supported
* (e.g. empty payload with Ethernet).
* @return Any negative error code reported by gnrc_netif2_t::dev.
*/
int (*send)(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
/**
* @brief Receives a @ref net_gnrc_pkt "packet" from the network interface
*
* @pre `netif != NULL`
*
* @note The function takes the bytes received via netdev_driver_t::recv()
* from gnrc_netif_t::dev and re-formats it to a
* @ref net_gnrc_pkt "packet" containing a @ref net_gnrc_netif_hdr
* and a payload header in receive order.
*
* @param[in] netif The network interface.
*
* @return The packet received. Contains the payload (with the type marked
* accordingly) and a @ref net_gnrc_netif_hdr in receive order.
* @return NULL, if @ref net_gnrc_pktbuf was full.
*/
gnrc_pktsnip_t *(*recv)(gnrc_netif2_t *netif);
/**
* @brief Gets an option from the network interface
*
* Use gnrc_netif2_get_from_netdev() to just get options from
* gnrc_netif2_t::dev.
*
* @param[in] netif The network interface.
* @param[in] opt The option parameters.
*
* @return Number of bytes in @p data.
* @return -EOVERFLOW, if @p max_len is lesser than the required space.
* @return -ENOTSUP, if @p opt is not supported to be set.
* @return Any negative error code reported by gnrc_netif2_t::dev.
*/
int (*get)(gnrc_netif2_t *netif, gnrc_netapi_opt_t *opt);
/**
* @brief Sets an option from the network interface
*
* Use gnrc_netif2_set_from_netdev() to just set options from
* gnrc_netif2_t::dev.
*
* @param[in] netif The network interface.
* @param[in] opt The option parameters.
*
* @return Number of bytes written to gnrc_netif2_t::dev.
* @return -EOVERFLOW, if @p data_len is greater than the allotted space in
* gnrc_netif2_t::dev or gnrc_netif_t.
* @return -ENOTSUP, if @p opt is not supported to be set.
* @return Any negative error code reported by gnrc_netif2_t::dev.
*/
int (*set)(gnrc_netif2_t *netif, const gnrc_netapi_opt_t *opt);
/**
* @brief Message handler for network interface
*
* This message handler is used, when the network interface needs to handle
* message types beyond the ones defined in @ref net_gnrc_netapi "netapi".
* Leave NULL if this is not the case.
*
* @param[in] netif The network interface.
* @param[in] msg Message to be handled.
*/
void (*msg_handler)(gnrc_netif2_t *netif, msg_t *msg);
};
/**
* @brief Creates a network interface
*
* @param[in] stack The stack for the network interface's thread.
* @param[in] stacksize Size of @p stack.
* @param[in] priority Priority for the network interface's thread.
* @param[in] name Name for the network interface. May be NULL.
* @param[in] dev Device for the interface.
* @param[in] ops Operations for the network interface.
*
* @note If @ref DEVELHELP is defined netif_params_t::name is used as the
* name of the network interface's thread.
*
* @attention Fails and crashes (assertion error with @ref DEVELHELP or
* segmentation fault without) if `GNRC_NETIF_NUMOF` is lower than
* the number of calls to this function.
*
* @return The network interface on success.
*/
gnrc_netif2_t *gnrc_netif2_create(char *stack, int stacksize, char priority,
const char *name, netdev_t *dev,
const gnrc_netif2_ops_t *ops);
/**
* @brief Get number of network interfaces actually allocated
*
* @return Number of network interfaces actually allocated
*/
unsigned gnrc_netif2_numof(void);
/**
* @brief Iterate over all network interfaces.
*
* @param[in] prev previous interface in iteration. NULL to start iteration.
*
* @return The next network interface after @p prev.
* @return NULL, if @p prev was the last network interface.
*/
gnrc_netif2_t *gnrc_netif2_iter(const gnrc_netif2_t *prev);
/**
* @brief Get network interface by PID
*
* @param[in] pid A PID of a network interface.
*
* @return The network interface on success.
* @return NULL, if no network interface with PID exists.
*/
gnrc_netif2_t *gnrc_netif2_get_by_pid(kernel_pid_t pid);
/**
* @brief Default operation for gnrc_netif2_ops_t::get()
*
* @note Can also be used to be called *after* a custom operation.
*
* @param[in] netif The network interface.
* @param[out] opt The option parameters.
*
* @return Return value of netdev_driver_t::get() of gnrc_netif2_t::dev of
* @p netif.
*/
int gnrc_netif2_get_from_netdev(gnrc_netif2_t *netif, gnrc_netapi_opt_t *opt);
/**
* @brief Default operation for gnrc_netif2_ops_t::set()
*
* @note Can also be used to be called *after* a custom operation.
*
* @param[in] netif The network interface.
* @param[in] opt The option parameters.
*
* @return Return value of netdev_driver_t::set() of gnrc_netif2_t::dev of
* @p netif.
*/
int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif,
const gnrc_netapi_opt_t *opt);
/**
* @brief Converts a hardware address to a human readable string.
*
* @details The format will be like `xx:xx:xx:xx` where `xx` are the bytes
* of @p addr in hexadecimal representation.
*
* @pre `(out != NULL) && ((addr != NULL) || (addr_len == 0))`
* @pre @p out **MUST** have allocated at least 3 * @p addr_len bytes.
*
* @param[in] addr A hardware address.
* @param[in] addr_len Length of @p addr.
* @param[out] out A string to store the output in. Must at least have
* 3 * @p addr_len bytes allocated.
*
* @return @p out.
*/
char *gnrc_netif2_addr_to_str(const uint8_t *addr, size_t addr_len, char *out);
/**
* @brief Parses a string of colon-separated hexadecimals to a hardware
* address.
*
* @details The input format must be like `xx:xx:xx:xx` where `xx` will be the
* bytes of @p addr in hexadecimal representation.
*
* @pre `(out != NULL)`
* @pre @p out **MUST** have allocated at least
* @ref GNRC_NETIF2_L2ADDR_MAXLEN bytes.
*
* @param[in] str A string of colon-separated hexadecimals.
* @param[out] out The resulting hardware address. Must at least have
* @ref GNRC_NETIF2_L2ADDR_MAXLEN bytes allocated.
*
* @return Actual length of @p out on success.
* @return 0, on failure.
*/
size_t gnrc_netif2_addr_from_str(const char *str, uint8_t *out);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_NETIF2_H */
/** @} */

View File

@ -103,13 +103,11 @@ gnrc_rpl_instance_t *gnrc_rpl_instance_get(uint8_t instance_id);
* @param[in] instance Pointer to the instance to add the DODAG to
* @param[in] dodag_id The DODAG-ID of the new DODAG
* @param[in] iface Interface PID where the DODAG operates
* @param[in] netif_addr netif address for this DODAG
*
* @return true, if DODAG could be created.
* @return false, if DODAG could not be created or exists already.
*/
bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface,
gnrc_ipv6_netif_addr_t *netif_addr);
bool gnrc_rpl_dodag_init(gnrc_rpl_instance_t *instance, ipv6_addr_t *dodag_id, kernel_pid_t iface);
/**
* @brief Remove all parents from the @p dodag.

View File

@ -27,7 +27,7 @@
extern "C" {
#endif
#include "net/gnrc/ipv6/netif.h"
#include "byteorder.h"
#include "net/ipv6/addr.h"
#include "xtimer.h"
#include "trickle.h"
@ -190,14 +190,16 @@ typedef struct __attribute__((packed)) {
* </a>
*/
typedef struct __attribute__((packed)) {
uint8_t type; /**< option type */
uint8_t length; /**< option length without the first two bytes */
uint8_t prefix_len; /**< prefix length */
uint8_t LAR_flags; /**< flags and resereved */
uint32_t valid_lifetime; /**< valid lifetime */
uint32_t pref_lifetime; /**< preferred lifetime */
uint32_t reserved; /**< reserved */
ipv6_addr_t prefix; /**< prefix used for Stateless Address Autoconfiguration */
uint8_t type; /**< option type */
uint8_t length; /**< option length without the first
* two bytes */
uint8_t prefix_len; /**< prefix length */
uint8_t LAR_flags; /**< flags and resereved */
network_uint32_t valid_lifetime; /**< valid lifetime */
network_uint32_t pref_lifetime; /**< preferred lifetime */
uint32_t reserved; /**< reserved */
ipv6_addr_t prefix; /**< prefix used for Stateless Address
* Autoconfiguration */
} gnrc_rpl_opt_prefix_info_t;
/**
@ -268,7 +270,6 @@ typedef struct {
*/
struct gnrc_rpl_dodag {
ipv6_addr_t dodag_id; /**< id of the DODAG */
gnrc_ipv6_netif_addr_t *netif_addr; /**< netif address for this DODAG */
gnrc_rpl_parent_t *parents; /**< pointer to the parents list of this DODAG */
gnrc_rpl_instance_t *instance; /**< pointer to the instance that this dodag is part of */
uint8_t dtsn; /**< DAO Trigger Sequence Number */

View File

@ -65,18 +65,17 @@
* packet will be silently discarded.
*
* The @ref GNRC_NETTYPE_SIXLOWPAN header must at least have the gnrc_netif_hdr_t::if_pid field
* set to a legal, 6LoWPAN compatible interface (a @ref gnrc_sixlowpan_netif_t entry referred to as
* `iface` in the following must exist) referred to as "the interface thread" in the following,
* otherwise the packet will be discarded.
* set to a legal, 6LoWPAN compatible interface referred to as `netif` in the
* following, otherwise the packet will be discarded.
*
* If @ref net_gnrc_sixlowpan_iphc is included and gnrc_sixlowpan_netif_t::iphc_enable of `iface`
* If @ref net_gnrc_sixlowpan_iphc is included and gnrc_sixlowpan_netif_t::iphc_enable of `netif`
* is true the @ref GNRC_NETTYPE_IPV6 header will be compressed according to
* <a href="https://tools.ietf.org/html/rfc6282">RFC 6282</a>. If it is false the
* @ref SIXLOWPAN_UNCOMP dispatch will be appended as a new @ref gnrc_pktsnip_t to the packet.
* The false case also applies if @ref net_gnrc_sixlowpan_iphc is not included.
*
* If the packet without @ref GNRC_NETTYPE_NETIF header is shorter than
* gnrc_sixlowpan_netif_t::max_frag_size of `iface` the packet will be send to the interface
* gnrc_netif_t::sixlo::max_frag_size of `netif` the packet will be send to the `netif`'s
* thread. Otherwise if @ref net_gnrc_sixlowpan_frag is included the packet will be fragmented
* according to <a href="https://tools.ietf.org/html/rfc4944">RFC 4944</a> if the packet is without
* @ref GNRC_NETTYPE_NETIF header shorter than @ref SIXLOWPAN_FRAG_MAX_LEN. If none of these cases

View File

@ -26,45 +26,15 @@
#include <stdint.h>
#include "kernel_types.h"
#include "net/gnrc/ipv6/nc.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/ipv6/addr.h"
#include "net/ndp.h"
#include "net/sixlowpan/nd.h"
#include "timex.h"
#include "net/gnrc/sixlowpan/nd/border_router.h"
#include "net/gnrc/sixlowpan/nd/router.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Message type for next multicast router solicitation.
*/
#define GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL (0x0220)
/**
* @brief Message type for next unicast router solicitation.
*/
#define GNRC_SIXLOWPAN_ND_MSG_UC_RTR_SOL (0x0221)
/**
* @brief Message type for removing 6LoWPAN contexts.
*/
#define GNRC_SIXLOWPAN_ND_MSG_DELETE_CTX (0x0222)
/**
* @brief Message type for authoritative border router timeout
*/
#define GNRC_SIXLOWPAN_ND_MSG_ABR_TIMEOUT (0x0223)
/**
* @brief Message type for address registration timeout
*/
#define GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT (0x0224)
#ifndef GNRC_SIXLOWPAN_ND_AR_LTIME
/**
* @brief Registration lifetime in minutes for the address registration option
@ -79,101 +49,6 @@ extern "C" {
#define GNRC_SIXLOWPAN_ND_AR_LTIME (15U)
#endif
/**
* @name Border router constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc6775#section-9">
* RFC 6775, section 9
* </a>
*/
#define GNRC_SIXLOWPAN_ND_RTR_MIN_CTX_DELAY (300U) /**< minimum delay between context change and
* stop of C=0 dissimination in seconds */
/** @} */
/**
* @name Host constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc6775#section-9">
* RFC 6775, section 9
* </a>
*/
#define GNRC_SIXLOWPAN_ND_RTR_SOL_INT (10U) /**< replacement value (in seconds) for
* @ref GNRC_NDP_MAX_RTR_SOL_INT */
#define GNRC_SIXLOWPAN_ND_MAX_RTR_SOL_INT (60U) /**< retransmission increment for exponential
* backoff of subsequent RS */
/** @} */
/**
* @name Router constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc6775#section-9">
* RFC 6775, section 9
* </a>
*/
#define GNRC_SIXLOWPAN_ND_MIN_RTR_ADV_DELAY (10U) /**< replacement value (in seconds) for
* @ref GNRC_NDP_MIN_RTR_ADV_DELAY */
/**
* @brief replacement value (in microseconds) for @ref GNRC_NDP_MAX_RTR_ADV_DELAY
*/
#define GNRC_SIXLOWPAN_ND_MAX_RTR_ADV_DELAY (2U * US_PER_SEC)
/**
* @brief Lifetime of a tentative address entry in seconds
*/
#define GNRC_SIXLOWPAN_ND_TENTATIVE_NCE_LIFETIME (20U)
/**
* @brief 6LoWPAN Multihop Hoplimit
*/
#define GNRC_SIXLOWPAN_ND_MULTIHOP_HOPLIMIT (64U)
/** @} */
/**
* @brief Initializes 6LoWPAN neighbor discovery for the interface.
* @pre @p iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN
* @param[in] iface An IPv6 interface.
*/
void gnrc_sixlowpan_nd_init(gnrc_ipv6_netif_t *iface);
/**
* @brief Multicasts a router solicitation over @p iface
* @pre @p iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN
* @param[in] iface An IPv6 interface.
*/
void gnrc_sixlowpan_nd_mc_rtr_sol(gnrc_ipv6_netif_t *iface);
/**
* @brief Unicasts a router solicitation to the neighbor represented by @p nce
* @pre @p nce->iface is an IPv6 interface and @ref GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN is set
* in its flags.
* @param[in] nce The neighbor to send the router solicitation to.
*/
void gnrc_sixlowpan_nd_uc_rtr_sol(gnrc_ipv6_nc_t *nce);
/**
* @brief Get link-layer address and interface for next hop to destination
* IPv6 address.
*
* @param[out] l2addr The link-layer for the next hop to @p dst.
* @param[out] l2addr_len Length of @p l2addr.
* @param[in] iface The interface to search the next hop on.
* May be @ref KERNEL_PID_UNDEF if not specified.
* @param[in] dst An IPv6 address to search the next hop for.
*
* @return The PID of the interface, on success.
* @return -EHOSTUNREACH, if @p dst is not reachable.
* @return -ENOBUFS, if @p l2addr_len was smaller than the resulting @p l2addr
* would be long.
*/
kernel_pid_t gnrc_sixlowpan_nd_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
kernel_pid_t iface, ipv6_addr_t *dst);
/**
* @brief Reschedules the next router advertisement for a neighboring router.
*
* @pre nce != NULL && sec_delay != 0U
*
* @param[in] nce Neighbor cache entry representing the neighboring router.
* @param[in] sec_delay The delay for the next router solicitation in seconds.
*/
void gnrc_sixlowpan_nd_rtr_sol_reschedule(gnrc_ipv6_nc_t *nce, uint32_t sec_delay);
/**
* @brief Builds the address registration option.
*
@ -188,62 +63,6 @@ void gnrc_sixlowpan_nd_rtr_sol_reschedule(gnrc_ipv6_nc_t *nce, uint32_t sec_dela
gnrc_pktsnip_t *gnrc_sixlowpan_nd_opt_ar_build(uint8_t status, uint16_t ltime, eui64_t *eui64,
gnrc_pktsnip_t *next);
/**
* @brief Handles address registration option.
*
* @param[in] iface The interface the ARO was received on.
* @param[in] ipv6 The IPv6 header the ARO was received in.
* @param[in] icmpv6_type Message type of the ICMPv6 message that contained.
* this message.
* @param[in] addr The IPv6 address to register.
* @param[in] ar_opt The address registration option.
* @param[in] sl2a The link-layer source address contained in SL2A accompanying this
* option. May be NULL for icmpv6_type == ICMPV6_NBR_ADV.
* @param[in] sl2a_len Length of @p sl2a. May be 0 if sl2a == NULL.
*
* @return Status for the ARO in the replying NA (always 0 if icmpv6_type == ICMPV6_NBR_ADV).
*/
uint8_t gnrc_sixlowpan_nd_opt_ar_handle(kernel_pid_t iface, ipv6_hdr_t *ipv6,
uint8_t icmpv6_type, ipv6_addr_t *addr,
sixlowpan_nd_opt_ar_t *ar_opt,
uint8_t *sl2a, size_t sl2a_len);
/**
* @brief Handles 6LoWPAN context option.
*
* @param[in] icmpv6_type Message type of the ICMPv6 message that contained.
* this message.
* @param[in] ctx_opt The 6LoWPAN context option.
*
* @return true, when 6LoWPAN context option was correct.
* @return false, when it was incorrect.
*/
bool gnrc_sixlowpan_nd_opt_6ctx_handle(uint8_t icmpv6_type, sixlowpan_nd_opt_6ctx_t *ctx_opt);
/**
* @brief Handles registration calls after node-wakeup.
*
* @see <a href="https://tools.ietf.org/html/rfc6775#section-5.8.2">
* RFC 6776, section 5.8.2
* </a>
*/
void gnrc_sixlowpan_nd_wakeup(void);
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
/**
* @brief Handles authoritative border router option.
*
* @param[in] iface Interface the source link-layer option was received
* on.
* @param[in] rtr_adv The router advertisement containing the ABRO.
* @param[in] icmpv6_size The size of the @p rtr_adv.
* @param[in] abr_opt The ABRO.
*
* @note Erroneous ABROs are always ignored silently.
*/
void gnrc_sixlowpan_nd_opt_abr_handle(kernel_pid_t iface, ndp_rtr_adv_t *rtr_adv, int icmpv6_size,
sixlowpan_nd_opt_abr_t *abr_opt);
/**
* @brief Builds the 6LoWPAN context option.
*
@ -272,11 +91,6 @@ gnrc_pktsnip_t *gnrc_sixlowpan_nd_opt_6ctx_build(uint8_t prefix_len, uint8_t fla
*/
gnrc_pktsnip_t *gnrc_sixlowpan_nd_opt_abr_build(uint32_t version, uint16_t ltime,
ipv6_addr_t *braddr, gnrc_pktsnip_t *next);
#else
#define gnrc_sixlowpan_nd_opt_abr_handle(iface, rtr_adv, icmpv6_size, abr_opt)
#define gnrc_sixlowpan_nd_opt_6ctx_build(prefix_len, flags, ltime, prefix, next) (NULL)
#define gnrc_sixlowpan_nd_opt_abr_build(version, ltime, braddr, next) (NULL)
#endif
#ifdef __cplusplus
}

View File

@ -1,226 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_sixlowpan_nd_router Router-part of 6LoWPAN-ND
* @ingroup net_gnrc_sixlowpan_nd
* @brief Router-part of 6LoWPAN-ND
* @{
*
* @file
* @brief Router-definitions for 6LoWPAN-ND.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_SIXLOWPAN_ND_ROUTER_H
#define NET_GNRC_SIXLOWPAN_ND_ROUTER_H
#include <stdbool.h>
#include "bitfield.h"
#include "net/gnrc/sixlowpan/ctx.h"
#include "net/gnrc/ipv6/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Number of registerable border routers
*
* @note More than one border routers require some way of synchronization
* of the context information (see
* [RFC 6775, section 8.1](https://tools.ietf.org/html/rfc6775#section-8.1))
*/
#ifndef GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF
#define GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF (1)
#endif
/**
* @brief The number of non-link-local prefixes associated with border routers
* at maximum.
*/
#ifndef GNRC_SIXLOWPAN_ND_ROUTER_ABR_PRF_NUMOF
/* One prefix per interface */
#define GNRC_SIXLOWPAN_ND_ROUTER_ABR_PRF_NUMOF \
(GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF * GNRC_NETIF_NUMOF)
#endif
/**
* @brief Representation for prefixes coming from a router
*/
typedef struct gnrc_sixlowpan_nd_router_prf {
struct gnrc_sixlowpan_nd_router_prf *next; /**< next prefix */
gnrc_ipv6_netif_t *iface; /**< interface the prefix is registered too */
gnrc_ipv6_netif_addr_t *prefix; /**< prefix on the interface/in the prefix list */
} gnrc_sixlowpan_nd_router_prf_t;
/**
* @brief Abstract representation of a border router on all (border) routers.
*/
typedef struct {
ipv6_addr_t addr; /**< the IPv6 address of the border router (BR) */
uint32_t version; /**< version of the information dissiminated by the
* BR */
uint16_t ltime; /**< the time in minutes until deletion */
#ifdef MODULE_GNRC_SIXLOWPAN_CTX
BITFIELD(ctxs, GNRC_SIXLOWPAN_CTX_SIZE);/**< contexts associated with BR */
#endif
gnrc_sixlowpan_nd_router_prf_t *prfs; /**< prefixes associated with BR */
xtimer_t ltimer; /**< timer for deletion */
msg_t ltimer_msg; /**< msg_t for gnrc_sixlowpan_nd_router_abr_t::ltimer */
} gnrc_sixlowpan_nd_router_abr_t;
/**
* @brief Removes tentetative neighbor cache entries or sets registered ones to
* garbage-collectible.
*
* @param[in] nc_entry A neighbor cache entry.
*/
static inline void gnrc_sixlowpan_nd_router_gc_nc(gnrc_ipv6_nc_t *nc_entry)
{
switch (gnrc_ipv6_nc_get_type(nc_entry)) {
case GNRC_IPV6_NC_TYPE_TENTATIVE:
case GNRC_IPV6_NC_TYPE_REGISTERED:
gnrc_ipv6_nc_remove(nc_entry->iface, &nc_entry->ipv6_addr);
break;
default:
break;
}
}
/**
* @brief Set @p netif to router mode.
*
* @details This sets/unsets the GNRC_IPV6_NETIF_FLAGS_ROUTER and initializes or ceases router
* behavior for 6LoWPAN neighbor discovery.
*
* @param[in] netif An IPv6 interface. Must not be NULL.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_ROUTER flag.
*/
static inline void gnrc_sixlowpan_nd_router_set_router(gnrc_ipv6_netif_t *netif, bool enable)
{
if (enable) {
netif->flags |= GNRC_IPV6_NETIF_FLAGS_ROUTER;
}
else {
netif->flags &= ~GNRC_IPV6_NETIF_FLAGS_ROUTER;
}
}
/**
* @brief Set/Unset GNRC_IPV6_NETIF_FLAGS_RTR_ADV flag for @p netif.
*
* @details GNRC_IPV6_NETIF_FLAGS_RTR_ADV and initializes or ceases
* periodic router advertising behavior for neighbor discovery.
*
* @param[in] netif An IPv6 interface. Must not be NULL.
* @param[in] enable Status for the GNRC_IPV6_NETIF_FLAGS_RTR_ADV flag.
*/
void gnrc_sixlowpan_nd_router_set_rtr_adv(gnrc_ipv6_netif_t *netif, bool enable);
/**
* @brief Get's the border router for this router.
*
* @return The border router, if one is specified.
* @return NULL, otherwise.
*/
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_get(void);
/**
* @brief Checks if the version data @p abr_opt is older than the version of the currently
* registered border router.
*
* @param[in] abr_opt An authoritative border router option containing potentially new
* information on the currently registered border router.
*
* @return true, if the information in @p abr_opt is newer.
* @return false, if the information in @p abr_opt is older.
*/
bool gnrc_sixlowpan_nd_router_abr_older(sixlowpan_nd_opt_abr_t *abr_opt);
/**
* @brief Removes the border router and all the prefixes and contexts it disseminated through
* the network for this node.
*
* @param[in] abr The border router.
*/
void gnrc_sixlowpan_nd_router_abr_remove(gnrc_sixlowpan_nd_router_abr_t *abr);
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
/**
* @brief Makes this node a new border router.
*
* @pre addr != NULL
*
* @param[in] addr The local address to use in the ABROs
* @param[in] ltime The lifetime to advertise in the ABROs. 0 assumes a default value of
* @ref GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME
*
* @return The new border router object.
* @return NULL, on error.
*/
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_create(ipv6_addr_t *addr,
unsigned int ltime);
/**
* @brief Adds a prefix for this border router to manage.
*
* @pre iface != NULL && prefix != NULL
*
* @param[in] abr The local border router.
* @param[in] iface The IPv6 interface the prefix was added to.
* @param[in] prefix The prefix.
*
* @return 0, on success
* @return -ENOMEM, if no space for the new prefix is available.
* @return -ENOENT, if @p abr is not registered.
*/
int gnrc_sixlowpan_nd_router_abr_add_prf(gnrc_sixlowpan_nd_router_abr_t* abr,
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix);
/**
* @brief Removes a prefix from this border router.
*
* @param[in] abr The local border router.
* @param[in] iface The IPv6 interface the prefix was added to.
* @param[in] prefix The prefix.
*/
void gnrc_sixlowpan_nd_router_abr_rem_prf(gnrc_sixlowpan_nd_router_abr_t *abr,
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix);
/**
* @brief Adds a context for this border router to manage.
*
* @param[in] abr The local border router
* @param[in] cid The context to be add.
*
* @return 0, on success
* @return -EINVAL, if @p ctx is greater than 15.
* @return -ENOENT, if @p abr is not registered.
*/
int gnrc_sixlowpan_nd_router_abr_add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid);
/**
* @brief Removes a context from this border router.
*
* @param[in] abr The local border router.
* @param[in] cid The context to be remove.
*/
void gnrc_sixlowpan_nd_router_abr_rem_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid);
#else
#define gnrc_sixlowpan_nd_router_abr_create(addr, ltime) (NULL)
#endif
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_SIXLOWPAN_ND_ROUTER_H */
/** @} */

View File

@ -1,77 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_sixlowpan_netif 6LoWPAN network interfaces
* @ingroup net_gnrc_sixlowpan
* @brief 6LoWPAN specific information on @ref net_gnrc_netif
* @{
*
* @file
* @brief Definitions for 6LoWPAN specific information of network interfaces.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef NET_GNRC_SIXLOWPAN_NETIF_H
#define NET_GNRC_SIXLOWPAN_NETIF_H
#include <stdbool.h>
#include "kernel_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Definition of 6LoWPAN interface type.
*/
typedef struct {
kernel_pid_t pid; /**< PID of the interface */
uint16_t max_frag_size; /**< Maximum fragment size for this interface */
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
bool iphc_enabled; /**< enable or disable IPHC */
#endif
} gnrc_sixlowpan_netif_t;
/**
* @brief Initializes the module
*/
void gnrc_sixlowpan_netif_init(void);
/**
* @brief Add interface to 6LoWPAN.
*
* @param[in] pid The PID to the interface.
* @param[in] max_frag_size The maximum fragment size for this interface.
*/
void gnrc_sixlowpan_netif_add(kernel_pid_t pid, uint16_t max_frag_size);
/**
* @brief Remove interface from 6LoWPAN.
*
* @param[in] pid The PID to the interface.
*/
void gnrc_sixlowpan_netif_remove(kernel_pid_t pid);
/**
* @brief Get interface.
*
* @param[in] pid The PID to the interface
*
* @return The interface describing structure, on success.
* @return NULL, if there is no interface with PID @p pid.
*/
gnrc_sixlowpan_netif_t *gnrc_sixlowpan_netif_get(kernel_pid_t pid);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_SIXLOWPAN_NETIF_H */
/** @} */

View File

@ -123,6 +123,7 @@ extern "C" {
/**
* @{
* @name Router constants
* @see [RFC 4861, section 6.2.1](https://tools.ietf.org/html/rfc4861#section-6.2.1)
* @see [RFC 4861, section 10](https://tools.ietf.org/html/rfc4861#section-10)
*/
#define NDP_MAX_INIT_RA_INTERVAL (16000U) /**< MAX_INITIAL_RTR_ADVERT_INTERVAL (in ms) */
@ -130,6 +131,9 @@ extern "C" {
#define NDP_MAX_FIN_RA_NUMOF (3U) /**< MAX_FINAL_RTR_ADVERTISEMENT */
#define NDP_MIN_MS_DELAY_BETWEEN_RAS (3000U) /**< MIN_DELAY_BETWEEN_RAS (in ms) */
#define NDP_MAX_RA_DELAY (500U) /**< MAX_RA_DELAY_TIME (in ms) */
#define NDP_MAX_RA_INTERVAL_MS (600000U) /**< default of MaxRtrAdvInterval (in ms) */
#define NDP_MIN_RA_INTERVAL_MS (198000U) /**< default of MinRtrAdvInterval (in ms) */
#define NDP_RTR_LTIME_SEC (1800U) /**< default of AdvDefaultLifetime (in sec) */
/** @} */
/**
@ -149,6 +153,13 @@ extern "C" {
*/
#define NDP_MAX_MC_SOL_NUMOF (3U) /**< MAX_MULTICAST_SOLICIT */
#define NDP_MAX_UC_SOL_NUMOF (3U) /**< MAX_UNICAST_SOLICIT */
/**
* @brief Default for DupAddrDetectTransmits
* @see [RFC 4862, section 5.1](https://tools.ietf.org/html/rfc4862#section-5.1)
* @note May not be greater than 7.
*/
#define NDP_DAD_TRANSMIT_NUMOF (1U)
#define NDP_MAX_ANYCAST_MS_DELAY (1000U) /**< MAX_ANYCAST_DELAY_TIME (in ms) */
#define NDP_MAX_NA_NUMOF (3U) /**< MAX_NEIGHBOR_ADVERTISEMENT */
#define NDP_REACH_MS (30000U) /**< REACHABLE_TIME (in ms) */
@ -159,6 +170,15 @@ extern "C" {
* @see [RFC 7048](https://tools.ietf.org/html/rfc7048)
*/
#define NDP_MAX_RETRANS_TIMER_MS (60000U)
/**
* @brief Maximum retransmission of neighbor solicitations when UNREACHABLE
*
* With more than this number the backoff will always be larger than
* @ref NDP_MAX_RETRANS_TIMER_MS, even if the random factor is 0.5 and the
* retransmission time is 1ms.
*/
#define NDP_MAX_NS_NUMOF (17U)
#define NDP_DELAY_FIRST_PROBE_MS (5000U) /**< DELAY_FIRST_PROBE_TIME (in ms) */
#define NDP_MIN_RANDOM_FACTOR (500U) /**< MIN_RANDOM_FACTOR (x 1000) */
#define NDP_MAX_RANDOM_FACTOR (1500U) /**< MAX_RANDOM_FACTOR (x 1000) */

View File

@ -86,7 +86,7 @@ typedef enum {
* When adding an IPv6 address to a GNRC interface using
* @ref GNRC_NETAPI_MSG_TYPE_SET, the gnrc_netapi_opt_t::context field can
* be used to pass the prefix length (8 MSB) and some flags (8 LSB)
* according to @ref net_gnrc_netif2_ipv6_addrs_flags. The address is however always
* according to @ref net_gnrc_netif_ipv6_addrs_flags. The address is however always
* considered to be manually added.
* When getting the option you can pass an array of @ref ipv6_addr_t of any
* length greater than 0 to the getter. The array will be filled up to to
@ -103,7 +103,7 @@ typedef enum {
*
* The information contained in the array is very specific to the
* interface's API. For GNRC e.g. the values are according to
* @ref net_gnrc_netif2_ipv6_addrs_flags.
* @ref net_gnrc_netif_ipv6_addrs_flags.
*/
NETOPT_IPV6_ADDR_FLAGS,
/**
@ -114,7 +114,7 @@ typedef enum {
* When adding an IPv6 address to a GNRC interface using
* @ref GNRC_NETAPI_MSG_TYPE_SET, the gnrc_netapi_opt_t::context field can
* be used to pass the prefix length (8 MSB) and some flags (8 LSB)
* according to @ref net_gnrc_netif2_ipv6_addrs_flags. The address is however always
* according to @ref net_gnrc_netif_ipv6_addrs_flags. The address is however always
* considered to be manually added.
* When getting the option you can pass an array of @ref ipv6_addr_t of any
* length greater than 0 to the getter. The array will be filled up to to

View File

@ -37,6 +37,8 @@ extern "C" {
* @name Lengths for fixed length options
* @note Options don't use bytes as their length unit, but 8 bytes.
*/
#define SIXLOWPAN_ND_OPT_6CTX_LEN_MIN (2U)
#define SIXLOWPAN_ND_OPT_6CTX_LEN_MAX (3U)
#define SIXLOWPAN_ND_OPT_AR_LEN (2U)
#define SIXLOWPAN_ND_OPT_ABR_LEN (3U)
/**
@ -110,6 +112,12 @@ extern "C" {
* @see [RFC 6775, section 9](https://tools.ietf.org/html/rfc6775#section-9)
* @{
*/
/**
* @brief Number of address registration retries
*
* @note May not be greater than 7.
*/
#define SIXLOWPAN_ND_REG_TRANSMIT_NUMOF (3U)
/**
* @brief RTR_SOLICITATION_INTERVAL (in msec)
*/

View File

@ -16,12 +16,6 @@ endif
ifneq (,$(filter gnrc_ipv6_hdr,$(USEMODULE)))
DIRS += network_layer/ipv6/hdr
endif
ifneq (,$(filter gnrc_ipv6_nc,$(USEMODULE)))
DIRS += network_layer/ipv6/nc
endif
ifneq (,$(filter gnrc_ipv6_netif,$(USEMODULE)))
DIRS += network_layer/ipv6/netif
endif
ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE)))
DIRS += network_layer/ipv6/nib
endif
@ -32,31 +26,13 @@ ifneq (,$(filter gnrc_ipv6_blacklist,$(USEMODULE)))
DIRS += network_layer/ipv6/blacklist
endif
ifneq (,$(filter gnrc_ndp,$(USEMODULE)))
DIRS += network_layer/ndp
endif
ifneq (,$(filter gnrc_ndp_internal,$(USEMODULE)))
DIRS += network_layer/ndp/internal
endif
ifneq (,$(filter gnrc_ndp_host,$(USEMODULE)))
DIRS += network_layer/ndp/host
endif
ifneq (,$(filter gnrc_ndp_node,$(USEMODULE)))
DIRS += network_layer/ndp/node
endif
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
DIRS += network_layer/ndp/router
endif
ifneq (,$(filter gnrc_ndp2,$(USEMODULE)))
DIRS += network_layer/ndp2
DIRS += network_layer/ndp
endif
ifneq (,$(filter gnrc_netapi,$(USEMODULE)))
DIRS += netapi
endif
ifneq (,$(filter gnrc_netif2,$(USEMODULE)))
DIRS += netif2
endif
ifneq (,$(filter gnrc_netif,$(USEMODULE)))
DIRS += netif
DIRS += netif
endif
ifneq (,$(filter gnrc_netif_hdr,$(USEMODULE)))
DIRS += netif/hdr
@ -112,12 +88,6 @@ endif
ifneq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
DIRS += network_layer/sixlowpan/nd
endif
ifneq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
DIRS += network_layer/sixlowpan/nd/router
endif
ifneq (,$(filter gnrc_sixlowpan_netif,$(USEMODULE)))
DIRS += network_layer/sixlowpan/netif
endif
ifneq (,$(filter gnrc_sock,$(USEMODULE)))
DIRS += sock
endif

View File

@ -22,6 +22,7 @@
#include "net/gnrc/tftp.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netreg.h"
#include "net/gnrc/udp.h"
#include "net/gnrc/ipv6.h"
@ -253,14 +254,13 @@ static int _tftp_server(tftp_context_t *ctxt);
static uint16_t _tftp_get_maximum_block_size(void)
{
uint16_t tmp;
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
size_t ifnum = gnrc_netif_get(ifs);
gnrc_netif_t *netif = gnrc_netif_iter(NULL);
if (ifnum > 0 && gnrc_netapi_get(ifs[0], NETOPT_MAX_PACKET_SIZE, 0, &tmp, sizeof(uint16_t)) >= 0) {
if ((netif != NULL) && gnrc_netapi_get(netif->pid, NETOPT_MAX_PACKET_SIZE,
0, &tmp, sizeof(uint16_t)) >= 0) {
/* TODO calculate proper block size */
return tmp - sizeof(udp_hdr_t) - sizeof(ipv6_hdr_t) - 10;
}
return GNRC_TFTP_MAX_TRANSFER_UNIT;
}

View File

@ -6,10 +6,8 @@
* directory for more details.
*/
#include "net/fib.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/ipv6/nc.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netif.h"
#include "net/ipv6/addr.h"
@ -25,25 +23,19 @@ static kernel_pid_t gnrc_wireless_interface;
static void set_interface_roles(void)
{
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
size_t numof = gnrc_netif_get(ifs);
gnrc_netif_t *netif = NULL;
for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
kernel_pid_t dev = ifs[i];
while ((netif = gnrc_netif_iter(netif))) {
kernel_pid_t dev = netif->pid;
int is_wired = gnrc_netapi_get(dev, NETOPT_IS_WIRED, 0, NULL, 0);
if ((!gnrc_border_interface) && (is_wired == 1)) {
ipv6_addr_t addr, defroute;
ipv6_addr_t addr, defroute = IPV6_ADDR_UNSPECIFIED;
gnrc_border_interface = dev;
ipv6_addr_from_str(&addr, "fe80::2");
gnrc_ipv6_netif_add_addr(dev, &addr, 64,
GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST);
ipv6_addr_from_str(&defroute, "::");
gnrc_netapi_set(dev, NETOPT_IPV6_ADDR, 64 << 8, &addr, sizeof(addr));
ipv6_addr_from_str(&addr, "fe80::1");
fib_add_entry(&gnrc_ipv6_fib_table, dev, defroute.u8, 16,
0x00, addr.u8, 16, 0,
(uint32_t)FIB_LIFETIME_NO_EXPIRE);
gnrc_ipv6_nib_ft_add(&defroute, IPV6_ADDR_BIT_LEN, &addr, dev, 0);
}
else if ((!gnrc_wireless_interface) && (is_wired != 1)) {
gnrc_wireless_interface = dev;
@ -90,17 +82,25 @@ void uhcp_handle_prefix(uint8_t *prefix, uint8_t prefix_len, uint16_t lifetime,
return;
}
gnrc_ipv6_netif_add_addr(gnrc_wireless_interface, (ipv6_addr_t*)prefix, 64,
GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST |
GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_AUTO);
gnrc_ipv6_netif_remove_addr(gnrc_wireless_interface, &_prefix);
gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR, (64 << 8),
prefix, sizeof(ipv6_addr_t));
#if defined(MODULE_GNRC_IPV6_NIB) && GNRC_IPV6_NIB_CONF_6LBR && \
GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
gnrc_ipv6_nib_abr_add((ipv6_addr_t *)prefix);
#endif
gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR_REMOVE, 0,
&_prefix, sizeof(_prefix));
print_str("gnrc_uhcpc: uhcp_handle_prefix(): configured new prefix ");
ipv6_addr_print((ipv6_addr_t*)prefix);
puts("/64");
if (!ipv6_addr_is_unspecified(&_prefix)) {
gnrc_ipv6_netif_remove_addr(gnrc_wireless_interface, &_prefix);
gnrc_netapi_set(gnrc_wireless_interface, NETOPT_IPV6_ADDR_REMOVE, 0,
&_prefix, sizeof(_prefix));
#if defined(MODULE_GNRC_IPV6_NIB) && GNRC_IPV6_NIB_CONF_6LBR && \
GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
gnrc_ipv6_nib_abr_del(&_prefix);
#endif
print_str("gnrc_uhcpc: uhcp_handle_prefix(): removed old prefix ");
ipv6_addr_print(&_prefix);
puts("/64");

View File

@ -24,7 +24,7 @@
#include <stdint.h>
#include "periph/rtt.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/mac/types.h"
#include "net/gnrc/lwmac/types.h"
@ -41,7 +41,7 @@ extern "C" {
* successively transmit its packets back to back with this flag set up,
* with the awareness that the receiver will also keep awake for receptions.
*/
#define GNRC_NETDEV_LWMAC_TX_CONTINUE (0x0008U)
#define GNRC_LWMAC_TX_CONTINUE (0x0008U)
/**
* @brief Flag to track if the sender should quit Tx in current cycle.
@ -53,7 +53,7 @@ extern "C" {
* cycle (started by the wake-up period), thus not to collide with other
* (neighbor) nodes' transmissions.
*/
#define GNRC_NETDEV_LWMAC_QUIT_TX (0x0010U)
#define GNRC_LWMAC_QUIT_TX (0x0010U)
/**
* @brief Flag to track if the device need to reselect a new wake-up phase.
@ -65,7 +65,7 @@ extern "C" {
* sender finds its phase close to its receiver's, it sets up this flag and then
* randomly reselects a new wake-up phase.
*/
#define GNRC_NETDEV_LWMAC_PHASE_BACKOFF (0x0020U)
#define GNRC_LWMAC_PHASE_BACKOFF (0x0020U)
/**
* @brief Flag to track if the device needs to quit the wake-up (listening) procedure.
@ -78,15 +78,15 @@ extern "C" {
* should immediately goto sleep (by setting up this flag) after one reception, thus not
* to receive duplicate broadcast packets.
*/
#define GNRC_NETDEV_LWMAC_QUIT_RX (0x0040U)
#define GNRC_LWMAC_QUIT_RX (0x0040U)
/**
* @brief Type to pass information about parsing.
*/
typedef struct {
gnrc_lwmac_hdr_t *header; /**< LWMAC header of packet */
gnrc_lwmac_l2_addr_t src_addr; /**< copied source address of packet */
gnrc_lwmac_l2_addr_t dst_addr; /**< copied destination address of packet */
gnrc_lwmac_hdr_t *header; /**< LWMAC header of packet */
gnrc_lwmac_l2_addr_t src_addr; /**< copied source address of packet */
gnrc_lwmac_l2_addr_t dst_addr; /**< copied destination address of packet */
} gnrc_lwmac_packet_info_t;
/**
@ -98,185 +98,209 @@ typedef struct {
#define GNRC_LWMAC_RTT_EVENT_MARGIN_TICKS (RTT_MS_TO_TICKS(2))
/**
* @brief set the TX-continue flag of the device
* @brief set the @ref GNRC_LWMAC_TX_CONTINUE flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
* @param[in] tx_continue value for LWMAC tx-continue flag
*
*/
static inline void gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev_t *dev, bool tx_continue)
static inline void gnrc_lwmac_set_tx_continue(gnrc_netif_t *netif, bool tx_continue)
{
if (tx_continue) {
dev->mac_info |= GNRC_NETDEV_LWMAC_TX_CONTINUE;
netif->mac.mac_info |= GNRC_LWMAC_TX_CONTINUE;
}
else {
dev->mac_info &= ~GNRC_NETDEV_LWMAC_TX_CONTINUE;
netif->mac.mac_info &= ~GNRC_LWMAC_TX_CONTINUE;
}
}
/**
* @brief get the TX-continue flag of the device
* @brief get the @ref GNRC_LWMAC_TX_CONTINUE flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
*
* @return true if tx continue
* @return false if tx will continue
* @return false if tx will not continue
*/
static inline bool gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev_t *dev)
static inline bool gnrc_lwmac_get_tx_continue(gnrc_netif_t *netif)
{
return (dev->mac_info & GNRC_NETDEV_LWMAC_TX_CONTINUE);
return (netif->mac.mac_info & GNRC_LWMAC_TX_CONTINUE);
}
/**
* @brief set the quit-TX flag of the device
* @brief set the @ref GNRC_LWMAC_QUIT_TX flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] quit_tx value for LWMAC quit-TX flag
* @param[in] netif ptr to the network interface
* @param[in] quit_tx value for @ref GNRC_LWMAC_QUIT_TX flag
*
*/
static inline void gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev_t *dev, bool quit_tx)
static inline void gnrc_lwmac_set_quit_tx(gnrc_netif_t *netif, bool quit_tx)
{
if (quit_tx) {
dev->mac_info |= GNRC_NETDEV_LWMAC_QUIT_TX;
netif->mac.mac_info |= GNRC_LWMAC_QUIT_TX;
}
else {
dev->mac_info &= ~GNRC_NETDEV_LWMAC_QUIT_TX;
netif->mac.mac_info &= ~GNRC_LWMAC_QUIT_TX;
}
}
/**
* @brief get the quit-TX flag of the device
* @brief get the @ref GNRC_LWMAC_QUIT_TX flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
*
* @return true if quit tx
* @return false if will not quit tx
*/
static inline bool gnrc_netdev_lwmac_get_quit_tx(gnrc_netdev_t *dev)
static inline bool gnrc_lwmac_get_quit_tx(gnrc_netif_t *netif)
{
return (dev->mac_info & GNRC_NETDEV_LWMAC_QUIT_TX);
return (netif->mac.mac_info & GNRC_LWMAC_QUIT_TX);
}
/**
* @brief set the phase-backoff flag of the device
* @brief set the @ref GNRC_LWMAC_PHASE_BACKOFF flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] backoff value for LWMAC phase-backoff flag
* @param[in] netif ptr to the network interface
* @param[in] backoff value for LWMAC @ref GNRC_LWMAC_PHASE_BACKOFF flag
*
*/
static inline void gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev_t *dev, bool backoff)
static inline void gnrc_lwmac_set_phase_backoff(gnrc_netif_t *netif, bool backoff)
{
if (backoff) {
dev->mac_info |= GNRC_NETDEV_LWMAC_PHASE_BACKOFF;
netif->mac.mac_info |= GNRC_LWMAC_PHASE_BACKOFF;
}
else {
dev->mac_info &= ~GNRC_NETDEV_LWMAC_PHASE_BACKOFF;
netif->mac.mac_info &= ~GNRC_LWMAC_PHASE_BACKOFF;
}
}
/**
* @brief get the phase-backoff of the device
* @brief get the @ref GNRC_LWMAC_PHASE_BACKOFF flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
*
* @return true if will run phase-backoff
* @return false if will not run phase-backoff
*/
static inline bool gnrc_netdev_lwmac_get_phase_backoff(gnrc_netdev_t *dev)
static inline bool gnrc_lwmac_get_phase_backoff(gnrc_netif_t *netif)
{
return (dev->mac_info & GNRC_NETDEV_LWMAC_PHASE_BACKOFF);
return (netif->mac.mac_info & GNRC_LWMAC_PHASE_BACKOFF);
}
/**
* @brief set the quit-RX flag of the device
* @brief set the @ref GNRC_LWMAC_QUIT_RX flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] quit_rx value for LWMAC quit-Rx flag
* @param[in] netif ptr to the network interface
* @param[in] quit_rx value for LWMAC @ref GNRC_LWMAC_QUIT_RX flag
*
*/
static inline void gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev_t *dev, bool quit_rx)
static inline void gnrc_lwmac_set_quit_rx(gnrc_netif_t *netif, bool quit_rx)
{
if (quit_rx) {
dev->mac_info |= GNRC_NETDEV_LWMAC_QUIT_RX;
netif->mac.mac_info |= GNRC_LWMAC_QUIT_RX;
}
else {
dev->mac_info &= ~GNRC_NETDEV_LWMAC_QUIT_RX;
netif->mac.mac_info &= ~GNRC_LWMAC_QUIT_RX;
}
}
/**
* @brief get the quit-RX flag of the device
* @brief get the @ref GNRC_LWMAC_QUIT_RX flag of the device
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
*
* @return true if will quit rx
* @return false if will not quit rx
*/
static inline bool gnrc_netdev_lwmac_get_quit_rx(gnrc_netdev_t *dev)
static inline bool gnrc_lwmac_get_quit_rx(gnrc_netif_t *netif)
{
return (dev->mac_info & GNRC_NETDEV_LWMAC_QUIT_RX);
return (netif->mac.mac_info & GNRC_LWMAC_QUIT_RX);
}
/**
* @brief set the duty-cycle-active flag of LWMAC
* @brief set the @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag of LWMAC
*
* @param[in] dev ptr to netdev device
* @param[in] active value for LWMAC duty-cycle-active flag
* @param[in] netif ptr to the network interface
* @param[in] active value for LWMAC @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag
*
*/
static inline void gnrc_netdev_lwmac_set_dutycycle_active(gnrc_netdev_t *dev, bool active)
static inline void gnrc_lwmac_set_dutycycle_active(gnrc_netif_t *netif, bool active)
{
if (active) {
dev->lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
}
else {
dev->lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
}
}
/**
* @brief get the duty-cycle-active flag of LWMAC
* @brief get the @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag of LWMAC
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
*
* @return true if active
* @return false if not active
*/
static inline bool gnrc_netdev_lwmac_get_dutycycle_active(gnrc_netdev_t *dev)
static inline bool gnrc_lwmac_get_dutycycle_active(gnrc_netif_t *netif)
{
return (dev->lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
}
/**
* @brief set the needs-rescheduling flag of LWMAC
* @brief set the @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag of LWMAC
*
* @param[in] dev ptr to netdev device
* @param[in] reschedule value for LWMAC needs-rescheduling flag
* @param[in] netif ptr to the network interface
* @param[in] reschedule value for @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag
*
*/
static inline void gnrc_netdev_lwmac_set_reschedule(gnrc_netdev_t *dev, bool reschedule)
static inline void gnrc_lwmac_set_reschedule(gnrc_netif_t *netif, bool reschedule)
{
if (reschedule) {
dev->lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
}
else {
dev->lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
}
}
/**
* @brief get the needs-rescheduling flag of LWMAC
* @brief get the @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag of LWMAC
*
* @param[in] dev ptr to netdev device
* @param[in] netif ptr to the network interface
*
* @return true if needs rescheduling
* @return false if no need for rescheduling
*/
static inline bool gnrc_netdev_lwmac_get_reschedule(gnrc_netdev_t *dev)
static inline bool gnrc_lwmac_get_reschedule(gnrc_netif_t *netif)
{
return (dev->lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
}
/**
* @brief send a @ref net_gnrc_pkt "packet" over the network interface in LWMAC
*
* @internal
*
* @pre `netif != NULL && pkt != NULL`
*
* @note The function re-formats the content of @p pkt to a format expected
* by the netdev_driver_t::send() method of gnrc_netif_t::dev and
* releases the packet before returning (so no additional release
* should be required after calling this method).
*
* @param[in] netif The network interface.
* @param[in] pkt A packet to send.
*
* @return The number of bytes actually sent on success
* @return -EBADMSG, if the @ref net_gnrc_netif_hdr in @p pkt is missing
* or is in an unexpected format.
* @return -ENOTSUP, if sending @p pkt in the given format isn't supported
* (e.g. empty payload with Ethernet).
* @return Any negative error code reported by gnrc_netif_t::dev.
*/
int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
/**
* @brief Parse an incoming packet and extract important information.
*
@ -293,19 +317,19 @@ int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info
/**
* @brief Shortcut to get the state of netdev.
*
* @param[in] gnrc_netdev gnrc_netdev structure
* @param[in] netif ptr to the network interface
*
* @return state of netdev
* @return state of netdev
*/
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netdev_t *gnrc_netdev);
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netif_t *netif);
/**
* @brief Shortcut to set the state of netdev
*
* @param[in] gnrc_netdev gnrc_netdev structure
* @param[in] devstate new state for netdev
* @param[in] netif ptr to the network interface
* @param[in] devstate new state for netdev
*/
void _gnrc_lwmac_set_netdev_state(gnrc_netdev_t *gnrc_netdev, netopt_state_t devstate);
void _gnrc_lwmac_set_netdev_state(gnrc_netif_t *netif, netopt_state_t devstate);
/**
* @brief Convert RTT ticks to device phase

View File

@ -23,7 +23,7 @@
#define RX_STATE_MACHINE_H
#include "net/gnrc/pkt.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
@ -32,26 +32,26 @@ extern "C" {
/**
* @brief Start LWMAC RX procedure to receive packet
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif ptr to the network interface
*
*/
void gnrc_lwmac_rx_start(gnrc_netdev_t *gnrc_netdev);
void gnrc_lwmac_rx_start(gnrc_netif_t *netif);
/**
* @brief Stop LWMAC RX procedure
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif ptr to the network interface
*
*/
void gnrc_lwmac_rx_stop(gnrc_netdev_t *gnrc_netdev);
void gnrc_lwmac_rx_stop(gnrc_netif_t *netif);
/**
* @brief Update LWMAC RX procedure for packet reception
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif ptr to the network interface
*
*/
void gnrc_lwmac_rx_update(gnrc_netdev_t *gnrc_netdev);
void gnrc_lwmac_rx_update(gnrc_netif_t *netif);
#ifdef __cplusplus
}

View File

@ -23,7 +23,7 @@
#define TX_STATE_MACHINE_H
#include "net/gnrc/pkt.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/mac/types.h"
#ifdef __cplusplus
@ -33,30 +33,30 @@ extern "C" {
/**
* @brief Start LWMAC TX procedure to transmit packet @p pkt to @p neighbor
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif ptr to the network interface
* @param[in] pkt packet to transmit
* @param[in] neighbor Tx neighbor
*
*/
void gnrc_lwmac_tx_start(gnrc_netdev_t *gnrc_netdev,
void gnrc_lwmac_tx_start(gnrc_netif_t *netif,
gnrc_pktsnip_t *pkt,
gnrc_mac_tx_neighbor_t *neighbor);
/**
* @brief Stop LWMAC TX procedure
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif ptr to the network interface
*
*/
void gnrc_lwmac_tx_stop(gnrc_netdev_t *gnrc_netdev);
void gnrc_lwmac_tx_stop(gnrc_netif_t *netif);
/**
* @brief Update LWMAC TX procedure for transmission
*
* @param[in,out] gnrc_netdev gnrc_netdev structure
* @param[in,out] netif ptr to the network interface
*
*/
void gnrc_lwmac_tx_update(gnrc_netdev_t *gnrc_netdev);
void gnrc_lwmac_tx_update(gnrc_netif_t *netif);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@ -24,13 +24,99 @@
#include "periph/rtt.h"
#include "net/gnrc.h"
#include "net/gnrc/mac/mac.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/lwmac/lwmac.h"
#include "include/lwmac_internal.h"
#include "net/gnrc/netif/ieee802154.h"
#include "net/netdev/ieee802154.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
int _gnrc_lwmac_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
netdev_t *dev = netif->dev;
netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
gnrc_netif_hdr_t *netif_hdr;
gnrc_pktsnip_t *vec_snip;
const uint8_t *src, *dst = NULL;
int res = 0;
size_t n, src_len, dst_len;
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;
/* prepare destination address */
if (netif_hdr->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_len = IEEE802154_ADDR_BCAST_LEN;
}
else {
dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
dst_len = netif_hdr->dst_l2addr_len;
}
src_len = netif_hdr->src_l2addr_len;
if (src_len > 0) {
src = gnrc_netif_hdr_get_src_addr(netif_hdr);
}
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;
}
/* prepare packet for sending */
vec_snip = gnrc_pktbuf_get_iovec(pkt, &n);
if (vec_snip != NULL) {
struct iovec *vector;
pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */
vector = (struct iovec *)pkt->data;
vector[0].iov_base = mhr;
vector[0].iov_len = (size_t)res;
#ifdef MODULE_NETSTATS_L2
if (netif_hdr->flags &
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
netif->dev->stats.tx_mcast_count++;
}
else {
netif->dev->stats.tx_unicast_count++;
}
#endif
#ifdef MODULE_GNRC_MAC
if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) {
res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf);
}
else {
res = dev->driver->send(dev, vector, n);
}
#else
res = dev->driver->send(dev, vector, n);
#endif
}
else {
return -ENOBUFS;
}
/* release old data */
gnrc_pktbuf_release(pkt);
return res;
}
int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info)
{
gnrc_netif_hdr_t *netif_hdr;
@ -103,42 +189,42 @@ int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info
return 0;
}
void _gnrc_lwmac_set_netdev_state(gnrc_netdev_t *gnrc_netdev, netopt_state_t devstate)
void _gnrc_lwmac_set_netdev_state(gnrc_netif_t *netif, netopt_state_t devstate)
{
gnrc_netdev->dev->driver->set(gnrc_netdev->dev,
NETOPT_STATE,
&devstate,
sizeof(devstate));
netif->dev->driver->set(netif->dev,
NETOPT_STATE,
&devstate,
sizeof(devstate));
#if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
if (devstate == NETOPT_STATE_IDLE) {
if (!(gnrc_netdev->lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
gnrc_netdev->lwmac.last_radio_on_time_ticks = rtt_get_counter();
gnrc_netdev->lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
if (!(netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
netif->mac.lwmac.last_radio_on_time_ticks = rtt_get_counter();
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
}
return;
}
else if ((devstate == NETOPT_STATE_SLEEP) &&
(gnrc_netdev->lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
gnrc_netdev->lwmac.radio_off_time_ticks = rtt_get_counter();
(netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
netif->mac.lwmac.radio_off_time_ticks = rtt_get_counter();
gnrc_netdev->lwmac.awake_duration_sum_ticks +=
(gnrc_netdev->lwmac.radio_off_time_ticks -
gnrc_netdev->lwmac.last_radio_on_time_ticks);
netif->mac.lwmac.awake_duration_sum_ticks +=
(netif->mac.lwmac.radio_off_time_ticks -
netif->mac.lwmac.last_radio_on_time_ticks);
gnrc_netdev->lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
}
#endif
}
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netdev_t *gnrc_netdev)
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netif_t *netif)
{
netopt_state_t state;
if (0 < gnrc_netdev->dev->driver->get(gnrc_netdev->dev,
NETOPT_STATE,
&state,
sizeof(state))) {
if (0 < netif->dev->driver->get(netif->dev,
NETOPT_STATE,
&state,
sizeof(state))) {
return state;
}
return -1;
@ -165,23 +251,23 @@ int _gnrc_lwmac_dispatch_defer(gnrc_pktsnip_t *buffer[], gnrc_pktsnip_t *pkt)
return 0;
}
else if (bcast &&
(((gnrc_lwmac_hdr_t *)buffer[i]->next->data)->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) &&
(bcast->seq_nr == ((gnrc_lwmac_frame_broadcast_t *)buffer[i]->next->data)->seq_nr)) {
/* Filter same broadcasts, compare sequence number */
gnrc_netif_hdr_t *hdr_queued, *hdr_new;
hdr_new = pkt->next->next->data;
hdr_queued = buffer[i]->next->next->data;
(((gnrc_lwmac_hdr_t *)buffer[i]->next->data)->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) &&
(bcast->seq_nr == ((gnrc_lwmac_frame_broadcast_t *)buffer[i]->next->data)->seq_nr)) {
/* Filter same broadcasts, compare sequence number */
gnrc_netif_hdr_t *hdr_queued, *hdr_new;
hdr_new = pkt->next->next->data;
hdr_queued = buffer[i]->next->next->data;
/* Sequence numbers match, compare source addresses */
if ((hdr_new->src_l2addr_len == hdr_queued->src_l2addr_len) &&
(memcmp(gnrc_netif_hdr_get_src_addr(hdr_new),
gnrc_netif_hdr_get_src_addr(hdr_queued),
hdr_new->src_l2addr_len) == 0)) {
/* Source addresses match, same packet */
DEBUG("[LWMAC] Found duplicate broadcast packet, dropping\n");
gnrc_pktbuf_release(pkt);
return -2;
}
/* Sequence numbers match, compare source addresses */
if ((hdr_new->src_l2addr_len == hdr_queued->src_l2addr_len) &&
(memcmp(gnrc_netif_hdr_get_src_addr(hdr_new),
gnrc_netif_hdr_get_src_addr(hdr_queued),
hdr_new->src_l2addr_len) == 0)) {
/* Source addresses match, same packet */
DEBUG("[LWMAC] Found duplicate broadcast packet, dropping\n");
gnrc_pktbuf_release(pkt);
return -2;
}
}
}

View File

@ -52,14 +52,14 @@
*/
#define GNRC_LWMAC_RX_FOUND_DATA (0x04U)
static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
static uint8_t _packet_process_in_wait_for_wr(gnrc_netif_t *netif)
{
uint8_t rx_info = 0;
gnrc_pktsnip_t *pkt;
assert(gnrc_netdev != NULL);
assert(netif != NULL);
while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
LOG_DEBUG("[LWMAC-rx] Inspecting pkt @ %p\n", pkt);
/* Parse packet */
@ -72,13 +72,13 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
}
if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&gnrc_netdev->rx);
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&netif->mac.rx);
rx_info |= GNRC_LWMAC_RX_FOUND_BROADCAST;
/* quit listening period to avoid receiving duplicate broadcast packets */
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
gnrc_lwmac_set_quit_rx(netif, true);
/* quit TX in this cycle to avoid collisions with broadcast packets */
gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
gnrc_lwmac_set_quit_tx(netif, true);
break;
}
@ -91,18 +91,18 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
/* No need to keep pkt anymore */
gnrc_pktbuf_release(pkt);
if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
gnrc_netdev->l2_addr_len) == 0)) {
if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
netif->l2addr_len) == 0)) {
LOG_DEBUG("[LWMAC-rx] Packet is WR but not for us\n");
/* quit TX in this cycle to avoid collisions with other senders, since
* found ongoing WR (preamble) stream */
gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
gnrc_lwmac_set_quit_tx(netif, true);
continue;
}
/* If reach here, the node gets a WR for itself. */
/* Save source address for later addressing */
gnrc_netdev->rx.l2_addr = info.src_addr;
netif->mac.rx.l2_addr = info.src_addr;
rx_info |= GNRC_LWMAC_RX_FOUND_WR;
break;
@ -112,56 +112,56 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
}
/* return false if send wa failed, otherwise return true */
static bool _send_wa(gnrc_netdev_t *gnrc_netdev)
static bool _send_wa(gnrc_netif_t *netif)
{
gnrc_pktsnip_t *pkt;
gnrc_pktsnip_t *pkt_lwmac;
gnrc_netif_hdr_t *nethdr_wa;
assert(gnrc_netdev != NULL);
assert(gnrc_netdev->rx.l2_addr.len != 0);
assert(netif != NULL);
assert(netif->mac.rx.l2_addr.len != 0);
/* if found ongoing transmission,
* quit sending WA for collision avoidance. */
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
gnrc_netdev->rx.rx_bad_exten_count++;
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
netif->mac.rx.rx_bad_exten_count++;
return false;
}
/* Assemble WA packet */
gnrc_lwmac_frame_wa_t lwmac_hdr;
lwmac_hdr.header.type = GNRC_LWMAC_FRAMETYPE_WA;
lwmac_hdr.dst_addr = gnrc_netdev->rx.l2_addr;
lwmac_hdr.dst_addr = netif->mac.rx.l2_addr;
uint32_t phase_now = _gnrc_lwmac_phase_now();
/* Embed the current 'relative phase timing' (counted from the start of this cycle)
* of the receiver into its WA packet, thus to allow the sender to infer the
* receiver's exact wake-up timing */
if (phase_now > _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup)) {
if (phase_now > _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup)) {
lwmac_hdr.current_phase = (phase_now -
_gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup));
_gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup));
}
else {
lwmac_hdr.current_phase = (phase_now + RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)) -
_gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup);
_gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
}
pkt = gnrc_pktbuf_add(NULL, &lwmac_hdr, sizeof(lwmac_hdr), GNRC_NETTYPE_LWMAC);
if (pkt == NULL) {
LOG_ERROR("ERROR: [LWMAC-rx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
gnrc_lwmac_set_quit_rx(netif, true);
return false;
}
pkt_lwmac = pkt;
pkt = gnrc_pktbuf_add(pkt, NULL,
sizeof(gnrc_netif_hdr_t) + gnrc_netdev->rx.l2_addr.len,
sizeof(gnrc_netif_hdr_t) + netif->mac.rx.l2_addr.len,
GNRC_NETTYPE_NETIF);
if (pkt == NULL) {
LOG_ERROR("ERROR: [LWMAC-rx] Cannot allocate pktbuf of type GNRC_NETTYPE_NETIF\n");
gnrc_pktbuf_release(pkt_lwmac);
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
gnrc_lwmac_set_quit_rx(netif, true);
return false;
}
@ -170,44 +170,44 @@ static bool _send_wa(gnrc_netdev_t *gnrc_netdev)
nethdr_wa = (gnrc_netif_hdr_t *)(gnrc_pktsnip_search_type(pkt,
GNRC_NETTYPE_NETIF)->data);
/* Construct NETIF header and insert address for WA packet */
gnrc_netif_hdr_init(nethdr_wa, 0, gnrc_netdev->rx.l2_addr.len);
gnrc_netif_hdr_init(nethdr_wa, 0, netif->mac.rx.l2_addr.len);
/* Send WA as broadcast*/
nethdr_wa->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
/* Disable Auto ACK */
netopt_enable_t autoack = NETOPT_DISABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
/* Send WA */
if (gnrc_netdev->send(gnrc_netdev, pkt) < 0) {
if (_gnrc_lwmac_transmit(netif, pkt) < 0) {
LOG_ERROR("ERROR: [LWMAC-rx] Send WA failed.");
if (pkt != NULL) {
gnrc_pktbuf_release(pkt);
}
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
gnrc_lwmac_set_quit_rx(netif, true);
return false;
}
/* Enable Auto ACK again for data reception */
autoack = NETOPT_ENABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
return true;
}
static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
static uint8_t _packet_process_in_wait_for_data(gnrc_netif_t *netif)
{
uint8_t rx_info = 0;
gnrc_pktsnip_t *pkt;
assert(gnrc_netdev != NULL);
assert(netif != NULL);
pkt = NULL;
while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
LOG_DEBUG("[LWMAC-rx] Inspecting pkt @ %p\n", pkt);
/* Parse packet */
@ -220,40 +220,40 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
}
if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&gnrc_netdev->rx);
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&netif->mac.rx);
/* quit listening period to avoid receiving duplicate broadcast packets */
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
gnrc_lwmac_set_quit_rx(netif, true);
continue;
}
if (!(memcmp(&info.src_addr.addr, &gnrc_netdev->rx.l2_addr.addr,
gnrc_netdev->rx.l2_addr.len) == 0)) {
if (!(memcmp(&info.src_addr.addr, &netif->mac.rx.l2_addr.addr,
netif->mac.rx.l2_addr.len) == 0)) {
LOG_DEBUG("[LWMAC-rx] Packet is not from destination\n");
gnrc_pktbuf_release(pkt);
/* Reset timeout to wait for the data packet */
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
continue;
}
if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
gnrc_netdev->l2_addr_len) == 0)) {
if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
netif->l2addr_len) == 0)) {
LOG_DEBUG("[LWMAC-rx] Packet is not for us\n");
gnrc_pktbuf_release(pkt);
/* Reset timeout to wait for the data packet */
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
continue;
}
/* Sender maybe didn't get the WA */
if (info.header->type == GNRC_LWMAC_FRAMETYPE_WR) {
LOG_DEBUG("[LWMAC-rx] Found a WR while waiting for DATA\n");
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
rx_info |= GNRC_LWMAC_RX_FOUND_WR;
/* Push WR back to rx queue */
gnrc_mac_queue_rx_packet(&gnrc_netdev->rx, 0, pkt);
gnrc_mac_queue_rx_packet(&netif->mac.rx, 0, pkt);
break;
}
@ -261,10 +261,10 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
case GNRC_LWMAC_FRAMETYPE_DATA:
case GNRC_LWMAC_FRAMETYPE_DATA_PENDING: {
/* Receiver gets the data packet */
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&gnrc_netdev->rx);
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&netif->mac.rx);
LOG_DEBUG("[LWMAC-rx] Found DATA!\n");
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
rx_info |= GNRC_LWMAC_RX_FOUND_DATA;
return rx_info;
}
@ -277,117 +277,117 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
return rx_info;
}
void gnrc_lwmac_rx_start(gnrc_netdev_t *gnrc_netdev)
void gnrc_lwmac_rx_start(gnrc_netif_t *netif)
{
if (gnrc_netdev == NULL) {
if (netif == NULL) {
return;
}
/* RX address should have been reset, probably not stopped then */
assert(gnrc_netdev->rx.l2_addr.len == 0);
assert(netif->mac.rx.l2_addr.len == 0);
/* Don't attempt to send a WA if channel is busy to get timings right */
gnrc_netdev->mac_info &= ~GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
netif->mac.mac_info &= ~GNRC_NETIF_MAC_INFO_CSMA_ENABLED;
netopt_enable_t csma_disable = NETOPT_DISABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA, &csma_disable,
sizeof(csma_disable));
netif->dev->driver->set(netif->dev, NETOPT_CSMA, &csma_disable,
sizeof(csma_disable));
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_INIT;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_INIT;
}
void gnrc_lwmac_rx_stop(gnrc_netdev_t *gnrc_netdev)
void gnrc_lwmac_rx_stop(gnrc_netif_t *netif)
{
if (!gnrc_netdev) {
if (!netif) {
return;
}
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_STOPPED;
gnrc_netdev->rx.l2_addr.len = 0;
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_STOPPED;
netif->mac.rx.l2_addr.len = 0;
}
/* Returns whether rescheduling is needed or not */
static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
static bool _lwmac_rx_update(gnrc_netif_t *netif)
{
bool reschedule = false;
if (!gnrc_netdev) {
if (!netif) {
return reschedule;
}
switch (gnrc_netdev->rx.state) {
switch (netif->mac.rx.state) {
case GNRC_LWMAC_RX_STATE_INIT: {
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_WR;
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_WR;
reschedule = true;
break;
}
case GNRC_LWMAC_RX_STATE_WAIT_FOR_WR: {
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_FOR_WR\n");
uint8_t rx_info = _packet_process_in_wait_for_wr(gnrc_netdev);
uint8_t rx_info = _packet_process_in_wait_for_wr(netif);
/* if found broadcast packet, goto rx successful */
if (rx_info & GNRC_LWMAC_RX_FOUND_BROADCAST) {
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
reschedule = true;
break;
}
if (!(rx_info & GNRC_LWMAC_RX_FOUND_WR)) {
LOG_DEBUG("[LWMAC-rx] No WR found, stop RX\n");
gnrc_netdev->rx.rx_bad_exten_count++;
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
netif->mac.rx.rx_bad_exten_count++;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
reschedule = true;
break;
}
gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
/* Found WR packet (preamble), goto next state to send WA (preamble-ACK) */
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SEND_WA;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SEND_WA;
reschedule = true;
break;
}
case GNRC_LWMAC_RX_STATE_SEND_WA: {
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_SEND_WA\n");
if (!_send_wa(gnrc_netdev)) {
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
if (!_send_wa(netif)) {
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
reschedule = true;
break;
}
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_WA_SENT;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_WA_SENT;
reschedule = false;
break;
}
case GNRC_LWMAC_RX_STATE_WAIT_WA_SENT: {
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_WA_SENT\n");
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
LOG_DEBUG("[LWMAC-rx] WA not yet completely sent\n");
break;
}
/* When reach here, WA has been sent, set timeout for expected data arrival */
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
_gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
_gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
reschedule = false;
break;
}
case GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA: {
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA\n");
uint8_t rx_info = _packet_process_in_wait_for_data(gnrc_netdev);
uint8_t rx_info = _packet_process_in_wait_for_data(netif);
/* If WA got lost we wait for data but we will be hammered with WR
* packets. So a WR indicates a lost WA => reset RX state machine. */
if (rx_info & GNRC_LWMAC_RX_FOUND_WR) {
LOG_INFO("[LWMAC-rx] WA probably got lost, reset RX state machine\n");
/* Start over again */
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_INIT;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_INIT;
reschedule = true;
break;
}
@ -396,16 +396,16 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
* received. This won't be blocked by WRs as they restart the state
* machine (see above).
*/
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA)) {
if (!gnrc_netdev_get_rx_started(gnrc_netdev)) {
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_DATA)) {
if (!gnrc_netif_get_rx_started(netif)) {
LOG_INFO("[LWMAC-rx] DATA timed out\n");
gnrc_netdev->rx.rx_bad_exten_count++;
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
netif->mac.rx.rx_bad_exten_count++;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
reschedule = true;
}
else {
/* If radio is receiving packet, reset wait data timeout */
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
}
break;
}
@ -415,7 +415,7 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
break;
}
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
reschedule = true;
break;
}
@ -430,8 +430,8 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
return reschedule;
}
void gnrc_lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
void gnrc_lwmac_rx_update(gnrc_netif_t *netif)
{
/* Update until no rescheduling needed */
while (_lwmac_rx_update(gnrc_netdev)) {}
while (_lwmac_rx_update(netif)) {}
}

View File

@ -58,40 +58,40 @@ static int _lwmac_find_timeout(gnrc_lwmac_t *lwmac, gnrc_lwmac_timeout_type_t ty
return -ENOENT;
}
inline bool gnrc_lwmac_timeout_is_running(gnrc_netdev_t *gnrc_netdev,
inline bool gnrc_lwmac_timeout_is_running(gnrc_netif_t *netif,
gnrc_lwmac_timeout_type_t type)
{
assert(gnrc_netdev);
return (_lwmac_find_timeout(&gnrc_netdev->lwmac, type) >= 0);
assert(netif);
return (_lwmac_find_timeout(&netif->mac.lwmac, type) >= 0);
}
bool gnrc_lwmac_timeout_is_expired(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type)
bool gnrc_lwmac_timeout_is_expired(gnrc_netif_t *netif, gnrc_lwmac_timeout_type_t type)
{
assert(gnrc_netdev);
assert(netif);
int index = _lwmac_find_timeout(&gnrc_netdev->lwmac, type);
int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
if (index >= 0) {
if (gnrc_netdev->lwmac.timeouts[index].expired) {
_lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[index]);
if (netif->mac.lwmac.timeouts[index].expired) {
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
}
return gnrc_netdev->lwmac.timeouts[index].expired;
return netif->mac.lwmac.timeouts[index].expired;
}
return false;
}
gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netdev_t *gnrc_netdev,
gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netif_t *netif,
gnrc_lwmac_timeout_type_t type)
{
assert(gnrc_netdev);
assert(netif);
if (gnrc_lwmac_timeout_is_running(gnrc_netdev, type)) {
if (gnrc_lwmac_timeout_is_running(netif, type)) {
return NULL;
}
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
if (gnrc_netdev->lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
gnrc_netdev->lwmac.timeouts[i].type = type;
return &gnrc_netdev->lwmac.timeouts[i];
if (netif->mac.lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
netif->mac.lwmac.timeouts[i].type = type;
return &netif->mac.lwmac.timeouts[i];
}
}
return NULL;
@ -104,31 +104,31 @@ void gnrc_lwmac_timeout_make_expire(gnrc_lwmac_timeout_t *timeout)
timeout->expired = true;
}
void gnrc_lwmac_clear_timeout(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type)
void gnrc_lwmac_clear_timeout(gnrc_netif_t *netif, gnrc_lwmac_timeout_type_t type)
{
assert(gnrc_netdev);
assert(netif);
int index = _lwmac_find_timeout(&gnrc_netdev->lwmac, type);
int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
if (index >= 0) {
_lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[index]);
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
}
}
void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
void gnrc_lwmac_set_timeout(gnrc_netif_t *netif,
gnrc_lwmac_timeout_type_t type,
uint32_t offset)
{
assert(gnrc_netdev);
assert(netif);
gnrc_lwmac_timeout_t *timeout;
if ((timeout = _lwmac_acquire_timeout(gnrc_netdev, type))) {
if ((timeout = _lwmac_acquire_timeout(netif, type))) {
DEBUG("[LWMAC] Set timeout %s in %" PRIu32 " us\n",
lwmac_timeout_names[type], offset);
timeout->expired = false;
timeout->msg.type = GNRC_LWMAC_EVENT_TIMEOUT_TYPE;
timeout->msg.content.ptr = (void *) timeout;
xtimer_set_msg(&(timeout->timer), offset,
&(timeout->msg), gnrc_netdev->pid);
&(timeout->msg), netif->pid);
}
else {
DEBUG("[LWMAC] Cannot set timeout %s, too many concurrent timeouts\n",
@ -136,13 +136,13 @@ void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
}
}
void gnrc_lwmac_reset_timeouts(gnrc_netdev_t *gnrc_netdev)
void gnrc_lwmac_reset_timeouts(gnrc_netif_t *netif)
{
assert(gnrc_netdev);
assert(netif);
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
if (gnrc_netdev->lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
_lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[i]);
if (netif->mac.lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[i]);
}
}
}

View File

@ -49,77 +49,77 @@
*/
#define GNRC_LWMAC_TX_FAIL (0x02U)
static uint8_t _send_bcast(gnrc_netdev_t *gnrc_netdev)
static uint8_t _send_bcast(gnrc_netif_t *netif)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
uint8_t tx_info = 0;
gnrc_pktsnip_t *pkt = gnrc_netdev->tx.packet;
gnrc_pktsnip_t *pkt = netif->mac.tx.packet;
bool first = false;
if (gnrc_lwmac_timeout_is_running(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
if (gnrc_lwmac_timeout_is_running(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
gnrc_pktbuf_release(pkt);
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
tx_info |= GNRC_LWMAC_TX_SUCCESS;
return tx_info;
}
}
else {
LOG_INFO("[LWMAC-tx] Initialize broadcasting\n");
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END,
GNRC_LWMAC_BROADCAST_DURATION_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END,
GNRC_LWMAC_BROADCAST_DURATION_US);
gnrc_pktsnip_t *pkt_payload;
/* Prepare packet with LWMAC header*/
gnrc_lwmac_frame_broadcast_t hdr = {};
hdr.header.type = GNRC_LWMAC_FRAMETYPE_BROADCAST;
hdr.seq_nr = gnrc_netdev->tx.bcast_seqnr++;
hdr.seq_nr = netif->mac.tx.bcast_seqnr++;
pkt_payload = pkt->next;
pkt->next = gnrc_pktbuf_add(pkt->next, &hdr, sizeof(hdr), GNRC_NETTYPE_LWMAC);
if (pkt->next == NULL) {
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type FRAMETYPE_BROADCAST\n");
gnrc_netdev->tx.packet->next = pkt_payload;
netif->mac.tx.packet->next = pkt_payload;
/* Drop the broadcast packet */
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the broadcast packet\n");
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
gnrc_pktbuf_release(netif->mac.tx.packet);
/* clear packet point to avoid TX retry */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
tx_info |= GNRC_LWMAC_TX_FAIL;
return tx_info;
}
/* No Auto-ACK for broadcast packets */
netopt_enable_t autoack = NETOPT_DISABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
first = true;
}
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST) ||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST) ||
first) {
/* if found ongoing transmission, quit this cycle for collision avoidance.
* Broadcast packet will be re-queued and try to send in the next cycle. */
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
* Broadcast packet will be re-queued and try to send in the next cycle. */
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
/* save pointer to netif header */
gnrc_pktsnip_t *netif = pkt->next->next;
gnrc_pktsnip_t *netif_snip = pkt->next->next;
/* remove LWMAC header */
pkt->next->next = NULL;
gnrc_pktbuf_release(pkt->next);
/* make append netif header after payload again */
pkt->next = netif;
pkt->next = netif_snip;
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
tx_info |= GNRC_LWMAC_TX_FAIL;
return tx_info;
}
@ -127,24 +127,24 @@ static uint8_t _send_bcast(gnrc_netdev_t *gnrc_netdev)
/* Don't let the packet be released yet, we want to send it again */
gnrc_pktbuf_hold(pkt, 1);
int res = gnrc_netdev->send(gnrc_netdev, pkt);
int res = _gnrc_lwmac_transmit(netif, pkt);
if (res < 0) {
LOG_ERROR("ERROR: [LWMAC-tx] Send broadcast pkt failed.");
tx_info |= GNRC_LWMAC_TX_FAIL;
return tx_info;
}
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,
GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,
GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US);
LOG_INFO("[LWMAC-tx] Broadcast sent\n");
}
return tx_info;
}
static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
static uint8_t _send_wr(gnrc_netif_t *netif)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
uint8_t tx_info = 0;
gnrc_pktsnip_t *pkt;
@ -153,13 +153,13 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
/* if found ongoing transmission, quit this cycle for collision avoidance.
* Data packet will be re-queued and try to send in the next cycle. */
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
tx_info |= GNRC_LWMAC_TX_FAIL;
return tx_info;
}
@ -167,17 +167,17 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
/* Assemble WR */
gnrc_lwmac_frame_wr_t wr_hdr = {};
wr_hdr.header.type = GNRC_LWMAC_FRAMETYPE_WR;
memcpy(&(wr_hdr.dst_addr.addr), gnrc_netdev->tx.current_neighbor->l2_addr,
gnrc_netdev->tx.current_neighbor->l2_addr_len);
wr_hdr.dst_addr.len = gnrc_netdev->tx.current_neighbor->l2_addr_len;
memcpy(&(wr_hdr.dst_addr.addr), netif->mac.tx.current_neighbor->l2_addr,
netif->mac.tx.current_neighbor->l2_addr_len);
wr_hdr.dst_addr.len = netif->mac.tx.current_neighbor->l2_addr_len;
pkt = gnrc_pktbuf_add(NULL, &wr_hdr, sizeof(wr_hdr), GNRC_NETTYPE_LWMAC);
if (pkt == NULL) {
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
/* clear packet point to avoid TX retry */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
tx_info |= GNRC_LWMAC_TX_FAIL;
return tx_info;
}
@ -190,9 +190,9 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_NETIF\n");
gnrc_pktbuf_release(pkt_lwmac);
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
gnrc_pktbuf_release(netif->mac.tx.packet);
/* clear packet point to avoid TX retry */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
tx_info |= GNRC_LWMAC_TX_FAIL;
return tx_info;
}
@ -209,12 +209,12 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
/* Disable Auto ACK */
netopt_enable_t autoack = NETOPT_DISABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
sizeof(autoack));
/* Prepare WR, this will discard any frame in the transceiver that has
* possibly arrived in the meantime but we don't care at this point. */
int res = gnrc_netdev->send(gnrc_netdev, pkt);
* possibly arrived in the meantime but we don't care at this point. */
int res = _gnrc_lwmac_transmit(netif, pkt);
if (res < 0) {
LOG_ERROR("ERROR: [LWMAC-tx] Send WR failed.");
if (pkt != NULL) {
@ -224,13 +224,13 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
return tx_info;
}
gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
return tx_info;
}
static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
static uint8_t _packet_process_in_wait_for_wa(gnrc_netif_t *netif)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
uint8_t tx_info = 0;
gnrc_pktsnip_t *pkt;
@ -238,7 +238,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
bool postponed = false;
bool from_expected_destination = false;
while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
LOG_DEBUG("[LWMAC-tx] Inspecting pkt @ %p\n", pkt);
/* Parse packet */
@ -251,14 +251,14 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
continue;
}
if (memcmp(&info.src_addr.addr, &gnrc_netdev->tx.current_neighbor->l2_addr,
gnrc_netdev->tx.current_neighbor->l2_addr_len) == 0) {
if (memcmp(&info.src_addr.addr, &netif->mac.tx.current_neighbor->l2_addr,
netif->mac.tx.current_neighbor->l2_addr_len) == 0) {
from_expected_destination = true;
}
if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&gnrc_netdev->rx);
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
gnrc_mac_dispatch(&netif->mac.rx);
/* Drop pointer to it can't get released */
pkt = NULL;
continue;
@ -267,14 +267,14 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
/* Check if destination is talking to another node. It will sleep
* after a finished transaction so there's no point in trying any
* further now. */
if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
gnrc_netdev->l2_addr_len) == 0) && from_expected_destination) {
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
netif->l2addr_len) == 0) && from_expected_destination) {
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
postponed = true;
gnrc_pktbuf_release(pkt);
break;
@ -283,12 +283,12 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
/* if found anther node is also trying to send data,
* quit this cycle for collision avoidance. */
if (info.header->type == GNRC_LWMAC_FRAMETYPE_WR) {
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
postponed = true;
gnrc_pktbuf_release(pkt);
break;
@ -302,33 +302,33 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
if (from_expected_destination) {
/* calculate the phase of the receiver based on WA */
gnrc_netdev->tx.timestamp = _gnrc_lwmac_phase_now();
netif->mac.tx.timestamp = _gnrc_lwmac_phase_now();
gnrc_lwmac_frame_wa_t *wa_hdr;
wa_hdr = (gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_LWMAC))->data;
if (gnrc_netdev->tx.timestamp >= wa_hdr->current_phase) {
gnrc_netdev->tx.timestamp = gnrc_netdev->tx.timestamp -
wa_hdr->current_phase;
if (netif->mac.tx.timestamp >= wa_hdr->current_phase) {
netif->mac.tx.timestamp = netif->mac.tx.timestamp -
wa_hdr->current_phase;
}
else {
gnrc_netdev->tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
gnrc_netdev->tx.timestamp -= wa_hdr->current_phase;
netif->mac.tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
netif->mac.tx.timestamp -= wa_hdr->current_phase;
}
uint32_t own_phase;
own_phase = _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup);
own_phase = _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
if (own_phase >= gnrc_netdev->tx.timestamp) {
own_phase = own_phase - gnrc_netdev->tx.timestamp;
if (own_phase >= netif->mac.tx.timestamp) {
own_phase = own_phase - netif->mac.tx.timestamp;
}
else {
own_phase = gnrc_netdev->tx.timestamp - own_phase;
own_phase = netif->mac.tx.timestamp - own_phase;
}
if ((own_phase < RTT_US_TO_TICKS((3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2))) ||
(own_phase > RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
(3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)))) {
gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev, true);
gnrc_lwmac_set_phase_backoff(netif, true);
LOG_WARNING("WARNING: [LWMAC-tx] phase close\n");
}
}
@ -342,7 +342,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
}
/* All checks passed so this must be a valid WA */
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
found_wa = true;
break;
@ -360,39 +360,40 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
}
/* Save newly calculated phase for destination */
gnrc_netdev->tx.current_neighbor->phase = gnrc_netdev->tx.timestamp;
LOG_INFO("[LWMAC-tx] New phase: %" PRIu32 "\n", gnrc_netdev->tx.timestamp);
netif->mac.tx.current_neighbor->phase = netif->mac.tx.timestamp;
LOG_INFO("[LWMAC-tx] New phase: %" PRIu32 "\n", netif->mac.tx.timestamp);
/* We've got our WA, so discard the rest, TODO: no flushing */
gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
tx_info |= GNRC_LWMAC_TX_SUCCESS;
return tx_info;
}
/* return false if send data failed, otherwise return true */
static bool _send_data(gnrc_netdev_t *gnrc_netdev)
static bool _send_data(gnrc_netif_t *netif)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
gnrc_pktsnip_t *pkt = gnrc_netdev->tx.packet;
gnrc_pktsnip_t *pkt = netif->mac.tx.packet;
gnrc_pktsnip_t *pkt_payload;
assert(pkt != NULL);
/* Enable Auto ACK again */
netopt_enable_t autoack = NETOPT_ENABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK,
&autoack, sizeof(autoack));
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK,
&autoack, sizeof(autoack));
/* It's okay to retry sending DATA. Timing doesn't matter anymore and
* destination is waiting for a certain amount of time. */
uint8_t csma_retries = GNRC_LWMAC_DATA_CSMA_RETRIES;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA_RETRIES,
&csma_retries, sizeof(csma_retries));
netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
&csma_retries, sizeof(csma_retries));
gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
netif->mac.mac_info |= GNRC_NETIF_MAC_INFO_CSMA_ENABLED;
netopt_enable_t csma_enable = NETOPT_ENABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
&csma_enable, sizeof(csma_enable));
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
&csma_enable, sizeof(csma_enable));
pkt_payload = pkt->next;
@ -403,198 +404,196 @@ static bool _send_data(gnrc_netdev_t *gnrc_netdev)
* In case the sender has no more packet for the receiver, it simply sets the
* data type to FRAMETYPE_DATA. */
gnrc_lwmac_hdr_t hdr;
if ((gnrc_priority_pktqueue_length(&gnrc_netdev->tx.current_neighbor->queue) > 0) &&
(gnrc_netdev->tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
if ((gnrc_priority_pktqueue_length(&netif->mac.tx.current_neighbor->queue) > 0) &&
(netif->mac.tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
hdr.type = GNRC_LWMAC_FRAMETYPE_DATA_PENDING;
gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, true);
gnrc_netdev->tx.tx_burst_count++;
gnrc_lwmac_set_tx_continue(netif, true);
netif->mac.tx.tx_burst_count++;
}
else {
hdr.type = GNRC_LWMAC_FRAMETYPE_DATA;
gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, false);
gnrc_lwmac_set_tx_continue(netif, false);
}
pkt->next = gnrc_pktbuf_add(pkt->next, &hdr, sizeof(hdr), GNRC_NETTYPE_LWMAC);
if (pkt->next == NULL) {
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
gnrc_netdev->tx.packet->next = pkt_payload;
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
netif->mac.tx.packet->next = pkt_payload;
gnrc_pktbuf_release(netif->mac.tx.packet);
/* clear packet point to avoid TX retry */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
return false;
}
/* if found ongoing transmission, quit this cycle for collision avoidance.
* Data packet will be re-queued and try to send in the next cycle. */
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
/* save pointer to netif header */
gnrc_pktsnip_t *netif = pkt->next->next;
gnrc_pktsnip_t *netif_snip = pkt->next->next;
/* remove LWMAC header */
pkt->next->next = NULL;
gnrc_pktbuf_release(pkt->next);
/* make append netif header after payload again */
pkt->next = netif;
pkt->next = netif_snip;
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
return false;
}
/* Send data */
int res = gnrc_netdev->send(gnrc_netdev, pkt);
int res = _gnrc_lwmac_transmit(netif, pkt);
if (res < 0) {
LOG_ERROR("ERROR: [LWMAC-tx] Send data failed.");
if (pkt != NULL) {
gnrc_pktbuf_release(pkt);
}
gnrc_pktbuf_release(pkt);
/* clear packet point to avoid TX retry */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
return false;
}
/* Packet has been released by netdev, so drop pointer */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", gnrc_netdev->tx.wr_sent);
DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", netif->mac.tx.wr_sent);
#if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
gnrc_netdev->lwmac.pkt_start_sending_time_ticks =
rtt_get_counter() - gnrc_netdev->lwmac.pkt_start_sending_time_ticks;
netif->mac.lwmac.pkt_start_sending_time_ticks =
rtt_get_counter() - netif->mac.lwmac.pkt_start_sending_time_ticks;
DEBUG("[LWMAC-tx]: pkt sending delay in TX: %lu us\n",
RTT_TICKS_TO_US(gnrc_netdev->lwmac.pkt_start_sending_time_ticks));
RTT_TICKS_TO_US(netif->mac.lwmac.pkt_start_sending_time_ticks));
#endif
return true;
}
void gnrc_lwmac_tx_start(gnrc_netdev_t *gnrc_netdev,
void gnrc_lwmac_tx_start(gnrc_netif_t *netif,
gnrc_pktsnip_t *pkt,
gnrc_mac_tx_neighbor_t *neighbor)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
assert(pkt != NULL);
assert(neighbor != NULL);
if (gnrc_netdev->tx.packet) {
if (netif->mac.tx.packet) {
LOG_WARNING("WARNING: [LWMAC-tx] Starting but tx.packet is still set\n");
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
gnrc_pktbuf_release(netif->mac.tx.packet);
}
gnrc_netdev->tx.packet = pkt;
gnrc_netdev->tx.current_neighbor = neighbor;
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_INIT;
gnrc_netdev->tx.wr_sent = 0;
netif->mac.tx.packet = pkt;
netif->mac.tx.current_neighbor = neighbor;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_INIT;
netif->mac.tx.wr_sent = 0;
#if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
gnrc_netdev->lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
netif->mac.lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
#endif
}
void gnrc_lwmac_tx_stop(gnrc_netdev_t *gnrc_netdev)
void gnrc_lwmac_tx_stop(gnrc_netif_t *netif)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_STOPPED;
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_STOPPED;
/* Release packet in case of failure */
if (gnrc_netdev->tx.packet) {
if (gnrc_netdev->tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
gnrc_netdev->tx.tx_retry_count = 0;
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
gnrc_netdev->tx.packet = NULL;
if (netif->mac.tx.packet) {
if (netif->mac.tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
netif->mac.tx.tx_retry_count = 0;
gnrc_pktbuf_release(netif->mac.tx.packet);
netif->mac.tx.packet = NULL;
LOG_WARNING("WARNING: [LWMAC-tx] Drop TX packet\n");
}
else {
gnrc_netdev->tx.tx_retry_count++;
netif->mac.tx.tx_retry_count++;
return;
}
}
if (!gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) {
gnrc_netdev->tx.current_neighbor = NULL;
if (!gnrc_lwmac_get_tx_continue(netif)) {
netif->mac.tx.current_neighbor = NULL;
}
}
/* Returns whether rescheduling is needed or not */
static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
static bool _lwmac_tx_update(gnrc_netif_t *netif)
{
assert(gnrc_netdev != NULL);
assert(netif != NULL);
bool reschedule = false;
switch (gnrc_netdev->tx.state) {
switch (netif->mac.tx.state) {
case GNRC_LWMAC_TX_STATE_INIT: {
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
/* if found ongoing transmission,
* quit this cycle for collision avoidance. */
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.packet = NULL;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
/* check if the packet is for broadcast */
if (gnrc_netif_hdr_get_flag(gnrc_netdev->tx.packet) &
if (gnrc_netif_hdr_get_flag(netif->mac.tx.packet) &
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
/* Set CSMA retries as configured and enable */
uint8_t csma_retries = GNRC_LWMAC_BROADCAST_CSMA_RETRIES;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA_RETRIES,
&csma_retries, sizeof(csma_retries));
gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
&csma_retries, sizeof(csma_retries));
netif->mac.mac_info |= GNRC_NETIF_MAC_INFO_CSMA_ENABLED;
netopt_enable_t csma_enable = NETOPT_ENABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
&csma_enable, sizeof(csma_enable));
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
&csma_enable, sizeof(csma_enable));
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_BROADCAST;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_BROADCAST;
reschedule = true;
break;
}
else {
/* Use CSMA for the first WR */
gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
netif->mac.mac_info |= GNRC_NETIF_MAC_INFO_CSMA_ENABLED;
netopt_enable_t csma_disable = NETOPT_ENABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
&csma_disable, sizeof(csma_disable));
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
&csma_disable, sizeof(csma_disable));
/* Set a timeout for the maximum transmission procedure */
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE, GNRC_LWMAC_PREAMBLE_DURATION_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE, GNRC_LWMAC_PREAMBLE_DURATION_US);
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
reschedule = true;
break;
}
}
case GNRC_LWMAC_TX_STATE_SEND_BROADCAST: {
uint8_t tx_info = _send_bcast(gnrc_netdev);
uint8_t tx_info = _send_bcast(netif);
if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
reschedule = true;
break;
}
if (tx_info & GNRC_LWMAC_TX_FAIL) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
@ -603,23 +602,23 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
}
case GNRC_LWMAC_TX_STATE_SEND_WR: {
/* In case of no Tx-isr error (e.g., no Tx-isr), goto TX failure. */
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination, "
"probably no TX-ISR\n");
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
"probably no TX-ISR\n");
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_SEND_WR\n");
uint8_t tx_info = _send_wr(gnrc_netdev);
uint8_t tx_info = _send_wr(netif);
if (tx_info & GNRC_LWMAC_TX_FAIL) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_WR_SENT;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_WR_SENT;
reschedule = false;
break;
}
@ -627,84 +626,84 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_WR_SENT\n");
/* In case of no Tx-isr error (e.g., no Tx-isr), goto TX failure. */
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
LOG_DEBUG("[LWMAC-tx] WR not yet completely sent\n");
break;
}
/* If found ongoing transmission, goto TX failure, i.e., postpone transmission to
* next cycle. This is mainly for collision avoidance. */
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_BUSY) {
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_BUSY) {
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* clear packet point to avoid TX retry */
gnrc_netdev->tx.packet = NULL;
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.packet = NULL;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
if (gnrc_netdev->tx.wr_sent == 0) {
if (netif->mac.tx.wr_sent == 0) {
/* Only the first WR use CSMA */
gnrc_netdev->mac_info &= ~GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
netif->mac.mac_info &= ~GNRC_NETIF_MAC_INFO_CSMA_ENABLED;
netopt_enable_t csma_disable = NETOPT_DISABLE;
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
&csma_disable, sizeof(csma_disable));
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
&csma_disable, sizeof(csma_disable));
}
gnrc_netdev->tx.wr_sent++;
netif->mac.tx.wr_sent++;
/* Set timeout for next WR in case no WA will be received */
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
/* Debug WR timing */
LOG_DEBUG("[LWMAC-tx] Destination phase was: %" PRIu32 "\n",
gnrc_netdev->tx.current_neighbor->phase);
netif->mac.tx.current_neighbor->phase);
LOG_DEBUG("[LWMAC-tx] Phase when sent was: %" PRIu32 "\n",
_gnrc_lwmac_ticks_to_phase(gnrc_netdev->tx.timestamp));
_gnrc_lwmac_ticks_to_phase(netif->mac.tx.timestamp));
LOG_DEBUG("[LWMAC-tx] Ticks when sent was: %" PRIu32 "\n",
gnrc_netdev->tx.timestamp);
_gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_FOR_WA;
netif->mac.tx.timestamp);
_gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_FOR_WA;
reschedule = false;
break;
}
case GNRC_LWMAC_TX_STATE_WAIT_FOR_WA: {
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_FOR_WA\n");
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR)) {
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_WR)) {
/* In case the sender is in consecutive (burst) transmission to the receiver,
* meaning that the sender has already successfully sent at least one data to
* the receiver, then the sender will only spend one WR for triggering the next
* transmission procedure. And, if this WR doesn't work (no WA replied), the
* sender regards consecutive transmission failed.
*/
if (gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) {
if (gnrc_lwmac_get_tx_continue(netif)) {
LOG_DEBUG("[LWMAC-tx] Tx burst fail\n");
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
gnrc_pktbuf_release(netif->mac.tx.packet);
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
}
/* drop pointer so it wont be free'd */
gnrc_netdev->tx.packet = NULL;
netif->mac.tx.packet = NULL;
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
@ -713,27 +712,27 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
* latter's wake-up period, the sender just keep sending WRs until it
* finds the WA.
*/
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
reschedule = true;
break;
}
}
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
/* Wait for completion of frame reception */
break;
}
uint8_t tx_info = _packet_process_in_wait_for_wa(gnrc_netdev);
uint8_t tx_info = _packet_process_in_wait_for_wa(netif);
if (tx_info & GNRC_LWMAC_TX_FAIL) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
reschedule = true;
break;
}
@ -745,49 +744,49 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
case GNRC_LWMAC_TX_STATE_SEND_DATA: {
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_SEND_DATA\n");
if (!_send_data(gnrc_netdev)) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
if (!_send_data(netif)) {
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK;
reschedule = false;
break;
}
case GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK: {
/* In case of no Tx-isr error, goto TX failure. */
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK\n");
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
break;
}
else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_SUCCESS) {
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
else if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_SUCCESS) {
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
reschedule = true;
break;
}
else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_NOACK) {
else if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_NOACK) {
LOG_ERROR("ERROR: [LWMAC-tx] Not ACKED\n");
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_BUSY) {
else if (gnrc_netif_get_tx_feedback(netif) == TX_FEEDBACK_BUSY) {
LOG_ERROR("ERROR: [LWMAC-tx] Channel busy \n");
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
LOG_ERROR("ERROR: [LWMAC-tx] Tx feedback unhandled: %i\n",
gnrc_netdev_get_tx_feedback(gnrc_netdev));
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
gnrc_netif_get_tx_feedback(netif));
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
reschedule = true;
break;
}
@ -803,8 +802,8 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
return reschedule;
}
void gnrc_lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
void gnrc_lwmac_tx_update(gnrc_netif_t *netif)
{
/* Update until no rescheduling needed */
while (_lwmac_tx_update(gnrc_netdev)) {}
while (_lwmac_tx_update(netif)) {}
}

View File

@ -1,3 +1,3 @@
MODULE = gnrc_netif
MODULE := gnrc_netif
include $(RIOTBASE)/Makefile.base

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
* Copyright (C) 2015 René Kijewski <rene.kijewski@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @{
*
* @file
*/
#include "net/gnrc/netif.h"
static inline int _dehex(char c, int default_)
{
if ('0' <= c && c <= '9') {
return c - '0';
}
else if ('A' <= c && c <= 'F') {
return c - 'A' + 10;
}
else if ('a' <= c && c <= 'f') {
return c - 'a' + 10;
}
else {
return default_;
}
}
size_t gnrc_netif_addr_from_str(uint8_t *out, size_t out_len, const char *str)
{
/* Walk over str from the end. */
/* Take two chars a time as one hex value (%hhx). */
/* Leading zeros can be omitted. */
/* Every non-hexadimal character is a delimiter. */
/* Leading, tailing and adjacent delimiters are forbidden. */
const char *end_str = str;
uint8_t *out_end = out;
size_t count = 0;
int assert_cell = 1;
if (!str || !*str) {
return 0;
}
while (end_str[1]) {
++end_str;
}
while (end_str >= str) {
int a = 0, b = _dehex(*end_str--, -1);
if (b < 0) {
if (assert_cell) {
return 0;
}
else {
assert_cell = 1;
continue;
}
}
assert_cell = 0;
if (end_str >= str) {
a = _dehex(*end_str--, 0);
}
if (++count > out_len) {
return 0;
}
*out_end++ = (a << 4) | b;
}
if (assert_cell) {
return 0;
}
/* out is reversed */
while (out < --out_end) {
uint8_t tmp = *out_end;
*out_end = *out;
*out++ = tmp;
}
return count;
}
/** @} */

View File

@ -1,48 +0,0 @@
/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @{
*
* @file
*/
#include "net/gnrc/netif.h"
static inline char _half_byte_to_char(uint8_t half_byte)
{
return (half_byte < 10) ? ('0' + half_byte) : ('a' + (half_byte - 10));
}
char *gnrc_netif_addr_to_str(char *out, size_t out_len, const uint8_t *addr,
size_t addr_len)
{
size_t i;
if (out_len < (3 * addr_len)) { /* 2 for every byte, 1 for ':' or '\0' */
return NULL;
}
out[0] = '\0';
for (i = 0; i < addr_len; i++) {
out[(3 * i)] = _half_byte_to_char(addr[i] >> 4);
out[(3 * i) + 1] = _half_byte_to_char(addr[i] & 0xf);
if (i != (addr_len - 1)) {
out[(3 * i) + 2] = ':';
}
else {
out[(3 * i) + 2] = '\0';
}
}
return out;
}
/** @} */

View File

@ -18,7 +18,7 @@
#ifdef MODULE_NETDEV_ETH
#include "net/ethernet/hdr.h"
#include "net/gnrc.h"
#include "net/gnrc/netif2/ethernet.h"
#include "net/gnrc/netif/ethernet.h"
#ifdef MODULE_GNRC_IPV6
#include "net/ipv6/hdr.h"
#endif
@ -26,22 +26,22 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif);
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif);
static const gnrc_netif2_ops_t ethernet_ops = {
static const gnrc_netif_ops_t ethernet_ops = {
.send = _send,
.recv = _recv,
.get = gnrc_netif2_get_from_netdev,
.set = gnrc_netif2_set_from_netdev,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
gnrc_netif2_t *gnrc_netif2_ethernet_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
gnrc_netif_t *gnrc_netif_ethernet_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
{
return gnrc_netif2_create(stack, stacksize, priority, name, dev,
&ethernet_ops);
return gnrc_netif_create(stack, stacksize, priority, name, dev,
&ethernet_ops);
}
static inline void _addr_set_broadcast(uint8_t *dst)
@ -67,7 +67,7 @@ static inline void _addr_set_multicast(uint8_t *dst, gnrc_pktsnip_t *payload)
}
}
static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
ethernet_hdr_t hdr;
gnrc_netif_hdr_t *netif_hdr;
@ -77,14 +77,14 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
netdev_t *dev = netif->dev;
if (pkt == NULL) {
DEBUG("gnrc_netif2_ethernet: pkt was NULL\n");
DEBUG("gnrc_netif_ethernet: pkt was NULL\n");
return -EINVAL;
}
payload = pkt->next;
if (pkt->type != GNRC_NETTYPE_NETIF) {
DEBUG("gnrc_netif2_ethernet: First header was not generic netif header\n");
DEBUG("gnrc_netif_ethernet: First header was not generic netif header\n");
return -EBADMSG;
}
@ -111,7 +111,7 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
}
else if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST) {
if (payload == NULL) {
DEBUG("gnrc_netif2_ethernet: empty multicast packets over Ethernet "
DEBUG("gnrc_netif_ethernet: empty multicast packets over Ethernet "
"are not yet supported\n");
return -ENOTSUP;
}
@ -122,12 +122,12 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
ETHERNET_ADDR_LEN);
}
else {
DEBUG("gnrc_netif2_ethernet: destination address had unexpected "
DEBUG("gnrc_netif_ethernet: destination address had unexpected "
"format\n");
return -EBADMSG;
}
DEBUG("gnrc_netif2_ethernet: send to %02x:%02x:%02x:%02x:%02x:%02x\n",
DEBUG("gnrc_netif_ethernet: send to %02x:%02x:%02x:%02x:%02x:%02x\n",
hdr.dst[0], hdr.dst[1], hdr.dst[2],
hdr.dst[3], hdr.dst[4], hdr.dst[5]);
@ -157,7 +157,7 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
return res;
}
static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)
{
netdev_t *dev = netif->dev;
int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL);
@ -169,7 +169,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
GNRC_NETTYPE_UNDEF);
if (!pkt) {
DEBUG("gnrc_netif2_ethernet: cannot allocate pktsnip.\n");
DEBUG("gnrc_netif_ethernet: cannot allocate pktsnip.\n");
/* drop the packet */
dev->driver->recv(dev, NULL, bytes_expected, NULL);
@ -179,7 +179,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
int nread = dev->driver->recv(dev, pkt->data, bytes_expected, NULL);
if (nread <= 0) {
DEBUG("gnrc_netif2_ethernet: read error.\n");
DEBUG("gnrc_netif_ethernet: read error.\n");
goto safe_out;
}
@ -187,14 +187,14 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
/* we've got less than the expected packet size,
* so free the unused space.*/
DEBUG("gnrc_netif2_ethernet: reallocating.\n");
DEBUG("gnrc_netif_ethernet: reallocating.\n");
gnrc_pktbuf_realloc_data(pkt, nread);
}
/* mark ethernet header */
gnrc_pktsnip_t *eth_hdr = gnrc_pktbuf_mark(pkt, sizeof(ethernet_hdr_t), GNRC_NETTYPE_UNDEF);
if (!eth_hdr) {
DEBUG("gnrc_netif2_ethernet: no space left in packet buffer\n");
DEBUG("gnrc_netif_ethernet: no space left in packet buffer\n");
goto safe_out;
}
@ -202,7 +202,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
#ifdef MODULE_L2FILTER
if (!l2filter_pass(dev->filter, hdr->src, ETHERNET_ADDR_LEN)) {
DEBUG("gnrc_netif2_ethernet: incoming packet filtered by l2filter\n");
DEBUG("gnrc_netif_ethernet: incoming packet filtered by l2filter\n");
goto safe_out;
}
#endif
@ -217,7 +217,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
GNRC_NETTYPE_NETIF);
if (netif_hdr == NULL) {
DEBUG("gnrc_netif2_ethernet: no space left in packet buffer\n");
DEBUG("gnrc_netif_ethernet: no space left in packet buffer\n");
pkt = eth_hdr;
goto safe_out;
}
@ -227,7 +227,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
gnrc_netif_hdr_set_dst_addr(netif_hdr->data, hdr->dst, ETHERNET_ADDR_LEN);
((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid();
DEBUG("gnrc_netif2_ethernet: received packet from %02x:%02x:%02x:%02x:%02x:%02x "
DEBUG("gnrc_netif_ethernet: received packet from %02x:%02x:%02x:%02x:%02x:%02x "
"of length %d\n",
hdr->src[0], hdr->src[1], hdr->src[2], hdr->src[3], hdr->src[4],
hdr->src[5], nread);

View File

@ -14,7 +14,7 @@
*/
#include "net/gnrc.h"
#include "net/gnrc/netif2/ieee802154.h"
#include "net/gnrc/netif/ieee802154.h"
#include "net/netdev/ieee802154.h"
#ifdef MODULE_GNRC_IPV6
@ -25,22 +25,22 @@
#include "debug.h"
#ifdef MODULE_NETDEV_IEEE802154
static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif);
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif);
static const gnrc_netif2_ops_t ieee802154_ops = {
static const gnrc_netif_ops_t ieee802154_ops = {
.send = _send,
.recv = _recv,
.get = gnrc_netif2_get_from_netdev,
.set = gnrc_netif2_set_from_netdev,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
gnrc_netif2_t *gnrc_netif2_ieee802154_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
gnrc_netif_t *gnrc_netif_ieee802154_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
{
return gnrc_netif2_create(stack, stacksize, priority, name, dev,
&ieee802154_ops);
return gnrc_netif_create(stack, stacksize, priority, name, dev,
&ieee802154_ops);
}
static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr)
@ -70,7 +70,7 @@ static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr)
return snip;
}
static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)
{
netdev_t *dev = netif->dev;
netdev_ieee802154_rx_info_t rx_info;
@ -156,7 +156,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
return pkt;
}
static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
netdev_t *dev = netif->dev;
netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
@ -223,8 +223,8 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
}
#endif
#ifdef MODULE_GNRC_MAC
if (netif->mac_info & GNRC_NETDEV_MAC_INFO_CSMA_ENABLED) {
res = csma_sender_csma_ca_send(dev, vector, n, &netif->csma_conf);
if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) {
res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf);
}
else {
res = dev->driver->send(dev, vector, n);

View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @{
*
* @file
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#include "net/gnrc/pktbuf.h"
#include "net/gnrc/netif/raw.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define IP_VERSION_MASK (0xf0U)
#define IP_VERSION4 (0x40U)
#define IP_VERSION6 (0x60U)
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 raw_ops = {
.send = _send,
.recv = _recv,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
gnrc_netif_t *gnrc_netif_raw_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
{
return gnrc_netif_create(stack, stacksize, priority, name, dev,
&raw_ops);
}
static inline uint8_t _get_version(uint8_t *data)
{
return (data[0] & IP_VERSION_MASK);
}
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)
{
netdev_t *dev = netif->dev;
int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL);
gnrc_pktsnip_t *pkt = NULL;
if (bytes_expected > 0) {
int nread;
pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF);
if (!pkt) {
DEBUG("gnrc_netif_raw: cannot allocate pktsnip.\n");
/* drop packet */
dev->driver->recv(dev, NULL, bytes_expected, NULL);
return pkt;
}
nread = dev->driver->recv(dev, pkt->data, bytes_expected, NULL);
if (nread <= 1) { /* we need at least 1 byte to identify IP version */
DEBUG("gnrc_netif_raw: read error.\n");
gnrc_pktbuf_release(pkt);
return NULL;
}
if (nread < bytes_expected) {
/* we've got less then the expected packet size,
* so free the unused space.*/
DEBUG("gnrc_netif_raw: reallocating.\n");
gnrc_pktbuf_realloc_data(pkt, nread);
}
switch (_get_version(pkt->data)) {
#ifdef MODULE_GNRC_IPV6
case IP_VERSION6:
pkt->type = GNRC_NETTYPE_IPV6;
break;
#endif
default:
/* leave UNDEF */
break;
}
}
return pkt;
}
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
gnrc_pktsnip_t *vector;
int res = -ENOBUFS;
size_t n;
if (pkt->type == GNRC_NETTYPE_NETIF) {
/* we don't need the netif snip: remove it */
pkt = gnrc_pktbuf_remove_snip(pkt, pkt);
}
vector = gnrc_pktbuf_get_iovec(pkt, &n);
if (vector != NULL) {
struct iovec *v = (struct iovec *)vector->data;
netdev_t *dev = netif->dev;
#ifdef MODULE_NETSTATS_L2
dev->stats.tx_unicast_count++;
#endif
res = dev->driver->send(dev, v, n);
}
return res;
}
/** @} */

View File

@ -44,9 +44,8 @@ void gnrc_netif_hdr_print(gnrc_netif_hdr_t *hdr)
if (hdr->src_l2addr_len > 0) {
printf("src_l2addr: %s\n",
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
gnrc_netif_hdr_get_src_addr(hdr),
(size_t)hdr->src_l2addr_len));
gnrc_netif_addr_to_str(gnrc_netif_hdr_get_src_addr(hdr),
hdr->src_l2addr_len, addr_str));
}
else {
puts("src_l2addr: (nil)");
@ -54,9 +53,8 @@ void gnrc_netif_hdr_print(gnrc_netif_hdr_t *hdr)
if (hdr->dst_l2addr_len > 0) {
printf("dst_l2addr: %s\n",
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
gnrc_netif_hdr_get_dst_addr(hdr),
(size_t)hdr->dst_l2addr_len));
gnrc_netif_addr_to_str(gnrc_netif_hdr_get_dst_addr(hdr),
hdr->dst_l2addr_len, addr_str));
}
else {
puts("dst_l2addr: (nil)");

View File

@ -1,3 +0,0 @@
MODULE := gnrc_netif2
include $(RIOTBASE)/Makefile.base

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,6 @@
#include "msg.h"
#include "mutex.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netif.h"
#include "net/netopt.h"
#include "net/gnrc/netreg.h"
#include "net/gnrc/pktbuf.h"
@ -132,13 +131,9 @@ gnrc_nettest_res_t gnrc_nettest_send_iface(kernel_pid_t pid, gnrc_pktsnip_t *in,
{
gnrc_nettest_res_t res;
gnrc_netif_add(thread_getpid());
res = _pkt_test(GNRC_NETAPI_MSG_TYPE_SND, pid, in, exp_pkts, exp_senders,
exp_out);
gnrc_netif_remove(thread_getpid());
return res;
}

View File

@ -15,7 +15,6 @@
#include "net/gnrc/pktbuf.h"
#include "net/ipv6.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/icmpv6/error.h"
#include "net/gnrc/icmpv6.h"

View File

@ -23,11 +23,7 @@
#include "kernel_types.h"
#include "net/ipv6/hdr.h"
#include "net/gnrc.h"
#ifndef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ndp.h"
#else
#include "net/gnrc/ipv6/nib.h"
#endif
#include "net/protnum.h"
#include "od.h"
#include "utlist.h"
@ -77,8 +73,7 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
return;
}
/* Note: size will be checked again in gnrc_icmpv6_echo_req_handle,
gnrc_ndp_rtr_sol_handle, and others */
/* Note: size will be checked again in packet handlers */
hdr = (icmpv6_hdr_t *)icmpv6->data;
@ -98,40 +93,6 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
break;
#endif
#ifndef MODULE_GNRC_IPV6_NIB
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
case ICMPV6_RTR_SOL:
DEBUG("icmpv6: router solicitation received\n");
gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6->data, (ndp_rtr_sol_t *)hdr,
icmpv6->size);
break;
#endif
#ifdef MODULE_GNRC_NDP
case ICMPV6_RTR_ADV:
DEBUG("icmpv6: router advertisement received\n");
gnrc_ndp_rtr_adv_handle(iface, pkt, ipv6->data, (ndp_rtr_adv_t *)hdr,
icmpv6->size);
break;
case ICMPV6_NBR_SOL:
DEBUG("icmpv6: neighbor solicitation received\n");
gnrc_ndp_nbr_sol_handle(iface, pkt, ipv6->data, (ndp_nbr_sol_t *)hdr,
icmpv6->size);
break;
case ICMPV6_NBR_ADV:
DEBUG("icmpv6: neighbor advertisement received\n");
gnrc_ndp_nbr_adv_handle(iface, pkt, ipv6->data, (ndp_nbr_adv_t *)hdr,
icmpv6->size);
break;
#endif
case ICMPV6_REDIRECT:
DEBUG("icmpv6: redirect message received\n");
/* TODO */
break;
#else /* MODULE_GNRC_IPV6_NIB */
case ICMPV6_RTR_SOL:
case ICMPV6_RTR_ADV:
case ICMPV6_NBR_SOL:
@ -140,9 +101,9 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
case ICMPV6_DAR:
case ICMPV6_DAC:
DEBUG("icmpv6: NDP message received. Handle with gnrc_ipv6_nib\n");
gnrc_ipv6_nib_handle_pkt(iface, ipv6->data, hdr, icmpv6->size);
gnrc_ipv6_nib_handle_pkt(gnrc_netif_get_by_pid(iface),
ipv6->data, hdr, icmpv6->size);
break;
#endif /* MODULE_GNRC_IPV6_NIB */
default:
DEBUG("icmpv6: unknown type field %u\n", hdr->type);

Some files were not shown because too many files have changed in this diff Show More