summaryrefslogtreecommitdiff
path: root/cesar/cp/sta/action
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-10-10 16:41:53 +0200
committerNélio Laranjeiro2011-11-02 17:47:52 +0100
commit4241dc50675f72fcfd69cfd797bd4644ec4ca58b (patch)
tree3018cd05c4d720f0430a5ee4aea5c68b105d6bbc /cesar/cp/sta/action
parent12108fe759efb7e12d06f41120d7ca231d69626d (diff)
cesar/cp/sta/action: update btt time out function, refs #2770
On BTT timeout, station was only looking for unassociated stations and not for any associated station. The fix permits the station to look for associated and unassociated stations in the avln.
Diffstat (limited to 'cesar/cp/sta/action')
-rw-r--r--cesar/cp/sta/action/src/poweron.c91
-rw-r--r--cesar/cp/sta/action/test/utest/src/poweron.c34
2 files changed, 86 insertions, 39 deletions
diff --git a/cesar/cp/sta/action/src/poweron.c b/cesar/cp/sta/action/src/poweron.c
index 7c2982a98b..7352fafcb2 100644
--- a/cesar/cp/sta/action/src/poweron.c
+++ b/cesar/cp/sta/action/src/poweron.c
@@ -171,54 +171,69 @@ cp_sta_action_poweron__poweron__ustt_timeout (cp_t *ctx)
cp_sta_action_poweron_ustt_timeout (ctx, CP_USTA_IND_INTERVAL_MS);
}
+/**
+ * Search for the first USTA with the mac address lesser than our own mac
+ * address.
+ * \param ctx the module context.
+ * \param net the AVLN to search in.
+ * \return true if a station with a bigger mac address than our own mac
+ * address.
+ */
+static bool
+cp_sta_action_btt_timeout_usta_with_mac_bigger (cp_t *ctx, cp_net_t *net)
+{
+ cp_sta_t *sta;
+ bool sta_found = false;
+ mac_t rmac = MAC_REVERSE (cp_sta_own_data_get_mac_address (ctx));
+ for (sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_UNASSOC);
+ sta && !sta_found;
+ sta = cp_net_sta_get_next (ctx, net, sta))
+ {
+ if (sta->cco_cap > CP_CCO_LEVEL
+ || (sta->cco_cap == CP_CCO_LEVEL
+ && MAC_REVERSE (cp_sta_get_mac_address (sta)) > rmac))
+ sta_found = true;
+ }
+ return sta_found;
+}
+
void
cp_sta_action_poweron__poweron__btt_timeout (cp_t *ctx)
{
dbg_assert (ctx);
- if (cp_sta_mgr_net_list_is_empty (ctx))
+ bool iam_cco_on_my_nid = false, iam_cco_on_other_nid = true;
+ cp_nid_t nid = cp_sta_own_data_get_nid (ctx);
+ cp_net_t *net;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
{
- cp_cco_action_ucco_start (ctx);
- cp_fsm_branch (ctx, POWERON, btt_timeout, no_avln);
- }
- else
- {
- /* I can become CCo only if at least one unassociated STA is seen. */
- bool iam_cco = true, sta_seen = false;
- mac_t rmac = MAC_REVERSE (cp_sta_own_data_get_mac_address (ctx));
- /* Look for a net with a matching NID (XXX: sta_mgr interface could be
- * improved on this point). */
- cp_snid_t snid;
- cp_nid_t nid = cp_sta_own_data_get_nid (ctx);
- for (snid = 0; iam_cco && snid < 16; snid++)
+ /* Search for AVLN with our NID. */
+ if (cp_net_get_nid (ctx, net) == nid)
{
- /* For each matching net, look at unassociated STA. */
- cp_net_t *net = cp_sta_mgr_get_avln (ctx, snid, nid);
- if (!net)
- continue;
- cp_sta_t *sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_UNASSOC);
- if (sta)
- sta_seen = true;
- for (; sta; sta = cp_net_sta_get_next (ctx, net, sta))
- {
- if (sta->cco_cap > CP_CCO_LEVEL
- || (sta->cco_cap == CP_CCO_LEVEL
- && MAC_REVERSE (cp_sta_get_mac_address (sta)) > rmac))
- {
- iam_cco = false;
- /* Early stop, should release the STA. */
- slab_release (sta);
- break;
- }
- }
+ iam_cco_on_my_nid = iam_cco_on_other_nid =
+ !cp_sta_action_btt_timeout_usta_with_mac_bigger (
+ ctx, net)
+ && !net->num_associated_stas;
}
- if (iam_cco && sta_seen)
+ /* Search for AVLN with another NID. */
+ else if (iam_cco_on_other_nid)
{
- cp_cco_action_cco__unassoc_start (ctx);
- cp_fsm_branch (ctx, POWERON, btt_timeout, nid_match_cco);
+ iam_cco_on_other_nid = !net->num_associated_stas;
}
- else
- cp_fsm_branch (ctx, POWERON, btt_timeout, avln);
}
+ if (iam_cco_on_my_nid)
+ {
+ cp_cco_action_cco__unassoc_start (ctx);
+ cp_fsm_branch (ctx, POWERON, btt_timeout, nid_match_cco);
+ }
+ else if (iam_cco_on_other_nid)
+ {
+ cp_cco_action_ucco_start (ctx);
+ cp_fsm_branch (ctx, POWERON, btt_timeout, no_avln);
+ }
+ else
+ cp_fsm_branch (ctx, POWERON, btt_timeout, avln);
}
void
diff --git a/cesar/cp/sta/action/test/utest/src/poweron.c b/cesar/cp/sta/action/test/utest/src/poweron.c
index 28e3b3297e..db906af646 100644
--- a/cesar/cp/sta/action/test/utest/src/poweron.c
+++ b/cesar/cp/sta/action/test/utest/src/poweron.c
@@ -359,9 +359,10 @@ poweron_test_cases (test_t t)
slab_release (sta);
scenario_entry_t entries[] = {
SCENARIO_ACTION (poweron__poweron__btt_timeout),
+ SCENARIO_EVENT (cp_cco_action_ucco_start),
SCENARIO_EVENT (cp_fsm_branch,
.branch = CP_FSM_BRANCH (POWERON, btt_timeout,
- avln)),
+ no_avln)),
SCENARIO_END
};
scenario_run (t, entries, &globals);
@@ -414,6 +415,37 @@ poweron_test_cases (test_t t)
scenario_run (t, entries, &globals);
cp_sta_mgr_sta_remove_from_mac (cp, 0x012345678901ull);
} test_end;
+ /* AVLN NID match, CCo authenticated. */
+ test_begin (t, "cco authenticated")
+ {
+ sta = cp_sta_mgr_sta_add (cp, net, 1, 0x012345678901ull);
+ cp_net_set_cco (cp, net, 1);
+ slab_release (sta);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (poweron__poweron__btt_timeout),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = CP_FSM_BRANCH (POWERON, btt_timeout,
+ avln)),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ cp_sta_mgr_sta_remove_from_mac (cp, 0x012345678901ull);
+ } test_end;
+ /* AVLN NID match, Sta associated. */
+ test_begin (t, "Sta associated")
+ {
+ sta = cp_sta_mgr_sta_add (cp, net, 1, 0x012345678901ull);
+ slab_release (sta);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (poweron__poweron__btt_timeout),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = CP_FSM_BRANCH (POWERON, btt_timeout,
+ avln)),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ cp_sta_mgr_sta_remove_from_mac (cp, 0x012345678901ull);
+ } test_end;
/* USTA indication. */
test_case_begin (t, "usta usta ind");
test_sta_action_reset (&ctx);