summaryrefslogtreecommitdiff
path: root/cesar/bsu
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-03-14 16:53:47 +0100
committerNélio Laranjeiro2011-03-15 14:19:36 +0100
commitafc0b2de8d610664a54d586a6f52697a6c7100a8 (patch)
tree80f9c3e41a1a42739834b7809466625117722fba /cesar/bsu
parentc64a500004a983ea48152714a4cf17acaa79b028 (diff)
cesar/bsu: remove oldest AVLN when adding a new one, closes #2395
When AVLN array is full, BSU should use the structure of the oldest one registered.
Diffstat (limited to 'cesar/bsu')
-rw-r--r--cesar/bsu/src/bsu.c55
-rw-r--r--cesar/bsu/test/utest/src/bsut.c46
2 files changed, 93 insertions, 8 deletions
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index 1190b4afb5..50893eb929 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -160,6 +160,28 @@ bsu_avln_get (bsu_t *ctx, u64 nid, u8 snid, mac_t mac)
}
/**
+ * Initialise the AVLN data.
+ * \param avln the avln structure to initialise.
+ * \param nid the network identifier.
+ * \param snid the short network identifier.
+ * \param mac the CCo mac address.
+ */
+static void
+bsu_avln_init (bsu_avln_t *avln, u64 nid, u8 snid, mac_t mac)
+{
+ bsu_ntb_init (&avln->sync);
+ avln->beacon.vf.nid = nid;
+ avln->snid = snid;
+ avln->cco_mac_address = mac;
+ /* Simulate an activity by setting the date to the current one, this is
+ * only used by BSU to
+ * - not remove it if adding a new AVLN
+ * - not process two beacons of the same AVLN on the beacon period.
+ */
+ avln->beacon.beacon_period_start_date = phy_date ();
+}
+
+/**
* Add an AVLN.
* \param ctx the module context.
* \param nid the NID of the AVLN.
@@ -169,21 +191,38 @@ bsu_avln_get (bsu_t *ctx, u64 nid, u8 snid, mac_t mac)
* \return the AVLN object.
*
* The AVLNs are static object do not release it.
+ * \warn When calling this function, if no more room are available the oldest
+ * AVLN will be used.
*/
inline bsu_avln_t*
bsu_avln_add (bsu_t *ctx, u64 nid, u8 snid, mac_t mac, bool *added)
{
*added = false;
bsu_avln_t* avln = bsu_avln_get (ctx, nid, snid, mac);
- if (!avln && ctx->avlns_nb < BSU_FOREIGN_AVLNS_NB)
+ if (!avln)
{
- avln = &ctx->avlns[ctx->avlns_nb];
- bsu_ntb_init (&avln->sync);
- avln->beacon.vf.nid = nid;
- avln->snid = snid;
- avln->cco_mac_address = mac;
- avln->beacon.beacon_period_start_date = phy_date ();
- ctx->avlns_nb++;
+ if(ctx->avlns_nb < BSU_FOREIGN_AVLNS_NB)
+ {
+ avln = &ctx->avlns[ctx->avlns_nb];
+ ctx->avlns_nb++;
+ }
+ /* No more space available. */
+ else
+ {
+ uint i;
+ for (i = 1, avln = &ctx->avlns[0];
+ i < BSU_FOREIGN_AVLNS_NB - 1;
+ i++)
+ {
+ if (less_mod2p32 (
+ ctx->avlns[i].beacon.beacon_period_start_date,
+ avln->beacon.beacon_period_start_date))
+ /* found the oldest AVLN. */
+ avln = &ctx->avlns[i];
+ }
+ dbg_assert (ctx->sta_avln != avln);
+ }
+ bsu_avln_init (avln, nid, snid, mac);
*added = true;
}
return avln;
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index 8baa2665ac..eb437fb717 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -21,6 +21,9 @@
#include "bsu/inc/context.h"
#include "bsu/inc/interface.h"
+bsu_avln_t*
+bsu_avln_add (bsu_t *ctx, u64 nid, u8 snid, mac_t mac, bool *added);
+
void
bsu_timer_event_process (void *ud);
@@ -805,6 +808,48 @@ test_case_bsu_discover_update (test_t test)
}
void
+test_case_bsu_add_avln_array_full (test_t t)
+{
+ test_case_begin (t, "Array BSU AVLN full");
+ bsu_test_t ctx;
+ bsu_test_init (&ctx);
+ test_begin (t, "Add new AVLN")
+ {
+ bsu_avln_t *avln;
+ bool added;
+ uint i;
+ u32 now = phy_date ();
+ for (i = 0; i < BSU_FOREIGN_AVLNS_NB; i++)
+ {
+ avln = bsu_avln_add (
+ ctx.bsu, i, i, MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, i),
+ &added);
+ avln->beacon.beacon_period_start_date = now + i;
+ test_fail_unless (added);
+ }
+ test_fail_unless (ctx.bsu->avlns_nb == BSU_FOREIGN_AVLNS_NB);
+ /* Add a new AVLN, the first one with NID == 0, snid == 0 should be
+ * removed. */
+ avln = bsu_avln_add (
+ ctx.bsu, 200, 0x4,
+ MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0xfe), &added);
+ test_fail_unless (added);
+ test_fail_unless (avln->beacon.vf.nid == 200);
+ test_fail_unless (avln->snid == 4);
+ test_fail_unless (avln->cco_mac_address ==
+ MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0xfe));
+ test_fail_unless (!avln->sync.init);
+ test_fail_unless (avln == &ctx.bsu->avlns[0]);
+ /* Try to get the first one. */
+ avln = bsu_avln_get (ctx.bsu, 0, 0,
+ MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x0));
+ test_fail_unless (!avln);
+ }
+ test_end;
+ bsu_test_uninit (&ctx);
+}
+
+void
test_suite_bsu (test_t t)
{
test_suite_begin (t, "BSU test");
@@ -817,4 +862,5 @@ test_suite_bsu (test_t t)
test_case_bsu_persistent_schedules_update (t);
test_case_bsu_nek_index (t);
test_case_bsu_discover_update (t);
+ test_case_bsu_add_avln_array_full (t);
}