summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cesar/bsu/beacon/beacon.h2
-rw-r--r--cesar/bsu/src/bsu.c124
-rw-r--r--cesar/bsu/test/utest/src/bsut.c47
3 files changed, 144 insertions, 29 deletions
diff --git a/cesar/bsu/beacon/beacon.h b/cesar/bsu/beacon/beacon.h
index 636a09f279..7cafd88eec 100644
--- a/cesar/bsu/beacon/beacon.h
+++ b/cesar/bsu/beacon/beacon.h
@@ -157,7 +157,7 @@ struct bsu_beacon_avln_t
/** NID. */
u64 nid;
/** SNID. */
- u16 snid;
+ u8 snid;
/** CCo's TEI. */
u8 tei;
/** Schedule description. */
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index 94a2a1fa70..ab3e168522 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -73,8 +73,8 @@ bsu_reprogram_timer (bsu_t *ctx, u32 date)
*
* The AVLNs are static object do not release it.
*/
-static inline bsu_avln_t*
-bsu_avln_get (bsu_t *ctx, u64 nid, u16 snid)
+inline bsu_avln_t*
+bsu_avln_get (bsu_t *ctx, u64 nid, u8 snid)
{
uint i;
for (i = 0; i < ctx->avlns_nb; i++)
@@ -92,8 +92,8 @@ bsu_avln_get (bsu_t *ctx, u64 nid, u16 snid)
*
* The AVLNs are static object do not release it.
*/
-static inline bsu_avln_t*
-bsu_avln_add (bsu_t *ctx, u64 nid, u16 snid)
+inline bsu_avln_t*
+bsu_avln_add (bsu_t *ctx, u64 nid, u8 snid)
{
bsu_avln_t* avln = bsu_avln_get (ctx, nid, snid);
if (!avln && ctx->avlns_nb < BSU_FOREIGN_AVLNS_NB)
@@ -107,6 +107,36 @@ bsu_avln_add (bsu_t *ctx, u64 nid, u16 snid)
}
/**
+ * Remove an AVLN.
+ * \param ctx the module context.
+ * \param nid the NID of the AVLN.
+ * \param snid the SNID of the AVLN.
+ *
+ * The AVLNs are static object do not release it.
+ */
+inline void
+bsu_avln_remove (bsu_t *ctx, u64 nid, u8 snid)
+{
+ bsu_avln_t *to_remove = NULL;
+ uint i, pos;
+ for (i = 0; i < ctx->avlns_nb; i++)
+ {
+ if (ctx->avlns[i].bs.nid == nid && ctx->avlns[i].bs.snid == snid)
+ {
+ to_remove = &ctx->avlns[i];
+ pos = i;
+ break;
+ }
+ }
+ if (to_remove)
+ {
+ for (i = pos; i < ctx->avlns_nb - 1; i++)
+ ctx->avlns[i] = ctx->avlns[i+1];
+ ctx->avlns_nb--;
+ }
+}
+
+/**
* Initialise the process position index object.
* \param ctx the module context.
* \param sched the schedules.
@@ -406,6 +436,52 @@ bsu_timer_event_process (void *ud)
}
}
+/**
+ * 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)
+{
+ uint i;
+ /* Coexistence mode */
+ if (ctx->beacon.bmis.change_hm.present)
+ {
+ ctx->sta_avln->bs.schedules.hm[0] = ctx->beacon.vf.hm;
+ for (i = ctx->beacon.bmis.change_hm.hmccd;
+ i < COUNT (ctx->sta_avln->bs.schedules.hm);
+ i++)
+ ctx->sta_avln->bs.schedules.hm[i] =
+ ctx->beacon.bmis.change_hm.newhm;
+ }
+ /* NEK switch. */
+ if (ctx->beacon.bmis.eks.present
+ && ctx->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK)
+ {
+ for (i = ctx->beacon.bmis.eks.kccd;
+ i < COUNT (ctx->sta_avln->bs.schedules.nek_switch);
+ i++)
+ ctx->sta_avln->bs.schedules.nek_switch[i] =
+ ctx->beacon.bmis.eks.new_eks;
+ }
+ /* SNID change. */
+ if (ctx->beacon.bmis.change_snid.present)
+ {
+ for (i = ctx->beacon.bmis.change_snid.snidccd;
+ i < COUNT (ctx->sta_avln->bs.schedules.snid);
+ i++)
+ ctx->sta_avln->bs.schedules.snid[i] =
+ ctx->beacon.bmis.change_snid.new_snid;
+ if (ctx->beacon.bmis.change_snid.snidccd == 0)
+ ctx->sta_avln->bs.snid =
+ ctx->beacon.bmis.change_snid.new_snid;
+ }
+ /* 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;
+}
+
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)
@@ -430,7 +506,7 @@ bsu_init (bsu_aclf_t *aclf, mac_config_t *mac_config, phy_t *phy,
uint i;
for (i = 0; i < HPAV_AVLNS_NB_MAX; i++)
bsu_ntb_init (&ctx->avlns[i].sync);
- ctx->sta_avln = NULL;
+ ctx->sta_avln = &ctx->poweron;
/* Initialise the SAR callback. */
sar_init_beacon_cb (sar, ctx, (sar_beacon_cb_t) bsu_beacon_recv);
/* Initialise timer events. */
@@ -494,28 +570,22 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
bsu_beacon_read_track_info (beacon, &tinfo);
ctx->beacon_nb_recv[tinfo.bt]++;
/* It the beacon from our AVLN ? */
- if (ctx->is_sta == BSU_UPDATE_STA_TYPE_STA
- && tinfo.nid == ctx->nid_track
- && params->snid == ctx->snid_track
- && ((ctx->tei_track == tinfo.tei
- && tinfo.bt == BSU_BEACON_TYPE_CENTRAL)
- || (ctx->tei_track == MAC_TEI_UNASSOCIATED
- && tinfo.bt == BSU_BEACON_TYPE_DISCOVER
- && ctx->is_sta != BSU_UPDATE_STA_TYPE_CCO)))
+ if (tinfo.bt == BSU_BEACON_TYPE_CENTRAL
+ && ctx->is_sta == BSU_UPDATE_STA_TYPE_STA
+ && ctx->nid_track == tinfo.nid
+ && ctx->snid_track == params->snid
+ && ctx->tei_track == tinfo.tei)
{
discover.present = false;
dbg_assert (ctx->is_sta == BSU_UPDATE_STA_TYPE_STA);
- dbg_assert ((tinfo.bt == BSU_BEACON_TYPE_DISCOVER
- && tinfo.tei == MAC_TEI_UNASSOCIATED)
- || (tinfo.bt == BSU_BEACON_TYPE_CENTRAL
- && MAC_TEI_IS_STA (tinfo.tei)));
+ dbg_assert (tinfo.bt == BSU_BEACON_TYPE_CENTRAL);
u32 bpsto = 0;
ctx->sta_avln->bs.nid = tinfo.nid;
ctx->sta_avln->bs.snid = params->snid;
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);
+ bsu_beacon_read_schedules (
+ beacon, &ctx->sta_avln->bs.schedules, &discover);
if (ctx->sta_avln->bs.schedules.bpsto.present)
bpsto = ctx->sta_avln->bs.schedules.bpsto.bpsto;
/* NTB synchronisation. */
@@ -523,8 +593,8 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
params->bts, params->preamble_sysdate,
params->preamble_date);
/* Configure the clock frequency. */
- bsu_ntb_clock_configure (&ctx->sta_avln->sync, ctx->mac_config,
- ctx->phy);
+ bsu_ntb_clock_configure (
+ &ctx->sta_avln->sync, ctx->mac_config, ctx->phy);
bsu_aclf_compute_beacon_period_start_date (
ctx->aclf, params->bts, (s16*) params->bto,
ctx->sta_avln->bs.schedules.bpsto.bpsto,
@@ -533,13 +603,17 @@ bsu_beacon_process (bsu_t *ctx, pb_beacon_t *beacon,
bsu_ca_schedules (ctx, ctx->sta_avln);
bsu_reprogram_timer (
ctx, bsu_aclf_beacon_period_start_date_next (ctx->aclf));
- BSU_TRACE (BEACON_PROCESS, phy_date (), params->snid, tinfo.tei,
- tinfo.bt, ctx->sta_avln->sync.ntb_offset_tck);
+ BSU_TRACE (
+ BEACON_PROCESS, phy_date (), params->snid, tinfo.tei,
+ tinfo.bt, ctx->sta_avln->sync.ntb_offset_tck);
/* A discover beacon had been requested ? */
if (discover.present && discover.tei == ctx->mac_config->tei)
bsu_beacon_send_prepare (ctx, BSU_BEACON_TYPE_DISCOVER);
}
- else
+ /* 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)
{
bsu_avln_t *avln;
avln = bsu_avln_add (ctx, tinfo.nid, params->snid);
@@ -679,6 +753,7 @@ bsu_update (bsu_beacon_t *beacon, bsu_update_sta_type_t is_sta)
ctx->beacon.bmis.mac_address_present =
beacon->bmis.mac_address_present;
}
+ bsu_update_sta_avln_schedules (ctx);
arch_dsr_unlock ();
}
@@ -705,6 +780,7 @@ bsu_track_avln (u64 nid, u16 snid, u8 tei, mac_coexistence_mode_t hm)
if (ctx->mfs_beacons[i])
bsu_mfs_remove (ctx, i);
}
+ bsu_ca_schedules (ctx, ctx->sta_avln);
arch_dsr_unlock ();
}
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index 79c6b1be4f..a1f3ea652b 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -29,6 +29,12 @@ bsu_avln_schedules_decrease_countdown (bsu_t *ctx, bsu_avln_t *avln);
void
bsu_update__persistent_schedules (bsu_t *ctx, bsu_beacon_t *beacon);
+bsu_avln_t*
+bsu_avln_get (bsu_t *ctx, u64 nid, u16 snid);
+
+void
+bsu_avln_remove (bsu_t *ctx, u64 nid, u8 snid);
+
void
test_case_bsu_process (test_t test)
{
@@ -89,10 +95,10 @@ test_case_bsu_process (test_t test)
== 2);
/* Our AVLN. */
t.mac_config.tei = 1;
- bsu_track_avln (0x2, 0x5, t.mac_config.tei,
+ bsu_track_avln (beacon_neighbour.vf.nid, 0x4, t.mac_config.tei,
MAC_COEXISTENCE_AV_ONLY_MODE);
+ t.bsu->sta_avln->sync.init = false;
bsu_test_create_beacon (&t, &beacon);
- beacon.vf.nid = 0x2;
b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL,
&t.mac_config, &bp_tx);
b->phy_pb.pb_rx.pb_measurement.crc_error = true;
@@ -104,7 +110,7 @@ test_case_bsu_process (test_t test)
== 2);
/* NTB called ? */
test_fail_unless (t.bsu->sta_avln->sync.init == false);
- bp_rx.snid = 0x5;
+ bp_rx.snid = 0x4;
bp_rx.bts = 0;
t.mac_config.tei = 1;
b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL,
@@ -131,6 +137,7 @@ test_case_bsu_process (test_t test)
brx.snid = 0x2;
b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config,
&btx);
+ bsu_beacon_process (t.bsu, b, &brx);
/* Change MAC config TEI for the test. */
bsu_beacon_track_info_t tinfo;
bsu_beacon_read_track_info (b, &tinfo);
@@ -146,7 +153,7 @@ test_case_bsu_process (test_t test)
test_fail_unless (t.bsu->beacon_nb_sent [BSU_BEACON_TYPE_DISCOVER]
== 1);
test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL]
- == 4);
+ == 5);
/* Upper layer receives it ? */
test_fail_unless (t.ul.beacon == t.sar.beacon);
test_fail_unless (t.ul.beacon->next);
@@ -154,6 +161,38 @@ test_case_bsu_process (test_t test)
blk_release_desc ((blk_t*) t.ul.beacon);
}
test_end;
+ test_begin (test, "Discover beacon: associated do not track discover")
+ {
+ bsu_beacon_t beacon;
+ bsu_test_create_beacon (&t, &beacon);
+ uint i;
+ t.mac_config.tei = 254;
+ bsu_update_sta_type_t type [] = { BSU_UPDATE_STA_TYPE_STA,
+ BSU_UPDATE_STA_TYPE_CCO };
+ for (i = 0; i < COUNT (type); i++)
+ {
+ bsu_update (&beacon, type[i]);
+ pb_beacon_t *b;
+ pbproc_tx_beacon_params_t btx;
+ pbproc_rx_beacon_params_t brx;
+ brx.snid = 0x3;
+ b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_DISCOVER,
+ &t.mac_config, &btx);
+ 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);
+ blk_release_desc ((blk_t*) b);
+ b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL,
+ &t.mac_config, &btx);
+ bsu_beacon_process (t.bsu, b, &brx);
+ avln = bsu_avln_get (t.bsu, beacon.vf.nid, brx.snid);
+ test_fail_unless (avln != NULL);
+ test_fail_unless (avln != t.bsu->sta_avln);
+ blk_release_desc ((blk_t*) b);
+ bsu_avln_remove (t.bsu, beacon.vf.nid, brx.snid);
+ }
+ }
+ test_end;
bsu_test_uninit (&t);
}