summaryrefslogtreecommitdiff
path: root/cesar/mac/sar
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-03-15 11:11:57 +0100
committerNélio Laranjeiro2011-03-15 17:09:08 +0100
commit7ae842f5334731fccb674fe8e4e4764ec0f52dd6 (patch)
tree32274316577da251d3e8b809ad9a7788e8205417 /cesar/mac/sar
parente892261ee6276a049a28ff9d11e4cd377d118f12 (diff)
cesar/mac/sar: no expiration for Bcast TX MFS, closes #2357
Broadcast MFS new behavior: - TX will never expire. - RX will set the ssn_min to the first PB's SSN received in the MPDU if the MFS is new (RX Bcast can expire). Note: This fix disallow the MFS to receive data not ordered if the MFS has just been created, i.e. receiving an MPDU with PB's 6 7 8, 1 2 3 4 5 will cause the reception process to drop 1 2 3 4 5.
Diffstat (limited to 'cesar/mac/sar')
-rw-r--r--cesar/mac/sar/src/sar.c54
-rw-r--r--cesar/mac/sar/src/sar_expiration.c7
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/expiration.c62
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/get_associated_mfs.c58
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/reassembly.c6
5 files changed, 145 insertions, 42 deletions
diff --git a/cesar/mac/sar/src/sar.c b/cesar/mac/sar/src/sar.c
index 68a8de06ec..561f5432d5 100644
--- a/cesar/mac/sar/src/sar.c
+++ b/cesar/mac/sar/src/sar.c
@@ -218,46 +218,48 @@ sar_rx_get_associated_mfs__mme_temporary_link (sar_t *ctx, sar_mpdu_t *rx)
* Create a non temporary MFS.
* \param ctx the sar context.
* \param rx the rx parameters.
- * \param mme indicate if it request a MME or a DATA MFS.
+ * \param pb the PB which require the MFS.
+ * \param mme true if MME false otherwise.
* \return the MFS.
*
* If the LID of the MFS is not a PLID for DATA MFS, this will return NULL.
*/
static inline mfs_rx_t*
-sar_rx_get_associated_mfs__from_mac_store (sar_t *ctx, sar_mpdu_t *rx,
- bool mme)
+sar_rx_get_associated_mfs__from_mac_store (
+ sar_t *ctx, pbproc_rx_t *rx, pb_t *pb, bool mme)
{
mfs_rx_t *local_mfs;
bool added;
-
- dbg_assert (MAC_TEI_IS_STA(rx->rx.params.tei));
-
+ dbg_assert (MAC_TEI_IS_STA(rx->params.tei));
/* If the MFS is not a lid one and it request a DATA MFS return NULL.
* The SAR is not allowed to create non PLID MFSs. */
- if (!mme && !MAC_LID_IS_PLID (rx->rx.params.lid))
+ if (!mme && !MAC_LID_IS_PLID (rx->params.lid))
{
- local_mfs = mac_store_mfs_get_rx (ctx->mac_store,
- rx->rx.params.bcast,
- false /* data requested. */,
- rx->rx.params.lid,
- rx->rx.params.tei);
+ local_mfs = mac_store_mfs_get_rx (
+ ctx->mac_store, rx->params.bcast, false /* data requested. */,
+ rx->params.lid, rx->params.tei);
}
else
{
-
local_mfs = mac_store_mfs_add_rx (ctx->mac_store,
- rx->rx.params.bcast, mme, mme ? MAC_LID_NONE : rx->rx.params.lid,
- rx->rx.params.tei, &added);
-
+ rx->params.bcast, mme, mme ? MAC_LID_NONE : rx->params.lid,
+ rx->params.tei, &added);
/* Configure the MFS created, only do this if the MFS has been created*/
if (added)
+ {
sar_mfs_add (ctx, PARENT_OF (mfs_t, rx, local_mfs));
+ /* Special behavior for bcast MFS, the ssn min should be set to
+ * the first PB on the MPDU. This allow the station to receive PBs
+ * with a SSN higher than 0x7fff when SSN min is 0. See #2357
+ */
+ if (local_mfs->common.bcast)
+ local_mfs->ssn_min = pb->header.ssn;
+ }
}
-
if (mme)
- rx->rx.mfs_mme = PARENT_OF_OR_NULL (mfs_t, rx, local_mfs);
+ rx->mfs_mme = PARENT_OF_OR_NULL (mfs_t, rx, local_mfs);
else
- rx->rx.mfs = PARENT_OF_OR_NULL (mfs_t, rx, local_mfs);
+ rx->mfs = PARENT_OF_OR_NULL (mfs_t, rx, local_mfs);
return local_mfs;
}
@@ -265,29 +267,29 @@ sar_rx_get_associated_mfs__from_mac_store (sar_t *ctx, sar_mpdu_t *rx,
* Get the associated MFS from mac store.
* \param sar the SAR context.
* \param rx the rx_mpdu
- * \param mme True if it is a MME MFS needed, false otherwise.
+ * \param pb The PB for the one the MFS is needed.
+ * \param mme true if MME false otherwise.
* \return the MFS corresponding, or the new created one.
*
* If the MFS does not exists it use the rx_params LID and source TEI to add
* it to the mac store.
*/
inline mfs_rx_t *
-sar_rx_get_associated_mfs (sar_t *ctx, sar_mpdu_t * rx, bool mme)
+sar_rx_get_associated_mfs (sar_t *ctx, sar_mpdu_t * rx, pb_t *pb, bool mme)
{
dbg_assert (rx);
-
if (mme && rx->rx.mfs_mme)
return (mfs_rx_t *) rx->rx.mfs_mme;
else if (!mme && rx->rx.mfs)
return (mfs_rx_t *) rx->rx.mfs;
-
/* Temporary link. */
if (mme && ((rx->rx.params.tei == MAC_TEI_UNASSOCIATED)
|| (rx->rx.params.multi_net_bcast)))
return sar_rx_get_associated_mfs__mme_temporary_link (ctx, rx);
/* Normal link. */
else
- return sar_rx_get_associated_mfs__from_mac_store (ctx, rx, mme);
+ return sar_rx_get_associated_mfs__from_mac_store (ctx, &rx->rx, pb,
+ mme);
}
/**
@@ -1263,8 +1265,8 @@ sar_rx_mpdu_process (sar_t *ctx, sar_mpdu_t * rx)
/* Get the current MFS. */
if ((mfs_current == NULL) || (mme != rx_head->header.mmqf))
{
- mfs_current = sar_rx_get_associated_mfs (ctx, rx,
- rx_head->header.mmqf);
+ mfs_current = sar_rx_get_associated_mfs (
+ ctx, rx, rx_head, rx_head->header.mmqf);
if (mfs_current)
{
sar_rx_mfs_resize_ssn (mfs_current, rx_head,
diff --git a/cesar/mac/sar/src/sar_expiration.c b/cesar/mac/sar/src/sar_expiration.c
index b42d9b2396..03fd0e35d7 100644
--- a/cesar/mac/sar/src/sar_expiration.c
+++ b/cesar/mac/sar/src/sar_expiration.c
@@ -69,8 +69,11 @@ sar_expiration_mfs_purge_tx (sar_t *ctx, mfs_tx_t *mfs, u32 phy_curr_ntb)
SAR_TRACE (PB_TX_RELEASE, old_first_ssn,
mfs->head ? mfs->head->header.ssn : SAR_SSN_INVALID, mfs);
}
- /* If the whole MFS has expired i.e. it does not have PB's. */
- if (mfs_empty && sar_expiration_mfs_expired (mfs, phy_curr_ntb))
+ /* If the whole MFS has expired i.e. it does not have PB's.
+ * Broadcast MFS must not expire see #2357. */
+ if (mfs_empty
+ && sar_expiration_mfs_expired (mfs, phy_curr_ntb)
+ && !mfs->common.bcast)
{
sar_mfs_remove (ctx, PARENT_OF (mfs_t, tx, mfs));
SAR_TRACE (MFS_RELEASE, phy_curr_ntb, mfs);
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/expiration.c b/cesar/mac/sar/test/unit_test/ecos/src/expiration.c
index 818cce6d4e..27548c5697 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/expiration.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/expiration.c
@@ -15,7 +15,13 @@
#include "lib/test.h"
#include "lib/trace.h"
#include "lib/stats.h"
+#include "mac/common/ntb.h"
+#include "mac/common/timings.h"
#include "mac/sar/test/unit_test/ecos/tests.h"
+#include <string.h>
+
+/* Override context. */
+#include "mac/pbproc/inc/context.h"
void
test_case_expiration__add (sar_test_t *t, u8 tei, u8 lid, bool tx,
@@ -109,11 +115,67 @@ test_case_expiration (test_t test)
sar_test_uninit (&t);
}
+mfs_t*
+test_case_expiration_bcast__common (sar_test_t *ctx, test_t t, bool tx)
+{
+ test_within (t);
+ bool added;
+ mfs_t *mfs = mac_store_mfs_add (ctx->mac_store, tx, true, false, 1,
+ tx ? MAC_TEI_BCAST : 1, &added);
+ test_fail_unless (added);
+ pb_t *pb = (pb_t*) blk_alloc_desc ();
+ pb->next = NULL;
+ pb->expiration_ntb =
+ mac_ntb () - MAC_MS_TO_TCK (MFS_PB_TX_DELAY_MS) - 10;
+ if (tx)
+ {
+ mfs->tx.head = mfs->tx.tail = pb;
+ mfs->tx.seg_nb = 1;
+ }
+ else
+ mfs->rx.head = pb;
+ /* Set expiration date. */
+ mfs->common.expiration_ntb = mac_ntb ()
+ - MAC_MS_TO_TCK (MFS_RELEASE_DELAY_MS) - 10;
+ sar_expiration_mfs (ctx->sar);
+ return mfs;
+}
+
+void
+test_case_expiration_bcast (test_t test)
+{
+ test_case_begin (test, "Broadcast MFS expiration");
+ sar_test_t ctx;
+ pbproc_t pbproc;
+ memset (&pbproc, 0, sizeof (pbproc_t));
+ sar_test_init (&ctx, INVALID_PTR, &pbproc);
+ test_begin (test, "TX")
+ {
+ mfs_t *mfs = test_case_expiration_bcast__common (&ctx, test, true);
+ /* TX bcast MFS should not be released. */
+ test_fail_unless (mfs->tx.fsm_state != MFS_FSM_CMD_RELEASE);
+ test_fail_unless (!mfs->tx.head);
+ blk_release (mfs);
+ }
+ test_end;
+ test_begin (test, "RX")
+ {
+ mfs_t *mfs = test_case_expiration_bcast__common (&ctx, test, false);
+ /* RX bcast MFS should be released. */
+ test_fail_unless (mfs->rx.release);
+ blk_release (mfs);
+ }
+ test_end;
+ sar_cleanup (ctx.sar);
+ sar_test_uninit (&ctx);
+}
+
void
test_suite_expiration (test_t test)
{
test_suite_begin (test, "MFS expiration");
test_case_expiration (test);
+ test_case_expiration_bcast (test);
test_begin (test, "Memory")
{
test_fail_if (blk_check_memory() == false, "Memory not freed");
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/get_associated_mfs.c b/cesar/mac/sar/test/unit_test/ecos/src/get_associated_mfs.c
index ee21753037..29003f562a 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/get_associated_mfs.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/get_associated_mfs.c
@@ -22,7 +22,7 @@
/* Function declared as inline in the source code. */
mfs_rx_t *
-sar_rx_get_associated_mfs (sar_t *ctx, sar_mpdu_t * rx, bool mme);
+sar_rx_get_associated_mfs (sar_t *ctx, sar_mpdu_t * rx, pb_t *pb, bool mme);
void
test_case_rx_get_associated_mfs__temporary_link (test_t test)
@@ -45,33 +45,46 @@ test_case_rx_get_associated_mfs__temporary_link (test_t test)
mpdu.rx.params.lid = 2;
mpdu.rx.params.bcast = true;
mpdu.rx.params.multi_net_bcast = true;
+ mpdu.rx.pb_first = (pb_t*) blk_alloc_desc ();
+ mpdu.rx.pb_first->header.mmqf = true;
+ mpdu.rx.pb_first->next = NULL;
/* Test. */
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, true);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, mpdu.rx.pb_first,
+ mpdu.rx.pb_first->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (mfs->common.tei == mpdu.rx.params.tei);
test_fail_unless (mfs->common.lid == MAC_LID_NONE);
test_fail_unless (mfs->common.bcast == mpdu.rx.params.bcast);
test_fail_unless (mfs->common.mme == true);
+ blk_release_desc (&mpdu.rx.pb_first->blk);
blk_release (mfs);
/* Test. */
mpdu.rx.params.multi_net_bcast = false;
mpdu.rx.mfs_mme = NULL;
mpdu.rx.mfs = NULL;
+ mpdu.rx.pb_first = (pb_t*) blk_alloc_desc ();
+ mpdu.rx.pb_first->header.mmqf = true;
+ mpdu.rx.pb_first->next = NULL;
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, true);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, mpdu.rx.pb_first,
+ mpdu.rx.pb_first->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (mfs->common.tei == mpdu.rx.params.tei);
test_fail_unless (mfs->common.lid == MAC_LID_NONE);
test_fail_unless (mfs->common.bcast == mpdu.rx.params.bcast);
test_fail_unless (mfs->common.mme == true);
+ blk_release_desc (&mpdu.rx.pb_first->blk);
blk_release (mfs);
/* Initialise for DATA (this should assert). */
+ pb_t *pb = (pb_t*) blk_alloc_desc ();
dbg_fatal_try_begin
{
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, false /* Data. */);
+ pb->header.mmqf = false;
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, pb,
+ pb->header.mmqf);
test_fail_unless (false);
}
dbg_fatal_try_catch (const char *fatal_message)
@@ -80,6 +93,7 @@ test_case_rx_get_associated_mfs__temporary_link (test_t test)
test_fail_unless (true);
}
dbg_fatal_try_end;
+ blk_release_desc (&pb->blk);
/* Initialise the rx parameters. */
mpdu.rx.mfs_mme = NULL;
@@ -88,14 +102,19 @@ test_case_rx_get_associated_mfs__temporary_link (test_t test)
mpdu.rx.params.lid = 2;
mpdu.rx.params.bcast = true;
mpdu.rx.params.multi_net_bcast = true;
+ mpdu.rx.pb_first = (pb_t*) blk_alloc_desc ();
+ mpdu.rx.pb_first->header.mmqf = true;
+ mpdu.rx.pb_first->next = NULL;
/* Test, will create a temporary link. */
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, true /* MME */);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, mpdu.rx.pb_first,
+ mpdu.rx.pb_first->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (mfs->common.tei == mpdu.rx.params.tei);
test_fail_unless (mfs->common.lid == MAC_LID_NONE);
test_fail_unless (mfs->common.bcast == mpdu.rx.params.bcast);
test_fail_unless (mfs->common.mme == true);
+ blk_release_desc (&mpdu.rx.pb_first->blk);
mfs_in_store = mac_store_mfs_get_rx (t.mac_store, mpdu.rx.params.bcast,
true /* data */,
@@ -127,6 +146,9 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
mfs_rx_t *mfs;
mfs_rx_t *mfs_in_store;
uint lid;
+ pb_t *pb = (pb_t*) blk_alloc_desc ();
+ pb->header.mmqf = false;
+ pb->next = NULL;
for (lid = MAC_PLID_MIN; lid <= MAC_PLID_MAX; lid ++)
{
@@ -139,7 +161,8 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
mpdu.rx.params.multi_net_bcast = false;
/* Test. */
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, false /* data */);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, pb,
+ pb->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (mfs->common.tei == mpdu.rx.params.tei);
test_fail_unless (mfs->common.lid == mpdu.rx.params.lid);
@@ -176,7 +199,8 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
&added);
blk_release (mfs);
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, false /* data. */);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, pb,
+ pb->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (added == true);
test_fail_unless (mfs == &mpdu.rx.mfs->rx);
@@ -184,6 +208,7 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
blk_release (mfs);
mac_store_mfs_remove (t.mac_store, mpdu.rx.mfs);
dbg_check (mac_store_sta_remove (t.mac_store, mpdu.rx.params.tei));
+ blk_release_desc (&pb->blk);
}
test_end;
@@ -193,7 +218,8 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
mfs_rx_t *mfs;
mfs_rx_t *mfs_in_store;
uint lid;
-
+ pb_t *pb = (pb_t*) blk_alloc_desc ();
+ pb->header.mmqf = true;
for (lid = MAC_PLID_MIN; lid <= MAC_PLID_MAX; lid ++)
{
/* Initialise the rx parameters. */
@@ -205,7 +231,8 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
mpdu.rx.params.multi_net_bcast = false;
/* Test. */
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, true /* MME */);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, pb,
+ pb->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (mfs->common.tei == mpdu.rx.params.tei);
test_fail_unless (mfs->common.lid == MAC_LID_NONE);
@@ -225,6 +252,7 @@ test_case_rx_get_associated_mfs__plid_link (test_t test)
blk_release (mfs);
sar_cleanup (t.sar);
}
+ blk_release_desc (&pb->blk);
}
test_end;
@@ -249,6 +277,8 @@ test_case_rx_get_associated_mfs__glid_link (test_t test)
/* Test MFS creation from LLID_MIN to GLID_MAX.
* SAR is not allowed to create it. */
+ pb_t *pb = (pb_t*) blk_alloc_desc ();
+ pb->header.mmqf = false;
for (lid = MAC_LLID_MIN; lid <= MAC_GLID_MAX; lid ++)
{
/* Initialise the rx parameters. */
@@ -260,9 +290,11 @@ test_case_rx_get_associated_mfs__glid_link (test_t test)
mpdu.rx.params.multi_net_bcast = false;
/* Test. */
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, false /* data */);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, pb,
+ pb->header.mmqf);
test_fail_unless (mfs == NULL);
}
+ blk_release_desc (&pb->blk);
}
test_end;
@@ -275,6 +307,8 @@ test_case_rx_get_associated_mfs__glid_link (test_t test)
/* Test MFS creation from LLID_MIN to GLID_MAX.
* SAR is not allowed to create it. */
+ pb_t *pb = (pb_t*) blk_alloc_desc ();
+ pb->header.mmqf = true;
for (lid = MAC_LLID_MIN; lid <= MAC_GLID_MAX; lid ++)
{
/* Initialise the rx parameters. */
@@ -286,7 +320,8 @@ test_case_rx_get_associated_mfs__glid_link (test_t test)
mpdu.rx.params.multi_net_bcast = false;
/* Test. */
- mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, true /* MME */);
+ mfs = sar_rx_get_associated_mfs (t.sar, &mpdu, pb,
+ pb->header.mmqf);
test_fail_unless (mfs != NULL);
test_fail_unless (mfs->common.tei == mpdu.rx.params.tei);
test_fail_unless (mfs->common.lid == MAC_LID_NONE);
@@ -306,6 +341,7 @@ test_case_rx_get_associated_mfs__glid_link (test_t test)
blk_release (mfs);
sar_cleanup (t.sar);
}
+ blk_release_desc (&pb->blk);
}
test_end;
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c b/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c
index dcb094bca9..7b39079f90 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c
@@ -109,7 +109,7 @@ test_case_brodcast (test_t test)
sar_mpdu_t mpdu;
pb_t *pb;
uint ssn;
- uint final_ssn_list[] = {0, 1, 2, 6, 7, 8};
+ uint final_ssn_list[] = {6, 7, 8};
uint i;
sar_test_init (&t, INVALID_PTR, INVALID_PTR);
@@ -227,7 +227,7 @@ test_case_brodcast (test_t test)
sar_mpdu_t mpdu;
pb_t *pb;
uint ssn;
- uint final_ssn_list[] = {0, 1, 2, 6, 7, 8};
+ uint final_ssn_list[] = {6, 7, 8};
uint i;
sar_test_init (&t, INVALID_PTR, INVALID_PTR);
@@ -248,7 +248,7 @@ test_case_brodcast (test_t test)
pb;
pb = pb->next, ssn ++)
test_fail_unless (pb->header.ssn == ssn);
- test_fail_unless (mpdu.rx.mfs->rx.ssn_min == 0);
+ test_fail_unless (mpdu.rx.mfs->rx.ssn_min == 6);
/* Create a second ordered list of PBs. */
ssn = 0;