summaryrefslogtreecommitdiff
path: root/cesar/cp/eoc/cco/action
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp/eoc/cco/action')
-rw-r--r--cesar/cp/eoc/cco/action/Config2
-rw-r--r--cesar/cp/eoc/cco/action/Module7
-rw-r--r--cesar/cp/eoc/cco/action/cco_action.h92
-rw-r--r--cesar/cp/eoc/cco/action/cco_action_master.h67
-rw-r--r--cesar/cp/eoc/cco/action/doc/Makefile48
-rw-r--r--cesar/cp/eoc/cco/action/doc/cp_eoc_cco_action.odtbin0 -> 125849 bytes
-rw-r--r--cesar/cp/eoc/cco/action/doc/simple.sdl12
-rw-r--r--cesar/cp/eoc/cco/action/doc/slave_states.sdl26
-rw-r--r--cesar/cp/eoc/cco/action/drv.h34
-rw-r--r--cesar/cp/eoc/cco/action/inc/cco_action.h38
-rw-r--r--cesar/cp/eoc/cco/action/src/cco_action.c286
-rw-r--r--cesar/cp/eoc/cco/action/src/cco_action_master.c524
-rw-r--r--cesar/cp/eoc/cco/action/src/drv.c49
-rw-r--r--cesar/cp/eoc/cco/action/src/vs_eoc_master.c821
-rw-r--r--cesar/cp/eoc/cco/action/stub/Module7
-rw-r--r--cesar/cp/eoc/cco/action/stub/src/cco_action.c75
-rw-r--r--cesar/cp/eoc/cco/action/stub/src/cco_action_master.c68
-rw-r--r--cesar/cp/eoc/cco/action/stub/src/drv.c24
-rw-r--r--cesar/cp/eoc/cco/action/stub/src/vs_eoc_master.c96
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/Config14
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/Makefile21
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/inc/scenario_defs.h138
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h98
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/core.h49
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/defs.h57
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/cyg/kernel/kapi.h37
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/mac/sar/inc/context.h23
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/stub.c56
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/test_actions.c471
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/Makefile12
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/actions-Config23
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/actions-Makefile29
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Config8
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Makefile19
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/inc/scenario_defs.h351
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/inc/test_cco_action.h56
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/inc/context.h120
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/core.h56
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/defs.h57
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/override/cyg/kernel/kapi.h37
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/actions.c116
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/ce_rx_stub.c31
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/cl_interf_stub.c44
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/core_stub.c42
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_msg_stub.c438
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_stub.c51
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/cyg_stub.c40
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/dataplane_stub.c38
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/fsm_event_stub.c78
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/hal_phy_stub.c26
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/msg_vs.c686
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/scenario_event_stub.c241
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/test_actions.c4016
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/test_fsm.c429
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/Config19
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/Makefile18
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/inc/scenario_defs.h160
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/inc/test_cco_action.h46
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/inc/context.h90
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/sta/core/defs.h57
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/override/cyg/kernel/kapi.h37
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/override/mac/sar/inc/context.h24
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/src/cl_mcast.c60
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/src/fsm_stub.c55
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/src/msg_stub.c289
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/src/scenario_actions.c72
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/src/test_cco_action.c75
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_mcast/src/test_mcast_suite.c97
-rw-r--r--cesar/cp/eoc/cco/action/vs_eoc_master.h100
69 files changed, 11483 insertions, 0 deletions
diff --git a/cesar/cp/eoc/cco/action/Config b/cesar/cp/eoc/cco/action/Config
new file mode 100644
index 0000000000..d30b6a611b
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/Config
@@ -0,0 +1,2 @@
+CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED = n
+CONFIG_CP_EOC_CCO_ACTION_CON_ALLOWED = n
diff --git a/cesar/cp/eoc/cco/action/Module b/cesar/cp/eoc/cco/action/Module
new file mode 100644
index 0000000000..18a6edd1cc
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/Module
@@ -0,0 +1,7 @@
+SOURCES := cco_action.c drv.c
+
+ifeq ($(CONFIG_CP_EOC_IS_MASTER),y)
+ SOURCES += cco_action_master.c vs_eoc_master.c
+endif
+
+MODULES := cp/cco/action
diff --git a/cesar/cp/eoc/cco/action/cco_action.h b/cesar/cp/eoc/cco/action/cco_action.h
new file mode 100644
index 0000000000..327d202ee3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/cco_action.h
@@ -0,0 +1,92 @@
+#ifndef cesar_cp_eoc_cco_action_cco_action_h
+#define cesar_cp_eoc_cco_action_cco_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cesar/cp/eoc/cco/action/cco_action.h
+ * \brief EoC CCo action Public functions.
+ * \ingroup cesar_cp_eoc_cco_action
+ *
+ */
+#include "cp/cp.h"
+#include "config/cp/eoc.h"
+
+#if CONFIG_CP_EOC_IS_MASTER
+#include "cco_action_master.h"
+#include "vs_eoc_master.h"
+#endif
+#include "drv.h"
+
+BEGIN_DECLS
+
+/**
+ * handle POWER_ON => CCO
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action__power_on_no_beacons (cp_t *ctx);
+
+/**
+ * Start CCO side FSM.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action_poweron__idle__to_poweron (cp_t *ctx);
+
+/**
+ * handle POWER_ON => BCCO
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action__power_on_rx_beacon (cp_t *ctx);
+
+/**
+ * handle CCO => STOPPING
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action__cco_drv_mac_stop (cp_t *ctx);
+
+/**
+ * handle BCCO => STOPPING
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action__bcco_drv_mac_stop (cp_t *ctx);
+
+/**
+ * handle BCCO => CCO
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action__bcco_no_beacons (cp_t *ctx);
+
+/**
+ * Generate and send a eoc central beacon.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx);
+
+/**
+ * EoC scheduler. Should be called in each beacon period.
+ * \param user_data cp context.
+ */
+void
+cp_eoc_scheduler_prepare (void * user_data);
+
+END_DECLS
+
+#endif /* cesar_cp_eoc_cco_action_cco_action_h */
diff --git a/cesar/cp/eoc/cco/action/cco_action_master.h b/cesar/cp/eoc/cco/action/cco_action_master.h
new file mode 100644
index 0000000000..76e312fb2f
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/cco_action_master.h
@@ -0,0 +1,67 @@
+#ifndef cesar_cp_eoc_cco_action_cco_action_master_h
+#define cesar_cp_eoc_cco_action_cco_action_master_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cesar/cp/eoc/cco/action/cco_action_master.h
+ * \brief « brief description »
+ * \ingroup cesar_cp_eoc_cco_action
+ *
+ * « long description »
+ */
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+/**
+ * Examine the received mme and create apropriate multi_sta_fsm event.
+ * \param ctx the module context.
+ */
+void
+cp_eoc_cco_action_event_dispatch (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs__cco__cc_leave_ind (
+ cp_t *ctx, cp_mme_peer_t *peer);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_nek_change_start_timeout (cp_t *ctx);
+
+/**
+ * Manage new neck distribution
+ * \param ctx the CP context
+ * \param mme CM_SET_KEY.CNF MME received from the station
+ */
+void
+cp_eoc_cco_action__set_key_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_nek_change_timeout (cp_t *ctx);
+
+/**
+ * Provide stations with new NEK
+ * \param ctx the CP context
+ */
+void
+cp_eoc_cco_action_nek_provide (cp_t *ctx);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx);
+
+#endif /* cesar_cp_eoc_cco_action_cco_action_master_h */
diff --git a/cesar/cp/eoc/cco/action/doc/Makefile b/cesar/cp/eoc/cco/action/doc/Makefile
new file mode 100644
index 0000000000..309aae3dda
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/doc/Makefile
@@ -0,0 +1,48 @@
+PAGES = simple slave_states
+GRAPHS = simple slave_states
+
+DOTFLAGS =
+CONVERTFLAGS = -border 1 -bordercolor '\#d7d7d7'
+
+TOOLS_DIR = ../../../../../common/tools
+DOC_DIR = ../../../../../common/doc
+SDL2DOT = $(TOOLS_DIR)/sdl2dot
+SDLPS = $(TOOLS_DIR)/sdl.ps
+#EXTRACT_DOC = $(DOC_DIR)/extractdoc
+DOX2RST = $(DOC_DIR)/dox2rst
+
+#all: png rst
+all: png
+
+png: $(GRAPHS:%=%.png)
+ps: $(GRAPHS:%=%.ps)
+
+%.png: %.ps
+ convert $(CONVERTFLAGS) $< $@
+
+%.ps: %.dot Makefile
+ dot $(DOTFLAGS) -Tps -l $(SDLPS) -o $@ $<
+
+%.dot: %.sdl
+ $(SDL2DOT) $< > $@
+
+rst: top.rst
+html: png top.html
+odt: top.odt
+
+top.rst: $(PAGES:%=%.rst)
+ cat $^ > $@
+
+%.rst: ../%.h
+ $(EXTRACT_DOC) $< | $(DOX2RST) -s 50 > $@
+
+%.html: %.rst
+ rst2html $< $@
+
+%.odt: %.rst
+ rst2odt.py $< $@
+
+clean:
+ rm -f $(GRAPHS:%=%.ps) $(GRAPHS:%=%.png)
+ rm -f $(PAGES:%=%.rst) $(PAGES:%=%.html)
+ rm -f top.rst top.html top.odt
diff --git a/cesar/cp/eoc/cco/action/doc/cp_eoc_cco_action.odt b/cesar/cp/eoc/cco/action/doc/cp_eoc_cco_action.odt
new file mode 100644
index 0000000000..56d5615ce8
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/doc/cp_eoc_cco_action.odt
Binary files differ
diff --git a/cesar/cp/eoc/cco/action/doc/simple.sdl b/cesar/cp/eoc/cco/action/doc/simple.sdl
new file mode 100644
index 0000000000..9d80030d79
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/doc/simple.sdl
@@ -0,0 +1,12 @@
+((start)) -> (POWER_ON)
+
+POWER_ON:
+(POWER_ON) -no beacons -> (CCO)
+(POWER_ON) -rx beacon -> (BCCO)
+
+CCO:
+(CCO) -DRV_MAC_STOP -> (STOPPING)
+
+BCCO:
+(BCCO) -DRV_MAC_STOP -> (STOPPING)
+(BCCO) -no beacons -> (CCO)
diff --git a/cesar/cp/eoc/cco/action/doc/slave_states.sdl b/cesar/cp/eoc/cco/action/doc/slave_states.sdl
new file mode 100644
index 0000000000..91f23c5d6a
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/doc/slave_states.sdl
@@ -0,0 +1,26 @@
+((start)) -> (disconnected)
+
+disconnected:
+(disconnected) -CC_ASSOC.REQ -> <:STA in WL?> -y -> (associated)
+ <:STA in WL?> -n -> (unassociated)
+
+unassociated:
+(unassociated) -CC_ASSOC.REQ -> <:STA in WL?> -y -> (associated)
+ <:STA in WL?> -n -> (unassociated)
+(unassociated) -timeout_assoc -> (disconnected)
+
+associated:
+(associated) -CC_GET_KEY.REQ -> <:all keys granted?> -y -> (authenticated)
+ <:all keys granted?> -n -> (associated)
+(associated) -timeout_auth -> (disconnected)
+(associated) -cc_leave -> (disconnected)
+
+authenticated:
+(authenticated) -CC_SLEEP_ENTER.REQ -> (sleep_authenticated)
+(authenticated) -cc_leave -> (disconnected)
+(authenticated) -bad connection -> (disconnected)
+
+sleep_authenticated:
+(sleep_authenticated) -CC_SLEEP_EXIT.IND -> (authenticated)
+(sleep_authenticated) -bad connection -> (disconnected)
+
diff --git a/cesar/cp/eoc/cco/action/drv.h b/cesar/cp/eoc/cco/action/drv.h
new file mode 100644
index 0000000000..41dc04c9ee
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/drv.h
@@ -0,0 +1,34 @@
+#ifndef cp_eoc_cco_action_drv_h
+#define cp_eoc_cco_action_drv_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/drv.h
+ * \brief Driver messages
+ * \ingroup cp_eoc_cco_action
+ *
+ * Entering and exiting sleep states
+ * ==========================
+ *
+ * This part relates to entering and exiting STA sleep states
+ *
+ * \image html
+ *
+ */
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+BEGIN_DECLS
+
+void
+cp_eoc_cco_action_drv__drv_mcast_set_list_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+END_DECLS
+
+#endif /* cp_eoc_sta_action_drv_h */
diff --git a/cesar/cp/eoc/cco/action/inc/cco_action.h b/cesar/cp/eoc/cco/action/inc/cco_action.h
new file mode 100644
index 0000000000..abce669ef1
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/inc/cco_action.h
@@ -0,0 +1,38 @@
+#ifndef cesar_cp_eoc_cco_inc_cco_action_h
+#define cesar_cp_eoc_cco_inc_cco_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cesar/cp/eoc/cco/inc/cco_action.h
+ * \brief EoC CCo private functions.
+ * \ingroup cesar_cp_eoc_cco_action
+ *
+ */
+
+#include "cp/cco/action/inc/cco_action.h"
+
+/** Maximum number of released TEIs printed on console for each GC call. */
+#define CCO_STA_CON 4
+#define CP_EOC_CCO_EKS_RETRY 3
+#define CP_EOC_STA_ASSOCIATED_TIMEOUT_MS 5*1000
+
+/* Timeout value for the EKS exchange MME. */
+#define CP_CCO_ACTION_EKS_TIMEOUT_MS 3000
+
+BEGIN_DECLS
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action__change_nek (cp_t *ctx);
+
+
+END_DECLS
+
+#endif /* cesar_cp_eoc_cco_inc_cco_action_h */
diff --git a/cesar/cp/eoc/cco/action/src/cco_action.c b/cesar/cp/eoc/cco/action/src/cco_action.c
new file mode 100644
index 0000000000..4b2bc189fc
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/src/cco_action.c
@@ -0,0 +1,286 @@
+/* Cesar EOC project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/src/cco_action.c
+ * \brief CCo Action functions.
+ * \ingroup cp_eoc_cco_action
+ *
+ */
+#include "common/std.h"
+
+/* Private headers. */
+#include "cp/inc/context.h"
+#include "cp/eoc/inc/dbg_print.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/sta/mgr/inc/net.h"
+#include "mac/pbproc/inc/context.h"
+#include "cp/eoc/cco/action/inc/cco_action.h"
+
+/* Public headers. */
+#include "mac/common/defs.h"
+#include "cp/beacon/beacon.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+#include "cp/eoc/sta/action/drv.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/sta.h"
+#if CONFIG_CP_EOC_IS_MASTER
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+#endif
+
+/* Config headers. */
+#include "config/cp/eoc/cco/action.h"
+
+#if CONFIG_CP_EOC_CCO_ACTION_CON_ALLOWED
+
+#include "mac/sar/inc/context.h"
+
+#define CONFIG_CP_EOC_CCO_CON_TIMEOUT_TCK MAC_MS_TO_TCK (950)
+#define SUB_STAT_ATTR(a, b, c) ((a).c - (b).c)
+#define SUB_STAT(c) SUB_STAT_ATTR (ctx->sar->stats, sar_offset, c)
+
+static int mem = 0, auth_time = 0;
+static sar_stats_t sar_offset;
+#endif
+
+
+void
+cp_eoc_cco_action__change_nek (cp_t *ctx)
+{
+ /* Program the timer to periodically change the NEK. */
+ cp_fsm_event_t * event = cp_fsm_event_bare_new (
+ ctx, CP_FSM_EVENT_TYPE_cco__nek_change);
+ cp_sta_core_gen_timed_event (ctx, &ctx->cco_action.nek_change,
+ event, HPAV_NEK_CHANGE_MS);
+}
+
+void
+cp_eoc_cco_action__power_on_no_beacons (cp_t *ctx)
+{
+ cp_tei_t tei;
+ cp_net_t *net;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ cp_sta_own_data_t *own;
+ dbg_assert (ctx);
+ ctx->cco_action.last_date = phy_date ();
+ tei = MAC_TEI_CCO_MIN;
+ cp_sta_own_data_set_tei (ctx, tei);
+ cp_sta_own_data_set_authenticated_status (ctx, true);
+
+ cp_eoc_sta_action_drv__drv_sta_get_status_ind (ctx);
+
+ /* Set our AVLN. */
+ snid = cp_sta_own_data_get_snid (ctx);
+ nid = cp_sta_own_data_get_nid (ctx);
+
+ net = cp_sta_mgr_add_avln (ctx, snid, nid);
+ cp_sta_mgr_set_our_avln (ctx, net);
+
+ /* Set the CCo status in the station own data. */
+ own = cp_sta_mgr_get_sta_own_data (ctx);
+ own->nid_track = cp_sta_own_data_get_nid (ctx);
+ cp_sta_own_data_set_cco_status (ctx, true);
+ /* Set the NEK. */
+ cp_cco_action_gen_nek (ctx);
+ cp_beacon_change_nek (ctx, ctx->cco_action.new_nek.eks,
+ ctx->cco_action.new_nek.nek_enc, true /* now. */);
+ /* Start timer for periodic NEK exchange */
+ cp_eoc_cco_action__change_nek (ctx);
+ /* set wl status. In maximus accept all stations */
+#if MODULE_INCLUDED (hal_phy_maximus)
+ ctx->cco_action.wl_accept_all = 1;
+ ctx->cco_action.gm_default_output_power = 0;
+ cp_key_t key = cp_secu_generate_keys (ctx, (u8 *) MASTER_GOLDEN_DPW,
+ strlen (MASTER_GOLDEN_DPW), CP_SECU_SALT_KEY_DAK);
+ cp_sta_own_data_set_dak (ctx, key);
+#endif
+}
+
+void
+cp_eoc_cco_action_poweron__idle__to_poweron (cp_t *ctx)
+{
+ /* simulated call to setup cp status */
+ cp_eoc_cco_action__power_on_no_beacons (ctx);
+ cp_eoc_cco_bw_bp_allocations (ctx);
+ cp_beacon_poweron_init (ctx);
+ bsu_init_scheduler_prepare (ctx->bsu, cp_eoc_scheduler_prepare, ctx);
+ bsu_power_on (ctx->bsu, cp_sta_own_data_get_snid (ctx));
+ bsu_activate (ctx->bsu, true);
+ cp_beacon_cco_update_beacon_data (ctx);
+ sar_activate (ctx->sar, true);
+ pbproc_activate (ctx->pbproc, true);
+ ctx->sta_action.assoc.peer = CP_MME_PEER (MAC_BROADCAST,
+ MAC_TEI_UNASSOCIATED);
+ cp_fsm_post_new_event (ctx, bare, BEACON_NOT_RECEIVED);
+}
+
+void
+cp_eoc_cco_action__power_on_rx_beacon (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_cco_action__cco_drv_mac_stop (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_cco_action__bcco_drv_mac_stop (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_cco_action__bcco_no_beacons (cp_t *ctx)
+{
+}
+
+/**
+ * bw scheduler
+ * \param user_data cp * context provided to BSU.
+ * call in DSR context on timer to assure that scheduling will be called
+ * in each beacon period.
+*/
+void
+cp_eoc_scheduler_prepare (void * user_data)
+{
+ /* only Master compilation */
+#if CONFIG_CP_EOC_IS_MASTER
+ cp_t * ctx = (cp_t *)user_data;
+ dbg_assert (ctx);
+ cp_eoc_cco_bw_scheduler (ctx);
+#endif
+}
+
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ arch_dsr_lock ();
+ cp_eoc_cco_bw_bp_allocations (ctx);
+ arch_dsr_unlock ();
+#if CONFIG_CP_EOC_CCO_ACTION_CON_ALLOWED
+ if (++mem >= 10)
+ {
+ auth_time++;
+ mem = 0;
+ }
+ if (less_mod2p32 (ctx->cco_action.last_date, phy_date ()))
+ {
+ char temp[128];
+ sprintf (temp, "cco=%d blk=%d sar[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]"
+ " pb[%d,%d]\n",
+ auth_time, blk_free_nb (),
+ SUB_STAT (rx_jobs_nb),
+ ctx->sar->stats.rx_jobs_waiting_nb,
+ SUB_STAT (rx_pb_count),
+ SUB_STAT (pb_data_before_ssn_min),
+ SUB_STAT (pb_data_duplicated),
+ SUB_STAT (pb_mme_before_ssn_min),
+ SUB_STAT (pb_mme_duplicated),
+ SUB_STAT (rx_pb_crc_error_count),
+ SUB_STAT (mfs_tx_data_pb_expired_nb),
+ SUB_STAT (mfs_rx_data_pb_expired_nb),
+ SUB_STAT (mfs_tx_mme_pb_expired_nb),
+ SUB_STAT (mfs_rx_mme_pb_expired_nb),
+ ctx->pbproc->stats.tx_data_cancel,
+ ctx->pbproc->stats.tx_data_wack_noack);
+ int pos = 0, len = strlen (temp), len1;
+ while (pos < len)
+ {
+ char * temp1 = temp + pos, tmpa[32];
+ len1 = MIN (len, pos + 10);
+ strncpy (tmpa, temp1, len1 - pos);
+ tmpa[len1 - pos] = '\0';
+ printf (tmpa);
+ pos = len1;
+ }
+ sar_offset = ctx->sar->stats;
+ ctx->cco_action.last_date = phy_date ()
+ + CONFIG_CP_EOC_CCO_CON_TIMEOUT_TCK;
+ }
+#endif
+}
+
+void
+cp_eoc_cco_action_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ memset (&ctx->cco_action, 0, sizeof (cp_cco_action_t));
+
+ ctx->cco_action.new_nek.eks = MAC_EKS_MAX; /* Initialized to MAC_EKS_MAX in
+ order to have MAC_EKS_MIN as the EKS of the first generated NEK. */
+}
+
+void
+cp_eoc_cco_action_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+void
+cp_eoc_cco_action_garbage (cp_t *ctx)
+{
+ int i, released_sta_nb = 0, released_sta_tei[CCO_STA_CON];
+ dbg_assert (ctx);
+ cp_net_t *net = cp_sta_mgr_get_our_avln (ctx);
+
+ /* Check if associated sta got disconnected */
+ for (i = MAC_TEI_STA_MIN_EOC; i < MAC_TEI_STA_MAX; i++)
+ {
+ cp_sta_t * station = cp_sta_mgr_sta_get_assoc (ctx, net, i);
+ if (!station)
+ continue;
+ sta_t *sta = mac_store_sta_get (ctx->mac_store, i);
+ /* cp sta is assoc but no mac store sta? Really wrong. */
+ dbg_assert (sta);
+ /* station is declared dead by lower layers? */
+ if(!sta->tdma_poll && sta->authenticated)
+ station->authenticated_to_unassociated = true;
+ /* release station, no answers + to long in assoc. state */
+ if ((!sta->tdma_poll && sta->authenticated)
+ || (!sta->authenticated
+ && (station->associated_date_ms
+ + CP_EOC_STA_ASSOCIATED_TIMEOUT_MS
+ < cp_sta_core_get_date_ms (ctx))))
+ {
+#if CONFIG_CP_EOC_IS_MASTER
+ /* only Master compilation */
+ cp_eoc_multi_sta_action_put_sta_unassociated (ctx, station);
+#endif
+ /* Start release procedure */
+ cp_sta_mgr_release_station (ctx, i);
+
+ if (sta->authenticated)
+ {
+ if (released_sta_nb < CCO_STA_CON)
+ released_sta_tei[released_sta_nb] = i;
+ released_sta_nb ++;
+ DBG_PRINT_2 ("sta: rel, tei=%d", i);
+ }
+ else
+ DBG_PRINT ("sta: auth fail, tei=%d", i);
+ }
+ slab_release (station);
+ blk_release (sta);
+ }
+ /* Check if unassociated sta is still in the network */
+ cp_net_garbage_station_list (ctx, cp_sta_mgr_get_our_avln (ctx),
+ cp_sta_core_get_date_ms (ctx),
+ CP_NET_STA_UNASSOC);
+
+ if (released_sta_nb)
+ {
+ DBG_PRINTC ("rel: %d; TEI:", released_sta_nb);
+ for (i = 0; ((i < released_sta_nb) && (i < CCO_STA_CON)); i++)
+ DBG_PRINTC (" %d", released_sta_tei[i]);
+ DBG_PRINTC (released_sta_nb > CCO_STA_CON ? " ...\n" : "\n");
+ }
+}
diff --git a/cesar/cp/eoc/cco/action/src/cco_action_master.c b/cesar/cp/eoc/cco/action/src/cco_action_master.c
new file mode 100644
index 0000000000..cf568dbe22
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/src/cco_action_master.c
@@ -0,0 +1,524 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/src/cco_action_master.c
+ * \brief EoC CCo Action functions.
+ * \ingroup cp_eoc_cco_action
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "common/defs/eoc.h"
+
+/* Private headers. */
+#include "cp/inc/context.h"
+#include "cp/eoc/cco/action/inc/cco_action.h"
+#include "cp/eoc/multi_sta_fsm/inc/events.h"
+#include "cp/eoc/inc/dbg_print.h"
+
+/* Public headers. */
+#include "cp/eoc/cco/action/cco_action_master.h"
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+
+
+/**
+ * Last transaction ends try next STA.
+ * \param ctx the module context.
+ * \return The next station to start a transaction with.
+ */
+static cp_sta_t *
+cp_cco_action_nek_next_sta (cp_t *ctx)
+{
+ cp_sta_t *sta;
+ cp_sta_t *sta_next = NULL;
+ cp_net_t *net;
+ dbg_assert (ctx);
+
+ ctx->cco_action.eks_eoc_retry = 0;
+ net = cp_sta_mgr_get_our_avln (ctx);
+ sta = cp_sta_mgr_sta_get_from_mac (
+ ctx, ctx->cco_action.eks_sta_current_peer.mac);
+ while (sta)
+ {
+ sta_next = cp_net_sta_get_next (ctx, net, sta);
+ if (sta_next &&
+ cp_eoc_sta_mgr_sta_is_assoc (ctx, net, cp_sta_get_tei (sta_next)))
+ {
+ cp_sta_get_peer (sta_next, &ctx->cco_action.eks_sta_current_peer);
+ return sta_next;
+ }
+ sta = sta_next;
+ }
+
+ return NULL;
+}
+
+/**
+ * Request the station for the NEK change.
+ * \param ctx the module context.
+ * \param sta the station to start the NEK exchange.
+ */
+static void
+cp_eoc_cco_action_nek_change_start (cp_t *ctx, cp_sta_t *sta)
+{
+ cp_msg_cm_set_key_req_t data;
+
+ dbg_assert (ctx);
+ dbg_assert (sta);
+
+ /* Get the station peer to send the MME. */
+ cp_sta_get_peer (sta, &ctx->cco_action.eks_sta_current_peer);
+ /* Check status */
+ if (cp_sta_get_authenticated (ctx, sta))
+ {
+ /* Initialise the protocol run. */
+ cp_secu_protocol_run_new (&ctx->cco_action.eks_prun, 1,
+ &ctx->rnd);
+
+ /* Fill the data structure with key type == NONCE_ONLY. */
+ memset (&data, 0, sizeof (cp_msg_cm_set_key_req_t));
+ data.key_type = CP_MSG_KEY_NONCE_ONLY;
+ data.cco_cap = CP_CCO_LEVEL;
+ data.nid = cp_sta_own_data_get_nid (ctx);
+
+ /* Send the MME. */
+ cp_msg_cm_set_key_req_send (ctx,
+ &ctx->cco_action.eks_sta_current_peer,
+ CP_MME_PEKS_DAK,
+ &ctx->cco_action.eks_prun,
+ &data);
+ }
+ cp_eoc_cco_action_nek_change_start_timeout (ctx);
+}
+
+void
+cp_eoc_cco_action_event_dispatch (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (mme);
+ cp_eoc_multi_sta_fsm_event_mme_t e;
+ cp_eoc_multi_sta_fsm_event_type_t type;
+
+ cp_net_t *net;
+ cp_sta_t *sta = NULL;
+ sta_t *mac_sta = NULL;
+ cp_tei_t tei = MAC_TEI_UNASSOCIATED;
+ net = cp_sta_mgr_get_our_avln (ctx);
+ /* On ASSOC.REQ fsm has to be initialized */
+ if (mme->mmtype == CC_ASSOC_REQ)
+ {
+ sta = cp_sta_mgr_sta_get_from_mac (ctx, mme->peer.mac);
+
+#if CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED
+ /* Accept all stations, no matter of white list */
+ if (ctx->cco_action.wl_accept_all)
+ {
+ DBG_PRINT ("sta: allowed");
+ if (sta)
+ {
+ slab_release (sta);
+ cp_sta_mgr_sta_remove (ctx, sta);
+ }
+ tei = cp_eoc_multi_sta_action_compute_tei (ctx);
+ sta = cp_sta_mgr_sta_add (ctx, net, tei, mme->peer.mac);
+ dbg_assert (sta);
+ cp_eoc_multi_sta_fsm_init (ctx, sta);
+ sta->multi_sta.allowed = true;
+ sta->multi_sta.dak = cp_sta_own_data_get_dak (ctx);
+ sta->multi_sta.output_level =
+ ctx->cco_action.gm_default_output_power;
+ sta->multi_sta.to_leave = false;
+ sta->expired_date_ms = cp_sta_core_get_date_ms (ctx)
+ + EOC_STA_PRESENCE_TIMEOUT_INSIDE_AVLN_MS;
+ }
+ if (!sta)
+ {
+ DBG_PRINT_2("sta: not_in_wl");
+ sta = cp_sta_mgr_sta_add (ctx, net, MAC_TEI_UNASSOCIATED,
+ mme->peer.mac);
+ cp_eoc_multi_sta_fsm_init (ctx, sta);
+ sta->multi_sta.allowed = false;
+ sta->multi_sta.to_leave = false;
+ sta->expired_date_ms = cp_sta_core_get_date_ms (ctx)
+ + EOC_STA_PRESENCE_TIMEOUT_INSIDE_AVLN_MS;
+ dbg_assert (sta);
+ }
+ else if (sta->multi_sta.to_leave == false)
+ {
+ if (sta->multi_sta.allowed == true)
+ {
+ tei = cp_sta_get_tei (sta);
+ DBG_PRINT_2 ("sta: allowed, tei=%d", tei);
+ sta = cp_sta_mgr_sta_add (ctx, net, tei ,mme->peer.mac);
+ sta->expired_date_ms = cp_sta_core_get_date_ms (ctx)
+ + EOC_STA_PRESENCE_TIMEOUT_INSIDE_AVLN_MS;
+ sta->multi_sta.allowed = true;
+ }
+ else
+ {
+ tei = cp_sta_get_tei (sta);
+ DBG_PRINT_2 ("sta: not_allowed, tei=%d", tei);
+ if (tei)
+ {
+ sta = cp_sta_mgr_sta_add (ctx, net,
+ MAC_TEI_UNASSOCIATED,
+ mme->peer.mac);
+ dbg_assert (sta);
+ sta->expired_date_ms = cp_sta_core_get_date_ms (ctx)
+ + EOC_STA_PRESENCE_TIMEOUT_INSIDE_AVLN_MS;
+ sta->multi_sta.allowed = false;
+ }
+ }
+ }
+
+ if ((tei) && (sta->multi_sta.allowed == true)
+ && (sta->multi_sta.to_leave == false))
+ {
+ mac_sta = mac_store_sta_get (ctx->mac_store, tei);
+ mac_sta->tdma_poll = true;
+ mac_sta->empty_poll = 0;
+ mac_sta->bp_before_poll = 0;
+ ca_sta_update (ctx->ca, mac_sta);
+ blk_release (mac_sta);
+ mfs_tx_t *mfs;
+ bool added;
+
+ cp_sta_set_authenticated (ctx, sta, false);
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, true,
+ MAC_LID_NONE, tei, &added);
+ if (added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ blk_release (mfs);
+
+ uint i;
+ for (i = 0; i < MAC_CAP_NB; i++)
+ {
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false,
+ MAC_LLID_MIN + i, tei, &added);
+ if (added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ {
+ mfs->cap = i;
+ blk_release (mfs);
+ }
+ }
+ }
+#else
+ if (sta)
+ {
+ slab_release (sta);
+ tei = cp_sta_get_tei (sta);
+ cp_sta_mgr_sta_remove_from_mac (ctx, mme->peer.mac);
+ }
+ if (tei == MAC_TEI_UNASSOCIATED)
+ tei = cp_eoc_multi_sta_action_compute_tei (ctx);
+ if (tei != MAC_TEI_UNASSOCIATED)
+ sta = cp_sta_mgr_sta_add (ctx, net, tei, mme->peer.mac);
+ dbg_assert (sta);
+ cp_eoc_multi_sta_fsm_init (ctx, sta);
+ cp_sta_set_assoc_confirmed (ctx, sta, false);
+ cp_sta_set_authenticated (ctx, sta, false);
+ mac_sta = mac_store_sta_get (ctx->mac_store, tei);
+ mac_sta->tdma_poll = true;
+ mac_sta->empty_poll = 0;
+ mac_sta->bp_before_poll = 0;
+ ca_sta_update (ctx->ca, mac_sta);
+
+ blk_release (mac_sta);
+
+ bool added;
+ mfs_tx_t *mfs;
+
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, true,
+ MAC_LID_NONE, tei, &added);
+ if (added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ blk_release (mfs);
+
+ uint i;
+ for (i = 0; i < MAC_CAP_NB; i++)
+ {
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false,
+ MAC_LLID_MIN + i, tei, &added);
+ if (added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ {
+ mfs->cap = i;
+ blk_release (mfs);
+ }
+ }
+#endif /* CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED */
+ }
+ else
+ {
+ /* The station already exists get the TEI. */
+ sta = cp_sta_mgr_sta_get_from_mac (ctx, mme->peer.mac);
+ dbg_assert (sta);
+ }
+
+ switch (mme->mmtype)
+ {
+ case CC_ASSOC_REQ:
+ type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_ASSOC_REQ;
+ break;
+ case CM_GET_KEY_REQ:
+ type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_GET_KEY_REQ;
+ break;
+ default:
+ dbg_assert (0);
+ break;
+ }
+ if (sta->multi_sta.to_leave == false)
+ {
+ e.event.type = type;
+ e.event.handler = cp_eoc_multi_sta_fsm_event_handler;
+ e.mme = mme;
+ cp_eoc_multi_sta_fsm_handled_event (ctx, sta, &(e.event));
+ }
+ slab_release (sta);
+}
+
+void
+cp_eoc_cco_action_vs__cco__cc_leave_ind (cp_t *ctx, cp_mme_peer_t *peer)
+{
+ dbg_assert (ctx);
+ dbg_assert (peer);
+
+ cp_eoc_multi_sta_fsm_event_mme_t e;
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ cp_sta_t *sta;
+ cp_net_t *net;
+ cp_tei_t tei;
+
+ type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_cc_leave;
+ net = cp_sta_mgr_get_our_avln (ctx);
+ tei = peer->tei;
+
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, tei);
+ if (sta)
+ {
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (ctx);
+ e.event.type = type;
+ e.event.handler = cp_eoc_multi_sta_fsm_event_handler;
+
+ cp_msg_cc_leave_ind_send (ctx, peer,
+ CP_MSG_CC_LEAVE_IND_REASON_USER_REQUEST,
+ cp_net_get_nid(ctx, net));
+
+ DBG_PRINT ("sta: CC_LEAVE sent, tei=%d", tei);
+ cp_eoc_multi_sta_fsm_handled_event (ctx, sta, &(e.event));
+ own->num_leave ++;
+
+ slab_release(sta);
+ }
+}
+
+void
+cp_eoc_cco_action_nek_change_start_timeout (cp_t *ctx)
+{
+ cp_fsm_event_t *event;
+ /* Start the timeout timer. */
+ event = cp_fsm_event_bare_new (ctx, CP_FSM_EVENT_TYPE_nek_timeout);
+ cp_sta_core_gen_timed_event (ctx, &ctx->cco_action.eks_timer,
+ event, CP_CCO_ACTION_EKS_TIMEOUT_MS);
+}
+
+void
+cp_eoc_cco_action__set_key_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_msg_cm_set_key_cnf_t data;
+ cp_sta_t *sta;
+ cp_net_t *net;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ /* Ignore delayed replies */
+ if (mme->peer.tei != ctx->cco_action.eks_sta_current_peer.tei)
+ return;
+
+ net = cp_sta_mgr_get_our_avln (ctx);
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net,
+ ctx->cco_action.eks_sta_current_peer.tei);
+
+ if (sta && cp_sta_get_authenticated (ctx, sta))
+ slab_release (sta);
+ else
+ {
+ if (sta)
+ slab_release (sta);
+ return;
+ }
+
+ /* Stop the time out timer. */
+ cp_sta_core_stop_timed_or_cyclic_event (ctx, &ctx->cco_action.eks_timer);
+
+ if (cp_msg_cm_set_key_cnf_receive (ctx, mme, &data)
+ && (mme->prun.pid == 1))
+ {
+ if (cp_secu_protocol_check (&ctx->cco_action.eks_prun, &mme->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEXT)
+ && (mme->prun.pmn == 2))
+ {
+ uint i;
+ cp_msg_cm_set_key_req_t data_req;
+ data_req.key_type = CP_MSG_KEY_NEK;
+ data_req.cco_cap = CP_CCO_LEVEL;
+ data_req.nid = cp_sta_own_data_get_nid (ctx);
+ data_req.new_eks = ctx->cco_action.new_nek.eks;
+ for (i = 0; i < COUNT (ctx->cco_action.new_nek.nek_enc.key); i++)
+ data_req.new_key.key[i]
+ = ctx->cco_action.new_nek.nek_enc.key[i];
+
+ /* Prepare the EKS NEK exchange. */
+ ctx->cco_action.eks_prun = mme->prun;
+ cp_secu_protocol_next (&ctx->cco_action.eks_prun, &ctx->rnd,
+ false /* not last*/);
+
+ cp_msg_cm_set_key_req_send (
+ ctx, &ctx->cco_action.eks_sta_current_peer,
+ CP_MME_PEKS_DAK, &ctx->cco_action.eks_prun, &data_req);
+ }
+ /* Key successfully exchanged with current tei, go to next tei. */
+ else if (cp_secu_protocol_check (
+ &ctx->cco_action.eks_prun, &mme->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_LAST)
+ && (mme->prun.pmn == 0xff))
+ {
+ if ((sta = cp_cco_action_nek_next_sta (ctx)))
+ {
+ cp_eoc_cco_action_nek_change_start (ctx, sta);
+ slab_release (sta);
+ }
+ else
+ {
+ cp_beacon_change_nek (ctx, ctx->cco_action.new_nek.eks,
+ ctx->cco_action.new_nek.nek_enc, false);
+ /* Set the EKS_current to the new one. */
+ ctx->cco_action.eks_sta_current_peer.tei =
+ MAC_TEI_UNASSOCIATED;
+ DBG_PRINT("key_exc: e[%d]", ctx->cco_action.new_nek.eks);
+ }
+ return;
+ }
+ }
+ /* Irregular events, errors or delayed message from current tei are
+ * ignored. */
+ cp_eoc_cco_action_nek_change_start_timeout (ctx);
+}
+
+void
+cp_eoc_cco_action_nek_change_timeout (cp_t *ctx)
+{
+ cp_sta_t *sta;
+ cp_net_t *net;
+ dbg_assert (ctx);
+ uint tei = ctx->cco_action.eks_sta_current_peer.tei;
+ uint retry_count = ctx->cco_action.eks_eoc_retry;
+ /* Stop the time out timer. */
+ cp_sta_core_stop_timed_or_cyclic_event (ctx, &ctx->cco_action.eks_timer);
+ ctx->cco_action.eks_eoc_retry ++;
+ /* exec is over. Timeout is late. Simply return. */
+ if (ctx->cco_action.eks_sta_current_peer.tei == MAC_TEI_UNASSOCIATED)
+ {
+ cp_fsm_branch (ctx, CCO, nek_timeout, yes);
+ return;
+ }
+ net = cp_sta_mgr_get_our_avln (ctx);
+ sta = cp_sta_mgr_sta_get_assoc (
+ ctx, net, ctx->cco_action.eks_sta_current_peer.tei);
+ if (sta && (ctx->cco_action.eks_eoc_retry < CP_EOC_CCO_EKS_RETRY))
+ {
+ cp_eoc_cco_action_nek_change_start (ctx, sta);
+ slab_release (sta);
+ cp_fsm_branch (ctx, CCO, nek_timeout, yes);
+ }
+ else
+ {
+ if (sta)
+ {
+ sta_t *mac_sta = mac_store_sta_get (
+ ctx->mac_store, ctx->cco_action.eks_sta_current_peer.tei);
+ dbg_assert (mac_sta);
+ mac_sta->tdma_poll = false;
+ ca_sta_update (ctx->ca, mac_sta);
+ blk_release (mac_sta);
+ slab_release (sta);
+ }
+ if ((sta = cp_cco_action_nek_next_sta (ctx)))
+ {
+ cp_eoc_cco_action_nek_change_start (ctx, sta);
+ slab_release (sta);
+ cp_fsm_branch (ctx, CCO, nek_timeout, yes);
+ }
+ else
+ {
+ ctx->cco_action.eks_sta_current_peer.tei = MAC_TEI_UNASSOCIATED;
+ cp_fsm_branch (ctx, CCO, nek_timeout, no);
+ }
+ }
+ DBG_PRINT ("mme_to[%d, %d]", tei, retry_count);
+}
+
+void
+cp_eoc_cco_action_nek_provide (cp_t *ctx)
+{
+ cp_net_t *net;
+ cp_sta_t *sta;
+ dbg_assert (ctx);
+
+ cp_sta_core_stop_timed_or_cyclic_event (ctx, &ctx->cco_action.nek_change);
+
+ if (ctx->cco_action.eks_sta_current_peer.tei == MAC_TEI_UNASSOCIATED)
+ {
+ cp_cco_action_gen_nek (ctx);
+
+ net = cp_sta_mgr_get_our_avln (ctx);
+ sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_ASSOC);
+
+ ctx->cco_action.eks_eoc_retry = 0;
+ if (sta)
+ {
+ cp_eoc_cco_action_nek_change_start (ctx, sta);
+ slab_release (sta);
+ }
+ DBG_PRINT("key_exc: s[%d]", ctx->cco_action.new_nek.eks);
+ }
+ else
+ DBG_PRINT("key_exc: wrk");
+ cp_eoc_cco_action__change_nek (ctx);
+}
+
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx)
+{
+ dbg_assert(ctx);
+ cp_sta_t *sta;
+ cp_sta_t *sta_next;
+ cp_net_t *net;
+
+ /* Stop the time out timer. */
+ cp_sta_core_stop_timed_or_cyclic_event (
+ ctx, &ctx->cco_action.leave_timer);
+
+ net = cp_sta_mgr_get_our_avln (ctx);
+
+ sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_ASSOC);
+ while (sta)
+ {
+ sta_next = cp_net_sta_get_next (ctx, net, sta);
+ if(sta->multi_sta.to_leave == true)
+ cp_sta_mgr_sta_remove (ctx, sta);
+ sta = sta_next;
+ }
+}
diff --git a/cesar/cp/eoc/cco/action/src/drv.c b/cesar/cp/eoc/cco/action/src/drv.c
new file mode 100644
index 0000000000..0684c63441
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/src/drv.c
@@ -0,0 +1,49 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/src/drv.c
+ * \brief DRV functions.
+ * \ingroup cp_eoc_cco_action
+ */
+
+#include "common/std.h"
+
+/* Private headers. */
+#include "cp/inc/context.h"
+#include "cp/msg/inc/msg_drv.h"
+
+/* Public headers. */
+#include "cp/eoc/cco/action/drv.h"
+#include "hal/arch/arch.h"
+#include "cl/mcast.h"
+
+void
+cp_eoc_cco_action_drv__drv_mcast_set_list_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ /* Check parameters. */
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ cp_msg_drv_result_t result = CP_MSG_DRV_RESULT_FAILURE;
+ igmp_groups_t *igmp_groups = NULL;
+ /* Lock DSR to avoid the CL to use corrupted entries. */
+ arch_dsr_lock ();
+ igmp_groups = cl_get_igmp_groups (ctx->cl);
+ if (cp_msg_drv_mcast_set_list_req_receive (
+ ctx, mme, &igmp_groups->nb, igmp_groups->group_mac,
+ igmp_groups->nb_total_members, igmp_groups->member_mac))
+ result = CP_MSG_DRV_RESULT_SUCCESS;
+ else
+ igmp_groups->nb = 0;
+ cl_update_igmp_groups (ctx->cl);
+ arch_dsr_unlock ();
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer,
+ DRV_MCAST_SET_LIST_CNF,
+ result);
+}
diff --git a/cesar/cp/eoc/cco/action/src/vs_eoc_master.c b/cesar/cp/eoc/cco/action/src/vs_eoc_master.c
new file mode 100644
index 0000000000..76a949dae9
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/src/vs_eoc_master.c
@@ -0,0 +1,821 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/src/vs_eoc_master.c
+ * \brief EoC master action, VS EoC MMEs req receive/cnf send
+ * functions
+ * \ingroup cp_eoc_cco_action
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+/* Private headers. */
+#include "cp/inc/context.h"
+#include "cp/eoc/msg/inc/msg_vs.h"
+#include "cp/eoc/inc/dbg_print.h"
+#include "mac/pbproc/inc/context.h"
+#include "ce/rx/bitloading/inc/nsr.h"
+#include "cp/eoc/msg/inc/msg_vs.h"
+
+/* Public headers. */
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/cco/bw/service.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+
+/* Config headers. */
+#include "config/cp/eoc/cco.h"
+
+#include "cp/sta/action/misc.h"
+
+/* ff:ff:ff:d7:13:00 */
+const mac_t MASTER_GOLDEN_MAC = 0xFFFFFFD71300ull;
+
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+#if CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED
+ uint i;
+ cp_net_t *net;
+ uint numStas = 0;
+ cp_tei_t stas_teis[MAC_TEI_STA_NB];
+ mac_t stas_macs[MAC_TEI_STA_NB];
+ u8 stas_authorizations[MAC_TEI_STA_NB];
+ u8 stas_output_levels[MAC_TEI_STA_NB];
+ u32 stas_start_times[MAC_TEI_STA_NB];
+ u32 stas_end_times[MAC_TEI_STA_NB];
+ cp_key_t stas_daks[MAC_TEI_STA_NB];
+ cp_dpw_t stas_dpws[MAC_TEI_STA_NB];
+ u8 stas_actions[MAC_TEI_STA_NB];
+
+ ctx->cco_action.wl_complete = false;
+ net = cp_sta_mgr_get_our_avln (ctx);
+ bool ok = cp_msg_vs_eoc_cco_set_wl_req_receive (
+ ctx, mme, &numStas, stas_teis, stas_macs, stas_authorizations,
+ stas_output_levels, stas_start_times, stas_end_times, stas_daks,
+ stas_dpws, stas_actions);
+
+ if (ok)
+ {
+ ctx->cco_action.wl_accept_all = 0;
+ /* Check for golden master special parameters. */
+ if (numStas == 1)
+ {
+ cp_key_t key = cp_secu_generate_keys (
+ ctx, (u8*) MASTER_GOLDEN_DPW,
+ strlen (MASTER_GOLDEN_DPW), CP_SECU_SALT_KEY_DAK);
+ if (MASTER_GOLDEN_MAC == stas_macs[0]
+ && !memcmp (&key, stas_daks, sizeof (key)))
+ {
+ cp_sta_own_data_set_dak (ctx, key);
+ ctx->cco_action.wl_accept_all = 1;
+ ctx->cco_action.gm_default_output_power =
+ stas_output_levels[0];
+ }
+ }
+ for (i = 0; i < numStas && !ctx->cco_action.wl_accept_all; i++)
+ {
+ cp_sta_t *sta;
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, stas_macs[i]);
+
+ if (stas_actions[i] == 1)
+ {
+ if (sta)
+ {
+ if (cp_eoc_sta_mgr_sta_is_assoc (ctx, net, stas_teis[i]))
+ {
+ cp_mme_peer_t peer = CP_MME_PEER (stas_macs[i],
+ stas_teis[i]);
+ sta->sta_in_wl = false;
+ cp_eoc_cco_action_vs__cco__cc_leave_ind (ctx, &peer);
+ sta->multi_sta.to_leave = true;
+ }
+ else
+ {
+ sta->sta_in_wl = false;
+ cp_sta_mgr_sta_remove (ctx, sta);
+ }
+ slab_release (sta);
+ }
+ }
+ else if (sta)
+ {
+ sta->sta_in_wl = true;
+ sta->multi_sta.allowed = stas_authorizations[i];
+ sta->multi_sta.output_level = stas_output_levels[i];
+
+ if (cp_eoc_sta_mgr_sta_is_assoc (ctx, net, stas_teis[i]))
+ {
+ cp_mme_peer_t peer = CP_MME_PEER (stas_macs[i],
+ stas_teis[i]);
+
+ if ((sta->multi_sta.allowed == true) &&
+ (sta->multi_sta.dak.key[0] == stas_daks[i].key[0]) &&
+ (sta->multi_sta.dak.key[1] == stas_daks[i].key[1]) &&
+ (sta->multi_sta.dak.key[2] == stas_daks[i].key[2]) &&
+ (sta->multi_sta.dak.key[3] == stas_daks[i].key[3]))
+ {
+ cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (ctx,
+ &peer);
+ }
+ else
+ {
+ sta->sta_in_wl = false;
+ cp_eoc_cco_action_vs__cco__cc_leave_ind (ctx, &peer);
+ sta->multi_sta.to_leave = true;
+ }
+ }
+ sta->multi_sta.dak = stas_daks[i];
+ sta->multi_sta.start_time = stas_start_times[i];
+ sta->multi_sta.end_time = stas_end_times[i];
+ sta->multi_sta.action = stas_actions[i];
+ sta->multi_sta.to_leave = false;
+ ((cp_sta_private_t *)sta)->tei = stas_teis[i];
+ ((cp_sta_private_t *)sta)->mac_address = stas_macs[i];
+ ((cp_sta_private_t *)sta)->net = net;
+ ((cp_sta_private_t *)sta)->dpw = stas_dpws[i];
+ slab_release (sta);
+ }
+ else
+ {
+ if (MAC_TEI_IS_STA (stas_teis[i]))
+ {
+ cp_sta_private_t *station;
+
+ station = (cp_sta_private_t *)
+ cp_sta_init (&ctx->sta_mgr.sta_slab_cache);
+
+ station->tei = stas_teis[i];
+ station->mac_address = stas_macs[i];
+ station->net = net;
+ if (stas_macs[i] != MAC_BROADCAST)
+ cp_eoc_sta_mgr_sta_insert_into_stas_list(ctx, station);
+
+ station->public_data.sta_in_wl = true;
+ station->public_data.multi_sta.allowed =
+ stas_authorizations[i];
+ station->public_data.multi_sta.output_level =
+ stas_output_levels[i];
+ station->public_data.multi_sta.start_time =
+ stas_start_times[i];
+ station->public_data.multi_sta.end_time =
+ stas_end_times[i];
+ station->public_data.multi_sta.dak = stas_daks[i];
+ station->public_data.multi_sta.action = stas_actions[i];
+ station->public_data.multi_sta.to_leave = false;
+ station->public_data.multi_sta.ports.port[0].index_of_service =
+ SERVICE_NOT_LIMITED;
+ station->dpw = stas_dpws[i];
+ }
+ }
+ }
+ }
+ /* Prevent double timer invocation in case of more than one
+ * VS_EOC_CCO_SET_WL_REQ message. */
+ cp_sta_core_stop_timed_or_cyclic_event (
+ ctx, &ctx->cco_action.leave_timer);
+
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ ctx, CP_FSM_EVENT_TYPE_leave_remove_delay);
+
+ cp_sta_core_gen_timed_event (ctx, &ctx->cco_action.leave_timer,
+ event, LEAVE_REMOVE_WAIT_TIMEOUT_MS);
+
+ cp_msg_vs_eoc_cco_set_wl_cnf_send (
+ ctx, &mme->peer, VS_EOC_CCO_SET_WL_CNF,
+ ok ? CP_MSG_VS_EOC_CCO_SET_WL_REQ_RESULT_SUCCESS
+ : CP_MSG_VS_EOC_CCO_SET_WL_REQ_RESULT_FAILURE);
+ /* If wl MME contains exactly WL_MME_MAX_ENTRY_COUNT entries,
+ an aditional wl MME always follows it. */
+ ctx->cco_action.wl_complete = (numStas != WL_MME_MAX_ENTRY_COUNT);
+ DBG_PRINT ("wl: ent_rcvd");
+#endif /* CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED */
+}
+
+void
+cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (
+ cp_t *ctx, cp_mme_peer_t *peer)
+{
+ dbg_assert (ctx);
+ dbg_assert (peer);
+
+ cp_sta_t *sta;
+ cp_net_t *net;
+ cp_tei_t tei;
+ uint output_level = 0;
+ bool ok;
+
+ net = cp_sta_mgr_get_our_avln (ctx);
+ tei = peer->tei;
+
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, tei);
+ if (sta)
+ {
+ output_level = sta->multi_sta.output_level;
+ ok = true;
+ slab_release (sta);
+ }
+ else
+ ok = false;
+
+ if (ok)
+ cp_msg_vs_eoc_cco_set_out_lev_ind_send (ctx, peer, output_level);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ uint i = 0;
+ uint j = 0;
+ uint numStas = 0;
+ cp_msg_vs_eoc_set_ports_req_result_t result =
+ CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_SUCCESS;
+ mac_t stas_macs[MAC_TEI_STA_NB];
+ u8 stas_port_ed[MAC_TEI_STA_NB][PORT_NB];
+ u8 stas_port_service[MAC_TEI_STA_NB][PORT_NB];
+
+ bool ok = cp_msg_vs_eoc_set_ports_req_receive (
+ ctx, mme, &numStas, stas_macs, stas_port_ed, stas_port_service);
+
+ if (ok)
+ {
+ for (i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac (ctx, stas_macs[i]);
+ if(sta)
+ {
+ for (j = 0; j < PORT_NB; j++)
+ {
+ sta->multi_sta.ports.port[j].enabled = stas_port_ed[i][j];
+ sta->multi_sta.ports.port[j].index_of_service =
+ stas_port_service[i][j];
+ }
+ slab_release (sta);
+ }
+ else
+ result = CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_FAILURE;
+ }
+ }
+ else
+ result = CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_FAILURE;
+ cp_msg_vs_eoc_set_ports_cnf_send (
+ ctx, &mme->peer, VS_EOC_SET_PORTS_CNF, result);
+
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (mme);
+
+ cp_net_t *net = NULL;
+
+ /* Sent data. */
+ cp_msg_vs_eoc_get_topo_cnf_result_t result;
+ u8 sta_nb = 0;
+ u8 assoc_sta_nb = 0;
+ u8 unassoc_sta_nb = 0;
+
+ cp_sta_t *sta = NULL;
+
+ /* Call Receive MME. */
+ bool ok = true;
+
+ /* Fill data for sending. */
+ if (ok)
+ {
+ net = cp_sta_mgr_get_our_avln (ctx);
+ dbg_assert_ptr (net);
+ sta_nb = net->num_stas;
+ assoc_sta_nb = net->num_associated_stas;
+ unassoc_sta_nb = sta_nb - assoc_sta_nb;
+
+ result = CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS;
+ }
+ else
+ {
+ result = CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_FAILURE;
+ }
+
+ /* Call Send MME. */
+ cp_mme_tx_t *reply = cp_msg_vs_eoc_get_topo_cnf_send_begin (
+ ctx, &mme->peer, result, sta_nb);
+
+ if ((result == CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS) && net)
+ {
+ /* Go through associated stations. */
+ for (sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_ASSOC);
+ sta;
+ sta = cp_net_sta_get_next (ctx, net, sta))
+ {
+ sta_t *station = mac_store_sta_get (
+ ctx->mac_store, cp_sta_get_tei (sta));
+ s8 agc_offset = cp_agc_offset (sta->multi_sta.output_level);
+ if (station && station->authenticated)
+ {
+ if (sta->authenticated_to_unassociated)
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (
+ ctx, reply, cp_sta_get_mac_address (sta),
+ 3 /* re-authenticated between
+ two successive get_topo calls. */,
+ station->agc_gain + agc_offset);
+ }
+ else
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (
+ ctx, reply, cp_sta_get_mac_address (sta),
+ 2 /* authenticated*/,
+ station->agc_gain + agc_offset);
+ }
+ }
+ else
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (
+ ctx, reply, cp_sta_get_mac_address (sta),
+ 1 /* associated*/,
+ station->agc_gain + agc_offset);
+
+ }
+
+ blk_release (station);
+ sta->authenticated_to_unassociated = false;
+ }
+ /* Go through unassociated stations. */
+ for (sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_UNASSOC);
+ sta;
+ sta = cp_net_sta_get_next (ctx, net, sta))
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (
+ ctx, reply, cp_sta_get_mac_address (sta),
+ 0 /* unassociated */,
+ 0);
+ }
+ }
+ cp_msg_vs_eoc_get_topo_cnf_send_end (ctx, reply);
+}
+
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+#if CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED
+ uint numStas = 0;
+ bool ok;
+ u8 first_wl_index_nb;
+ cp_tei_t stas_teis[MAC_TEI_STA_NB];
+ mac_t stas_macs[MAC_TEI_STA_NB];
+ u8 stas_authorizations[MAC_TEI_STA_NB];
+ u8 stas_output_levels[MAC_TEI_STA_NB];
+ u32 stas_start_times[MAC_TEI_STA_NB];
+ u32 stas_end_times[MAC_TEI_STA_NB];
+ cp_key_t stas_daks[MAC_TEI_STA_NB];
+ cp_dpw_t stas_dpws[MAC_TEI_STA_NB];
+ u8 stas_actions[MAC_TEI_STA_NB];
+
+ ok = cp_msg_vs_eoc_cco_get_wl_req_receive (ctx, mme, &first_wl_index_nb);
+
+ if (ok)
+ {
+ cp_eoc_sta_mgr_get_wl (
+ ctx, &numStas, stas_teis, stas_macs, stas_authorizations,
+ stas_output_levels, stas_start_times, stas_end_times, stas_daks,
+ stas_dpws, stas_actions);
+ }
+
+ cp_msg_vs_eoc_cco_get_wl_cnf_send (
+ ctx, ok ? CP_MSG_VS_EOC_CCO_GET_WL_REQ_RESULT_SUCCESS :
+ CP_MSG_VS_EOC_CCO_GET_WL_REQ_RESULT_FAILURE,
+ &mme->peer, numStas, stas_teis, stas_macs, stas_authorizations,
+ stas_output_levels, stas_start_times,
+ stas_end_times, stas_daks, stas_dpws, stas_actions,
+ first_wl_index_nb);
+#endif /* CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED */
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ uint numStas = 0;
+ bool ok;
+ u8 first_mac_index_nb;
+ mac_t stas_macs[MAC_TEI_STA_NB];
+ bool stas_port_ed[MAC_TEI_STA_NB][PORT_NB];
+ u8 stas_port_service[MAC_TEI_STA_NB][PORT_NB];
+
+ ok = cp_msg_vs_eoc_cco_get_ports_req_receive (ctx, mme,
+ &first_mac_index_nb);
+
+ if (ok)
+ {
+ cp_eoc_sta_mgr_get_ports (ctx, &numStas, stas_macs, stas_port_ed,
+ stas_port_service);
+ }
+
+ cp_msg_vs_eoc_cco_get_ports_cnf_send (
+ ctx, &mme->peer, ok ? CP_MSG_VS_EOC_CCO_GET_PORTS_REQ_RESULT_SUCCESS :
+ CP_MSG_VS_EOC_CCO_GET_PORTS_REQ_RESULT_FAILURE,
+ numStas, stas_macs, stas_port_ed, stas_port_service,
+ first_mac_index_nb);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ uint i, j;
+ cp_msg_vs_eoc_cco_set_services_req_result_t result =
+ CP_MSG_VS_EOC_CCO_SET_SERVICES_REQ_RESULT_SUCCESS;
+
+ u8 command;
+ u8 services_number;
+ u8 service_indexes[MAX_NUMBER_OF_SERVICES];
+ u8 classifier_rules[MAX_NUMBER_OF_SERVICES];
+ u16 classifier_values[MAX_NUMBER_OF_SERVICES];
+ u8 acses[MAX_NUMBER_OF_SERVICES];
+ u8 parameters_numbers[MAX_NUMBER_OF_SERVICES];
+ u16 parameters_lists[MAX_NUMBER_OF_SERVICES][SERVICE_PARAMETERS_NB];
+
+ bool ok = cp_msg_vs_eoc_cco_set_services_req_receive (
+ ctx, mme, &command, &services_number, service_indexes,
+ classifier_rules, classifier_values, acses, parameters_numbers,
+ parameters_lists);
+
+ if (ok)
+ {
+ /* Add services. */
+ if (command == 0)
+ {
+ for (i = 0; i < services_number; i++)
+ {
+ u16 parameters_list_tmp[SERVICE_PARAMETERS_NB];
+ cp_eoc_cco_bw_service_t *srv = NULL;
+ bool service_exists = true;
+ srv = cp_eoc_cco_bw_service_find (ctx, service_indexes[i]);
+ if (!srv)
+ {
+ srv = cp_eoc_cco_bw_service_alloc (ctx);
+ service_exists = false;
+ }
+ srv->service_index = service_indexes[i];
+ srv->classsif_rule = classifier_rules[i];
+ srv->classif_value = classifier_values[i];
+ srv->acs = acses[i];
+
+ for (j = 0; j < parameters_numbers[i]; j++)
+ {
+ parameters_list_tmp[j] = parameters_lists[i][j];
+ }
+
+ for (j = parameters_numbers[i];
+ j < SERVICE_PARAMETERS_NB; j++)
+ {
+ parameters_list_tmp[j] = 0x00;
+ }
+
+ srv->latency = parameters_list_tmp[0];
+ srv->jitter = parameters_list_tmp[1];
+ srv->dload_pir = parameters_list_tmp[2];
+ srv->uload_pir = parameters_list_tmp[3];
+ srv->dload_cir = parameters_list_tmp[4];
+ srv->uload_cir = parameters_list_tmp[5];
+ srv->qos_prio = parameters_list_tmp[6];
+
+ if (!service_exists)
+ {
+ cp_eoc_cco_bw_service_add (ctx, srv);
+ }
+ }
+ }
+ /* Remove services. */
+ else if (command == 1)
+ {
+ for(i = 0; i < services_number; i++)
+ {
+ bool ok2 = cp_eoc_cco_bw_service_remove (
+ ctx, service_indexes[i]);
+ if(!ok2)
+ {
+ result = CP_MSG_VS_EOC_CCO_SET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ }
+ }
+ /* Remove all services. */
+ else if (command == 2)
+ {
+ cp_eoc_cco_bw_service_t *service = NULL;
+ list_node_t *list_node;
+
+ while (!list_empty (&ctx->schedule.services.service_list))
+ {
+ list_node
+ = list_pop_back (&ctx->schedule.services.service_list);
+ service = PARENT_OF (cp_eoc_cco_bw_service_t, service_node,
+ list_node);
+ slab_release (service);
+ ctx->schedule.services.service_nb --;
+ }
+ }
+ /* Invalid command code. */
+ else
+ {
+ result = CP_MSG_VS_EOC_CCO_SET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ }
+ else
+ {
+ result = CP_MSG_VS_EOC_CCO_SET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ cp_msg_vs_eoc_cco_set_services_cnf_send (ctx, &mme->peer,
+ VS_EOC_CCO_SET_SERVICES_CNF,
+ result);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ u8 i = 0;
+ bool ok;
+ cp_msg_vs_eoc_cco_get_services_req_result_t result =
+ CP_MSG_VS_EOC_CCO_GET_SERVICES_REQ_RESULT_SUCCESS;
+ u8 first_service_index_nb;
+ u8 services_number = 0;
+ u8 service_indexes[MAX_NUMBER_OF_SERVICES];
+ u8 classifier_rules[MAX_NUMBER_OF_SERVICES];
+ u16 classifier_values[MAX_NUMBER_OF_SERVICES];
+ u8 acses[MAX_NUMBER_OF_SERVICES];
+ u8 parameters_numbers[MAX_NUMBER_OF_SERVICES];
+ u16 parameters_lists[MAX_NUMBER_OF_SERVICES][SERVICE_PARAMETERS_NB];
+
+ ok = cp_msg_vs_eoc_cco_get_services_req_receive (
+ ctx, mme, &first_service_index_nb);
+ if (ok)
+ {
+ services_number = ctx->schedule.services.service_nb;
+
+ list_node_t *list_node;
+ list_node = list_begin (
+ &ctx->schedule.services.service_list);
+
+ cp_eoc_cco_bw_service_t *srv = NULL;
+ for (i = 0; i < services_number; i++)
+ {
+ srv = PARENT_OF (cp_eoc_cco_bw_service_t, service_node,
+ list_node);
+ if (srv)
+ {
+ service_indexes[i] = srv->service_index;
+ classifier_rules[i] = srv->classsif_rule;
+ classifier_values[i] = srv->classif_value;
+ acses[i] = srv->acs;
+ parameters_lists[i][0] = srv->latency;
+ parameters_lists[i][1] = srv->jitter;
+ parameters_lists[i][2] = srv->dload_pir;
+ parameters_lists[i][3] = srv->uload_pir;
+ parameters_lists[i][4] = srv->dload_cir;
+ parameters_lists[i][5] = srv->uload_cir;
+ parameters_lists[i][6] = srv->qos_prio;
+ parameters_numbers[i] = SERVICE_PARAMETERS_NB;
+ }
+ else
+ {
+ result = CP_MSG_VS_EOC_CCO_GET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ list_node = list_next (list_node);
+ }
+ }
+ else
+ {
+ result = CP_MSG_VS_EOC_CCO_GET_SERVICES_REQ_RESULT_FAILURE;
+ }
+
+ cp_msg_vs_eoc_cco_get_services_cnf_send (
+ ctx, &mme->peer, result, services_number, service_indexes,
+ classifier_rules, classifier_values, acses, parameters_numbers,
+ parameters_lists, first_service_index_nb);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ sta_t *sta;
+
+ bool ok;
+ cp_msg_vs_eoc_get_info_req_result_t status =
+ CP_MSG_VS_EOC_GET_INFO_REQ_RESULT_SUCCESS;
+ u8 internal_eoc_index;
+ u8 control;
+ u16 tei = 0;
+ s8 attenuation = 0;
+ int attenuation_sum = 0;
+ int attenuation_sum_cnt = 0;
+ cp_net_t *net = NULL;
+ u8 assoc_sta_nb = 0;
+
+ set_node_t *current_node = NULL;
+ set_node_t *next_node = NULL;
+ cp_sta_t *current_sta = NULL;
+ u8 snr_sum = 0;
+ u8 snr = 0;
+ u8 snr_sum_cnt = 0;
+ u16 phy_uplink_speed = 0;
+ u16 phy_downlink_speed = 0;
+
+ u16 phy_uplink_speed_sum = 0;
+ u16 phy_downlink_speed_sum = 0;
+ u16 phy_uplink_speed_sum_cnt = 0;
+ u16 phy_downlink_speed_sum_cnt = 0;
+
+ u8 output_power = 0;
+ u32 tx_success_counter = 0;
+ u32 tx_crc_error_counter = 0;
+ u32 tx_other_error_counter = 0;
+ u32 rx_success_counter = 0;
+ u32 rx_crc_error_counter = 0;
+ u32 rx_other_error_counter = 0;
+
+
+ ok = cp_msg_vs_eoc_cco_get_info_req_receive (ctx, mme,
+ &internal_eoc_index,
+ &control);
+ if (ok)
+ {
+ tei = ctx->sta_mgr.sta_own_data.tei;
+ net = cp_sta_mgr_get_our_avln (ctx);
+ dbg_assert_ptr (net);
+ assoc_sta_nb = net->num_associated_stas;
+ if (!set_empty (&net->associated_stas))
+ {
+ next_node = set_begin (&net->associated_stas);
+ while (assoc_sta_nb)
+ {
+ dbg_assert_ptr (next_node);
+
+ current_node = next_node;
+ current_sta = PARENT_OF (cp_sta_t, node_net, current_node);
+ dbg_assert_ptr (current_sta);
+
+ sta = mac_store_sta_get (ctx->mac_store,
+ cp_sta_get_tei (current_sta));
+ if (sta->authenticated)
+ {
+ snr_sum += ce_rx_bl_nsr_compute_total_mean (
+ &sta->ce_rx_bt);
+ snr_sum_cnt ++;
+
+ attenuation_sum += sta->agc_gain
+ + cp_agc_offset (current_sta->multi_sta.output_level);
+ attenuation_sum_cnt ++;
+
+ phy_uplink_speed_sum += cp_sta_action_get_average_ble (
+ ctx, cp_sta_get_tei (current_sta), true, false);
+ phy_uplink_speed_sum_cnt ++;
+
+ phy_downlink_speed_sum += cp_sta_action_get_average_ble (
+ ctx, cp_sta_get_tei (current_sta), false, false);
+ phy_downlink_speed_sum_cnt ++;
+ }
+
+ next_node = set_next (&net->associated_stas, current_node);
+ assoc_sta_nb--;
+ }
+ snr = (snr_sum / snr_sum_cnt);
+ attenuation = (attenuation_sum / attenuation_sum_cnt);
+ phy_uplink_speed =
+ (phy_uplink_speed_sum / phy_uplink_speed_sum_cnt)
+ * MAX_THROUGHPUT_MBPS / DEFAULT_STREAM_QUALITY;
+ phy_downlink_speed =
+ (phy_downlink_speed_sum / phy_downlink_speed_sum_cnt)
+ * MAX_THROUGHPUT_MBPS / DEFAULT_STREAM_QUALITY;
+ }
+ else
+ {
+ snr = 0;
+
+ attenuation = 0;
+ phy_uplink_speed = 0;
+ phy_downlink_speed = 0;
+
+ }
+
+ /* N.A. */
+ output_power = 0;
+
+ if (control == 1)
+ {
+ ctx->pbproc->stats.tx_data = 0;
+ ctx->pbproc->stats.tx_data_cancel = 0;
+ ctx->pbproc->stats.tx_data_wack_noack = 0;
+ ctx->pbproc->stats.rx_data = 0;
+ ctx->pbproc->stats.rx_data_error = 0;
+ ctx->pbproc->stats.rx_crc_error = 0;
+ }
+ tx_success_counter = ctx->pbproc->stats.tx_data
+ - ctx->pbproc->stats.tx_data_cancel
+ - ctx->pbproc->stats.tx_data_wack_noack;
+ /* N.A. */
+ tx_crc_error_counter = 0;
+ tx_other_error_counter = ctx->pbproc->stats.tx_data_cancel
+ + ctx->pbproc->stats.tx_data_wack_noack;
+ rx_success_counter = ctx->pbproc->stats.rx_data
+ - ctx->pbproc->stats.rx_data_error;
+ rx_crc_error_counter = ctx->pbproc->stats.rx_crc_error;
+ rx_other_error_counter = ctx->pbproc->stats.rx_data_error;
+ }
+ else
+ {
+ status = CP_MSG_VS_EOC_GET_INFO_REQ_RESULT_FAILURE;
+ }
+
+ cp_msg_vs_eoc_cco_get_info_cnf_send (
+ ctx, &mme->peer, status, tei, attenuation, snr, phy_uplink_speed,
+ phy_downlink_speed, output_power,
+ tx_success_counter, tx_crc_error_counter, tx_other_error_counter,
+ rx_success_counter, rx_crc_error_counter, rx_other_error_counter);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ bool ok;
+ cp_msg_vs_eoc_diagnostic_info_req_result_t status =
+ CP_MSG_VS_EOC_DIAGNOSTIC_INFO_REQ_RESULT_SUCCESS;
+ u8 internal_eoc_index;
+ u8 control;
+ u8 assoc_stat = 0;
+ u64 nid = 0;
+ u8 num_slots = 0;
+ mac_t he_mac_address = 0;
+ u16 est_avg_phy_rate = 0;
+ u8 num_good_assoc_auth = 0;
+ u16 num_bad_could_not_assoc = 0;
+ u32 num_bad_assoc_failure = 0;
+ u32 num_bad_could_not_auth = 0;
+ u32 num_leave = 0;
+
+ ok = cp_msg_vs_eoc_cco_diagnostic_info_req_receive (
+ ctx, mme, &internal_eoc_index, &control);
+ if (ok)
+ {
+ /* N.A */
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (ctx);
+ assoc_stat = 2;
+ nid = cp_sta_own_data_get_nid (ctx);
+ num_slots = 1;
+ he_mac_address = cp_sta_own_data_get_mac_address (ctx);
+ est_avg_phy_rate = 0;
+ if (control == 1)
+ {
+ own->num_good_assoc_auth = 0;
+ own->num_bad_could_not_assoc = 0;
+ own->num_bad_assoc_failure = 0;
+ own->num_bad_could_not_auth = 0;
+ own->num_leave = 0;
+ }
+ num_good_assoc_auth = own->num_good_assoc_auth;
+ num_bad_could_not_assoc = own->num_bad_could_not_assoc;
+ num_bad_assoc_failure = own->num_bad_assoc_failure;
+ num_bad_could_not_auth = own->num_bad_could_not_auth;
+ num_leave = own->num_leave;
+ }
+ else
+ {
+ status = CP_MSG_VS_EOC_DIAGNOSTIC_INFO_REQ_RESULT_FAILURE;
+ }
+
+ cp_msg_vs_eoc_cco_diagnostict_info_cnf_send (
+ ctx, &mme->peer, status, assoc_stat, nid, num_slots, he_mac_address,
+ est_avg_phy_rate, num_good_assoc_auth, num_bad_could_not_assoc,
+ num_bad_assoc_failure, num_bad_could_not_auth, num_leave);
+}
diff --git a/cesar/cp/eoc/cco/action/stub/Module b/cesar/cp/eoc/cco/action/stub/Module
new file mode 100644
index 0000000000..8373bc43f5
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/Module
@@ -0,0 +1,7 @@
+SOURCES := cco_action.c drv.c
+
+ifeq ($(CONFIG_CP_EOC_IS_MASTER),y)
+ SOURCES += cco_action_master.c vs_eoc_master.c
+endif
+
+MODULES := cp/cco/action/stub
diff --git a/cesar/cp/eoc/cco/action/stub/src/cco_action.c b/cesar/cp/eoc/cco/action/stub/src/cco_action.c
new file mode 100644
index 0000000000..a08c7b5751
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/src/cco_action.c
@@ -0,0 +1,75 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/stub/src/cco_action.c
+ * \brief CCo functions stub.
+ * \ingroup cp_eoc_cco_action_stub
+ *
+ * Stub functions for the unit test of the other modules.
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+
+void
+cp_eoc_cco_action__power_on_no_beacons (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action__power_on_no_beacons (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action_poweron__idle__to_poweron (cp_t *ctx)
+ __attribute__((weak));
+void
+cp_eoc_cco_action_poweron__idle__to_poweron (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action__power_on_rx_beacon (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action__power_on_rx_beacon (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action__cco_drv_mac_stop (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action__cco_drv_mac_stop (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action__bcco_drv_mac_stop (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action__bcco_drv_mac_stop (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action__bcco_no_beacons (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action__bcco_no_beacons (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx)
+{}
+
+void
+cp_eoc_scheduler_prepare (void * user_data) __attribute__((weak));
+void
+cp_eoc_scheduler_prepare (void * user_data)
+{}
+
+void
+cp_eoc_cco_action_init (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action_init (cp_t *ctx) {}
+
+void
+cp_eoc_cco_action_uninit (cp_t *ctx) __attribute__((weak));
+void
+cp_eoc_cco_action_uninit (cp_t *ctx) {}
diff --git a/cesar/cp/eoc/cco/action/stub/src/cco_action_master.c b/cesar/cp/eoc/cco/action/stub/src/cco_action_master.c
new file mode 100644
index 0000000000..d839ab60a3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/src/cco_action_master.c
@@ -0,0 +1,68 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/stub/src/cco_action_master.c
+ * \brief CCo functions stub.
+ * \ingroup cp_eoc_cco_action_stub
+ *
+ * Stub functions for the unit test of the other modules.
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+void
+cp_eoc_cco_action_event_dispatch (cp_t *ctx, cp_mme_rx_t *mme)
+ __attribute__((weak));
+void
+cp_eoc_cco_action_event_dispatch (cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs__cco__cc_leave_ind (
+ cp_t *ctx, cp_mme_peer_t *peer)
+ __attribute__((weak));
+void
+cp_eoc_cco_action_vs__cco__cc_leave_ind (
+ cp_t *ctx, cp_mme_peer_t *peer)
+{}
+
+void
+cp_eoc_cco_action_nek_change_start_timeout (cp_t *ctx)
+ __attribute__((weak));
+void
+cp_eoc_cco_action_nek_change_start_timeout (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action__set_key_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+ __attribute__((weak));
+void
+cp_eoc_cco_action__set_key_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_nek_change_timeout (cp_t *ctx)
+ __attribute__((weak));
+void
+cp_eoc_cco_action_nek_change_timeout (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action_nek_provide (cp_t *ctx)
+ __attribute__((weak));
+void
+cp_eoc_cco_action_nek_provide (cp_t *ctx)
+{}
+
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx)
+ __attribute__((weak));
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx)
+{}
diff --git a/cesar/cp/eoc/cco/action/stub/src/drv.c b/cesar/cp/eoc/cco/action/stub/src/drv.c
new file mode 100644
index 0000000000..38f47676e8
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/src/drv.c
@@ -0,0 +1,24 @@
+/* Cesar-EoC project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/stub/src/drv.c
+ * \brief DRV functions stub.
+ * \ingroup cp_eoc_cco_action_stub
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+void
+cp_eoc_cco_action_drv__drv_mcast_set_list_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+void
+cp_eoc_cco_action_drv__drv_mcast_set_list_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
diff --git a/cesar/cp/eoc/cco/action/stub/src/vs_eoc_master.c b/cesar/cp/eoc/cco/action/stub/src/vs_eoc_master.c
new file mode 100644
index 0000000000..d51accde5c
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/src/vs_eoc_master.c
@@ -0,0 +1,96 @@
+/* Cesar-EoC project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/stub/vs_eoc.c
+ * \brief CCo action, Vendor Specific EoC MME stub.
+ * \ingroup cp_eoc_cco_action_stub
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (
+ cp_t *ctx, cp_mme_peer_t *peer) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (
+ cp_t *ctx, cp_mme_peer_t *peer)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
diff --git a/cesar/cp/eoc/cco/action/test/utest/Config b/cesar/cp/eoc/cco/action/test/utest/Config
new file mode 100644
index 0000000000..baaf313f89
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/Config
@@ -0,0 +1,14 @@
+CONFIG_CP_EOC = y
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF = "cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_EOC_IS_MASTER = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_FSM_DEF = "cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CP_EOC_CCO_ACTION_CON_ALLOWED = n
+CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED = y
+CONFIG_CP_STA_MGR_CCO_EOC = y
+CONFIG_MAC_COMMON_EOC_TEI = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 2
diff --git a/cesar/cp/eoc/cco/action/test/utest/Makefile b/cesar/cp/eoc/cco/action/test/utest/Makefile
new file mode 100644
index 0000000000..971241d654
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/Makefile
@@ -0,0 +1,21 @@
+BASE = ../../../../../..
+
+DEFS = -DSTA_CORE_UNIT_TEST=1
+
+INCLUDES = cp/eoc/cco/action/test/utest/override
+
+HOST_PROGRAMS = test_actions
+
+test_actions_SOURCES = test_actions.c stub.c
+test_actions_MODULES = lib mac/common \
+ cp/eoc/multi_sta_fsm cp/eoc/multi_sta/action \
+ cp/eoc/sta/mgr cp/eoc/msg cp/eoc/cco/action \
+ cp/eoc/cco/bw cp/secu \
+ cp/eoc/fsm/stub cp/eoc/beacon/stub mac/sar/stub bsu/stub \
+ cp/sta/core/stub cl/stub cp/eoc/sta/action/stub bufmgr/stub \
+ mac/pbproc/stub mac/ca/stub
+test_actions_CONFIG_MODULES = cp/eoc cl
+
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/cco/action/test/utest/inc/scenario_defs.h b/cesar/cp/eoc/cco/action/test/utest/inc/scenario_defs.h
new file mode 100644
index 0000000000..3efcca7681
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/inc/scenario_defs.h
@@ -0,0 +1,138 @@
+#ifndef inc_scenario_defs_h
+#define inc_scenario_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/scenario_defs.h
+ * \brief Scenario definitions.
+ * \ingroup test
+ */
+
+#include "cp/types.h"
+#include "cp/mme.h"
+//#include "cp/fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+
+/* Scenario globals. */
+#define SCENARIO_DEFS_GLOBALS \
+ cp_t *cp;
+
+/* Scenario actions. */
+#define SCENARIO_DEFS_ACTIONS \
+ post_and_process, \
+ post, \
+ trigger, \
+ post_urgent, \
+ process, \
+ process_urgent
+
+typedef struct
+{
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ cp_sta_t *sta;
+} scenario_action_param_t;
+
+typedef scenario_action_param_t scenario_action_post_and_process_t;
+typedef scenario_action_param_t scenario_action_post_t;
+typedef scenario_action_param_t scenario_action_trigger_t;
+typedef scenario_action_param_t scenario_action_post_urgent_t;
+typedef scenario_action_param_t scenario_action_process_t;
+typedef scenario_empty_t scenario_action_process_urgent_t;
+
+void
+scenario_action_post_and_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_post_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_trigger_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_post_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_process_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+/* Scenario events. */
+
+#define SCENARIO_DEFS_EVENTS \
+ cp_eoc_multi_sta_fsm_handled_event,\
+ cp_eoc_multi_sta_fsm__unassociated__timeout_assoc,\
+ cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ,\
+ cp_eoc_multi_sta_fsm__associated__timeout_auth,\
+ cp_eoc_multi_sta_fsm__associated__cc_leave,\
+ cp_eoc_multi_sta_fsm__authenticated__cc_leave,\
+ cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ,\
+ cp_eoc_multi_sta_fsm__authenticated__lost_connection,\
+ cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection,\
+ cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND,\
+ cp_eoc_multi_sta_fsm__disconnected__CC_ASSOC_REQ,\
+ cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ
+
+
+typedef struct
+{
+ //cp_fsm_branch_t branch;
+ cp_eoc_multi_sta_fsm_branch_t branch;
+ cp_sta_t *sta;
+} scenario_event_transition_with_branch_t;
+
+
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_eoc_multi_sta_fsm__disconnected__CC_ASSOC_REQ_t;
+
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm_handled_event_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__unassociated__timeout_assoc_t;
+
+// typedef scenario_empty_t
+// scenario_event_cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__associated__timeout_auth_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__associated__cc_leave_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__authenticated__cc_leave_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__authenticated__lost_connection_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection_t;
+
+typedef scenario_empty_t
+scenario_event_cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND_t;
+
+
+
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h b/cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h
new file mode 100644
index 0000000000..b43ccc39ba
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h
@@ -0,0 +1,98 @@
+#ifndef override_cp_inc_context_h
+#define override_cp_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/inc/context.h
+ * \brief Control plane context override.
+ * \ingroup test
+ */
+
+#include "cp/eoc/beacon/beacon.h"
+#include "cp/eoc/beacon/inc/beacon.h"
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+#include "cp/inc/trace.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta_mgr.h"
+#include "mac/common/config.h"
+#include "mac/common/store.h"
+#include "mac/sar/sar.h"
+#include "cl/cl.h"
+#include "cp/msg/inc/context.h"
+#include "lib/rnd.h"
+#include "interface/interface.h"
+#include "cp/sta/core/defs.h"
+#include "cp/sta/action/inc/context.h"
+#include "cp/eoc/cco/action/inc/cco_action.h"
+#include "cp/cco/action/inc/cco_action.h"
+#include "cp/cco/bw/bw.h"
+#include "cp/cco/bw/inc/context.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "cp/cl_interf/cl_interf.h"
+#include "cp/cl_interf/inc/context.h"
+#include "cp/cp.h"
+#include "cp/types.h"
+#include "mac/pbproc/inc/context.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "cp/cco/bw/bw.h"
+#include "cp/cco/bw/inc/context.h"
+#include "bufmgr/bufmgr.h"
+
+struct cp_t
+{
+#if CONFIG_TRACE
+ /** Trace context. */
+ trace_buffer_t trace;
+#endif /* CONFIG_TRACE */
+
+ /** FSM context. */
+ cp_fsm_t fsm;
+ /** STA core flag. */
+ bool sta_core_flag;
+ /** STA core urgent flag. */
+ bool sta_core_urgent_flag;
+ /** CCo Action. */
+ cp_cco_action_t cco_action;
+ /** STA action*/
+ cp_sta_action_t sta_action;
+ /** station manager context*/
+ cp_sta_mgr_t sta_mgr;
+ /** MAC config contest*/
+ mac_config_t *mac_config;
+ /** Mac store /dataplane */
+ mac_store_t *mac_store;
+ /** Convergence Layer context */
+ cl_t *cl;
+ /** Segmentation and reassembly context */
+ sar_t *sar;
+ /** messages context. */
+ cp_msg_t msg;
+ pbproc_t *pbproc;
+ /** EoC scheduling context */
+ cp_eoc_cco_bw_sched_t schedule;
+ /** Bandwidth Manager context. */
+ cp_cco_bw_t bw;
+ /** Channel access context. */
+ ca_t *ca;
+ /** Context of the bsu. */
+ bsu_t *bsu;
+
+ cp_beacon_t beacon;
+ lib_rnd_t rnd;
+ interface_t *interface;
+ cp_cl_interf_t cl_interf;
+
+ /** Context of the aclf. */
+ bsu_aclf_t *bsu_aclf;
+
+ /* Buffer manager. */
+ bufmgr_t *bufmgr;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/core.h b/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/core.h
new file mode 100644
index 0000000000..ab53723c91
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/core.h
@@ -0,0 +1,49 @@
+#ifndef override_cp_sta_core_core_h
+#define override_cp_sta_core_core_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/sta/core/core.h
+ * \brief STA Core override.
+ * \ingroup test
+ */
+
+#include "cp/inc/context.h"
+
+BEGIN_DECLS
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx);
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx);
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx);
+
+void
+cp_sta_core_checkpoint (cp_t *ctx);
+
+void
+cp_sta_core_signal_recv_mme_event(cp_t *cp_ctx);
+
+void
+cp_sta_core_gen_timed_event(cp_t *cp_ctx,
+ cp_sta_core_timed_event_def_t *sta_core_timed_event,
+ cp_fsm_event_t *fsm_event,
+ uint event_delay_ms);
+
+void
+cp_sta_core_stop_timed_or_cyclic_event(cp_t *cp_ctx,
+ cp_sta_core_timed_event_def_t *sta_core_timed_event);
+
+u32
+cp_sta_core_tck_per_rtc (cp_t *ctx);
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/defs.h b/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..71be233993
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/defs.h
@@ -0,0 +1,57 @@
+#ifndef cp_sta_core_defs_h
+#define cp_sta_core_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/core/defs.h
+ * \brief Sta core defs.
+ * \ingroup cp/sta/core
+ *
+ */
+#include "cp/fsm/forward.h"
+
+/** Forward declaration. */
+typedef struct cp_sta_core_t cp_sta_core_t;
+
+/*
+ * the sta core event flags
+ * these are some flags, so take care to give a value with all bits set to 0 but one.
+ */
+enum cp_sta_core_event_flag_t
+{
+ CP_STA_CORE_EVENT_FLAG_RECV_BEACON = 0x1,
+ CP_STA_CORE_EVENT_FLAG_RECV_MME = 0x2,
+ CP_STA_CORE_EVENT_FLAG_FSM = 0x4,
+ CP_STA_CORE_EVENT_FLAG_GARBAGE = 0x8,
+ CP_STA_CORE_EVENT_FLAG_TERMINATE = 0x10
+};
+typedef enum cp_sta_core_event_flag_t cp_sta_core_event_flag_t;
+
+/** Definition of alarm info structure
+ * (applications should not use it directly but use "alias" defined just below) */
+struct cp_sta_core_timed_event_def_t
+{
+ /* eCos alarm. */
+ uint alarm;
+ /* eCos alarm handle. */
+ uint alarm_handle;
+ /* the sta core event flag to set
+ * (auto or user-specified when creating/launching timer alarm). */
+ cp_sta_core_event_flag_t event_flag;
+ /* FSM event specified when creating/launching timer alarm
+ * (set if the previous flag is CP_STA_CORE_EVENT_FLAG_FSM). */
+ cp_fsm_event_t *fsm_event;
+ /* flag indicating a periodic alarm (if set to true)
+ * or one-shot alarm (if set to false). */
+ bool cyclic_alarm;
+ /* pointer to CP context. */
+ cp_t *cp_ctx;
+};
+typedef struct cp_sta_core_timed_event_def_t cp_sta_core_timed_event_def_t;
+
+#endif /* cp_sta_core_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/override/cyg/kernel/kapi.h b/cesar/cp/eoc/cco/action/test/utest/override/cyg/kernel/kapi.h
new file mode 100644
index 0000000000..019e5d3a07
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/cyg/kernel/kapi.h
@@ -0,0 +1,37 @@
+#ifndef override_cyg_kernel_kapi_h
+#define override_cyg_kernel_kapi_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cyg/kernel/kapi.h
+ * \brief override some kernel api from <cyg/kernel/kapi.h>.
+ * \ingroup cp_msg
+ *
+ *
+ */
+
+struct cyg_resolution_t
+{
+ u32 dividend;
+ u32 divisor;
+} ;
+
+typedef struct cyg_resolution_t cyg_resolution_t;
+
+typedef u64 cyg_tick_count_t;
+
+int
+cyg_real_time_clock (void);
+
+cyg_resolution_t
+cyg_clock_get_resolution (int clock);
+
+cyg_tick_count_t
+cyg_current_time (void);
+
+#endif
diff --git a/cesar/cp/eoc/cco/action/test/utest/override/mac/sar/inc/context.h b/cesar/cp/eoc/cco/action/test/utest/override/mac/sar/inc/context.h
new file mode 100644
index 0000000000..b74c7a57e3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/mac/sar/inc/context.h
@@ -0,0 +1,23 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/stub.c b/cesar/cp/eoc/cco/action/test/utest/src/stub.c
new file mode 100644
index 0000000000..c91260eecb
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/stub.c
@@ -0,0 +1,56 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file eoc/sta/action/test/utest/src/msg_stub.c
+ * \brief cp/sta/mgr/sta_mgr stub
+ * \ingroup test
+ *
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/inc/context.h"
+#include "cp/msg/inc/cc_assoc.h"
+#include <cyg/kernel/kapi.h>
+
+
+#define BSU_ACLF_BP_CABLE_TCK 2500000
+#define TCK_PER_RTC 250000
+
+u32
+cp_sta_core_tck_per_rtc (cp_t *ctx)
+{
+
+ return TCK_PER_RTC;
+}
+
+u32
+bsu_aclf_beacon_period_tck (bsu_aclf_t *ctx)
+{
+ return BSU_ACLF_BP_CABLE_TCK;
+}
+
+cyg_tick_count_t
+cyg_current_time (void)
+{
+ /* For tests purpose we can simulate 1000 beacon periods */
+ return (u32)((BSU_ACLF_BP_CABLE_TCK * 1000ull) / TCK_PER_RTC);
+}
+
+u8
+ce_rx_bl_nsr_compute_total_mean (ce_rx_bitloading_t *bl)
+{
+ return 1;
+}
+
+u8
+cp_sta_action_get_average_ble (cp_t *ctx, cp_tei_t tei, bool tx,
+ bool fc_format)
+{
+ return 0;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/test_actions.c b/cesar/cp/eoc/cco/action/test/utest/src/test_actions.c
new file mode 100644
index 0000000000..3545b61b47
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/test_actions.c
@@ -0,0 +1,471 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_actions.c
+ * \brief Test eoc cco action module.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/inc/context.h"
+#include "cl/inc/context.h"
+#include "cp/eoc/msg/msg.h"
+#include "cp/eoc/msg/inc/vs_eoc_get_topo.h"
+#include "mac/sar/inc/context.h"
+#include "common/defs/spidcom.h"
+#include "cp/eoc/msg/inc/msg_vs.h"
+#include "cp/eoc/cco/action/vs_eoc_master.h"
+
+void
+cp_eoc_cco_action__power_on_no_beacons (cp_t *ctx);
+
+/** Override MFS store context. */
+struct mac_store_t
+{
+};
+
+static cp_t cp;
+static mac_config_t mac_config;
+static mac_store_t mac_store;
+static cl_t cl;
+static sar_t sar;
+
+struct mme_header_t
+{
+ mac_t oda;
+ mac_t osa;
+ uint vlan;
+ uint mtype;
+ uint mmv;
+ mmtype_t mmtype;
+ uint fmi_inf;
+ uint fmi_mi;
+ uint fmi_ssn;
+};
+typedef struct mme_header_t mme_header_t;
+
+static u8 buffer[2048];
+
+mac_t own_mac_addr = 0x123456789ABCull;
+mac_t my_mac_addr = 0x112233445566ull;
+cp_nid_t nid = 0x1234567;
+test_t test;
+cp_mme_peer_t peer;
+cp_net_t *net;
+
+static void
+test_write_header (bool vlan_present, mme_header_t *pheader,
+ bitstream_t *pstream)
+{
+ bitstream_init (pstream, buffer, ETH_PACKET_MAX_NOVLAN_SIZE,
+ BITSTREAM_WRITE);
+
+ bitstream_write_large (pstream, pheader->oda, 48);
+ bitstream_write_large (pstream, pheader->osa, 48);
+ bitstream_write (pstream, HPAV_MTYPE_MME, 16);
+ bitstream_write (pstream, HPAV_MMV, 8);
+ bitstream_write (pstream, pheader->mmtype, 16);
+ bitstream_write (pstream, pheader->fmi_inf, 4);
+ bitstream_write (pstream, pheader->fmi_mi, 4);
+ bitstream_write (pstream, pheader->fmi_ssn, 8);
+ if (pheader->mmtype >= VS_MIN && pheader->mmtype <= VS_MAX)
+ bitstream_write (pstream, SPC_OUI, 24);
+}
+
+static void
+test_read_header (bool vlan_present, mme_header_t *pheader,
+ mme_header_t *pexpected, bitstream_t *pstream)
+{
+ bitstream_init (pstream, buffer, ETH_PACKET_MAX_NOVLAN_SIZE,
+ BITSTREAM_READ);
+
+ pheader->oda = bitstream_read_large (pstream, 48);
+ pheader->osa = bitstream_read_large (pstream, 48);
+ if (vlan_present)
+ pheader->vlan = bitstream_read (pstream, 32);
+ pheader->mtype = bitstream_read (pstream, 16);
+ pheader->mtype = pheader->mtype;
+ pheader->mmv = bitstream_read (pstream, 8);
+ pheader->mmtype = bitstream_read (pstream, 16);
+ pheader->fmi_inf = bitstream_read (pstream, 4);
+ pheader->fmi_mi = bitstream_read (pstream, 4);
+ pheader->fmi_ssn = bitstream_read (pstream, 8);
+ if (MMTYPE_IS_VS (pheader->mmtype) || MMTYPE_IS_IMAC (pheader->mmtype))
+ bitstream_read (pstream, 24);
+
+ test_begin (test, "Header")
+ {
+ test_fail_if (pheader->oda != pexpected->oda);
+ test_fail_if (pheader->osa != pexpected->osa);
+ test_fail_if (pheader->mtype != HPAV_MTYPE_MME);
+ test_fail_if (pheader->mmv != HPAV_MMV);
+ test_fail_if (pheader->mmtype != pexpected->mmtype);
+ test_fail_if (pheader->fmi_inf != pexpected->fmi_inf);
+ test_fail_if (pheader->fmi_mi != pexpected->fmi_mi);
+ test_fail_if (pheader->fmi_ssn != pexpected->fmi_ssn);
+ }
+ test_end;
+}
+
+void
+test_case_vs_eoc_get_topo (test_t test)
+{
+ test_case_begin (test, "VS_EOC_GET_TOPO");
+
+ test_begin (test, "VS_EOC_GET_TOPO.REQ Receive")
+ {
+ bitstream_t stream;
+ mme_header_t header;
+ mme_header_t expected;
+ uint fmi;
+ u64 data;
+ cp_t *ctx = &cp;
+
+ cp_mme_rx_t *rx_mme;
+ bool res;
+ /* init msg */
+ cp_msg_init (ctx);
+
+
+ /* add my sta to avln */
+ cp_sta_t *my_sta;
+ cp_tei_t my_tei = 5;
+ my_sta = cp_sta_mgr_sta_add (ctx, net, my_tei, my_mac_addr);
+ sta_t *sta = mac_store_sta_get (ctx->mac_store, my_tei);
+ s8 sta_attenuation_db;
+
+ my_sta->multi_sta.output_level = 90;
+ /* AGC gain value depends on the output level of the emitter */
+ sta->agc_gain = 42;
+ /*********************************/
+ /* Good values. */
+ /*********************************/
+ u8 result = CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS;
+ u8 sta_nb = 1;
+
+ /* Build MME Header */
+ header.oda = own_mac_addr;
+ header.osa = peer.mac;
+ header.mmtype = VS_EOC_GET_TOPO_REQ;
+ header.fmi_inf = 0;
+ header.fmi_mi = 0;
+ header.fmi_ssn = 0;
+
+ test_write_header (false, &header, &stream);
+
+ /*********************************/
+ /* Receive MME (empty data) */
+ /*********************************/
+ bitstream_finalise (&stream);
+
+ /* Receive MME */
+ rx_mme = cp_msg_mme_read_header (&cp, buffer,
+ ETH_PACKET_MAX_NOVLAN_SIZE,
+ peer.tei, &fmi);
+ test_fail_unless (rx_mme != NULL);
+ test_fail_unless (rx_mme->mmtype == VS_EOC_GET_TOPO_REQ);
+ data = cp_msg_mme_read_error (ctx, rx_mme);
+ test_fail_unless (data == true);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (ctx, rx_mme);
+
+ /* Expected header */
+ expected.oda = peer.mac;
+ expected.osa = own_mac_addr;
+ expected.mmtype = VS_EOC_GET_TOPO_CNF;
+ expected.fmi_inf = 0;
+ expected.fmi_mi = 0;
+ expected.fmi_ssn = 0;
+
+ /* Read MME for Data comparison. */
+ test_read_header (false, &header, &expected, &stream);
+
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != result, "Wrong Result");
+
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != sta_nb, "Wrong station number");
+
+ bitstream_access (&stream, &data, 48);
+ test_fail_unless (data == my_mac_addr);
+ bitstream_access (&stream, &data, 8);
+ test_fail_unless (data == 1);
+ bitstream_access (&stream, &sta_attenuation_db, 8);
+ test_fail_unless (sta_attenuation_db == 10);
+
+ /* End TEST VS_EOC_GET_TOPO.REQ Receive */
+ slab_release (rx_mme);
+ blk_release (sta);
+ res = mac_store_sta_remove (cp.mac_store, my_tei);
+ test_fail_unless (res == true);
+ slab_release (my_sta);
+
+ /* remove my sta from avln */
+ cp_sta_mgr_sta_remove_from_mac (ctx, my_mac_addr);
+
+ /* uninit msg */
+ cp_msg_uninit (ctx);
+ }
+ test_end;
+}
+
+void
+test_case_vs_eoc_cco_get_wl (test_t test)
+{
+ test_case_begin (test, "VS_EOC_CCO_GET_WL");
+
+ test_begin (test, "VS_EOC_CCO_GET_WL.REQ Receive")
+ {
+ uint i;
+ uint j;
+ bitstream_t stream;
+ mme_header_t header;
+ mme_header_t expected;
+ uint fmi;
+ u64 data;
+ cp_t *ctx = &cp;
+ cp_mme_rx_t *rx_mme;
+ bool res;
+ uint total_wl_index_nb = 4;
+ uint first_wl_index_nb = 0;
+ uint wl_index_nb = 4;
+
+ /* init msg */
+ cp_msg_init (ctx);
+
+ /* add my sta to avln */
+ cp_sta_t *my_stas[5];
+ cp_tei_t my_teis[5];
+ mac_t my_macs[5];
+
+ for (i=0; i < 5; i++)
+ {
+ my_teis[i] = i;
+ my_macs[i] = 0x112233445500ull + i;
+ my_stas[i] = cp_sta_mgr_sta_add (ctx, net, my_teis[i], my_macs[i]);
+ my_stas[i]->multi_sta.allowed = 1;
+ my_stas[i]->multi_sta.output_level = 2;
+ my_stas[i]->multi_sta.start_time = 55;
+ my_stas[i]->multi_sta.end_time = 77;
+ my_stas[i]->multi_sta.dak.key[0] = 0x11223344;
+ my_stas[i]->multi_sta.dak.key[1] = 0x55667788;
+ my_stas[i]->multi_sta.dak.key[2] = 0x99001122;
+ my_stas[i]->multi_sta.dak.key[3] = 0x33445566;
+ strcpy (((cp_sta_private_t *)my_stas[i])->dpw.dpw,
+ "SPiDCOM - SPC300");
+ my_stas[i]->multi_sta.action = 1;
+ }
+ /*********************************/
+ /* Good values. */
+ /*********************************/
+ u8 result = CP_MSG_VS_EOC_CCO_GET_WL_REQ_RESULT_SUCCESS;
+ u8 sta_nb = 4;
+
+ /* Build MME Header */
+ header.oda = own_mac_addr;
+ header.osa = peer.mac;
+ header.mmtype = VS_EOC_CCO_GET_WL_REQ;
+ header.fmi_inf = 0;
+ header.fmi_mi = 0;
+ header.fmi_ssn = 0;
+
+ test_write_header (false, &header, &stream);
+
+ /*********************************/
+ /* Receive MME (empty data) */
+ /*********************************/
+ bitstream_finalise (&stream);
+
+ /* Receive MME */
+ rx_mme = cp_msg_mme_read_header (&cp, buffer,
+ ETH_PACKET_MAX_NOVLAN_SIZE,
+ peer.tei, &fmi);
+ test_fail_unless (rx_mme != NULL);
+ test_fail_unless (rx_mme->mmtype == VS_EOC_CCO_GET_WL_REQ);
+ data = cp_msg_mme_read_error (ctx, rx_mme);
+ test_fail_unless (data == true);
+
+ cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (ctx, rx_mme);
+
+ /* Expected header */
+ expected.oda = peer.mac;
+ expected.osa = own_mac_addr;
+ expected.mmtype = VS_EOC_CCO_GET_WL_CNF;
+ expected.fmi_inf = 0;
+ expected.fmi_mi = 0;
+ expected.fmi_ssn = 0;
+
+ /* Read MME for Data comparison. */
+ test_read_header (false, &header, &expected, &stream);
+
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != result, "Wrong Result");
+
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != total_wl_index_nb, "Wrong total_wl_index_nb");
+
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != first_wl_index_nb, "Wrong first_wl_index_nb");
+
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != wl_index_nb, "Wrong wl_index_nb");
+
+ for(i = 0; i < sta_nb; i++)
+ {
+ bitstream_access (&stream, &data, 48);
+ test_fail_if ((data != my_macs[i+1]), "Wrong mac address");
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != my_teis[i+1], "Wrong tei");
+ test_fail_if (data == 0, "Tei = 0");
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != my_stas[i+1]->multi_sta.allowed,
+ "Wrong authorization");
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != my_stas[i]->multi_sta.output_level,
+ "Wrong output level");
+ bitstream_access (&stream, &data, 32);
+ test_fail_if (data != my_stas[i]->multi_sta.start_time,
+ "Wrong start time");
+ bitstream_access (&stream, &data, 32);
+ test_fail_if (data != my_stas[i]->multi_sta.end_time,
+ "Wrong end time");
+ for (j=0; j<4; j++)
+ {
+ bitstream_access (&stream, &data, 32);
+ test_fail_if (data != my_stas[i]->multi_sta.dak.key[j],
+ "Wrong sta dak");
+ }
+ for (j=0; j<CP_DPW_MAX_SIZE; j++)
+ {
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != (u64)((cp_sta_private_t *)my_stas[i])->dpw.dpw[j],
+ "Wrong sta dak");
+ }
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != my_stas[i]->multi_sta.action,
+ "Wrong action");
+ }
+
+ /* End TEST VS_EOC_CCO_GET_WL.REQ Receive */
+
+ slab_release (rx_mme);
+
+ for (i = 0; i < 4; i++)
+ {
+ res = mac_store_sta_remove (cp.mac_store, my_teis[i+1]);
+ test_fail_unless (res == true);
+ }
+
+ /* remove my sta from avln */
+ for (i = 0; i < 5; i++)
+ {
+ slab_release (my_stas[i]);
+ cp_sta_mgr_sta_remove_from_mac (ctx, my_macs[i]);
+ }
+ /* uninit msg */
+ cp_msg_uninit (ctx);
+ }
+ test_end;
+}
+
+int
+main (void)
+{
+ test_t test;
+ test_init (test, 0, NULL);
+
+ /* configure cp */
+ cp.mac_config = &mac_config;
+ cp.mac_store = &mac_store;
+ cp.cl = &cl;
+ cp.sar=&sar;
+
+ lib_stats_init();
+
+ /* init sta manager */
+ cp_eoc_sta_mgr_init (&cp);
+
+ /* add avln */
+ cp_snid_t snid = 4;
+ net = cp_sta_mgr_add_avln (&cp, snid, nid);
+
+ /* set avln */
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ /* set sta own data */
+ cp_tei_t own_tei = 4;
+ cp_sta_own_data_set_nid (&cp, nid);
+ cp_sta_own_data_set_mac_address (&cp, own_mac_addr);
+ cp_sta_own_data_set_tei (&cp, own_tei);
+ cp_sta_own_data_set_cco_status (&cp, true);
+
+ /* configure peer */
+ peer.mac = 0x23456789ABCDull;
+ peer.eth_type = HPAV_MTYPE_MME;
+ peer.vlan_tci = 0x0;
+ peer.tei = MAC_TEI_FOREIGN;
+
+ /* 1. test VS_EOC_GET_TOPO */
+ test_case_vs_eoc_get_topo (test);
+
+ /* 2. test VS_EOC_CCO_GET_WL */
+ test_case_vs_eoc_cco_get_wl (test);
+
+ /* 3. test power on */
+ test_begin (test, "Compile");
+ {
+ cp_eoc_cco_action__power_on_no_beacons (&cp);
+ }
+ test_end;
+
+ /* remove avln */
+ cp_sta_mgr_remove_avln (&cp, snid, nid);
+
+ /* uninit sta own data */
+ cp_sta_own_data_uninit (&cp);
+
+ /* uninit sta manager */
+ cp_sta_mgr_uninit (&cp);
+
+ /* uninit net */
+ cp_net_uninit (&cp, net);
+
+ lib_stats_uninit();
+
+ /* 4. check memory usage */
+ test_begin (test, "Memory verification")
+ {
+ test_fail_if (blk_check_memory() == false, "Memory not freed");
+ }
+ test_end;
+
+ /* 5. check test result */
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
+
+u8 *
+cp_cl_interf_get_buffer_tx (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return buffer;
+}
+
+/**
+ * Send a MME over the PWL or the HLE.
+ * \param ctx the module context.
+ * \param mme The MME to send.
+ *
+ */
+void
+cp_cl_interf_mme_send (cp_t *ctx, cp_mme_tx_t * mme)
+{
+ mme->p_mme = NULL;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/Makefile b/cesar/cp/eoc/cco/action/test/utest_eoc/Makefile
new file mode 100644
index 0000000000..b238673cdd
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/Makefile
@@ -0,0 +1,12 @@
+all: fsm actions
+
+fsm: fsm-Makefile
+ make -f fsm-Makefile
+
+actions: actions-Makefile
+ make -f actions-Makefile
+
+clean: fsm-Makefile actions-Makefile
+ make -f fsm-Makefile clean
+ make -f actions-Makefile clean
+ rmdir obj
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/actions-Config b/cesar/cp/eoc/cco/action/test/utest_eoc/actions-Config
new file mode 100644
index 0000000000..c052411539
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/actions-Config
@@ -0,0 +1,23 @@
+CONFIG_CP_EOC = y
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_IS_MASTER = y
+CONFIG_CP_FSM_DEF = "cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_ATU_FACTOR = 3
+CONFIG_MAC_COMMON_EOC_SCHED = y
+
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_TRACE_ON_FATAL = y
+CONFIG_TRACE = n
+CONFIG_STATS = y
+CONFIG_CP_STA_MGR_CCO_EOC = y
+CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED = y
+CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 1
+CONFIG_MAC_COMMON_EOC_TEI = y
+
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/actions-Makefile b/cesar/cp/eoc/cco/action/test/utest_eoc/actions-Makefile
new file mode 100644
index 0000000000..a98efadbb3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/actions-Makefile
@@ -0,0 +1,29 @@
+BASE = ../../../../../..
+
+VARIANT = actions
+
+DEFS = -DSTA_CORE_UNIT_TEST=1
+
+
+INCLUDES = cp/eoc/cco/action/test/utest_eoc \
+ cp/eoc/cco/action/test/utest_eoc/override
+
+HOST_PROGRAMS = test_actions
+
+test_actions_SOURCES = test_actions.c actions.c msg_vs.c core_stub.c\
+ dataplane_stub.c cp_stub.c ce_rx_stub.c fsm_event_stub.c \
+ hal_phy_stub.c cyg_stub.c cl_interf_stub.c cp_msg_stub.c
+
+test_actions_MODULES = lib lib/scenario mac/common cp/eoc/msg/stub \
+ cp/eoc/sta/mgr cp/eoc/sta/action cp/sta/core/stub \
+ cp/eoc/multi_sta_fsm cp/eoc/multi_sta/action \
+ cp/eoc/cco/action cp/eoc/cco/bw cp/msg \
+ cp/eoc/beacon/stub cp/eoc/fsm/stub \
+ cl/stub cp/secu interface/stub ce/rx/stub ce/tx/stub \
+ mac/sar/stub mac/pbproc/stub mac/ca/stub bsu/stub bufmgr/stub
+
+cp_msg_MODULE_SOURCES = msg_drv.c
+test_actions_CONFIG_MODULES = cp/eoc cl mac/sar
+test_actions_LDLIBS = -lm
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Config b/cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Config
new file mode 100644
index 0000000000..474d63c1b6
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Config
@@ -0,0 +1,8 @@
+CONFIG_CP_EOC = y
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_IS_MASTER = y
+CONFIG_CP_FSM_DEF = "cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_ATU_FACTOR = 3
+CONFIG_MAC_COMMON_EOC_SCHED = y
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Makefile b/cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Makefile
new file mode 100644
index 0000000000..200dfae1c8
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/fsm-Makefile
@@ -0,0 +1,19 @@
+BASE = ../../../../../..
+
+VARIANT = fsm
+
+INCLUDES = cp/eoc/cco/action/test/utest_eoc \
+ cp/eoc/cco/action/test/utest_eoc/override
+
+HOST_PROGRAMS = test_fsm
+
+test_fsm_SOURCES = test_fsm.c actions.c scenario_event_stub.c
+test_fsm_MODULES = lib lib/scenario cp/eoc/fsm ce/tx/stub \
+ mac/sar/stub cp/eoc/sta/action/stub cp/eoc/beacon/stub \
+ cp/eoc/cco/action/stub
+
+test_fsm_CONFIG_MODULES = mac/common cl mac/sar cp/eoc
+
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c)
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/inc/scenario_defs.h b/cesar/cp/eoc/cco/action/test/utest_eoc/inc/scenario_defs.h
new file mode 100644
index 0000000000..94bfa6c180
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/inc/scenario_defs.h
@@ -0,0 +1,351 @@
+#ifndef inc_scenario_defs_h
+#define inc_scenario_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/scenario_defs.h
+ * \brief Scenario definitions.
+ * \ingroup test
+ */
+
+#include "cp/msg/msg.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/net.h"
+#include "cp/fsm/fsm.h"
+
+#include "cp/mme.h"
+#include "cl/cl_mactotei.h"
+#include "mac/common/tonemap.h"
+#include "cp/eoc/cco/bw/service.h"
+#include "cp/eoc/msg/inc/msg_vs.h"
+
+/* Scenario globals. */
+#define SCENARIO_DEFS_GLOBALS \
+ cp_t *cp;\
+ u16 prn; \
+ u32 my_nonce; \
+ u32 your_nonce; \
+ cp_mme_tx_t *mme;
+
+/* Scenario actions. */
+#define SCENARIO_DEFS_ACTIONS \
+ post_and_process, \
+ post, \
+ trigger, \
+ post_urgent, \
+ process, \
+ process_urgent,\
+ vs__started__vs_get_tonemap_req,\
+ vs_eoc__cco__vs_eoc_cco_get_ports_req,\
+ vs_eoc__cco__vs_eoc_cco_get_services_req,\
+ vs__started__vs_get_attenuation_list_req
+
+/* Actions with MME and parameters. */
+#define __m(action, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ PREPROC_FOR_EACH (__m_, param) \
+} scenario_action_ ## action ## _t; \
+void \
+scenario_action_ ## action ## _cb ( \
+ scenario_globals_t *globals, scenario_params_t *params);
+#define __m_(param) param;
+
+
+__m (vs__started__vs_get_tonemap_req)
+__m (vs_eoc__cco__vs_eoc_cco_get_ports_req)
+__m (vs_eoc__cco__vs_eoc_cco_get_services_req)
+__m (vs__started__vs_get_attenuation_list_req)
+
+#undef __m_
+#undef __m
+
+typedef struct
+{
+ cp_fsm_event_type_t type;
+ cp_mme_rx_t *mme;
+ bsu_beacon_t *beacon;
+ cp_net_t *net;
+ cp_sta_t *sta;
+} scenario_action_event_param_t;
+
+typedef scenario_action_event_param_t scenario_action_post_and_process_t;
+typedef scenario_action_event_param_t scenario_action_post_t;
+typedef scenario_action_event_param_t scenario_action_trigger_t;
+typedef scenario_action_event_param_t scenario_action_post_urgent_t;
+typedef scenario_empty_t scenario_action_process_t;
+typedef scenario_empty_t scenario_action_process_urgent_t;
+
+void
+scenario_action_post_and_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_post_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_trigger_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_post_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_process_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+/* Scenario events. */
+
+#define SCENARIO_DEFS_EVENTS \
+ cp_fsm__STOPPED__drv_sta_set_mac_addr_req, \
+ cp_fsm__STOPPED__drv_sta_set_cco_pref_req, \
+ cp_fsm__STOPPED__drv_sta_set_was_cco_req, \
+ cp_fsm__STOPPED__drv_sta_set_dpw_req, \
+ cp_fsm__STOPPED__drv_sta_set_nid_req, \
+ cp_fsm__STOPPED__drv_sta_set_tonemask_req, \
+ cp_fsm__STOPPED__drv_sta_set_key_req, \
+ cp_fsm__STOPPED__drv_sta_set_dak_req, \
+ cp_fsm__STOPPED__drv_sta_mac_start_req, \
+ cp_fsm__STOPPED__drv_sta_set_npw_req, \
+ cp_fsm__STOPPED__drv_sta_set_sl_req,\
+ cp_fsm__STOPPED__drv_sta_set_m_sta_hfid_req,\
+ cp_fsm__STOPPED__drv_sta_set_u_sta_hfid_req,\
+ cp_fsm__STOPPED__drv_sta_set_avln_hfid_req,\
+ cp_fsm__STARTED__poweron__idle__to_poweron, \
+ cp_fsm__STARTED__drv_sta_mac_stop_req,\
+ cp_fsm__POWER_ON__beacon_not_received, \
+ cp_fsm__POWER_ON__power_on_rx_beacon, \
+ cp_fsm__POWER_ON__power_on_no_beacons, \
+ cp_fsm__CCO__cco_drv_mac_stop, \
+ cp_fsm__CCO__send_central_beacon, \
+ cp_fsm__CCO__event_dispatch, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_topo_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_wl_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_wl_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_ports_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_ports_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_services_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_services_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_info_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_diagnostic_info_req, \
+ cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_real_time_statistics_req, \
+ cp_msg_drv_sta_set_key_req_receive, \
+ cp_msg_drv_any_cnf_send, \
+ cp_msg_drv_sta_set_dak_req_receive, \
+ cp_msg_drv_sta_status_req_receive, \
+ cp_msg_drv_sta_status_cnf_send, \
+ cp_msg_drv_sta_status_ind_send, \
+ cp_msg_cc_relay_req_receive, \
+ cp_msg_cc_relay_ind_send, \
+ cp_msg_drv_sta_set_avln_hfid_ind_send, \
+ cp_msg_drv_sta_set_u_sta_hfid_ind_send, \
+ cp_msg_cm_nw_stats_cnf_send_begin, \
+ cp_msg_cm_nw_stats_cnf_send, \
+ cp_msg_cm_nw_stats_cnf_send_end, \
+ cp_msg_cm_link_stats_req_receive, \
+ cp_msg_cm_link_stats_cnf_send, \
+ cp_msg_cm_link_stats_cnf_send_begin, \
+ cp_msg_cm_link_stats_cnf_send_end, \
+ cp_msg_vs_get_attenuation_list_req_receive, \
+ cp_msg_vs_get_attenuation_list_cnf_send_begin, \
+ cp_msg_vs_get_attenuation_list_cnf_send_entry, \
+ cp_msg_vs_get_attenuation_list_cnf_send_end, \
+ cp_msg_vs_get_snr_req_receive, \
+ cp_msg_vs_get_snr_cnf_send, \
+ cp_msg_vs_get_ce_stats_cnf_send, \
+ cp_msg_imac_get_discover_list_req_receive, \
+ cp_msg_imac_get_discover_list_cnf_send_begin, \
+ cp_msg_imac_get_discover_list_cnf_send, \
+ cp_msg_imac_get_discover_list_cnf_send_end, \
+ cp_msg_vs_get_tonemap_req_receive, \
+ cp_msg_vs_get_tonemap_cnf_send, \
+ cp_msg_vs_eoc_cco_get_ports_req_receive, \
+ cp_msg_vs_eoc_cco_get_ports_cnf_send, \
+ cp_msg_vs_eoc_cco_get_services_req_receive, \
+ cp_msg_vs_eoc_cco_get_services_cnf_send, \
+ cp_fsm__CCO__bridge_first_com,\
+ cp_fsm__CCO__nek_provide,\
+ cp_fsm__CCO__set_key_cnf,\
+ cp_fsm__CCO__nek_change_timeout,\
+ cp_fsm__CCO__vs_eoc__cco__leave_remove_timeout, \
+ cp_fsm__CCO__drv_sta_get_key_req, \
+ cp_fsm__BCCO__bcco_drv_mac_stop, \
+ cp_fsm__BCCO__bcco_no_beacons,\
+ cp_fsm__STOPPING__poweron__many__to_idle,\
+ cp_fsm__STOPPING__stopped
+
+/* MME send event. */
+#define __ms(event, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME send event complex. */
+#define __msc(event, param...) \
+typedef struct \
+{ \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME receive event. */
+#define __mr(event, param...) \
+typedef struct \
+{ \
+ bool ok; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+#define __p_(param) param;
+
+/* MME send event for CC_RELAY.IND. */
+#define __msr(event, param...) \
+ typedef struct \
+{ \
+ mac_t mac_fa; \
+ cp_tei_t ftei; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+__mr (cp_msg_drv_sta_set_key_req_receive,
+ cp_key_t nmk, cp_msg_drv_sta_set_key_type_t type,
+ cp_nid_t nid, cp_security_level_t sl)
+__ms (cp_msg_drv_any_cnf_send, mmtype_t mmtype, cp_msg_drv_result_t result)
+__mr (cp_msg_drv_sta_set_dak_req_receive, cp_key_t dak)
+__mr (cp_msg_drv_sta_status_req_receive)
+__ms (cp_msg_drv_sta_status_cnf_send, const cp_msg_drv_sta_status_cnf_t data)
+__ms (cp_msg_drv_sta_status_ind_send, const cp_msg_drv_sta_status_t data)
+__mr (cp_msg_cc_relay_req_receive, uint length, uint mmtype)
+__msr (cp_msg_cc_relay_ind_send, mac_t osa, cp_tei_t stei, uint length)
+__ms (cp_msg_drv_sta_set_avln_hfid_ind_send, char *avln_hfid)
+__ms (cp_msg_drv_sta_set_u_sta_hfid_ind_send, char *u_sta_hfid)
+__ms (cp_msg_cm_nw_stats_cnf_send_begin, uint num_stats)
+__msc (cp_msg_cm_nw_stats_cnf_send, mac_t mac, uint phy_dr_tx, uint phy_dr_rx)
+__msc (cp_msg_cm_nw_stats_cnf_send_end)
+__mr (cp_msg_cm_link_stats_req_receive, cp_msg_cm_link_stats_req_t data)
+__msc (cp_msg_cm_link_stats_cnf_send, mfs_t *mfs,
+ cp_msg_cm_link_stats_tlflag_t transmit)
+__ms (cp_msg_cm_link_stats_cnf_send_begin, u8 req_id, u8 res_type)
+__msc (cp_msg_cm_link_stats_cnf_send_end)
+__mr (cp_msg_vs_get_snr_req_receive, mac_t mac_addr,
+ cp_msg_vs_get_snr_req_int_t tm_int_i, u8 int_id, u8 carrier_gr)
+__ms (cp_msg_vs_get_snr_cnf_send, const cp_msg_vs_get_snr_cnf_t data)
+__mr (cp_msg_vs_get_attenuation_list_req_receive)
+__ms (cp_msg_vs_get_attenuation_list_cnf_send_begin, uint nb)
+__msc (cp_msg_vs_get_attenuation_list_cnf_send_entry,
+ mac_t mac, cp_tei_t tei,
+ vs_get_attenuation_list_att_status_t status, s8 attenuation_db)
+__msc (cp_msg_vs_get_attenuation_list_cnf_send_end)
+
+__ms (cp_msg_vs_get_ce_stats_cnf_send, u8 version, u8 result, sta_t *sta,
+ tonemask_info_t *ti)
+__mr (cp_msg_imac_get_discover_list_req_receive)
+__ms (cp_msg_imac_get_discover_list_cnf_send_begin,
+ cp_msg_imac_get_discover_list_cnf_result_t result, u8 version,
+ u8 num_stations)
+__msc (cp_msg_imac_get_discover_list_cnf_send,
+ const cp_msg_imac_discover_list_sta_info_t *data)
+__msc (cp_msg_imac_get_discover_list_cnf_send_end)
+
+__mr (cp_msg_vs_get_tonemap_req_receive,
+ mac_t mac_addr, cp_msg_vs_get_tonemap_tmi_t tmi,
+ u8 int_id, cp_msg_vs_get_tonemap_req_dir_t dir)
+__ms (cp_msg_vs_get_tonemap_cnf_send,
+ cp_msg_vs_get_tonemap_cnf_result_t result,
+ uint beacon_delta, u8 int_id,
+ tonemaps_t *tms, cp_msg_vs_get_tonemap_tmi_t tmi)
+
+__mr (cp_msg_vs_eoc_cco_get_ports_req_receive,
+ u8 first_mac_index_nb)
+
+__ms (cp_msg_vs_eoc_cco_get_ports_cnf_send,
+ cp_msg_vs_eoc_cco_get_ports_req_result_t result,
+ uint numStas, mac_t* stas_macs, bool (*stas_port_ed)[PORT_NB],
+ u8 (*stas_port_service)[PORT_NB], u8 first_mac_index_nb)
+
+__mr (cp_msg_vs_eoc_cco_get_services_req_receive,
+ u8 first_service_index_nb)
+
+__ms (cp_msg_vs_eoc_cco_get_services_cnf_send,
+ cp_msg_vs_eoc_cco_get_services_req_result_t result,
+ u8 services_number, u8* service_indexes, u8* classifier_rules,
+ u16* classifier_values, u8* acses, u8* parameters_numbers,
+ u16 (*parameters_lists)[SERVICE_PARAMETERS_NB],
+ u8 first_service_index_nb)
+
+#undef __ms
+#undef __msc
+#undef __mr
+#undef __msr
+typedef struct
+{
+ cp_fsm_branch_t branch;
+} scenario_event_transition_with_branch_t;
+
+/* Any event. */
+#define __e(event, param...) \
+typedef struct \
+{ \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+__e (cp_fsm__STOPPED__drv_sta_set_mac_addr_req)
+__e (cp_fsm__STOPPED__drv_sta_set_cco_pref_req)
+__e (cp_fsm__STOPPED__drv_sta_set_was_cco_req)
+__e (cp_fsm__STOPPED__drv_sta_set_dpw_req)
+__e (cp_fsm__STOPPED__drv_sta_set_nid_req)
+__e (cp_fsm__STOPPED__drv_sta_set_tonemask_req)
+__e (cp_fsm__STOPPED__drv_sta_set_key_req)
+__e (cp_fsm__STOPPED__drv_sta_set_dak_req)
+__e (cp_fsm__STOPPED__drv_sta_mac_start_req)
+__e (cp_fsm__STARTED__poweron__idle__to_poweron)
+__e (cp_fsm__STARTED__drv_sta_mac_stop_req)
+__e (cp_fsm__POWER_ON__beacon_not_received)
+__e (cp_fsm__POWER_ON__power_on_rx_beacon)
+__e (cp_fsm__POWER_ON__power_on_no_beacons)
+__e (cp_fsm__CCO__cco_drv_mac_stop)
+__e (cp_fsm__CCO__bridge_first_com)
+__e (cp_fsm__CCO__event_dispatch)
+__e (cp_fsm__CCO__send_central_beacon)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_topo_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_wl_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_wl_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_ports_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_ports_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_services_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_services_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_info_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_diagnostic_info_req)
+__e (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_real_time_statistics_req)
+__e (cp_fsm__CCO__nek_provide)
+__e (cp_fsm__CCO__set_key_cnf)
+__e (cp_fsm__CCO__nek_change_timeout, cp_fsm_branch_t branch)
+__e (cp_fsm__CCO__vs_eoc__cco__leave_remove_timeout)
+__e (cp_fsm__CCO__drv_sta_get_key_req)
+__e (cp_fsm__BCCO__bcco_no_beacons)
+__e (cp_fsm__BCCO__bcco_drv_mac_stop)
+__e (cp_fsm__STOPPING__poweron__many__to_idle)
+__e (cp_fsm__STOPPING__stopped)
+__e (cp_fsm__STOPPED__drv_sta_set_npw_req)
+__e (cp_fsm__STOPPED__drv_sta_set_sl_req)
+__e (cp_fsm__STOPPED__drv_sta_set_m_sta_hfid_req)
+__e (cp_fsm__STOPPED__drv_sta_set_u_sta_hfid_req)
+__e (cp_fsm__STOPPED__drv_sta_set_avln_hfid_req)
+
+#undef __e
+#undef __p_
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/inc/test_cco_action.h b/cesar/cp/eoc/cco/action/test/utest_eoc/inc/test_cco_action.h
new file mode 100644
index 0000000000..c6c25bf850
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/inc/test_cco_action.h
@@ -0,0 +1,56 @@
+#ifndef inc_test_sta_action_h
+#define inc_test_sta_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/test_cco_action.h
+ * \brief Test sta/action.
+ * \ingroup test
+ */
+#include "cp/inc/context.h"
+
+/** Contexts used in tests. */
+struct test_sta_action_t
+{
+ cp_t cp;
+ mac_config_t mac_config;
+};
+typedef struct test_sta_action_t test_sta_action_t;
+
+/**
+ * Initialise test contexts.
+ * \param ctx test context
+ */
+void
+test_sta_action_init (test_sta_action_t *ctx);
+
+/**
+ * Uninitialise test contexts.
+ * \param ctx test context
+ */
+void
+test_sta_action_uninit (test_sta_action_t *ctx);
+
+/**
+ * Reset test contexts.
+ * \param ctx test context
+ */
+void
+test_sta_action_reset (test_sta_action_t *ctx);
+
+/**
+ * Create our AVLN as if the STA was associated.
+ * \param ctx test context
+ * \param nid our NID
+ * \param snid our SNID
+ */
+void
+test_sta_action_create_our_net (test_sta_action_t *ctx, cp_nid_t nid,
+ cp_snid_t snid);
+
+#endif /* inc_test_sta_action_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/inc/context.h b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/inc/context.h
new file mode 100644
index 0000000000..933c8fbb36
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/inc/context.h
@@ -0,0 +1,120 @@
+#ifndef override_cp_inc_context_h
+#define override_cp_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/inc/context.h
+ * \brief Control plane context override.
+ * \ingroup test
+ */
+
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+#include "cp/inc/trace.h"
+#include "mac/common/config.h"
+#include "cp/msg/inc/context.h"
+#include "lib/rnd.h"
+#include "interface/forward.h"
+#include "cp/sta/mgr/inc/sta_mgr.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cl/cl.h"
+#include "cl/inc/context.h"
+#include "cp/cco/bw/bw.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "cp/cco/bw/inc/context.h"
+#include "cp/eoc/cco/action/inc/cco_action.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/beacon/beacon.h"
+#include "cp/eoc/beacon/inc/beacon.h"
+#include "cp/cl_interf/inc/context.h"
+#include "cp/cl_interf/cl_interf.h"
+#include "cp/cco/region/region.h"
+#include "cp/cco/region/inc/context.h"
+#include "cp/sta/core/defs.h"
+#include "cp/sta/action/action.h"
+#include "cp/sta/action/inc/context.h"
+#include "hal/phy/phy.h"
+#include "hal/timer/timer.h"
+#include "config/cp/eoc.h"
+#include "bsu/beacon/beacon.h"
+#include "bsu/aclf/aclf.h"
+#include "mac/pbproc/inc/context.h"
+#include "bsu/inc/context.h"
+#include "cp/eoc/inc/dbg_print.h"
+#include "bufmgr/bufmgr.h"
+
+#include "cp/eoc/sta/action/vs.h"
+#include "cp/eoc/sta/action/inc/vs.h"
+
+struct cp_t
+{
+#if CONFIG_TRACE
+ /** Trace context. */
+ trace_buffer_t trace;
+ /** Verbose trace context. */
+ trace_buffer_t trace_verbose;
+#endif /* CONFIG_TRACE */
+
+ /** FSM context. */
+ cp_fsm_t fsm;
+ /** STA core flag. */
+ bool sta_core_flag;
+ /** STA core urgent flag. */
+ bool sta_core_urgent_flag;
+
+ cp_msg_t msg;
+
+ lib_rnd_t rnd;
+
+ interface_t *interface;
+
+ cp_sta_mgr_t sta_mgr;
+
+ cl_t *cl;
+
+ mac_store_t *mac_store;
+
+ sar_t *sar;
+
+ mac_config_t *mac_config;
+
+ cp_cco_bw_t bw;
+
+ cp_eoc_cco_bw_sched_t schedule;
+
+ ca_t *ca;
+
+ cp_beacon_t beacon;
+
+ hal_timer_t *hal_timer;
+
+ cp_cl_interf_t cl_interf;
+
+ cp_cco_region_t region;
+
+ phy_t *phy;
+
+ pbproc_t *pbproc;
+
+ cp_sta_action_t sta_action;
+
+ cp_cco_action_t cco_action;
+
+ /** CE RX context. */
+ ce_rx_t *ce_rx;
+
+ bsu_aclf_t *bsu_aclf;
+
+ /** BSU context. */
+ bsu_t *bsu;
+
+ /* Buffer manager context. */
+ bufmgr_t *bufmgr;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/core.h b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/core.h
new file mode 100644
index 0000000000..3239854677
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/core.h
@@ -0,0 +1,56 @@
+#ifndef override_cp_sta_core_core_h
+#define override_cp_sta_core_core_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/sta/core/core.h
+ * \brief STA Core override.
+ * \ingroup test
+ */
+#include "cp/inc/context.h"
+#include "defs.h"
+
+BEGIN_DECLS
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx);
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx);
+
+void
+cp_sta_core_checkpoint (cp_t *ctx);
+
+void
+cp_sta_core_signal_recv_mme_event(cp_t *ctx);
+
+void
+cp_sta_core_gen_timed_event(cp_t *cp_ctx,
+ cp_sta_core_timed_event_def_t *sta_core_timed_event,
+ cp_fsm_event_t *fsm_event,
+ uint event_delay_ms);
+
+void
+cp_sta_core_gen_cyclic_event(cp_t *cp_ctx,
+ cp_sta_core_timed_event_def_t *sta_core_cyclic_event,
+ cp_fsm_event_t *fsm_event,
+ uint event_period_ms);
+
+void
+cp_sta_core_stop_timed_or_cyclic_event(cp_t *cp_ctx,
+ cp_sta_core_timed_event_def_t *sta_core_timed_event);
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx);
+
+int
+cp_sta_core_ms_to_cyg_tick (cp_t *ctx, const uint ms);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/defs.h b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..9698b44e93
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/defs.h
@@ -0,0 +1,57 @@
+#ifndef cp_sta_core_defs_h
+#define cp_sta_core_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/core/defs.h
+ * \brief Sta core defs.
+ * \ingroup cp/sta/core
+ *
+ */
+#include "cp/fsm/forward.h"
+
+/** Forward declaration. */
+typedef struct cp_sta_core_t cp_sta_core_t;
+
+/*
+ * the sta core event flags
+ * these are some flags, so take care to give a value with all bits set to 0 but one.
+ */
+enum cp_sta_core_event_flag_t
+{
+ CP_STA_CORE_EVENT_FLAG_RECV_BEACON = 0x1,
+ CP_STA_CORE_EVENT_FLAG_RECV_MME = 0x2,
+ CP_STA_CORE_EVENT_FLAG_FSM = 0x4,
+ CP_STA_CORE_EVENT_FLAG_GARBAGE = 0x8,
+ CP_STA_CORE_EVENT_FLAG_TERMINATE = 0x10
+};
+typedef enum cp_sta_core_event_flag_t cp_sta_core_event_flag_t;
+
+/** Definition of alarm info structure
+ * (applications should not use it directly but use "alias" defined just below) */
+struct cp_sta_core_timed_event_def_t
+{
+ /* eCos alarm. */
+ uint alarm;
+ /* eCos alarm handle. */
+ uint alarm_handle;
+ /* the sta core event flag to set
+ * (auto or user-specified when creating/launching timer alarm). */
+ cp_sta_core_event_flag_t event_flag;
+ /* FSM event specified when creating/launching timer alarm
+ * (set if the previous flag is CP_STA_CORE_EVENT_FLAG_FSM). */
+ cp_fsm_event_t *fsm_event;
+ /* flag indicating a periodic alarm (if set to true)
+ * or one-shot alarm (if set to false). */
+ bool cyclic_alarm;
+ /* pointer to CP context. */
+ cp_t *cp_ctx;
+};
+typedef struct cp_sta_core_timed_event_def_t cp_sta_core_timed_event_def_t;
+
+#endif /* cp_sta_core_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/override/cyg/kernel/kapi.h b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cyg/kernel/kapi.h
new file mode 100644
index 0000000000..019e5d3a07
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cyg/kernel/kapi.h
@@ -0,0 +1,37 @@
+#ifndef override_cyg_kernel_kapi_h
+#define override_cyg_kernel_kapi_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cyg/kernel/kapi.h
+ * \brief override some kernel api from <cyg/kernel/kapi.h>.
+ * \ingroup cp_msg
+ *
+ *
+ */
+
+struct cyg_resolution_t
+{
+ u32 dividend;
+ u32 divisor;
+} ;
+
+typedef struct cyg_resolution_t cyg_resolution_t;
+
+typedef u64 cyg_tick_count_t;
+
+int
+cyg_real_time_clock (void);
+
+cyg_resolution_t
+cyg_clock_get_resolution (int clock);
+
+cyg_tick_count_t
+cyg_current_time (void);
+
+#endif
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/actions.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/actions.c
new file mode 100644
index 0000000000..6ebdcb4ed7
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/actions.c
@@ -0,0 +1,116 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/actions.c
+ * \brief Scenario actions.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/scenario/scenario.h"
+#include "cp/inc/context.h"
+#include "cp/eoc/cco/action/cco_action.h"
+
+cp_fsm_event_t *
+scenario_action_make_event (cp_t *cp, scenario_action_event_param_t *ep)
+{
+ cp_fsm_event_t *event;
+ if (ep->mme)
+ event = cp_fsm_event_mme_new (cp, ep->type, ep->mme);
+ else if (ep->beacon)
+ event = cp_fsm_event_beacon_new (cp, ep->type, ep->beacon, ep->net,
+ ep->sta);
+ else if (ep->sta)
+ event = cp_fsm_event_sta_new (cp, ep->type, ep->net, ep->sta);
+ else
+ event = cp_fsm_event_bare_new (cp, ep->type);
+ return event;
+}
+
+void
+scenario_action_post_and_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_post_and_process_t *p = &params->action_post_and_process;
+ cp_fsm_post (globals->cp, scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_flag);
+ globals->cp->sta_core_flag = false;
+ cp_fsm_process (globals->cp);
+}
+
+void
+scenario_action_post_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_post_t *p = &params->action_post;
+ cp_fsm_post (globals->cp, scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_flag);
+}
+
+void
+scenario_action_trigger_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_trigger_t *p = &params->action_trigger;
+ cp_fsm_trigger (globals->cp, scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_flag);
+}
+
+void
+scenario_action_post_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_post_urgent_t *p = &params->action_post_urgent;
+ cp_fsm_post_urgent (globals->cp,
+ scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_urgent_flag);
+}
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ test_fail_unless (globals->cp->sta_core_flag);
+ globals->cp->sta_core_flag = false;
+ cp_fsm_process (globals->cp);
+}
+
+void
+scenario_action_process_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ test_fail_unless (globals->cp->sta_core_urgent_flag);
+ globals->cp->sta_core_urgent_flag = false;
+ cp_fsm_process_urgent (globals->cp);
+}
+
+
+#define __m(FOLDER, ACTION) \
+void \
+scenario_action_ ## ACTION ## _cb (scenario_globals_t *globals, \
+ scenario_params_t *params) \
+{ \
+ cp_mme_rx_t mme; \
+ unsigned char buffer[1024];\
+ memset (&mme, 0, sizeof (cp_mme_rx_t)); \
+ mme.peer = params->action_ ## ACTION.peer; \
+ mme.peks = CP_MME_PEKS_SPC_NOT_EMBEDDED; \
+ bitstream_init (&mme.bitstream, buffer, sizeof(buffer), BITSTREAM_READ);\
+ cp_ ## FOLDER ## ACTION (globals->cp, &mme); \
+}
+
+__m (sta_action_, vs__started__vs_get_tonemap_req)
+__m (eoc_cco_action_, vs_eoc__cco__vs_eoc_cco_get_ports_req)
+__m (eoc_cco_action_, vs_eoc__cco__vs_eoc_cco_get_services_req)
+
+#undef __m
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/ce_rx_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/ce_rx_stub.c
new file mode 100644
index 0000000000..d57d3ae2cd
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/ce_rx_stub.c
@@ -0,0 +1,31 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/ce_stub.c
+ * \brief CE stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/blk.h"
+#include "ce/rx/rx.h"
+
+blk_t* nsr_block;
+
+blk_t *
+ce_rx_get_nsr (ce_rx_t *ce_rx, cp_tei_t tei, uint int_index,
+ uint int_version, u16* tm_ber)
+{
+ return nsr_block;
+}
+
+u8
+ce_rx_bl_nsr_compute_total_mean (ce_rx_bitloading_t *bl)
+{
+ return 1;
+}
+
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/cl_interf_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cl_interf_stub.c
new file mode 100644
index 0000000000..910786a8a5
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cl_interf_stub.c
@@ -0,0 +1,44 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest3/src/cl_interf_stub.c
+ * \brief « brief description »
+ * \ingroup cp_eoc_cco_action_test_utest3
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+static u8 buffer[2048];
+
+u8 *
+cp_cl_interf_get_buffer_tx (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return buffer;
+}
+
+/**
+ * Send a MME over the PWL or the HLE.
+ * \param ctx the module context.
+ * \param mme The MME to send.
+ *
+ */
+void
+cp_cl_interf_mme_send (cp_t *ctx, cp_mme_tx_t * mme)
+{
+ mme->p_mme = NULL;
+}
+
+void
+cp_cl_interf_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/core_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/core_stub.c
new file mode 100644
index 0000000000..980e81f77a
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/core_stub.c
@@ -0,0 +1,42 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/core_stub.c
+ * \brief STA core stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "cp/sta/core/core.h"
+
+void
+cp_sta_core_gen_timed_event (
+ cp_t *cp_ctx, cp_sta_core_timed_event_def_t *sta_core_timed_event,
+ cp_fsm_event_t *fsm_event, uint event_delay_ms)
+{
+ dbg_assert (cp_ctx);
+ dbg_assert (sta_core_timed_event);
+ dbg_assert (fsm_event);
+
+ slab_release (fsm_event);
+}
+
+void
+cp_sta_core_stop_timed_or_cyclic_event(
+ cp_t *cp_ctx, cp_sta_core_timed_event_def_t *sta_core_timed_event)
+{
+ dbg_assert (cp_ctx);
+ dbg_assert (sta_core_timed_event);
+}
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx)
+{
+ static uint time=0;
+ time+=2000;
+ return time;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_msg_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_msg_stub.c
new file mode 100644
index 0000000000..94a3270610
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_msg_stub.c
@@ -0,0 +1,438 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cp/inc/context.h"
+#include "hal/phy/defs.h"
+
+#include <string.h>
+
+#define __ptr_(TYPE) PASTE_EXPAND (__ptr__, TYPE)
+#define __ptr__assign *
+#define __ptr__string
+#define __ptr__string_or_null
+#define __ptr__tonemask
+#define __ptr__hash_key
+
+/* Code for MME transmission. */
+#define __ms(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ scenario_event (EVENT, param); \
+ __ms_test_peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+/* Code for MME transmission complex with a begin. */
+#define __mscb(EVENT, PARAMS...) \
+cp_mme_tx_t * \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ scenario_event (EVENT, param, global); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+ return global->mme; \
+}
+
+/* Code for MME transmission complex (with or without an end). */
+#define __msc(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_tx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ scenario_event (EVENT, param); \
+ test_fail_unless (param); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+#define __ms_pdecl_(TYPE, PARAM, KIND) , TYPE PARAM
+#define __ms_test_(TYPE, PARAM, KIND) \
+ PASTE_EXPAND (__ms_test__, KIND) (PARAM)
+#define __ms_test__assign(PARAM) \
+ test_fail_unless (PARAM == param->PARAM);
+#define __ms_test__string(PARAM) \
+ test_fail_unless (strcmp (PARAM, param->PARAM) == 0);
+#define __ms_test_peer \
+ test_fail_unless (peer->mac == param->peer.mac); \
+ test_fail_unless (peer->eth_type == param->peer.eth_type); \
+ test_fail_unless (peer->vlan_tci == param->peer.vlan_tci); \
+ test_fail_unless (peer->tei == param->peer.tei); \
+
+/* Code for MME transmission with a data structure. */
+#define __msd(EVENT, DATA, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer, const DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param); \
+ __ms_test_peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __msd_test_, ## PARAMS) \
+}
+
+#define __msd_test_(TYPE, PARAM, KIND) \
+ PASTE_EXPAND (__msd_test__, KIND) (PARAM)
+#define __msd_test__assign(PARAM) \
+ test_fail_unless (data->PARAM == param->PARAM);
+#define __msd_test__string(PARAM) \
+ test_fail_unless (strcmp (data->PARAM, param->PARAM) == 0);
+#define __msd_test__hash_key(PARAM) \
+ test_fail_unless (!param->PARAM || memcmp (data->PARAM, param->PARAM, \
+ CP_HASH_KEY_SIZE) == 0);
+#define __msd_test__key(PARAM) \
+ test_fail_unless (memcmp (&data->PARAM, &param->PARAM, \
+ sizeof (cp_key_t)) == 0);
+
+/* Code for MME transmission with a data structure with encryption
+ * information. */
+#define __msk(EVENT, DATA, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer, cp_mme_peks_t peks, \
+ const cp_secu_protocol_run_t *prun, const DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param, global); \
+ __ms_test_peer \
+ test_fail_unless (peks == param->peks); \
+ test_fail_unless (prun->pid == param->pid); \
+ test_fail_unless (prun->pmn == param->pmn); \
+ global->prn = prun->prn; \
+ global->my_nonce = prun->my_nonce; \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __msd_test_, ## PARAMS) \
+}
+
+/* Code for MME transmission for CC_RELAY.IND. */
+#define __msr(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ scenario_event (EVENT, param); \
+ test_fail_unless (mme->relay.mac_fa == param->mac_fa); \
+ test_fail_unless (mme->relay.ftei == param->ftei); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+
+/* Code for MME reception. */
+#define __mr(EVENT, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_assert_, ## PARAMS) \
+ scenario_event (EVENT, param); \
+ if (param->ok) \
+ { \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_copy_, ## PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+#define __mr_pdecl_(TYPE, PARAM, KIND) , TYPE __ptr_ (KIND) PARAM
+#define __mr_assert_(TYPE, PARAM, KIND) dbg_assert_ptr (PARAM);
+#define __mr_copy_(TYPE, PARAM, KIND) PASTE_EXPAND (__mr_copy__, KIND) (PARAM)
+
+#define __mr_copy__assign(PARAM) *PARAM = param->PARAM;
+#define __mr_copy__string(PARAM) strcpy (PARAM, param->PARAM);
+#define __mr_copy__string_or_null(PARAM) \
+ if (param->PARAM) strcpy (PARAM, param->PARAM);
+#define __mr_copy__tonemask(PARAM) \
+ memcpy (PARAM, param->PARAM, PHY_TONEMASK_SIZE);
+
+/* Code for MME reception with a data structure. */
+#define __mrd(EVENT, DATA, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme, DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param); \
+ if (param->ok) \
+ { \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mrd_copy_, PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+#define __mrd_copy_(TYPE, PARAM, KIND) \
+ PASTE_EXPAND (__mrd_copy__, KIND) (PARAM)
+
+#define __mrd_copy__assign(PARAM) data->PARAM = param->PARAM;
+#define __mrd_copy__string(PARAM) strcpy (data->PARAM, param->PARAM);
+#define __mrd_copy__tonemask(PARAM) \
+ memcpy (data->PARAM, param->PARAM, PHY_TONEMASK_SIZE);
+#define __mrd_copy__hash_key(PARAM) \
+ if (param->PARAM) memcpy (data->PARAM, param->PARAM, CP_HASH_KEY_SIZE);
+#define __mrd_copy__assign_deref(PARAM) \
+ if (param->PARAM) data->PARAM = *param->PARAM;
+
+/* Code for MME reception with a data structure with encryption
+ * information. */
+#define __mrk(EVENT, DATA, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme, DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param, g); \
+ if (param->ok) \
+ { \
+ mme->peks = param->peks; \
+ if (param->new_prn) g->prn = lib_rnd32 (&ctx->rnd) & 0xffff; \
+ if (param->new_my_nonce) g->my_nonce = lib_rnd32 (&ctx->rnd); \
+ if (param->new_your_nonce) g->your_nonce = lib_rnd32 (&ctx->rnd); \
+ mme->prun.pid = param->pid; \
+ mme->prun.pmn = param->pmn; \
+ mme->prun.prn = g->prn; \
+ mme->prun.my_nonce = g->my_nonce; \
+ mme->prun.your_nonce = g->your_nonce; \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mrd_copy_, PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+/* Code for MME reception for CC_RELAY.REQ. */
+#define __mrr(EVENT, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_assert_, ## PARAMS) \
+ scenario_event (EVENT, param); \
+ if (param->ok) \
+ { \
+ mme->relay.mac_fa = param->mac_fa; \
+ mme->relay.ftei = param->ftei; \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_copy_, ## PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+__mr (cp_msg_cc_relay_req_receive,
+ (uint, length, assign),
+ (uint, mmtype, assign))
+__msr (cp_msg_cc_relay_ind_send,
+ (mac_t, osa, assign),
+ (cp_tei_t, stei, assign),
+ (uint, length, assign))
+
+__mr (cp_msg_cm_link_stats_req_receive,
+ (cp_msg_cm_link_stats_req_t, data, assign))
+__msc (cp_msg_cm_link_stats_cnf_send,
+ (mfs_t *, mfs, assign),
+ (cp_msg_cm_link_stats_tlflag_t, transmit, assign))
+__mscb (cp_msg_cm_link_stats_cnf_send_begin,
+ (u8, req_id, assign),
+ (u8, res_type, assign))
+__msc (cp_msg_cm_link_stats_cnf_send_end)
+__mr (cp_msg_vs_get_snr_req_receive,
+ (mac_t, mac_addr, assign),
+ (cp_msg_vs_get_snr_req_int_t, tm_int_i, assign),
+ (u8, int_id, assign),
+ (u8, carrier_gr, assign))
+__msd (cp_msg_vs_get_snr_cnf_send, cp_msg_vs_get_snr_cnf_t)
+__ms (cp_msg_vs_get_ce_stats_cnf_send,
+ (u8, version, assign),
+ (u8, result, assign),
+ (sta_t *, sta, assign),
+ (tonemask_info_t *, ti, assign))
+__mr (cp_msg_imac_get_discover_list_req_receive)
+__mscb (cp_msg_imac_get_discover_list_cnf_send_begin,
+ (cp_msg_imac_get_discover_list_cnf_result_t, result, assign),
+ (u8, version, assign),
+ (u8, num_stations, assign))
+__msc (cp_msg_imac_get_discover_list_cnf_send,
+ (const cp_msg_imac_discover_list_sta_info_t *, data, assign))
+__msc (cp_msg_imac_get_discover_list_cnf_send_end)
+__mr (cp_msg_vs_get_tonemap_req_receive,
+ (mac_t, mac_addr, assign),
+ (cp_msg_vs_get_tonemap_tmi_t, tmi, assign),
+ (u8, int_id, assign),
+ (cp_msg_vs_get_tonemap_req_dir_t, dir, assign))
+__ms (cp_msg_vs_get_tonemap_cnf_send,
+ (cp_msg_vs_get_tonemap_cnf_result_t, result, assign),
+ (uint, beacon_delta, assign),
+ (u8, int_id, assign),
+ (tonemaps_t *, tms, assign),
+ (cp_msg_vs_get_tonemap_tmi_t, tmi, assign))
+__mr (cp_msg_vs_get_attenuation_list_req_receive)
+__mscb (cp_msg_vs_get_attenuation_list_cnf_send_begin,
+ (uint, nb, assign))
+__msc (cp_msg_vs_get_attenuation_list_cnf_send_entry,
+ (mac_t, mac, assign),
+ (cp_tei_t, tei, assign),
+ (vs_get_attenuation_list_att_status_t, status, assign),
+ (s8, attenuation_db, assign))
+__msc (cp_msg_vs_get_attenuation_list_cnf_send_end)
+
+
+cp_mme_tx_t *
+cp_msg_mme_init_not_frag (cp_t *ctx, cp_mme_peer_t *peer, mmtype_t mmtype)
+{
+ static cp_mme_tx_t my_mme;
+ cp_mme_tx_t *mme = &my_mme;
+
+ u64 data;
+ static u8 buffer[2048];
+ bitstream_t bitstream;
+
+ if ((mmtype == VS_EOC_GET_TOPO_CNF) || (mmtype == VS_EOC_CCO_GET_WL_CNF) \
+ || (mmtype == VS_EOC_CCO_SET_OUT_LEV_IND)
+ || (mmtype == VS_EOC_CCO_GET_PORTS_CNF))
+ {
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_WRITE);
+
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_READ);
+ //ODA
+ data = 0x2;
+ bitstream_access (&my_mme.bitstream, &data, 48);
+ // OSA.
+ data = 0x1;
+ bitstream_access (&my_mme.bitstream, &data, 48);
+ // Mtype
+ data = HPAV_MTYPE_MME;
+ bitstream_access (&my_mme.bitstream, &data, 16);
+ // MMV.
+ data = HPAV_MMV1;
+ bitstream_access (&my_mme.bitstream, &data, 8);
+ // MMtype.
+ data = CM_GET_KEY_REQ;
+ bitstream_access (&my_mme.bitstream, &data, 16);
+ // FMI
+ data = 0;
+ bitstream_access (&my_mme.bitstream, &data, 16);
+
+ bitstream_finalise (&my_mme.bitstream);
+
+ mme->length = 19;
+ mme->p_mme = buffer;
+ mme->peer.mac = 2;
+ mme->bitstream.data = bitstream.data;
+ mme->bitstream.data_bits = bitstream.data_bits;
+ }
+ else
+ {
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+ //ODA
+ data = 0x2;
+ bitstream_access (&bitstream, &data, 48);
+ // OSA.
+ data = 0x1;
+ bitstream_access (&bitstream, &data, 48);
+ // Mtype
+ data = HPAV_MTYPE_MME;
+ bitstream_access (&bitstream, &data, 16);
+ // MMV.
+ data = HPAV_MMV1;
+ bitstream_access (&bitstream, &data, 8);
+ // MMtype.
+ data = CM_GET_KEY_REQ;
+ bitstream_access (&bitstream, &data, 16);
+ // FMI
+ data = 0;
+ bitstream_access (&bitstream, &data, 16);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 19;
+ mme->p_mme = buffer;
+ mme->peer.mac = 2;
+ mme->bitstream.data = bitstream.data;
+ mme->bitstream.data_bits = bitstream.data_bits;
+ }
+
+ return mme;
+}
+
+/**
+ * Receive a CM_GET_KEY.REQ.
+ * \param ctx control plane context
+ * \param mme MME handle
+ * \param data received MME data
+ * \return true on success
+ *
+ * Encryption and protocol run information is available in the MME handle.
+ */
+bool
+cp_msg_cm_get_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cm_get_key_req_t *data)
+{
+
+ uint offset;
+ u64 unused;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (mme->p_mme);
+ dbg_assert (mme->length < ETH_PACKET_MAX_SIZE);
+ dbg_assert (data);
+
+ /* Read the MME. */
+ bitstream_init (&mme->bitstream, mme->p_mme, mme->length, BITSTREAM_READ);
+ bitstream_access (&mme->bitstream, &mme->peer.mac, 48);
+ bitstream_access (&mme->bitstream, &unused, 48);
+ bitstream_access (&mme->bitstream, &mme->peer.eth_type, 16);
+ if (ETH_IS_VLANTAG (mme->peer.eth_type))
+ {
+ bitstream_access (&mme->bitstream, &mme->peer.vlan_tci, 16);
+ bitstream_access (&mme->bitstream, &unused, 16);
+ }
+ else
+ {
+ mme->peer.vlan_tci = 0;
+ }
+
+ bitstream_access (&mme->bitstream, &unused, 8);
+ bitstream_access (&mme->bitstream, &unused, 16);
+ bitstream_access (&mme->bitstream, &unused, 16);
+
+ /* Read the data in the MME. */
+ bitstream_access (&mme->bitstream, &data->relayed, 8);
+ bitstream_access (&mme->bitstream, &data->key_type, 8);
+ bitstream_access (&mme->bitstream, &data->nid, 56);
+
+ offset = 37 + ETH_GET_VLANTAG_SIZE (mme->peer.eth_type);
+
+ memcpy (mme->p_mme + offset, &data->hash_key, mme->length - offset);
+
+ return true;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_stub.c
new file mode 100644
index 0000000000..5114e52c33
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cp_stub.c
@@ -0,0 +1,51 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file eoc/sta/action/test/utest/src/cp_stub.c
+ * \brief cp/cp.c stub
+ * \ingroup test
+ *
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/inc/context.h"
+#include "cp/msg/inc/cc_assoc.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+
+/**
+ * Compute the NID and the NMK from the network password.
+ * \param ctx the CP context.
+ * \param npw the network password.
+ * \param sl the security level of the station.
+ *
+ * This function will generate the NID and the NMK from the NPW and store it
+ * in the station own data.
+ */
+void
+cp_compute_nmk_and_nid_from_npw (cp_t *ctx, const char *npw,
+ cp_security_level_t sl)
+{
+ u64 nid;
+ cp_key_t nmk;
+ uint length;
+
+ dbg_assert (ctx);
+ dbg_assert (npw);
+
+ length = strlen (npw);
+
+ nmk = cp_secu_npw2nmk (ctx, (const u8*) npw, length);
+ nid = cp_secu_nmk2nid (ctx, nmk, sl);
+
+ /* Store the nid and the nmk to the station own data. */
+ cp_sta_own_data_set_nid (ctx, nid);
+ cp_sta_own_data_set_nmk (ctx, nmk,
+ CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_NID);
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/cyg_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cyg_stub.c
new file mode 100644
index 0000000000..f9f9784e0e
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/cyg_stub.c
@@ -0,0 +1,40 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/cyg_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "bsu/aclf/aclf.h"
+#include <cyg/kernel/kapi.h>
+
+#define BSU_ACLF_BP_CABLE_TCK 2500000
+#define TCK_PER_RTC 250000
+
+u32
+cp_sta_core_tck_per_rtc (cp_t *ctx)
+{
+ return TCK_PER_RTC;
+}
+
+u32
+bsu_aclf_beacon_period_tck (bsu_aclf_t *ctx)
+{
+ return BSU_ACLF_BP_CABLE_TCK;
+}
+
+cyg_tick_count_t
+cyg_current_time (void)
+{
+ /* For tests purpose we can simulate 1000 beacon periods */
+ return (u32)((BSU_ACLF_BP_CABLE_TCK * 1000ull) / TCK_PER_RTC);
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/dataplane_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/dataplane_stub.c
new file mode 100644
index 0000000000..4d9be7745b
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/dataplane_stub.c
@@ -0,0 +1,38 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/dataplane_stub.c
+ * \brief Data plane layers stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cl/cl_mactotei.h"
+#include "mac/pbproc/pbproc.h"
+#include "cp/inc/context.h"
+#include "mac/sar/inc/context.h"
+
+void
+sar_sta_remove (sar_t *ctx, u8 tei)
+{
+// cp_t *cp = (void *) ctx;
+// dbg_check (mac_store_sta_remove (cp->mac_store, tei));
+// dbg_assert (ctx);
+
+ if (MAC_TEI_IS_STA (tei))
+ {
+ bool ok;
+ ok = mac_store_sta_remove (ctx->mac_store, tei);
+
+ dbg_assert (ok);
+ }
+}
+
+
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/fsm_event_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/fsm_event_stub.c
new file mode 100644
index 0000000000..6355a7ba5d
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/fsm_event_stub.c
@@ -0,0 +1,78 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file events_stub.c
+ * \brief FSM events stub
+ * \ingroup cp_fsm
+ */
+#include "common/std.h"
+#include "cp/inc/context.h"
+
+#include "cp/fsm/inc/events.h"
+#include "cp/fsm/fsm.h"
+
+typedef void (*cp_fsm_event_bare_transition_t) (cp_t *ctx);
+
+void
+cp_fsm_event_bare_handler (cp_t *ctx, cp_fsm_event_t *event,
+ cp_fsm_transition_t transition)
+{
+ dbg_assert (ctx);
+ dbg_assert_ptr (event);
+ dbg_assert (transition);
+ cp_fsm_event_bare_transition_t t = transition;
+ /* Call transition. */
+ t (ctx);
+}
+
+cp_fsm_event_t *
+cp_fsm_event_bare_new (cp_t *ctx, cp_fsm_event_type_t type)
+{
+ dbg_assert (ctx);
+ dbg_assert (type < CP_FSM_EVENT_TYPE_NB);
+ cp_fsm_event_t *e;
+ e = slab_alloc (&ctx->fsm.event_bare_cache);
+ e->next = NULL;
+ e->type = type;
+ e->handler = cp_fsm_event_bare_handler;
+ return e;
+}
+
+cp_fsm_event_t *
+cp_fsm_event_mme_new (cp_t *ctx, cp_fsm_event_type_t type, cp_mme_rx_t *mme)
+{
+ return NULL;
+}
+
+cp_fsm_event_t *
+cp_fsm_event_beacon_new (cp_t *ctx, cp_fsm_event_type_t type,
+ bsu_beacon_t *beacon, cp_net_t *net,
+ cp_sta_t *sta)
+{
+ return NULL;
+}
+
+cp_fsm_event_t *
+cp_fsm_event_sta_new (cp_t *ctx, cp_fsm_event_type_t type,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ return NULL;
+}
+
+void
+cp_fsm_event_init (cp_t *ctx)
+{
+}
+
+void
+cp_fsm_post (cp_t *ctx, cp_fsm_event_t *event)
+{
+ dbg_assert (ctx);
+ dbg_assert (event);
+ slab_release (event);
+} \ No newline at end of file
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/hal_phy_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/hal_phy_stub.c
new file mode 100644
index 0000000000..5e8eb8cc99
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/hal_phy_stub.c
@@ -0,0 +1,26 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/hal_phy_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "hal/phy/forward.h"
+
+void
+phy_tx_scale_adapt_exp_set (phy_t *ctx, u8 exp)
+{
+}
+
+void
+phy_tx_scale_adapt_set (phy_t *ctx, u16 value)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/msg_vs.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/msg_vs.c
new file mode 100644
index 0000000000..d0cdcf00da
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/msg_vs.c
@@ -0,0 +1,686 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/src/msg_vs_eoc.c
+ * \brief VS EoC family MME.
+ * \ingroup cp_msg
+ */
+#include "common/std.h"
+#include "common/defs/homeplugAV.h"
+#include "common/defs/ethernet.h"
+#include "lib/scenario/scenario.h"
+
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/msg/msg.h"
+#include "common/defs/spidcom.h"
+
+#include "cp/sta/mgr/net.h"
+#include "cp/sta/mgr/sta_mgr.h"
+
+
+#include "cp/eoc/msg/inc/msg_vs.h"
+#include "cp/msg/inc/msg.h"
+#include "cp/eoc/sta/action/inc/vs.h"
+
+#include <stdio.h>
+
+#define WL_MME_MAX_ENTRY_COUNT 15
+
+/* Code for MME reception. */
+#define __ptr_(TYPE) PASTE_EXPAND (__ptr__, TYPE)
+#define __ptr__assign *
+#define __ms_test_(TYPE, PARAM, KIND) \
+PASTE_EXPAND (__ms_test__, KIND) (PARAM)
+#define __ms_test__assign(PARAM) \
+test_fail_unless (PARAM == param->PARAM);
+#define __ms_test_multi_sta_(TYPE, PARAM, KIND, NUM) \
+PASTE_EXPAND (__ms_test_multi_sta__, KIND) (NUM, PARAM)
+#define __ms_test_services_(TYPE, PARAM, KIND, NUM1, NUM2) \
+PASTE_EXPAND (__ms_test_services__, KIND) (NUM1, NUM2, PARAM)
+#define __ms_test_multi_sta__assign(NUM, PARAM) \
+test_fail_unless (PARAM == param->PARAM);
+#define __ms_test_services__assign(NUM1, NUM2, PARAM) \
+{ \
+test_fail_unless (PARAM == param->PARAM); \
+}
+#define __ms_test_multi_sta__array(NUM, PARAM) \
+{ \
+uint i = 0; \
+for (i = 0; i < NUM; i++) \
+{ \
+test_fail_unless(PARAM[i] == param->PARAM[i]); \
+} \
+}
+#define __ms_test_services__array(NUM1, NUM2, PARAM) \
+{ \
+uint i = 0; \
+for (i = 0; i < NUM1; i++) \
+{ \
+test_fail_unless(PARAM[i] == param->PARAM[i]); \
+} \
+}
+#define __ms_test_services__two_dim_array(NUM1, NUM2, PARAM) \
+{ \
+uint i = 0; \
+uint j = 0; \
+for (i = 0; i < NUM1; i++) \
+{ \
+for(j = 0; j < NUM2; j++)\
+{ \
+test_fail_unless(PARAM[i][j] == param->PARAM[i][j]); \
+} \
+} \
+}
+#define __ms_pdecl_(TYPE, PARAM, KIND) , TYPE PARAM
+#define __ms_pdecl_multi_sta_(TYPE, PARAM, KIND, NUM) , TYPE PARAM
+#define __ms_pdecl_services_(TYPE, PARAM, KIND, NUM1, NUM2) \
+PASTE_EXPAND (__ms_pdecl_services__, KIND) (TYPE, NUM1, NUM2, PARAM)
+#define __ms_pdecl_ports_(TYPE, PARAM, KIND, NUM1, NUM2) \
+PASTE_EXPAND (__ms_pdecl_ports__, KIND) (TYPE, NUM1, NUM2, PARAM)
+#define __ms_pdecl_services__assign(TYPE, NUM1, NUM2, PARAM) , TYPE PARAM
+#define __ms_pdecl_services__array(TYPE, NUM1, NUM2, PARAM) , TYPE PARAM
+#define __ms_pdecl_services__two_dim_array(TYPE, NUM1, NUM2, PARAM) , \
+ TYPE (*PARAM)[SERVICE_PARAMETERS_NB]
+#define __ms_pdecl_ports__assign(TYPE, NUM1, NUM2, PARAM) , TYPE PARAM
+#define __ms_pdecl_ports__array(TYPE, NUM1, NUM2, PARAM) , TYPE PARAM
+#define __ms_pdecl_ports__two_dim_array(TYPE, NUM1, NUM2, PARAM) , \
+ TYPE (*PARAM)[PORT_NB]
+#define __ms_test_peer \
+test_fail_unless (peer->mac == param->peer.mac); \
+test_fail_unless (peer->eth_type == param->peer.eth_type); \
+test_fail_unless (peer->vlan_tci == param->peer.vlan_tci); \
+test_fail_unless (peer->tei == param->peer.tei); \
+
+#define __mr_pdecl_(TYPE, PARAM, KIND) , TYPE __ptr_ (KIND) PARAM
+
+#define __mr_assert_(TYPE, PARAM, KIND) dbg_assert_ptr (PARAM);
+#define __mr_copy_(TYPE, PARAM, KIND) PASTE_EXPAND (__mr_copy__, KIND) (PARAM)
+
+#define __mr_copy__assign(PARAM) *PARAM = param->PARAM;
+
+
+/* Code for MME reception. */
+#define __mr(EVENT, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_pdecl_, ## PARAMS)) \
+{ \
+dbg_assert (ctx); \
+dbg_assert (mme); \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_assert_, ## PARAMS) \
+scenario_event (EVENT, param); \
+if (param->ok) \
+{ \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_copy_, ## PARAMS) \
+return true; \
+} \
+else \
+ return false; \
+ }
+
+/* Code for MME transmission. */
+#define __ms(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+dbg_assert (ctx); \
+dbg_assert (peer); \
+scenario_event (EVENT, param); \
+__ms_test_peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+#define __ms_multi_sta(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_multi_sta_, ## PARAMS)) \
+{ \
+dbg_assert (ctx); \
+dbg_assert (peer); \
+scenario_event (EVENT, param); \
+__ms_test_peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_multi_sta_, ## PARAMS) \
+}
+
+#define __ms_services(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_services_, ## PARAMS)) \
+{ \
+dbg_assert (ctx); \
+dbg_assert (peer); \
+scenario_event (EVENT, param); \
+__ms_test_peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_services_, ## PARAMS) \
+}
+
+#define __ms_ports(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_ports_, ## PARAMS)) \
+{ \
+dbg_assert (ctx); \
+dbg_assert (peer); \
+scenario_event (EVENT, param); \
+__ms_test_peer \
+if(!param->result) \
+{ \
+PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_services_, ## PARAMS) \
+} \
+}
+
+
+__mr (cp_msg_vs_eoc_cco_get_ports_req_receive,
+ (u8, first_mac_index_nb, assign))
+
+__ms_ports (cp_msg_vs_eoc_cco_get_ports_cnf_send,
+ (cp_msg_vs_eoc_cco_get_ports_req_result_t, result, assign, 0, 0),
+ (uint, numStas, assign, 0, 0),
+ (mac_t*, stas_macs, array, numStas, 0),
+ (bool, stas_port_ed, two_dim_array, numStas, PORT_NB),
+ (u8, stas_port_service, two_dim_array, numStas, PORT_NB),
+ (u8, first_mac_index_nb, assign, 0, 0))
+
+__ms_services (cp_msg_vs_eoc_cco_get_services_cnf_send,
+ (cp_msg_vs_eoc_cco_get_services_req_result_t, result, assign, 0,
+ 0),
+ (u8, services_number, assign, 0, 0),
+ (u8*, service_indexes, array, services_number, 0),
+ (u8*, classifier_rules, array, services_number, 0),
+ (u16*, classifier_values, array, services_number, 0),
+ (u8*, acses, array, services_number, 0),
+ (u8*, parameters_numbers, array, services_number, 0),
+ (u16, parameters_lists, two_dim_array, services_number, 7),
+ (u8, first_service_index_nb, assign, 0, 0))
+
+__mr (cp_msg_vs_eoc_cco_get_services_req_receive,
+ (u8, first_service_index_nb, assign))
+
+/**
+ * Start sending of a VS_EOC_GET_TOPO.CNF.
+ * \param ctx the control plane context.
+ * \param peer the peer info.
+ * \param result the result.
+ * \param sta_nb the number of stations connected to CCo.
+ * \return the message context.
+ */
+cp_mme_tx_t *
+cp_msg_vs_eoc_get_topo_cnf_send_begin (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_vs_eoc_get_topo_cnf_result_t
+ result, u8 sta_nb)
+{
+ cp_mme_tx_t * mme;
+
+ dbg_assert (ctx);
+ dbg_assert (peer);
+ dbg_assert (result < CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_NB);
+
+ mme = cp_msg_mme_init_not_frag (ctx, peer, VS_EOC_GET_TOPO_CNF);
+ dbg_assert (mme);
+
+ bitstream_write (&mme->bitstream, result, 8);
+ bitstream_write (&mme->bitstream, sta_nb, 8);
+
+ return mme;
+}
+
+/**
+ * Fill the MME with the station parameters.
+ * \param ctx the module context.
+ * \param mme the MME message.
+ * \param mac_addr the mac address of the station.
+ * \param auth_status the authorization status of the station.
+ * \param up_att the upstream attenuation.
+ */
+void
+cp_msg_vs_eoc_get_topo_cnf_send_sta (cp_t *ctx, cp_mme_tx_t *mme,
+ mac_t mac_addr, u8 auth_status,
+ s8 up_att)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (auth_status <= 3);
+
+ bitstream_write_large (&mme->bitstream, mac_addr, 48);
+ bitstream_write (&mme->bitstream, auth_status, 8);
+ /* Cast up_att to u8 because bitstream only process words, so the s8
+ * will be promoted to int (i.e. 32bits) and bitstream verifies that only
+ * 8 bits are set. */
+ bitstream_write (&mme->bitstream, (u8) up_att, 8);
+}
+
+/**
+ * End sending of a VS_EOC_GET_TOPO.CNF.
+ * \param ctx the control plane context.
+ * \param mme the MME to send.
+ */
+void
+cp_msg_vs_eoc_get_topo_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ bitstream_write_finalise (&mme->bitstream);
+
+ cp_msg_mme_send (ctx, mme);
+}
+
+bool
+cp_msg_vs_eoc_cco_set_wl_req_receive (
+ cp_t *ctx, cp_mme_rx_t *mme, uint *numStas, cp_tei_t *stas_teis,
+ mac_t *stas_macs, u8 *stas_authorizations, u8 *stas_output_levels,
+ u32 *stas_start_times, u32 *stas_end_times, cp_key_t *stas_daks,
+ cp_dpw_t *stas_dpws, u8 *stas_actions)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (numStas);
+ dbg_assert (stas_teis);
+ dbg_assert (stas_macs);
+ dbg_assert (stas_authorizations);
+ dbg_assert (stas_output_levels);
+ dbg_assert (stas_start_times);
+ dbg_assert (stas_end_times);
+ dbg_assert (stas_daks);
+ dbg_assert (stas_dpws);
+ dbg_assert (stas_actions);
+
+ /* Number of stations in the current MME */
+ uint number_of_stations;
+ uint i, j;
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ number_of_stations = bitstream_read (&mme->bitstream, 8);
+ *numStas = number_of_stations;
+
+ for (i=0; i<number_of_stations; i++)
+ {
+ bitstream_access (&mme->bitstream, &stas_macs[i], 48);
+ bitstream_access (&mme->bitstream, &stas_teis[i], 8);
+ bitstream_access (&mme->bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&mme->bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&mme->bitstream, &stas_start_times[i], 32);
+ bitstream_access (&mme->bitstream, &stas_end_times[i], 32);
+ for (j=0; j<4; j++)
+ bitstream_access (&mme->bitstream, &stas_daks[i].key[j], 32);
+ bitstream_access_buf (&mme->bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ stas_dpws[i].dpw[CP_DPW_MAX_SIZE] = '\0';
+ bitstream_access (&mme->bitstream, &stas_actions[i], 8);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void
+cp_msg_vs_eoc_cco_set_wl_cnf_send (
+ cp_t *ctx, cp_mme_peer_t *peer, mmtype_t mmtype,
+ cp_msg_vs_eoc_cco_set_wl_req_result_t result)
+{
+ cp_mme_tx_t *msg;
+
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+
+ msg = cp_msg_mme_init_not_frag (ctx, peer, mmtype);
+ dbg_check (msg);
+
+ bitstream_access (&msg->bitstream, &result, 8);
+
+ cp_msg_mme_send (ctx, msg);
+}
+
+
+bool
+cp_msg_vs_eoc_cco_get_wl_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ u8 *first_wl_index_nb)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *first_wl_index_nb = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+void
+cp_msg_vs_eoc_cco_get_wl_cnf_send (cp_t *ctx,
+ cp_msg_vs_eoc_cco_get_wl_req_result_t result, cp_mme_peer_t *peer,
+ uint numStas, cp_tei_t *stas_teis, mac_t *stas_macs,
+ u8 *stas_authorizations, u8 *stas_output_levels, u32 *stas_start_times,
+ u32 *stas_end_times, cp_key_t *stas_daks, cp_dpw_t *stas_dpws,
+ u8 *stas_actions, u8 first_wl_index_nb)
+{
+ cp_mme_tx_t *tx;
+ u8 i, j;
+ u8 total_wl_index_nb;
+ u8 wl_index_nb;
+ dbg_assert (ctx);
+ dbg_assert (stas_teis);
+ dbg_assert (stas_macs);
+ dbg_assert (stas_authorizations);
+ dbg_assert (stas_output_levels);
+ dbg_assert (stas_start_times);
+ dbg_assert (stas_end_times);
+ dbg_assert (stas_daks);
+ dbg_assert (stas_dpws);
+ dbg_assert (stas_actions);
+
+ /* One MME can contain maximum of WL_MME_MAX_ENTRY_COUNT WL entries. */
+ total_wl_index_nb = numStas;
+
+ if (first_wl_index_nb > total_wl_index_nb)
+ wl_index_nb = 0;
+ else
+ wl_index_nb = MIN (total_wl_index_nb - first_wl_index_nb,
+ WL_MME_MAX_ENTRY_COUNT);
+
+ tx = cp_msg_mme_init_not_frag (ctx, peer, VS_EOC_CCO_GET_WL_CNF);
+ dbg_assert (tx);
+ bitstream_write (&tx->bitstream, result, 8);
+ bitstream_write (&tx->bitstream, total_wl_index_nb, 8);
+ bitstream_write (&tx->bitstream, first_wl_index_nb, 8);
+ bitstream_write (&tx->bitstream, wl_index_nb, 8);
+ for (i = first_wl_index_nb; i < first_wl_index_nb + wl_index_nb; i++)
+ {
+ bitstream_write_large(&tx->bitstream, stas_macs[i], 48);
+ bitstream_write(&tx->bitstream, stas_teis[i], 8);
+ bitstream_write(&tx->bitstream, stas_authorizations[i], 8);
+ bitstream_write(&tx->bitstream, stas_output_levels[i], 8);
+ bitstream_write(&tx->bitstream, stas_start_times[i], 32);
+ bitstream_write(&tx->bitstream, stas_end_times[i], 32);
+ for (j=0; j<4; j++)
+ bitstream_write(&tx->bitstream, stas_daks[i].key[j], 32);
+ bitstream_write_buf(&tx->bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ bitstream_write(&tx->bitstream, stas_actions[i], 8);
+ }
+
+ cp_msg_mme_send (ctx, tx);
+}
+
+void
+cp_msg_vs_eoc_cco_set_out_lev_ind_send(cp_t *ctx, cp_mme_peer_t *peer,
+ uint output_level)
+{
+ dbg_assert(ctx);
+
+ cp_mme_tx_t *tx;
+
+ tx = cp_msg_mme_init_not_frag (ctx, peer, VS_EOC_CCO_SET_OUT_LEV_IND);
+ dbg_assert(tx);
+
+ bitstream_write(&tx->bitstream, output_level, 8);
+ bitstream_write_finalise(&tx->bitstream);
+ cp_msg_mme_send (ctx, tx);
+}
+
+bool
+cp_msg_eoc_sta_vs_set_out_lev_ind_receive(cp_t *ctx, cp_mme_rx_t *mme,
+ uint *output_level)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *output_level = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+
+bool cp_msg_vs_eoc_set_ports_req_receive(cp_t *ctx, cp_mme_rx_t *mme,
+ uint *numStas, mac_t *stas_macs, u8 stas_ports_ed[][PORT_NB],
+ u8 stas_ports_service[][PORT_NB])
+{
+ dbg_assert(ctx);
+ dbg_assert(mme);
+ dbg_assert(numStas);
+ dbg_assert(stas_macs);
+ dbg_assert(stas_ports_ed);
+ dbg_assert(stas_ports_service);
+
+ uint number_of_stations;
+ uint i,j;
+
+ if(cp_msg_mme_read_error(ctx,mme))
+ {
+ number_of_stations = bitstream_read (&mme->bitstream, 8);
+ *numStas = number_of_stations;
+
+ for(i = 0; i < number_of_stations; i++)
+ {
+ bitstream_access(&mme->bitstream, &stas_macs[i], 48);
+ for(j = 0; j < PORT_NB; j++)
+ {
+ bitstream_access(&mme->bitstream, &stas_ports_ed[i][j], 8);
+ bitstream_access(&mme->bitstream, &stas_ports_service[i][j], 8);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+void
+cp_msg_vs_eoc_set_ports_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ mmtype_t mmtype, cp_msg_vs_eoc_set_ports_req_result_t result)
+{
+ cp_mme_tx_t *msg;
+
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+
+ msg = cp_msg_mme_init_not_frag (ctx, peer, mmtype);
+ dbg_check (msg);
+
+ bitstream_access (&msg->bitstream, &result, 8);
+
+ cp_msg_mme_send (ctx, msg);
+}
+
+bool
+cp_msg_vs_eoc_cco_set_services_req_receive (
+ cp_t *ctx, cp_mme_rx_t *mme, u8 *command, u8 *services_number,
+ u8 *service_indexes, u8 *classifier_rules, u16 *classifier_values,
+ u8 *acses, u8 *parameters_numbers,
+ u16 parameters_lists[][SERVICE_PARAMETERS_NB])
+{
+ dbg_assert(ctx);
+ dbg_assert(mme);
+ dbg_assert(command);
+ dbg_assert(services_number);
+ dbg_assert(service_indexes);
+ dbg_assert(classifier_rules);
+ dbg_assert(classifier_values);
+ dbg_assert(acses);
+ dbg_assert(parameters_numbers);
+ dbg_assert(parameters_lists);
+
+ u8 number_of_services;
+ u8 i,j;
+ u8 parameters_number_tmp;
+
+ if(cp_msg_mme_read_error(ctx,mme))
+ {
+ *command = bitstream_read(&mme->bitstream, 8);
+ number_of_services = bitstream_read (&mme->bitstream, 8);
+ *services_number = number_of_services;
+
+ for(i = 0; i < number_of_services; i++)
+ {
+ bitstream_access(&mme->bitstream, &service_indexes[i], 8);
+ bitstream_access(&mme->bitstream, &classifier_rules[i], 8);
+ bitstream_access(&mme->bitstream, &classifier_values[i], 16);
+ bitstream_access(&mme->bitstream, &acses[i], 8);
+ bitstream_access(&mme->bitstream, &parameters_numbers[i], 8);
+ parameters_number_tmp = parameters_numbers[i];
+ for(j = 0; j < parameters_number_tmp; j++)
+ {
+ bitstream_access(&mme->bitstream, &parameters_lists[i][j], 16);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+void
+cp_msg_vs_eoc_cco_set_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ mmtype_t mmtype, cp_msg_vs_eoc_cco_set_services_req_result_t result)
+{
+ cp_mme_tx_t *msg;
+
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+
+ msg = cp_msg_mme_init_not_frag (ctx, peer, mmtype);
+ dbg_check (msg);
+
+ bitstream_access (&msg->bitstream, &result, 8);
+
+ cp_msg_mme_send (ctx, msg);
+}
+
+bool
+cp_msg_vs_eoc_cco_get_info_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ u8 *internal_eoc_index, u8 *control)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *internal_eoc_index = bitstream_read(&mme->bitstream, 8);
+ *control = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+void
+cp_msg_vs_eoc_cco_get_info_cnf_send(cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_vs_eoc_get_info_req_result_t status, u16 tei, s8 attenuation,
+ u8 snr, u16 phy_uplink_speed, u16 phy_downlink_speed, u8 output_power,
+ u32 tx_success_counter, u32 tx_crc_error_counter,
+ u32 tx_other_error_counter, u32 rx_success_counter,
+ u32 rx_crc_error_counter, u32 rx_other_error_counter)
+{
+ dbg_assert(ctx);
+ dbg_assert(peer);
+
+ FILE *fp;
+
+ if((fp = fopen("get_info.txt", "w")) != NULL)
+ {
+ fprintf(fp, "%u,%u,%d,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", status,
+ tei, attenuation, snr, phy_uplink_speed, phy_downlink_speed,
+ output_power, tx_success_counter, tx_crc_error_counter,
+ tx_other_error_counter, rx_success_counter,
+ rx_crc_error_counter, rx_other_error_counter);
+ }
+ else
+ printf("DBG:cp_msg_mme_send_stub_get_info, \
+ Error opening get_info.txt\n");
+ fclose(fp);
+}
+
+
+bool
+cp_msg_vs_eoc_cco_diagnostic_info_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ u8 *internal_eoc_index, u8 *control)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *internal_eoc_index = bitstream_read(&mme->bitstream, 8);
+ *control = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+void
+cp_msg_vs_eoc_cco_diagnostict_info_cnf_send(cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_vs_eoc_diagnostic_info_req_result_t status, u8 assoc_stat, u64 nid,
+ u8 num_slots, mac_t he_mac_address, u16 est_avg_phy_rate,
+ u8 num_good_assoc_auth, u16 num_bad_could_not_assoc,
+ u32 num_bad_assoc_failure, u32 num_bad_could_not_auth, u32 num_leave)
+{
+ dbg_assert(ctx);
+ dbg_assert(peer);
+
+ FILE *fp;
+
+ if((fp = fopen("get_info.txt", "w")) != NULL)
+ {
+ fprintf(fp,"%u,%u,%llu,%u,%llu,%u,%u,%u,%u,%u,%u", status, assoc_stat,
+ nid, num_slots, he_mac_address, est_avg_phy_rate,
+ num_good_assoc_auth, num_bad_could_not_assoc,
+ num_bad_assoc_failure, num_bad_could_not_auth, num_leave);
+ }
+ else
+ printf("DBG:cp_msg_mme_send_stub_get_info, \
+ Error opening get_info.txt\n");
+ fclose(fp);
+}
+
+
+bool
+cp_msg_vs_eoc_cco_get_real_time_stats_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ u8 *control)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ return true;
+}
+
+void
+cp_msg_vs_eoc_cco_get_real_time_stats_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_vs_eoc_get_real_time_statistics_req_result_t status,
+ real_time_stats_t *rt_stats)
+{
+ dbg_assert(ctx);
+ dbg_assert(peer);
+
+ FILE *fp;
+
+ if((fp = fopen("get_info.txt", "w")) != NULL)
+ {
+ fprintf(fp, "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", status,
+ rt_stats->nb_unicast_packets_rx,
+ rt_stats->nb_unicast_packets_tx, rt_stats->total_nb_bytes_rx,
+ rt_stats->total_nb_bytes_tx, rt_stats->nb_broadcast_packets_rx,
+ rt_stats->nb_broadcast_packets_tx,
+ rt_stats->nb_multicast_packets_rx,
+ rt_stats->nb_multicast_packets_tx, rt_stats->nb_packets_rx_crc,
+ rt_stats->nb_packets_rx_short, rt_stats->nb_packets_tx_short,
+ rt_stats->nb_packets_tx_dropped,
+ rt_stats->nb_packets_rx_discarded,
+ rt_stats->avg_pre_fec_bit_error_rate);
+ }
+ else
+ printf("DBG:cp_msg_mme_send_stub_get_real_time_stats, \
+ Error opening get_info.txt\n");
+ fclose(fp);
+}
+
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/scenario_event_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/scenario_event_stub.c
new file mode 100644
index 0000000000..2969227196
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/scenario_event_stub.c
@@ -0,0 +1,241 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/fsm_stub.c
+ * \brief Override FSM tables.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/tables.h"
+
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STARTED__drv_sta_mac_stop_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_mac_addr_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_cco_pref_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_was_cco_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_dpw_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_nid_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_tonemask_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_key_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_dak_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_mac_start_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_npw_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_sl_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_m_sta_hfid_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_u_sta_hfid_req);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STOPPED__drv_sta_set_avln_hfid_req);
+}
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STOPPING__stopped);
+}
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STOPPING__poweron__many__to_idle);
+}
+
+void
+cp_eoc_cco_action_poweron__idle__to_poweron (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STARTED__poweron__idle__to_poweron);
+}
+
+void
+cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta)
+{
+ scenario_event (cp_fsm__CCO__bridge_first_com);
+}
+
+void
+cp_eoc_cco_action__power_on_rx_beacon (cp_t *ctx)
+{
+ scenario_event (cp_fsm__POWER_ON__power_on_rx_beacon);
+}
+
+void
+cp_eoc_cco_action__power_on_no_beacons (cp_t *ctx)
+{
+ scenario_event (cp_fsm__POWER_ON__power_on_no_beacons);
+}
+
+void
+cp_eoc_cco_action__cco_drv_mac_stop (cp_t *ctx)
+{
+ scenario_event (cp_fsm__CCO__cco_drv_mac_stop);
+}
+
+void
+cp_eoc_cco_action__bcco_no_beacons (cp_t *ctx)
+{
+ scenario_event (cp_fsm__BCCO__bcco_no_beacons);
+}
+
+void
+cp_eoc_cco_action__bcco_drv_mac_stop (cp_t *ctx)
+{
+ scenario_event (cp_fsm__BCCO__bcco_drv_mac_stop);
+}
+
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx)
+{
+ scenario_event (cp_fsm__CCO__send_central_beacon);
+}
+
+void
+cp_eoc_cco_action_nek_provide (cp_t *ctx)
+{
+ scenario_event (cp_fsm__CCO__nek_provide);
+}
+
+void
+cp_eoc_cco_action__set_key_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__set_key_cnf);
+}
+
+void
+cp_eoc_cco_action_nek_change_timeout (cp_t *ctx)
+{
+ scenario_event (cp_fsm__CCO__nek_change_timeout, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_beacon_beacon_not_received (cp_t *ctx)
+{
+ scenario_event (cp_fsm__POWER_ON__beacon_not_received);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_topo_req);
+}
+
+void
+cp_eoc_cco_action_event_dispatch (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__event_dispatch);
+}
+
+void
+cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__drv_sta_get_key_req);
+}
+
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_wl_req);
+}
+
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_wl_req);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_ports_req);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_ports_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_ports_req);
+}
+
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__leave_remove_timeout);
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_actions.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_actions.c
new file mode 100644
index 0000000000..c0ac860fb2
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_actions.c
@@ -0,0 +1,4016 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_actions.c
+ * \brief Test CCo actions.
+ * \ingroup test
+ */
+
+#include "stdio.h"
+#include "common/std.h"
+#include "lib/blk.h"
+#include "lib/test.h"
+#include "lib/scenario/scenario.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/inc/context.h"
+#include "cp/sta/core/core.h"
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+#include "cp/msg/msg.h"
+#include "lib/test.h"
+#include "lib/utils.h"
+#include "lib/swap.h"
+#include "lib/slab.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "inc/test_cco_action.h"
+#include "mac/sar/inc/context.h"
+#include "mac/common/defs.h"
+#include "cp/eoc/cco/bw/service.h"
+
+#define SET_STATIONS(number_of_stations) \
+ uint i = 0; \
+ uint j = 0; \
+ cp_tei_t starting_tei = 2; \
+ mac_t starting_mac = 0x0000111111111111ull; \
+ u8 starting_index_of_service = 0; \
+ mac_t stas_macs[MAC_TEI_STA_NB]; \
+ cp_tei_t stas_teis[MAC_TEI_STA_NB]; \
+ bool stas_ports_ed[MAC_TEI_STA_NB][PORT_NB]; \
+ u8 stas_ports_service[MAC_TEI_STA_NB][PORT_NB]; \
+ cp_sta_t* stations[MAC_TEI_STA_NB]; \
+ for (i = 0; i < number_of_stations; i++) \
+ { \
+ stas_macs[i] = starting_mac + i; \
+ stas_teis[i] = starting_tei + i; \
+ for(j = 0; j < PORT_NB; j++)\
+ { \
+ stas_ports_ed[i][j] = j % 2 ? true : false; \
+ stas_ports_service[i][j] = starting_index_of_service + j; \
+ stations[i] = cp_sta_mgr_sta_add (cp, net, stas_teis[i],\
+ stas_macs[i]); \
+ stations[i]->multi_sta.ports.port[j].enabled = \
+ stas_ports_ed[i][j]; \
+ stations[i]->multi_sta.ports.port[j].index_of_service = \
+ stas_ports_service[i][j]; \
+ slab_release (stations[i]);\
+ } \
+ }
+
+#define SET_UNASSOC_STATIONS(number_of_stations, number_of_unassoc_stations) \
+ for(i = number_of_stations; \
+ i < (number_of_stations + number_of_unassoc_stations); i++)\
+ {\
+ stas_macs[i] = starting_mac + i; \
+ stas_teis[i] = MAC_TEI_UNASSOCIATED; \
+ for (j = 0; j < PORT_NB; j++)\
+ { \
+ stas_ports_ed[i][j] = j % 2 ? true : false; \
+ stas_ports_service[i][j] = starting_index_of_service + j; \
+ stations[i] = cp_sta_mgr_sta_add (cp, net, stas_teis[i], \
+ stas_macs[i]); \
+ dbg_assert (stations[i]);\
+ stations[i]->multi_sta.ports.port[j].enabled = \
+ stas_ports_ed[i][j]; \
+ stations[i]->multi_sta.ports.port[j].index_of_service = \
+ stas_ports_service[i][j]; \
+ slab_release (stations[i]);\
+ } \
+ }
+
+void
+test_sta_action_init (test_sta_action_t *ctx)
+{
+#if CONFIG_TRACE
+ static trace_namespace_t namespace;
+ trace_buffer_add (&ctx->cp.trace, "cp", 8, 1, false, &namespace);
+#endif
+ ctx->cp.mac_config = &ctx->mac_config;
+ ctx->cp.mac_store = mac_store_init ();
+ ctx->cp.pbproc = NULL;
+ ctx->cp.cl = INVALID_PTR;
+ cp_eoc_sta_mgr_init (&ctx->cp);
+ lib_rnd_init (&ctx->cp.rnd, 1234);
+}
+
+void
+test_sta_action_uninit (test_sta_action_t *ctx)
+{
+ cp_sta_mgr_uninit (&ctx->cp);
+ mac_store_uninit (ctx->cp.mac_store);
+#if CONFIG_TRACE
+ trace_buffer_remove (&ctx->cp.trace);
+#endif
+}
+
+void
+test_sta_action_create_our_net (test_sta_action_t *ctx, cp_nid_t nid,
+ cp_snid_t snid)
+{
+ cp_t *cp = &ctx->cp;
+ cp_sta_own_data_set_nid (cp, nid);
+ cp_sta_own_data_set_snid (cp, snid);
+ cp_net_t *our_net = cp_sta_mgr_add_avln (cp, snid, nid);
+ cp_sta_mgr_set_our_avln (cp, our_net);
+}
+
+void
+cp_eoc_cco_action_test_release_mac_store (cp_t *ctx)
+{
+ uint tei, i;
+ for (tei = MAC_TEI_STA_MIN_EOC; tei < MAC_TEI_STA_MAX; tei++)
+ {
+ mfs_t *mfs;
+ for (i = 0; i < MAC_CAP_NB; i++)
+ {
+ mfs = mac_store_mfs_get (ctx->mac_store, true, false, false,
+ MAC_LLID_MIN + i, tei);
+ if (mfs)
+ {
+ mac_store_mfs_remove (ctx->mac_store, mfs);
+ blk_release (mfs);
+ }
+ }
+ mfs = mac_store_mfs_get (ctx->mac_store, true, false, true,
+ MAC_LID_NONE, tei);
+ if (mfs)
+ {
+ mac_store_mfs_remove (ctx->mac_store, mfs);
+ blk_release (mfs);
+ }
+ }
+}
+
+void
+test_case_DRV_and_VS_MMEs (test_t test)
+{
+ test_case_begin (test, "test_case_DRV_and_VS_MMEs");
+
+ test_begin (test, "cp_eoc_multi_sta_action_compute_tei")
+ {
+ cp_t ctx;
+ cp_tei_t tei;
+
+ for (tei = MAC_TEI_STA_MIN_EOC; tei <= MAC_TEI_STA_MAX; tei++)
+ {
+ test_fail_unless (cp_eoc_multi_sta_action_compute_tei (&ctx) == tei);
+ }
+
+ test_fail_unless (cp_eoc_multi_sta_action_compute_tei (&ctx) ==
+ MAC_TEI_UNASSOCIATED);
+
+ test_fail_unless (cp_eoc_multi_sta_action_compute_tei (&ctx) ==
+ MAC_TEI_UNASSOCIATED);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_MAC_ADDR_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+ uint cl;
+ bitstream_t bitstream;
+ u64 data;
+ u8 buffer[1024];
+ sar_t sar;
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ cp_eoc_sta_mgr_init (&ctx);
+ ctx.sar=&sar;
+ ctx.mac_store = mac_store_init ();
+ ctx.sta_mgr.sta_own_data.security_level = CP_SECURITY_LEVEL_HS;
+ ctx.cl = (cl_t *) &cl;
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->mmtype = DRV_STA_SET_MAC_ADDR_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ data = 0x3;
+ bitstream_access (&bitstream, &data, 48);
+ bitstream_finalise (&bitstream);
+ mme->length = 6;
+ mme->peer.mac = 0x3;
+
+ cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (&ctx, mme);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.mac_addr == mme->peer.mac);
+
+ test_fail_unless (ctx.mac_config->sta_mac_address == mme->peer.mac);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_CCO_PREF_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ bitstream_t bitstream;
+ u8 cco_pref;
+ u8 buffer[1024];
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_CCO_PREF_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ /* 0x01 means that the staion is prefered as CCO
+ 0x00 means that the station is not prefered as CCO. */
+ cco_pref = 0x1;
+ bitstream_access (&bitstream, &cco_pref, 8);
+ bitstream_finalise (&bitstream);
+ mme->length = 1;
+
+ cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (&ctx, mme);
+
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless (own->cco_prefered == cco_pref);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_WAS_CCO_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ bitstream_t bitstream;
+ u8 was_cco;
+ u8 buffer[1024];
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_WAS_CCO_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ /* 0x01 means that the staion was a CCO prviously */
+ /* 0x00 means that the station was not a CCO previously */
+ was_cco = 0x1;
+
+ bitstream_access (&bitstream, &was_cco, 8);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 1;
+
+ cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (&ctx, mme);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.was_cco == was_cco);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_SL_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ bitstream_t bitstream;
+ cp_security_level_t sl;
+ u8 buffer[1024];
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_SL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ strcpy (ctx.sta_mgr.sta_own_data.npw, "SPC-300_EoC_200MBps");
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ /* Possible security level values: CP_SECURITY_LEVEL_SC,
+ * CP_SECURITY_LEVEL_HS */
+ sl = CP_SECURITY_LEVEL_HS;
+
+ bitstream_access (&bitstream, &sl, 8);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 1;
+
+ cp_sta_action_drv__stopped__drv_sta_set_sl_req (&ctx, mme);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.security_level == sl);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_M_STA_HFID_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ char m_sta_hfid[CP_HFID_SIZE + 1];
+
+ /* sample manufacturer human friendly identifier:
+ * Spidcom_SPC_300_EoC_m_HFID_123. */
+ memset (m_sta_hfid, 0, sizeof (m_sta_hfid));
+ strcpy (m_sta_hfid, "Spidcom_SPC_300_EoC_m_HFID_123");
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_M_STA_HFID_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ for(i = 0; i < CP_HFID_SIZE; i++)
+ bitstream_access (&bitstream, &m_sta_hfid[i], 8);
+
+ bitstream_finalise (&bitstream);
+
+ cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req (&ctx, mme);
+
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless (!(strcmp(own->hfid_manufacturer, m_sta_hfid)));
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_U_STA_HFID_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ char u_sta_hfid[CP_HFID_SIZE + 1];
+
+ /* sample user human friendly identifier:
+ * Spidcom_SPC_300_EoC_u_HFID_123. */
+ memset (u_sta_hfid, 0, sizeof(u_sta_hfid));
+ strcpy (u_sta_hfid, "Spidcom_SPC_300_EoC_u_HFID_123");
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_M_STA_HFID_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ for(i = 0; i < CP_HFID_SIZE; i++)
+ bitstream_access (&bitstream, &u_sta_hfid[i], 8);
+
+ bitstream_finalise (&bitstream);
+
+ cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req (&ctx, mme);
+
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless (!(strcmp(own->hfid_user, u_sta_hfid)));
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_AVLN_HFID_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ char avln_hfid[CP_HFID_SIZE + 1];
+
+ /* sample avln human friendly identifier:
+ * Spidcom_SPC_300_EoC_avln_HFID_123. */
+ memset (avln_hfid, 0, sizeof (avln_hfid));
+ strcpy (avln_hfid, "Spidcom_SPC_300_EoC_avln_HFID_123");
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_M_STA_HFID_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ for(i = 0; i < CP_HFID_SIZE; i++)
+ bitstream_access (&bitstream, &avln_hfid[i], 8);
+ bitstream_finalise (&bitstream);
+
+ cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req (&ctx, mme);
+
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless (!(strcmp(own->hfid_avln, avln_hfid)));
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_KEY_REQ change NID")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ uint cl;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ cp_nid_t nid;
+ cp_net_t *net;
+ cp_key_t nmk;
+ enum cp_msg_drv_sta_set_key_type_t type;
+ cp_security_level_t sl;
+
+ /* sample network id: 0x11223344556677 */
+ nid = 0x11223344556677ull;
+
+ /* Possible security level values:
+ * CP_SECURITY_LEVEL_SC, CP_SECURITY_LEVEL_HS. */
+ sl = CP_SECURITY_LEVEL_HS;
+
+ /* Possible type values:
+ * CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_NID,
+ * CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_SECURITY_LEVEL,
+ * CP_MSG_DRV_STA_SET_KEY_TYPE_NB */
+ type = CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_NID;
+
+ /* sample network membership key: */
+ nmk.key[0] = 0x11111111;
+ nmk.key[1] = 0x22222222;
+ nmk.key[2] = 0x33333333;
+ nmk.key[3] = 0x44444444;
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ cp_eoc_sta_mgr_init (&ctx);
+
+ /* set our avln */
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ cp_sta_own_data_set_security_level (&ctx, sl);
+
+ mme->mmtype = DRV_STA_SET_KEY_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ for (i = 0; i < COUNT (nmk.key); i++)
+ bitstream_access (&bitstream, &nmk.key[i], 32);
+
+ bitstream_access (&bitstream, &type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &sl, 8);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 25;
+
+ cp_sta_action_drv__stopped__drv_sta_set_key_req (&ctx, mme);
+
+ for (i = 0; i < COUNT (nmk.key); i++)
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nmk.key[i] == nmk.key[i]);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nid ==
+ (((cp_nid_t) sl << 52) | nid));
+
+ test_fail_unless (ctx.sta_mgr.our_avln->nid ==
+ (((cp_nid_t) sl << 52) | nid));
+
+ /* When NID is changed, SL should stay the same */
+ test_fail_unless (ctx.sta_mgr.sta_own_data.security_level == sl);
+ }
+ test_end
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_KEY_REQ change sl")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ uint cl;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ cp_nid_t nid;
+ cp_net_t *net;
+ cp_key_t nmk;
+ enum cp_msg_drv_sta_set_key_type_t type;
+ cp_security_level_t sl;
+
+ /* sample network id: 0x11223344556677 */
+ nid = 0x11223344556677ull;
+
+ /* Possible security level values:
+ * CP_SECURITY_LEVEL_SC, CP_SECURITY_LEVEL_HS */
+ sl = CP_SECURITY_LEVEL_SC;
+
+ /* Possible type values:
+ * CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_NID,
+ * CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_SECURITY_LEVEL,
+ * CP_MSG_DRV_STA_SET_KEY_TYPE_NB */
+ type = CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_SECURITY_LEVEL;
+
+ /* sample network membership key: */
+ nmk.key[0] = 0x11111111;
+ nmk.key[1] = 0x22222222;
+ nmk.key[2] = 0x33333333;
+ nmk.key[3] = 0x44444444;
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ cp_eoc_sta_mgr_init (&ctx);
+
+ /* set our avln */
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ cp_sta_own_data_set_security_level (&ctx, sl);
+
+ mme->mmtype = DRV_STA_SET_KEY_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ for (i = 0; i < COUNT (nmk.key); i++)
+ bitstream_access (&bitstream, &nmk.key[i], 32);
+
+ bitstream_access (&bitstream, &type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &sl, 8);
+ bitstream_finalise (&bitstream);
+
+ mme->length = 25;
+
+ cp_sta_action_drv__stopped__drv_sta_set_key_req (&ctx, mme);
+
+ for (i = 0; i < COUNT (nmk.key); i++)
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nmk.key[i] == nmk.key[i]);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.security_level == sl);
+ /* STA that changes Security Level shall discard the previous NMK. */
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nid !=
+ (((cp_nid_t) sl << 52) | nid));
+ test_fail_unless (ctx.sta_mgr.our_avln->nid !=
+ (((cp_nid_t) sl << 52) | nid));
+ }
+ test_end
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_DAK_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ bitstream_t bitstream;
+ cp_key_t dak;
+ u8 buffer[1024];
+
+ /* sample device access key: */
+ dak.key[0] = 0x11111111;
+ dak.key[1] = 0x22222222;
+ dak.key[2] = 0x33333333;
+ dak.key[3] = 0x44444444;
+
+ ctx.mac_config = &mac_config;
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->mmtype = DRV_STA_SET_DAK_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ for (i = 0; i < COUNT (dak.key); i++)
+ bitstream_access (&bitstream, &dak.key[i], 32);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 16;
+
+ cp_sta_action_drv__stopped__drv_sta_set_dak_req (&ctx, mme);
+
+ for (i = 0; i < COUNT (dak.key); i++)
+ {
+ test_fail_unless (ctx.sta_mgr.sta_own_data.dak.key[i] == dak.key[i]);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_TONEMASK_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint i;
+ bitstream_t bitstream;
+ tonemask_info_t ti;
+ u8 buffer[2048];
+ u32 ff32, ff10;
+
+ ctx.mac_config = &mac_config;
+ mac_config_init (ctx.mac_config);
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ ff32 = 0xffffffff;
+ ff10 = 0x3ff;
+
+ mme->mmtype = DRV_STA_SET_TONEMASK_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ ti.carrier_nb = tonemask_default (ti.tonemask);
+ tonemask_update(&ti);
+
+ /* ti.tonemask[2] = 0x3FFFFFFC by default,
+ * MSB coresponds to carrier 169 (0-enable,
+ * 1-disable), by default it is enabled (MSB = 0). */
+
+ /* disable carrier number 169
+ * (set MSB to 1, i.e. ti.tonemask[2] = 0xBFFFFFFC. */
+ ti.tonemask[2] = 0xBFFFFFFC;
+ tonemask_update(&ti);
+
+ for (i = 0; i < PHY_CARRIER_OFFSET / 32; i++)
+ bitstream_access (&bitstream, &ff32, 32);
+
+ bitstream_access (&bitstream, &ff10, 10);
+
+ for (i = 0; i < PHY_TONEMASK_WORDS; i++)
+ bitstream_access (&bitstream, &ti.tonemask[i], 32);
+
+ for (i = 0; i <= (PHY_ALL_CARRIER_NB - PHY_TONEMASK_WORDS * 32
+ - PHY_CARRIER_OFFSET) / 32; i++)
+ bitstream_access (&bitstream, &ff32, 32);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = PHY_TONEMASK_WORDS * 32 + PHY_CARRIER_OFFSET + \
+ (PHY_ALL_CARRIER_NB - PHY_TONEMASK_WORDS * 32 -
+ PHY_CARRIER_OFFSET) ;
+
+ cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (&ctx, mme);
+
+ test_fail_unless (ctx.mac_config->tonemask_info.carrier_nb ==
+ ti.carrier_nb);
+
+ for (i = 0; i < PHY_TONEMASK_WORDS; i++)
+ test_fail_unless (ctx.mac_config->tonemask_info.tonemask[i] ==
+ ti.tonemask[i]);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_WL_REQ new")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ uint numStas;
+ cp_tei_t stas_teis[3];
+ mac_t stas_macs[3];
+ u8 stas_authorizations[3];
+ u8 stas_output_levels[3];
+ u32 stas_start_times[3];
+ u32 stas_end_times[3];
+ cp_key_t stas_daks[3];
+ u8 stas_actions[3];
+ cp_dpw_t stas_dpws[3];
+ memset (stas_dpws, 0, 3 * sizeof (cp_dpw_t));
+ u8 buffer[1024];
+
+ uint i,j;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ /* First case is to set authorizations for
+ * stations which are not registered until now. */
+ mme->mmtype = VS_EOC_CCO_SET_WL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 3;
+ stas_macs[0] = 0x111111111111ull;
+ stas_macs[1] = 0x222222222222ull;
+ stas_macs[2] = 0x333333333333ull;
+ stas_teis[0] = 20;
+ stas_teis[1] = 21;
+ stas_teis[2] = 22;
+ stas_authorizations[0] = true;
+ stas_authorizations[1] = false;
+ stas_authorizations[2] = true;
+ stas_output_levels[0] = 0x78;
+ stas_output_levels[1] = 0x79;
+ stas_output_levels[2] = 0x7A;
+ stas_start_times[0] = 0x10000000;
+ stas_start_times[1] = 0x20000000;
+ stas_start_times[2] = 0x30000000;
+ stas_end_times[0] = 0x40000000;
+ stas_end_times[1] = 0x50000000;
+ stas_end_times[2] = 0x60000000;
+ stas_daks[0].key[0] = 0x11110000;
+ stas_daks[0].key[1] = 0x00001101;
+ stas_daks[0].key[2] = 0x01010101;
+ stas_daks[0].key[3] = 0x11111111;
+ stas_daks[1].key[0] = 0x22220000;
+ stas_daks[1].key[1] = 0x22001101;
+ stas_daks[1].key[2] = 0x02020202;
+ stas_daks[1].key[3] = 0x11112222;
+ stas_daks[2].key[0] = 0x33333333;
+ stas_daks[2].key[1] = 0x33001101;
+ stas_daks[2].key[2] = 0x01033301;
+ stas_daks[2].key[3] = 0x03030303;
+ strcpy (stas_dpws[0].dpw, "SPiDCOM - SPC300 - 1");
+ strcpy (stas_dpws[1].dpw, "SPiDCOM - SPC300 - 2");
+ strcpy (stas_dpws[2].dpw, "SPiDCOM - SPC300 - 3");
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+ stas_actions[2] = 0x00;
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ bitstream_access (&bitstream, &stas_teis[i], 8);
+ bitstream_access (&bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&bitstream, &stas_start_times[i], 32);
+ bitstream_access (&bitstream, &stas_end_times[i], 32);
+ for (j = 0; j < 4; j++)
+ bitstream_access (&bitstream, &stas_daks[i].key[j], 32);
+ bitstream_write_buf(&bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ bitstream_access (&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t), NULL);
+ cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (&ctx, mme);
+
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ dbg_assert (sta);
+ cp_tei_t tei = cp_sta_get_tei(sta);
+
+ test_fail_unless(tei == stas_teis[i]);
+ test_fail_unless(sta->multi_sta.allowed == stas_authorizations[i]);
+ test_fail_unless(sta->multi_sta.output_level ==
+ stas_output_levels[i]);
+ test_fail_unless(sta->multi_sta.start_time == stas_start_times[i]);
+ test_fail_unless(sta->multi_sta.end_time == stas_end_times[i]);
+ for (j = 0; j < 4; j++)
+ test_fail_unless(sta->multi_sta.dak.key[j] ==
+ stas_daks[i].key[j]);
+ for (j = 0; j < CP_DPW_MAX_SIZE; j++)
+ test_fail_unless(((cp_sta_private_t *)sta)->dpw.dpw[j]
+ == stas_dpws[i].dpw[j]);
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ test_fail_unless (ctx.cco_action.wl_complete == 1);
+ slab_release (sta);
+ }
+ /* Remove the stations. It is only in sta_mgr list. */
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ slab_release (sta);
+ slab_release (sta);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_WL_REQ"
+ " change existing")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+
+ cp_net_t *net;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ uint numStas;
+ cp_tei_t stas_teis[3];
+ mac_t stas_macs[3];
+ u8 stas_authorizations[3];
+ u8 stas_output_levels[3];
+ u32 stas_start_times[3];
+ u32 stas_end_times[3];
+ cp_key_t stas_daks[3];
+ cp_dpw_t stas_dpws[3];
+ memset (stas_dpws, 0, 3 * sizeof (cp_dpw_t));
+ u8 stas_actions[3];
+ u8 buffer[1024];
+
+ uint i,j;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ /* Second case is to change authorizations
+ * for stations which are registered before. */
+ mme->mmtype = VS_EOC_CCO_SET_WL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 3;
+ stas_macs[0] = 0x111111111111ull;
+ stas_macs[1] = 0x222222222222ull;
+ stas_macs[2] = 0x333333333333ull;
+ stas_teis[0] = 201;
+ stas_teis[1] = 202;
+ stas_teis[2] = 203;
+ stas_authorizations[0] = false;
+ stas_authorizations[1] = true;
+ stas_authorizations[2] = false;
+ stas_output_levels[0] = 0x01;
+ stas_output_levels[1] = 0x02;
+ stas_output_levels[2] = 0x03;
+ stas_start_times[0] = 0x10000000;
+ stas_start_times[1] = 0x20000000;
+ stas_start_times[2] = 0x30000000;
+ stas_end_times[0] = 0x40000000;
+ stas_end_times[1] = 0x50000000;
+ stas_end_times[2] = 0x60000000;
+ stas_daks[0].key[0] = 0x11110000;
+ stas_daks[0].key[1] = 0x00001101;
+ stas_daks[0].key[2] = 0x01010101;
+ stas_daks[0].key[3] = 0x11111111;
+ stas_daks[1].key[0] = 0x22220000;
+ stas_daks[1].key[1] = 0x22001101;
+ stas_daks[1].key[2] = 0x02020202;
+ stas_daks[1].key[3] = 0x11112222;
+ stas_daks[2].key[0] = 0x33333333;
+ stas_daks[2].key[1] = 0x33001101;
+ stas_daks[2].key[2] = 0x01033301;
+ stas_daks[2].key[3] = 0x03030303;
+ strcpy (stas_dpws[0].dpw, "SPiDCOM - SPC300 - 1");
+ strcpy (stas_dpws[1].dpw, "SPiDCOM - SPC300 - 2");
+ strcpy (stas_dpws[2].dpw, "SPiDCOM - SPC300 - 3");
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+ stas_actions[2] = 0x00;
+
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ bitstream_access (&bitstream, &stas_teis[i], 8);
+ bitstream_access (&bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&bitstream, &stas_start_times[i], 32);
+ bitstream_access (&bitstream, &stas_end_times[i], 32);
+ for (j = 0; j < 4; j++)
+ bitstream_access (&bitstream, &stas_daks[i].key[j], 32);
+ bitstream_write_buf(&bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ bitstream_access (&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t), NULL);
+ cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (&ctx, mme);
+
+ /* Now, change authorizations for previously added stations */
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 3;
+ stas_macs[0] = 0x111111111111ull;
+ stas_macs[1] = 0x222222222222ull;
+ stas_macs[2] = 0x333333333333ull;
+ stas_teis[0] = 201;
+ stas_teis[1] = 202;
+ stas_teis[2] = 203;
+ stas_authorizations[0] = true;
+ stas_authorizations[1] = false;
+ stas_authorizations[2] = true;
+ stas_output_levels[0] = 0x01;
+ stas_output_levels[1] = 0x02;
+ stas_output_levels[2] = 0x03;
+ stas_start_times[0] = 0x10000000;
+ stas_start_times[1] = 0x20000000;
+ stas_start_times[2] = 0x30000000;
+ stas_end_times[0] = 0x40000000;
+ stas_end_times[1] = 0x50000000;
+ stas_end_times[2] = 0x60000000;
+ stas_daks[0].key[0] = 0x11110000;
+ stas_daks[0].key[1] = 0x00001101;
+ stas_daks[0].key[2] = 0x01010101;
+ stas_daks[0].key[3] = 0x11111111;
+ stas_daks[1].key[0] = 0x22220000;
+ stas_daks[1].key[1] = 0x22001101;
+ stas_daks[1].key[2] = 0x02020202;
+ stas_daks[1].key[3] = 0x11112222;
+ stas_daks[2].key[0] = 0x33333333;
+ stas_daks[2].key[1] = 0x33001101;
+ stas_daks[2].key[2] = 0x01033301;
+ stas_daks[2].key[3] = 0x03030303;
+ strcpy (stas_dpws[0].dpw, "SPiDCOM - SPC300 - 1");
+ strcpy (stas_dpws[1].dpw, "SPiDCOM - SPC300 - 2");
+ strcpy (stas_dpws[2].dpw, "SPiDCOM - SPC300 - 3");
+
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+ stas_actions[2] = 0x00;
+
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ bitstream_access (&bitstream, &stas_teis[i], 8);
+ bitstream_access (&bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&bitstream, &stas_start_times[i], 32);
+ bitstream_access (&bitstream, &stas_end_times[i], 32);
+ for (j = 0; j < 4; j++)
+ bitstream_access (&bitstream, &stas_daks[i].key[j], 32);
+ bitstream_write_buf(&bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ bitstream_access (&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (&ctx, mme);
+
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ cp_tei_t tei = cp_sta_get_tei(sta);
+
+ test_fail_unless(tei == stas_teis[i]);
+ test_fail_unless(sta->multi_sta.allowed == stas_authorizations[i]);
+ test_fail_unless(sta->multi_sta.output_level ==
+ stas_output_levels[i]);
+ test_fail_unless(sta->multi_sta.start_time == stas_start_times[i]);
+ test_fail_unless(sta->multi_sta.end_time == stas_end_times[i]);
+ for (j = 0; j < 4; j++)
+ test_fail_unless(sta->multi_sta.dak.key[j] ==
+ stas_daks[i].key[j]);
+ for (j = 0; j < CP_DPW_MAX_SIZE; j++)
+ test_fail_unless(((cp_sta_private_t *)sta)->dpw.dpw[j]
+ == stas_dpws[i].dpw[j]);
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ test_fail_unless (ctx.cco_action.wl_complete == 1);
+ slab_release (sta);
+ }
+ /* Remove the stations. It is only in sta_mgr list. */
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ slab_release (sta);
+ slab_release (sta);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_WL_REQ "
+ "unassociated stas")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+
+ cp_net_t *net;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ uint numStas;
+ cp_tei_t stas_teis[3];
+ mac_t stas_macs[3];
+ u8 stas_authorizations[3];
+ u8 stas_output_levels[3];
+ u32 stas_start_times[3];
+ u32 stas_end_times[3];
+ cp_key_t stas_daks[3];
+ cp_dpw_t stas_dpws[3];
+ memset (stas_dpws, 0, 3 * sizeof (cp_dpw_t));
+ u8 stas_actions[3];
+ u8 buffer[1024];
+
+ uint i,j;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ /* Third case is to set authorizations for stations which
+ * have tried to associate before. Such stations are registerd,
+ * do not have teis assigned and are not allowed in the white list
+ * (their authorizations "allowed" fields are set to "false" by
+ * default) */
+
+ mme->mmtype = VS_EOC_CCO_SET_WL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 3;
+ stas_macs[0] = 0x444444444444ull;
+ stas_macs[1] = 0x555555555555ull;
+ stas_macs[2] = 0x666666666666ull;
+ stas_teis[0] = 204;
+ stas_teis[1] = 205;
+ stas_teis[2] = 206;
+ stas_authorizations[0] = false;
+ stas_authorizations[1] = true;
+ stas_authorizations[2] = false;
+ stas_output_levels[0] = 0x01;
+ stas_output_levels[1] = 0x02;
+ stas_output_levels[2] = 0x03;
+ stas_start_times[0] = 0x10000000;
+ stas_start_times[1] = 0x20000000;
+ stas_start_times[2] = 0x30000000;
+ stas_end_times[0] = 0x40000000;
+ stas_end_times[1] = 0x50000000;
+ stas_end_times[2] = 0x60000000;
+ stas_daks[0].key[0] = 0x11110000;
+ stas_daks[0].key[1] = 0x00001101;
+ stas_daks[0].key[2] = 0x01010101;
+ stas_daks[0].key[3] = 0x11111111;
+ stas_daks[1].key[0] = 0x22220000;
+ stas_daks[1].key[1] = 0x22001101;
+ stas_daks[1].key[2] = 0x02020202;
+ stas_daks[1].key[3] = 0x11112222;
+ stas_daks[2].key[0] = 0x33333333;
+ stas_daks[2].key[1] = 0x33001101;
+ stas_daks[2].key[2] = 0x01033301;
+ stas_daks[2].key[3] = 0x03030303;
+ strcpy (stas_dpws[0].dpw, "SPiDCOM - SPC300 - 1");
+ strcpy (stas_dpws[1].dpw, "SPiDCOM - SPC300 - 2");
+ strcpy (stas_dpws[2].dpw, "SPiDCOM - SPC300 - 3");
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+ stas_actions[2] = 0x00;
+
+ cp_sta_t *sta = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED,
+ stas_macs[0]);
+ dbg_assert (sta);
+ slab_release (sta);
+ sta = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED,
+ stas_macs[1]);
+ dbg_assert (sta);
+ slab_release (sta);
+ sta = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED,
+ stas_macs[2]);
+ dbg_assert (sta);
+ slab_release (sta);
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ bitstream_access (&bitstream, &stas_teis[i], 8);
+ bitstream_access (&bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&bitstream, &stas_start_times[i], 32);
+ bitstream_access (&bitstream, &stas_end_times[i], 32);
+ for (j = 0; j < 4; j++)
+ {
+ bitstream_access (&bitstream, &stas_daks[i].key[j], 32);
+ }
+ bitstream_write_buf(&bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ bitstream_access (&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t), NULL);
+ cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (&ctx, mme);
+
+ for(i = 0; i < numStas; i++)
+ {
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ cp_tei_t tei = cp_sta_get_tei(sta);
+
+ test_fail_unless(tei == stas_teis[i]);
+ test_fail_unless(sta->multi_sta.allowed == stas_authorizations[i]);
+ test_fail_unless(sta->multi_sta.output_level ==
+ stas_output_levels[i]);
+ test_fail_unless(sta->multi_sta.start_time == stas_start_times[i]);
+ test_fail_unless(sta->multi_sta.end_time == stas_end_times[i]);
+ for (j = 0; j < 4; j++)
+ test_fail_unless(sta->multi_sta.dak.key[j] ==
+ stas_daks[i].key[j]);
+ for (j = 0; j < CP_DPW_MAX_SIZE; j++)
+ test_fail_unless(((cp_sta_private_t *)sta)->dpw.dpw[j]
+ == stas_dpws[i].dpw[j]);
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ test_fail_unless (ctx.cco_action.wl_complete == 1);
+ slab_release (sta);
+ }
+ /* Remove the stations. It is only in sta_mgr list. */
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ slab_release (sta);
+ slab_release (sta);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_WL_REQ"
+ " add new stations and change authorisation")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ uint numStas;
+ cp_tei_t stas_teis[2];
+ mac_t stas_macs[2];
+ u8 stas_authorizations[2];
+ u8 stas_output_levels[2];
+ u32 stas_start_times[2];
+ u32 stas_end_times[2];
+ cp_key_t stas_daks[2];
+ cp_dpw_t stas_dpws[2];
+ memset (stas_dpws, 0, 2 * sizeof (cp_dpw_t));
+ u8 stas_actions[2];
+ u8 buffer[1024];
+
+ uint i,j;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ /* First case is to set authorizations for stations which are not
+ registered until now */
+ mme->mmtype = VS_EOC_CCO_SET_WL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 2;
+ stas_macs[0] = 0x777777777777ull;
+ stas_macs[1] = 0x888888888888ull;
+ stas_teis[0] = 207;
+ stas_teis[1] = 208;
+ stas_authorizations[0] = true;
+ stas_authorizations[1] = false;
+ stas_output_levels[0] = 0x78;
+ stas_output_levels[1] = 0x79;
+ stas_start_times[0] = 0x10000000;
+ stas_start_times[1] = 0x20000000;
+ stas_end_times[0] = 0x40000000;
+ stas_end_times[1] = 0x50000000;
+ stas_daks[0].key[0] = 0x11110000;
+ stas_daks[0].key[1] = 0x00001101;
+ stas_daks[0].key[2] = 0x01010101;
+ stas_daks[0].key[3] = 0x11111111;
+ stas_daks[1].key[0] = 0x22220000;
+ stas_daks[1].key[1] = 0x22001101;
+ stas_daks[1].key[2] = 0x02020202;
+ stas_daks[1].key[3] = 0x11112222;
+ strcpy (stas_dpws[0].dpw, "SPiDCOM - SPC300 - 1");
+ strcpy (stas_dpws[1].dpw, "SPiDCOM - SPC300 - 2");
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ bitstream_access (&bitstream, &stas_teis[i], 8);
+ bitstream_access (&bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&bitstream, &stas_start_times[i], 32);
+ bitstream_access (&bitstream, &stas_end_times[i], 32);
+ for (j = 0; j < 4; j++)
+ {
+ bitstream_access (&bitstream, &stas_daks[i].key[j], 32);
+ }
+ bitstream_write_buf(&bitstream, (u8 *) stas_dpws[i].dpw,
+ CP_DPW_MAX_SIZE);
+ bitstream_access (&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t), NULL);
+ cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (&ctx, mme);
+
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ dbg_assert (sta);
+ cp_tei_t tei = cp_sta_get_tei(sta);
+
+ test_fail_unless(tei == stas_teis[i]);
+ test_fail_unless(sta->multi_sta.allowed == stas_authorizations[i]);
+ test_fail_unless(sta->multi_sta.output_level ==
+ stas_output_levels[i]);
+ test_fail_unless(sta->multi_sta.start_time == stas_start_times[i]);
+ test_fail_unless(sta->multi_sta.end_time == stas_end_times[i]);
+ for (j = 0; j < 4; j++)
+ test_fail_unless(sta->multi_sta.dak.key[j] ==
+ stas_daks[i].key[j]);
+ for (j = 0; j < CP_DPW_MAX_SIZE; j++)
+ test_fail_unless(((cp_sta_private_t *)sta)->dpw.dpw[j]
+ == stas_dpws[i].dpw[j]);
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ test_fail_unless (ctx.cco_action.wl_complete == 1);
+ slab_release (sta);
+ }
+
+ /*station 207 sends assoc_req, and is successfully associated*/
+ uint req_type = CP_MSG_CC_ASSOC_REQ_TYPE_NEW;
+ u64 nid = 1;
+ uint cco_cap = 2;
+ uint pco_cap = true;
+ uint num_stas;
+ uint num_associated_stas;
+
+ mme->peer.mac = 0x777777777777ull;
+ mme->peer.tei = 207;
+ mme->mmtype = CC_ASSOC_REQ;
+
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+ num_stas = net->num_stas;
+ num_associated_stas = net->num_associated_stas;
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_associated);
+ test_fail_unless (net->num_stas == num_stas + 1);
+ test_fail_unless (net->num_associated_stas == num_associated_stas + 1);
+ slab_release (sta);
+ slab_release (sta);
+ /*station 208 sends assoc_req, it is not associated, this must increase
+ number of stations in the network*/
+ mme->peer.mac = 0x888888888888ull;
+ mme->peer.tei = 208;
+ mme->mmtype = CC_ASSOC_REQ;
+
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+ num_stas = net->num_stas;
+ num_associated_stas = net->num_associated_stas;
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_unassociated);
+ test_fail_unless (net->num_stas == num_stas + 1);
+ test_fail_unless (net->num_associated_stas == num_associated_stas);
+ slab_release (sta);
+ slab_release (sta);
+
+ /*set station 207 authorisation to false*/
+ mme->mmtype = VS_EOC_CCO_SET_WL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 1;
+ stas_macs[0] = 0x777777777777ull;
+ stas_teis[0] = 207;
+ stas_authorizations[0] = false;
+ stas_output_levels[0] = 0x78;
+ stas_start_times[0] = 0x10000000;
+ stas_end_times[0] = 0x40000000;
+ stas_daks[0].key[0] = 0x11110000;
+ stas_daks[0].key[1] = 0x00001101;
+ stas_daks[0].key[2] = 0x01010101;
+ stas_daks[0].key[3] = 0x11111111;
+ stas_actions[0] = 0x00;
+
+ bitstream_access (&bitstream, &numStas, 8);
+
+ bitstream_access (&bitstream, &stas_macs[0], 48);
+ bitstream_access (&bitstream, &stas_teis[0], 8);
+ bitstream_access (&bitstream, &stas_authorizations[0], 8);
+ bitstream_access (&bitstream, &stas_output_levels[0], 8);
+ bitstream_access (&bitstream, &stas_start_times[0], 32);
+ bitstream_access (&bitstream, &stas_end_times[0], 32);
+ for (j = 0; j < 4; j++)
+ bitstream_access (&bitstream, &stas_daks[0].key[j], 32);
+ bitstream_access (&bitstream, &stas_actions[0], 8);
+
+ bitstream_finalise (&bitstream);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t), NULL);
+ cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[0]);
+ cp_tei_t tei = cp_sta_get_tei(sta);
+
+ test_fail_unless(tei == stas_teis[0]);
+ test_fail_unless(sta->multi_sta.allowed == stas_authorizations[0]);
+ test_fail_unless(sta->multi_sta.output_level == stas_output_levels[0]);
+ test_fail_unless(sta->multi_sta.start_time == stas_start_times[0]);
+ test_fail_unless(sta->multi_sta.end_time == stas_end_times[0]);
+ for (j = 0; j < 4; j++)
+ {
+ test_fail_unless(sta->multi_sta.dak.key[j] == stas_daks[0].key[j]);
+ }
+ test_fail_unless(sta->multi_sta.action == stas_actions[0]);
+ test_fail_unless (ctx.cco_action.wl_complete == 1);
+ slab_release (sta);
+ /* now station 207 sends assoc_req before it is actually removed by
+ * cp_cco_action_garbage, this must not change number of stations in
+ * network. */
+
+ mme->peer.mac = 0x777777777777ull;
+ mme->peer.tei = 207;
+ mme->mmtype = CC_ASSOC_REQ;
+
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+ num_stas = net->num_stas;
+ num_associated_stas = net->num_associated_stas;
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_unassociated);
+ test_fail_unless (net->num_stas == num_stas);
+ test_fail_unless (net->num_associated_stas == num_associated_stas);
+ slab_release (sta);
+ slab_release (sta);
+ /* The cp_cco_action_garbage removes station 207 and changes
+ * the number of associated stations in the network. */
+ num_stas = net->num_stas;
+ num_associated_stas = net->num_associated_stas;
+ ctx.sta_mgr.sta_own_data.is_cco = true;
+ cp_cco_action_garbage (&ctx);
+ test_fail_unless (net->num_stas == num_stas);
+ test_fail_unless (net->num_associated_stas == num_associated_stas - 1);
+
+ /* now station 207 sends assoc_req after it is actually removed,
+ * this must not change number of stations. */
+ mme->peer.mac = 0x777777777777ull;
+ mme->peer.tei = 207;
+ mme->mmtype = CC_ASSOC_REQ;
+
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+ num_stas = net->num_stas;
+ num_associated_stas = net->num_associated_stas;
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_unassociated);
+ test_fail_unless (net->num_stas == num_stas);
+ test_fail_unless (net->num_associated_stas == num_associated_stas);
+ slab_release (sta);
+ slab_release (sta);
+ /* Remove all mfs. */
+ cp_eoc_cco_action_test_release_mac_store (&ctx);
+ /* Release and remove stations. */
+ for (sta = cp_net_sta_get_first (&ctx, net, CP_NET_STA_UNASSOC); sta;)
+ {
+ cp_sta_t *sta1 = sta;
+ sta = cp_net_sta_get_next_status (&ctx, net, sta,
+ CP_NET_STA_UNASSOC);
+ uint tei = cp_sta_get_tei (sta1);
+ if (tei)
+ {
+ sta_t *station = mac_store_sta_get (ctx.mac_store, tei);
+ if (station)
+ {
+ blk_release (station);
+ sar_sta_remove (ctx.sar, tei);
+ }
+ }
+ slab_release (sta1);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_GET_WL_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+
+ cp_net_t *net;
+ cp_sta_t *sta;
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ uint numStas;
+ cp_tei_t stas_teis[3];
+ mac_t stas_macs[3];
+ u8 stas_authorizations[3];
+ u8 stas_output_levels[3];
+ u32 stas_start_times[3];
+ u32 stas_end_times[3];
+ u64 stas_daks[3];
+ u8 stas_actions[3];
+ u8 buffer[1024];
+
+ uint i;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ mme->mmtype = VS_EOC_CCO_GET_WL_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 3;
+ stas_macs[0] = 0x444444444444ull;
+ stas_macs[1] = 0x555555555555ull;
+ stas_macs[2] = 0x666666666666ull;
+ stas_teis[0] = 204;
+ stas_teis[1] = 205;
+ stas_teis[2] = 206;
+ stas_authorizations[0] = false;
+ stas_authorizations[1] = true;
+ stas_authorizations[2] = false;
+ stas_output_levels[0] = 0x01;
+ stas_output_levels[1] = 0x02;
+ stas_output_levels[2] = 0x03;
+ stas_start_times[0] = 0x10000000;
+ stas_start_times[1] = 0x20000000;
+ stas_start_times[2] = 0x30000000;
+ stas_end_times[0] = 0x40000000;
+ stas_end_times[1] = 0x50000000;
+ stas_end_times[2] = 0x60000000;
+ stas_daks[0] = 0x1111000000001111ull;
+ stas_daks[1] = 0x2222000000002222ull;
+ stas_daks[2] = 0x3333000000003333ull;
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+ stas_actions[2] = 0x00;
+
+ for(i = 0; i < numStas; i++)
+ {
+ sta = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED,
+ stas_macs[i]);
+ dbg_assert (sta);
+ slab_release (sta);
+ }
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ bitstream_access (&bitstream, &stas_teis[i], 8);
+ bitstream_access (&bitstream, &stas_authorizations[i], 8);
+ bitstream_access (&bitstream, &stas_output_levels[i], 8);
+ bitstream_access (&bitstream, &stas_start_times[i], 32);
+ bitstream_access (&bitstream, &stas_end_times[i], 32);
+ bitstream_access (&bitstream, &stas_daks[i], 64);
+ bitstream_access (&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (&ctx, mme);
+ /* Release the stations. */
+ for (sta = cp_net_sta_get_first (&ctx, net, CP_NET_STA_UNASSOC); sta;)
+ {
+ cp_sta_t *sta1 = sta;
+ sta = cp_net_sta_get_next_status (&ctx, net, sta,
+ CP_NET_STA_UNASSOC);
+ slab_release (sta1);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_GET_TOPO_REQ new")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ u8 buffer[1024];
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ /* First case is to set authorizations for stations
+ * which are not registered until now. */
+ mme->mmtype = VS_EOC_GET_TOPO_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (&ctx, mme);
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing VS_EOC_SET_PORTS_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+ uint cl;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+ uint numStas;
+ mac_t stas_macs[3];
+ cp_tei_t stas_teis[3];
+ bool stas_ports_ed[3][PORT_NB];
+ u8 stas_ports_service[3][PORT_NB];
+ u8 buffer[1024];
+ uint i, j;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ mme->mmtype = VS_EOC_SET_PORTS_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ numStas = 3;
+ stas_macs[0] = 0x111111111111ull;
+ stas_macs[1] = 0x222222222222ull;
+ stas_macs[2] = 0x333333333333ull;
+ stas_teis[0] = 0x1E;
+ stas_teis[1] = 0x1F;
+ stas_teis[2] = 0x20;
+ stas_ports_ed[0][0] = true;
+ stas_ports_ed[0][1] = false;
+ stas_ports_ed[0][2] = true;
+ stas_ports_ed[0][3] = false;
+ stas_ports_ed[0][4] = true;
+ stas_ports_service[0][0] = 0x01;
+ stas_ports_service[0][1] = 0x02;
+ stas_ports_service[0][2] = 0x03;
+ stas_ports_service[0][3] = 0x0D;
+ stas_ports_service[0][4] = 0x0E;
+ stas_ports_ed[1][0] = false;
+ stas_ports_ed[1][1] = false;
+ stas_ports_ed[1][2] = false;
+ stas_ports_ed[1][3] = false;
+ stas_ports_ed[1][4] = false;
+ stas_ports_service[1][0] = 0x04;
+ stas_ports_service[1][1] = 0x05;
+ stas_ports_service[1][2] = 0x06;
+ stas_ports_service[1][3] = 0x0E;
+ stas_ports_service[1][4] = 0x0F;
+ stas_ports_ed[2][0] = true;
+ stas_ports_ed[2][1] = true;
+ stas_ports_ed[2][2] = true;
+ stas_ports_ed[2][3] = true;
+ stas_ports_ed[2][4] = true;
+ stas_ports_service[2][0] = 0x07;
+ stas_ports_service[2][1] = 0x08;
+ stas_ports_service[2][2] = 0x09;
+ stas_ports_service[2][3] = 0x0F;
+ stas_ports_service[2][4] = 0x0E;
+
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t * sta = cp_sta_mgr_sta_add (&ctx, net, stas_teis[i],
+ stas_macs[i]);
+ dbg_assert (sta);
+ slab_release (sta);
+ }
+
+ bitstream_access (&bitstream, &numStas, 8);
+ for(i = 0; i < numStas; i++)
+ {
+ bitstream_access (&bitstream, &stas_macs[i], 48);
+ for(j = 0; j < PORT_NB; j++)
+ {
+ bitstream_access (&bitstream, &stas_ports_ed[i][j], 8);
+ bitstream_access (&bitstream, &stas_ports_service[i][j], 8);
+ }
+ }
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req (&ctx, mme);
+
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ cp_tei_t tei = cp_sta_get_tei(sta);
+
+ test_fail_unless(tei == stas_teis[i]);
+ for(j = 0; j < PORT_NB; j++)
+ {
+ test_fail_unless(sta->multi_sta.ports.port[j].enabled ==
+ stas_ports_ed[i][j]);
+ test_fail_unless(
+ sta->multi_sta.ports.port[j].index_of_service ==
+ stas_ports_service[i][j]);
+ }
+ slab_release (sta);
+ }
+ for(i = 0; i < numStas; i++)
+ {
+ cp_sta_t *sta = cp_sta_mgr_sta_get_from_mac(&ctx, stas_macs[i]);
+ dbg_assert (sta);
+ cp_sta_mgr_sta_remove (&ctx, sta);
+ slab_release (sta);
+ }
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing VS_EOC_GET_PORTS_REQ")
+ {
+
+ uint test_fail_nb_temp;
+ uint numStas = 10;
+ uint numStasUnassoc = 5;
+ test_sta_action_t ctx;
+
+ cp_t *cp = &ctx.cp;
+
+ u8 first_mac_index_number = 2;
+
+ const cp_nid_t our_nid = 0x111111111111ull;
+
+ cp_tei_t tei = 10;
+
+
+ /* init globals */
+ scenario_globals_t globals = {
+ .cp = &ctx.cp,
+ };
+
+ cp_mme_peer_t peer = CP_MME_PEER (0x112233445577ull, 5);
+ cp_mme_tx_t mme_to_send;
+ globals.mme = &mme_to_send;
+
+ test_sta_action_init (&ctx);
+
+ sar_t sar;
+ sar.mac_store = globals.cp->mac_store;
+ globals.cp->sar = &sar;
+
+ /* Create our net/AVLN. */
+ test_sta_action_create_our_net (&ctx, our_nid, tei);
+ cp_net_t *net = cp_sta_mgr_get_our_avln (cp);
+
+ test_fail_nb_temp = test->fail_nb;
+ SET_STATIONS(numStas);
+ SET_UNASSOC_STATIONS(numStas, numStasUnassoc);
+
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs_eoc__cco__vs_eoc_cco_get_ports_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_eoc_cco_get_ports_req_receive, .ok = true,
+ .first_mac_index_nb = first_mac_index_number),
+ SCENARIO_EVENT (cp_msg_vs_eoc_cco_get_ports_cnf_send, .peer = peer,
+ .result = CP_MSG_VS_EOC_CCO_GET_PORTS_REQ_RESULT_SUCCESS,
+ .numStas = numStas,
+ .stas_macs = stas_macs,
+ .stas_port_ed = stas_ports_ed,
+ .stas_port_service = stas_ports_service,
+ .first_mac_index_nb = first_mac_index_number),
+ SCENARIO_END
+ };
+ scenario_run (test, entries, &globals);
+
+ if(test_fail_nb_temp == test->fail_nb)
+ {
+ DBG_PRINT ("\"vs_eoc__cco__vs_eoc_cco_get_ports_req\" "
+ "successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"vs_eoc__cco__vs_eoc_cco_get_ports_req\" test failed");
+ test_fail_nb_temp = test->fail_nb;
+ }
+
+ cp_sta_t *sta;
+ /* Release the stations. First unassociated. */
+ for (sta = cp_net_sta_get_first (cp, net, CP_NET_STA_UNASSOC); sta;)
+ {
+ cp_sta_t *sta1 = sta;
+ sta = cp_net_sta_get_next_status (cp, net, sta,
+ CP_NET_STA_UNASSOC);
+ cp_sta_mgr_sta_remove (cp, sta1);
+ }
+ /* Associated. */
+ for (sta = cp_net_sta_get_first (cp, net, CP_NET_STA_ASSOC); sta;)
+ {
+ cp_sta_t *sta1 = sta;
+ sta = cp_net_sta_get_next_status (cp, net, sta,
+ CP_NET_STA_ASSOC);
+ cp_sta_mgr_sta_remove (cp, sta1);
+ }
+ test_sta_action_uninit (&ctx);
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing VS_EOC_GET_PORTS_REQ, "
+ "data from stations not correct")
+ {
+
+ uint test_fail_nb_temp;
+ uint numStas = 0;
+ test_sta_action_t ctx;
+ cp_t *cp = &ctx.cp;
+
+ u8 first_mac_index_number = 2;
+
+ const cp_nid_t our_nid = 0x111111111111ull;
+ cp_net_t *net;
+ net = cp_sta_mgr_add_avln (cp, 1, our_nid);
+
+ /* init globals */
+ scenario_globals_t globals = {
+ .cp = &ctx.cp,
+ };
+
+ cp_mme_peer_t peer = CP_MME_PEER (0x112233445577ull, 5);
+ cp_mme_tx_t mme_to_send;
+ globals.mme = &mme_to_send;
+
+ test_sta_action_init (&ctx);
+
+ sar_t sar;
+ sar.mac_store = globals.cp->mac_store;
+ globals.cp->sar = &sar;
+
+ test_fail_nb_temp = test->fail_nb;
+ SET_STATIONS(numStas);
+
+
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs_eoc__cco__vs_eoc_cco_get_ports_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_eoc_cco_get_ports_req_receive, .ok = false,
+ .first_mac_index_nb = first_mac_index_number),
+ SCENARIO_EVENT (cp_msg_vs_eoc_cco_get_ports_cnf_send, .peer = peer,
+ .result = CP_MSG_VS_EOC_CCO_GET_PORTS_REQ_RESULT_FAILURE,
+ .numStas = numStas,
+ .stas_macs = stas_macs,
+ .stas_port_ed = stas_ports_ed,
+ .stas_port_service = stas_ports_service,
+ .first_mac_index_nb = first_mac_index_number),
+ SCENARIO_END
+ };
+ scenario_run (test, entries, &globals);
+
+ if(test_fail_nb_temp == test->fail_nb)
+ {
+ DBG_PRINT ("\"vs_eoc__cco__vs_eoc_cco_get_ports_req, data from "
+ "stations not correct\" successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"vs_eoc__cco__vs_eoc_cco_get_ports_req, "
+ "data from stations not correct\" test failed");
+ test_fail_nb_temp = test->fail_nb;
+ }
+
+ test_sta_action_uninit (&ctx);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_SERVICES_REQ")
+ {
+ u8 i, j;
+ cp_t ctx;
+ cp_eoc_cco_services_init (&ctx);
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ sar_t sar;
+ uint cl;
+ ctx.cl = (cl_t *) &cl;
+
+ u8 command;
+ u8 services_number;
+ u8 service_indexes[MAX_NUMBER_OF_SERVICES];
+ u8 classifier_rules[MAX_NUMBER_OF_SERVICES];
+ u16 classifier_values[MAX_NUMBER_OF_SERVICES];
+ u8 acses[MAX_NUMBER_OF_SERVICES];
+ u8 parameters_numbers[MAX_NUMBER_OF_SERVICES];
+ u16 parameters_lists[MAX_NUMBER_OF_SERVICES][SERVICE_PARAMETERS_NB];
+
+ u8 command2;
+ u8 services_number2;
+ u8 service_indexes2[MAX_NUMBER_OF_SERVICES];
+ u8 classifier_rules2[MAX_NUMBER_OF_SERVICES];
+ u16 classifier_values2[MAX_NUMBER_OF_SERVICES];
+ u8 acses2[MAX_NUMBER_OF_SERVICES];
+ u8 parameters_numbers2[MAX_NUMBER_OF_SERVICES];
+ u16 parameters_lists2[MAX_NUMBER_OF_SERVICES][SERVICE_PARAMETERS_NB];
+
+ u8 command3;
+ u8 services_number3;
+ u8 service_indexes3[MAX_NUMBER_OF_SERVICES];
+ u8 classifier_rules3[MAX_NUMBER_OF_SERVICES];
+ u16 classifier_values3[MAX_NUMBER_OF_SERVICES];
+ u8 acses3[MAX_NUMBER_OF_SERVICES];
+ u8 parameters_numbers3[MAX_NUMBER_OF_SERVICES];
+ u16 parameters_lists3[MAX_NUMBER_OF_SERVICES][SERVICE_PARAMETERS_NB];
+
+ u8 buffer[1024];
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ bitstream_t bitstream;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+ cp_eoc_cco_services_init (&ctx);
+
+ mme->mmtype = VS_EOC_CCO_SET_SERVICES_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ /* set services */
+ command = 0x00;
+ services_number = 3;
+ service_indexes[0] = 5;
+ service_indexes[1] = 67;
+ service_indexes[2] = 12;
+ classifier_rules[0] = 0;
+ classifier_rules[1] = 2;
+ classifier_rules[2] = 3;
+ classifier_values[0] = 45;
+ classifier_values[1] = 111;
+ classifier_values[2] = 89;
+ acses[0] = 0;
+ acses[1] = 1;
+ acses[2] = 1;
+ parameters_numbers[0] = 7;
+ parameters_numbers[1] = 7;
+ parameters_numbers[2] = 7;
+ parameters_lists[0][0] = 256;
+ parameters_lists[0][1] = 128;
+ parameters_lists[0][2] = 64;
+ parameters_lists[0][3] = 32;
+ parameters_lists[0][4] = 100;
+ parameters_lists[0][5] = 10;
+ parameters_lists[0][6] = 32;
+ parameters_lists[1][0] = 512;
+ parameters_lists[1][1] = 256;
+ parameters_lists[1][2] = 64;
+ parameters_lists[1][3] = 16;
+ parameters_lists[1][4] = 16;
+ parameters_lists[1][5] = 16;
+ parameters_lists[1][6] = 16;
+ parameters_lists[2][0] = 256;
+ parameters_lists[2][1] = 32;
+ parameters_lists[2][2] = 64;
+ parameters_lists[2][3] = 32;
+ parameters_lists[2][4] = 256;
+ parameters_lists[2][5] = 16;
+ parameters_lists[2][6] = 32;
+
+ bitstream_access (&bitstream, &command, 8);
+ bitstream_access (&bitstream, &services_number, 8);
+ for(i = 0; i < services_number; i++)
+ {
+ bitstream_access (&bitstream, &service_indexes[i], 8);
+ bitstream_access (&bitstream, &classifier_rules[i], 8);
+ bitstream_access (&bitstream, &classifier_values[i], 16);
+ bitstream_access (&bitstream, &acses[i], 8);
+ bitstream_access (&bitstream, &parameters_numbers[i], 8);
+ for(j = 0; j < parameters_numbers[i]; j++)
+ bitstream_access (&bitstream, &parameters_lists[i][j], 16);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (&ctx, mme);
+
+ test_fail_unless (ctx.schedule.services.service_nb == services_number);
+
+ for(i = 0; i < services_number; i++)
+ {
+ cp_eoc_cco_bw_service_t *srv;
+ srv = cp_eoc_cco_bw_service_find (&ctx, service_indexes[i]);
+ test_fail_if (!srv);
+
+ test_fail_if (srv->latency != parameters_lists[i][0]);
+ test_fail_if (srv->jitter != parameters_lists[i][1]);
+ test_fail_if (srv->dload_pir != parameters_lists[i][2]);
+ test_fail_if (srv->uload_pir != parameters_lists[i][3]);
+ test_fail_if (srv->dload_cir != parameters_lists[i][4]);
+ test_fail_if (srv->uload_cir != parameters_lists[i][5]);
+ test_fail_if (srv->qos_prio != parameters_lists[i][6]);
+
+ }
+
+ /* remove services */
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ command2 = 0x01;
+ services_number2 = 1;
+ service_indexes2[0] = 5;
+ classifier_rules2[0] = 0;
+ classifier_values2[0] = 45;
+ acses2[0] = 0;
+ parameters_numbers2[0] = 7;
+ parameters_lists2[0][0] = 256;
+ parameters_lists2[0][1] = 32;
+ parameters_lists2[0][2] = 64;
+ parameters_lists2[0][3] = 16;
+ parameters_lists2[0][4] = 128;
+ parameters_lists2[0][5] = 32;
+ parameters_lists2[0][6] = 512;
+
+
+ bitstream_access (&bitstream, &command2, 8);
+ bitstream_access (&bitstream, &services_number2, 8);
+ for(i = 0; i < services_number2; i++)
+ {
+ bitstream_access (&bitstream, &service_indexes2[i], 8);
+ bitstream_access (&bitstream, &classifier_rules2[i], 8);
+ bitstream_access (&bitstream, &classifier_values2[i], 16);
+ bitstream_access (&bitstream, &acses2[i], 8);
+ bitstream_access (&bitstream, &parameters_numbers2[i], 8);
+ for(j = 0; j < parameters_numbers2[i]; j++)
+ bitstream_access (&bitstream, &parameters_lists2[i][j], 16);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (&ctx, mme);
+
+ test_fail_unless (ctx.schedule.services.service_nb ==
+ services_number - services_number2);
+
+ for(i = 0; i < services_number2; i++)
+ {
+ cp_eoc_cco_bw_service_t *srv;
+ srv = cp_eoc_cco_bw_service_find (&ctx, service_indexes2[i]);
+ test_fail_if (srv);
+ }
+
+ /* remove all services */
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ command3 = 0x02;
+ services_number3 = 1;
+ service_indexes3[0] = 5;
+ classifier_rules3[0] = 0;
+ classifier_values3[0] = 45;
+ acses3[0] = 0;
+ parameters_numbers3[0] = 7;
+ parameters_lists3[0][0] = 256;
+ parameters_lists3[0][1] = 32;
+ parameters_lists3[0][2] = 512;
+ parameters_lists3[0][3] = 32;
+ parameters_lists3[0][4] = 128;
+ parameters_lists3[0][5] = 16;
+ parameters_lists3[0][6] = 32;
+
+ bitstream_access (&bitstream, &command3, 8);
+ bitstream_access (&bitstream, &services_number3, 8);
+ for(i = 0; i < services_number3; i++)
+ {
+ bitstream_access (&bitstream, &service_indexes3[i], 8);
+ bitstream_access (&bitstream, &classifier_rules3[i], 8);
+ bitstream_access (&bitstream, &classifier_values3[i], 16);
+ bitstream_access (&bitstream, &acses3[i], 8);
+ bitstream_access (&bitstream, &parameters_numbers3[i], 8);
+ for(j = 0; j < parameters_numbers3[i]; j++)
+ bitstream_access (&bitstream, &parameters_lists3[i][j], 16);
+ }
+
+ bitstream_finalise (&bitstream);
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (&ctx, mme);
+ test_fail_unless (ctx.schedule.services.service_nb == 0);
+ cp_eoc_cco_services_uninit (&ctx);
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing VS_EOC_GET_SERVICES_REQ")
+ {
+
+ uint test_fail_nb_temp;
+ test_sta_action_t ctx;
+ cp_t *cp = &ctx.cp;
+
+ u8 i = 0;
+ u8 j = 0;
+ const cp_nid_t our_nid = 0x111111111111ull;
+ cp_sta_mgr_add_avln (cp, 1, our_nid);
+
+ /* init globals */
+ scenario_globals_t globals = {
+ .cp = &ctx.cp,
+ };
+
+ cp_mme_peer_t peer = CP_MME_PEER (0x112233445577ull, 5);
+ cp_mme_tx_t mme_to_send;
+ globals.mme = &mme_to_send;
+
+ test_sta_action_init (&ctx);
+ cp_eoc_cco_services_init (cp);
+
+ sar_t sar;
+ sar.mac_store = globals.cp->mac_store;
+ globals.cp->sar = &sar;
+
+ test_fail_nb_temp = test->fail_nb;
+
+ u8 first_service_index_number;
+ u8 services_number;
+ u8 service_indexes[MAX_NUMBER_OF_SERVICES];
+ u8 classifier_rules[MAX_NUMBER_OF_SERVICES];
+ u16 classifier_values[MAX_NUMBER_OF_SERVICES];
+ u8 acses[MAX_NUMBER_OF_SERVICES];
+ u8 parameters_numbers[MAX_NUMBER_OF_SERVICES];
+ u16 parameters_lists[MAX_NUMBER_OF_SERVICES][SERVICE_PARAMETERS_NB];
+
+ first_service_index_number = 0;
+ services_number = 3;
+ service_indexes[0] = 0;
+ service_indexes[1] = 1;
+ service_indexes[2] = 2;
+ classifier_rules[0] = 0;
+ classifier_rules[1] = 2;
+ classifier_rules[2] = 3;
+ classifier_values[0] = 45;
+ classifier_values[1] = 111;
+ classifier_values[2] = 89;
+ acses[0] = 0;
+ acses[1] = 1;
+ acses[2] = 1;
+ parameters_numbers[0] = 7;
+ parameters_numbers[1] = 7;
+ parameters_numbers[2] = 7;
+ parameters_lists[0][0] = 32;
+ parameters_lists[0][1] = 16;
+ parameters_lists[0][2] = 64;
+ parameters_lists[0][3] = 32;
+ parameters_lists[0][4] = 100;
+ parameters_lists[0][5] = 10;
+ parameters_lists[0][6] = 10;
+ parameters_lists[1][0] = 512;
+ parameters_lists[1][1] = 256;
+ parameters_lists[1][2] = 64;
+ parameters_lists[1][3] = 64;
+ parameters_lists[1][4] = 64;
+ parameters_lists[1][5] = 64;
+ parameters_lists[1][6] = 64;
+ parameters_lists[2][0] = 256;
+ parameters_lists[2][1] = 32;
+ parameters_lists[2][2] = 32;
+ parameters_lists[2][3] = 32;
+ parameters_lists[2][4] = 32;
+ parameters_lists[2][5] = 32;
+ parameters_lists[2][6] = 32;
+
+ for(i = 0; i < services_number; i++)
+ {
+ u16 parameters_list_tmp[SERVICE_PARAMETERS_NB];
+ cp_eoc_cco_bw_service_t *srv = NULL;
+
+ srv = cp_eoc_cco_bw_service_alloc (cp);
+ srv->service_index = service_indexes[i];
+ srv->classsif_rule = classifier_rules[i];
+ srv->classif_value = classifier_values[i];
+ srv->acs = acses[i];
+
+ for(j = 0; j < parameters_numbers[i]; j++)
+ parameters_list_tmp[j] = parameters_lists[i][j];
+
+ for(j = parameters_numbers[i]; j < SERVICE_PARAMETERS_NB; j++)
+ parameters_list_tmp[j] = 0x00;
+
+ srv->latency = parameters_list_tmp[0];
+ srv->jitter = parameters_list_tmp[1];
+ srv->dload_pir = parameters_list_tmp[2];
+ srv->uload_pir = parameters_list_tmp[3];
+ srv->dload_cir = parameters_list_tmp[4];
+ srv->uload_cir = parameters_list_tmp[5];
+ srv->qos_prio = parameters_list_tmp[6];
+
+
+ cp_eoc_cco_bw_service_add (cp, srv);
+ }
+
+
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs_eoc__cco__vs_eoc_cco_get_services_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_eoc_cco_get_services_req_receive, .ok = true,
+ .first_service_index_nb = first_service_index_number),
+ SCENARIO_EVENT (cp_msg_vs_eoc_cco_get_services_cnf_send, .peer = peer,
+ .result = CP_MSG_VS_EOC_CCO_GET_SERVICES_REQ_RESULT_SUCCESS,
+ .services_number = services_number,
+ .service_indexes = service_indexes,
+ .classifier_rules = classifier_rules,
+ .classifier_values = classifier_values,
+ .acses = acses,
+ .parameters_numbers = parameters_numbers,
+ .parameters_lists = parameters_lists,
+ .first_service_index_nb = first_service_index_number),
+ SCENARIO_END
+ };
+ scenario_run (test, entries, &globals);
+
+ if(test_fail_nb_temp == test->fail_nb)
+ {
+ DBG_PRINT ("\"vs_eoc__cco__vs_eoc_cco_get_services_req\" "
+ "successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"vs_eoc__cco__vs_eoc_cco_get_services_req\" "
+ "test failed");
+ test_fail_nb_temp = test->fail_nb;
+ }
+
+ cp_eoc_cco_services_uninit (cp);
+ test_sta_action_uninit (&ctx);
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing VS_EOC_GET_INFO_REQ")
+ {
+
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+ sar_t sar;
+ cl_t cl;
+ pbproc_t pbproc;
+ memset (&pbproc.stats, 0, sizeof (pbproc.stats));
+
+ u8 buffer[1024];
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.cl = &cl;
+ ctx.mac_config = &mac_config;
+ ctx.pbproc = &pbproc;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+ memset (ctx.cl, 0, sizeof (cl_t));
+ memset (ctx.sar, 0, sizeof (sar_t));
+
+ bitstream_t bitstream;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ mme->mmtype = VS_EOC_GET_INFO_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ u8 control = 1;
+ u8 internal_eoc_index = 1;
+
+ /* set our avln */
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ cp_msg_vs_eoc_get_info_req_result_t status =
+ CP_MSG_VS_EOC_GET_INFO_REQ_RESULT_SUCCESS;
+ uint tei = ctx.sta_mgr.sta_own_data.tei = 1;
+ uint attenuation = 0; /* N.A. */
+ uint snr = 0;
+ uint phy_uplink_speed =
+ cp_sta_action_get_average_ble (&ctx, tei, true, false);
+ uint phy_downlink_speed =
+ cp_sta_action_get_average_ble (&ctx, tei, false, false);
+ uint output_power = 0; /* N.A. */
+ uint tx_success_counter = ctx.pbproc->stats.tx_data -
+ ctx.pbproc->stats.tx_data_cancel -
+ ctx.pbproc->stats.tx_data_wack_noack;
+ uint tx_crc_error_counter = 0; /* N.A. */
+ uint tx_other_error_counter = ctx.pbproc->stats.tx_data_cancel +
+ ctx.pbproc->stats.tx_data_wack_noack;
+ uint rx_success_counter = ctx.pbproc->stats.rx_data -
+ ctx.pbproc->stats.rx_data_error;
+ uint rx_crc_error_counter =ctx.pbproc->stats.rx_crc_error;
+ uint rx_other_error_counter = ctx.pbproc->stats.rx_data_error;
+
+ uint status_read = 0;
+ uint tei_read = 0;
+ uint attenuation_read = 0;
+ uint snr_read = 0;
+ uint phy_uplink_speed_read = 0;
+ uint phy_downlink_speed_read = 0;
+ uint output_power_read = 0;
+ uint tx_success_counter_read = 0;
+ uint tx_crc_error_counter_read = 0;
+ uint tx_other_error_counter_read = 0;
+ uint rx_success_counter_read = 0;
+ uint rx_crc_error_counter_read = 0;
+ uint rx_other_error_counter_read = 0;
+
+ /* Write the statistics values down into the Cesar structures */
+
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &control, 8);
+ bitstream_access (&bitstream, &internal_eoc_index, 8);
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_info_req(&ctx, mme);
+
+ FILE *fp;
+ if((fp = fopen("get_info.txt", "r")) != NULL)
+ {
+
+ fscanf(fp,"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", &status_read,
+ &tei_read, &attenuation_read, &snr_read,
+ &phy_uplink_speed_read, &phy_downlink_speed_read,
+ &output_power_read, &tx_success_counter_read,
+ &tx_crc_error_counter_read, &tx_other_error_counter_read,
+ &rx_success_counter_read, &rx_crc_error_counter_read,
+ &rx_other_error_counter_read);
+ }
+ else
+ DBG_PRINT ("test, Receiving and processing VS_EOC_GET_INFO_REQ, "
+ "Error opening get_info.txt");
+
+ fclose(fp);
+ remove("get_info.txt");
+
+ test_fail_unless(status_read == status);
+ test_fail_unless(tei_read == tei);
+ test_fail_unless(attenuation_read == attenuation);
+ test_fail_unless(snr_read == snr);
+ test_fail_unless(phy_uplink_speed_read == phy_uplink_speed);
+ test_fail_unless(phy_downlink_speed_read == phy_downlink_speed);
+ test_fail_unless(output_power_read == output_power);
+ test_fail_unless(tx_success_counter_read == tx_success_counter);
+ test_fail_unless(tx_crc_error_counter_read == tx_crc_error_counter);
+ test_fail_unless(tx_other_error_counter_read == tx_other_error_counter);
+ test_fail_unless(rx_success_counter_read == rx_success_counter);
+ test_fail_unless(rx_crc_error_counter_read == rx_crc_error_counter);
+ test_fail_unless(rx_other_error_counter_read == rx_other_error_counter);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_DIAGNOSTIC_INFO_REQ")
+ {
+
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ sar_t sar;
+ cl_t cl;
+
+ u8 buffer[1024];
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.cl = &cl;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+ memset (ctx.cl, 0, sizeof (cl_t));
+ memset (ctx.sar, 0, sizeof (sar_t));
+
+ bitstream_t bitstream;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ mme->mmtype = VS_EOC_DIAGNOSTIC_INFO_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ u8 control = 1;
+ u8 internal_eoc_index = 1;
+
+ const cp_nid_t our_nid = 0x111111111111ull;
+ cp_net_t *net;
+ net = cp_sta_mgr_add_avln (&ctx, 1, our_nid);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ cp_msg_vs_eoc_diagnostic_info_req_result_t status =
+ CP_MSG_VS_EOC_DIAGNOSTIC_INFO_REQ_RESULT_SUCCESS;
+ uint assoc_stat = 2; /* N.A */
+ unsigned long long int nid = ctx.sta_mgr.our_avln->nid;
+ uint num_slots = 1;
+ unsigned long long int he_mac_address = ctx.sta_mgr.sta_own_data.mac_addr;
+ uint est_avg_phy_rate = 0;
+ uint num_good_assoc_auth = ctx.sta_mgr.sta_own_data.public.num_good_assoc_auth;
+ uint num_bad_could_not_assoc =
+ ctx.sta_mgr.sta_own_data.public.num_bad_could_not_assoc;
+ uint num_bad_assoc_failure =
+ ctx.sta_mgr.sta_own_data.public.num_bad_assoc_failure;
+ uint num_bad_could_not_auth =
+ ctx.sta_mgr.sta_own_data.public.num_bad_could_not_auth;
+ uint num_leave = ctx.sta_mgr.sta_own_data.public.num_leave;
+
+ uint status_read = 0;
+ uint assoc_stat_read = 30;
+ unsigned long long int nid_read = 0;
+ uint num_slots_read = 30;
+ unsigned long long int he_mac_address_read = 0;
+ uint est_avg_phy_rate_read = 0;
+ uint num_good_assoc_auth_read = 0;
+ uint num_bad_could_not_assoc_read = 0;
+ uint num_bad_assoc_failure_read = 0;
+ uint num_bad_could_not_auth_read = 0;
+ uint num_leave_read = 0;
+
+ /* Write the statistics values down into the Cesar structures. */
+
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &control, 8);
+ bitstream_access (&bitstream, &internal_eoc_index, 8);
+
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req(&ctx, mme);
+
+ FILE *fp;
+ if((fp = fopen("get_info.txt", "r")) != NULL)
+ {
+ fscanf(fp,"%u,%u,%llu,%u,%llu,%u,%u,%u,%u,%u,%u", &status_read,
+ &assoc_stat_read, &nid_read, &num_slots_read,
+ &he_mac_address_read, &est_avg_phy_rate_read,
+ &num_good_assoc_auth_read, &num_bad_could_not_assoc_read,
+ &num_bad_assoc_failure_read, &num_bad_could_not_auth_read,
+ &num_leave_read);
+ }
+ else
+ DBG_PRINT ("test, Receiving and processing VS_EOC_GET_INFO_REQ, "
+ "Error opening get_info.txt");
+
+ fclose(fp);
+ remove("get_info.txt");
+
+ test_fail_unless(status_read == status);
+ test_fail_unless(assoc_stat_read == assoc_stat);
+ test_fail_unless(nid_read == nid);
+ test_fail_unless(num_slots_read == num_slots);
+ test_fail_unless(he_mac_address_read == he_mac_address);
+ test_fail_unless(est_avg_phy_rate_read == est_avg_phy_rate);
+ test_fail_unless(num_good_assoc_auth_read == num_good_assoc_auth);
+ test_fail_unless(num_bad_could_not_assoc_read ==
+ num_bad_could_not_assoc);
+ test_fail_unless(num_bad_assoc_failure_read == num_bad_assoc_failure);
+ test_fail_unless(num_bad_could_not_auth_read == num_bad_could_not_auth);
+ test_fail_unless(num_leave_read == num_leave);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing "
+ "VS_EOC_GET_REAL_TIME_STATISTICS_REQ")
+ {
+
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ sar_t sar;
+ cl_t cl;
+ pbproc_t pbproc;
+
+ u8 buffer[1024];
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.cl = &cl;
+ ctx.mac_config = &mac_config;
+ ctx.pbproc = &pbproc;
+
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+ memset (ctx.cl, 0, sizeof (cl_t));
+ memset (ctx.sar, 0, sizeof (sar_t));
+ memset (ctx.pbproc, 0, sizeof (pbproc_t));
+
+ bitstream_t bitstream;
+
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ mme->mmtype = VS_EOC_GET_INFO_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ u8 clear = 0;
+
+ /* Dummy values for the statistics */
+ cp_msg_vs_eoc_get_real_time_statistics_req_result_t status =
+ CP_MSG_VS_EOC_GET_REAL_TIME_STATISTICS_REQ_RESULT_SUCCESS;
+
+ real_time_stats_t rt_stats;
+
+ rt_stats.nb_unicast_packets_rx = 100;
+ rt_stats.nb_unicast_packets_tx = 200;
+ rt_stats.total_nb_bytes_rx = 300;
+ rt_stats.total_nb_bytes_tx = 400;
+ rt_stats.nb_broadcast_packets_rx = 500;
+ rt_stats.nb_broadcast_packets_tx =600;
+ rt_stats.nb_multicast_packets_rx = 700;
+ rt_stats.nb_multicast_packets_tx = 900;
+ rt_stats.nb_packets_rx_crc = 10;
+ rt_stats.nb_packets_rx_short = 20;
+ rt_stats.nb_packets_tx_short = 30;
+ rt_stats.nb_packets_tx_dropped = 40;
+ rt_stats.nb_packets_rx_discarded = 50;
+ rt_stats.avg_pre_fec_bit_error_rate = 0;
+
+#define RT_STATS(a,b) b = rt_stats.a
+
+ RT_STATS (nb_unicast_packets_rx,
+ ctx.pbproc->stats.rx_data);
+ RT_STATS (nb_unicast_packets_tx,
+ ctx.pbproc->stats.tx_data_wack);
+ RT_STATS (total_nb_bytes_rx,
+ ctx.cl->stats.rx_data_bytes);
+ RT_STATS (total_nb_bytes_tx,
+ ctx.cl->stats.tx_data_bytes);
+ RT_STATS (nb_broadcast_packets_rx,
+ ctx.pbproc->stats.rx_data_woack);
+ RT_STATS (nb_broadcast_packets_tx,
+ ctx.pbproc->stats.tx_data_woack);
+ RT_STATS (nb_multicast_packets_rx,
+ ctx.cl->stats.rx_data_multicast);
+ RT_STATS (nb_multicast_packets_tx,
+ ctx.cl->stats.tx_data_multicast);
+ RT_STATS (nb_packets_rx_short,
+ ctx.pbproc->stats.rx_data_empty);
+ RT_STATS (nb_packets_tx_short,
+ ctx.pbproc->stats.tx_data_empty);
+ RT_STATS (nb_packets_tx_dropped,
+ ctx.pbproc->stats.tx_data_cancel);
+ RT_STATS (nb_packets_rx_discarded,
+ ctx.pbproc->stats.rx_data_error);
+ RT_STATS (nb_packets_rx_crc,
+ ctx.sar->stats.rx_pb_crc_error_count);
+
+ uint status_read = 0;
+
+ real_time_stats_t rt_stats_read;
+
+ /* Write the statistics values down into the Cesar structures */
+
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &clear, 8);
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_sta_action_vs__vs_eoc_get_real_time_statistics_req (&ctx, mme);
+
+ FILE *fp;
+ if((fp = fopen("get_info.txt", "r")) != NULL)
+ {
+
+ fscanf(fp,"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
+ &status_read, &rt_stats_read.nb_unicast_packets_rx,
+ &rt_stats_read.nb_unicast_packets_tx,
+ & rt_stats_read.total_nb_bytes_rx,
+ &rt_stats_read.total_nb_bytes_tx,
+ &rt_stats_read.nb_broadcast_packets_rx,
+ &rt_stats_read.nb_broadcast_packets_tx,
+ &rt_stats_read.nb_multicast_packets_rx,
+ &rt_stats_read.nb_multicast_packets_tx,
+ &rt_stats_read.nb_packets_rx_crc,
+ &rt_stats_read.nb_packets_rx_short,
+ &rt_stats_read.nb_packets_tx_short,
+ &rt_stats_read.nb_packets_tx_dropped,
+ &rt_stats_read.nb_packets_rx_discarded,
+ &rt_stats_read.avg_pre_fec_bit_error_rate);
+ }
+ else
+ {
+ DBG_PRINT ("test, Receiving and processing \
+ VS_EOC_GET_REAL_TIME_STATISTICS_REQ, \
+ Error opening get_info.txt");
+ }
+
+ fclose(fp);
+ remove("get_info.txt");
+
+ test_fail_unless(status_read == status);
+ test_fail_unless(rt_stats_read.nb_unicast_packets_rx ==
+ rt_stats.nb_unicast_packets_rx);
+ test_fail_unless(rt_stats_read.nb_unicast_packets_tx ==
+ rt_stats.nb_unicast_packets_tx);
+ test_fail_unless(rt_stats_read.total_nb_bytes_rx ==
+ rt_stats.total_nb_bytes_rx);
+ test_fail_unless(rt_stats_read.total_nb_bytes_tx ==
+ rt_stats.total_nb_bytes_tx);
+ test_fail_unless(rt_stats_read.nb_broadcast_packets_rx ==
+ rt_stats.nb_broadcast_packets_rx);
+ test_fail_unless(rt_stats_read.nb_broadcast_packets_tx ==
+ rt_stats.nb_broadcast_packets_tx);
+ test_fail_unless(rt_stats_read.nb_multicast_packets_rx ==
+ rt_stats.nb_multicast_packets_rx);
+ test_fail_unless(rt_stats_read.nb_multicast_packets_tx ==
+ rt_stats.nb_multicast_packets_tx);
+ test_fail_unless(rt_stats_read.nb_packets_rx_crc ==
+ rt_stats.nb_packets_rx_crc);
+ test_fail_unless(rt_stats_read.nb_packets_rx_short ==
+ rt_stats.nb_packets_rx_short);
+ test_fail_unless(rt_stats_read.nb_packets_tx_short ==
+ rt_stats.nb_packets_tx_short);
+ test_fail_unless(rt_stats_read.nb_packets_tx_dropped ==
+ rt_stats.nb_packets_tx_dropped);
+ test_fail_unless(rt_stats_read.nb_packets_rx_discarded ==
+ rt_stats.nb_packets_rx_discarded);
+ test_fail_unless(rt_stats_read.avg_pre_fec_bit_error_rate ==
+ rt_stats.avg_pre_fec_bit_error_rate);
+
+ DBG_PRINT ("test, Receiving and processing "
+ "VS_EOC_GET_REAL_TIME_STATISTICS PASSED");
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing CM_NW_STATS_REQ new")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cl_t cl;
+ sar_t sar;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_net_t *net;
+ cp_sta_t *cp_sta_1;
+ cp_sta_t *cp_sta_2;
+ cp_sta_t *cp_sta_3;
+ bitstream_t bitstream;
+ uint numStas;
+ cp_tei_t stas_teis[3];
+ mac_t stas_macs[3];
+ u8 buffer[1024];
+
+ ctx.cl = &cl;
+ ctx.sar = &sar;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ sar.mac_store = ctx.mac_store;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ cp_msg_init (&ctx);
+ cp_cl_interf_init (&ctx);
+
+ numStas = 3;
+ stas_macs[0] = 0x111111111111ull;
+ stas_macs[1] = 0x222222222222ull;
+ stas_macs[2] = 0x333333333333ull;
+ stas_teis[0] = 20;
+ stas_teis[1] = 21;
+ stas_teis[2] = 22;
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_1 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[0], stas_macs[0]);
+ dbg_assert (cp_sta_1);
+ slab_release (cp_sta_1);
+ cp_sta_2 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[1], stas_macs[1]);
+ dbg_assert (cp_sta_2);
+ slab_release (cp_sta_2);
+ cp_sta_3 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[2], stas_macs[2]);
+ dbg_assert (cp_sta_3);
+ slab_release (cp_sta_3);
+
+ cp_sta_own_data_set_tei (&ctx, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ cp_sta_set_authenticated (&ctx, cp_sta_1, true);
+ cp_sta_set_authenticated (&ctx, cp_sta_2, false);
+ cp_sta_set_authenticated (&ctx, cp_sta_3, true);
+
+ /* First case is to set authorizations for stations
+ * which are not registered until now. */
+ mme->mmtype = CM_NW_STATS_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &numStas, 8);
+
+ bitstream_finalise (&bitstream);
+
+ cp_sta_action_process_cm_nw_stats_req (&ctx, mme);
+ /* Remove the stations from network. */
+ cp_sta_mgr_sta_remove (&ctx, cp_sta_1);
+ cp_sta_mgr_sta_remove (&ctx, cp_sta_2);
+ cp_sta_mgr_sta_remove (&ctx, cp_sta_3);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_OUT_LEV")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cl_t cl;
+ sar_t sar;
+ cp_mme_peer_t my_mme;
+ cp_mme_peer_t *mme = &my_mme;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ ctx.cl = &cl;
+ ctx.sar = &sar;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ sar.mac_store = ctx.mac_store;
+ cp_eoc_sta_mgr_init (&ctx);
+
+ mme->mac = 2;
+ mme->tei = 5;
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->tei, mme->mac);
+ dbg_assert (sta);
+ slab_release (sta);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sta->multi_sta.output_level = 30;
+
+ cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (&ctx, mme);
+ cp_sta_mgr_sta_remove (&ctx, sta);
+ }
+ test_end;
+}
+
+void
+test_case_sta_assoc_and_auth_procedure_action (test_t test)
+{
+ cp_t ctx;
+ cp_net_t *net;
+ cp_tei_t tei = 200;
+ sar_t sar;
+ uint cl;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_sta_t *sta;
+ u8 buffer[1024];
+ uint req_type = CP_MSG_CC_ASSOC_REQ_TYPE_NEW;
+ u64 nid = 1;
+ uint cco_cap = 2;
+ uint pco_cap = true;
+
+ memset (&ctx, 0, sizeof (cp_t));
+ cp_msg_init (&ctx);
+ cp_trace_init (&ctx);
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ ctx.cco_action.wl_accept_all = 0;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_beacon_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ memset (&ctx.beacon, 0, sizeof (cp_beacon_t));
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ mme->peer.mac = 2;
+ mme->peer.tei = 0;
+ mme->mmtype = CC_ASSOC_REQ;
+
+ test_case_begin (test, "Receiving CC_ASSOC.REQ and CM_GET_KEY.REQ\n");
+
+ test_begin (test, "Receiving a CC_ASSOC.REQ and transfering to multi_sta,"
+ " sta not in the wl\n")
+ {
+ bitstream_t bitstream;
+
+ /* Write the request. */
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_unassociated);
+
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_unassociated)
+ DBG_PRINT ("success: station state is unassociated "
+ "(sta not in the wl)");
+ slab_release (sta);
+ }
+ test_end;
+
+ test_begin (test, "Receiving a CC_ASSOC.REQ and transfering to multi_sta, "
+ "mac address registered but no tei assigned")
+ {
+ bitstream_t bitstream;
+
+ /* Write the request. */
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_unassociated);
+
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_unassociated)
+ {
+ DBG_PRINT ("success: station state is unassociated "
+ "(mac address registered but no tei assigned)");
+ }
+ slab_release (sta);
+ }
+ test_end;
+
+ cp_sta_mgr_sta_remove(&ctx, sta);
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mme->peer.mac);
+ sta->multi_sta.allowed = false;
+ slab_release (sta);
+
+ test_begin (test, "Receiving a CC_ASSOC.REQ and transfering to multi_sta, "
+ "sta in the wl, not allowed")
+ {
+
+ bitstream_t bitstream;
+
+ /* Write the request. */
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+ sta = cp_sta_mgr_sta_get_from_mac (&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_unassociated);
+
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_unassociated)
+ {
+ DBG_PRINT ("success: station state is unassociated "
+ "(sta in the wl, not allowed )");
+ }
+ slab_release (sta);
+ slab_release (sta);
+ }
+ test_end;
+
+ cp_sta_mgr_sta_remove(&ctx, sta);
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mme->peer.mac);
+ sta->multi_sta.allowed = true;
+ slab_release (sta);
+
+ test_begin (test, "Receiving a CC_ASSOC.REQ and transfering to multi_sta, "
+ "sta in the wl")
+ {
+ bitstream_t bitstream;
+
+ /* Write the request. */
+ bitstream_init (&bitstream, buffer + 19, 10, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &req_type, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &cco_cap, 8);
+ bitstream_access (&bitstream, &pco_cap, 8);
+ bitstream_finalise (&bitstream);
+
+ /* Initialise the MME Rx object. */
+ mme->p_mme = buffer;
+ mme->length = 60;
+ bitstream_init (&mme->bitstream, buffer + 19, 60, BITSTREAM_READ);
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_associated);
+
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_associated)
+ {
+ DBG_PRINT ("success: station state is associated (sta in the wl)");
+ }
+ slab_release (sta);
+ slab_release (sta);
+ }
+ test_end;
+
+ test_begin (test, "Receiving a CM_GET_KEY.REQ and transfering to multi_sta")
+ {
+ bitstream_t bitstream;
+ u64 data;
+ u8 buffer[1024];
+ mme->mmtype = CM_GET_KEY_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+ /* ODA. */
+ data = 0x2;
+ bitstream_access (&bitstream, &data, 48);
+ /* OSA. */
+ data = 0x1;
+ bitstream_access (&bitstream, &data, 48);
+ /* Mtype */
+ data = HPAV_MTYPE_MME;
+ bitstream_access (&bitstream, &data, 16);
+ /* MMV. */
+ data = HPAV_MMV1;
+ bitstream_access (&bitstream, &data, 8);
+ /* MMtype. */
+ data = CM_GET_KEY_REQ;
+ bitstream_access (&bitstream, &data, 16);
+ /* FMI */
+ data = 0;
+ bitstream_access (&bitstream, &data, 16);
+ /* Request type. */
+ data = 0;
+ bitstream_access (&bitstream, &data, 8);
+ /* Request key type. */
+ data = CP_MSG_KEY_NEK;
+ bitstream_access (&bitstream, &data, 8);
+ /* NID. */
+ data = cp_net_get_nid (&ctx, net);
+ bitstream_access (&bitstream, &data, 56);
+ /* Nonce. */
+ data = 0xc;
+ bitstream_access (&bitstream, &data, 32);
+ /* PID. */
+ data = 0;
+ bitstream_access (&bitstream, &data, 32);
+ /* Key. */
+ data = 0xA;
+ bitstream_access (&bitstream, &data, 8);
+ bitstream_finalise (&bitstream);
+
+ mme->length = 37;
+ mme->p_mme = buffer;
+ mme->peer.tei = cp_sta_get_tei(sta);
+ mme->peer.mac = 2;
+ mme->bitstream.data = bitstream.data;
+ mme->bitstream.data_bits = bitstream.data_bits;
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ /* Receiving CP_MSG_KEY_TEK: */
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+ /* ODA. */
+ data = 0x2;
+ bitstream_access (&bitstream, &data, 48);
+ /* OSA. */
+ data = 0x1;
+ bitstream_access (&bitstream, &data, 48);
+ /* Mtype */
+ data = HPAV_MTYPE_MME;
+ bitstream_access (&bitstream, &data, 16);
+ /* MMV. */
+ data = HPAV_MMV1;
+ bitstream_access (&bitstream, &data, 8);
+ /* MMtype. */
+ data = CM_GET_KEY_REQ;
+ bitstream_access (&bitstream, &data, 16);
+ /* FMI */
+ data = 0;
+ bitstream_access (&bitstream, &data, 16);
+ /* Request type. */
+ data = 0;
+ bitstream_access (&bitstream, &data, 8);
+ /* Request key type. */
+ data = CP_MSG_KEY_TEK;
+ bitstream_access (&bitstream, &data, 8);
+ /* NID. */
+ data = cp_net_get_nid (&ctx, net);
+ bitstream_access (&bitstream, &data, 56);
+ /* Nonce. */
+ data = 0xc;
+ bitstream_access (&bitstream, &data, 32);
+ /* PID. */
+ data = 0;
+ bitstream_access (&bitstream, &data, 32);
+ /* Key. */
+ data = 0xA;
+ bitstream_access (&bitstream, &data, 8);
+ bitstream_finalise (&bitstream);
+
+ mme->prun.pmn=1;
+
+ cp_eoc_cco_action_event_dispatch (&ctx, mme);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mme->peer.mac);
+
+ test_fail_unless(sta);
+
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_authenticated);
+
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_authenticated)
+ DBG_PRINT ("station state is authenticated");
+ slab_release (sta);
+ }
+ test_end;
+ cp_eoc_cco_action_test_release_mac_store (&ctx);
+ cp_sta_mgr_sta_remove(&ctx, sta);
+ cp_sta_mgr_uninit(&ctx);
+ mac_store_uninit (ctx.mac_store);
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&ctx.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&ctx);
+}
+
+void
+test_case_garbage_collector (test_t test)
+{
+ test_begin (test, "cp_cco_action_garbage")
+ {
+ cp_t ctx;
+ cp_net_t *net;
+ sar_t sar;
+ uint cl;
+ mac_config_t mac_config;
+ cp_sta_t *sta;
+ cp_tei_t tei;
+ mac_t mac;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ tei = 5;
+ mac = 0x004444444444ull;
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ cp_sta_own_data_set_tei (&ctx, 1);
+ cp_sta_own_data_set_cco_status (&ctx, true);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mac);
+ slab_release (sta);
+
+ /* The station should still exist as it has not expired. */
+ cp_cco_action_garbage(&ctx);
+
+ sta = cp_sta_mgr_sta_get_from_mac (&ctx, mac);
+ test_fail_unless(sta);
+
+ /* The station has expired so it should be removed. */
+ sta->expired_date_ms = 0;
+ slab_release(sta);
+
+ cp_cco_action_garbage(&ctx);
+
+ sta = cp_sta_mgr_sta_get_from_mac (&ctx, mac);
+ test_fail_unless(!sta);
+
+ mac_store_uninit (ctx.mac_store);
+ }
+ test_end
+
+ test_begin (test, "cp_cco_action_garbage")
+ {
+ cp_t ctx;
+ cp_tei_t tei;
+ u8 row;
+
+ tei = 5;
+ row = tei / CP_CCO_ACTION_TEI_FLAGS_ROW_SIZE_BITS;
+
+ memset (ctx.cco_action.tei_flags, 0,
+ sizeof (uint) * CP_CCO_ACTION_TEI_FLAGS_ROW);
+
+ cp_cco_action_tei_release (&ctx, tei);
+
+ test_fail_unless(ctx.cco_action.tei_flags[row] == 0);
+ }
+ test_end
+}
+
+void
+test_case_cco_action (test_t test)
+{
+ test_begin (test, "cp_eoc_cco_action_nek_provide")
+ {
+ cp_t ctx;
+ cp_net_t *net;
+ sar_t sar;
+ uint cl;
+ mac_config_t mac_config;
+ cp_sta_t *sta;
+ cp_tei_t tei;
+ mac_t mac;
+ cp_key_t nek_old;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+ cp_cco_action_init (&ctx);
+ tei = 5;
+ mac = 0x004444444444ull;
+ nek_old.key[0] = ctx.cco_action.new_nek.nek_enc.key[0];
+ nek_old.key[1] = ctx.cco_action.new_nek.nek_enc.key[1];
+ nek_old.key[2] = ctx.cco_action.new_nek.nek_enc.key[2];
+ nek_old.key[3] = ctx.cco_action.new_nek.nek_enc.key[3];
+
+
+ lib_rnd_init (&ctx.rnd, 0x4242);
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mac);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t),
+ NULL);
+
+ cp_eoc_cco_action_nek_provide(&ctx);
+
+ test_fail_unless(nek_old.key[0]
+ != ctx.cco_action.new_nek.nek_enc.key[0]);
+ test_fail_unless(nek_old.key[1]
+ != ctx.cco_action.new_nek.nek_enc.key[1]);
+ test_fail_unless(nek_old.key[2]
+ != ctx.cco_action.new_nek.nek_enc.key[2]);
+ test_fail_unless(nek_old.key[3]
+ != ctx.cco_action.new_nek.nek_enc.key[3]);
+
+ slab_release(sta);
+ cp_sta_mgr_sta_remove(&ctx, sta);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_cco_action__set_key_cnf")
+ {
+ cp_t ctx;
+ sar_t sar;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ bitstream_t bitstream;
+ u8 result, cco_cap;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ cp_tei_t tei;
+ u8 buffer[1024];
+
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ cp_msg_init (&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_eoc_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ ctx.cco_action.eks_sta_current_peer.tei = 5;
+ mme->prun.my_nonce = ctx.cco_action.eks_prun.my_nonce =
+ lib_rnd32 (&ctx.rnd);
+ mme->prun.your_nonce = ctx.cco_action.eks_prun.your_nonce =
+ lib_rnd32 (&ctx.rnd);
+
+ snid=0;
+ result = 0;
+ mme->prun.prn = ctx.cco_action.eks_prun.prn = 1;
+ nid = 0x11223344556677ull;
+ cco_cap = 1;
+ mme->prun.pid = ctx.cco_action.eks_prun.pid = 1;
+ ctx.cco_action.eks_prun.pmn = 1;
+ mme->prun.pmn = ctx.cco_action.eks_prun.pmn + 1;
+ mme->peks = CP_MME_PEKS_DAK;
+
+ mme->peer.tei = tei = ctx.sta_action.assoc.peer.tei = 5;
+ mme->peer.mac = ctx.sta_action.assoc.peer.mac = 0x2;
+
+ /* set our avln */
+ net = cp_sta_mgr_add_avln (&ctx, snid, nid);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ cp_sta_t *sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei,
+ mme->peer.mac);
+ mme->mmtype = CM_SET_KEY_CNF;
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer),
+ BITSTREAM_READ);
+ /* Build the MME. */
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &result, 8);
+ bitstream_access (&bitstream, &mme->prun.my_nonce, 32);
+ bitstream_access (&bitstream, &mme->prun.your_nonce, 32);
+ bitstream_access (&bitstream, &mme->prun.pid, 8);
+ bitstream_access (&bitstream, &mme->prun.prn, 16);
+ bitstream_access (&bitstream, &mme->prun.pmn, 8);
+ bitstream_access (&bitstream, &cco_cap, 8);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 14;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_CCO;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CM_SET_KEY_CNF;
+
+ cp_eoc_cco_action__set_key_cnf (&ctx, mme);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_CCO);
+ test_fail_unless(ctx.cco_action.eks_prun.pid == mme->prun.pid);
+ test_fail_unless(ctx.cco_action.eks_prun.pmn == (mme->prun.pmn - 1));
+ test_fail_unless(ctx.cco_action.eks_prun.prn == mme->prun.prn);
+ test_fail_unless(ctx.cco_action.eks_prun.my_nonce ==
+ mme->prun.my_nonce);
+ test_fail_unless(ctx.cco_action.eks_prun.your_nonce ==
+ mme->prun.your_nonce);
+ slab_release (sta);
+ cp_sta_mgr_sta_remove(&ctx, sta);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_cco_action__set_key_cnf")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ cp_tei_t tei1;
+ mac_t mac1;
+ sar_t sar;
+
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ sar.mac_store = ctx.mac_store;
+ cp_msg_init (&ctx);
+ ctx.cl = (cl_t *) &cl;
+ ctx.sar = &sar;
+ cp_cl_interf_init (&ctx);
+ cp_eoc_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ nid = 0x11223344556677ull;
+ mac1 = 3;
+ tei1 = 20;
+ snid=0;
+
+ ctx.cco_action.eks_sta_current_peer.tei = 5;
+ ctx.cco_action.eks_sta_current_peer.mac = 0x2;
+ ctx.cco_action.eks_eoc_retry = 0;
+ ctx.fsm.handling_urgent_event = false;
+ ctx.fsm.handled_active_state = 0;
+ ctx.fsm.head = 0;
+
+ /* set our avln */
+ net = cp_sta_mgr_add_avln (&ctx, snid, nid);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ cp_sta_t *sta1 = cp_sta_mgr_sta_add (
+ &ctx, net, ctx.cco_action.eks_sta_current_peer.tei,
+ ctx.cco_action.eks_sta_current_peer.mac);
+ cp_sta_t *sta2 = cp_sta_mgr_sta_add (&ctx, net, tei1, mac1);
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t),
+ NULL);
+
+ ctx.fsm.active_states[0] = CP_FSM_STATE_CCO;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_nek_timeout;
+
+ cp_eoc_cco_action_nek_change_timeout (&ctx);
+
+ test_fail_unless (ctx.fsm.active_states[0] == CP_FSM_STATE_CCO);
+ slab_release (sta1);
+ slab_release (sta2);
+ cp_sta_mgr_sta_remove(&ctx, sta1);
+ cp_sta_mgr_sta_remove(&ctx, sta2);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_cco_action__power_on_no_beacons")
+ {
+
+ cp_t ctx;
+
+ sar_t sar;
+ uint cl;
+ mac_config_t mac_config;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t),
+ NULL);
+
+ cp_eoc_cco_action__power_on_no_beacons (&ctx);
+
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless(cp_sta_own_data_get_tei(&ctx) == MAC_TEI_CCO_MIN);
+ test_fail_unless(cp_sta_own_data_get_authenticated_status(&ctx) == true);
+ test_fail_unless(cp_sta_mgr_get_our_avln(&ctx) != NULL);
+ test_fail_unless(own->nid_track == cp_sta_own_data_get_nid (&ctx));
+ test_fail_unless(cp_sta_own_data_get_cco_status(&ctx) == true);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_cco_action_poweron__idle__to_poweron")
+ {
+ cp_t ctx;
+ cp_trace_init (&ctx);
+ cp_cco_bw_init (&ctx);
+
+ slab_cache_init (&ctx.fsm.event_bare_cache, "event_bare",
+ sizeof (cp_fsm_event_t),
+ NULL);
+
+ cp_eoc_cco_action_poweron__idle__to_poweron (&ctx);
+
+
+ test_fail_unless(ctx.sta_action.assoc.peer.mac == MAC_BROADCAST);
+ test_fail_unless(ctx.sta_action.assoc.peer.eth_type == HPAV_MTYPE_MME);
+ test_fail_unless(ctx.sta_action.assoc.peer.vlan_tci == 0);
+ test_fail_unless(ctx.sta_action.assoc.peer.tei == MAC_TEI_UNASSOCIATED);
+ cp_cco_bw_uninit (&ctx);
+ cp_trace_uninit (&ctx);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_cco_action_vs__cco__cc_leave_ind")
+ {
+ cp_t ctx;
+ cp_mme_peer_t my_mme;
+ cp_mme_peer_t *mme = &my_mme;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ cp_eoc_sta_mgr_init (&ctx);
+
+ mme->mac = 2;
+ mme->tei = 5;
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->tei, mme->mac);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ cp_eoc_cco_action_vs__cco__cc_leave_ind (&ctx, mme);
+
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_disconnected);
+ slab_release (sta);
+ cp_sta_mgr_sta_remove(&ctx, sta);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_cco_action__cco__leave_remove_timeout")
+ {
+ cp_t ctx;
+ cp_net_t *net;
+ sar_t sar;
+ uint cl;
+ cp_sta_t *sta, *sta1;
+ mac_t mac, mac1;
+ cp_tei_t tei, tei1;
+ mac_config_t mac_config;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+
+ mac = 2;
+ tei = 5;
+ mac1 = 3;
+ tei1 = 6;
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mac);
+ sta1 = cp_sta_mgr_sta_add (&ctx, net, tei1, mac1);
+
+ sta->multi_sta.to_leave = true;
+ slab_release (sta);
+ test_fail_unless (net->num_stas == 2);
+ test_fail_unless (net->num_associated_stas == 2);
+ test_fail_unless (net->num_visible_stas == 2);
+
+ cp_eoc_cco_action__cco__leave_remove_timeout (&ctx);
+ sta = cp_sta_mgr_sta_get_from_mac(&ctx, mac);
+ test_fail_if (sta);
+ test_fail_unless (net->num_stas == 1);
+ test_fail_unless (net->num_associated_stas == 1);
+ test_fail_unless (net->num_visible_stas == 1);
+ sta1->multi_sta.to_leave = true;
+ slab_release (sta1);
+ cp_eoc_cco_action__cco__leave_remove_timeout (&ctx);
+ sta1 = cp_sta_mgr_sta_get_from_mac (&ctx, mac1);
+ test_fail_if (sta1);
+ }
+ test_end
+}
+
+void
+set_insert_set_remove_test_case(test_t t)
+{
+ cp_t ctx;
+ cp_trace_init (&ctx);
+ cp_net_t *net;
+ sar_t sar;
+ uint cl;
+ mac_config_t mac_config;
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_eoc_sta_mgr_init (&ctx);
+
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ test_begin (t, "set_insert")
+ {
+ int i;
+ cp_tei_t tei;
+ mac_t mac;
+ cp_sta_t *sta = NULL;
+ for (i = 0; i < 13; i++)
+ {
+ tei = i + 3;
+ mac = i + 0x0000010000D00000ull;
+ sta = cp_sta_mgr_sta_get_from_mac (&ctx, mac);
+ if(!sta)
+ {
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mac);
+ sta->multi_sta.allowed = true;
+ }
+ test_fail_unless (sta != NULL);
+ slab_release (sta);
+ }
+ }
+ test_end;
+
+ test_begin (t, "set_remove")
+ {
+ int i;
+ mac_t mac;
+ cp_sta_t *sta = NULL;
+ for (i = 0; i < 13; i++)
+ {
+ mac = i + 0x0000010000D00000ull;
+ sta = cp_sta_mgr_sta_get_from_mac (&ctx, mac);
+ test_fail_unless (sta != NULL);
+ cp_sta_mgr_sta_remove (&ctx, sta);
+ slab_release (sta);
+ }
+ test_fail_unless (net->num_stas == 0);
+ test_fail_unless (net->num_associated_stas == 0);
+ }
+ test_end;
+
+ cp_sta_mgr_uninit (&ctx);
+ mac_store_uninit (ctx.mac_store);
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&ctx.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&ctx);
+}
+
+void
+vs_get_tonemap_test_case (test_t t)
+{
+ /* init test context */
+ uint test_fail_nb_temp;
+ test_sta_action_t ctx;
+ cp_t *cp = &ctx.cp;
+ const cp_tei_t tei_1 = 10;
+ const mac_t mac_1 = 0x111111111111ull;
+ const cp_nid_t our_nid = 0x111111111111ull;
+
+ memset (cp, 0, sizeof (cp_t));
+
+ /* init globals */
+ scenario_globals_t globals = {
+ .cp = &ctx.cp,
+ };
+
+ cp_mme_peer_t peer = CP_MME_PEER (0x112233445577ull, 5);
+ cp_mme_tx_t mme_to_send;
+ globals.mme = &mme_to_send;
+
+ test_sta_action_init (&ctx);
+
+ sar_t sar;
+ memset (&sar, 0, sizeof (sar_t));
+ sar.mac_store = globals.cp->mac_store;
+ globals.cp->sar = &sar;
+
+ test_case_begin (t, "get tonemap");
+ test_fail_nb_temp = t->fail_nb;
+
+ test_begin (t, "get_tonemap_req_receive return false")
+ {
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs__started__vs_get_tonemap_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_req_receive, .ok = false,
+ .mac_addr = mac_1, .tmi = 0, .int_id = 0, .dir = 0),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+
+ if(test_fail_nb_temp == t->fail_nb)
+ {
+ DBG_PRINT ("\"get_tonemap_req_receive return false\" "
+ "successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"get_tonemap_req_receive return false\" test failed");
+ test_fail_nb_temp = t->fail_nb;
+ }
+
+ test_begin (t, "invalid mac address")
+ {
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs__started__vs_get_tonemap_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_req_receive, .ok = true,
+ .mac_addr = mac_1, .tmi = 0x00, .int_id = 0,
+ .dir = CP_MSG_VS_GET_TONEMAP_REQ_DIRECTION_RX),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_cnf_send,
+ .peer = peer,
+ .result = CP_MSG_VS_GET_TONEMAP_CNF_RESULT_FAILURE,
+ .beacon_delta = 0, .int_id = 0, .tms = 0, .tmi = 0),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+
+ if(test_fail_nb_temp == t->fail_nb)
+ {
+ DBG_PRINT ("\"invalid mac address\" successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"invalid mac address\" test failed");
+ test_fail_nb_temp = t->fail_nb;
+ }
+
+ /* Create our net/AVLN. */
+ test_sta_action_create_our_net (&ctx, our_nid, tei_1);
+ cp_net_t *my_net = cp_sta_mgr_get_our_avln (cp);
+ cp_sta_t *sta_1 = cp_sta_mgr_sta_add (cp, my_net, tei_1, mac_1);
+ sta_t* station = mac_store_sta_get (cp->mac_store, tei_1);
+ station->authenticated = true;
+
+ test_begin (t, "only get intervals and tonemaps")
+ {
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs__started__vs_get_tonemap_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_req_receive, .ok = true,
+ .mac_addr = mac_1,
+ .tmi = CP_MSG_VS_GET_TONEMAP_TMI_AND_INT_ONLY,
+ .int_id = 0,
+ .dir = CP_MSG_VS_GET_TONEMAP_REQ_DIRECTION_TX),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_cnf_send,
+ .peer = peer,
+ .result = CP_MSG_VS_GET_TONEMAP_CNF_RESULT_SUCCESS,
+ .beacon_delta = 0,
+ .int_id = station->tx_tonemaps->intervals->version,
+ .tms = station->tx_tonemaps,
+ .tmi = CP_MSG_VS_GET_TONEMAP_TMI_AND_INT_ONLY),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+
+ if(test_fail_nb_temp == t->fail_nb)
+ {
+ DBG_PRINT ("\"only get intervals and tonemaps\" successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"only get intervals and tonemaps\" test failed");
+ test_fail_nb_temp = t->fail_nb;
+ }
+
+ test_begin (t, "tonemap doesn't exist")
+ {
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs__started__vs_get_tonemap_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_req_receive, .ok = true,
+ .mac_addr = mac_1,
+ .tmi = 4,
+ .int_id = station->tx_tonemaps->intervals->version,
+ .dir = CP_MSG_VS_GET_TONEMAP_REQ_DIRECTION_TX),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_cnf_send,
+ .peer = peer,
+ .result = CP_MSG_VS_GET_TONEMAP_CNF_RESULT_FAILURE,
+ .beacon_delta = 0,
+ .int_id = station->tx_tonemaps->intervals->version,
+ .tms = 0,
+ .tmi = 0),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+
+ if(test_fail_nb_temp == t->fail_nb)
+ {
+ DBG_PRINT ("\"tonemap doesn't exist\" successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"tonemap doesn't exist\" test failed");
+ test_fail_nb_temp = t->fail_nb;
+ }
+
+ station->tx_tonemaps->tm[4] = tonemap_alloc ();
+ station->rx_tonemaps->tm[4] = tonemap_alloc ();
+ station->tx_tonemaps->intervals->version = 23;
+ station->rx_tonemaps->intervals->version = 15;
+
+ test_begin (t, "correct tonemap")
+ {
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs__started__vs_get_tonemap_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_req_receive, .ok = true,
+ .mac_addr = mac_1,
+ .tmi = 4,
+ .int_id = station->tx_tonemaps->intervals->version,
+ .dir = CP_MSG_VS_GET_TONEMAP_REQ_DIRECTION_TX),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_cnf_send,
+ .peer = peer,
+ .result = CP_MSG_VS_GET_TONEMAP_CNF_RESULT_SUCCESS,
+ .beacon_delta = 0,
+ .int_id = station->tx_tonemaps->intervals->version,
+ .tms = station->tx_tonemaps,
+ .tmi = 4),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+
+ if(test_fail_nb_temp == t->fail_nb)
+ {
+ DBG_PRINT ("\"correct tonemap\" successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"correct tonemap\" test failed");
+ test_fail_nb_temp = t->fail_nb;
+ }
+
+ /* In this test we try to get the tonemap tx with the tmi version of
+ * the rx, which is invalid.
+ */
+ test_begin (t, "wrong interval list index")
+ {
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (vs__started__vs_get_tonemap_req, .peer = peer),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_req_receive, .ok = true,
+ .mac_addr = mac_1,
+ .tmi = 4,
+ .int_id = station->rx_tonemaps->intervals->version,
+ .dir = CP_MSG_VS_GET_TONEMAP_REQ_DIRECTION_TX),
+ SCENARIO_EVENT (cp_msg_vs_get_tonemap_cnf_send,
+ .peer = peer,
+ .result =
+ CP_MSG_VS_GET_TONEMAP_CNF_RESULT_BAD_TMP_INT_LIST_ID,
+ .beacon_delta = 0,
+ .int_id = station->tx_tonemaps->intervals->version,
+ .tms = station->tx_tonemaps,
+ .tmi = 4),
+ SCENARIO_END
+ };
+ scenario_run (t, entries, &globals);
+ } test_end;
+
+ if(test_fail_nb_temp == t->fail_nb)
+ {
+ DBG_PRINT ("\"wrong interval list index\" successfully tested");
+ }
+ else
+ {
+ DBG_PRINT ("\"wrong interval list index\" test failed");
+ test_fail_nb_temp = t->fail_nb;
+ }
+
+ /* Cleanup. */
+ blk_release (station);
+ slab_release (sta_1);
+
+ test_sta_action_uninit (&ctx);
+}
+
+
+void
+test_action_test_suite (test_t t)
+{
+ test_suite_begin (t, "cco_action");
+ test_case_sta_assoc_and_auth_procedure_action (t);
+ test_case_garbage_collector (t);
+ test_case_cco_action (t);
+ test_case_DRV_and_VS_MMEs (t);
+}
+
+
+void
+vs_test_suite (test_t t)
+{
+ test_suite_begin (t, "vs");
+ vs_get_tonemap_test_case (t);
+}
+
+int
+main (int argc, char **argv)
+{
+ lib_stats_init();
+ test_t t;
+ trace_init ();
+ test_init (t, argc, argv);
+ vs_test_suite (t);
+ test_action_test_suite (t);
+ set_insert_set_remove_test_case(t);
+ trace_uninit ();
+ lib_stats_uninit();
+ test_case_begin (t, "Memory allocation");
+ test_begin (t, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_fsm.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_fsm.c
new file mode 100644
index 0000000000..bb556d83ef
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_fsm.c
@@ -0,0 +1,429 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_fsm.c
+ * \brief Test FSM module.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+#include "lib/blk.h"
+#include "lib/test.h"
+
+#include "cp/fsm/fsm.h"
+#include "cp/inc/context.h"
+#include "cp/sta/core/core.h"
+
+void
+test_fsm_basic_test_case (test_t t)
+{
+ test_case_begin (t, "basic");
+ cp_t cp;
+ cp.sta_core_urgent_flag = false;
+ cp_trace_init (&cp);
+
+ test_begin (t, "CCO")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO, DRV_STA_GET_KEY_REQ */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_GET_KEY_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__drv_sta_get_key_req),
+ /* CCO, VS_EOC_GET_TOPO_REQ */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_GET_TOPO_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_topo_req),
+ /* CCO, VS_EOC_CCO_SET_WL_REQ */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_CCO_SET_WL_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_wl_req),
+ /* CCO, VS_EOC_CCO_GET_WL_REQ */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_CCO_GET_WL_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_wl_req),
+ /* CCO, NEK change */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_cco__nek_change),
+ SCENARIO_EVENT (cp_fsm__CCO__nek_provide),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_SET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__CCO__set_key_cnf),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nek_timeout),
+ SCENARIO_EVENT (cp_fsm__CCO__nek_change_timeout,
+ .branch = CP_FSM_BRANCH (CCO, nek_timeout, yes)),
+ /* CCO*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "CCO -> Multi_sta")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_MULTI_STA_MME),
+ SCENARIO_EVENT (cp_fsm__CCO__event_dispatch),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "BCCO")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_rx_beacon),
+ SCENARIO_EVENT (cp_fsm__POWER_ON__power_on_rx_beacon),
+ /* BCCO*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__BCCO__bcco_drv_mac_stop),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "BCCO -> CCO")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_rx_beacon),
+ SCENARIO_EVENT (cp_fsm__POWER_ON__power_on_rx_beacon),
+ /* BCCO*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__BCCO__bcco_no_beacons),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+void
+test_vs_eoc_test_case (test_t t)
+{
+ test_case_begin (t, "vs eoc");
+ cp_t cp;
+ cp.sta_core_urgent_flag = false;
+ cp_trace_init (&cp);
+
+ test_begin (t, "VS_EOC_GET_TOPO")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_GET_TOPO_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_topo_req),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "VS_EOC_CCO_GET_WL")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_CCO_GET_WL_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_wl_req),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "VS_EOC_CCO_SET_WL")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_CCO_SET_WL_REQ),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_wl_req),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "VS_EOC_SEND_CENTRAL_BEACON")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_TIMER_EXPIRES),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_CCO);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "leave_remove_timeout")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_START_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_mac_start_req),
+ /* STARTED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_poweron),
+ SCENARIO_EVENT (cp_fsm__STARTED__poweron__idle__to_poweron),
+ /* POWER_ON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON_NOT_RECEIVED),
+ SCENARIO_EVENT (cp_fsm__CCO__send_central_beacon),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_leave_remove_delay),
+ SCENARIO_EVENT (cp_fsm__CCO__vs_eoc__cco__leave_remove_timeout),
+ /* CCO */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__STARTED__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPING);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+
+
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+void
+test_fsm_test_suite (test_t t)
+{
+ test_suite_begin (t, "cco fsm");
+ test_fsm_basic_test_case (t);
+ test_vs_eoc_test_case (t);
+}
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->sta_core_flag = true;
+}
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->sta_core_urgent_flag = true;
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ trace_init ();
+ test_init (t, argc, argv);
+ test_fsm_test_suite (t);
+ trace_uninit ();
+ test_case_begin (t, "Memory allocation");
+ test_begin (t, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/Config b/cesar/cp/eoc/cco/action/test/utest_mcast/Config
new file mode 100644
index 0000000000..4660a4c5b7
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/Config
@@ -0,0 +1,19 @@
+CONFIG_CP_EOC = y
+CONFIG_TRACE = n
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_EOC_IS_MASTER = y
+CONFIG_CP_STA_MGR_CCO_EOC = y
+CONFIG_CP_FSM_DEF = "cp/eoc/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_CP_EOC_BEACON_SPC_CENTRAL = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_CP_EOC_CCO_ACTION_WL_ALLOWED = y
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 1
+CONFIG_AV_ONLY_MODE = y
+CONFIG_CP_EOC_CCO_ACTION_CON_ALLOWED = n
+CONFIG_MAC_COMMON_EOC_TEI = y
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/Makefile b/cesar/cp/eoc/cco/action/test/utest_mcast/Makefile
new file mode 100644
index 0000000000..8fc6f16a77
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/Makefile
@@ -0,0 +1,18 @@
+BASE = ../../../../../..
+
+INCLUDES = cp/eoc/cco/action/test/utest_mcast/override \
+ cp/eoc/cco/action/test/utest_mcast
+
+HOST_PROGRAMS = test_cco_action
+test_cco_action_SOURCES = test_cco_action.c test_mcast_suite.c \
+ scenario_actions.c fsm_stub.c msg_stub.c cl_mcast.c
+test_cco_action_MODULES = lib lib/scenario cp/eoc/fsm/stub mac/common \
+ cp/eoc/cco/action cp/eoc/cco/bw/stub cl/stub \
+ cp/eoc/sta/mgr cp/eoc/sta/action/stub cp/sta/core/stub \
+ cp/eoc/multi_sta_fsm cp/eoc/multi_sta/action/stub \
+ cp/eoc/beacon/stub cp/eoc/msg/stub bsu/stub cp/secu/stub \
+ mac/sar/stub mac/pbproc/stub mac/ca/stub ce/rx/stub \
+ hal/ipmbox/stub bufmgr/stub
+test_cco_action_CONFIG_MODULES = cp/eoc cl mac/sar
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/inc/scenario_defs.h b/cesar/cp/eoc/cco/action/test/utest_mcast/inc/scenario_defs.h
new file mode 100644
index 0000000000..1806228271
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/inc/scenario_defs.h
@@ -0,0 +1,160 @@
+#ifndef inc_scenario_defs_h
+#define inc_scenario_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/scenario_defs.h
+ * \brief Scenario definitions.
+ * \ingroup test
+ */
+#include "cp/fsm/fsm.h"
+
+/* Scenario globals. */
+#define SCENARIO_DEFS_GLOBALS \
+ cp_t *cp; \
+ u16 prn; \
+ u32 my_nonce; \
+ u32 your_nonce; \
+ cp_mme_tx_t *mme;
+
+/* Scenario actions. */
+#define SCENARIO_DEFS_ACTIONS \
+ drv__drv_mcast_set_list_req
+
+/* Actions without parameter. */
+#define __0(action) \
+typedef scenario_empty_t scenario_action_ ## action ## _t; \
+void \
+scenario_action_ ## action ## _cb ( \
+ scenario_globals_t *globals, scenario_params_t *params);
+
+/* Actions with parameters. */
+#define __n(action, param...) \
+typedef struct \
+{ \
+ PREPROC_FOR_EACH (__n_, param) \
+} scenario_action_ ## action ## _t; \
+void \
+scenario_action_ ## action ## _cb ( \
+ scenario_globals_t *globals, scenario_params_t *params);
+#define __n_(param) param;
+
+/* Actions with MME and parameters. */
+#define __m(action, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ PREPROC_FOR_EACH (__m_, param) \
+} scenario_action_ ## action ## _t; \
+void \
+scenario_action_ ## action ## _cb ( \
+ scenario_globals_t *globals, scenario_params_t *params);
+#define __m_(param) param;
+
+__m (drv__drv_mcast_set_list_req)
+
+#undef __0
+#undef __n
+#undef __n_
+#undef __m
+#undef __m_
+
+/* Scenario events. */
+#define SCENARIO_DEFS_EVENTS \
+ cp_fsm_event_bare_new, \
+ cp_fsm_event_mme_new, \
+ cp_fsm_branch, \
+ cp_msg_drv_mcast_set_list_req_receive
+
+/* MME send event. */
+#define __ms(event, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME send event complex. */
+#define __msc(event, param...) \
+typedef struct \
+{ \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME send event with encryption information. */
+#define __msk(event, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ cp_mme_peks_t peks; \
+ u8 pid; \
+ u8 pmn; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME send event for CC_RELAY.IND. */
+#define __msr(event, param...) \
+typedef struct \
+{ \
+ mac_t mac_fa; \
+ cp_tei_t ftei; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME receive event. */
+#define __mr(event, param...) \
+typedef struct \
+{ \
+ bool ok; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+/* MME receive event with encryption information. */
+#define __mrk(event, param...) \
+typedef struct \
+{ \
+ bool ok; \
+ cp_mme_peks_t peks; \
+ u8 pid; \
+ u8 pmn; \
+ bool new_prn; \
+ bool new_my_nonce; \
+ bool new_your_nonce; \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+#define __p_(param) param;
+
+__mr (cp_msg_drv_mcast_set_list_req_receive,
+ int nb_groups,
+ mac_t* groups, uint* nb_members,
+ mac_t* members)
+
+#undef __ms
+#undef __msk
+#undef __msr
+#undef __mr
+#undef __mrk
+#undef __msc
+
+/* Any event. */
+#define __e(event, param...) \
+typedef struct \
+{ \
+ PREPROC_FOR_EACH (__p_, ## param) \
+} scenario_event_ ## event ## _t;
+
+__e (cp_fsm_event_bare_new, cp_fsm_event_type_t type)
+__e (cp_fsm_event_mme_new, cp_fsm_event_type_t type)
+__e (cp_fsm_branch, cp_fsm_branch_t branch)
+
+#undef __e
+
+#undef __p_
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/inc/test_cco_action.h b/cesar/cp/eoc/cco/action/test/utest_mcast/inc/test_cco_action.h
new file mode 100644
index 0000000000..06213c752d
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/inc/test_cco_action.h
@@ -0,0 +1,46 @@
+#ifndef inc_test_cco_action_h
+#define inc_test_cco_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/test_cco_action.h
+ * \brief Test cco/action.
+ * \ingroup test
+ */
+#include "cp/inc/context.h"
+
+/** Contexts used in tests. */
+struct test_cco_action_t
+{
+ cp_t cp;
+ mac_config_t mac_config;
+};
+typedef struct test_cco_action_t test_cco_action_t;
+
+/**
+ * Initialise test contexts.
+ * \param ctx test context
+ */
+void
+test_cco_action_init (test_cco_action_t *ctx);
+
+/**
+ * Uninitialise test contexts.
+ * \param ctx test context
+ */
+void
+test_cco_action_uninit (test_cco_action_t *ctx);
+
+/**
+ * Reset test contexts.
+ * \param ctx test context
+ */
+void
+test_cco_action_reset (test_cco_action_t *ctx);
+
+#endif /* inc_test_cco_action_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/inc/context.h b/cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/inc/context.h
new file mode 100644
index 0000000000..af86ef23f3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/inc/context.h
@@ -0,0 +1,90 @@
+#ifndef override_cp_inc_context_h
+#define override_cp_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/inc/context.h
+ * \brief Control plane context override.
+ * \ingroup test
+ */
+#include "cp/types.h"
+#include "cp/eoc/cco/action/inc/cco_action.h"
+#include "cp/cco/action/inc/cco_action.h"
+#include "cp/sta/action/inc/context.h"
+#include "cp/eoc/beacon/inc/beacon.h"
+#include "cp/eoc/beacon/beacon.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta_mgr.h"
+#include "cp/cco/region/inc/context.h"
+#include "cp/cco/bw/bw.h"
+#include "cp/cco/bw/inc/context.h"
+#include "cl/cl.h"
+#include "mac/common/config.h"
+#include "mac/common/store.h"
+#include "mac/sar/sar.h"
+#include "mac/pbproc/pbproc.h"
+#include "lib/rnd.h"
+#include "lib/trace.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "cp/inc/trace.h"
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+
+enum cp_handover_reason_t
+{
+ CP_HANDOVER_REASON_CCO_SELECTION,
+ CP_HANDOVER_REASON_CCO_LEAVING,
+ CP_HANDOVER_REASON_USER_APPOINT,
+ CP_HANDOVER_REASON_NB,
+};
+
+enum cp_handover_soft_hard_t
+{
+ CP_HANDOVER_SOFT_HARD_SOFT,
+ CP_HANDOVER_SOFT_HARD_HARD,
+ CP_HANDOVER_NB,
+};
+
+struct cp_handover_t
+{
+ /** Handover timeout. */
+ cp_sta_core_timed_event_def_t handover_timeout;
+
+ /** handover reason. */
+ enum cp_handover_reason_t reason;
+
+ /** Handover soft hard */
+ enum cp_handover_soft_hard_t soft_hard;
+};
+
+struct cp_t
+{
+ cp_fsm_t fsm;
+ cp_cco_action_t cco_action;
+ cp_sta_action_t sta_action;
+ cp_sta_mgr_t sta_mgr;
+ cp_beacon_t beacon;
+ lib_rnd_t rnd;
+ cl_t *cl;
+ mac_config_t *mac_config;
+ mac_store_t *mac_store;
+ sar_t *sar;
+ ca_t *ca;
+ pbproc_t *pbproc;
+ struct cp_handover_t handover;
+ struct cp_cco_region_t region;
+ struct cp_cco_bw_t bw;
+ bsu_t *bsu;
+ cp_eoc_cco_bw_sched_t schedule;
+
+#if CONFIG_TRACE
+ trace_buffer_t trace;
+#endif
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/sta/core/defs.h b/cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..9698b44e93
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/override/cp/sta/core/defs.h
@@ -0,0 +1,57 @@
+#ifndef cp_sta_core_defs_h
+#define cp_sta_core_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/core/defs.h
+ * \brief Sta core defs.
+ * \ingroup cp/sta/core
+ *
+ */
+#include "cp/fsm/forward.h"
+
+/** Forward declaration. */
+typedef struct cp_sta_core_t cp_sta_core_t;
+
+/*
+ * the sta core event flags
+ * these are some flags, so take care to give a value with all bits set to 0 but one.
+ */
+enum cp_sta_core_event_flag_t
+{
+ CP_STA_CORE_EVENT_FLAG_RECV_BEACON = 0x1,
+ CP_STA_CORE_EVENT_FLAG_RECV_MME = 0x2,
+ CP_STA_CORE_EVENT_FLAG_FSM = 0x4,
+ CP_STA_CORE_EVENT_FLAG_GARBAGE = 0x8,
+ CP_STA_CORE_EVENT_FLAG_TERMINATE = 0x10
+};
+typedef enum cp_sta_core_event_flag_t cp_sta_core_event_flag_t;
+
+/** Definition of alarm info structure
+ * (applications should not use it directly but use "alias" defined just below) */
+struct cp_sta_core_timed_event_def_t
+{
+ /* eCos alarm. */
+ uint alarm;
+ /* eCos alarm handle. */
+ uint alarm_handle;
+ /* the sta core event flag to set
+ * (auto or user-specified when creating/launching timer alarm). */
+ cp_sta_core_event_flag_t event_flag;
+ /* FSM event specified when creating/launching timer alarm
+ * (set if the previous flag is CP_STA_CORE_EVENT_FLAG_FSM). */
+ cp_fsm_event_t *fsm_event;
+ /* flag indicating a periodic alarm (if set to true)
+ * or one-shot alarm (if set to false). */
+ bool cyclic_alarm;
+ /* pointer to CP context. */
+ cp_t *cp_ctx;
+};
+typedef struct cp_sta_core_timed_event_def_t cp_sta_core_timed_event_def_t;
+
+#endif /* cp_sta_core_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/override/cyg/kernel/kapi.h b/cesar/cp/eoc/cco/action/test/utest_mcast/override/cyg/kernel/kapi.h
new file mode 100644
index 0000000000..019e5d3a07
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/override/cyg/kernel/kapi.h
@@ -0,0 +1,37 @@
+#ifndef override_cyg_kernel_kapi_h
+#define override_cyg_kernel_kapi_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cyg/kernel/kapi.h
+ * \brief override some kernel api from <cyg/kernel/kapi.h>.
+ * \ingroup cp_msg
+ *
+ *
+ */
+
+struct cyg_resolution_t
+{
+ u32 dividend;
+ u32 divisor;
+} ;
+
+typedef struct cyg_resolution_t cyg_resolution_t;
+
+typedef u64 cyg_tick_count_t;
+
+int
+cyg_real_time_clock (void);
+
+cyg_resolution_t
+cyg_clock_get_resolution (int clock);
+
+cyg_tick_count_t
+cyg_current_time (void);
+
+#endif
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/override/mac/sar/inc/context.h b/cesar/cp/eoc/cco/action/test/utest_mcast/override/mac/sar/inc/context.h
new file mode 100644
index 0000000000..3cf70530df
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/override/mac/sar/inc/context.h
@@ -0,0 +1,24 @@
+#ifndef override_mac_sar_inc_context_h
+#define override_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "mac/common/store.h"
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+};
+
+#endif /* override_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/src/cl_mcast.c b/cesar/cp/eoc/cco/action/test/utest_mcast/src/cl_mcast.c
new file mode 100644
index 0000000000..6eb9f07fd2
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/src/cl_mcast.c
@@ -0,0 +1,60 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/scenario/src/cl_mcast.c
+ * \brief Multicast.
+ * \ingroup cp_eoc_cco_action_test_scenario
+ */
+#include "common/std.h"
+#include "cl/cl.h"
+#include "cl/mcast.h"
+#include "config/cl/eoc/route.h"
+#include "cl/inc/context.h"
+
+igmp_groups_t*
+cl_get_igmp_groups (cl_t *ctx)
+{
+ dbg_assert (ctx);
+ return &ctx->groups;
+}
+
+void
+cl_update_igmp_groups (cl_t *ctx)
+{
+ dbg_assert (ctx);
+ uint g;
+ uint m;
+ for (g = 0; g < ctx->groups.nb; g++)
+ {
+ uint tei = MAC_TEI_UNASSOCIATED;
+ ctx->groups.nb_actual_members[g] = 0;
+
+ for (m = 0; m < ctx->groups.nb_total_members[g]; m++)
+# if CONFIG_CL_EOC_ROUTE
+ {
+ tei = cl_eoc_mactotei_find_tei (
+ ctx, ctx->groups.member_mac[g][m]);
+ if (MAC_TEI_IS_EOC_STA (tei))
+ ctx->groups.member_tei[g][ctx->groups.nb_actual_members[g]++] =
+ tei;
+ }
+ if (ctx->groups.nb_actual_members[g] == 0)
+ ctx->groups.member_tei[g][0] = MAC_TEI_UNASSOCIATED;
+#else
+ {
+ tei = cl_mactotei_table_find_tei_from_mac (
+ ctx, ctx->groups.member_mac[g][m]);
+ if (MAC_TEI_IS_STA(tei))
+ ctx->groups.member_tei[g][ctx->groups.nb_actual_members[g]++] =
+ tei;
+ }
+ if (ctx->groups.nb_actual_members[g] == 0)
+ ctx->groups.member_tei[g][0] = MAC_TEI_BCAST;
+#endif
+ }
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/src/fsm_stub.c b/cesar/cp/eoc/cco/action/test/utest_mcast/src/fsm_stub.c
new file mode 100644
index 0000000000..993bffaaaa
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/src/fsm_stub.c
@@ -0,0 +1,55 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/fsm_stub.c
+ * \brief FSM stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "cp/fsm/fsm.h"
+
+#include "lib/scenario/scenario.h"
+
+cp_fsm_event_t *
+cp_fsm_event_bare_new (cp_t *ctx, cp_fsm_event_type_t type)
+{
+ dbg_assert (ctx);
+ switch (type)
+ {
+ case CP_FSM_EVENT_TYPE_net_list_empty:
+ /* Ignore. */
+ return INVALID_PTR;
+ case CP_FSM_EVENT_TYPE_sta_status_changed:
+ if (!scenario.current ||
+ (scenario.current->params.event_cp_fsm_event_bare_new.type != type))
+ return INVALID_PTR;
+
+ default:
+ ;
+ }
+ scenario_event (cp_fsm_event_bare_new, param);
+ test_fail_unless (type == param->type);
+ return INVALID_PTR;
+}
+
+cp_fsm_event_t *
+cp_fsm_event_mme_new (cp_t *ctx, cp_fsm_event_type_t type, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ scenario_event (cp_fsm_event_mme_new, param);
+ test_fail_unless (type == param->type);
+ return INVALID_PTR;
+}
+
+void
+cp_fsm_branch_ (cp_t *ctx, cp_fsm_branch_t branch)
+{
+ dbg_assert (ctx);
+ scenario_event (cp_fsm_branch, param);
+ test_fail_unless (branch == param->branch);
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/src/msg_stub.c b/cesar/cp/eoc/cco/action/test/utest_mcast/src/msg_stub.c
new file mode 100644
index 0000000000..c9beef391b
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/src/msg_stub.c
@@ -0,0 +1,289 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/msg_stub.c
+ * \brief cp_msg_stub functions.
+ * \ingroup cp_msg
+ */
+#include "common/std.h"
+#include "lib/scenario/scenario.h"
+#include "cp/inc/context.h"
+#include "cp/msg/msg.h"
+
+#define __ptr_(TYPE) PASTE_EXPAND (__ptr__, TYPE)
+#define __ptr__assign *
+#define __ptr__string
+#define __ptr__array
+#define __ptr__string_or_null
+#define __ptr__tonemask
+#define __ptr__hash_key
+
+#define __dim_(TYPE, DIM...) PASTE_EXPAND (__dim__, TYPE) (DIM)
+#define __dim__assign()
+#define __dim__string()
+#define __dim__array(DIM) DIM
+#define __dim__string_or_null()
+#define __dim__tonemask()
+#define __dim__hash_key()
+
+/* Code for MME transmission. */
+#define __ms(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ scenario_event (EVENT, param); \
+ __ms_test_peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+/* Code for MME transmission complex with a begin. */
+#define __mscb(EVENT, PARAMS...) \
+cp_mme_tx_t * \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ scenario_event (EVENT, param, global); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+ return global->mme; \
+}
+
+/* Code for MME transmission complex (with or without an end). */
+#define __msc(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_tx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ scenario_event (EVENT, param); \
+ test_fail_unless (param); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+#define __msdc(EVENT, DATA, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_tx_t *mme, const DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __msd_test_, ## PARAMS) \
+}
+
+#define __ms_pdecl_(TYPE, PARAM, KIND) , TYPE PARAM
+#define __ms_test_(TYPE, PARAM, KIND) \
+ PASTE_EXPAND (__ms_test__, KIND) (PARAM)
+#define __ms_test__assign(PARAM) \
+ test_fail_unless (PARAM == param->PARAM);
+#define __ms_test__ignore_pointer(PARAM)
+#define __ms_test__string(PARAM) \
+ test_fail_unless (strcmp (PARAM, param->PARAM) == 0);
+#define __ms_test_peer \
+ test_fail_unless (peer->mac == param->peer.mac); \
+ test_fail_unless (peer->eth_type == param->peer.eth_type); \
+ test_fail_unless (peer->vlan_tci == param->peer.vlan_tci); \
+ test_fail_unless (peer->tei == param->peer.tei); \
+
+/* Code for MME transmission with a data structure. */
+#define __msd(EVENT, DATA, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer, const DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param); \
+ __ms_test_peer \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __msd_test_, ## PARAMS) \
+}
+
+#define __msd_test_(TYPE, PARAM, KIND) \
+ PASTE_EXPAND (__msd_test__, KIND) (PARAM)
+#define __msd_test__assign(PARAM) \
+ test_fail_unless (data->PARAM == param->PARAM);
+#define __msd_test__string(PARAM) \
+ test_fail_unless (strcmp (data->PARAM, param->PARAM) == 0);
+#define __msd_test__hash_key(PARAM) \
+ test_fail_unless (!param->PARAM || memcmp (data->PARAM, param->PARAM, \
+ CP_HASH_KEY_SIZE) == 0);
+#define __msd_test__key(PARAM) \
+ test_fail_unless (memcmp (&data->PARAM, &param->PARAM, \
+ sizeof (cp_key_t)) == 0);
+#define __ms_test__key(PARAM) \
+ test_fail_unless (memcmp (&PARAM, &param->PARAM, \
+ sizeof (cp_key_t)) == 0);
+#define __msd_test__sub_assign(PARAM) \
+ __msd_test__sub_assign_ PARAM
+#define __msd_test__sub_assign_(PARAM, SUBNAME) \
+ test_fail_unless (data->SUBNAME.PARAM == param->PARAM);
+#define __msd_test__ignore_pointer(PARAM) ;
+
+#define __msd_test__array(PARAM) \
+ __msd_test__array_ PARAM
+#define __msd_test__array_(PARAM, SIZE) \
+ test_fail_unless (memcmp (data->PARAM, param->PARAM, SIZE) == 0);
+
+/* Code for MME transmission with a data structure with encryption
+ * information. */
+#define __msk(EVENT, DATA, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_peer_t *peer, cp_mme_peks_t peks, \
+ const cp_secu_protocol_run_t *prun, const DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (peer); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param, global); \
+ __ms_test_peer \
+ test_fail_unless (peks == param->peks); \
+ test_fail_unless (prun->pid == param->pid); \
+ test_fail_unless (prun->pmn == param->pmn); \
+ global->prn = prun->prn; \
+ global->my_nonce = prun->my_nonce; \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __msd_test_, ## PARAMS) \
+}
+
+/* Code for MME transmission for CC_RELAY.IND. */
+#define __msr(EVENT, PARAMS...) \
+void \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ scenario_event (EVENT, param); \
+ test_fail_unless (mme->relay.mac_fa == param->mac_fa); \
+ test_fail_unless (mme->relay.ftei == param->ftei); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __ms_test_, ## PARAMS) \
+}
+
+
+/* Code for MME reception. */
+#define __mr(EVENT, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_assert_, ## PARAMS) \
+ scenario_event (EVENT, param); \
+ if (param->ok) \
+ { \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_copy_, ## PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+#define __mr_pdecl_(TYPE, PARAM, KIND, DIM...) \
+ , TYPE __ptr_ (KIND) PARAM __dim_ (KIND, ## DIM)
+#define __mr_assert_(TYPE, PARAM, KIND, DIM...) dbg_assert_ptr (PARAM);
+#define __mr_copy_(TYPE, PARAM, KIND, DIM...) \
+ PASTE_EXPAND (__mr_copy__, KIND) (PARAM, TYPE, ## DIM)
+
+#define __mr_copy__assign(PARAM, TYPE) *PARAM = param->PARAM;
+#define __mr_copy__string(PARAM, TYPE) strcpy (PARAM, param->PARAM);
+#define __mr_copy__string_or_null(PARAM, TYPE) \
+ if (param->PARAM) strcpy (PARAM, param->PARAM);
+#define __mr_copy__tonemask(PARAM, TYPE) \
+ memcpy (PARAM, param->PARAM, PHY_TONEMASK_SIZE);
+#define __mr_copy__array(PARAM, TYPE, DIM) \
+ memcpy (PARAM, param->PARAM, sizeof(TYPE DIM));
+
+/* Code for MME reception with a data structure. */
+#define __mrd(EVENT, DATA, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme, DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param); \
+ if (param->ok) \
+ { \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mrd_copy_, PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+#define __mrd_copy_(TYPE, PARAM, KIND) \
+ PASTE_EXPAND (__mrd_copy__, KIND) (PARAM)
+
+#define __mrd_copy__assign(PARAM) data->PARAM = param->PARAM;
+#define __mrd_copy__string(PARAM) strcpy (data->PARAM, param->PARAM);
+#define __mrd_copy__tonemask(PARAM) \
+ memcpy (data->PARAM, param->PARAM, PHY_TONEMASK_SIZE);
+#define __mrd_copy__hash_key(PARAM) \
+ if (param->PARAM) memcpy (data->PARAM, param->PARAM, CP_HASH_KEY_SIZE);
+#define __mrd_copy__assign_deref(PARAM) \
+ if (param->PARAM) data->PARAM = *param->PARAM;
+
+/* Code for MME reception with a data structure with encryption
+ * information. */
+#define __mrk(EVENT, DATA, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme, DATA *data) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ dbg_assert (data); \
+ scenario_event (EVENT, param, g); \
+ if (param->ok) \
+ { \
+ mme->peks = param->peks; \
+ if (param->new_prn) g->prn = lib_rnd32 (&ctx->rnd) & 0xffff; \
+ if (param->new_my_nonce) g->my_nonce = lib_rnd32 (&ctx->rnd); \
+ if (param->new_your_nonce) g->your_nonce = lib_rnd32 (&ctx->rnd); \
+ mme->prun.pid = param->pid; \
+ mme->prun.pmn = param->pmn; \
+ mme->prun.prn = g->prn; \
+ mme->prun.my_nonce = g->my_nonce; \
+ mme->prun.your_nonce = g->your_nonce; \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mrd_copy_, PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+/* Code for MME reception for CC_RELAY.REQ. */
+#define __mrr(EVENT, PARAMS...) \
+bool \
+EVENT (cp_t *ctx, cp_mme_rx_t *mme \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_pdecl_, ## PARAMS)) \
+{ \
+ dbg_assert (ctx); \
+ dbg_assert (mme); \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_assert_, ## PARAMS) \
+ scenario_event (EVENT, param); \
+ if (param->ok) \
+ { \
+ mme->relay.mac_fa = param->mac_fa; \
+ mme->relay.ftei = param->ftei; \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, __mr_copy_, ## PARAMS) \
+ return true; \
+ } \
+ else \
+ return false; \
+}
+
+__mr (cp_msg_drv_mcast_set_list_req_receive,
+ (uint, nb_groups, assign),
+ (mac_t, groups, array, [MCAST_GROUP_MAX_NB]),
+ (uint, nb_members, array, [MCAST_GROUP_MAX_NB]),
+ (mac_t, members, array, [MCAST_GROUP_MAX_NB][MCAST_MEMBER_MAX_NB]))
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/src/scenario_actions.c b/cesar/cp/eoc/cco/action/test/utest_mcast/src/scenario_actions.c
new file mode 100644
index 0000000000..edcd638f3b
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/src/scenario_actions.c
@@ -0,0 +1,72 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/scenario_actions.c
+ * \brief Scenario actions.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "lib/scenario/scenario.h"
+
+#define __m(ACTION) \
+void \
+scenario_action_ ## ACTION ## _cb (scenario_globals_t *globals, \
+ scenario_params_t *params) \
+{ \
+ static cp_mme_rx_t mme; \
+ mme.peer = params->action_ ## ACTION.peer; \
+ cp_eoc_cco_action_ ## ACTION (globals->cp, &mme); \
+}
+
+#define __mp(ACTION) \
+void \
+scenario_action_ ## ACTION ## _cb (scenario_globals_t *globals, \
+ scenario_params_t *params) \
+{ \
+ ccotic cp_mme_rx_t mme; \
+ mme.peer = params->action_ ## ACTION.peer; \
+ mme.prun.pid = params->action_ ## ACTION.pid; \
+ cp_eoc_cco_action_ ## ACTION (globals->cp, &mme); \
+}
+
+#define __me(ACTION) \
+void \
+scenario_action_ ## ACTION ## _cb (scenario_globals_t *globals, \
+ scenario_params_t *params) \
+{ \
+ ccotic cp_mme_rx_t mme; \
+ mme.peer = params->action_ ## ACTION.peer; \
+ mme.encrypt = params->action_ ## ACTION.encrypt; \
+ cp_eoc_cco_action_ ## ACTION (globals->cp, &mme); \
+}
+
+#define __0(ACTION) \
+void \
+scenario_action_ ## ACTION ## _cb (scenario_globals_t *globals, \
+ scenario_params_t *params) \
+{ \
+ cp_eoc_cco_action_ ## ACTION (globals->cp); \
+}
+
+#define __n(ACTION, PARAMS...) \
+void \
+scenario_action_ ## ACTION ## _cb (scenario_globals_t *globals, \
+ scenario_params_t *params) \
+{ \
+ scenario_action_ ## ACTION ## _t *p = &params->action_ ## ACTION; \
+ cp_eoc_cco_action_ ## ACTION (globals->cp \
+ PREPROC_FOR_EACH_PARAM (PREPROC_CALL_UNPACK, \
+ __n_args, ## PARAMS) \
+ ); \
+}
+
+#define __n_args(TYPE, PARAM) \
+ , p->PARAM
+
+__m (drv__drv_mcast_set_list_req)
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/src/test_cco_action.c b/cesar/cp/eoc/cco/action/test/utest_mcast/src/test_cco_action.c
new file mode 100644
index 0000000000..8659c74c13
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/src/test_cco_action.c
@@ -0,0 +1,75 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_sta_action.c
+ * \brief Test sta/action.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "cp/eoc/multi_sta_fsm/forward.h"
+#include "cl/inc/context.h"
+#include "mac/sar/inc/context.h"
+#include "inc/test_cco_action.h"
+
+void
+test_suite_mcast (test_t test);
+
+void
+test_cco_action_init (test_cco_action_t *ctx)
+{
+ static sar_t sar;
+ static cl_t cl;
+ memset (&cl, 0, sizeof (cl_t));
+
+ lib_rnd_init (&ctx->cp.rnd, 1234);
+ ctx->cp.mac_config = &ctx->mac_config;
+ ctx->cp.mac_store = mac_store_init ();
+ ctx->cp.sar = &sar;
+ ctx->cp.cl = &cl;
+ sar.mac_store = ctx->cp.mac_store;
+ ctx->cp.pbproc = NULL;
+ cp_eoc_sta_mgr_init (&ctx->cp);
+}
+
+void
+test_cco_action_uninit (test_cco_action_t *ctx)
+{
+ cp_sta_mgr_uninit (&ctx->cp);
+ mac_store_uninit (ctx->cp.mac_store);
+}
+
+void
+test_cco_action_reset (test_cco_action_t *ctx)
+{
+ cp_sta_mgr_uninit (&ctx->cp);
+ mac_store_uninit (ctx->cp.mac_store);
+ ctx->cp.mac_store = mac_store_init ();
+ cp_eoc_sta_mgr_init (&ctx->cp);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ trace_init ();
+ lib_stats_init ();
+ test_suite_mcast (t);
+ lib_stats_uninit ();
+ trace_uninit ();
+ test_case_begin (t, "Memory allocation");
+ test_begin (t, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/cp/eoc/cco/action/test/utest_mcast/src/test_mcast_suite.c b/cesar/cp/eoc/cco/action/test/utest_mcast/src/test_mcast_suite.c
new file mode 100644
index 0000000000..2352da0115
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_mcast/src/test_mcast_suite.c
@@ -0,0 +1,97 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/mcast.c
+ * \brief Multicast test.
+ * \ingroup cp_eoc
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "lib/scenario/scenario.h"
+#include "inc/test_cco_action.h"
+#include "cl/mcast.h"
+
+void
+test_suite_mcast (test_t test)
+{
+ test_cco_action_t ctx;
+ test_cco_action_init (&ctx);
+ cp_cco_action_init (&ctx.cp);
+ scenario_globals_t globals = {
+ .cp = &ctx.cp,
+ };
+
+ test_suite_begin (test, "Multicast");
+ test_case_begin (test, "No groups");
+ test_begin (test, "MME received with errors")
+ {
+ igmp_groups_t *igmp = cl_get_igmp_groups (ctx.cp.cl);
+ igmp->nb = 10;
+ scenario_entry_t entry [] = {
+ SCENARIO_ACTION (drv__drv_mcast_set_list_req,
+ .peer = CP_MME_PEER (3, 3)),
+ SCENARIO_EVENT (cp_msg_drv_mcast_set_list_req_receive,
+ .ok = false),
+ SCENARIO_END
+ };
+ scenario_run (test, entry, &globals);
+ test_fail_unless (igmp->nb == 0);
+ }
+ test_end;
+ test_begin (test, "Test all groups cases")
+ {
+ igmp_groups_t *igmp = cl_get_igmp_groups (ctx.cp.cl);
+ igmp->nb = 0;
+ uint nb_groups;
+ mac_t groups[MCAST_GROUP_MAX_NB];
+ uint nb_members[MCAST_GROUP_MAX_NB];
+ mac_t members[MCAST_GROUP_MAX_NB][MCAST_MEMBER_MAX_NB];
+
+ mac_t gmac = 0xAA0000000000ll;
+ mac_t mmac = 0xFF0000000000ll;
+ for (nb_groups = 0; nb_groups < MCAST_GROUP_MAX_NB; nb_groups++)
+ {
+ groups[nb_groups] = gmac + nb_groups;
+ for (nb_members[nb_groups] = 0;
+ nb_members[nb_groups] < MCAST_MEMBER_MAX_NB;
+ nb_members[nb_groups]++)
+ {
+ members[nb_groups][nb_members[nb_groups]] =
+ mmac | (nb_groups << 8) | nb_members[nb_groups];
+
+ scenario_entry_t entry [] = {
+ SCENARIO_ACTION (drv__drv_mcast_set_list_req,
+ .peer = CP_MME_PEER (3, 3)),
+ SCENARIO_EVENT (cp_msg_drv_mcast_set_list_req_receive,
+ .ok = true,
+ .nb_groups = nb_groups,
+ .groups = groups,
+ .nb_members = nb_members,
+ .members = (mac_t*)members),
+ SCENARIO_END
+ };
+ scenario_run (test, entry, &globals);
+ /* Verify. */
+ test_fail_unless (igmp->nb == nb_groups);
+ uint i, j;
+ for (i = 0; i < igmp->nb; i++)
+ {
+ test_fail_unless (igmp->group_mac[i] == gmac + i);
+ test_fail_unless (igmp->nb_total_members[i] == nb_members[i]);
+ for (j = 0; j < nb_members[i]; j++)
+ {
+ test_fail_unless (igmp->member_mac[i][j] ==
+ (mmac | (i << 8) | j));
+ }
+ }
+ }
+ }
+ }
+ test_end;
+ test_cco_action_uninit (&ctx);
+}
diff --git a/cesar/cp/eoc/cco/action/vs_eoc_master.h b/cesar/cp/eoc/cco/action/vs_eoc_master.h
new file mode 100644
index 0000000000..48205a40db
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/vs_eoc_master.h
@@ -0,0 +1,100 @@
+#ifndef cp_eoc_cco_action_vs_eoc_master_h
+#define cp_eoc_cco_action_vs_eoc_master_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2012 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/vs_eoc_master.h
+ * \brief « brief description »
+ * \ingroup cp_eoc_cco_action
+ *
+ * « long description »
+ */
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+/* After sending a CC_LEAVE mme to a sta,
+ * wait 100ms before removing the sta from lists. */
+#define LEAVE_REMOVE_WAIT_TIMEOUT_MS 300
+
+BEGIN_DECLS
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (
+ cp_t *ctx, cp_mme_peer_t *peer);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * Handle CCO => VS_EOC_GET_TOPO.REQ.
+ * \param ctx control plane context
+ * \param mme received MME handle
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_ports_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_set_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_cco_get_services_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * TODO
+ */
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req (
+ cp_t *ctx, cp_mme_rx_t *mme);
+
+END_DECLS
+
+#endif /* cp_eoc_cco_action_vs_eoc_master_h */