summaryrefslogtreecommitdiff
path: root/mac/ca
diff options
context:
space:
mode:
authorschodet2007-11-16 16:51:05 +0000
committerschodet2007-11-16 16:51:05 +0000
commit9613e5560f4a42e14ef0036100baef06cc65389b (patch)
tree023c255b57df322ec7cba422aeaf5aef86ce1773 /mac/ca
parent93c40166f388c3b34ccf1fa8c13134b1876a92f9 (diff)
* mac/ca:
- replaced ca_mfs_init and ca_mfs_uninit by ca_mfs_add and ca_mfs_remove. - added beacon MFS support. - added hold support for CFP MFS. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@1012 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'mac/ca')
-rw-r--r--mac/ca/ca.h30
-rw-r--r--mac/ca/inc/context.h4
-rw-r--r--mac/ca/inc/mfs.h27
-rw-r--r--mac/ca/inc/trace.h5
-rw-r--r--mac/ca/mfs.h2
-rw-r--r--mac/ca/src/access.c20
-rw-r--r--mac/ca/src/ca.c61
-rw-r--r--mac/ca/src/trace.c5
-rw-r--r--mac/ca/test/ca/src/test_access.c36
9 files changed, 149 insertions, 41 deletions
diff --git a/mac/ca/ca.h b/mac/ca/ca.h
index ecdaf04cbe..d8494466f9 100644
--- a/mac/ca/ca.h
+++ b/mac/ca/ca.h
@@ -250,23 +250,25 @@ void
ca_backoff_success (ca_t *ctx);
/**
- * Initialise Channel Access related parameters in an MFS TX.
+ * Register an MFS with the Channel Access, so it can be sent.
* \param ctx ca context
- * \param mfs the newly created MFS
- *
- * The MFS is not registered in the Channel Access queues.
+ * \param mfs the MFS to add
*/
void
-ca_mfs_init (ca_t *ctx, mfs_tx_t *mfs);
+ca_mfs_add (ca_t *ctx, mfs_tx_t *mfs);
/**
- * Uninitialise Channel Access related parameters in an MFS TX prior to
- * deletion.
+ * Unregister an MFS from the Channel Access, so that it can no longer be
+ * sent.
* \param ctx ca context
- * \param mfs the MFS to be deleted
+ * \param mfs the MFS to remove
+ * \return true if successful
+ *
+ * If unsuccessful, the caller should try later because the MFS is currently
+ * been used for a transmission.
*/
-void
-ca_mfs_uninit (ca_t *ctx, mfs_tx_t *mfs);
+bool
+ca_mfs_remove (ca_t *ctx, mfs_tx_t *mfs);
/**
* Update Channel Access after a MFS update.
@@ -281,6 +283,14 @@ void
ca_mfs_update (ca_t *ctx, mfs_tx_t *mfs);
/**
+ * Hold any transmission on this MFS until the next beacon period.
+ * \param ctx ca context
+ * \param mfs the MFS to hold
+ */
+void
+ca_mfs_hold (ca_t *ctx, mfs_tx_t *mfs);
+
+/**
* Retrieve a pointer to a schedule table entry.
* \param ctx ca context
* \param index schedule index in [0..CA_SCHEDULE_NB)
diff --git a/mac/ca/inc/context.h b/mac/ca/inc/context.h
index 6e0467b6ea..0096042cdf 100644
--- a/mac/ca/inc/context.h
+++ b/mac/ca/inc/context.h
@@ -13,8 +13,6 @@
* \ingroup mac_ca
*/
-#include "lib/heap.h"
-
#include "mac/ca/ca.h"
#include "mac/common/mfs.h"
@@ -61,6 +59,8 @@ struct ca_t
uint current_allocation_index;
/** Priority sorted MFS heap. */
heap_t mfs_heap;
+ /** List of CFP MFS held until the next beacon period. */
+ list_t cfp_held;
};
/* Forward declaration in mac/ca/ca.h. */
diff --git a/mac/ca/inc/mfs.h b/mac/ca/inc/mfs.h
new file mode 100644
index 0000000000..6354505429
--- /dev/null
+++ b/mac/ca/inc/mfs.h
@@ -0,0 +1,27 @@
+#ifndef mac_ca_inc_mfs_h
+#define mac_ca_inc_mfs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file mac/ca/inc/mfs.h
+ * \brief MFS related functions header.
+ * \ingroup mac_ca
+ */
+
+BEGIN_DECLS
+
+/**
+ * Prepare for the next beacon period.
+ * \param ctx ca context
+ */
+void
+ca_mfs_next_beacon_period (ca_t *ctx);
+
+END_DECLS
+
+#endif /* mac_ca_inc_mfs_h */
diff --git a/mac/ca/inc/trace.h b/mac/ca/inc/trace.h
index ed3a489823..eeb53fcd60 100644
--- a/mac/ca/inc/trace.h
+++ b/mac/ca/inc/trace.h
@@ -24,9 +24,10 @@ enum
{
CA_TRACE_INIT = TRACE_ID (1, 0),
CA_TRACE_UNINIT = TRACE_ID (2, 0),
- CA_TRACE_MFS_INIT = TRACE_ID (11, 1),
- CA_TRACE_MFS_UNINIT = TRACE_ID (12, 1),
+ CA_TRACE_MFS_ADD = TRACE_ID (11, 1),
+ CA_TRACE_MFS_REMOVE = TRACE_ID (12, 1),
CA_TRACE_MFS_UPDATE = TRACE_ID (13, 1),
+ CA_TRACE_MFS_HOLD = TRACE_ID (14, 1),
CA_TRACE_ALLOC_UPDATE_BEACON_PERIODS = TRACE_ID (101, 0),
diff --git a/mac/ca/mfs.h b/mac/ca/mfs.h
index e86a002a1b..6cc42349fa 100644
--- a/mac/ca/mfs.h
+++ b/mac/ca/mfs.h
@@ -19,7 +19,9 @@ enum ca_mfs_state_t
CA_MFS_STATE_UNKNOWN, /*< MFS unknown to CA, also if it contains no
PB. */
CA_MFS_STATE_PRIO_QUEUED, /*< MFS queued to CSMA CA MFS heap. */
+ CA_MFS_STATE_PRIO_HELD, /*< CSMA MFS held until next beacon period. */
CA_MFS_STATE_CFP_QUEUED, /*< MFS available for TDMA. */
+ CA_MFS_STATE_CFP_HELD, /*< TDMA MFS held until next beacon period. */
};
typedef enum ca_mfs_state_t ca_mfs_state_t;
diff --git a/mac/ca/src/access.c b/mac/ca/src/access.c
index f56413e955..7cdec9a7b8 100644
--- a/mac/ca/src/access.c
+++ b/mac/ca/src/access.c
@@ -19,6 +19,7 @@
#include "mac/ca/inc/context.h"
#include "mac/ca/inc/alloc.h"
+#include "mac/ca/inc/mfs.h"
/**
* Choose a MFS TX for the given GLID.
@@ -279,6 +280,8 @@ ca_access_aifs (ca_t *ctx)
dbg_assert (bp_i != ctx->beacon_periods_tail);
alloc_i = 0;
access_date = ctx->beacon_periods[bp_i].start_date;
+ /* Prepare next beacon period. */
+ ca_mfs_next_beacon_period (ctx);
}
else
{
@@ -328,17 +331,24 @@ ca_access_choose_mfs_tx (ca_t *ctx, uint glid)
dbg_assert (glid >= MAC_GLID_MIN);
/* If GLID, this is a CFP allocation, else choose the MFS with the greater
* priority. */
- if (glid <= MAC_GLID_MAX)
+ if (!CA_ALLOC_IS_CSMA (glid))
{
+ dbg_assert (glid <= MAC_GLID_MAX
+ || glid == MAC_LID_SPC_CENTRAL
+ || glid == MAC_LID_DISCOVER);
mfs = mac_store_mfs_get_tx (ctx->store, false, false, glid, 0);
dbg_assert (!mfs || mfs->ca_state == CA_MFS_STATE_UNKNOWN
- || mfs->ca_state == CA_MFS_STATE_CFP_QUEUED);
+ || mfs->ca_state == CA_MFS_STATE_CFP_QUEUED
+ || mfs->ca_state == CA_MFS_STATE_CFP_HELD);
/* Reference is borrowed from the store. */
if (mfs)
blk_release (mfs);
- return mfs;
+ if (mfs && mfs->ca_state == CA_MFS_STATE_CFP_QUEUED)
+ return mfs;
+ else
+ return NULL;
}
- else if (CA_ALLOC_IS_CSMA (glid))
+ else
{
if (!heap_empty (&ctx->mfs_heap))
{
@@ -350,7 +360,5 @@ ca_access_choose_mfs_tx (ca_t *ctx, uint glid)
else
return NULL;
}
- else /* \todo support beacon TX. */
- return NULL;
}
diff --git a/mac/ca/src/ca.c b/mac/ca/src/ca.c
index 6f0d989d94..ed45413344 100644
--- a/mac/ca/src/ca.c
+++ b/mac/ca/src/ca.c
@@ -55,6 +55,7 @@ ca_init (phy_t *phy, mac_config_t *config, mac_store_t *store)
ctx->current_beacon_period = 0;
ctx->current_allocation_index = 0;
heap_init (&ctx->mfs_heap, ca_mfs_less);
+ list_init (&ctx->cfp_held);
CA_TRACE (INIT);
return ctx;
}
@@ -69,28 +70,35 @@ ca_uninit (ca_t *ctx)
}
void
-ca_mfs_init (ca_t *ctx, mfs_tx_t *mfs)
+ca_mfs_add (ca_t *ctx, mfs_tx_t *mfs)
{
dbg_assert (ctx);
dbg_assert (mfs);
- CA_TRACE (MFS_INIT, mfs);
- heap_node_init (&mfs->ca_prio_link);
- mfs->ca_state = CA_MFS_STATE_UNKNOWN;
+ CA_TRACE (MFS_ADD, mfs);
+ ca_mfs_update (ctx, mfs);
}
-void
-ca_mfs_uninit (ca_t *ctx, mfs_tx_t *mfs)
+bool
+ca_mfs_remove (ca_t *ctx, mfs_tx_t *mfs)
{
dbg_assert (ctx);
dbg_assert (mfs);
- CA_TRACE (MFS_UNINIT, mfs);
- if (mfs->ca_state == CA_MFS_STATE_PRIO_QUEUED)
+ CA_TRACE (MFS_REMOVE, mfs);
+ switch (mfs->ca_state)
{
+ case CA_MFS_STATE_PRIO_QUEUED:
heap_remove (&ctx->mfs_heap, &mfs->ca_prio_link);
+ break;
+ case CA_MFS_STATE_CFP_HELD:
+ list_remove (&ctx->cfp_held, &mfs->ca_cfp_held_link);
+ break;
+ default:
+ ;
}
mfs->ca_state = CA_MFS_STATE_UNKNOWN;
/* The current ACCESS may have changed. */
ca_access_update (ctx, phy_date (ctx->phy));
+ return true;
}
void
@@ -98,7 +106,7 @@ ca_mfs_update (ca_t *ctx, mfs_tx_t *mfs)
{
ca_mfs_state_t new_state;
dbg_assert (ctx);
- dbg_assert (mfs);
+ dbg_assert_ptr (mfs);
CA_TRACE (MFS_UPDATE, mfs);
/* Compute the new MFS state... */
if (mfs->seg_nb + mfs->pending_seg_nb != 0)
@@ -128,6 +136,41 @@ ca_mfs_update (ca_t *ctx, mfs_tx_t *mfs)
ca_access_update (ctx, phy_date (ctx->phy));
}
+void
+ca_mfs_hold (ca_t *ctx, mfs_tx_t *mfs)
+{
+ dbg_assert (ctx);
+ dbg_assert_ptr (mfs);
+ CA_TRACE (MFS_HOLD, mfs);
+ /* CFP MFS. */
+ if (mfs->cfp && (mfs->ca_state == CA_MFS_STATE_CFP_QUEUED
+ || mfs->ca_state == CA_MFS_STATE_UNKNOWN))
+ {
+ mfs->ca_state = CA_MFS_STATE_CFP_HELD;
+ list_push (&ctx->cfp_held, &mfs->ca_cfp_held_link);
+ }
+ else if (mfs->ca_state == CA_MFS_STATE_PRIO_QUEUED)
+ {
+ dbg_assert (0); // TODO
+ }
+ else
+ dbg_assert (0);
+ /* The current ACCESS may have changed. */
+ ca_access_update (ctx, phy_date (ctx->phy));
+}
+
+void
+ca_mfs_next_beacon_period (ca_t *ctx)
+{
+ /* Unhold CFP MFS. */
+ while (!list_empty (&ctx->cfp_held))
+ {
+ mfs_tx_t *mfs = PARENT_OF (mfs_tx_t, ca_cfp_held_link,
+ list_pop (&ctx->cfp_held));
+ ca_mfs_update (ctx, mfs);
+ }
+}
+
static bool
ca_mfs_less (heap_node_t *left, heap_node_t *right)
{
diff --git a/mac/ca/src/trace.c b/mac/ca/src/trace.c
index fa035af262..efed8ab5f2 100644
--- a/mac/ca/src/trace.c
+++ b/mac/ca/src/trace.c
@@ -22,9 +22,10 @@ ca_trace_init (ca_t *ctx)
{
TRACE_EVENT (CA_TRACE_INIT, "init"),
TRACE_EVENT (CA_TRACE_UNINIT, "uninit"),
- TRACE_EVENT (CA_TRACE_MFS_INIT, "mfs init %x"),
- TRACE_EVENT (CA_TRACE_MFS_UNINIT, "mfs uninit %x"),
+ TRACE_EVENT (CA_TRACE_MFS_ADD, "mfs add %x"),
+ TRACE_EVENT (CA_TRACE_MFS_REMOVE, "mfs remove %x"),
TRACE_EVENT (CA_TRACE_MFS_UPDATE, "mfs update %x"),
+ TRACE_EVENT (CA_TRACE_MFS_HOLD, "mfs hold %x"),
TRACE_EVENT (CA_TRACE_ALLOC_UPDATE_BEACON_PERIODS,
"alloc update beacon periods"),
diff --git a/mac/ca/test/ca/src/test_access.c b/mac/ca/test/ca/src/test_access.c
index 5bca0c3c86..700a35776c 100644
--- a/mac/ca/test/ca/src/test_access.c
+++ b/mac/ca/test/ca/src/test_access.c
@@ -63,7 +63,8 @@ access_random_schedule (lib_rnd_t *rnd, ca_schedule_t *sched, uint length_tck)
{ MAC_LID_SHARED_CSMA, MAC_LID_SHARED_CSMA, 8 + 8 + 1 + 2 + 8 },
{ MAC_LID_LOCAL_CSMA, MAC_LID_LOCAL_CSMA, 8 + 8 + 1 + 2 + 8 + 8 },
};
- for (i = 0; i < nb; i++)
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ for (i = 1; i < nb; i++)
{
uint r = lib_rnd_uniform (rnd, glid_prob[COUNT (glid_prob) - 1].prob);
uint j;
@@ -153,12 +154,12 @@ access_basic_test_case (test_t t)
ca = ca_init (phy, &config, store);
/* Characteristics for null slots are determined as-is:
* - for index < NB_GLID: i = index
- * - lid = i + MAC_GLID_MIN
+ * - lid = i != 0 ? i + MAC_GLID_MIN : MAC_LID_SPC_CENTRAL
* - cap = i % 4
* - tei = i % NB_PEER + PEER_MIN
* - bcast = false
* - cfp = true
- * - for index > NB_GLID: i = index - NB_GLID
+ * - for index >= NB_GLID: i = index - NB_GLID
* - lid = i % MAC_PLID_NB + MAC_PLID_MIN
* - cap = lid - MAC_PLID_MIN
* - tei = i >= MAC_PLID_NB * NB_PEER
@@ -208,6 +209,9 @@ access_basic_test_case (test_t t)
if (ca->access_param.mfs)
{
mfs_tx_t *mfs = ca->access_param.mfs;
+ dbg_assert (
+ mfs->ca_state == CA_MFS_STATE_PRIO_QUEUED
+ || mfs->ca_state == CA_MFS_STATE_CFP_QUEUED);
/* Timings are completely approximated. */
int seg_sent = lib_rnd_uniform (rnd, mfs->seg_nb);
uint fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
@@ -259,7 +263,8 @@ access_basic_test_case (test_t t)
bool bcast, cfp;
if (j < NB_GLID)
{
- lid = j + MAC_GLID_MIN;
+ lid = j != 0 ? j + MAC_GLID_MIN
+ : MAC_LID_SPC_CENTRAL;
cap = j % 4;
tei = j % NB_PEER + PEER_MIN;
bcast = false;
@@ -283,14 +288,13 @@ access_basic_test_case (test_t t)
mfs->seg_nb = lib_rnd_uniform (rnd, 100);
mfses[j] = mfs;
mfses_used++;
- ca_mfs_init (ca, mfs);
- ca_mfs_update (ca, mfs);
+ ca_mfs_add (ca, mfs);
}
else
{
/* Remove an MFS. */
mfs_tx_t *mfs = mfses[j];
- ca_mfs_uninit (ca, mfs);
+ ca_mfs_remove (ca, mfs);
mac_store_mfs_remove (store,
PARENT_OF (mfs_t, tx, mfs));
blk_release (mfs);
@@ -305,8 +309,20 @@ access_basic_test_case (test_t t)
j = lib_rnd_uniform (rnd, COUNT (mfses));
} while (!mfses[j]);
mfs_tx_t *mfs = mfses[j];
- mfs->seg_nb = lib_rnd_uniform (rnd, 100);
- ca_mfs_update (ca, mfs);
+ if (mfs->ca_state != CA_MFS_STATE_CFP_HELD
+ && mfs->ca_state != CA_MFS_STATE_PRIO_HELD)
+ {
+ if (mfs->cfp &&
+ lib_rnd_flip_coin (rnd, LIB_RND_RATIO (0.05)))
+ {
+ ca_mfs_hold (ca, mfs);
+ }
+ else
+ {
+ mfs->seg_nb = lib_rnd_uniform (rnd, 100);
+ ca_mfs_update (ca, mfs);
+ }
+ }
}
}
}
@@ -318,7 +334,7 @@ access_basic_test_case (test_t t)
mfs_tx_t *mfs = mfses[i];
if (mfs)
{
- ca_mfs_uninit (ca, mfs);
+ ca_mfs_remove (ca, mfs);
mac_store_mfs_remove (store, PARENT_OF (mfs_t, tx, mfs));
blk_release (mfs);
}