From 3c9e8ac80d7c079b0f6055bcac18f2e4c6af650e Mon Sep 17 00:00:00 2001
From: Martine Lenders <mlenders@inf.fu-berlin.de>
Date: Sun, 5 Jun 2016 14:29:03 +0200
Subject: [PATCH] csma_sender: allow for multi-interface configuration

---
 sys/include/net/csma_sender.h                | 42 +++++++-------
 sys/net/link_layer/csma_sender/csma_sender.c | 61 ++++++++------------
 2 files changed, 46 insertions(+), 57 deletions(-)

diff --git a/sys/include/net/csma_sender.h b/sys/include/net/csma_sender.h
index 579a711d9f..6faed9db60 100644
--- a/sys/include/net/csma_sender.h
+++ b/sys/include/net/csma_sender.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2015 INRIA
+ * Copyright (C) 2016 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
@@ -18,6 +19,7 @@
  * @brief       Interface definition for the CSMA/CA helper
  *
  * @author      Kévin Roussel <Kevin.Roussel@inria.fr>
+ * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
  */
 
 #ifndef CSMA_SENDER_H_
@@ -32,51 +34,49 @@
 extern "C" {
 #endif
 
-
 /**
  * @brief Default Minimal CSMA/CA Backoff Exponent
  */
+#ifndef CSMA_SENDER_MIN_BE_DEFAULT
 #define CSMA_SENDER_MIN_BE_DEFAULT          (3U)
+#endif
 
 /**
  * @brief Default Maximal CSMA/CA Backoff Exponent
  */
+#ifndef CSMA_SENDER_MAX_BE_DEFAULT
 #define CSMA_SENDER_MAX_BE_DEFAULT          (5U)
+#endif
 
 /**
  * @brief Default Maximal number of retries for sending
  *        a given packet with the CSMA/CA method
  */
+#ifndef CSMA_SENDER_MAX_BACKOFFS_DEFAULT
 #define CSMA_SENDER_MAX_BACKOFFS_DEFAULT    (4U)
+#endif
 
 /**
  * @brief CSMA/CA backoff period, in microseconds
  */
+#ifndef CSMA_SENDER_BACKOFF_PERIOD_UNIT
 #define CSMA_SENDER_BACKOFF_PERIOD_UNIT     (320U)
+#endif
 
 /**
- * @brief Define a different (non-standard) value for
- *        the CSMA macMinBE parameter.
- *
- * @param[in] val     new value for macMinBE
- */
-void csma_sender_set_min_be(uint8_t val);
-
-/**
- * @brief Define a different (non-standard) value for
- *        the CSMA macMaxBE parameter.
- *
- * @param[in] val     new value for macMaxBE
+ * @brief   Configuration type for backoff
  */
-void csma_sender_set_max_be(uint8_t val);
+typedef struct {
+    uint8_t min_be;             /**< minimum backoff exponent */
+    uint8_t max_be;             /**< maximum backoff exponent */
+    uint16_t max_backoffs;      /**< maximum number of retries */
+    uint32_t backoff_period;    /**< backoff period in microseconds */
+} csma_sender_conf_t;
 
 /**
- * @brief Define a different (non-standard) value for
- *        the CSMA macMaxCSMABackoffs parameter.
- *
- * @param[in] val     new value for macMaxCSMABackoffs
+ * @brief   Default configuration.
  */
-void csma_sender_set_max_backoffs(uint8_t val);
+extern const csma_sender_conf_t CSMA_SENDER_CONF_DEFAULT;
 
 /**
  * @brief   Sends a 802.15.4 frame using the CSMA/CA method
@@ -89,6 +89,8 @@ void csma_sender_set_max_backoffs(uint8_t val);
  * @param[in] dev       netdev device, needs to be already initialized
  * @param[in] vector    pointer to the data
  * @param[in] count     number of elements in @p vector
+ * @param[in] conf      configuration for the backoff;
+ *                      will be set to @ref CSMA_SENDER_CONF_DEFAULT if NULL.
  *
  * @return              number of bytes that were actually send out
  * @return              -ENODEV if @p dev is invalid
@@ -100,7 +102,7 @@ void csma_sender_set_max_backoffs(uint8_t val);
  *                      to send the given data
  */
 int csma_sender_csma_ca_send(netdev2_t *dev, struct iovec *vector,
-                             unsigned count);
+                             unsigned count, const csma_sender_conf_t *conf);
 
 /**
  * @brief   Sends a 802.15.4 frame when medium is avaiable.
diff --git a/sys/net/link_layer/csma_sender/csma_sender.c b/sys/net/link_layer/csma_sender/csma_sender.c
index 2bdedd1e16..82254f8835 100644
--- a/sys/net/link_layer/csma_sender/csma_sender.c
+++ b/sys/net/link_layer/csma_sender/csma_sender.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2015 INRIA
+ * Copyright (C) 2016 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
@@ -13,6 +14,7 @@
  * @brief       Implementation of the CSMA/CA helper
  *
  * @author      Kévin Roussel <Kevin.Roussel@inria.fr>
+ * @author      Martine Lenders <mlenders@inf.fu-berlin.de>
  * @}
  */
 
@@ -35,16 +37,12 @@
 #include <inttypes.h>
 #endif
 
-
-/** @brief Current value for mac_min_be parameter */
-static uint8_t mac_min_be = CSMA_SENDER_MIN_BE_DEFAULT;
-
-/** @brief Current value for mac_max_be parameter */
-static uint8_t mac_max_be = CSMA_SENDER_MAX_BE_DEFAULT;
-
-/** @brief Current value for mac_max_csma_backoffs parameter */
-static uint8_t mac_max_csma_backoffs = CSMA_SENDER_MAX_BACKOFFS_DEFAULT;
-
+const csma_sender_conf_t CSMA_SENDER_CONF_DEFAULT = {
+    CSMA_SENDER_MIN_BE_DEFAULT,
+    CSMA_SENDER_MAX_BE_DEFAULT,
+    CSMA_SENDER_MAX_BACKOFFS_DEFAULT,
+    CSMA_SENDER_BACKOFF_PERIOD_UNIT
+};
 
 /*--------------------- "INTERNAL" UTILITY FUNCTIONS ---------------------*/
 
@@ -56,13 +54,14 @@ static uint8_t mac_max_csma_backoffs = CSMA_SENDER_MAX_BACKOFFS_DEFAULT;
  *
  * @return              An adequate random backoff exponent in microseconds
  */
-static inline uint32_t choose_backoff_period(int be)
+static inline uint32_t choose_backoff_period(int be,
+                                             const csma_sender_conf_t *conf)
 {
-    if (be < mac_min_be) {
-        be = mac_min_be;
+    if (be < conf->min_be) {
+        be = conf->min_be;
     }
-    if (be > mac_max_be) {
-        be = mac_max_be;
+    if (be > conf->max_be) {
+        be = conf->max_be;
     }
     uint32_t max_backoff = ((1 << be) - 1) * CSMA_SENDER_BACKOFF_PERIOD_UNIT;
 
@@ -118,28 +117,16 @@ static int send_if_cca(netdev2_t *device, struct iovec *vector, unsigned count)
 
 /*------------------------- "EXPORTED" FUNCTIONS -------------------------*/
 
-void csma_sender_set_min_be(uint8_t val)
-{
-    mac_min_be = val;
-}
-
-void csma_sender_set_max_be(uint8_t val)
-{
-    mac_max_be = val;
-}
-
-void csma_sender_set_max_backoffs(uint8_t val)
-{
-    mac_max_csma_backoffs = val;
-}
-
-
 int csma_sender_csma_ca_send(netdev2_t *dev, struct iovec *vector,
-                             unsigned count)
+                             unsigned count, const csma_sender_conf_t *conf)
 {
     netopt_enable_t hwfeat;
 
     assert(dev);
+    /* choose default configuration if none is given */
+    if (conf == NULL) {
+        conf = &CSMA_SENDER_CONF_DEFAULT;
+    }
     /* Does the transceiver do automatic CSMA/CA when sending? */
     int res = dev->driver->get(dev,
                                NETOPT_CSMA,
@@ -174,11 +161,11 @@ int csma_sender_csma_ca_send(netdev2_t *dev, struct iovec *vector,
     random_init(xtimer_now());
     DEBUG("csma: Starting software CSMA/CA....\n");
 
-    int nb = 0, be = mac_min_be;
+    int nb = 0, be = conf->min_be;
 
-    while (nb <= mac_max_csma_backoffs) {
+    while (nb <= conf->max_be) {
         /* delay for an adequate random backoff period */
-        uint32_t bp = choose_backoff_period(be);
+        uint32_t bp = choose_backoff_period(be, conf);
         xtimer_usleep(bp);
 
         /* try to send after a CCA */
@@ -195,8 +182,8 @@ int csma_sender_csma_ca_send(netdev2_t *dev, struct iovec *vector,
         /* medium is busy: increment CSMA counters */
         DEBUG("csma: Radio medium busy.\n");
         be++;
-        if (be > mac_max_be) {
-            be = mac_max_be;
+        if (be > conf->max_be) {
+            be = conf->max_be;
         }
         nb++;
         /* ... and try again if we have no exceeded the retry limit */
-- 
GitLab