summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
Diffstat (limited to 'cesar')
-rw-r--r--cesar/cp/av/fsm/src/fsm/cp.fsm45
-rw-r--r--cesar/cp/av/sta/action/Module2
-rw-r--r--cesar/cp/av/sta/action/action.h1
-rw-r--r--cesar/cp/av/sta/action/poweron_role_forced.h26
-rw-r--r--cesar/cp/av/sta/action/src/poweron.c36
-rw-r--r--cesar/cp/av/sta/action/src/poweron_role_forced.c31
-rw-r--r--cesar/cp/av/sta/action/test/utest/Makefile2
-rw-r--r--cesar/cp/av/sta/action/test/utest/inc/scenario_defs.h5
-rw-r--r--cesar/cp/av/sta/action/test/utest/src/drv.c10
-rw-r--r--cesar/cp/av/sta/action/test/utest/src/msg_stub.c2
-rw-r--r--cesar/cp/av/sta/action/test/utest/src/poweron.c46
-rw-r--r--cesar/cp/av/sta/action/test/utest/src/scenario_actions.c1
-rw-r--r--cesar/cp/av/sta/action/test/utest/src/test_sta_action.c1
-rw-r--r--cesar/cp/av/sta/mgr/src/sta_own_data.c2
-rw-r--r--cesar/cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm1
-rw-r--r--cesar/cp/eoc/fsm/src/fsm/cp_eoc_sta.fsm1
-rw-r--r--cesar/cp/msg/inc/msg_drv.h11
-rw-r--r--cesar/cp/msg/src/msg.c2
-rw-r--r--cesar/cp/msg/src/msg_drv.c17
-rw-r--r--cesar/cp/msg/stub/src/msg_drv.c11
-rw-r--r--cesar/cp/sta/action/drv.h10
-rw-r--r--cesar/cp/sta/action/src/drv.c26
-rw-r--r--cesar/cp/sta/action/stub/src/drv.c7
-rw-r--r--cesar/cp/sta/mgr/sta_own_data.h4
-rw-r--r--cesar/mac/common/defs.h10
-rw-r--r--cesar/maximus/python/maximus/station/config.py14
-rw-r--r--cesar/maximus/python/maximus/station/sta.py62
-rw-r--r--cesar/maximus/python/tools/csi/csiavln.py5
-rw-r--r--cesar/maximus/python/tools/csi/csistation.py7
-rw-r--r--cesar/test_general/station/scenario/av/Makefile3
-rw-r--r--cesar/test_general/station/scenario/av/py/sc16_force_role.py86
31 files changed, 449 insertions, 38 deletions
diff --git a/cesar/cp/av/fsm/src/fsm/cp.fsm b/cesar/cp/av/fsm/src/fsm/cp.fsm
index c3dee770b8..9ed8148fe8 100644
--- a/cesar/cp/av/fsm/src/fsm/cp.fsm
+++ b/cesar/cp/av/fsm/src/fsm/cp.fsm
@@ -47,6 +47,12 @@ States:
CCO_LEAVING_HOIP
UNASSOCIATING [enter=cp_av_sta_action_unassoc__unassoc__enter]
+ STA_FORCED
+ Same as STA, without simple connect & Homeplug AV poweron process.
+ CCO_FORCED [enter=cp_av_cco_action_ucco_start]
+ Same as CCO, without simple connect & Homeplug AV poweron process.
+ CCO_FORCED_STOPPING
+
SC_USTA
Same as USTA, but the STA is doing SC procedure at the same time.
SC_USTA_JOINING
@@ -119,6 +125,7 @@ Events:
DRV_STA_SC_REQ
DRV_STA_SET_KEY_REQ
DRV_STA_SET_DAK_REQ
+ DRV_STA_FORCE_ROLE_REQ
DRV_STA_GET_KEY_REQ
DRV_STA_STATUS_REQ
DRV_STA_SET_CONFIG_REQ
@@ -366,6 +373,7 @@ STOPPED:
DRV_STA_SET_TONEMASK_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_tonemask_req]
DRV_STA_SET_KEY_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_key_req]
DRV_STA_SET_DAK_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_dak_req]
+ DRV_STA_FORCE_ROLE_REQ -> . [cp_sta_action_drv__stopped__drv_sta_force_role_req]
DRV_STA_MAC_START_REQ -> STARTED [cp_sta_action_drv__stopped__drv_sta_mac_start_req]
send DRV_STA_MAC_START.CNF
DRV_STA_GET_KEY_REQ -> . [cp_sta_action_drv__drv_sta_get_key_req]
@@ -418,7 +426,9 @@ STOPPING:
sta_status_changed -> . [cp_sta_action_drv__drv_sta_status_ind_send]
IDLE:
- to_poweron -> POWERON [cp_sta_action_poweron__idle__to_poweron]
+ to_poweron: homeplug_av -> POWERON [cp_sta_action_poweron__idle__to_poweron]
+ to_poweron: cco_forced -> CCO_FORCED
+ to_poweron: sta_forced -> STA_FORCED
POWERON:
BEACON_TIMER_EXPIRES -> . [cp_beacon_beacon_not_received]
@@ -505,6 +515,13 @@ SC_UCCO:
CC_ASSOC_REQ:nok -> . [cp_av_cco_action_sc_ucco__cc_assoc_req]
CC_ASSOC_REQ:ok -> CCO
+STA_FORCED:
+ BEACON: nid match -> . [cp_av_sta_action_poweron__sta_forced__beacon]
+ BEACON: no nid match -> .
+ BEACON_TIMER_EXPIRES -> . [cp_beacon_beacon_not_received]
+ CC_WHO_RU_CNF -> . [cp_sta_action_process_cc_who_ru_cnf]
+ to_stop -> UNASSOCIATING [cp_av_sta_action_assoc_leave]
+
STA:
BEACON_TIMER_EXPIRES -> . [cp_beacon_beacon_not_received]
avln_failure -> POWERON [NULL]
@@ -527,8 +544,23 @@ SC_STA:
sc_failed -> STA [NULL]
sc_succeed -> STA [NULL]
-CCO:
+CCO_FORCED_STOPPING:
+ to_stop -> IDLE [cp_sta_action_poweron__many__to_idle]
+
+CCO_FORCED:
+ to_stop -> CCO_FORCED_STOPPING [cp_av_cco_action_ucco__to_stop]
+
+CCO_FORCED, CCO:
+ CC_WHO_RU_REQ -> . [cp_sta_action_process_cc_who_ru_req]
+ CC_ASSOC_REQ -> . [cp_av_cco_action_cco__cc_assoc_req]
+ CM_GET_KEY_REQ_PID0 -> . [cp_av_cco_action_cco__cm_get_key_req_pid0]
+ CM_GET_KEY_REQ_PID1 -> . [cp_av_cco_action_cco__cm_get_key_req_pid1]
+ CC_LEAVE_REQ -> . [cp_av_cco_action_cco__cc_leave_req]
BEACON_TIMER_EXPIRES -> . [cp_beacon_cco_update_beacon_data]
+ cco__nek_change -> . [cp_av_cco_action_cco__cco_nek_change]
+ cco__snid_conflict -> . [cp_av_cco_action_cco__cco_snid_conflict]
+
+CCO:
BEACON_WITH_SAME_NID -> . [cp_av_cco_action_beacon_with_same_nid]
join_timeout: sta -> . [cp_av_sta_action_poweron__cco__join_timeout]
join_timeout: no sta avln -> USTA
@@ -536,17 +568,8 @@ CCO:
cco__all_sta_leaved -> UCCO [cp_av_cco_action_cco__to_ucco]
to_stop -> CCO_LEAVING [cp_av_cco_action_drv_mac_stop]
discover_info_updated -> . [cp_av_cco_action_cco__cc_discover_list_req]
-
- cco__nek_change -> . [cp_av_cco_action_cco__cco_nek_change]
- cco__snid_conflict -> . [cp_av_cco_action_cco__cco_snid_conflict]
cco_leave_merge_avln -> USTA [cp_av_cco_action_cco__unassoc_stop]
- CC_WHO_RU_REQ -> . [cp_sta_action_process_cc_who_ru_req]
- CC_ASSOC_REQ -> . [cp_av_cco_action_cco__cc_assoc_req]
- CM_GET_KEY_REQ_PID0 -> . [cp_av_cco_action_cco__cm_get_key_req_pid0]
- CM_GET_KEY_REQ_PID1 -> . [cp_av_cco_action_cco__cm_get_key_req_pid1]
- CC_LEAVE_REQ -> . [cp_av_cco_action_cco__cc_leave_req]
-
HANDOVER_DISCOVER_PROCESS_DONE:sta -> HANDOVER_CCO [cp_av_cco_action_handover__discover_done]
HANDOVER_DISCOVER_PROCESS_DONE:no_sta -> .
diff --git a/cesar/cp/av/sta/action/Module b/cesar/cp/av/sta/action/Module
index 79370ecb2e..7642efc6cf 100644
--- a/cesar/cp/av/sta/action/Module
+++ b/cesar/cp/av/sta/action/Module
@@ -1,4 +1,4 @@
SOURCES := sc.c drv.c misc.c handover.c poweron.c action.c assoc.c info.c \
- key.c
+ key.c poweron_role_forced.c
MODULES := cp/sta/action
diff --git a/cesar/cp/av/sta/action/action.h b/cesar/cp/av/sta/action/action.h
index c230025749..7975f0595c 100644
--- a/cesar/cp/av/sta/action/action.h
+++ b/cesar/cp/av/sta/action/action.h
@@ -17,6 +17,7 @@
#include "cp/mme.h"
#include "cp/sta/action/action.h"
+#include "cp/av/sta/action/poweron_role_forced.h"
#include "cp/av/sta/action/sc.h"
#include "cp/av/sta/action/handover.h"
#include "cp/av/sta/action/poweron.h"
diff --git a/cesar/cp/av/sta/action/poweron_role_forced.h b/cesar/cp/av/sta/action/poweron_role_forced.h
new file mode 100644
index 0000000000..73ad773d06
--- /dev/null
+++ b/cesar/cp/av/sta/action/poweron_role_forced.h
@@ -0,0 +1,26 @@
+#ifndef cp_av_sta_action_poweron_role_forced_h
+#define cp_av_sta_action_poweron_role_forced_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/av/sta/action/poweron_role_forced.h
+ * \ingroup cp_av_sta_action
+ */
+#include "cp/inc/context.h"
+#include "bsu/bsu.h"
+
+BEGIN_DECLS
+
+void
+cp_av_sta_action_poweron__sta_forced__beacon (
+ cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+END_DECLS
+
+#endif /* cp_av_sta_action_poweron_role_forced_h */
diff --git a/cesar/cp/av/sta/action/src/poweron.c b/cesar/cp/av/sta/action/src/poweron.c
index 91a270cc6d..a46a86b892 100644
--- a/cesar/cp/av/sta/action/src/poweron.c
+++ b/cesar/cp/av/sta/action/src/poweron.c
@@ -54,6 +54,8 @@ cp_av_sta_action_poweron__many__to_idle (cp_t *ctx)
void
cp_av_sta_action_poweron__idle__to_poweron (cp_t *ctx)
{
+ cp_sta_own_data_t *own;
+
cp_beacon_poweron_init (ctx);
bsu_power_on (ctx->bsu, cp_sta_own_data_get_snid (ctx));
/* Update beacon data program a timer is a wrong values beacon ACLF is
@@ -62,6 +64,31 @@ cp_av_sta_action_poweron__idle__to_poweron (cp_t *ctx)
cp_beacon_reconfigure_timer (ctx, false);
sar_activate (ctx->sar, true);
pbproc_activate (ctx->pbproc, true);
+
+ if (ctx->sta_action.poweron.enter.need_set)
+ {
+ cp_sta_own_data_set_nid (ctx, ctx->sta_action.poweron.enter.nid);
+ cp_sta_own_data_set_nmk (ctx, ctx->sta_action.poweron.enter.nmk,
+ ctx->sta_action.poweron.enter.type);
+
+ ctx->sta_action.poweron.enter.need_set = false;
+ }
+
+ own = cp_sta_mgr_get_sta_own_data (ctx);
+ switch (own->force_role)
+ {
+ case MAC_FORCE_ROLE_STA:
+ cp_fsm_branch (ctx, IDLE, to_poweron, sta_forced);
+ break;
+
+ case MAC_FORCE_ROLE_CCO:
+ cp_fsm_branch (ctx, IDLE, to_poweron, cco_forced);
+ break;
+
+ default:
+ cp_fsm_branch (ctx, IDLE, to_poweron, homeplug_av);
+ break;
+ }
}
void
@@ -131,15 +158,6 @@ cp_av_sta_action_poweron__poweron__enter (cp_t *ctx)
/* USTT timer. */
cp_av_sta_action_poweron_ustt_start (ctx, CP_USTA_IND_INTERVAL_MS);
- if (ctx->sta_action.poweron.enter.need_set)
- {
- cp_sta_own_data_set_nid (ctx, ctx->sta_action.poweron.enter.nid);
- cp_sta_own_data_set_nmk (ctx, ctx->sta_action.poweron.enter.nmk,
- ctx->sta_action.poweron.enter.type);
-
- ctx->sta_action.poweron.enter.need_set = false;
- }
-
bsu_beacon_t beacon;
cp_beacon_fill (ctx, &beacon);
/* Act as STA, for BSU corresponds to only hear the central beacon from
diff --git a/cesar/cp/av/sta/action/src/poweron_role_forced.c b/cesar/cp/av/sta/action/src/poweron_role_forced.c
new file mode 100644
index 0000000000..b1b41e447c
--- /dev/null
+++ b/cesar/cp/av/sta/action/src/poweron_role_forced.c
@@ -0,0 +1,31 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/av/sta/action/src/poweron_role_forced.c
+ * \ingroup cp_av_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/av/sta/action/poweron_role_forced.h"
+#include "cp/fsm/fsm.h"
+#include "cp/av/sta/action/inc/action.h"
+
+void
+cp_av_sta_action_poweron__sta_forced__beacon (
+ cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ dbg_assert (ctx);
+ dbg_assert (beacon);
+ dbg_assert (net);
+ dbg_assert (sta);
+ cp_av_sta_action_beacon_match_and_join (
+ ctx, beacon, net, sta, false /* not in SC */,
+ CP_FSM_BRANCH (STA_FORCED, BEACON, nid_match),
+ CP_FSM_BRANCH (STA_FORCED, BEACON, no_nid_match));
+}
diff --git a/cesar/cp/av/sta/action/test/utest/Makefile b/cesar/cp/av/sta/action/test/utest/Makefile
index 78dfa099c6..604e38c8c2 100644
--- a/cesar/cp/av/sta/action/test/utest/Makefile
+++ b/cesar/cp/av/sta/action/test/utest/Makefile
@@ -4,7 +4,7 @@ INCLUDES = cp/av/sta/action/test/utest cp/av/sta/action/test/utest/override
HOST_PROGRAMS = test_sta_action
test_sta_action_SOURCES = test_sta_action.c assoc.c drv.c info.c key.c \
- bridge.c handover.c \
+ bridge.c handover.c poweron.c \
msg_stub.c dataplane_stub.c fsm_stub.c \
core_stub.c beacon_stub.c cp_stub.c \
cco_stub.c scenario_actions.c vs.c ce_stub.c \
diff --git a/cesar/cp/av/sta/action/test/utest/inc/scenario_defs.h b/cesar/cp/av/sta/action/test/utest/inc/scenario_defs.h
index 9253e17650..2b27bcbebd 100644
--- a/cesar/cp/av/sta/action/test/utest/inc/scenario_defs.h
+++ b/cesar/cp/av/sta/action/test/utest/inc/scenario_defs.h
@@ -75,6 +75,7 @@
drv__started__drv_sta_mac_stop_req, \
drv__stopping__stopped, \
drv__drv_sta_get_key_req, \
+ drv__stopped__drv_sta_force_role_req, \
drv__drv_sta_status_req, \
drv__drv_sta_set_config_req, \
drv__drv_mcast_set_list_req, \
@@ -248,6 +249,7 @@ __m (drv__stopped__drv_sta_mac_start_req)
__m (drv__stopped__drv_sta_set_key_req)
__m (drv__stopped__drv_sta_set_dak_req)
__m (drv__started__drv_sta_mac_stop_req)
+__m (drv__stopped__drv_sta_force_role_req)
__0 (drv__stopping__stopped)
__m (drv__drv_sta_get_key_req)
__m (drv__drv_sta_status_req)
@@ -424,6 +426,7 @@ __0 (whoru_timeout_process)
cp_msg_drv_sta_status_req_receive, \
cp_msg_drv_sta_status_cnf_send, \
cp_msg_drv_sta_status_ind_send, \
+ cp_msg_drv_sta_force_role_req_receive, \
cp_msg_drv_sta_set_config_req_receive, \
cp_msg_drv_mcast_set_list_req_receive, \
\
@@ -720,6 +723,8 @@ __ms (cp_msg_drv_sta_status_ind_send,
bool backup_cco,
bool simple_connect,
bsu_aclf_frequency_t pwl_sync_frequency)
+__mr (cp_msg_drv_sta_force_role_req_receive,
+ char force_role)
__mr (cp_msg_drv_sta_set_config_req_receive,
char *config)
__mr (cp_msg_drv_mcast_set_list_req_receive,
diff --git a/cesar/cp/av/sta/action/test/utest/src/drv.c b/cesar/cp/av/sta/action/test/utest/src/drv.c
index 9da1bb0fde..493f17b396 100644
--- a/cesar/cp/av/sta/action/test/utest/src/drv.c
+++ b/cesar/cp/av/sta/action/test/utest/src/drv.c
@@ -245,6 +245,16 @@ drv_basic_test_case (test_t t)
.result = CONFIG_STATS ?
CP_MSG_DRV_RESULT_SUCCESS:
CP_MSG_DRV_RESULT_FAILURE),
+ /* Force role. */
+ SCENARIO_ACTION (drv__stopped__drv_sta_force_role_req,
+ .peer = peer),
+ SCENARIO_EVENT (cp_msg_drv_sta_force_role_req_receive,
+ .ok = true,
+ .force_role = 0),
+ SCENARIO_EVENT (cp_msg_drv_any_cnf_send,
+ .peer = peer,
+ .mmtype = DRV_STA_FORCE_ROLE_CNF,
+ .result = CP_MSG_DRV_RESULT_SUCCESS),
SCENARIO_END
};
scenario_globals_t globals = {
diff --git a/cesar/cp/av/sta/action/test/utest/src/msg_stub.c b/cesar/cp/av/sta/action/test/utest/src/msg_stub.c
index 23f409be71..d816d85956 100644
--- a/cesar/cp/av/sta/action/test/utest/src/msg_stub.c
+++ b/cesar/cp/av/sta/action/test/utest/src/msg_stub.c
@@ -501,6 +501,8 @@ __msd (cp_msg_drv_sta_status_ind_send, cp_msg_drv_sta_status_t,
(bool, backup_cco, assign),
(bool, simple_connect, assign),
(bsu_aclf_frequency_t, pwl_sync_frequency, assign))
+__mr (cp_msg_drv_sta_force_role_req_receive,
+ (char, force_role, assign))
__mr (cp_msg_drv_sta_set_config_req_receive,
(char *, config, string))
__mr (cp_msg_drv_mcast_set_list_req_receive,
diff --git a/cesar/cp/av/sta/action/test/utest/src/poweron.c b/cesar/cp/av/sta/action/test/utest/src/poweron.c
index 49df7066d9..e45dd844ba 100644
--- a/cesar/cp/av/sta/action/test/utest/src/poweron.c
+++ b/cesar/cp/av/sta/action/test/utest/src/poweron.c
@@ -28,6 +28,7 @@ poweron_test_cases (test_t t)
cp_nid_t nid = 0x111111111111ull;
cp_net_t *net = NULL;
cp_sta_t *sta = NULL;
+ cp_sta_own_data_t *own = NULL;
bsu_beacon_t beacon;
test_sta_action_beacon_create (&beacon, nid, 0, 1, 0);
/* Poweron start. */
@@ -35,20 +36,43 @@ poweron_test_cases (test_t t)
test_sta_action_reset (&ctx);
cp_av_sta_action_init (cp);
+ own = cp_sta_mgr_get_sta_own_data (cp);
+
test_begin (t, "start")
{
- scenario_entry_t entries[] = {
- SCENARIO_ACTION (poweron_start),
- SCENARIO_EVENT (cp_fsm_event_bare_new,
- .type = CP_FSM_EVENT_TYPE_to_poweron),
- SCENARIO_ACTION (poweron__idle__to_poweron),
- SCENARIO_EVENT (cp_beacon_reconfigure_timer),
- SCENARIO_EVENT (sar_activate, .flag = true),
- SCENARIO_EVENT (pbproc_activate, .flag = true),
- SCENARIO_END
- };
- scenario_run (t, entries, &globals);
+ for (own->force_role = MAC_FORCE_ROLE_AUTO;
+ own->force_role < MAC_FORCE_ROLE_NB;
+ own->force_role ++)
+ {
+ cp_fsm_branch_t branch_to;
+
+ if (own->force_role == MAC_FORCE_ROLE_AUTO)
+ branch_to = CP_FSM_BRANCH (IDLE, to_poweron,
+ homeplug_av);
+ else if (own->force_role == MAC_FORCE_ROLE_CCO)
+ branch_to = CP_FSM_BRANCH (IDLE, to_poweron,
+ cco_forced);
+ else if (own->force_role == MAC_FORCE_ROLE_STA)
+ branch_to = CP_FSM_BRANCH (IDLE, to_poweron,
+ sta_forced);
+
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (poweron_start),
+ SCENARIO_EVENT (cp_fsm_event_bare_new,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_ACTION (poweron__idle__to_poweron),
+ SCENARIO_EVENT (cp_beacon_reconfigure_timer),
+ SCENARIO_EVENT (sar_activate, .flag = true),
+ SCENARIO_EVENT (pbproc_activate, .flag = true),
+ SCENARIO_EVENT (cp_fsm_branch,
+ .branch = branch_to),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ }
+
} test_end;
+ own->force_role = MAC_FORCE_ROLE_AUTO;
/* POWERON timers. */
test_case_begin (t, "poweron");
test_sta_action_reset (&ctx);
diff --git a/cesar/cp/av/sta/action/test/utest/src/scenario_actions.c b/cesar/cp/av/sta/action/test/utest/src/scenario_actions.c
index 56eb47677d..f141f484f3 100644
--- a/cesar/cp/av/sta/action/test/utest/src/scenario_actions.c
+++ b/cesar/cp/av/sta/action/test/utest/src/scenario_actions.c
@@ -152,6 +152,7 @@ __m (drv__stopped__drv_sta_mac_start_req)
__m (drv__started__drv_sta_mac_stop_req)
__m (drv__stopped__drv_sta_set_key_req)
__m (drv__stopped__drv_sta_set_dak_req)
+__m (drv__stopped__drv_sta_force_role_req)
__0 (drv__stopping__stopped)
__m (drv__drv_sta_get_key_req)
__m (drv__drv_sta_status_req)
diff --git a/cesar/cp/av/sta/action/test/utest/src/test_sta_action.c b/cesar/cp/av/sta/action/test/utest/src/test_sta_action.c
index 2cec42d3b9..3980ceda77 100644
--- a/cesar/cp/av/sta/action/test/utest/src/test_sta_action.c
+++ b/cesar/cp/av/sta/action/test/utest/src/test_sta_action.c
@@ -110,6 +110,7 @@ main (int argc, char **argv)
vs_test_suite (t);
bridge_test_suite (t);
handover_test_suite (t);
+ poweron_test_suite (t);
test_result (t);
return test_nb_failed (t) == 0 ? 0 : 1;
}
diff --git a/cesar/cp/av/sta/mgr/src/sta_own_data.c b/cesar/cp/av/sta/mgr/src/sta_own_data.c
index 373d696797..ecd63ae118 100644
--- a/cesar/cp/av/sta/mgr/src/sta_own_data.c
+++ b/cesar/cp/av/sta/mgr/src/sta_own_data.c
@@ -56,6 +56,8 @@ cp_av_sta_own_data_init (cp_t *ctx)
dbg_assert (ctx);
memset (&ctx->sta_mgr.sta_own_data, 0,
sizeof (cp_sta_own_data_private_t));
+ ctx->sta_mgr.sta_own_data.public.force_role =
+ MAC_FORCE_ROLE_AUTO;
/* Store the hybrid mode. */
ctx->sta_mgr.sta_own_data.public.hybrid_mode =
MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE;
diff --git a/cesar/cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm b/cesar/cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm
index 8cc1b04667..94e305ad51 100644
--- a/cesar/cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm
+++ b/cesar/cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm
@@ -59,6 +59,7 @@ Events:
DRV_EOC_STA_SET_SLAVE_CONFIG_REQ
DRV_EOC_STA_SET_EOC_CONFIG_REQ
DRV_MCAST_SET_LIST_REQ
+ DRV_STA_FORCE_ROLE_REQ
VS_GET_TONEMAP_REQ
VS_GET_SNR_REQ
diff --git a/cesar/cp/eoc/fsm/src/fsm/cp_eoc_sta.fsm b/cesar/cp/eoc/fsm/src/fsm/cp_eoc_sta.fsm
index 42402143a6..c60b92f202 100644
--- a/cesar/cp/eoc/fsm/src/fsm/cp_eoc_sta.fsm
+++ b/cesar/cp/eoc/fsm/src/fsm/cp_eoc_sta.fsm
@@ -64,6 +64,7 @@ Events:
DRV_EOC_STA_SET_SLAVE_CONFIG_REQ
DRV_EOC_STA_SET_EOC_CONFIG_REQ
DRV_MCAST_SET_LIST_REQ
+ DRV_STA_FORCE_ROLE_REQ
VS_GET_TONEMAP_REQ
VS_GET_SNR_REQ
diff --git a/cesar/cp/msg/inc/msg_drv.h b/cesar/cp/msg/inc/msg_drv.h
index a9cd65f8c6..854b64f6ab 100644
--- a/cesar/cp/msg/inc/msg_drv.h
+++ b/cesar/cp/msg/inc/msg_drv.h
@@ -267,6 +267,17 @@ cp_msg_drv_sta_get_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
const cp_msg_drv_sta_get_key_t *data);
/**
+ * Receives a DRV_STA_FORCE_ROLE.REQ.
+ * \param ctx control plane context.
+ * \param mme MME to handle.
+ * \param force_role unique data received.
+ * \return true on success.
+ */
+bool
+cp_msg_drv_sta_force_role_req_receive (
+ cp_t *ctx, cp_mme_rx_t *mme, char *force_role);
+
+/**
* Receive a DRV_STA_STATUS.REQ.
* \param ctx control plane context.
* \param mme MME to handle.
diff --git a/cesar/cp/msg/src/msg.c b/cesar/cp/msg/src/msg.c
index c59a038f53..9037f44854 100644
--- a/cesar/cp/msg/src/msg.c
+++ b/cesar/cp/msg/src/msg.c
@@ -308,6 +308,8 @@ cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
CP_MSG_MME_ALLOWED_ENTRY (DRV_EOC_STA_SET_EOC_CONFIG_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_EOC_STA_SET_EOC_CONFIG_REQ),
CP_MSG_MME_ALLOWED_ENTRY (DRV_EOC_STA_SET_EOC_CONFIG_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
#endif /* CONFIG_CP_EOC */
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_FORCE_ROLE_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_FORCE_ROLE_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_FORCE_ROLE_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
};
uint cp_msg_mme_allowed_count = COUNT (cp_msg_mme_allowed);
diff --git a/cesar/cp/msg/src/msg_drv.c b/cesar/cp/msg/src/msg_drv.c
index 4dba4b3f09..390af9b173 100644
--- a/cesar/cp/msg/src/msg_drv.c
+++ b/cesar/cp/msg/src/msg_drv.c
@@ -575,6 +575,23 @@ cp_msg_drv_sta_get_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
}
bool
+cp_msg_drv_sta_force_role_req_receive (
+ cp_t *ctx, cp_mme_rx_t *mme, char *force_role)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *force_role = bitstream_read (&mme->bitstream, 8);
+
+ if (*force_role < MAC_FORCE_ROLE_NB)
+ return true;
+ }
+ return false;
+}
+
+bool
cp_msg_drv_sta_status_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
{
dbg_assert (ctx);
diff --git a/cesar/cp/msg/stub/src/msg_drv.c b/cesar/cp/msg/stub/src/msg_drv.c
index 87ae57ab32..6b7b01431b 100644
--- a/cesar/cp/msg/stub/src/msg_drv.c
+++ b/cesar/cp/msg/stub/src/msg_drv.c
@@ -286,6 +286,17 @@ cp_msg_drv_sta_get_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
}
bool
+cp_msg_drv_sta_force_role_req_receive (
+ cp_t *ctx, cp_mme_rx_t *mme, char *force_role)
+ __attribute__((weak));
+bool
+cp_msg_drv_sta_force_role_req_receive (
+ cp_t *ctx, cp_mme_rx_t *mme, char *force_role)
+{
+ return true;
+}
+
+bool
cp_msg_drv_sta_status_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
__attribute__((weak));
bool
diff --git a/cesar/cp/sta/action/drv.h b/cesar/cp/sta/action/drv.h
index 829d2304dd..ae090f2dae 100644
--- a/cesar/cp/sta/action/drv.h
+++ b/cesar/cp/sta/action/drv.h
@@ -221,6 +221,16 @@ cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx, cp_mme_rx_t *mme);
void
cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * Common handler for DRV_STA_FORCE_ROLE.
+ * \param ctx control plane context.
+ * \param mme the MME to handle.
+ */
+void
+cp_sta_action_drv__stopped__drv_sta_force_role_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
/**
* Common handler for DRV_STA_STATUS.
* \param ctx control plane context.
diff --git a/cesar/cp/sta/action/src/drv.c b/cesar/cp/sta/action/src/drv.c
index 90239aeb03..36453f8ea4 100644
--- a/cesar/cp/sta/action/src/drv.c
+++ b/cesar/cp/sta/action/src/drv.c
@@ -283,6 +283,32 @@ cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
}
}
+void
+cp_sta_action_drv__stopped__drv_sta_force_role_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ char force_role;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_drv_sta_force_role_req_receive (
+ ctx, mme, &force_role))
+ {
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (ctx);
+
+ /* 'force_role' values in MME are the same as 'mac_force_role_t'. */
+ own->force_role = force_role;
+
+ cp_msg_drv_any_cnf_send (
+ ctx, &mme->peer, DRV_STA_FORCE_ROLE_CNF,
+ CP_MSG_DRV_RESULT_SUCCESS);
+ }
+ else
+ cp_msg_drv_any_cnf_send (
+ ctx, &mme->peer, DRV_STA_FORCE_ROLE_CNF,
+ CP_MSG_DRV_RESULT_FAILURE);
+}
+
/**
* Fill the data structure corresponding the station's status.
* \param ctx the control place context.
diff --git a/cesar/cp/sta/action/stub/src/drv.c b/cesar/cp/sta/action/stub/src/drv.c
index aba745f034..a65f18b19b 100644
--- a/cesar/cp/sta/action/stub/src/drv.c
+++ b/cesar/cp/sta/action/stub/src/drv.c
@@ -133,6 +133,13 @@ void
cp_sta_action_drv__drv_sta_status_req (cp_t *ctx, cp_mme_rx_t *mme) {}
void
+cp_sta_action_drv__stopped__drv_sta_force_role_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_sta_action_drv__stopped__drv_sta_force_role_req (
+ cp_t *ctx, cp_mme_rx_t *mme) {};
+
+void
cp_sta_action_drv__drv_sta_status_ind_send (cp_t *ctx) __attribute__ ((weak));
void
cp_sta_action_drv__drv_sta_status_ind_send (cp_t *ctx) {}
diff --git a/cesar/cp/sta/mgr/sta_own_data.h b/cesar/cp/sta/mgr/sta_own_data.h
index 952bc69040..c09f5c4d88 100644
--- a/cesar/cp/sta/mgr/sta_own_data.h
+++ b/cesar/cp/sta/mgr/sta_own_data.h
@@ -106,6 +106,10 @@ struct cp_sta_own_data_t
uint num_leave;
+ /*
+ * Current Force Role
+ */
+ mac_force_role_t force_role;
};
typedef struct cp_sta_own_data_t cp_sta_own_data_t;
diff --git a/cesar/mac/common/defs.h b/cesar/mac/common/defs.h
index f56806dc01..6fdf67966f 100644
--- a/cesar/mac/common/defs.h
+++ b/cesar/mac/common/defs.h
@@ -142,6 +142,16 @@ enum mac_coexistence_mode_t
};
typedef enum mac_coexistence_mode_t mac_coexistence_mode_t;
+/** Force role. */
+enum mac_force_role_t
+{
+ MAC_FORCE_ROLE_AUTO,
+ MAC_FORCE_ROLE_CCO,
+ MAC_FORCE_ROLE_STA,
+ MAC_FORCE_ROLE_NB,
+};
+typedef enum mac_force_role_t mac_force_role_t;
+
/** Network modes. */
enum mac_network_mode_t
{
diff --git a/cesar/maximus/python/maximus/station/config.py b/cesar/maximus/python/maximus/station/config.py
index 2b49a0b86b..630968c997 100644
--- a/cesar/maximus/python/maximus/station/config.py
+++ b/cesar/maximus/python/maximus/station/config.py
@@ -12,6 +12,7 @@ DEFAULT_M_STA_HFID = "M_STA_HFID_"
DEFAULT_U_STA_HFID = "U_STA_HFID_"
DEFAULT_AVLN_HFID = "AVLN_HomePlugAV0123"
DEFAULT_SL = 0
+DEFAULT_FORCE_ROLE = 0
DEFAULT_TONEMASK = 85,139,167,214,225,282,302,409,419,569,591,736,748,856,882,1015,1027,1143,1535
DEFAULT_SNID = 0
DEFAULT_INTERNAL_CONF = None
@@ -27,11 +28,16 @@ class Config:
u_sta_hfid - a Python string of length from 0 to 64 octets
avln_hfid - a Python string of length from 0 to 64 octets
sl - a Python integer from 0 to 2
+ force_role - a Python integer from 0 to 2 included
tonemask - a Python tuple of Python integers
snid - a Python integer from 0 to 15
internal_conf - a Python string giving the full path and name of the internal.conf file
"""
- def __init__(self, default_config=True, mac_address=None, cco_preference=None, was_cco=None, npw=None, dpw=None, m_sta_hfid=None, u_sta_hfid=None, avln_hfid=None, sl=None, tonemask=None, snid=None, internal_conf=None):
+ def __init__(
+ self, default_config=True, mac_address=None, cco_preference=None,
+ was_cco=None, npw=None, dpw=None, m_sta_hfid=None,
+ u_sta_hfid=None, avln_hfid=None, sl=None, tonemask=None,
+ snid=None, internal_conf=None, force_role=None):
# MAC address
if mac_address is None and default_config is True:
@@ -87,6 +93,12 @@ class Config:
else:
self.sl = sl
+ # Force Role
+ if force_role is None and default_config is True:
+ self.force_role = DEFAULT_FORCE_ROLE
+ else:
+ self.force_role = force_role
+
# Tonemask
if tonemask is None and default_config is True:
self.tonemask = DEFAULT_TONEMASK
diff --git a/cesar/maximus/python/maximus/station/sta.py b/cesar/maximus/python/maximus/station/sta.py
index d8ae730090..fa848c4392 100644
--- a/cesar/maximus/python/maximus/station/sta.py
+++ b/cesar/maximus/python/maximus/station/sta.py
@@ -21,6 +21,7 @@ MAX_SIZE_OF_NPW = 64 # in octets
MAX_SIZE_OF_DPW = MAX_SIZE_OF_NPW
MAX_SIZE_OF_HFID = MAX_SIZE_OF_DPW
MAX_VALUE_OF_SL = 1
+MAX_VALUE_OF_FORCE_ROLE = 2
MAX_VALUE_OF_SNID = 15
# Constants from 'hal/phy/defs.h'
@@ -256,6 +257,7 @@ class STA:
self.set_u_sta_hfid(config.u_sta_hfid)
self.set_avln_hfid(config.avln_hfid)
self.set_sl(config.sl)
+ self.set_force_role (config.force_role)
self.set_tonemask(config.tonemask)
self.set_snid(config.snid)
self.set_internal_conf(config.internal_conf)
@@ -431,6 +433,24 @@ class STA:
# Send a message to the station to configure the SL
self.__send_sl()
+ def set_force_role (self, force_role):
+ """Set the Force Role.
+ The FR must be a Python integer
+ from 0 to MAX_VALUE_OF_FORCE_ROLE.
+ """
+ if type (force_role) is int:
+ if force_role >= 0 and force_role <= MAX_VALUE_OF_FORCE_ROLE:
+ self.__force_role = force_role
+ else:
+ raise OutOfRangeError ("Force Role")
+ elif force_role is None:
+ self.__force_role = force_role
+ else:
+ raise TypeError("FR")
+
+ # Send a message to the station to configure the SL
+ self.__send_force_role ()
+
def set_tonemask(self, carriers):
"""Set the tonemask.
The carriers must be a Python tuple of Python integers.
@@ -610,6 +630,13 @@ class STA:
"""
return self.__sl
+ def get_force_role (self):
+ """Get the Force Role.
+ The FR is a Python integer.
+ """
+ return self.__force_role
+
+
def get_tonemask(self):
"""Get the tonemask.
The tonemask is a bits field.
@@ -969,6 +996,41 @@ class STA:
self.__check_cnf(rsp,
mmtype.DRV_STA_SET_SL_CNF)
+ def __send_force_role (self):
+ """Send a message to the station to configure the FR.
+ """
+ if self.__force_role is not None:
+ if self.get_config_mode() is CONFIG_MODES[2]: # 'fcall_cp_station'
+ m = self.__get_maximus().create_fcall("maximus_set_fr")
+ m.add_param_uchar("fr", self.__force_role)
+ m.send(self.get())
+ else: # we need to build an MME
+
+ # Computes MM Header
+ mmheader = MMHeader(ODA=self.__get_oda(),
+ OSA=DEFAULT_MAC_ADDRESS, MMV=0x01,
+ MMTYPE = mmtype.DRV_STA_FORCE_ROLE_REQ)
+
+ # Computes MM Entry: Security Level for New NMK
+ # Octet Number = 0
+ # Field Size (Octets) = 1
+ FR = htohp8(self.__force_role)
+ FR = data_pad (FR, 41 - len (FR))
+
+ # Create the MME
+ mme = MME(MMHeader=mmheader, MMEntry=FR)
+
+ if self.get_config_mode() is CONFIG_MODES[1]: # 'fcall_process_drv'
+ m = self.__get_maximus().create_fcall("maximus_set_fr")
+ m.add_param("mme", mme.get())
+ m.send(self.get())
+ else: # 'MME'
+ # Send the MME and wait for the response
+ rsp = mme.sendnrecv(maximus=self.__get_maximus(),
+ station=self.get(), filter=mme_filter)
+ self.__check_cnf(rsp,
+ mmtype.DRV_STA_FORCE_ROLE_CNF)
+
def __send_tonemask(self):
"""Send a message to the station to configure the tonemask.
"""
diff --git a/cesar/maximus/python/tools/csi/csiavln.py b/cesar/maximus/python/tools/csi/csiavln.py
index 069c9f1b7a..4d05356bce 100644
--- a/cesar/maximus/python/tools/csi/csiavln.py
+++ b/cesar/maximus/python/tools/csi/csiavln.py
@@ -30,7 +30,7 @@ class csiAvln:
def sta_add (self, mac_addr, cco_pref, was_cco, dpw, mhfid, uhfid, sl,
debug = False, delay_ms = 0, executable = None,
- internal_conf = None):
+ internal_conf = None, force_role = 0):
if self.__hp_sta_max <= self.get_nb_sta():
return None
@@ -48,7 +48,8 @@ class csiAvln:
sta = csiSta (mac_addr, cco_pref, was_cco, self.get_npw(), dpw,
mhfid, uhfid, self.get_ahfid(), sl, debug, delay_ms,
- executable=executable, internal_conf = internal_conf)
+ executable=executable, internal_conf = internal_conf,
+ force_role = force_role)
self.__sta_list.append (sta)
return sta
diff --git a/cesar/maximus/python/tools/csi/csistation.py b/cesar/maximus/python/tools/csi/csistation.py
index 338eddfd76..a9d41229fb 100644
--- a/cesar/maximus/python/tools/csi/csistation.py
+++ b/cesar/maximus/python/tools/csi/csistation.py
@@ -3,7 +3,8 @@ from maximus.station.config import Config
class csiSta:
def __init__(self, mac_addr, cco_pref, was_cco, npw, dpw, mhfid, uhfid,
- ahfid, sl, debug, delay_ms = 0, executable = None, internal_conf=None):
+ ahfid, sl, debug, delay_ms = 0, executable = None,
+ internal_conf=None, force_role = 0):
self.__stacesar = None
self.__debug = debug
self.__config = Config ()
@@ -19,6 +20,7 @@ class csiSta:
self.__config.sl = sl
self.__config.tonemask = (85,139,167,214,225,282,302,409,419,569,591,736,748,856,882,1015,1027,1143,1535)
self.__config.snid = None
+ self.__config.force_role = force_role
self.__config.internal_conf = internal_conf
self.__config.default_config = True if not internal_conf else False
@@ -39,6 +41,9 @@ class csiSta:
def get_dpw (self):
return self.__config.dpw
+ def get_force_role (self):
+ return self.__config.force_role
+
def get_manufacturer_hfid (self):
return self.__config.m_sta_hfid
diff --git a/cesar/test_general/station/scenario/av/Makefile b/cesar/test_general/station/scenario/av/Makefile
index 6dfeb65f78..e0992943b4 100644
--- a/cesar/test_general/station/scenario/av/Makefile
+++ b/cesar/test_general/station/scenario/av/Makefile
@@ -18,7 +18,8 @@ testbook: py/sc01_assoc_auth.py py/sc02_stas_communication.py \
py/sc07_bridge.py py/sc08_bentry_change.py \
py/sc09_simple_connect.py py/sc10_short_messages.py \
py/sc11_cm_nw_info.py py/sc12_change_nmk.py \
- py/sc13_data_rate.py py/sc14_igmp.py
+ py/sc14_igmp.py \
+ py/sc15_hide.py py/sc16_force_role.py
python testbook.py $^ > $@.rst
CLEAN_FILES += testbook.rst
diff --git a/cesar/test_general/station/scenario/av/py/sc16_force_role.py b/cesar/test_general/station/scenario/av/py/sc16_force_role.py
new file mode 100644
index 0000000000..3f456f712f
--- /dev/null
+++ b/cesar/test_general/station/scenario/av/py/sc16_force_role.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+
+#############################################################################
+# Copyright (C) 2011 Spidcom
+#############################################################################
+
+import sys
+sys.path.append ('py')
+from scenario_init import *
+
+class TestForceRole(unittest.TestCase):
+ """Test the communication on an AVLN with force role in config.
+ Feature for Zenitel"""
+
+ def setUp(self):
+ self.csi = csiCore (1234)
+ self.csi.process_init (args)
+
+ def tearDown(self):
+ self.csi.process_uninit ()
+ del self.csi
+
+ def testCommunication2StaForced (self):
+ """Communication between 2 stations.
+ Send some data between the stations.
+
+ Expected result: Data should be received from each station.
+
+ Check DRV_MAC_STOP and START also on CCO.
+ """
+ # Generate a NPW.
+ npw = str (random.getrandbits(64))
+ ahfid = str (random.getrandbits(32))
+ avln = self.csi.avln_add (npw, ahfid)
+
+ """ force_role = 1 is CCO_FORCED """
+ cco_mac = "00:13:d7:00:00:10"
+ dpw = "HomePlugAV_station10"
+ mhfid = "HomePlugAV_station10"
+ uhfid = "HomePlugAV_station10"
+ avln.sta_add (
+ cco_mac, False, False, dpw, mhfid, uhfid, 0,
+ force_role = 1)
+
+ """ force_role = 2 is STA_FORCED """
+ sta_mac = "00:13:d7:00:00:60"
+ dpw = "HomePlugAV_station60"
+ mhfid = "HomePlugAV_station60"
+ uhfid = "HomePlugAV_station60"
+ avln.sta_add (
+ sta_mac, False, False, dpw, mhfid, uhfid, 0,
+ force_role = 2)
+
+ self.csi.process_avlns_launch ()
+ self.csi.process_wait_association ()
+ self.csi.process_wait_authentication ()
+ cco = avln.get_cco (self.csi.get_maximus ())
+ self.failUnless (cco_mac == cco.get_mac_addr())
+
+ self.failUnless (send_check_datas (self.csi, avln))
+ cco = avln.get_cco (self.csi.get_maximus ())
+ drv_sta_mac_stop_req = Ether (
+ src = "10:10:10:10:10:10", dst = cco_mac) \
+ / scammer.MME () \
+ / scammer.DRV_STA_MAC_STOP_REQ ()
+
+ send_mme (self.csi.get_maximus (), cco, drv_sta_mac_stop_req)
+ self.csi.process_wait_sec (10)
+ self.failIf (send_check_datas (self.csi, avln))
+
+ drv_sta_mac_start_req = Ether (
+ src = "10:10:10:10:10:10", dst = cco_mac) \
+ / scammer.MME () \
+ / scammer.DRV_STA_MAC_START_REQ ()
+
+ send_mme (self.csi.get_maximus (), cco, drv_sta_mac_start_req)
+ self.csi.process_wait_association ()
+ self.csi.process_wait_authentication ()
+ self.failUnless (cco_mac == cco.get_mac_addr())
+ self.failUnless (send_check_datas (self.csi, avln))
+ self.csi.process_avlns_remove ()
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(TestForceRole)
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
+ sys.exit ((1, 0)[testResult.wasSuccessful ()])