summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-10-17 14:47:27 +0200
committerNélio Laranjeiro2011-11-02 17:47:55 +0100
commit761ae5d824480fe15741b38c33ae7be58dd97d77 (patch)
treef71ac6c0c947ddc6f386c18a085dd4d64bf7441e
parentdae00d4fd8fa295efeef5c4a207d359ee8b60547 (diff)
cesar/cp/sta/action: avoid getting the CCo if it does not exists, closes #2787
When an authenticated STA leaves the AVLN it must send a CC_LEAVE.REQ message to the CCo. But if no CCo is present it should leave silently. This avoids a handover failure on the CCo to assert if no new CCo has been elected.
-rw-r--r--cesar/cp/fsm/src/fsm/cp.fsm4
-rw-r--r--cesar/cp/sta/action/src/assoc.c35
-rw-r--r--cesar/cp/sta/action/test/utest/src/assoc.c25
3 files changed, 53 insertions, 11 deletions
diff --git a/cesar/cp/fsm/src/fsm/cp.fsm b/cesar/cp/fsm/src/fsm/cp.fsm
index 884a60ef19..5b7a420970 100644
--- a/cesar/cp/fsm/src/fsm/cp.fsm
+++ b/cesar/cp/fsm/src/fsm/cp.fsm
@@ -319,8 +319,10 @@ AUTHENTICATED:
CM_SET_KEY_REQ_PID1 -> . [cp_sta_action_assoc__authenticated__cm_set_key_req_pid_1]
send CM_SET_KEY.CNF
CM_GET_KEY_CNF_PID1 -> . [cp_sta_action_assoc__authenticated__cm_get_key_cnf_pid_1]
- to_leave -> LEAVING [cp_sta_action_assoc__authenticated__to_leave]
+ to_leave:cco -> LEAVING [cp_sta_action_assoc__authenticated__to_leave]
send CC_LEAVE.REQ
+ to_leave:no_cco -> UNASSOCIATED
+ No CCo is present to send a CC_LEAVE.REQ MME.
CC_LEAVE_IND: ok -> LEAVE_WAIT [cp_sta_action_assoc__authenticated__cc_leave_ind]
send CC_LEAVE.RSP
CC_LEAVE_IND: nok -> .
diff --git a/cesar/cp/sta/action/src/assoc.c b/cesar/cp/sta/action/src/assoc.c
index ab17d149d2..97516b8e61 100644
--- a/cesar/cp/sta/action/src/assoc.c
+++ b/cesar/cp/sta/action/src/assoc.c
@@ -667,16 +667,31 @@ cp_sta_action_assoc__authenticated__to_leave (cp_t *ctx)
dbg_assert (ctx);
/* Get our CCo. */
cp_net_t *our_net = cp_sta_mgr_get_our_avln (ctx);
- cp_mme_peer_t peer;
- cp_net_get_cco_peer (ctx, our_net, &peer);
- /* Start timer. */
- cp_fsm_event_t *event = cp_fsm_event_bare_new (
- ctx, CP_FSM_EVENT_TYPE_assoc_timeout);
- cp_sta_core_gen_timed_event (ctx, &ctx->sta_action.assoc.timer, event,
- LEAVING_TIMEOUT_MS);
- /* Send leave request. */
- cp_msg_cc_leave_req_send (ctx, &peer,
- CP_MSG_CC_LEAVE_REQ_REASON_USER_REQUEST);
+ /* If we were the CCo and we cannot provide the CCo role to another
+ * station (Handover failure because no station were authenticated in the
+ * AVLN) we must not send any MME to the CCo. */
+ cp_sta_t *cco = cp_net_get_cco (ctx, our_net);
+ if (cco)
+ {
+ cp_mme_peer_t peer;
+ cp_sta_get_peer (cco, &peer);
+ /* Start timer. */
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ ctx, CP_FSM_EVENT_TYPE_assoc_timeout);
+ cp_sta_core_gen_timed_event (ctx, &ctx->sta_action.assoc.timer, event,
+ LEAVING_TIMEOUT_MS);
+ /* Send leave request. */
+ cp_msg_cc_leave_req_send (ctx, &peer,
+ CP_MSG_CC_LEAVE_REQ_REASON_USER_REQUEST);
+ slab_release (cco);
+ /* Branch to the LEAVING state. */
+ cp_fsm_branch (ctx, AUTHENTICATED, to_leave, cco);
+ }
+ else
+ {
+ /* Branch to the UNASSOCIATED state. */
+ cp_fsm_branch (ctx, AUTHENTICATED, to_leave, no_cco);
+ }
}
void
diff --git a/cesar/cp/sta/action/test/utest/src/assoc.c b/cesar/cp/sta/action/test/utest/src/assoc.c
index a5925344ac..4b33e3492c 100644
--- a/cesar/cp/sta/action/test/utest/src/assoc.c
+++ b/cesar/cp/sta/action/test/utest/src/assoc.c
@@ -639,6 +639,9 @@ assoc_basic_test_cases (test_t t)
SCENARIO_EVENT (cp_msg_cc_leave_req_send, .peer = cco_peer,
.reason =
CP_MSG_CC_LEAVE_REQ_REASON_USER_REQUEST),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = CP_FSM_BRANCH (AUTHENTICATED, to_leave,
+ cco)),
SCENARIO_ACTION (assoc__leaving__cc_leave_cnf, .peer = cco_peer),
SCENARIO_EVENT (cp_msg_cc_leave_cnf_receive, .ok = true),
SCENARIO_EVENT (cp_sta_core_stop_timed_or_cyclic_event),
@@ -667,6 +670,9 @@ assoc_basic_test_cases (test_t t)
SCENARIO_EVENT (cp_msg_cc_leave_req_send, .peer = cco_peer,
.reason =
CP_MSG_CC_LEAVE_REQ_REASON_USER_REQUEST),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = CP_FSM_BRANCH (AUTHENTICATED, to_leave,
+ cco)),
/* Bad TEI. */
SCENARIO_ACTION (assoc__leaving__cc_leave_cnf,
.peer = CP_MME_PEER (cco_mac, 42)),
@@ -709,6 +715,9 @@ assoc_basic_test_cases (test_t t)
SCENARIO_EVENT (cp_msg_cc_leave_req_send, .peer = cco_peer,
.reason =
CP_MSG_CC_LEAVE_REQ_REASON_USER_REQUEST),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = CP_FSM_BRANCH (AUTHENTICATED, to_leave,
+ cco)),
/* Timeout. */
SCENARIO_ACTION (assoc__leaving__timeout),
SCENARIO_EVENT (cp_msg_cc_leave_req_send, .peer = cco_peer,
@@ -800,6 +809,22 @@ assoc_basic_test_cases (test_t t)
/* Cleanup. */
slab_release (cco);
test_sta_action_uninit (&ctx);
+ /* New test, the CCo does not exists. */
+ test_sta_action_init (&ctx);
+ test_sta_action_create_our_net (&ctx, 0x1, 0x0);
+ test_begin (t, "sta ok")
+ {
+ scenario_entry_t entries[] = {
+ /* Leave the AVLN. */
+ SCENARIO_ACTION (assoc__authenticated__to_leave),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = CP_FSM_BRANCH (AUTHENTICATED, to_leave,
+ no_cco)),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+ test_sta_action_uninit (&ctx);
}
void