summaryrefslogtreecommitdiff
path: root/cesar/bsu
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/bsu')
-rw-r--r--cesar/bsu/beacon/beacon.h20
-rw-r--r--cesar/bsu/beacon/src/beacon.c25
-rw-r--r--cesar/bsu/inc/context.h3
-rw-r--r--cesar/bsu/ntb/ntb_sync.h2
-rw-r--r--cesar/bsu/ntb/src/ntb.c1
-rw-r--r--cesar/bsu/src/bsu.c244
-rw-r--r--cesar/bsu/test/utest/src/bsut.c46
-rw-r--r--cesar/bsu/test/utest/src/schedules.c157
-rw-r--r--cesar/bsu/test/utest/src/tests.c12
9 files changed, 278 insertions, 232 deletions
diff --git a/cesar/bsu/beacon/beacon.h b/cesar/bsu/beacon/beacon.h
index dedafb3711..df0d038adf 100644
--- a/cesar/bsu/beacon/beacon.h
+++ b/cesar/bsu/beacon/beacon.h
@@ -136,12 +136,6 @@ typedef struct bsu_beacon_t bsu_beacon_t;
/** Schedule description for the AVLN. */
struct bsu_beacon_schedules_t
{
- /** Hybrid mode. */
- mac_coexistence_mode_t hm[BSU_BEACON_SCHEDULES_MAX];
- /** SNID. */
- u8 snid[BSU_BEACON_SCHEDULES_MAX];
- /** NEK switch. */
- uint nek_switch[BSU_BEACON_SCHEDULES_MAX];
/** Network mode. */
bsu_beacon_nm_t nm;
/** Persistent schedule. */
@@ -150,6 +144,12 @@ struct bsu_beacon_schedules_t
bsu_beacon_bmi_non_persistent_schedule_t nps;
/** Beacon period start time offset. */
bsu_beacon_bmi_bpsto_t bpsto;
+ /** SNID change beacon entry. */
+ bsu_beacon_bmi_change_snid_t snid;
+ /** EKS change beacon entry. */
+ bsu_beacon_bmi_eks_t eks;
+ /** Change hybrid mode. */
+ bsu_beacon_bmi_change_hybrid_mode_t hm;
};
typedef struct bsu_beacon_schedules_t bsu_beacon_schedules_t;
@@ -162,6 +162,10 @@ struct bsu_beacon_avln_t
u8 snid;
/** CCo's TEI. */
u8 tei;
+ /** Hybrid mode. */
+ mac_coexistence_mode_t hm;
+ /** NEK switch. */
+ uint nek_switch;
/** Schedule description. */
bsu_beacon_schedules_t schedules;
};
@@ -200,11 +204,13 @@ bsu_beacon_write (bsu_beacon_t *beacon, bsu_beacon_type_t type,
* \param beacon the beacon received from the medium.
* \param schedules schedules structure to store the data.
* \param discover the discover structure to store discover data.
+ * \param hm the coexistence mode the AVLN is currently using.
*/
void
bsu_beacon_read_schedules (pb_beacon_t *beacon,
bsu_beacon_schedules_t *schedules,
- bsu_beacon_bmi_discover_t *discover);
+ bsu_beacon_bmi_discover_t *discover,
+ mac_coexistence_mode_t *hm);
/**
* Read the whole beacon and store the data into the beacon structure.
diff --git a/cesar/bsu/beacon/src/beacon.c b/cesar/bsu/beacon/src/beacon.c
index adadc99070..d1b7256ecd 100644
--- a/cesar/bsu/beacon/src/beacon.c
+++ b/cesar/bsu/beacon/src/beacon.c
@@ -1018,14 +1018,12 @@ bsu_beacon_countdown (bsu_beacon_t *beacon)
void
bsu_beacon_read_schedules (pb_beacon_t *beacon,
bsu_beacon_schedules_t *schedules,
- bsu_beacon_bmi_discover_t *discover)
+ bsu_beacon_bmi_discover_t *discover,
+ mac_coexistence_mode_t *hm)
{
bitstream_t stream;
- uint i, j, nbe, nb_persistent = 0;
+ uint i, nbe, nb_persistent = 0;
bsu_beacon_entry_header_t header;
- bsu_beacon_bmi_change_snid_t snid;
- bsu_beacon_bmi_eks_t eks;
- bsu_beacon_bmi_change_hybrid_mode_t hm;
uint length;
dbg_assert (beacon);
dbg_assert (schedules);
@@ -1033,7 +1031,7 @@ bsu_beacon_read_schedules (pb_beacon_t *beacon,
bitstream_read_init (&stream, beacon->data, BSU_BEACON_SIZE);
/* Skip the NID. */
bitstream_skip (&stream, 22);
- schedules->hm[0] = bitstream_read (&stream, 2);
+ *hm = bitstream_read (&stream, 2);
/* Skip the variant fields until network mode. */
bitstream_skip (&stream, 32);
schedules->nm = bitstream_read (&stream, 2);
@@ -1060,22 +1058,13 @@ bsu_beacon_read_schedules (pb_beacon_t *beacon,
bsu_beacon_read_bmi_bpsto (&stream, &schedules->bpsto);
break;
case BSU_BEACON_ENTRY_HEADER_ENCRYPTION_KEY_CHANGE:
- bsu_beacon_read_bmi_eks (&stream, &eks);
- if (eks.kbc == BSU_BEACON_EKS_KBC_NEK)
- {
- for (j = eks.kccd; j < COUNT (schedules->nek_switch); j++)
- schedules->nek_switch [j] = eks.new_eks;
- }
+ bsu_beacon_read_bmi_eks (&stream, &schedules->eks);
break;
case BSU_BEACON_ENTRY_HEADER_CHANGE_SNID:
- bsu_beacon_read_bmi_change_snid (&stream, &snid);
- for (j = snid.snidccd; j < COUNT (schedules->snid); j++)
- schedules->snid [j] = snid.new_snid;
+ bsu_beacon_read_bmi_change_snid (&stream, &schedules->snid);
break;
case BSU_BEACON_ENTRY_HEADER_CHANGE_HM:
- bsu_beacon_read_bmi_change_hm (&stream, &hm);
- for (j = hm.hmccd; j < COUNT (schedules->hm); j++)
- schedules->hm[j] = hm.newhm;
+ bsu_beacon_read_bmi_change_hm (&stream, &schedules->hm);
break;
case BSU_BEACON_ENTRY_HEADER_DISCOVER:
bsu_beacon_read_bmi_discover (&stream, discover);
diff --git a/cesar/bsu/inc/context.h b/cesar/bsu/inc/context.h
index 9862047d88..1f9abb6480 100644
--- a/cesar/bsu/inc/context.h
+++ b/cesar/bsu/inc/context.h
@@ -40,6 +40,9 @@ struct bsu_avln_t
bsu_beacon_avln_t bs;
/** NTB synchronisation data. */
bsu_ntb_sync_t sync;
+ /** Last beacon period in the one it had received the beacon.
+ * The date is the value of the beginning of the beacon period. */
+ u32 beacon_recv_bps_tck;
};
struct bsu_t
diff --git a/cesar/bsu/ntb/ntb_sync.h b/cesar/bsu/ntb/ntb_sync.h
index 9afe12db8c..e515ab3897 100644
--- a/cesar/bsu/ntb/ntb_sync.h
+++ b/cesar/bsu/ntb/ntb_sync.h
@@ -24,8 +24,6 @@ struct bsu_ntb_sync_t
* because the first computation of the frequency error is not equal to
* the others. */
bool second_shoot;
- /** Number of beacon processed. */
- u32 beacon_nb;
/** Frequency error. */
double fe;
/** beacon time stamp. */
diff --git a/cesar/bsu/ntb/src/ntb.c b/cesar/bsu/ntb/src/ntb.c
index bc61fe96d7..66fc6f3e31 100644
--- a/cesar/bsu/ntb/src/ntb.c
+++ b/cesar/bsu/ntb/src/ntb.c
@@ -100,7 +100,6 @@ bsu_ntb_clk_sync (bsu_ntb_sync_t * ctx, phy_t *phy, u32 beacon_bts,
double freq_error;
dbg_assert (ctx);
dbg_assert (phy);
- ctx->beacon_nb ++;
freq_error = ctx->fe;
bsu_ntb_frequency_error (ctx, freq_error, beacon_bts, beacon_sys_ltmr);
ctx->ntb_offset_tck= bsu_ntb_offset (ctx, phy, freq_error, beacon_bts,
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index ee36b2316b..25f8cc90d6 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -89,20 +89,24 @@ bsu_avln_get (bsu_t *ctx, u64 nid, u8 snid)
* \param ctx the module context.
* \param nid the NID of the AVLN.
* \param snid the SNID of the AVLN.
+ * \param added set true if newly added.
* \return the AVLN object.
*
* The AVLNs are static object do not release it.
*/
inline bsu_avln_t*
-bsu_avln_add (bsu_t *ctx, u64 nid, u8 snid)
+bsu_avln_add (bsu_t *ctx, u64 nid, u8 snid, bool *added)
{
+ *added = false;
bsu_avln_t* avln = bsu_avln_get (ctx, nid, snid);
if (!avln && ctx->avlns_nb < BSU_FOREIGN_AVLNS_NB)
{
avln = &ctx->avlns[ctx->avlns_nb];
avln->bs.nid = nid;
avln->bs.snid = snid;
+ avln->beacon_recv_bps_tck = phy_date ();
ctx->avlns_nb++;
+ *added = true;
}
return avln;
}
@@ -303,10 +307,39 @@ bsu_schedules_merge (bsu_t *ctx, bsu_beacon_schedules_t *asched,
}
/* store the number of allocations. */
schedule->allocations_nb = alloc;
- /* Store the end of data for this schedule-> */
- schedule->coexistence_mode = asched->hm[bp_index];
- schedule->nek_switch = asched->nek_switch[bp_index];
- schedule->snid = asched->snid[bp_index];
+}
+
+/**
+ * Fill the Hybrid mode, SNID and NEK value for CA schedule.
+ * \param ctx the module context.
+ * \param asched the AVLN schedule structure containing the necessary data.
+ * \param casched the Channel access schedule to fill.
+ * \param bpn the beacon period number, 0 for the current one, 1 for the
+ * next one and so on.
+ */
+inline void
+bsu_ca_schedules_settings (bsu_t *ctx, bsu_beacon_avln_t *asched,
+ ca_schedule_t *casched, uint bpn)
+{
+ /* SNID. */
+ if (asched->schedules.snid.present
+ && asched->schedules.snid.snidccd <= bpn)
+ casched->snid = asched->schedules.snid.new_snid;
+ else
+ casched->snid = asched->snid;
+ /* NEK switch. */
+ if (asched->schedules.eks.present
+ && asched->schedules.eks.kbc == BSU_BEACON_EKS_KBC_NEK
+ && asched->schedules.eks.kccd <= bpn)
+ casched->nek_switch = !ctx->nek_switch;
+ else
+ casched->nek_switch = ctx->nek_switch;
+ /* Hybrid mode. */
+ if (asched->schedules.hm.present
+ && asched->schedules.hm.hmccd <= bpn)
+ casched->coexistence_mode = asched->schedules.hm.newhm;
+ else
+ casched->coexistence_mode = asched->hm;
}
/**
@@ -368,6 +401,7 @@ bsu_ca_schedules (bsu_t *ctx, bsu_avln_t *avln)
{
schedule = ca_alloc_get_schedule (ctx->ca, ctx->ca_index);
bsu_schedules_merge (ctx, &avln->bs.schedules, schedule, i);
+ bsu_ca_schedules_settings (ctx, &avln->bs, schedule, i);
beacon_period[i].start_date = bpsd[i];
beacon_period[i].schedule_index = ctx->ca_index;
ctx->ca_index = (ctx->ca_index + 1) % CA_SCHEDULE_NB;
@@ -378,6 +412,57 @@ bsu_ca_schedules (bsu_t *ctx, bsu_avln_t *avln)
}
/**
+ * Decrease countdown EKS, SNID and HM.
+ * \param ctx the module context.
+ * \param avln the AVLN schedules data.
+ * This should be done after programming the CA with the current schedules to
+ * have data ready for next awake.
+ */
+static inline void
+bsu_avln_countdown_beacon_entries (bsu_t *ctx, bsu_avln_t *avln)
+{
+ if (avln->bs.schedules.snid.present)
+ avln->bs.schedules.snid.snidccd--;
+ if (avln->bs.schedules.hm.present)
+ avln->bs.schedules.hm.hmccd--;
+ if (avln->bs.schedules.eks.present)
+ avln->bs.schedules.eks.kccd--;
+}
+
+/**
+ * Apply EKS, SNID and HM.
+ * \param ctx the module context.
+ * \param avln the AVLN schedules data.
+ * This should be done after programming the CA with the current schedules to
+ * have data ready for next awake.
+ */
+static inline void
+bsu_avln_countdown_beacon_entries_apply_changes (bsu_t *ctx, bsu_avln_t *avln)
+{
+ if (avln->bs.schedules.snid.present
+ && avln->bs.schedules.snid.snidccd == 1)
+ {
+ avln->bs.schedules.snid.present = false;
+ avln->bs.snid = avln->bs.schedules.snid.new_snid;
+ if (avln == ctx->sta_avln)
+ ctx->snid_track = avln->bs.snid;
+ }
+ if (avln->bs.schedules.hm.present
+ && avln->bs.schedules.hm.hmccd == 1)
+ {
+ avln->bs.schedules.hm.present = false;
+ avln->bs.hm = avln->bs.schedules.hm.newhm;
+ }
+ if (avln->bs.schedules.eks.present
+ && avln->bs.schedules.eks.kccd == 1)
+ {
+ avln->bs.schedules.eks.present = false;
+ if (avln->bs.schedules.eks.kbc == BSU_BEACON_EKS_KBC_NEK)
+ avln->bs.nek_switch = !avln->bs.nek_switch;
+ }
+}
+
+/**
* Decrease schedules countdown.
* \param ctx the module context.
* \param avln the AVLN object.
@@ -386,6 +471,9 @@ inline void
bsu_avln_schedules_decrease_countdown (bsu_t *ctx, bsu_avln_t *avln)
{
uint i;
+ uint bpsd0;
+ bsu_aclf_beacon_period_start_date (ctx->aclf, &bpsd0, 1);
+ avln->beacon_recv_bps_tck = bpsd0;
for (i = 0; i < avln->bs.schedules.ps.nb; i++)
{
/* If one of the persistent schedules has the CSCD == 0, it should be
@@ -410,17 +498,6 @@ bsu_avln_schedules_decrease_countdown (bsu_t *ctx, bsu_avln_t *avln)
avln->bs.schedules.ps.ps[i].cscd--;
}
}
- /* Special case, the SNID of our network change. */
- if (ctx->sta_avln == avln
- && avln->bs.schedules.snid[0] != avln->bs.schedules.snid[1])
- ctx->snid_track = avln->bs.schedules.snid[1];
- /* Countdown all. */
- for (i = 0; i < BSU_BEACON_SCHEDULES_MAX - 1; i++)
- {
- avln->bs.schedules.snid[i] = avln->bs.schedules.snid[i+1];
- avln->bs.schedules.hm[i] = avln->bs.schedules.hm[i+1];
- avln->bs.schedules.nek_switch[i] = avln->bs.schedules.nek_switch[i+1];
- }
}
/**
@@ -462,7 +539,10 @@ bsu_timer_event_process (void *ud)
bsu_aclf_beacon_period_start_date (ctx->aclf, bpsd, COUNT (bpsd));
dbg_assert (less_mod2p32 (phy_date (), bpsd[1]));
if (ctx->is_sta == BSU_UPDATE_STA_TYPE_STA)
- bsu_avln_schedules_decrease_countdown (ctx, ctx->sta_avln);
+ {
+ if (less_mod2p32 (ctx->sta_avln->beacon_recv_bps_tck, bpsd[0]))
+ bsu_avln_schedules_decrease_countdown (ctx, ctx->sta_avln);
+ }
else
{
/* Are update data late ?. */
@@ -490,65 +570,12 @@ bsu_timer_event_process (void *ud)
}
}
bsu_ca_schedules (ctx, ctx->sta_avln);
+ bsu_avln_countdown_beacon_entries_apply_changes (ctx, ctx->sta_avln);
+ bsu_avln_countdown_beacon_entries (ctx, ctx->sta_avln);
bsu_reprogram_timer (ctx, bpsd[2]);
}
}
-/**
- * Provide last data from beacon structure data into AVLN schedules.
- * \param ctx the module context.
- */
-static inline void
-bsu_update_sta_avln_schedules (bsu_t *ctx)
-{
- /* Copy schedules. */
- ctx->sta_avln->bs.schedules.ps = ctx->beacon.bmis.ps;
- ctx->sta_avln->bs.schedules.nps = ctx->beacon.bmis.nps;
- ctx->sta_avln->bs.schedules.bpsto = ctx->beacon.bmis.bpsto;
- /* Countdown all. */
- uint i;
- for (i = 0; i < BSU_BEACON_SCHEDULES_MAX - 1; i++)
- {
- ctx->sta_avln->bs.schedules.snid[i] =
- ctx->sta_avln->bs.schedules.snid[i+1];
- ctx->sta_avln->bs.schedules.hm[i] =
- ctx->sta_avln->bs.schedules.hm[i+1];
- ctx->sta_avln->bs.schedules.nek_switch[i] =
- ctx->sta_avln->bs.schedules.nek_switch[i+1];
- }
- /* Coexistence mode
- * Because only the CCo call this function and it will
- * set the CA schedule with this value before the countdown ends in the
- * central beacon. */
- if (ctx->beacon.bmis.change_hm.present
- && ctx->beacon.bmis.change_hm.hmccd == 1)
- {
- ctx->sta_avln->bs.schedules.hm[BSU_BEACON_SCHEDULES_MAX - 1] =
- ctx->beacon.vf.hm;
- }
- /* NEK switch.
- * Because only the CCo call this function and it will
- * set the CA schedule with this value before the countdown ends in the
- * central beacon. */
- if (ctx->beacon.bmis.eks.present
- && ctx->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK
- && ctx->beacon.bmis.eks.kccd == 1)
- {
- ctx->sta_avln->bs.schedules.nek_switch[BSU_BEACON_SCHEDULES_MAX - 1] =
- ctx->beacon.bmis.eks.new_eks;
- }
- /* SNID change.
- * Because only the CCo call this function and it will
- * set the CA schedule with this value before the countdown ends in the
- * central beacon. */
- if (ctx->beacon.bmis.change_snid.present
- && ctx->beacon.bmis.change_snid.snidccd == 1)
- {
- ctx->sta_avln->bs.schedules.snid[BSU_BEACON_SCHEDULES_MAX-1] =
- ctx->beacon.bmis.change_snid.new_snid;
- }
-}
-
bsu_t *
bsu_init (bsu_aclf_t *aclf, mac_config_t *mac_config, phy_t *phy,
mac_store_t *mac_store, ca_t *ca, sar_t *sar, hal_timer_t *timer,
@@ -634,10 +661,12 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
!((pb_t *) beacon)->phy_pb.pb_rx.pb_measurement.crc_error;
if (crc_ok)
{
+ u32 bpsd;
bsu_beacon_bmi_discover_t discover;
bsu_beacon_track_info_t tinfo;
bsu_beacon_read_track_info (beacon, &tinfo);
ctx->beacon_nb_recv[tinfo.bt]++;
+ bsu_aclf_beacon_period_start_date (ctx->aclf, &bpsd, 1);
/* It the beacon from our AVLN ? */
if (tinfo.bt == BSU_BEACON_TYPE_CENTRAL
&& ctx->is_sta == BSU_UPDATE_STA_TYPE_STA
@@ -659,7 +688,8 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
ctx->sta_avln->bs.schedules.bpsto.bpsto = 0;
ctx->sta_avln->bs.schedules.bpsto.present = false;
bsu_beacon_read_schedules (
- beacon, &ctx->sta_avln->bs.schedules, &discover);
+ beacon, &ctx->sta_avln->bs.schedules, &discover,
+ &ctx->sta_avln->bs.hm);
if (ctx->sta_avln->bs.schedules.bpsto.present)
bpsto = ctx->sta_avln->bs.schedules.bpsto.bpsto;
/* NTB synchronisation. */
@@ -683,24 +713,31 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
/* A discover beacon had been requested ? */
if (discover.present && discover.tei == ctx->mac_config->tei)
bsu_beacon_send_prepare (ctx, BSU_BEACON_TYPE_DISCOVER);
+ /* Store the reception date. */
+ ctx->sta_avln->beacon_recv_bps_tck = bpsd;
}
/* Track only Central beacon when associated. */
else if ((ctx->mac_config->tei == MAC_TEI_UNASSOCIATED
&& tinfo.bt == BSU_BEACON_TYPE_DISCOVER)
|| tinfo.bt == BSU_BEACON_TYPE_CENTRAL)
{
+ bool added;
bsu_avln_t *avln;
- avln = bsu_avln_add (ctx, tinfo.nid, params->snid);
+ avln = bsu_avln_add (ctx, tinfo.nid, params->snid, &added);
/* Other AVLN. */
- if (avln && avln != ctx->sta_avln)
+ if ((!added
+ && avln != ctx->sta_avln
+ && less_mod2p32 (avln->beacon_recv_bps_tck, bpsd))
+ || added)
{
bsu_beacon_read_schedules (beacon, &avln->bs.schedules,
- &discover);
- avln->bs.schedules.snid[0] = params->snid;
+ &discover, &avln->bs.hm);
/* NTB synchronisation. */
bsu_ntb_clk_sync (&avln->sync, ctx->phy,
params->bts, params->preamble_sysdate,
params->preamble_date);
+ /* Store the reception date. */
+ avln->beacon_recv_bps_tck = bpsd;
BSU_TRACE (BEACON_PROCESS, phy_date (), params->snid,
tinfo.tei, tinfo.bt,
avln ? avln->sync.ntb_offset_tck : 0);
@@ -843,13 +880,37 @@ bsu_update (bsu_beacon_t *beacon, bsu_update_sta_type_t is_sta)
ctx->beacon.bmis.discover_info =
beacon->bmis.discover_info;
}
- bsu_update_sta_avln_schedules (ctx);
+ /* Copy schedules. */
+ ctx->sta_avln->bs.schedules.ps = ctx->beacon.bmis.ps;
+ ctx->sta_avln->bs.schedules.nps = ctx->beacon.bmis.nps;
+ ctx->sta_avln->bs.schedules.bpsto = ctx->beacon.bmis.bpsto;
+ if (ctx->is_sta == BSU_UPDATE_STA_TYPE_CCO)
+ {
+ /* CCo should increase by one the countdown because it will apply
+ * those value in the CA schedule one beacon period before the STA. */
+ if (ctx->beacon.bmis.change_snid.present)
+ {
+ ctx->sta_avln->bs.schedules.snid = ctx->beacon.bmis.change_snid;
+ ctx->sta_avln->bs.schedules.snid.snidccd++;
+ }
+ if (ctx->beacon.bmis.change_hm.present)
+ {
+ ctx->sta_avln->bs.schedules.hm = ctx->beacon.bmis.change_hm;
+ ctx->sta_avln->bs.schedules.hm.hmccd++;
+ }
+ if (ctx->beacon.bmis.eks.present)
+ {
+ ctx->sta_avln->bs.schedules.eks = ctx->beacon.bmis.eks;
+ ctx->sta_avln->bs.schedules.eks.kccd++;
+ }
+ }
arch_dsr_unlock ();
}
void
bsu_track_avln (u64 nid, u16 snid, u8 tei, mac_coexistence_mode_t hm)
{
+ bool added;
uint i;
bsu_t *ctx = &bsu_global;
arch_dsr_lock ();
@@ -859,11 +920,10 @@ bsu_track_avln (u64 nid, u16 snid, u8 tei, mac_coexistence_mode_t hm)
ctx->nid_track = nid;
ctx->snid_track = snid;
ctx->tei_track = tei;
- ctx->sta_avln = bsu_avln_add (ctx, nid, snid);
- for (i = 0; i < COUNT (ctx->sta_avln->bs.schedules.hm); i++)
- ctx->sta_avln->bs.schedules.hm [i] = hm;
- for (i = 0; i < COUNT (ctx->sta_avln->bs.schedules.snid); i++)
- ctx->sta_avln->bs.schedules.snid[i] = snid;
+ ctx->sta_avln = bsu_avln_add (ctx, nid, snid, &added);
+ dbg_check (ctx->sta_avln);
+ ctx->sta_avln->bs.hm = hm;
+ ctx->sta_avln->bs.snid = snid;
/* If there is still beacon to be sent drop it. */
for (i = 0; i < COUNT (ctx->mfs_beacons); i++)
{
@@ -882,13 +942,9 @@ bsu_power_on (u8 snid)
ctx->sta_avln->bs.nid = ctx->beacon.vf.nid;
ctx->sta_avln->bs.snid = snid;
ctx->sta_avln->bs.tei = MAC_TEI_UNASSOCIATED;
- uint i;
- for (i = 0; i < COUNT (ctx->sta_avln->bs.schedules.hm); i++)
- {
- ctx->sta_avln->bs.schedules.hm [i] = ctx->beacon.vf.hm;
- ctx->sta_avln->bs.schedules.snid [i] = snid;
- ctx->sta_avln->bs.schedules.nek_switch [i] = 0;
- }
+ ctx->sta_avln->bs.hm = ctx->beacon.vf.hm;
+ ctx->sta_avln->bs.snid = snid;
+ ctx->sta_avln->bs.nek_switch = 0;
ctx->sta_avln->bs.schedules.ps = ctx->beacon.bmis.ps;
ctx->sta_avln->bs.schedules.nps = ctx->beacon.bmis.nps;
}
@@ -928,18 +984,14 @@ uint
bsu_nek_index_current (void)
{
bsu_t *ctx = &bsu_global;
- dbg_assert (ctx->sta_avln);
- return ctx->sta_avln->bs.schedules.nek_switch[0];
+ return ctx->sta_avln->bs.nek_switch;
}
uint
bsu_nek_index_next (void)
{
bsu_t *ctx = &bsu_global;
- dbg_assert (ctx->sta_avln);
- uint index_max =
- ctx->sta_avln->bs.schedules.nek_switch[BSU_BEACON_SCHEDULES_MAX-1];
- return (index_max + 1) % MAC_NEK_INDEX_NB;
+ return !ctx->sta_avln->bs.nek_switch;
}
void
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index 5d1fdd3e0b..df61f673a4 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -91,7 +91,6 @@ test_case_bsu_process (test_t test)
test_fail_unless (t.bsu->avlns[0].bs.nid == beacon_neighbour.vf.nid);
/* NTB called ? */
test_fail_unless (t.bsu->avlns[0].sync.init == true);
- test_fail_unless (t.bsu->avlns[0].sync.beacon_nb == 2);
blk_release_desc ((blk_t*) bneighbour);
test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL]
== 2);
@@ -140,6 +139,8 @@ test_case_bsu_process (test_t test)
brx.snid = 0x2;
b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config,
&btx);
+ t.bsu->sta_avln->beacon_recv_bps_tck = phy_date () -
+ BSU_ACLF_BP_50HZ_TCK - 1000;
bsu_beacon_process (t.bsu, b, &brx);
/* Change MAC config TEI for the test. */
bsu_beacon_track_info_t tinfo;
@@ -182,6 +183,8 @@ test_case_bsu_process (test_t test)
brx.snid = 0x3;
b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_DISCOVER,
&t.mac_config, &btx);
+ t.bsu->sta_avln->beacon_recv_bps_tck = phy_date () -
+ BSU_ACLF_BP_50HZ_TCK - 1000;
bsu_beacon_process (t.bsu, b, &brx);
bsu_avln_t *avln = bsu_avln_get (t.bsu, beacon.vf.nid, brx.snid);
test_fail_unless (avln == NULL);
@@ -389,6 +392,8 @@ test_case_bsu_timer_event_cco_ucco (test_t test, bsu_test_t *t,
t->bsu->beacon.beacon_period_start_date = t->bsu->aclf->bpsd[0] - 1;
for (i = 0; i < 7; i++)
{
+ cmp_avln.beacon_recv_bps_tck = phy_date () - BSU_ACLF_BP_50HZ_TCK -
+ 1000;
bsu_avln_schedules_decrease_countdown (t->bsu, &cmp_avln);
bsu_timer_event_process (t->bsu);
test_fail_unless (t->ul.beacon != INVALID_PTR);
@@ -434,8 +439,12 @@ test_case_bsu_timer_event (test_t test)
t.bsu->aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK;
for (j = 0; j < 10; j++)
{
- bsu_timer_event_process (t.bsu);
+ t.bsu->sta_avln->beacon_recv_bps_tck = t.bsu->aclf->bpsd[0] -
+ BSU_ACLF_BP_50HZ_TCK;
+ cmp_avln.beacon_recv_bps_tck = t.bsu->aclf->bpsd[0] -
+ BSU_ACLF_BP_50HZ_TCK;
bsu_avln_schedules_decrease_countdown (t.bsu, &cmp_avln);
+ bsu_timer_event_process (t.bsu);
for (i = 0; i < BSU_ACLF_BPSD_NB; i++)
test_fail_unless (
t.bsu->aclf->bpsd[i] = (i+j+1) * BSU_ACLF_BP_50HZ_TCK);
@@ -544,16 +553,6 @@ test_case_bsu_power_on (test_t test)
bsu_update (&beacon, BSU_UPDATE_STA_TYPE_STA);
bsu_power_on (0xa);
test_fail_unless (t.bsu->sta_avln == &t.bsu->poweron);
- uint i;
- for (i = 0; i < COUNT (t.bsu->sta_avln->bs.schedules.hm); i++)
- {
- test_fail_unless (t.bsu->sta_avln->bs.schedules.hm [i]
- == beacon.vf.hm);
- test_fail_unless (t.bsu->sta_avln->bs.schedules.snid [i]
- == 0xa);
- test_fail_unless (t.bsu->sta_avln->bs.schedules.nek_switch[i]
- == 0);
- }
test_fail_unless (
memcmp (&t.bsu->sta_avln->bs.schedules.ps,
&t.bsu->beacon.bmis.ps,
@@ -666,19 +665,16 @@ test_case_bsu_nek_index (test_t test)
bsu_test_init (&t);
test_begin (test, "Current index")
{
- uint i;
- uint index = bsu_nek_index_current ();
- test_fail_unless (index == 0);
- index = bsu_nek_index_next ();
- test_fail_unless (index == 1);
- /* Change NEK index in schedules. */
- for (i = 0; i < BSU_BEACON_SCHEDULES_MAX; i++)
- t.bsu->sta_avln->bs.schedules.nek_switch [i] = 1;
- index = bsu_nek_index_current ();
- test_fail_unless (index == 1);
- /* Next index. */
- index = bsu_nek_index_next ();
- test_fail_unless (index == 0);
+ bsu_test_avln_create (&t, t.bsu->sta_avln);
+ test_fail_unless (bsu_nek_index_current () ==
+ t.bsu->sta_avln->bs.nek_switch);
+ test_fail_unless (bsu_nek_index_next () ==
+ !t.bsu->sta_avln->bs.nek_switch);
+ t.bsu->sta_avln->bs.nek_switch = 1;
+ test_fail_unless (bsu_nek_index_current () ==
+ t.bsu->sta_avln->bs.nek_switch);
+ test_fail_unless (bsu_nek_index_next () ==
+ !t.bsu->sta_avln->bs.nek_switch);
}
test_end;
bsu_test_uninit (&t);
diff --git a/cesar/bsu/test/utest/src/schedules.c b/cesar/bsu/test/utest/src/schedules.c
index 61953497a0..e9dff54852 100644
--- a/cesar/bsu/test/utest/src/schedules.c
+++ b/cesar/bsu/test/utest/src/schedules.c
@@ -117,58 +117,35 @@ test_case_ca_schedules (test_t test)
}
void
+test_case_bsu_schedules_countdowns_init (bsu_t *bsu, ca_schedule_t *cas)
+{
+ bsu->sta_avln->bs.schedules.snid.present = true;
+ bsu->sta_avln->bs.schedules.snid.snidccd = 3;
+ bsu->sta_avln->bs.schedules.snid.new_snid = 3;
+ bsu->sta_avln->bs.schedules.eks.present = true;
+ bsu->sta_avln->bs.schedules.eks.kccd = 3;
+ bsu->sta_avln->bs.schedules.eks.kbc = BSU_BEACON_EKS_KBC_NEK;
+ bsu->sta_avln->bs.schedules.eks.new_eks = 4;
+ bsu->sta_avln->bs.schedules.hm.present = true;
+ bsu->sta_avln->bs.schedules.hm.hmccd = 3;
+ bsu->sta_avln->bs.schedules.hm.newhm = 1;
+ bsu->sta_avln->bs.nek_switch = 0;
+ cas[0].snid = bsu->sta_avln->bs.snid;
+ cas[0].coexistence_mode = bsu->sta_avln->bs.hm;
+ cas[0].nek_switch = bsu->sta_avln->bs.nek_switch;
+ cas[1].snid = bsu->sta_avln->bs.snid;
+ cas[1].coexistence_mode = bsu->sta_avln->bs.hm;
+ cas[1].nek_switch = bsu->sta_avln->bs.nek_switch;
+ cas[2].snid = bsu->sta_avln->bs.schedules.snid.new_snid;
+ cas[2].coexistence_mode = bsu->sta_avln->bs.schedules.hm.newhm;
+ cas[2].nek_switch = !bsu->sta_avln->bs.nek_switch;
+}
+
+void
test_case_bsu_schedules_countdowns (test_t t)
{
test_suite_begin (t, "Countdowns");
- test_begin (t, "SNID/EKS/HM change On event process")
- {
- uint i, j;
- ca_schedule_t *casched;
- bsu_test_t ctx;
- bsu_test_init (&ctx);
- bsu_activate (true);
- ctx.bsu->is_sta = BSU_UPDATE_STA_TYPE_STA;
- bsu_test_avln_create (&ctx, ctx.bsu->sta_avln);
- for (i = 0; i < BSU_BEACON_SCHEDULES_MAX; i++)
- {
- ctx.bsu->sta_avln->bs.schedules.snid [i] = i;
- ctx.bsu->sta_avln->bs.schedules.nek_switch [i] = i;
- ctx.bsu->sta_avln->bs.schedules.hm [i] = i;
- }
- for (i = 0; i < 3; i++)
- {
- ctx.bsu->ca_index = 0;
- bsu_timer_event_process (ctx.bsu);
- for (j = 0; j < 3; j++)
- {
- casched = ca_alloc_get_schedule (INVALID_PTR, j);
- test_fail_unless (
- casched->snid ==
- ctx.bsu->sta_avln->bs.schedules.snid [j]);
- test_fail_unless (
- casched->nek_switch ==
- ctx.bsu->sta_avln->bs.schedules.nek_switch [j]);
- test_fail_unless (
- casched->coexistence_mode ==
- ctx.bsu->sta_avln->bs.schedules.hm [j]);
- }
- for (j = 0; j < BSU_BEACON_SCHEDULES_MAX - 1; j++)
- {
- ctx.bsu->sta_avln->bs.schedules.snid [j] =
- ctx.bsu->sta_avln->bs.schedules.snid [j+1];
- ctx.bsu->sta_avln->bs.schedules.nek_switch[j] =
- ctx.bsu->sta_avln->bs.schedules.nek_switch[j+1];
- ctx.bsu->sta_avln->bs.schedules.hm [j] =
- ctx.bsu->sta_avln->bs.schedules.hm [j+1];
- }
- ctx.bsu->sta_avln->bs.schedules.snid [2] = 2;
- ctx.bsu->sta_avln->bs.schedules.nek_switch [2] = 2;
- ctx.bsu->sta_avln->bs.schedules.hm [2] = 2;
- }
- bsu_test_uninit (&ctx);
- }
- test_end;
- test_begin (t, "SNID/EKS/HM change On beacon reception")
+ test_begin (t, "SNID/EKS/HM change")
{
uint i, j;
bsu_beacon_t beacon;
@@ -184,40 +161,68 @@ test_case_bsu_schedules_countdowns (test_t t)
bsu_track_avln (beacon.vf.nid, 0x0, ctx.mac_config.tei,
MAC_COEXISTENCE_FULL_HYBRID_MODE);
ctx.bsu->is_sta = BSU_UPDATE_STA_TYPE_STA;
- beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK;
- for (i = 0; i < 5; i++)
+ for (i = 0; i < BSU_ACLF_BPSD_NB; i++)
+ ctx.bsu->aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK;
+ ca_schedule_t cas[3];
+ test_case_bsu_schedules_countdowns_init (ctx.bsu, cas);
+ beacon.bmis.change_hm = ctx.bsu->sta_avln->bs.schedules.hm;
+ beacon.bmis.change_hm.hmccd--;
+ beacon.bmis.change_snid = ctx.bsu->sta_avln->bs.schedules.snid;
+ beacon.bmis.change_snid.snidccd--;
+ beacon.bmis.eks = ctx.bsu->sta_avln->bs.schedules.eks;
+ beacon.bmis.eks.kccd--;
+ for (i = 0; i < COUNT (cas); i++)
{
- pb_beacon_t *b = bsu_beacon_write (
- &beacon, BSU_BEACON_TYPE_CENTRAL, &ctx.mac_config, &bparams);
- ((pb_t *) b)->phy_pb.pb_rx.pb_measurement.crc_error = false;
- bsu_beacon_recv (ctx.bsu, b, &bparamsrx);
ctx.bsu->ca_index = 0;
- for (j = 0; j < 3; j++)
+ /* Prepare expected results. */
+ for (i = 0; i < CA_SCHEDULE_NB; i++)
+ memset (ca_alloc_get_schedule (INVALID_PTR, i), 0xff,
+ sizeof (ca_schedule_t));
+ /* station does not receive the last beacon. */
+ ctx.bsu->sta_avln->beacon_recv_bps_tck = phy_date () -
+ BSU_ACLF_BP_50HZ_TCK;
+ if (i != 1)
+ {
+ pb_beacon_t *b = bsu_beacon_write (
+ &beacon, BSU_BEACON_TYPE_CENTRAL, &ctx.mac_config, &bparams);
+ ((pb_t *) b)->phy_pb.pb_rx.pb_measurement.crc_error = false;
+ bparamsrx.preamble_date = bparamsrx.preamble_sysdate = 0;
+ bparamsrx.bts = 0;
+ /* On beacon reception only schedules are read and CA is
+ * programmed with the current data. */
+ bsu_beacon_recv (ctx.bsu, b, &bparamsrx);
+ }
+ /* On timer event the snid change, NEK and hybrid mode are changed
+ * in the lower layers. */
+ bsu_timer_event_process (ctx.bsu);
+ for (j = 0; j < COUNT (cas); j++)
{
casched = ca_alloc_get_schedule (INVALID_PTR, j);
- test_fail_unless (
- casched->snid ==
- ctx.bsu->sta_avln->bs.schedules.snid [j]);
- test_fail_unless (
- casched->nek_switch ==
- ctx.bsu->sta_avln->bs.schedules.nek_switch[j]);
- test_fail_unless (
- casched->coexistence_mode ==
- ctx.bsu->sta_avln->bs.schedules.hm [j]);
+ test_fail_unless (casched->snid == cas[j].snid);
+ test_fail_unless (casched->nek_switch == cas[j].nek_switch);
+ test_fail_unless (casched->coexistence_mode ==
+ cas[j].coexistence_mode);
+ }
+ cas[0] = cas[1];
+ cas[1] = cas[2];
+ if (i != 1)
+ {
+ /* Release beacon. */
+ blk_release_desc ((blk_t*) ctx.ul.beacon);
+ ctx.ul.beacon = INVALID_PTR;
}
- /* Release beacon. */
- blk_release_desc ((blk_t*) ctx.ul.beacon);
- ctx.ul.beacon = INVALID_PTR;
beacon.bmis.change_snid.snidccd --;
+ beacon.bmis.change_snid.present =
+ beacon.bmis.change_snid.snidccd != 0;
+ if (beacon.bmis.change_snid.present == false)
+ bparamsrx.snid = beacon.bmis.change_snid.new_snid;
beacon.bmis.eks.kccd--;
+ beacon.bmis.eks.present = beacon.bmis.eks.kccd != 0;
beacon.bmis.change_hm.hmccd--;
+ beacon.bmis.change_hm.present = beacon.bmis.change_hm.hmccd != 0;
+ if (beacon.bmis.change_hm.present == false)
+ beacon.vf.hm = beacon.bmis.change_hm.newhm;
}
- test_fail_unless (ctx.bsu->sta_avln->bs.schedules.snid [0] ==
- beacon.bmis.change_snid.new_snid);
- test_fail_unless (ctx.bsu->sta_avln->bs.schedules.nek_switch [0] ==
- beacon.bmis.eks.new_eks);
- test_fail_unless (ctx.bsu->sta_avln->bs.schedules.hm [0] ==
- beacon.bmis.change_hm.newhm);
bsu_test_uninit (&ctx);
}
test_end;
@@ -255,8 +260,12 @@ test_case_ca_schedules_intellon (test_t test)
pbbeacon = bsu_beacon_write (
&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &btx);
pbbeacon->phy_pb.pb_rx.pb_measurement.crc_error = false;
+ /* The first time bsu receives a beacon of an AVLN. */
+ bsu_beacon_process (t.bsu, pbbeacon, &brx);
+ /* Control plane request to track this AVLN. */
bsu_track_avln (beacon.vf.nid, brx.snid, 0, beacon.vf.nm);
t.bsu->is_sta = BSU_UPDATE_STA_TYPE_STA;
+ /* BSU receives the next beacon. */
bsu_beacon_process (t.bsu, pbbeacon, &brx);
/* Schedules which should be present. */
test_fail_unless (t.bsu->sta_avln->bs.schedules.ps.nb == 1);
diff --git a/cesar/bsu/test/utest/src/tests.c b/cesar/bsu/test/utest/src/tests.c
index cc3c51100d..cb2d9fe39a 100644
--- a/cesar/bsu/test/utest/src/tests.c
+++ b/cesar/bsu/test/utest/src/tests.c
@@ -491,15 +491,9 @@ bsu_test_avln_create (bsu_test_t *ctx, bsu_avln_t *avln)
{
avln->bs.schedules.bpsto.present = true;
avln->bs.schedules.bpsto.bpsto = 0x45;
- avln->bs.schedules.hm[0] = MAC_COEXISTENCE_FULL_HYBRID_MODE;
- avln->bs.schedules.hm[1] = MAC_COEXISTENCE_FULL_HYBRID_MODE;
- avln->bs.schedules.hm[3] = MAC_COEXISTENCE_AV_ONLY_MODE;
- avln->bs.schedules.nek_switch[0] = 0;
- avln->bs.schedules.nek_switch[1] = 0;
- avln->bs.schedules.nek_switch[2] = 1;
- avln->bs.schedules.snid[0] = 0;
- avln->bs.schedules.snid[1] = 0;
- avln->bs.schedules.snid[2] = 1;
+ avln->bs.hm = MAC_COEXISTENCE_FULL_HYBRID_MODE;
+ avln->bs.nek_switch = 0;
+ avln->bs.snid = 0;
bsu_test_schedules_persistent (ctx, &avln->bs.schedules.ps);
bsu_test_schedules_non_persistent (ctx, &avln->bs.schedules.nps);
}