summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorYacine Belkadi2013-04-02 17:38:42 +0200
committerYacine Belkadi2013-05-22 10:53:37 +0200
commit46b9d84d9dfca1a27cea6f3b85af148cd72a2434 (patch)
treeed6cf26bf8bbb5a634b6ce758d7fad484160d271 /cesar
parent21ef1bf39c7cbbeff2c333e74b24c8ad426006e3 (diff)
cesar/{bsu,cp}/beacon: make bsu send a fake beacon to cp when no beacon is received
On a Sta, when an expected beacon is not received, make the bsu send a fake beacon to the cp. This allows the bsu to communicate with the cp when no beacon is received, and will be used in following commits.
Diffstat (limited to 'cesar')
-rw-r--r--cesar/bsu/beacon/beacon.h2
-rw-r--r--cesar/bsu/src/bsu.c17
-rw-r--r--cesar/bsu/test/utest/src/bsut.c62
-rw-r--r--cesar/cp/beacon/src/beacon.c37
4 files changed, 110 insertions, 8 deletions
diff --git a/cesar/bsu/beacon/beacon.h b/cesar/bsu/beacon/beacon.h
index dbaa5eb785..677bc399c7 100644
--- a/cesar/bsu/beacon/beacon.h
+++ b/cesar/bsu/beacon/beacon.h
@@ -29,6 +29,8 @@ enum bsu_beacon_direction_t
{
BSU_BEACON_DIRECTION_TO_PLC,
BSU_BEACON_DIRECTION_FROM_PLC,
+ /* Fake beacon used by the bsu to pass info to the cp. */
+ BSU_BEACON_DIRECTION_FROM_BSU,
BSU_BEACON_DIRECTION_NB
};
typedef enum bsu_beacon_direction_t bsu_beacon_direction_t;
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index 72557a80db..68e4c9d206 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -788,6 +788,21 @@ bsu_beacon_send_prepare (bsu_t *ctx, bsu_beacon_type_t type,
}
/**
+ * Inform upper layers (cp, in particular) that an expected beacon was not
+ * received, and use a fake beacon to pass any needed information.
+ * \param ctx bsu context.
+ */
+static void
+bsu_beacon_inform_beacon_not_received (bsu_t *ctx)
+{
+ /* Send a fake beacon to the cp. */
+ bsu_beacon_t *fake_beacon = blk_alloc ();
+ dbg_assert (fake_beacon);
+ bsu_beacon_send_upper_layer (ctx, fake_beacon,
+ BSU_BEACON_DIRECTION_FROM_BSU);
+}
+
+/**
* Handle the timer as STA.
* \param ctx the module context.
*/
@@ -838,6 +853,8 @@ bsu_timer_event_process__sta (bsu_t *ctx)
{
bsu_avln_schedules_decrease_countdown (ctx, ctx->sta_avln);
ctx->sta_avln->beacon.beacon_period_start_date = bpsd0;
+
+ bsu_beacon_inform_beacon_not_received (ctx);
}
}
}
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index e82cb6b761..0edc94d8c3 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -641,6 +641,8 @@ test_case_bsu_timer_event_cco_ucco (test_t test, bsu_test_t *t,
cmp_avln.beacon.vf.nm = MAC_NM_UNCOORDINATED;
bsu_timer_event_process (t->bsu);
test_fail_unless (t->ul.beacon != INVALID_PTR);
+ test_fail_unless (t->ul.beacon->params.direction
+ == BSU_BEACON_DIRECTION_TO_PLC);
test_fail_unless (t->ul.beacon->next == NULL);
/* Release the reference handled by the CP. */
blk_release (t->ul.beacon);
@@ -660,6 +662,8 @@ test_case_bsu_timer_event_cco_ucco (test_t test, bsu_test_t *t,
bsu_avln_schedules_decrease_countdown (t->bsu, &cmp_avln);
bsu_timer_event_process (t->bsu);
test_fail_unless (t->ul.beacon != INVALID_PTR);
+ test_fail_unless (t->ul.beacon->params.direction
+ == BSU_BEACON_DIRECTION_TO_PLC);
blk_release (t->ul.beacon);
for (j = 0; j < cmp_avln.beacon.bmis.ps.nb; j++)
{
@@ -720,10 +724,64 @@ test_case_bsu_timer_event (test_t test)
test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].cscd
== cmp_avln.beacon.bmis.ps.ps[i].cscd);
}
+ /* Fake beacon sent to the upper layer (i.e. the cp)? */
+ test_fail_unless (t.ul.beacon != INVALID_PTR);
+ test_fail_unless (t.ul.beacon->params.direction
+ == BSU_BEACON_DIRECTION_FROM_BSU);
+ blk_release (t.ul.beacon);
+ t.ul.beacon = INVALID_PTR;
}
bsu_test_uninit (&t);
}
test_end;
+ test_begin (test, "STA:Fake beacon from bsu:PLC beacon received")
+ {
+ bsu_test_t t;
+ bsu_test_init (&t);
+ bsu_activate (t.bsu, true);
+ bsu_beacon_t beacon;
+ bsu_test_create_beacon (&t, &beacon);
+ bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA);
+ t.phy->phy_date = 0;
+ t.bsu->sta_avln->sync.init = true;
+
+ u32 bpsd0;
+ bsu_aclf_beacon_period_start_date (t.bsu->aclf, &bpsd0, 1);
+ t.bsu->sta_avln->beacon.beacon_period_start_date = bpsd0 + 1;
+
+ bsu_timer_event_process (t.bsu);
+
+ test_fail_unless (t.ul.beacon == INVALID_PTR);
+ bsu_test_uninit (&t);
+ }
+ test_end;
+ test_begin (test, "STA:Fake beacon from bsu:PLC beacon not received")
+ {
+ bsu_test_t t;
+ bsu_test_init (&t);
+ bsu_activate (t.bsu, true);
+ bsu_beacon_t beacon;
+ bsu_test_create_beacon (&t, &beacon);
+ bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA);
+ t.phy->phy_date = 0;
+ t.bsu->sta_avln->sync.init = true;
+
+ u32 bpsd0;
+ bsu_aclf_beacon_period_start_date (t.bsu->aclf, &bpsd0, 1);
+ t.bsu->sta_avln->beacon.beacon_period_start_date
+ = bpsd0 - t.bsu->aclf->beacon_period_tck;
+
+ bsu_timer_event_process (t.bsu);
+
+ test_fail_unless (t.ul.beacon != INVALID_PTR);
+ test_fail_unless (t.ul.beacon->params.direction
+ == BSU_BEACON_DIRECTION_FROM_BSU);
+
+ blk_release (t.ul.beacon);
+ t.ul.beacon = INVALID_PTR;
+ bsu_test_uninit (&t);
+ }
+ test_end;
test_begin (test, "CCo")
{
bsu_test_t t;
@@ -747,7 +805,11 @@ test_case_bsu_timer_event (test_t test)
t.bsu->is_sta = BSU_UPDATE_STA_TYPE_CCO;
bsu_timer_event_process (t.bsu);
test_fail_unless (t.ul.beacon);
+ test_fail_unless (t.ul.beacon->params.direction
+ == BSU_BEACON_DIRECTION_TO_PLC);
test_fail_unless (t.ul.beacon->next);
+ test_fail_unless (t.ul.beacon->next->params.direction
+ == BSU_BEACON_DIRECTION_TO_PLC);
blk_release (t.ul.beacon->next);
blk_release (t.ul.beacon);
mfs = mac_store_mfs_get (t.mac_store, true, true, false,
diff --git a/cesar/cp/beacon/src/beacon.c b/cesar/cp/beacon/src/beacon.c
index f509711638..bb1c34270f 100644
--- a/cesar/cp/beacon/src/beacon.c
+++ b/cesar/cp/beacon/src/beacon.c
@@ -260,7 +260,8 @@ cp_beacon_receive (void *ul, bsu_beacon_t *beacon)
dbg_assert (ul);
dbg_assert (beacon);
interface_beacon (ctx->interface, beacon);
- if (beacon->params.direction == BSU_BEACON_DIRECTION_FROM_PLC)
+ if (beacon->params.direction == BSU_BEACON_DIRECTION_FROM_PLC
+ || beacon->params.direction == BSU_BEACON_DIRECTION_FROM_BSU)
{
beacon->next = NULL;
slist_push_back (ctx->beacon.list., beacon, bare);
@@ -605,6 +606,19 @@ cp_beacon_process_bmi_eks (cp_t *ctx, const bsu_beacon_t *beacon)
}
/**
+ * Handle the non-reception of a beacon, as reported by the bsu which sends a
+ * fake one.
+ * \param ctx cp context.
+ * \param fake_beacon A fake beacon.
+ */
+static void
+cp_beacon__bsu_inform__beacon_not_received (cp_t *ctx,
+ const bsu_beacon_t *fake_beacon)
+{
+ dbg_assert (!cp_sta_own_data_get_cco_status (ctx));
+}
+
+/**
* Process the first beacon in the received list.
* \param ctx the control plane context.
*/
@@ -622,13 +636,20 @@ cp_beacon_get_and_process_beacon (cp_t *ctx)
arch_dsr_lock ();
beacon = slist_pop_front (ctx->beacon.list., bare);
arch_dsr_unlock ();
- /** Beacon received ok. */
- GPIO_TOGGLE (LED_BEACON_TX_RX);
- CP_TRACE_VERBOSE (
- BEACON_BEACON_PROCESS, phy_date(), beacon->vf.nid,
- beacon->params.rx_parameters.snid, beacon->vf.stei,
- beacon->vf.bt, beacon->params.rx_parameters.bts);
- cp_beacon_process_beacon (ctx, beacon);
+ if (beacon->params.direction == BSU_BEACON_DIRECTION_FROM_BSU)
+ {
+ cp_beacon__bsu_inform__beacon_not_received (ctx, beacon);
+ }
+ else
+ {
+ /** Beacon received ok. */
+ GPIO_TOGGLE (LED_BEACON_TX_RX);
+ CP_TRACE_VERBOSE (
+ BEACON_BEACON_PROCESS, phy_date(), beacon->vf.nid,
+ beacon->params.rx_parameters.snid, beacon->vf.stei,
+ beacon->vf.bt, beacon->params.rx_parameters.bts);
+ cp_beacon_process_beacon (ctx, beacon);
+ }
/** Release the beacon. */
blk_release (beacon);
}