summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-01-10 18:29:49 +0100
committerNélio Laranjeiro2011-01-11 15:39:48 +0100
commit37bab195dc8b75e77dede1b8ea58741fbc256408 (patch)
treee49e7e738e80b01031e5885959345575021f12a9 /cesar
parentbeb25f77a358fbdf4a6060483df7799779da328a (diff)
cesar/cp/beacon: do not process beacon when net is unavailable, closes #2166
Diffstat (limited to 'cesar')
-rw-r--r--cesar/cp/beacon/src/beacon.c173
-rw-r--r--cesar/cp/beacon/test/src/beacon.c54
2 files changed, 150 insertions, 77 deletions
diff --git a/cesar/cp/beacon/src/beacon.c b/cesar/cp/beacon/src/beacon.c
index 99807dfa91..2cb10ed63f 100644
--- a/cesar/cp/beacon/src/beacon.c
+++ b/cesar/cp/beacon/src/beacon.c
@@ -638,97 +638,116 @@ cp_beacon_get_and_process_beacon (cp_t *ctx)
beacon->params.rx_parameters.snid, beacon->vf.stei,
beacon->vf.bt, beacon->params.rx_parameters.bts);
/** Add network and station info to local data. */
- net = cp_sta_mgr_add_avln (ctx, beacon->params.rx_parameters.snid,
- beacon->vf.nid);
- net->hm = beacon->vf.hm;
- net->avln_num_slots = beacon->vf.numslots;
- cp_net_set_access (ctx, net, beacon->params.rx_parameters.access);
- cp_net_set_slot_id_and_usage (ctx, net, beacon->vf.slotid,
- beacon->vf.slotusage);
- sta = cp_beacon_update_sta_peer (ctx, beacon, net);
- /** Our station is associated and the beacon is from our CCo. */
- own = cp_sta_mgr_get_sta_own_data (ctx);
- if (beacon->vf.bt == BSU_BEACON_TYPE_CENTRAL
- && beacon->vf.nid == own->nid_track
- && beacon->vf.stei == own->tei_track
- && beacon->params.rx_parameters.snid
- == cp_sta_own_data_get_snid (ctx))
+ net = cp_sta_mgr_add_avln (
+ ctx, beacon->params.rx_parameters.snid, beacon->vf.nid);
+ /** If no NET object available, do not process this beacon.
+ * This can happen on SNID conflict when some AVLN are powered on at
+ * the time, the SNID conflict will cause the CP to create a net
+ * object for each new tuple of {nid, snid}. STA mgr garbage should
+ * resolve the problem by removing the old AVLN but it takes its
+ * time. */
+ if (net)
{
- if (ctx->beacon.spoc_update_interval_ms
- && less_mod2p32 (ctx->beacon.spoc_update_date, phy_date ()))
+ net->hm = beacon->vf.hm;
+ net->avln_num_slots = beacon->vf.numslots;
+ cp_net_set_access (ctx, net, beacon->params.rx_parameters.access);
+ cp_net_set_slot_id_and_usage (ctx, net, beacon->vf.slotid,
+ beacon->vf.slotusage);
+ dbg_assert (beacon->vf.stei == MAC_TEI_UNASSOCIATED
+ || MAC_TEI_IS_STA (beacon->vf.stei));
+ sta = cp_beacon_update_sta_peer (ctx, beacon, net);
+ /** Our station is associated and the beacon is from our CCo. */
+ own = cp_sta_mgr_get_sta_own_data (ctx);
+ if (beacon->vf.bt == BSU_BEACON_TYPE_CENTRAL
+ && beacon->vf.nid == own->nid_track
+ && beacon->vf.stei == own->tei_track
+ && beacon->params.rx_parameters.snid
+ == cp_sta_own_data_get_snid (ctx))
{
- cp_beacon_clk_sync_call_spoc (
- ctx, beacon->params.frequency_error);
- ctx->beacon.spoc_update_date = phy_date ()
- + MAC_MS_TO_TCK (ctx->beacon.spoc_update_interval_ms);
- CP_TRACE_VERBOSE (SPOC, beacon->params.frequency_error);
- }
- if (cp_sta_own_data_get_tei (ctx))
- {
- /* Update the countdowns. */
- if (beacon->bmis.change_snid.present)
- {
- ctx->beacon.snids.snidcd
- = beacon->bmis.change_snid.snidccd;
- ctx->beacon.snids.snid
- = beacon->bmis.change_snid.new_snid;
- }
- if (beacon->bmis.change_hm.present)
+ if (ctx->beacon.spoc_update_interval_ms
+ && less_mod2p32 (
+ ctx->beacon.spoc_update_date, phy_date ()))
{
- ctx->beacon.hm.hmcd = beacon->bmis.change_hm.hmccd;
- ctx->beacon.hm.hm = beacon->bmis.change_hm.newhm;
+ cp_beacon_clk_sync_call_spoc (
+ ctx, beacon->params.frequency_error);
+ ctx->beacon.spoc_update_date = phy_date ()
+ + MAC_MS_TO_TCK (ctx->beacon.spoc_update_interval_ms);
+ CP_TRACE_VERBOSE (SPOC, bsu_params->frequency_error);
}
- if (beacon->bmis.handover.present)
+ if (cp_sta_own_data_get_tei (ctx))
{
- ctx->beacon.hoip.hoipcd = beacon->bmis.handover.hcd;
- ctx->beacon.hoip.cco = beacon->bmis.handover.tei;
+ /* Update the countdowns. */
+ if (beacon->bmis.change_snid.present)
+ {
+ ctx->beacon.snids.snidcd
+ = beacon->bmis.change_snid.snidccd;
+ ctx->beacon.snids.snid
+ = beacon->bmis.change_snid.new_snid;
+ }
+ if (beacon->bmis.change_hm.present)
+ {
+ ctx->beacon.hm.hmcd =
+ beacon->bmis.change_hm.hmccd;
+ ctx->beacon.hm.hm = beacon->bmis.change_hm.newhm;
+ }
+ if (beacon->bmis.handover.present)
+ {
+ ctx->beacon.hoip.hoipcd =
+ beacon->bmis.handover.hcd;
+ ctx->beacon.hoip.cco = beacon->bmis.handover.tei;
+ }
+ if (beacon->bmis.eks.present)
+ {
+ ctx->beacon.eks.kccd = beacon->bmis.eks.kccd;
+ ctx->beacon.eks.kbc = beacon->bmis.eks.kbc;
+ ctx->beacon.eks.new_eks =
+ beacon->bmis.eks.new_eks;
+ }
+ /** Update the schedules. */
+ cp_beacon_sta_compute_schedules (ctx, beacon);
+ bsu_beacon_bmi_discover_info_t discover;
+ cp_beacon_fill_discover_info (ctx, &discover);
+ bsu_update_discover_info (&discover);
+ /** Program the timer. */
+ cp_beacon_reconfigure_timer (ctx, false);
}
- if (beacon->bmis.eks.present)
+ }
+ /* Discover beacons from our AVLN. */
+ else if (cp_sta_own_data_get_tei (ctx)
+ && beacon->vf.bt == BSU_BEACON_TYPE_DISCOVER
+ && beacon->vf.nid == cp_sta_own_data_get_nid (ctx)
+ && beacon->params.rx_parameters.snid
+ == cp_sta_own_data_get_snid (ctx))
+ {
+ bool updated = bitstream_direct_read (
+ &beacon->bmis.discover_info.info_data, 0, 1);
+ if (updated)
{
- ctx->beacon.eks.kccd = beacon->bmis.eks.kccd;
- ctx->beacon.eks.kbc = beacon->bmis.eks.kbc;
- ctx->beacon.eks.new_eks = beacon->bmis.eks.new_eks;
+ cp_fsm_event_t *event = cp_fsm_event_sta_new (
+ ctx, CP_FSM_EVENT_TYPE_discover_info_updated,
+ net, sta);
+ cp_fsm_post (ctx, event);
}
- /** Update the schedules. */
- cp_beacon_sta_compute_schedules (ctx, beacon);
- bsu_beacon_bmi_discover_info_t discover;
- cp_beacon_fill_discover_info (ctx, &discover);
- bsu_update_discover_info (&discover);
- /** Program the timer. */
- cp_beacon_reconfigure_timer (ctx, false);
}
- }
- /* Discover beacons from our AVLN. */
- else if (cp_sta_own_data_get_tei (ctx)
- && beacon->vf.bt == BSU_BEACON_TYPE_DISCOVER
- && beacon->vf.nid == cp_sta_own_data_get_nid (ctx)
- && beacon->params.rx_parameters.snid
- == cp_sta_own_data_get_snid (ctx))
- {
- bool updated = bitstream_direct_read (
- &beacon->bmis.discover_info.info_data, 0, 1);
- if (updated)
+ else if (cp_sta_own_data_get_cco_status (ctx))
{
- cp_fsm_event_t *event = cp_fsm_event_sta_new (
- ctx, CP_FSM_EVENT_TYPE_discover_info_updated, net, sta);
- cp_fsm_post (ctx, event);
+ /* Is the SNID in conflict. */
+ cp_net_t *our_net = cp_sta_mgr_get_our_avln (ctx);
+ if (our_net != net
+ && cp_net_get_snid (ctx, our_net)
+ == cp_net_get_snid (ctx, net)
+ && ctx->beacon.snids.snidcd == 0)
+ cp_fsm_post_new_event (ctx, bare, snid_conflict);
}
+ /** Raise the event in the FSM for station action. */
+ if (beacon->vf.bt == BSU_BEACON_TYPE_CENTRAL
+ || beacon->vf.bt == BSU_BEACON_TYPE_PROXY)
+ cp_fsm_post_new_event (
+ ctx, beacon, BEACON, beacon, net, sta);
+ slab_release (sta);
}
- /* Is the SNID in conflict. */
- else if (cp_sta_own_data_get_cco_status (ctx)
- && snid == cp_sta_own_data_get_snid (ctx)
- && ctx->beacon.snids.snidcd == 0)
- cp_fsm_post_new_event (ctx, bare, snid_conflict);
- /** Raise the event in the FSM for station action. */
- if (beacon->vf.bt == BSU_BEACON_TYPE_CENTRAL
- || beacon->vf.bt == BSU_BEACON_TYPE_PROXY)
- cp_fsm_post_new_event (ctx, beacon, BEACON,
- (bsu_beacon_t*) beacon, net, sta);
/** Release the beacon. */
blk_release (beacon);
- /** Release the station provided the function which processed the beacon.
- * cp_beacon_process_central_proxy or cp_beacon_process_discover. */
- slab_release (sta);
}
}
diff --git a/cesar/cp/beacon/test/src/beacon.c b/cesar/cp/beacon/test/src/beacon.c
index 8547a87722..f021411afe 100644
--- a/cesar/cp/beacon/test/src/beacon.c
+++ b/cesar/cp/beacon/test/src/beacon.c
@@ -1337,6 +1337,59 @@ test_suite_beacon_mac_address_bentry (test_t test)
}
+void
+test_suite_beacon_no_net (test_t t)
+{
+ test_suite_begin (t, "No net for beacon processing");
+ test_case_begin (t, "Beacon process");
+ test_begin (t, "let's go")
+ {
+ bsu_aclf_t aclf;
+ cp_t cp;
+ cp_cco_region_alloc_t *region;
+ cp_cco_bw_alloc_t *alloc;
+ bsu_beacon_t *beacon = blk_alloc ();
+ uint i;
+ memset (&cp, 0, sizeof (cp_t));
+ cp.bsu_aclf = &aclf;
+ cp_sta_mgr_init (&cp);
+ cp_beacon_init (&cp);
+ cp_cco_region_init (&cp);
+ cp_cco_bw_init (&cp);
+ aclf.beacon_period = BSU_ACLF_BP_50HZ_TCK;
+ /* Regions. */
+ region = cp_cco_region_alloc_init (&cp);
+ region->type = CP_BEACON_REGION_TYPE_SHARED_CSMA;
+ region->end_time_atu = 3907;
+ cp_cco_region_alloc_add (&cp, &cp.region.region_list, region);
+ slab_release (region);
+ /* Schedules. */
+ alloc = cp_cco_bw_alloc_init (&cp);
+ alloc->pscd = 7;
+ alloc->cscd = 7;
+ alloc->stpf = false;
+ alloc->glid = 0x45;
+ alloc->end_time_atu = 3907;
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_PERSISTENT;
+ cp_cco_bw_alloc_add (&cp, &cp.bw.alloc_list, alloc);
+ slab_release (alloc);
+ cp_beacon_fill (&cp, beacon);
+ for (i = 0; i < HPAV_AVLNS_NB_MAX; i++)
+ cp_sta_mgr_add_avln (&cp, i + 1, i);
+ test_fail_unless (!cp_sta_mgr_add_avln (&cp, 15, 30));
+ beacon->params.rx_parameters.snid = 0xf;
+ beacon->vf.nid = 0x1234;
+ beacon->params.direction = BSU_BEACON_DIRECTION_FROM_PLC;
+ cp_beacon_receive (&cp, beacon);
+ cp_beacon_get_and_process_beacon (&cp);
+ test_fail_unless (!cp_sta_mgr_get_avln (&cp, 15, 30));
+ cp_cco_bw_uninit (&cp);
+ cp_cco_region_uninit (&cp);
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
int
main (void)
{
@@ -1351,6 +1404,7 @@ main (void)
test_suite_beacon_hm_change (test);
test_suite_beacon_eks_change (test);
test_suite_beacon_mac_address_bentry (test);
+ test_suite_beacon_no_net (test);
test_case_begin (test, "Memory allocation");
test_begin (test, "memory leaks")