Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnrc_netif: add packet to queue when device is busy #11263

Merged
merged 3 commits into from
Sep 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,10 @@ ifneq (,$(filter gnrc_netif_%,$(USEMODULE)))
USEMODULE += gnrc_netif
endif

ifneq (,$(filter gnrc_netif_pktq,$(USEMODULE)))
USEMODULE += xtimer
endif

ifneq (,$(filter netstats_%, $(USEMODULE)))
USEMODULE += netstats
endif
Expand Down
13 changes: 12 additions & 1 deletion sys/include/net/gnrc/netif.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
* Copyright (C) 2017-20 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
Expand Down Expand Up @@ -59,6 +59,9 @@
#if IS_USED(MODULE_GNRC_NETIF_MAC)
#include "net/gnrc/netif/mac.h"
#endif
#if IS_USED(MODULE_GNRC_NETIF_PKTQ)
#include "net/gnrc/netif/pktq/type.h"
#endif
#include "net/ndp.h"
#include "net/netdev.h"
#include "net/netopt.h"
Expand Down Expand Up @@ -171,6 +174,14 @@ typedef struct {
#endif
#if IS_USED(MODULE_GNRC_NETIF_6LO) || defined(DOXYGEN)
gnrc_netif_6lo_t sixlo; /**< 6Lo component */
#endif
#if IS_USED(MODULE_GNRC_NETIF_PKTQ) || defined(DOXYGEN)
/**
* @brief Packet queue for sending
*
* @note Only available with @ref net_gnrc_netif_pktq.
*/
gnrc_netif_pktq_t send_queue;
#endif
uint8_t cur_hl; /**< Current hop-limit for out-going packets */
uint8_t device_type; /**< Device type */
Expand Down
24 changes: 24 additions & 0 deletions sys/include/net/gnrc/netif/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ extern "C" {
#define CONFIG_GNRC_NETIF_MSG_QUEUE_SIZE_EXP (4U)
#endif

/**
* @brief Packet queue pool size for all network interfaces
*
* @note With @ref net_gnrc_sixlowpan_frag the queue should fit at least
* all fragments of the minimum MTU.
* @see net_gnrc_netif_pktq
*/
#ifndef CONFIG_GNRC_NETIF_PKTQ_POOL_SIZE
#define CONFIG_GNRC_NETIF_PKTQ_POOL_SIZE (16U)
#endif

/**
* @brief Time in microseconds for when to try send a queued packet at the
* latest
*
* Set to -1 to deactivate dequeing by timer. For this it has to be ensured that
* none of the notifications by the driver are missed!
*
* @see net_gnrc_netif_pktq
*/
#ifndef CONFIG_GNRC_NETIF_PKTQ_TIMER_US
#define CONFIG_GNRC_NETIF_PKTQ_TIMER_US (5000U)
#endif

/**
* @brief Number of multicast addresses needed for @ref net_gnrc_rpl "RPL".
*
Expand Down
7 changes: 6 additions & 1 deletion sys/include/net/gnrc/netif/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@
extern "C" {
#endif

/**
* @brief Message type to send from @ref net_gnrc_netif_pktq
*/
#define GNRC_NETIF_PKTQ_DEQUEUE_MSG (0x1233)

/**
* @brief Message type for @ref netdev_event_t "netdev events"
*/
#define NETDEV_MSG_TYPE_EVENT (0x1234)
#define NETDEV_MSG_TYPE_EVENT (0x1234)

/**
* @brief Acquires exclusive access to the interface
Expand Down
138 changes: 138 additions & 0 deletions sys/include/net/gnrc/netif/pktq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright (C) 2019-20 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_netif_pktq Send queue for @ref net_gnrc_netif
* @ingroup net_gnrc_netif
* @brief
* @{
*
* @file
* @brief @ref net_gnrc_netif_pktq definitions
*
* @author Martine S. Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF_PKTQ_H
#define NET_GNRC_NETIF_PKTQ_H

#include <assert.h>
#include <stdbool.h>

#include "net/gnrc/netif.h"
#include "net/gnrc/netif/pktq/type.h"
#include "net/gnrc/pkt.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Puts a packet into the packet send queue of a network interface
*
* @pre `netif != NULL`
* @pre `pkt != NULL`
*
* @param[in] netif A network interface. May not be NULL.
* @param[in] pkt A packet. May not be NULL.
*
* @return 0 on success
* @return -1 when the pool of available gnrc_pktqueue_t entries (of size
* @ref CONFIG_GNRC_NETIF_PKTQ_POOL_SIZE) is depleted
*/
int gnrc_netif_pktq_put(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);

/**
* @brief Gets a packet from the packet send queue of a network interface
*
* @pre `netif != NULL`
*
* @param[in] netif A network interface. May not be NULL.
*
* @return A packet on success
* @return NULL when the queue is empty
*/
static inline gnrc_pktsnip_t *gnrc_netif_pktq_get(gnrc_netif_t *netif)
{
#if IS_USED(MODULE_GNRC_NETIF_PKTQ)
assert(netif != NULL);

gnrc_pktsnip_t *pkt = NULL;
gnrc_pktqueue_t *entry = gnrc_pktqueue_remove_head(
&netif->send_queue.queue
);

if (entry != NULL) {
pkt = entry->pkt;
entry->pkt = NULL;
}
return pkt;
#else /* IS_USED(MODULE_GNRC_NETIF_PKTQ) */
(void)netif;
return NULL;
#endif /* IS_USED(MODULE_GNRC_NETIF_PKTQ) */
}

/**
* @brief Schedule a dequeue notification to network interface
*
* The notification will be scheduled in @ref CONFIG_GNRC_NETIF_PKTQ_TIMER_US
* microseconds.
*
* @pre `netif != NULL`
*
* The signaling message can be used to send the next message in
* gnrc_netif_pktq_t::queue.
*
* @param[in] netif A network interface. May not be NULL.
*/
void gnrc_netif_pktq_sched_get(gnrc_netif_t *netif);

/**
* @brief Pushes a packet back to the head of the packet send queue of a
* network interface
*
* @pre `netif != NULL`
* @pre `pkt != NULL`
*
* @param[in] netif A network interface. May not be NULL.
* @param[in] pkt A packet. May not be NULL.
*
* @return 0 on success
* @return -1 when the pool of available gnrc_pktqueue_t entries (of size
* @ref CONFIG_GNRC_NETIF_PKTQ_POOL_SIZE) is depleted
*/
int gnrc_netif_pktq_push_back(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);

/**
* @brief Check if a network interface's packet send queue is empty
*
* @pre `netif != NULL`
*
* @param[in] netif A network interface. May not be NULL.
*
* @return true, when the packet send queue of @p netif is empty
* @return false, otherwise
*/
static inline bool gnrc_netif_pktq_empty(gnrc_netif_t *netif)
{
#if IS_USED(MODULE_GNRC_NETIF_PKTQ)
assert(netif != NULL);

return (netif->send_queue.queue == NULL);
#else /* IS_USED(MODULE_GNRC_NETIF_PKTQ) */
(void)netif;
return false;
#endif /* IS_USED(MODULE_GNRC_NETIF_PKTQ) */
}

#ifdef __cplusplus
}
#endif

#endif /* NET_GNRC_NETIF_PKTQ_H */
/** @} */
50 changes: 50 additions & 0 deletions sys/include/net/gnrc/netif/pktq/type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2019-20 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.
*/

/**
* @addtogroup net_gnrc_netif_pktq
* @brief
* @{
*
* @file
* @brief @ref net_gnrc_netif_pktq type definitions
*
* Contained in its own file, so the type can be included in
* @ref gnrc_netif_t while the functions in net/gnrc/netif/pktq.h can use
* @ref gnrc_netif_t as operating type.
*
* @author Martine S. Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_NETIF_PKTQ_TYPE_H
#define NET_GNRC_NETIF_PKTQ_TYPE_H

#include "net/gnrc/pktqueue.h"
#include "xtimer.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief A packet queue for @ref net_gnrc_netif with a de-queue timer
*/
typedef struct {
gnrc_pktqueue_t *queue; /**< the actual packet queue class */
#if CONFIG_GNRC_NETIF_PKTQ_TIMER_US >= 0
msg_t dequeue_msg; /**< message for gnrc_netif_pktq_t::dequeue_timer to send */
xtimer_t dequeue_timer; /**< timer to schedule next sending of
* queued packets */
#endif
} gnrc_netif_pktq_t;

#ifdef __cplusplus
}
#endif

#endif /* NET_GNRC_NETIF_PKTQ_TYPE_H */
/** @} */
13 changes: 13 additions & 0 deletions sys/net/gnrc/netif/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,17 @@ config GNRC_NETIF_NONSTANDARD_6LO_MTU
This is non compliant with RFC 4944 and might not be supported by other
implementations.

config GNRC_NETIF_PKTQ_POOL_SIZE
int "Packet queue pool size for all network interfaces"
depends on USEMODULE_GNRC_NETIF_PKTQ
default 16

config GNRC_NETIF_PKTQ_TIMER_US
int "Time in microseconds for when to try to send a queued packet at the latest"
depends on USEMODULE_GNRC_NETIF_PKTQ
default 5000
help
Set to -1 to deactivate dequeing by timer. For this it has to be ensured
that none of the notifications by the driver are missed!

endif # KCONFIG_USEMODULE_GNRC_NETIF
3 changes: 3 additions & 0 deletions sys/net/gnrc/netif/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ endif
ifneq (,$(filter gnrc_netif_init_devs,$(USEMODULE)))
DIRS += init_devs
endif
ifneq (,$(filter gnrc_netif_pktq,$(USEMODULE)))
DIRS += pktq
endif
ifneq (,$(filter gnrc_netif_hdr,$(USEMODULE)))
DIRS += hdr
endif
Expand Down
Loading