summaryrefslogtreecommitdiff
path: root/cesar/bsu/src/bsu.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/bsu/src/bsu.c')
-rw-r--r--cesar/bsu/src/bsu.c99
1 files changed, 92 insertions, 7 deletions
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