summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaranjeiro2010-05-17 09:38:39 +0000
committerlaranjeiro2010-05-17 09:38:39 +0000
commit8c7a01c0052495f7887c36f862f7ae834aaafe49 (patch)
tree54db50407efb41e7c280a38076912df331bf3f68
parentd2dfa84e8a70545f44b7afd34bb3e74587edac72 (diff)
cesar/bsu: improve update data
BSU has a copy of the bsu_beacon_t, on each update if the data corresponds to the next beacon period it will copy the whole structure. Otherwise it will take only new data. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@7034 017c9cb6-072f-447c-8318-d5b54f68fe89
-rw-r--r--cesar/bsu/inc/context.h4
-rw-r--r--cesar/bsu/src/bsu.c99
-rw-r--r--cesar/bsu/test/utest/src/bsut.c123
-rw-r--r--cesar/bsu/test/utest/src/tests.c1
4 files changed, 199 insertions, 28 deletions
diff --git a/cesar/bsu/inc/context.h b/cesar/bsu/inc/context.h
index b0abb203a0..09a3aae93d 100644
--- a/cesar/bsu/inc/context.h
+++ b/cesar/bsu/inc/context.h
@@ -75,8 +75,8 @@ struct bsu_t
u8 ca_index;
/** Is station */
bool is_sta;
- /** Beacon Pointer. */
- bsu_beacon_t *beacon;
+ /** Beacon data to use. */
+ bsu_beacon_t beacon;
/** HAL timer context. */
hal_timer_t *hal_timer;
/** HAL timer instance. */
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index 9c3b9c0a24..74375f22e3 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -330,20 +330,19 @@ bsu_timer_event_process (void *ud)
}
else
{
- dbg_assert (ctx->beacon);
pb_beacon_t *beacon;
pbproc_tx_beacon_params_t params;
bsu_aclf_ac_compute_beacon_period_start_date (ctx->aclf);
bsu_aclf_beacon_period_start_date (ctx->aclf, bpsd, COUNT (bpsd));
/* Are update data late ?. */
- if (less_mod2p32 (ctx->beacon->beacon_period_start_date, bpsd[0]))
+ if (less_mod2p32 (ctx->beacon.beacon_period_start_date, bpsd[0]))
/* Create and send the beacon. */
- bsu_beacon_countdown (ctx->beacon);
- beacon = bsu_beacon_write (ctx->beacon, BSU_BEACON_TYPE_CENTRAL,
+ bsu_beacon_countdown (&ctx->beacon);
+ beacon = bsu_beacon_write (&ctx->beacon, BSU_BEACON_TYPE_CENTRAL,
ctx->mac_config, &params);
/* Send the beacon. */
bsu_beacon_send (ctx, BSU_BEACON_TYPE_CENTRAL, beacon,
- &ctx->beacon->bsu_params, &params);
+ &ctx->beacon.bsu_params, &params);
}
bsu_ca_schedules (ctx, ctx->sta_avln);
/* Reprogram the timer. */
@@ -463,15 +462,101 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
blk_release_desc ((blk_t*) beacon);
}
+/**
+ * Check if new persistent schedules is scheduled from the CP and copy it into
+ * the BSU context.
+ * \param ctx the module context.
+ * \param beacon the beacon data to be used in the future.
+ */
+static inline void
+bsu_update__persistent_schedules (bsu_t *ctx, bsu_beacon_t *beacon)
+{
+ /* If the persistent schedules number are at the maximum
+ * ignore the data from the CP. */
+ if (ctx->beacon.bmis.ps.nb != BSU_BEACON_BMI_PERSISTENT_SCHEDULE_MAX)
+ {
+ /* Copy the second one and update the beacon countdown. */
+ ctx->beacon.bmis.ps.nb++;
+ ctx->beacon.bmis.ps.ps[1] = beacon->bmis.ps.ps[1];
+ uint beacon_delta =
+ (bsu_aclf_beacon_period_start_date_next (ctx->aclf)
+ - beacon->beacon_period_start_date)
+ / bsu_aclf_beacon_period (ctx->aclf);
+ if (ctx->beacon.bmis.ps.ps[1].pscd <= beacon_delta)
+ {
+ beacon_delta -= ctx->beacon.bmis.ps.ps[1].pscd;
+ ctx->beacon.bmis.ps.ps[1].pscd = 0;
+ ctx->beacon.bmis.ps.ps[1].cscd -= beacon_delta;
+ }
+ else
+ ctx->beacon.bmis.ps.ps[1].pscd -= beacon_delta;
+ }
+}
+
void
bsu_update (bsu_beacon_t *beacon, bool is_sta)
{
bsu_t *ctx = &bsu_global;
dbg_assert (ctx);
dbg_assert (beacon);
- ctx->beacon = beacon;
ctx->is_sta = is_sta;
- beacon->beacon_period_start_date = phy_date (ctx->phy);
+ /* If persistent schedules are present and there is more than one. The
+ * second can only be present if the first one has its PSCD equal to 0.
+ * See specification section 5.1.2 Beacon Period Structure Figure 5-3. */
+ dbg_assert (beacon->bmis.ps.nb < BSU_BEACON_BMI_PERSISTENT_SCHEDULE_MAX
+ || (beacon->bmis.ps.nb
+ == BSU_BEACON_BMI_PERSISTENT_SCHEDULE_MAX
+ && beacon->bmis.ps.ps[0].pscd == 0
+ && beacon->bmis.ps.ps[0].pscd
+ < beacon->bmis.ps.ps[1].pscd));
+ /* If the data provided are for the next beacon period. */
+ if (lesseq_mod2p32 (bsu_aclf_beacon_period_start_date_next (ctx->aclf),
+ beacon->beacon_period_start_date))
+ ctx->beacon = *beacon;
+ /* Data in the beacon are had already expired. */
+ else
+ {
+ /* Copy some payload variant fields. */
+ ctx->beacon.vf.ncnr = beacon->vf.ncnr;
+ ctx->beacon.vf.npsm = beacon->vf.npsm;
+ ctx->beacon.vf.rtsbf = beacon->vf.rtsbf;
+ ctx->beacon.vf.ccocap = beacon->vf.ccocap;
+ ctx->beacon.vf.hoip = beacon->vf.hoip;
+ /* Copy data in non countdown beacon entry. */
+ ctx->beacon.bmis.mac_address_present =
+ beacon->bmis.mac_address_present;
+ ctx->beacon.bmis.discover = beacon->bmis.discover;
+ ctx->beacon.bmis.discover_info = beacon->bmis.discover_info;
+ ctx->beacon.bmis.bpsto = beacon->bmis.bpsto;
+ ctx->beacon.bmis.nps = beacon->bmis.nps;
+ ctx->beacon.bmis.region = beacon->bmis.region;
+ /* Process the beacon entry with countdowns. */
+ bsu_update__persistent_schedules (ctx, beacon);
+ if (beacon->bmis.eks.present && !ctx->beacon.bmis.eks.present)
+ ctx->beacon.bmis.eks = beacon->bmis.eks;
+ if (beacon->bmis.handover.present
+ && !ctx->beacon.bmis.handover.present)
+ ctx->beacon.bmis.handover = beacon->bmis.handover;
+ if (beacon->bmis.relocation.present
+ && !ctx->beacon.bmis.relocation.present)
+ ctx->beacon.bmis.relocation = beacon->bmis.relocation;
+ if (beacon->bmis.aclsc.present
+ && !ctx->beacon.bmis.aclsc.present)
+ ctx->beacon.bmis.aclsc = beacon->bmis.aclsc;
+ if (beacon->bmis.cns.present
+ && !ctx->beacon.bmis.cns.present)
+ ctx->beacon.bmis.cns = beacon->bmis.cns;
+ if (beacon->bmis.change_hm.present
+ && !ctx->beacon.bmis.change_hm.present)
+ ctx->beacon.bmis.change_hm = beacon->bmis.change_hm;
+ if (beacon->bmis.change_snid.present
+ && !ctx->beacon.bmis.change_snid.present)
+ ctx->beacon.bmis.change_snid = beacon->bmis.change_snid;
+ if (beacon->bmis.mac_address_present.present
+ && !ctx->beacon.bmis.mac_address_present.present)
+ ctx->beacon.bmis.mac_address_present =
+ beacon->bmis.mac_address_present;
+ }
}
void
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index 629bbcd206..12a0498da5 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -108,34 +108,117 @@ test_case_bsu_process (test_t test)
}
void
+test_case_bsu_update_init (bsu_test_t *test, bsu_beacon_t *beacon)
+{
+ uint i;
+ bsu_test_create_beacon (test, beacon);
+ bsu_test_create_beacon (test, &test->bsu->beacon);
+ for (i = 0; i < COUNT (test->bsu->aclf->bpsd); i++)
+ test->bsu->aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK;
+ beacon->beacon_period_start_date =
+ bsu_aclf_beacon_period_start_date_next (test->bsu->aclf)
+ - BSU_ACLF_BP_50HZ_TCK;
+}
+
+void
test_case_bsu_update (test_t test)
{
+ bsu_test_t t;
+ bsu_beacon_t beacon;
+ bsu_test_init (&t);
test_case_begin (test, "BSU Update");
- test_begin (test, "update bsu")
+ test_begin (test, "update BSU in time")
{
- bsu_test_t t;
- bsu_beacon_t beacon;
- bsu_test_init (&t);
- beacon.beacon_period_start_date = phy_date (t.bsu->phy) + 1000000;
- t.bsu->beacon = INVALID_PTR;
+ bsu_test_create_beacon (&t, &beacon);
+ beacon.beacon_period_start_date =
+ bsu_aclf_beacon_period_start_date_next (t.bsu->aclf);
t.bsu->is_sta = false;
bsu_update (&beacon, true /* is station. */);
- test_fail_unless (t.bsu->beacon == &beacon);
- test_fail_unless (t.bsu->beacon->beacon_period_start_date
- == phy_date (t.bsu->phy));
+ test_fail_unless (memcmp (&t.bsu->beacon, &beacon,
+ sizeof (bsu_beacon_t)) == 0);
test_fail_unless (t.bsu->is_sta == true);
/* Change station situation. */
- t.bsu->beacon = INVALID_PTR;
t.bsu->is_sta = true;
- beacon.beacon_period_start_date = phy_date (t.bsu->phy) + 1000000;
bsu_update (&beacon, false /* is CCo. */);
- test_fail_unless (t.bsu->beacon == &beacon);
- test_fail_unless (t.bsu->beacon->beacon_period_start_date
- == phy_date (t.bsu->phy));
+ test_fail_unless (memcmp (&t.bsu->beacon, &beacon,
+ sizeof (bsu_beacon_t)) == 0);
test_fail_unless (t.bsu->is_sta == false);
- bsu_test_uninit (&t);
}
test_end;
+ test_begin (test, "Old data")
+ {
+ test_case_bsu_update_init (&t, &beacon);
+ t.bsu->is_sta = false;
+ t.bsu->beacon.bmis.ps.ps[0].pscd--;
+ t.bsu->beacon.bmis.ps.ps[1].pscd--;
+ bsu_update (&beacon, true /* is station. */);
+ test_fail_unless (memcmp (&t.bsu->beacon, &beacon,
+ sizeof (bsu_beacon_t)) != 0);
+ test_fail_unless (t.bsu->is_sta == true);
+ }
+ test_end;
+ test_begin (test, "New persistent schedule")
+ {
+ test_case_bsu_update_init (&t, &beacon);
+ t.bsu->beacon.bmis.ps.nb = 1;
+ bsu_update (&beacon, true /* is station. */);
+ /* Only the second schedules should be touched by the function. */
+ t.bsu->beacon.bmis.ps.ps[1].pscd++;
+ test_fail_unless (t.bsu->beacon.bmis.ps.nb == beacon.bmis.ps.nb);
+ uint i;
+ for (i = 0; i < beacon.bmis.ps.nb; i++)
+ {
+ test_fail_unless (t.bsu->beacon.bmis.ps.ps[i].cscd
+ == beacon.bmis.ps.ps[i].cscd);
+ test_fail_unless (t.bsu->beacon.bmis.ps.ps[i].pscd
+ == beacon.bmis.ps.ps[i].pscd);
+ }
+ }
+ test_end;
+ test_begin (test, "Beacon entries without countdown.")
+ {
+ test_case_bsu_update_init (&t, &beacon);
+ t.bsu->beacon.bmis.mac_address_present.present = false;
+ t.bsu->beacon.bmis.discover.present = false;
+ t.bsu->beacon.bmis.discover_info.present = false;
+ t.bsu->beacon.bmis.bpsto.present = false;
+ t.bsu->beacon.bmis.nps.ns = 0;
+ t.bsu->beacon.bmis.region.nb = 0;
+ bsu_update (&beacon, true /* is station. */);
+ test_fail_unless (t.bsu->beacon.bmis.mac_address_present.present ==
+ true);
+ test_fail_unless (t.bsu->beacon.bmis.discover.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.discover_info.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.bpsto.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.nps.ns == beacon.bmis.nps.ns);
+ test_fail_unless (t.bsu->beacon.bmis.region.nb ==
+ beacon.bmis.region.nb);
+ }
+ test_end;
+ test_begin (test, "Beacon entries with countdown.")
+ {
+ test_case_bsu_update_init (&t, &beacon);
+ t.bsu->beacon.bmis.eks.present = false;
+ t.bsu->beacon.bmis.handover.present = false;
+ t.bsu->beacon.bmis.relocation.present = false;
+ t.bsu->beacon.bmis.aclsc.present = false;
+ t.bsu->beacon.bmis.cns.present = false;
+ t.bsu->beacon.bmis.change_hm.present = false;
+ t.bsu->beacon.bmis.change_snid.present = false;
+ t.bsu->beacon.bmis.mac_address_present.present = false;
+ bsu_update (&beacon, true /* is station. */);
+ test_fail_unless (t.bsu->beacon.bmis.eks.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.handover.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.relocation.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.aclsc.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.cns.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.change_hm.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.change_snid.present == true);
+ test_fail_unless (t.bsu->beacon.bmis.mac_address_present.present
+ == true);
+ }
+ test_end;
+ bsu_test_uninit (&t);
}
void
@@ -185,6 +268,8 @@ test_case_bsu_timer_event (test_t test)
bsu_test_create_beacon (&t, &beacon);
/* First case, update beacon in time. */
bsu_test_upper_layer_beacon_received_init (&t);
+ beacon.beacon_period_start_date =
+ bsu_aclf_beacon_period_start_date_next (t.bsu->aclf);
bsu_update (&beacon, false /* CCo */);
bsu_timer_event_process (t.bsu);
test_fail_unless (t.ul.beacon != INVALID_PTR);
@@ -199,7 +284,7 @@ test_case_bsu_timer_event (test_t test)
blk_release (mfs);
/* Second case, beacon not updated. */
bsu_test_upper_layer_beacon_received_init (&t);
- t.bsu->beacon->beacon_period_start_date = t.bsu->aclf->bpsd[0] - 1;
+ t.bsu->beacon.beacon_period_start_date = t.bsu->aclf->bpsd[0] - 1;
for (i = 0; i < 7; i++)
{
bsu_avln_schedules_beacon_not_received (t.bsu, &cmp_avln);
@@ -211,10 +296,10 @@ test_case_bsu_timer_event (test_t test)
for (j = 0; j < cmp_avln.bs.schedules.ps.nb; j++)
{
test_fail_unless (cmp_avln.bs.schedules.ps.ps[j].pscd
- == t.bsu->beacon->bmis.ps.ps[j].pscd);
+ == t.bsu->beacon.bmis.ps.ps[j].pscd);
test_fail_unless (cmp_avln.bs.schedules.ps.ps[j].cscd
- == t.bsu->beacon->bmis.ps.ps[j].cscd);
- test_fail_unless (t.bsu->beacon->bmis.ps.nb ==
+ == t.bsu->beacon.bmis.ps.ps[j].cscd);
+ test_fail_unless (t.bsu->beacon.bmis.ps.nb ==
cmp_avln.bs.schedules.ps.nb);
}
}
diff --git a/cesar/bsu/test/utest/src/tests.c b/cesar/bsu/test/utest/src/tests.c
index a48926b783..3c35be491e 100644
--- a/cesar/bsu/test/utest/src/tests.c
+++ b/cesar/bsu/test/utest/src/tests.c
@@ -118,6 +118,7 @@ bsu_test_create_beacon (bsu_test_t *ctx, bsu_beacon_t *beacon)
dbg_assert (beacon);
memset (beacon, 0, sizeof (bsu_beacon_t));
+ beacon->vf.nid = 0x123456789ull;
beacon->vf.hm = MAC_COEXISTENCE_FULL_HYBRID_MODE;
beacon->vf.ncnr = false;
beacon->vf.npsm = false;