summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
Diffstat (limited to 'cesar')
-rw-r--r--cesar/bsu/Config2
-rw-r--r--cesar/bsu/aclf/aclf.h12
-rw-r--r--cesar/bsu/aclf/src/aclf.c102
-rw-r--r--cesar/bsu/aclf/test/utest/Config2
-rw-r--r--cesar/bsu/aclf/test/utest/Makefile1
-rw-r--r--cesar/bsu/beacon/src/beacon.c12
-rw-r--r--cesar/bsu/beacon/test/utest/Config2
-rw-r--r--cesar/bsu/beacon/test/utest/Makefile1
-rw-r--r--cesar/bsu/bsu.h7
-rw-r--r--cesar/bsu/inc/context.h2
-rw-r--r--cesar/bsu/ntb/ntb.h2
-rw-r--r--cesar/bsu/src/bsu.c33
-rw-r--r--cesar/ce/fcall/test/Makefile1
-rw-r--r--cesar/ce/rx/bitloading/inc/nsr.h11
-rw-r--r--cesar/ce/rx/bitloading/src/bitloading.c2
-rw-r--r--cesar/ce/rx/bitloading/src/nsr.c48
-rw-r--r--cesar/ce/rx/bitloading/src/transition.c3
-rw-r--r--cesar/ce/rx/bitloading/test/fsm-Makefile1
-rw-r--r--cesar/ce/rx/bitloading/test/host-Makefile1
-rw-r--r--cesar/ce/rx/bitloading/test/sparc-Makefile1
-rw-r--r--cesar/ce/rx/cp/test/Config2
-rw-r--r--cesar/ce/rx/cp/test/Makefile2
-rw-r--r--cesar/ce/rx/test/Config1
-rw-r--r--cesar/ce/rx/test/Makefile3
-rw-r--r--cesar/ce/tx/test/Config2
-rw-r--r--cesar/ce/tx/test/Makefile1
-rw-r--r--cesar/ce/tx/test/src/test_mme.c21
-rw-r--r--cesar/cl/Config5
-rw-r--r--cesar/cl/Module3
-rw-r--r--cesar/cl/cl_eoc_mactotei.h143
-rw-r--r--cesar/cl/cl_mactotei.h31
-rw-r--r--cesar/cl/inc/context.h10
-rw-r--r--cesar/cl/src/bridge_table.c20
-rw-r--r--cesar/cl/src/cl.c136
-rw-r--r--cesar/cl/src/cl_eoc_mactotei.c279
-rw-r--r--cesar/cl/src/cl_mactotei.c2
-rw-r--r--cesar/cl/stub/Module3
-rw-r--r--cesar/cl/stub/src/cl_eoc_mactotei.c30
-rw-r--r--cesar/cl/test/bridge_table/Makefile1
-rw-r--r--cesar/cl/test/utest_eoc/Config6
-rw-r--r--cesar/cl/test/utest_eoc/Makefile13
-rw-r--r--cesar/cl/test/utest_eoc/src/ntb_stub.c33
-rw-r--r--cesar/cl/test/utest_eoc/src/test_mactotei.c194
-rw-r--r--cesar/common/defs/ethernet.h2
-rw-r--r--cesar/common/defs/homeplugAV.h2
-rw-r--r--cesar/common/tests/tests49
-rwxr-xr-xcesar/common/tools/build-info1
-rw-r--r--cesar/cp/Config2
-rw-r--r--cesar/cp/beacon/Config5
-rw-r--r--cesar/cp/beacon/beacon.h7
-rw-r--r--cesar/cp/beacon/src/beacon.c81
-rw-r--r--cesar/cp/beacon/stub/src/beacon.c18
-rw-r--r--cesar/cp/beacon/test/utest_eoc/Config6
-rw-r--r--cesar/cp/beacon/test/utest_eoc/Makefile15
-rw-r--r--cesar/cp/beacon/test/utest_eoc/ecos.ecc.sh6
-rw-r--r--cesar/cp/beacon/test/utest_eoc/src/beacon.c261
-rw-r--r--cesar/cp/beacon/test/utest_eoc/src/phy_stub.c21
-rw-r--r--cesar/cp/cco/action/inc/cco_action.h16
-rw-r--r--cesar/cp/cco/action/test/Makefile2
-rw-r--r--cesar/cp/cco/action/test/src/sar_stub.c5
-rw-r--r--cesar/cp/cco/bw/test/Makefile1
-rw-r--r--cesar/cp/cco/region/test/Makefile1
-rw-r--r--cesar/cp/cl_interf/src/cl_interf.c2
-rw-r--r--cesar/cp/cl_interf/test/Makefile1
-rw-r--r--cesar/cp/defs.h7
-rw-r--r--cesar/cp/eoc/cco/action/Config2
-rw-r--r--cesar/cp/eoc/cco/action/Module1
-rw-r--r--cesar/cp/eoc/cco/action/bridge.h32
-rw-r--r--cesar/cp/eoc/cco/action/cco_action.h125
-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.h95
-rw-r--r--cesar/cp/eoc/cco/action/misc.h17
-rw-r--r--cesar/cp/eoc/cco/action/src/cco_action.c726
-rw-r--r--cesar/cp/eoc/cco/action/src/vs_eoc.c792
-rw-r--r--cesar/cp/eoc/cco/action/stub/Module1
-rw-r--r--cesar/cp/eoc/cco/action/stub/src/cco_action.c73
-rw-r--r--cesar/cp/eoc/cco/action/stub/src/vs_eoc.c104
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/Config11
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/Makefile11
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/actions-Config27
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/actions-Makefile36
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/fsm-Config12
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/fsm-Makefile19
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/inc/scenario_defs.h304
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/inc/test_cco_action.h56
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h118
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/core.h53
-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/mac/sar/inc/sar_context.h37
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/actions.c141
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/beacon_stub.c30
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/ce_stub.c24
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/cp_eoc_sta_misc_stub.c49
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/cp_stub.c125
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/dataplane_stub.c38
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/events_stub.c76
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/fsm_stub.c534
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/mac_common_store_stub.c582
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/msg_stub.c1160
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/pbproc_stub.c31
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/pwl_stub.c21
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/sta_vs_eoc_stub.c85
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/test_actions.c3598
-rw-r--r--cesar/cp/eoc/cco/action/test/utest/src/test_fsm.c423
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/Config11
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/Makefile26
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/inc/scenario_defs.h139
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/inc/context.h90
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/core.h31
-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/mac/sar/inc/context.h23
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/interface_stub.c27
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/mgr_stub.c65
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/pbproc_stub.c19
-rw-r--r--cesar/cp/eoc/cco/action/test/utest_eoc/src/test_actions.c304
-rw-r--r--cesar/cp/eoc/cco/action/vs_eoc.h60
-rw-r--r--cesar/cp/eoc/cco/bw/Module1
-rw-r--r--cesar/cp/eoc/cco/bw/bw.h73
-rw-r--r--cesar/cp/eoc/cco/bw/doc/bandwidth_scheduler.odtbin0 -> 105290 bytes
-rw-r--r--cesar/cp/eoc/cco/bw/doc/beacon_period.odtbin0 -> 193316 bytes
-rw-r--r--cesar/cp/eoc/cco/bw/inc/bw.h95
-rw-r--r--cesar/cp/eoc/cco/bw/inc/service.h66
-rw-r--r--cesar/cp/eoc/cco/bw/service.h68
-rw-r--r--cesar/cp/eoc/cco/bw/src/bw.c527
-rw-r--r--cesar/cp/eoc/cco/bw/src/service.c144
-rw-r--r--cesar/cp/eoc/cco/bw/stub/Module1
-rw-r--r--cesar/cp/eoc/cco/bw/stub/src/bw.c35
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/Config5
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/Makefile24
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/override/cp/inc/context.h52
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/core.h28
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/defs.h58
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/override/mac/sar/inc/sar_context.h39
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/src/bw_stub.c133
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/src/sched.c198
-rw-r--r--cesar/cp/eoc/cco/bw/test/utest/src/serv.c92
-rw-r--r--cesar/cp/eoc/inc/dbg_print.h41
-rw-r--r--cesar/cp/eoc/multi_sta/action/Config1
-rw-r--r--cesar/cp/eoc/multi_sta/action/Module1
-rw-r--r--cesar/cp/eoc/multi_sta/action/multi_sta_action.h121
-rw-r--r--cesar/cp/eoc/multi_sta/action/src/multi_sta_action.c480
-rw-r--r--cesar/cp/eoc/multi_sta/action/stub/Module1
-rw-r--r--cesar/cp/eoc/multi_sta/action/stub/src/multi_sta_action.c136
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/Makefile11
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/actions-Config13
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/actions-Makefile31
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/inc/context.h85
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/core.h27
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/defs.h57
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h37
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/fsm-Config11
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/fsm-Makefile30
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/inc/context.h88
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/core.h28
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/defs.h57
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h38
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/inc/scenario_defs.h135
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/actions.c41
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/actions_stub.c95
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/beacon_stub.c30
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/ce_stub.c24
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/cp_eoc_sta_misc_stub.c45
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/fsm_stub.c199
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/mgr_stub.c63
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/pb_proc_stub.c34
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/pbproc_stub.c31
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/pwl_stub.c21
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/test_actions.c319
-rw-r--r--cesar/cp/eoc/multi_sta/action/test/utest/src/test_fsm.c119
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/Config1
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/Module40
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/doc/cp_eoc_multi_sta_fsm.odtbin0 -> 180232 bytes
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/forward.h19
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/fsm.h68
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/inc/context.h33
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/inc/events.h74
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/inc/tables.h52
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/events.c71
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/fsm.c158
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.conf6
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm45
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/fsm/template_defs.h53
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/fsm/template_tables.h46
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/src/tables.c25
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/stub/Module3
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/stub/src/fsm_stub.c69
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/Config4
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/Makefile26
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/inc/scenario_defs.h107
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/inc/context.h66
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/core.h28
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/defs.h58
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/override/mac/sar/inc/sar_context.h39
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/src/actions.c37
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/src/fsm_stub.c185
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/src/test_fsm.c287
-rw-r--r--cesar/cp/eoc/multi_sta_fsm/test/utest/src/utest.fsm53
-rw-r--r--cesar/cp/eoc/sta/action/Config1
-rw-r--r--cesar/cp/eoc/sta/action/Module1
-rw-r--r--cesar/cp/eoc/sta/action/action.h119
-rw-r--r--cesar/cp/eoc/sta/action/assoc.h192
-rw-r--r--cesar/cp/eoc/sta/action/bridge.h32
-rw-r--r--cesar/cp/eoc/sta/action/cco_action.h0
-rw-r--r--cesar/cp/eoc/sta/action/doc/Makefile48
-rw-r--r--cesar/cp/eoc/sta/action/doc/assoc.sdl41
-rw-r--r--cesar/cp/eoc/sta/action/doc/cp_eoc_sta_action.odtbin0 -> 249905 bytes
-rw-r--r--cesar/cp/eoc/sta/action/drv.h84
-rw-r--r--cesar/cp/eoc/sta/action/misc.h31
-rw-r--r--cesar/cp/eoc/sta/action/poweron.h32
-rw-r--r--cesar/cp/eoc/sta/action/sleep.h60
-rw-r--r--cesar/cp/eoc/sta/action/src/action.c37
-rw-r--r--cesar/cp/eoc/sta/action/src/assoc.c686
-rw-r--r--cesar/cp/eoc/sta/action/src/cco_stub.c127
-rw-r--r--cesar/cp/eoc/sta/action/src/drv.c423
-rw-r--r--cesar/cp/eoc/sta/action/src/misc.c121
-rw-r--r--cesar/cp/eoc/sta/action/src/poweron.c125
-rw-r--r--cesar/cp/eoc/sta/action/src/sleep.c36
-rw-r--r--cesar/cp/eoc/sta/action/src/vs_eoc.c297
-rw-r--r--cesar/cp/eoc/sta/action/stub/Module1
-rw-r--r--cesar/cp/eoc/sta/action/stub/src/bridge.c43
-rw-r--r--cesar/cp/eoc/sta/action/stub/src/drv.c159
-rw-r--r--cesar/cp/eoc/sta/action/stub/src/poweron.c34
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/Makefile11
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/actions-Config11
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/actions-Makefile31
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/actions-override/cp/inc/context.h85
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/core.h28
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/defs.h57
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h38
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/fsm-Config7
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/fsm-Makefile16
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/inc/context.h35
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/sta/core/core.h26
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h38
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/inc/scenario_defs.h263
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/inc/test_sta_action.h56
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/actions.c119
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/actions_stub.c96
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/beacon_stub.c29
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/bw_stub.c28
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/ce_stub.c24
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/cp_stub.c48
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/dataplane_stub.c28
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/fsm_stub.c637
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/msg_stub.c476
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/pb_proc_stub.c44
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/phy_stub.c26
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/test_actions.c1792
-rw-r--r--cesar/cp/eoc/sta/action/test/utest/src/test_fsm.c685
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/Config8
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/Makefile18
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/inc/context.h73
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/sta/core/core.h43
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/override/mac/sar/inc/context.h23
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/override/mac/sar/inc/sar_context.h37
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/src/assoc.c48
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/src/core_stub.c36
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/src/cp_stub.c48
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/src/mgr_stub.c89
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/src/msg_stub.c72
-rw-r--r--cesar/cp/eoc/sta/action/test/utest_eoc/src/phy_stub.c15
-rw-r--r--cesar/cp/eoc/sta/action/vs_eoc.h50
-rw-r--r--cesar/cp/eoc/sta/mgr/Config1
-rw-r--r--cesar/cp/eoc/sta/mgr/Module1
-rw-r--r--cesar/cp/eoc/sta/mgr/doc/sta_manager.odtbin0 -> 292047 bytes
-rw-r--r--cesar/cp/eoc/sta/mgr/doc/sta_mgr.xmi1832
-rw-r--r--cesar/cp/eoc/sta/mgr/src/sta_mgr.c1184
-rw-r--r--cesar/cp/eoc/sta/mgr/src/sta_own_data.c670
-rw-r--r--cesar/cp/eoc/sta/mgr/sta_mgr.h66
-rw-r--r--cesar/cp/eoc/sta/mgr/test/Config3
-rw-r--r--cesar/cp/eoc/sta/mgr/test/Makefile13
-rw-r--r--cesar/cp/eoc/sta/mgr/test/doc/Makefile20
-rw-r--r--cesar/cp/eoc/sta/mgr/test/doc/net.txt190
-rw-r--r--cesar/cp/eoc/sta/mgr/test/doc/net_list.txt114
-rw-r--r--cesar/cp/eoc/sta/mgr/test/doc/sta.txt44
-rw-r--r--cesar/cp/eoc/sta/mgr/test/doc/sta_mgr.txt14
-rw-r--r--cesar/cp/eoc/sta/mgr/test/doc/sta_own_data.txt111
-rw-r--r--cesar/cp/eoc/sta/mgr/test/overide/cp/cco/action/inc/context.h26
-rw-r--r--cesar/cp/eoc/sta/mgr/test/overide/cp/inc/context.h55
-rw-r--r--cesar/cp/eoc/sta/mgr/test/overide/cp/sta/core/core.h21
-rw-r--r--cesar/cp/eoc/sta/mgr/test/overide/mac/sar/inc/context.h23
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/core_stub.c23
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/net_test.c225
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/sar_stub.c50
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/sta-test.c688
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/sta_mgr.c1695
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/station_test.c428
-rw-r--r--cesar/cp/eoc/sta/mgr/test/src/test_sta_mgr.c136
-rw-r--r--cesar/cp/eoc/sta/mgr/test/test_sta_mgr.h54
-rw-r--r--cesar/cp/fsm/Config1
-rw-r--r--cesar/cp/fsm/src/fsm.c17
-rw-r--r--cesar/cp/fsm/src/fsm/cp_eoc_cco.fsm211
-rw-r--r--cesar/cp/fsm/src/fsm/cp_eoc_sta.fsm248
-rw-r--r--cesar/cp/fsm/src/tables.c10
-rw-r--r--cesar/cp/fsm/test/utest/Makefile1
-rw-r--r--cesar/cp/inc/context.h6
-rw-r--r--cesar/cp/inc/trace.h4
-rw-r--r--cesar/cp/mme.h489
-rw-r--r--cesar/cp/msg/Config3
-rw-r--r--cesar/cp/msg/Module5
-rw-r--r--cesar/cp/msg/inc/cc_assoc.h3
-rw-r--r--cesar/cp/msg/inc/msg_drv.h37
-rw-r--r--cesar/cp/msg/inc/msg_vs_eoc.h247
-rw-r--r--cesar/cp/msg/inc/vs_eoc_get_topo.h27
-rw-r--r--cesar/cp/msg/msg.h7
-rw-r--r--cesar/cp/msg/src/msg.c100
-rw-r--r--cesar/cp/msg/src/msg_cm.c5
-rw-r--r--cesar/cp/msg/src/msg_drv.c103
-rw-r--r--cesar/cp/msg/src/msg_vs_eoc.c626
-rw-r--r--cesar/cp/msg/stub/Module4
-rw-r--r--cesar/cp/msg/stub/src/msg_cc.c6
-rw-r--r--cesar/cp/msg/stub/src/msg_drv.c49
-rw-r--r--cesar/cp/msg/stub/src/msg_vs_eoc.c207
-rw-r--r--cesar/cp/msg/test/Config1
-rw-r--r--cesar/cp/msg/test/Makefile3
-rw-r--r--cesar/cp/msg/test/src/cc_discover_list.c12
-rw-r--r--cesar/cp/msg/test/src/mme_frag.c7
-rw-r--r--cesar/cp/msg/test_eoc/Config7
-rw-r--r--cesar/cp/msg/test_eoc/Makefile30
-rw-r--r--cesar/cp/msg/test_eoc/doc/Makefile20
-rw-r--r--cesar/cp/msg/test_eoc/doc/read-header.txt67
-rw-r--r--cesar/cp/msg/test_eoc/overide/cp/inc/context.h71
-rw-r--r--cesar/cp/msg/test_eoc/overide/mac/sar/inc/context.h23
-rw-r--r--cesar/cp/msg/test_eoc/src/interface_stub.c27
-rw-r--r--cesar/cp/msg/test_eoc/src/msg_cc_eoc.c133
-rw-r--r--cesar/cp/msg/test_eoc/src/msg_vs_eoc.c316
-rw-r--r--cesar/cp/pwl/Config1
-rw-r--r--cesar/cp/pwl/pwl.h181
-rw-r--r--cesar/cp/pwl/src/pwl.c377
-rw-r--r--cesar/cp/src/cp.c13
-rw-r--r--cesar/cp/src/trace.c66
-rw-r--r--cesar/cp/sta/action/Config1
-rw-r--r--cesar/cp/sta/action/inc/context.h6
-rw-r--r--cesar/cp/sta/action/src/bridge.c3
-rw-r--r--cesar/cp/sta/action/src/misc.c7
-rw-r--r--cesar/cp/sta/action/test/utest/Makefile2
-rw-r--r--cesar/cp/sta/action/test/utest/src/sc.c25
-rw-r--r--cesar/cp/sta/core/core.h10
-rw-r--r--cesar/cp/sta/core/inc/core.h4
-rw-r--r--cesar/cp/sta/core/src/core.c42
-rw-r--r--cesar/cp/sta/core/test/Makefile.mk4
-rw-r--r--cesar/cp/sta/mgr/Config3
-rw-r--r--cesar/cp/sta/mgr/inc/sta_mgr.h1
-rw-r--r--cesar/cp/sta/mgr/inc/sta_own_data.h46
-rw-r--r--cesar/cp/sta/mgr/src/sta.c11
-rw-r--r--cesar/cp/sta/mgr/src/sta_own_data.c3
-rw-r--r--cesar/cp/sta/mgr/sta.h69
-rw-r--r--cesar/cp/sta/mgr/sta_mgr.h24
-rw-r--r--cesar/cp/sta/mgr/sta_own_data.h16
-rw-r--r--cesar/cp/sta/mgr/test/src/sta_mgr.c1
-rw-r--r--cesar/ecos/packages/hal/common/current/cdl/interrupts.cdl2
-rw-r--r--cesar/ecos/packages/kernel/current/src/common/thread.cxx169
-rw-r--r--cesar/hal/leon/watchdog.h4
-rw-r--r--cesar/hal/phy/Module2
-rw-r--r--cesar/hal/phy/defs.h5
-rw-r--r--cesar/hal/phy/inc/phy_params.txt2
-rw-r--r--cesar/hal/phy/inc/regs.h10
-rw-r--r--cesar/hal/phy/maximus/dur/test/Config1
-rw-r--r--cesar/hal/phy/maximus/dur/test/Makefile1
-rw-r--r--cesar/hal/phy/maximus/inc/maximus_phy_ctx.h2
-rw-r--r--cesar/hal/phy/maximus/src/maximus_phy_ctrl.c32
-rw-r--r--cesar/hal/phy/phy.h23
-rw-r--r--cesar/hal/phy/spoc/Module2
-rw-r--r--cesar/hal/phy/spoc/inc/utils.h30
-rw-r--r--cesar/hal/phy/spoc/spoc.h4
-rw-r--r--cesar/hal/phy/spoc/src/spoc.c3
-rw-r--r--cesar/hal/phy/spoc/src/spoc_regs.c24
-rw-r--r--cesar/hal/phy/spoc/test/Makefile16
-rw-r--r--cesar/hal/phy/spoc/test/src/spoc_coeff_check.c13
-rw-r--r--cesar/hal/phy/spoc/test/src/test_spoc.c91
-rw-r--r--cesar/hal/phy/src/phy.c16
-rw-r--r--cesar/hal/phy/src/rx.c9
-rw-r--r--cesar/hal/phy/src/tx.c18
-rw-r--r--cesar/hal/phy/test/bridgedma/Makefile.mk1
-rw-r--r--cesar/hle/src/hle.c8
-rw-r--r--cesar/interface/sniffer/test/Makefile1
-rw-r--r--cesar/interface/test/sparc-Makefile1
-rw-r--r--cesar/interface/test/synth-Makefile1
-rw-r--r--cesar/lib/Config1
-rw-r--r--cesar/lib/blk.h8
-rw-r--r--cesar/lib/src/blk.c6
-rw-r--r--cesar/lib/test/trace/Makefile1
-rw-r--r--cesar/lib/utils.h8
-rw-r--r--cesar/mac/ca/ca.h64
-rw-r--r--cesar/mac/ca/inc/alloc.h9
-rw-r--r--cesar/mac/ca/inc/context.h6
-rw-r--r--cesar/mac/ca/src/access.c286
-rw-r--r--cesar/mac/ca/src/alloc.c7
-rw-r--r--cesar/mac/ca/src/ca.c16
-rw-r--r--cesar/mac/ca/test/ca/src/phy_stub.c1
-rw-r--r--cesar/mac/ca/test/ca_eoc/Config6
-rw-r--r--cesar/mac/ca/test/ca_eoc/Makefile8
-rw-r--r--cesar/mac/ca/test/ca_eoc/inc/phy_stub.h23
-rw-r--r--cesar/mac/ca/test/ca_eoc/src/test_access.c551
-rw-r--r--cesar/mac/ca/test/ca_eoc/src/test_alloc.c444
-rw-r--r--cesar/mac/ca/test/ca_eoc/src/test_ca.c39
-rw-r--r--cesar/mac/common/Config5
-rw-r--r--cesar/mac/common/defs.h45
-rw-r--r--cesar/mac/common/mfs.h17
-rw-r--r--cesar/mac/common/src/mfs.c22
-rw-r--r--cesar/mac/common/src/sta.c6
-rw-r--r--cesar/mac/common/src/store.c164
-rw-r--r--cesar/mac/common/src/tonemap.c3
-rw-r--r--cesar/mac/common/src/tonemask.c18
-rw-r--r--cesar/mac/common/sta.h16
-rw-r--r--cesar/mac/common/store.h57
-rw-r--r--cesar/mac/common/test/store/Config3
-rw-r--r--cesar/mac/common/test/store/override/mac/common/mfs.h1
-rw-r--r--cesar/mac/common/test/store/override/mac/common/sta.h1
-rw-r--r--cesar/mac/common/test/store/src/test_store.c87
-rw-r--r--cesar/mac/common/test/tonemap/Config1
-rw-r--r--cesar/mac/common/test/tonemap/src/test_tonemap.c16
-rw-r--r--cesar/mac/common/timings.h6
-rw-r--r--cesar/mac/common/tonemap.h6
-rw-r--r--cesar/mac/pbproc/Config3
-rw-r--r--cesar/mac/pbproc/inc/context.h20
-rw-r--r--cesar/mac/pbproc/inc/fc.h213
-rw-r--r--cesar/mac/pbproc/inc/fsm_rx_data.h4
-rw-r--r--cesar/mac/pbproc/inc/prep_mpdu.h34
-rw-r--r--cesar/mac/pbproc/inc/trace.h5
-rw-r--r--cesar/mac/pbproc/pbproc.h15
-rw-r--r--cesar/mac/pbproc/src/fsm.c10
-rw-r--r--cesar/mac/pbproc/src/fsm_handle_fc.c78
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_beacon.c4
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_data.c401
-rw-r--r--cesar/mac/pbproc/src/fsm_rx_sound.c86
-rw-r--r--cesar/mac/pbproc/src/fsm_top.c6
-rw-r--r--cesar/mac/pbproc/src/fsm_tx_data.c93
-rw-r--r--cesar/mac/pbproc/src/fsm_tx_sound.c25
-rw-r--r--cesar/mac/pbproc/src/pbproc.c39
-rw-r--r--cesar/mac/pbproc/src/prep_mpdu.c507
-rw-r--r--cesar/mac/pbproc/src/trace.c68
-rw-r--r--cesar/mac/pbproc/test/fsm/Makefile1
-rw-r--r--cesar/mac/pbproc/test/int/maximus-Config3
-rw-r--r--cesar/mac/pbproc/test/int/maximus-Makefile1
-rw-r--r--cesar/mac/pbproc/test/int/sparc-Config3
-rw-r--r--cesar/mac/pbproc/test/int/sparc-Makefile1
-rw-r--r--cesar/mac/pbproc/test/int/src/test_pbproc.c9
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/Config6
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/Makefile13
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/inc/scenario_defs.h346
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/inc/test_pbproc.h93
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/inc/utils.h81
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/ca.c169
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/hal.c27
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/phy.c363
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/prep_mpdu.c1847
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/rx_data.c1782
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c331
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/scenario_defs.c166
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/test_pbproc.c512
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/tx_data.c1155
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/tx_sound.c364
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/utils.c253
-rw-r--r--cesar/mac/sar/Config3
-rw-r--r--cesar/mac/sar/inc/sar.h6
-rw-r--r--cesar/mac/sar/inc/sar_context.h10
-rw-r--r--cesar/mac/sar/sar_mf.h3
-rw-r--r--cesar/mac/sar/src/sar.c191
-rw-r--r--cesar/mac/sar/src/sar_expiration.c18
-rw-r--r--cesar/mac/sar/src/sar_mf.c22
-rw-r--r--cesar/mac/sar/src/trace.c6
-rw-r--r--cesar/mac/sar/stub/src/sar.c18
-rw-r--r--cesar/mac/sar/test/functional/host-Config3
-rw-r--r--cesar/mac/sar/test/functional/sparc-Config3
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c3
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/misc.c3
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/msdu_timeout.c82
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/reassembly.c1
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/segmentation.c49
-rw-r--r--cesar/mac/sar/test/unit_test/host/Makefile1
-rw-r--r--cesar/maximus/common/types/phy_types.h4
-rw-r--r--cesar/maximus/common/types/sci_types.h2
-rw-r--r--cesar/maximus/phy/src/PhySciMsg.cpp9
-rw-r--r--cesar/maximus/python/maximus/station/sta.py5
-rw-r--r--cesar/projects/eoc/Makefile16
-rw-r--r--cesar/projects/eoc/master-Config48
-rw-r--r--cesar/projects/eoc/master-Makefile25
-rw-r--r--cesar/projects/eoc/master-ecos.ecc.sh5
-rw-r--r--cesar/projects/eoc/slave-Config35
-rw-r--r--cesar/projects/eoc/slave-Makefile22
-rw-r--r--cesar/projects/eoc/slave-ecos.ecc.sh5
-rw-r--r--cesar/projects/eoc/src/eoc.c24
-rw-r--r--cesar/station/src/station.c9
-rw-r--r--cesar/test_general/maximus/integration/cl-sar-pbproc/Makefile4
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Config9
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Makefile16
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/doc/test1.txt76
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/ecos.ecc.sh5
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/override/cp/msg/inc/vs_eoc_get_topo.h31
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/src/station.c1534
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_2sta_bc.py153
-rw-r--r--cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_multista.py236
-rw-r--r--cesar/test_general/maximus/integration/hle-cl-sar-pbproc/Makefile4
-rw-r--r--cesar/test_general/maximus/integration/interface-dp/Makefile2
-rw-r--r--cesar/test_general/maximus/integration/ipmbox-hle-cl-sar-pbproc/Makefile1
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/Config4
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/Makefile14
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/doc/test1.txt76
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/ecos.ecc.sh5
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/src/station.c1386
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test1.py128
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test2.py100
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta.py142
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_bc.py154
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_csmaonly.py140
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2stasound.py149
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta.py230
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta1bad.py167
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_multista.py231
-rw-r--r--cesar/test_general/maximus/integration/sar-pbproc/Makefile3
-rw-r--r--cesar/test_general/station/cco0/s2/Config1
-rw-r--r--cesar/test_general/station/common_eoc/Module1
-rw-r--r--cesar/test_general/station/common_eoc/src/station.c162
-rw-r--r--cesar/test_general/station/compliance-eoc/Makefile25
-rw-r--r--cesar/test_general/station/compliance-eoc/Makefile-cco.mk21
-rw-r--r--cesar/test_general/station/compliance-eoc/Makefile-sta.mk19
-rw-r--r--cesar/test_general/station/compliance-eoc/board-cco-Config47
-rw-r--r--cesar/test_general/station/compliance-eoc/board-cco-Makefile7
-rw-r--r--cesar/test_general/station/compliance-eoc/board-cco-ecos.ecc.sh5
-rw-r--r--cesar/test_general/station/compliance-eoc/board-sta-Config42
-rw-r--r--cesar/test_general/station/compliance-eoc/board-sta-Makefile7
-rw-r--r--cesar/test_general/station/compliance-eoc/board-sta-ecos.ecc.sh5
-rw-r--r--cesar/test_general/station/compliance-eoc/py/sc01_dut_as_a_cco.py96
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_cco.py95
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_sta.py94
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test02_eoc_beacon.py113
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test03_eoc_init_cco_sta.py85
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test04_avln_start_stop.py95
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test05_eoc_init_cco_multista.py182
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test06_eoc_change_nek.py101
-rw-r--r--cesar/test_general/station/compliance-eoc/py/test07_eoc_startup.py87
-rw-r--r--cesar/test_general/station/compliance-eoc/py/trace.py29
-rw-r--r--cesar/test_general/station/compliance-eoc/simu-cco-Config35
-rw-r--r--cesar/test_general/station/compliance-eoc/simu-cco-Makefile5
-rw-r--r--cesar/test_general/station/compliance-eoc/simu-cco-ecos.ecc.sh5
-rw-r--r--cesar/test_general/station/compliance-eoc/simu-sta-Config28
-rw-r--r--cesar/test_general/station/compliance-eoc/simu-sta-Makefile5
-rw-r--r--cesar/test_general/station/compliance-eoc/simu-sta-ecos.ecc.sh5
-rw-r--r--cesar/test_general/station/compliance/Makefile5
-rw-r--r--cesar/test_general/station/fcall/src/beacon.c2
-rw-r--r--cesar/test_general/station/vs_eoc/py/vs_eoc_get_topo.py175
-rw-r--r--cesar/tools/sniffer_phy/Config3
-rw-r--r--cesar/tools/sniffer_phy/Makefile4
-rw-r--r--cesar/tools/sniffer_phy/src/lowlevel.c9
-rw-r--r--cesar/tools/sniffer_phy/src/mme.c75
-rw-r--r--cesar/tools/sniffer_phy/src/test_mme.c9
550 files changed, 55671 insertions, 994 deletions
diff --git a/cesar/bsu/Config b/cesar/bsu/Config
new file mode 100644
index 0000000000..16343c68f5
--- /dev/null
+++ b/cesar/bsu/Config
@@ -0,0 +1,2 @@
+CONFIG_BSU_ACLF_EOC = n
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = n \ No newline at end of file
diff --git a/cesar/bsu/aclf/aclf.h b/cesar/bsu/aclf/aclf.h
index 1041f5511c..bf0574dc5f 100644
--- a/cesar/bsu/aclf/aclf.h
+++ b/cesar/bsu/aclf/aclf.h
@@ -31,6 +31,7 @@ enum bsu_aclf_frequency_t
BSU_ACLF_FREQ_UNKNOWN,
BSU_ACLF_FREQ_50HZ,
BSU_ACLF_FREQ_60HZ,
+ BSU_ACLF_FREQ_20HZ,
BSU_ACLF_FREQ_CABLE,
BSU_ACLF_FREQ_NB
};
@@ -41,7 +42,8 @@ enum bsu_aclf_bp_t
{
BSU_ACLF_BP_50HZ_TCK = 1000000,
BSU_ACLF_BP_55HZ_TCK = 909090,
- BSU_ACLF_BP_60HZ_TCK = 833333
+ BSU_ACLF_BP_60HZ_TCK = 833333,
+ BSU_ACLF_BP_20HZ_TCK = 2500000
};
typedef enum bsu_aclf_bp_t bsu_aclf_bp_t;
@@ -229,6 +231,14 @@ void
bsu_aclf_bpsd_avoid_overlap (bsu_aclf_t *ctx);
/**
+ * ACLF should extend beacon period
+ * \param ctx the module context.
+ * \param status true to start, false stop.
+ */
+void
+bsu_aclf_beacon_skew (bsu_aclf_t *ctx, bool status);
+
+/**
* Clear all data in BSU ACLF.
* \param ctx the module context.
*/
diff --git a/cesar/bsu/aclf/src/aclf.c b/cesar/bsu/aclf/src/aclf.c
index 56e4e203be..6857ec9fc9 100644
--- a/cesar/bsu/aclf/src/aclf.c
+++ b/cesar/bsu/aclf/src/aclf.c
@@ -15,6 +15,7 @@
#include "common/std.h"
#include "mac/common/timings.h"
#include "bsu/aclf/aclf.h"
+#include "config/bsu/aclf/eoc.h"
#include <string.h>
#include "config/aclf.h"
@@ -41,6 +42,9 @@ bsu_aclf_set_frequency (bsu_aclf_t *ctx, bsu_aclf_frequency_t freq)
else
*((bsu_aclf_bp_t*) &ctx->beacon_period_theo_tck) =
BSU_ACLF_BP_50HZ_TCK;
+ if (CONFIG_BSU_ACLF_EOC)
+ *((bsu_aclf_bp_t*) &ctx->beacon_period_theo_tck) =
+ BSU_ACLF_BP_20HZ_TCK;
}
/**
@@ -94,31 +98,36 @@ bsu_aclf_truncate_beacon_period (bsu_aclf_t *ctx)
void
bsu_aclf_track_powerline (bsu_aclf_t *ctx)
{
- u32 cross_date = phy_clock_get_zero_cross_captured_date (ctx->phy);
- if (ctx->pwl_sync.trig_present && ctx->pwl_sync.init)
+ if (!CONFIG_BSU_ACLF_EOC)
{
- uint hinterval_tck = ctx->pwl_sync.cross_interval_tck / 2;
- dbg_assert (hinterval_tck);
- uint diff_tck = cross_date - ctx->pwl_sync.cross_date;
- uint nb_cross = (diff_tck + hinterval_tck / 2) / hinterval_tck;
- /* Compute the estimated cross. */
- ctx->pwl_sync.cross_est_date +=
- ctx->pwl_sync.w_err_tck + nb_cross * hinterval_tck;
- int err_tck = cross_date - ctx->pwl_sync.cross_est_date;
- ctx->pwl_sync.w_err_tck =
- (err_tck >> BSU_ACLF_PWL_E0)
- + (ctx->pwl_sync.w_err_tck >> BSU_ACLF_PWL_W0);
- ctx->pwl_sync.cross_date = cross_date;
- ctx->pwl_sync.cross_interval_tck += ctx->pwl_sync.w_err_tck;
+ u32 cross_date = phy_clock_get_zero_cross_captured_date (ctx->phy);
+ if (ctx->pwl_sync.trig_present && ctx->pwl_sync.init)
+ {
+ uint hinterval_tck = ctx->pwl_sync.cross_interval_tck / 2;
+ dbg_assert (hinterval_tck);
+ uint diff_tck = cross_date - ctx->pwl_sync.cross_date;
+ uint nb_cross = (diff_tck + hinterval_tck / 2) / hinterval_tck;
+ /* Compute the estimated cross. */
+ ctx->pwl_sync.cross_est_date +=
+ ctx->pwl_sync.w_err_tck + nb_cross * hinterval_tck;
+ int err_tck = cross_date - ctx->pwl_sync.cross_est_date;
+ ctx->pwl_sync.w_err_tck =
+ (err_tck >> BSU_ACLF_PWL_E0)
+ + (ctx->pwl_sync.w_err_tck >> BSU_ACLF_PWL_W0);
+ ctx->pwl_sync.cross_date = cross_date;
+ ctx->pwl_sync.cross_interval_tck += ctx->pwl_sync.w_err_tck;
+ }
+ else
+ {
+ /* Simply initialise the PLL for the next step. */
+ ctx->pwl_sync.cross_date = cross_date;
+ ctx->pwl_sync.cross_est_date = cross_date;
+ ctx->pwl_sync.w_err_tck = 0;
+ ctx->pwl_sync.init = true;
+ }
}
else
- {
- /* Simply initialise the PLL for the next step. */
- ctx->pwl_sync.cross_date = cross_date;
- ctx->pwl_sync.cross_est_date = cross_date;
- ctx->pwl_sync.w_err_tck = 0;
- ctx->pwl_sync.init = true;
- }
+ ctx->beacon_period_tck = ctx->beacon_period_theo_tck;
}
void
@@ -131,9 +140,15 @@ bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx)
/* For the last beacon period start date, add the difference of the
* previous one, this should help the station to keep a
* synchronisation near the CCo's clock even if it miss 5 beacons. */
- ctx->bpsd[BSU_ACLF_BPSD_NB - 1] +=
- ctx->bpsd[BSU_ACLF_BPSD_NB - 2] - ctx->bpsd[BSU_ACLF_BPSD_NB - 3];
- ctx->beacon_period_tck = ctx->bpsd[1] - ctx->bpsd[0];
+ if (!CONFIG_BSU_ACLF_EOC)
+ {
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 1] +=
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 2] - ctx->bpsd[BSU_ACLF_BPSD_NB - 3];
+ ctx->beacon_period_tck = ctx->bpsd[1] - ctx->bpsd[0];
+ }
+ else
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 1] =
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 2] + ctx->beacon_period_theo_tck;
}
void
@@ -144,13 +159,18 @@ bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx)
u32 bts;
int bto;
- if (ctx->pwl_sync.trig_present)
- ctx->beacon_period_tck = ctx->pwl_sync.cross_interval_tck;
- bsu_aclf_truncate_beacon_period (ctx);
+ if (!CONFIG_BSU_ACLF_EOC)
+ {
+ if (ctx->pwl_sync.trig_present)
+ ctx->beacon_period_tck = ctx->pwl_sync.cross_interval_tck;
+ bsu_aclf_truncate_beacon_period (ctx);
+ }
+ else
+ ctx->beacon_period_tck = ctx->beacon_period_theo_tck;
/* First time the function is called. */
if (ctx->bpsd[0] == ctx->bpsd[1])
{
- if (ctx->pwl_sync.trig_present)
+ if (!CONFIG_BSU_ACLF_EOC && ctx->pwl_sync.trig_present)
ctx->bpsd[0] = ctx->pwl_sync.cross_est_date;
else
ctx->bpsd[0] = phy_date ();
@@ -164,7 +184,8 @@ bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx)
ctx->bpsd[i] = ctx->bpsd[i+1];
/* Add on the last beacon period start date the beacon period
* estimated. */
- if (ctx->beacon_period_tck == ctx->pwl_sync.cross_interval_tck)
+ if (!CONFIG_BSU_ACLF_EOC
+ && ctx->beacon_period_tck == ctx->pwl_sync.cross_interval_tck)
{
uint pwl_cross_tck = ctx->beacon_period_tck / 2;
u32 bpsd_last = ctx->pwl_sync.cross_est_date
@@ -260,8 +281,16 @@ bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx)
/* No 0_cross activity, means medium is a cable. */
else
{
- bsu_aclf_set_frequency (ctx, BSU_ACLF_FREQ_CABLE);
- ctx->beacon_period_tck = BSU_ACLF_BP_50HZ_TCK;
+ if (!CONFIG_BSU_ACLF_EOC)
+ {
+ bsu_aclf_set_frequency (ctx, BSU_ACLF_FREQ_CABLE);
+ ctx->beacon_period_tck = BSU_ACLF_BP_50HZ_TCK;
+ }
+ else
+ {
+ bsu_aclf_set_frequency (ctx, BSU_ACLF_FREQ_20HZ);
+ ctx->beacon_period_tck = ctx->beacon_period_theo_tck;
+ }
}
bsu_aclf_truncate_beacon_period (ctx);
}
@@ -363,3 +392,12 @@ bsu_aclf_bpsd_avoid_overlap (bsu_aclf_t *ctx)
ctx->bpsd[i] = ctx->bpsd[i+1];
ctx->bpsd[i] += ctx->beacon_period_theo_tck;
}
+
+void
+bsu_aclf_beacon_skew (bsu_aclf_t *ctx, bool status)
+{
+ bsu_aclf_set_frequency (ctx, BSU_ACLF_FREQ_20HZ);
+ if (status)
+ *((bsu_aclf_bp_t*) &ctx->beacon_period_theo_tck) += MAC_MS_TO_TCK (7);
+ ctx->beacon_period_tck = ctx->beacon_period_theo_tck;
+}
diff --git a/cesar/bsu/aclf/test/utest/Config b/cesar/bsu/aclf/test/utest/Config
index 7e0f77a8bb..ce218923ce 100644
--- a/cesar/bsu/aclf/test/utest/Config
+++ b/cesar/bsu/aclf/test/utest/Config
@@ -1,3 +1,5 @@
CONFIG_TRACE = y
CONFIG_STATS = y
CONFIG_ACLF_SYNC_TO_SLOWER_WEIGHT_NB=1000000
+CONFIG_ATU_FACTOR = 3
+CONFIG_BSU_ACLF_EOC = n
diff --git a/cesar/bsu/aclf/test/utest/Makefile b/cesar/bsu/aclf/test/utest/Makefile
index b9c10002e8..19e3fc86ef 100644
--- a/cesar/bsu/aclf/test/utest/Makefile
+++ b/cesar/bsu/aclf/test/utest/Makefile
@@ -3,5 +3,6 @@ BASE = ../../../..
HOST_PROGRAMS = aclf
aclf_SOURCES = aclf.c common.c bpsd.c freq.c
aclf_MODULES = lib bsu/aclf hal/timer/stub
+aclf_CONFIG_MODULES = mac/common bsu
include $(BASE)/common/make/top.mk
diff --git a/cesar/bsu/beacon/src/beacon.c b/cesar/bsu/beacon/src/beacon.c
index 67ebf18342..ae21d2e969 100644
--- a/cesar/bsu/beacon/src/beacon.c
+++ b/cesar/bsu/beacon/src/beacon.c
@@ -17,6 +17,7 @@
#include "lib/bitstream.h"
#include "bsu/beacon/beacon.h"
#include "cp/defs.h"
+#include "config/bsu/beacon.h"
/**
* Reset the schedules data.
@@ -489,8 +490,8 @@ bsu_beacon_write_bmi_mac_address (bitstream_t *stream,
PRIVATE inline uint
bsu_beacon_write_nbe_nb (bsu_beacon_t *beacon)
{
- uint nbe = 1;
- dbg_assert (beacon->bmis.region.nb);
+ uint nbe = (beacon->bmis.region.nb) ? 1 : 0;
+ dbg_assert (beacon->bmis.region.nb || CONFIG_BSU_BEACON_EOC_SPC_CENTRAL);
dbg_assert ((beacon->vf.bt == BSU_BEACON_TYPE_DISCOVER &&
beacon->bmis.discover_info.present)
|| beacon->vf.bt != BSU_BEACON_TYPE_DISCOVER);
@@ -546,7 +547,8 @@ bsu_beacon_write_beacon_entries (bsu_beacon_t *beacon, bitstream_t *stream,
data);
bsu_beacon_write_bmi_persistent (stream, &beacon->bmis.ps,
data);
- bsu_beacon_write_bmi_region (stream, &beacon->bmis.region);
+ if (beacon->bmis.region.nb)
+ bsu_beacon_write_bmi_region (stream, &beacon->bmis.region);
bsu_beacon_write_bmi_mac_address (
stream, &beacon->bmis.mac_address);
bsu_beacon_write_bmi_discover (
@@ -636,6 +638,8 @@ bsu_beacon_read_variant_fields (pb_beacon_t *phy_beacon,
beacon->vf.hoip = bitstream_read (stream, 1);
beacon->vf.rtsbf = bitstream_read (stream, 1);
beacon->vf.nm = bitstream_read (stream, 2);
+ if (CONFIG_BSU_BEACON_EOC_SPC_CENTRAL)
+ beacon->vf.nm = BSU_BEACON_NM_COORDINATED;
beacon->vf.ccocap = bitstream_read (stream, 2);
bitstream_skip (stream, 4);
if ((beacon->vf.bt < BSU_BEACON_TYPE_NB)
@@ -996,7 +1000,7 @@ bsu_beacon_read (pb_beacon_t *pbbeacon, bsu_beacon_t *beacon)
* present. */
if (ok
&& !((beacon->vf.bt == BSU_BEACON_TYPE_CENTRAL)
- && (beacon->bmis.region.nb != 0)
+ && (beacon->bmis.region.nb != 0 || CONFIG_BSU_BEACON_EOC_SPC_CENTRAL)
&& (beacon->bmis.nps.ns != 0 || beacon->bmis.ps.nb != 0)
&& (((beacon->vf.nm == BSU_BEACON_NM_CSMA_ONLY)
&& (beacon->bmis.bpsto.present == true))
diff --git a/cesar/bsu/beacon/test/utest/Config b/cesar/bsu/beacon/test/utest/Config
new file mode 100644
index 0000000000..25a982be10
--- /dev/null
+++ b/cesar/bsu/beacon/test/utest/Config
@@ -0,0 +1,2 @@
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = n
+
diff --git a/cesar/bsu/beacon/test/utest/Makefile b/cesar/bsu/beacon/test/utest/Makefile
index 50de64f980..a44e0a0609 100644
--- a/cesar/bsu/beacon/test/utest/Makefile
+++ b/cesar/bsu/beacon/test/utest/Makefile
@@ -3,5 +3,6 @@ BASE = ../../../..
HOST_PROGRAMS = beacon
beacon_SOURCES = test.c beacon.c
beacon_MODULES = lib bsu/beacon mac/common
+beacon_CONFIG_MODULES = bsu
include $(BASE)/common/make/top.mk
diff --git a/cesar/bsu/bsu.h b/cesar/bsu/bsu.h
index cedb08a40c..cf60cfde44 100644
--- a/cesar/bsu/bsu.h
+++ b/cesar/bsu/bsu.h
@@ -140,6 +140,13 @@ uint
bsu_nek_index_next (bsu_t *ctx);
/**
+ * Adjust current value of index.
+ * \param nek_index index to be applied.
+ */
+void
+bsu_nek_index_adjust (uint nek_index);
+
+/**
* Update discover info beacon entry.
* \param ctx the module context.
* \param discover the discover info beacon entry.
diff --git a/cesar/bsu/inc/context.h b/cesar/bsu/inc/context.h
index 02f64e30a2..ec25ae908a 100644
--- a/cesar/bsu/inc/context.h
+++ b/cesar/bsu/inc/context.h
@@ -132,6 +132,8 @@ struct bsu_t
/** Statistics. */
bsu_stats_t stats;
#endif
+ /** Retrieved information from the beacon of the tracked AVLN */
+ bool avln_tracked;
};
#endif /* bsu_inc_context_h */
diff --git a/cesar/bsu/ntb/ntb.h b/cesar/bsu/ntb/ntb.h
index 3b1ff5e778..b18c487126 100644
--- a/cesar/bsu/ntb/ntb.h
+++ b/cesar/bsu/ntb/ntb.h
@@ -22,7 +22,7 @@
BEGIN_DECLS
-/*
+/**
* Synchronize local clock to be as close as possible to estimated value
* of the NTB clock reference.
* \param ctx the module context data.
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index ccbf601f35..77cdaf9936 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -31,6 +31,8 @@
#include <string.h>
#include "hal/arch/arch.h"
#include "mac/pbproc/pbproc.h"
+#include "cp/sta/core/core.h"
+
/* Define the process invalid value. */
#define BSU_MERGE_PROCESS_INVALID 0xff
@@ -45,6 +47,17 @@
static bsu_t bsu_global;
/**
+ * EoC scheduler. Should be called in each beacon period.
+ * \param user_data cp context.
+ */
+void
+cp_eoc_scheduler_prepare (void * user_data) __attribute__ ((weak));
+
+void
+cp_eoc_scheduler_prepare (void * user_data)
+{
+}
+/**
* Store the values computed into the stats.
* \param ctx the module context.
*
@@ -127,6 +140,9 @@ bsu_track_avln_identify (bsu_t *ctx, bsu_avln_t *avln)
ctx->tei_track = avln->beacon.vf.stei;
ctx->cco_mac_address_track = avln->cco_mac_address;
ctx->sta_avln = avln;
+ bsu_aclf_beacon_skew (ctx->aclf, false);
+ ctx->track_new = true;
+ ctx->avln_tracked = false;
}
else
{
@@ -141,8 +157,8 @@ bsu_track_avln_identify (bsu_t *ctx, bsu_avln_t *avln)
/* When the CCo starts it must keep the ntb offset tck of the network.
*/
ctx->poweron.sync.ntb_offset_tck = old_avln->sync.ntb_offset_tck;
+ bsu_aclf_beacon_skew (ctx->aclf, true);
}
- ctx->track_new = true;
}
/**
@@ -754,13 +770,14 @@ bsu_timer_event_process (void *ud)
{
dbg_assert (ctx);
u32 bpsd0;
+ cp_sta_core_refresh_watch_dog (ctx->ul_data);
bsu_aclf_beacon_period_start_date (ctx->aclf, &bpsd0, 1);
dbg_assert (
less_mod2p32 (phy_date (),
bsu_aclf_beacon_period_start_date_next(ctx->aclf)));
if (ctx->is_sta == BSU_UPDATE_STA_TYPE_STA)
{
- if (ctx->track_new)
+ if (ctx->track_new && ctx->avln_tracked)
{
u32 bpsd[BSU_BEACON_SCHEDULES_NB];
uint bp = bsu_aclf_beacon_period_tck (ctx->aclf);
@@ -813,6 +830,7 @@ bsu_timer_event_process (void *ud)
&ctx->sta_avln->sync, ctx->mac_config, ctx->phy);
ctx->track_new = false;
}
+ cp_eoc_scheduler_prepare (ctx->ul_data);
/* Inform PBProc we send a central beacon. */
pbproc_beacon_detected (
ctx->pbproc,
@@ -987,7 +1005,7 @@ bsu_beacon_process__avln_tracked (bsu_t *ctx, bsu_beacon_t *beacon,
ctx->sta_avln->bto[i] = params->bto[i];
bts_date = params->bts - ctx->sta_avln->sync.ntb_offset_tck;
bsu_aclf_beacon_period_start_date (ctx->aclf, &bpsd0, 1);
- if (ctx->track_new == false && less_mod2p32 (bpsd0, bts_date))
+ if (ctx->track_new == false)
{
bsu_aclf_compute_beacon_period_start_date (
ctx->aclf, bts_date, (s16*) params->bto,
@@ -1009,6 +1027,7 @@ bsu_beacon_process__avln_tracked (bsu_t *ctx, bsu_beacon_t *beacon,
bsu_beacon_send_prepare (ctx, BSU_BEACON_TYPE_DISCOVER, beacon);
ctx->sta_avln->beacon.beacon_period_start_date = bts_date;
bsu_stats_store (ctx);
+ ctx->avln_tracked = true;
return ctx->sta_avln;
}
@@ -1255,6 +1274,7 @@ bsu_untrack_avln (bsu_t *ctx)
arch_dsr_unlock ();
}
+
void
bsu_power_on (bsu_t *ctx, u8 snid)
{
@@ -1300,6 +1320,13 @@ bsu_activate (bsu_t *ctx, bool status)
arch_dsr_unlock ();
}
+void
+bsu_nek_index_adjust (uint nek_index)
+{
+ bsu_t *ctx = &bsu_global;
+ ctx->nek_switch = nek_index;
+}
+
uint
bsu_nek_index_current (bsu_t *ctx)
{
diff --git a/cesar/ce/fcall/test/Makefile b/cesar/ce/fcall/test/Makefile
index cf5b4d4da8..1833bbd0e5 100644
--- a/cesar/ce/fcall/test/Makefile
+++ b/cesar/ce/fcall/test/Makefile
@@ -7,6 +7,7 @@ test_ce_fcall_SOURCES = test_fcall.c fcall_stub.c ecos_stub.c
test_ce_fcall_MODULES = ce/fcall ce/common ce/rx/bitloading \
ce/rx/bitloading/fsm ce/rx/cp/stub \
lib mac/common host
+test_ce_fcall_CONFIG_MODULES = cp/sta/mgr
host_MODULE_MODULES =
include $(BASE)/common/make/top.mk
diff --git a/cesar/ce/rx/bitloading/inc/nsr.h b/cesar/ce/rx/bitloading/inc/nsr.h
index 1215a1c3a9..f0fe4aee67 100644
--- a/cesar/ce/rx/bitloading/inc/nsr.h
+++ b/cesar/ce/rx/bitloading/inc/nsr.h
@@ -101,6 +101,17 @@ void
ce_rx_bl_nsr_compute_mean (ce_rx_bitloading_t *bl);
/**
+ * Compute the mean of the total NSR sum for all the channels together.
+ * \param bl the bit loading context of the station.
+ * \return the average total nsr.
+ *
+ * This function compute the mean of the NSR-s for all the channels together.
+ * It adds NSR means of all the channels and divides the sum with number of channels.
+ */
+u8
+ce_rx_bl_nsr_compute_total_mean (ce_rx_bitloading_t *bl);
+
+/**
* Change margin to apply to NSR before usage in the bit loading algorithms.
* \param margin_q margin to apply to NSR
*
diff --git a/cesar/ce/rx/bitloading/src/bitloading.c b/cesar/ce/rx/bitloading/src/bitloading.c
index d09061fac6..223d24fab9 100644
--- a/cesar/ce/rx/bitloading/src/bitloading.c
+++ b/cesar/ce/rx/bitloading/src/bitloading.c
@@ -27,7 +27,7 @@
uint ce_rx_bl_pb_false_factor_ = 1;
uint ce_rx_bl_pb_total_factor_ = 4;
uint ce_rx_bl_min_pb_per_frame_ = 2;
-uint ce_rx_bl_min_frame_with_high_pb_err_rate_ = 4;
+uint ce_rx_bl_min_frame_with_high_pb_err_rate_ = 9;
uint ce_rx_bl_ber_lower_bound_ = 70;
/**
diff --git a/cesar/ce/rx/bitloading/src/nsr.c b/cesar/ce/rx/bitloading/src/nsr.c
index 4b4c2b14ba..4da8168e0f 100644
--- a/cesar/ce/rx/bitloading/src/nsr.c
+++ b/cesar/ce/rx/bitloading/src/nsr.c
@@ -17,6 +17,8 @@
#include "ce/rx/bitloading/inc/ber.h"
#include "hal/phy/defs.h"
+#include "stdio.h"
+
/**
* Default value of margin to apply to NSR.
* To convert a dB value to this one, you need to apply the following formula:
@@ -149,6 +151,7 @@ ce_rx_bl_nsr_compute_mean (ce_rx_bitloading_t *bl)
/* Tone represents the current tone.
* tone_limit represents the limit of tone for this block. */
uint tone, tone_limit;
+
for (i = 0, tone = 0,
tone_limit = BLK_SIZE / CE_RX_BITLOADING_NOISE_NRJ_SIZE;
i < bl->noise_nrj_blk_count;
@@ -177,6 +180,51 @@ ce_rx_bl_nsr_compute_mean (ce_rx_bitloading_t *bl)
}
}
+u8
+ce_rx_bl_nsr_compute_total_mean (ce_rx_bitloading_t *bl)
+{
+ /* Check parameter. */
+ dbg_assert (bl);
+ dbg_assert_ptr (bl->noise_nrj);
+
+ /* Go through each block of NSR sum. */
+ blk_t *blk = bl->noise_nrj;
+ uint i;
+ u32 total_sum = 0;
+ u8 ch_nb = 0;
+ u8 average_nsr;
+ /* Tone represents the current tone.
+ * tone_limit represents the limit of tone for this block. */
+ uint tone, tone_limit;
+
+ for (i = 0, tone = 0,
+ tone_limit = BLK_SIZE / CE_RX_BITLOADING_NOISE_NRJ_SIZE;
+ i < bl->noise_nrj_blk_count;
+ i++, tone_limit += BLK_SIZE / CE_RX_BITLOADING_NOISE_NRJ_SIZE)
+ {
+ /* Sanity check. */
+ dbg_assert (blk);
+ /* Get current NSR sum. */
+ u32 *cur_sum_nsr = (u32 *) blk->data;
+
+ /* If tone limit is over number of tone, we need to force it to the
+ * maximum value. */
+ if (tone_limit > PHY_CARRIER_NB)
+ tone_limit = PHY_CARRIER_NB;
+ uint j;
+ /* Go through each sum of NSR of this block. */
+ for (j = 0; tone < tone_limit; j++, tone++)
+ {
+ total_sum = total_sum + cur_sum_nsr[j];
+ ch_nb++;
+ }
+ /* Next block. */
+ blk = blk->next;
+ }
+ average_nsr = (u8)(total_sum / ch_nb);
+ return average_nsr;
+}
+
void
ce_rx_bl_nsr_margin_set (u8 margin_q)
{
diff --git a/cesar/ce/rx/bitloading/src/transition.c b/cesar/ce/rx/bitloading/src/transition.c
index 2a6bc4751f..3511ab8fb3 100644
--- a/cesar/ce/rx/bitloading/src/transition.c
+++ b/cesar/ce/rx/bitloading/src/transition.c
@@ -292,7 +292,8 @@ ce_rx_bl_fsm__TRACKING__data (ce_rx_t *ce_rx,
dbg_assert (sta->rx_tonemaps);
- sta->rx_tonemaps->sound_frame_counter = TONEMAP_SOUND_FRAME_COUNTER;
+ if (!sta->rx_tonemaps->sound_frame_counter)
+ sta->rx_tonemaps->sound_frame_counter = TONEMAP_SOUND_FRAME_COUNTER;
/* Increase CE statistics. */
/* If measure is a negotiated tone map. */
diff --git a/cesar/ce/rx/bitloading/test/fsm-Makefile b/cesar/ce/rx/bitloading/test/fsm-Makefile
index 8735a7a9e2..f9fdd7c38d 100644
--- a/cesar/ce/rx/bitloading/test/fsm-Makefile
+++ b/cesar/ce/rx/bitloading/test/fsm-Makefile
@@ -10,6 +10,7 @@ HOST_PROGRAMS = test_ce_fsm
test_ce_fsm_SOURCES = scenario_actions.c test_fsm.c scenario_events.c \
ce_rx_bl_stub.c ecos_stub.c
test_ce_fsm_MODULES = $(ce_rx_bl_modules_common) lib/scenario
+test_ce_fsm_CONFIG_MODULES = cp/sta/mgr
ce_rx_bitloading_MODULE_SOURCES = transition.c intervals.c
mac_common_MODULE_SOURCES = interval.c
diff --git a/cesar/ce/rx/bitloading/test/host-Makefile b/cesar/ce/rx/bitloading/test/host-Makefile
index f50f12d6b8..2a3c80085c 100644
--- a/cesar/ce/rx/bitloading/test/host-Makefile
+++ b/cesar/ce/rx/bitloading/test/host-Makefile
@@ -11,6 +11,7 @@ HOST_PROGRAMS = test_ce_host test_ce_intervals
test_ce_host_SOURCES = $(ce_rx_bl_test_sources_common) ecos_stub.c
test_ce_host_MODULES = $(ce_rx_bl_modules_common)
+test_ce_host_CONFIG_MODULES = cp/sta/mgr
test_ce_intervals_SOURCES = test_intervals.c ecos_stub.c
test_ce_intervals_MODULES = $(ce_rx_bl_modules_common)
diff --git a/cesar/ce/rx/bitloading/test/sparc-Makefile b/cesar/ce/rx/bitloading/test/sparc-Makefile
index 2c0d8990f8..76ea62d15b 100644
--- a/cesar/ce/rx/bitloading/test/sparc-Makefile
+++ b/cesar/ce/rx/bitloading/test/sparc-Makefile
@@ -16,6 +16,7 @@ TARGET_PROGRAMS = test_ce_sparc
test_ce_sparc_SOURCES = $(ce_rx_bl_test_sources_common)
test_ce_sparc_MODULES = $(ce_rx_bl_modules_common) hal/arch
+test_ce_sparc_CONFIG_MODULES = cp/sta/mgr
# Include base makefile.
include $(BASE)/common/make/top.mk
diff --git a/cesar/ce/rx/cp/test/Config b/cesar/ce/rx/cp/test/Config
new file mode 100644
index 0000000000..47b4d7d423
--- /dev/null
+++ b/cesar/ce/rx/cp/test/Config
@@ -0,0 +1,2 @@
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CP_STA_MGR_EOC = n
diff --git a/cesar/ce/rx/cp/test/Makefile b/cesar/ce/rx/cp/test/Makefile
index 80f8c51d7b..6c06aebb4e 100644
--- a/cesar/ce/rx/cp/test/Makefile
+++ b/cesar/ce/rx/cp/test/Makefile
@@ -15,10 +15,12 @@ HOST_PROGRAMS = test_mbox
test_mme_SOURCES = test_mme.c stub.c
test_mme_MODULES = lib mac/common ce/rx/cp ce/common cp/msg/stub cp/sta/mgr \
cp/fsm/stub
+test_mme_CONFIG_MODULES = mac/sar
# Test mailbox.
test_mbox_SOURCES = test_mbox.c stub_mbox.c
test_mbox_MODULES = lib mac/common ce/rx/cp ce/common cp/fsm/stub cp/msg/stub
+test_mbox_CONFIG_MODULES = mac/sar cp/sta/mgr
# Remove sta.c to prevent multiple definition of cp_sta_get_peer.
cp_sta_mgr_MODULE_SOURCES = net.c sta_mgr.c sta_own_data.c
diff --git a/cesar/ce/rx/test/Config b/cesar/ce/rx/test/Config
index 79114fce7f..b164580cc7 100644
--- a/cesar/ce/rx/test/Config
+++ b/cesar/ce/rx/test/Config
@@ -1,2 +1,3 @@
CONFIG_DEBUG_FATAL_CATCH = y
CONFIG_SLAB_ALLOC_SCRAMBLE = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
diff --git a/cesar/ce/rx/test/Makefile b/cesar/ce/rx/test/Makefile
index 5c2ede2792..5649e18ff3 100644
--- a/cesar/ce/rx/test/Makefile
+++ b/cesar/ce/rx/test/Makefile
@@ -16,6 +16,7 @@ common_MODULES = ce/rx ce/rx/cp ce/common \
mac/sar/stub cp/sta/mgr cp/fsm/stub cp/cco/action/stub \
cp/sta/core/stub cl/stub bsu/stub
+
# Override sources for BL (we only want our stubbed handle event for the FSM).
ce_rx_bitloading_fsm_MODULE_SOURCES =
@@ -25,6 +26,6 @@ TARGET_PROGRAMS = test_rx
# Test CE RX.
test_rx_SOURCES = test_rx.c pbproc_stub.c
test_rx_MODULES = $(common_MODULES)
-
+test_rx_CONFIG_MODULES = mac/pbproc mac/sar
# Include main Makefile.
include $(BASE)/common/make/top.mk
diff --git a/cesar/ce/tx/test/Config b/cesar/ce/tx/test/Config
new file mode 100644
index 0000000000..d02940c1dc
--- /dev/null
+++ b/cesar/ce/tx/test/Config
@@ -0,0 +1,2 @@
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CL_EOC_ROUTE = y
diff --git a/cesar/ce/tx/test/Makefile b/cesar/ce/tx/test/Makefile
index a8a655d3af..a8950f5fd5 100644
--- a/cesar/ce/tx/test/Makefile
+++ b/cesar/ce/tx/test/Makefile
@@ -14,6 +14,7 @@ HOST_PROGRAMS = test_expiration test_mme test_tm
test_expiration_SOURCES = test_expiration.c mme.c
test_expiration_MODULES = $(common_MODULES)
+test_expiration_CONFIG_MODULES = mac/sar cl
test_mme_SOURCES = test_mme.c mme.c
test_mme_MODULES = $(common_MODULES)
diff --git a/cesar/ce/tx/test/src/test_mme.c b/cesar/ce/tx/test/src/test_mme.c
index 85b52d9ee9..6be0790c0f 100644
--- a/cesar/ce/tx/test/src/test_mme.c
+++ b/cesar/ce/tx/test/src/test_mme.c
@@ -210,7 +210,7 @@ mme_test_suite (test_t t)
test_case_begin (t, "ce tx mme reception");
int i;
- uint intervals_version = 0;
+ u8 intervals_version = 0;
cp_mme_rx_t mme;
mme.peer.tei = peer_tei;
mme.mmtype = CM_CHAN_EST_IND;
@@ -698,6 +698,25 @@ mme_test_suite (test_t t)
test_fail_if (sta->tx_tonemaps->intervals->version != intervals_version);
} test_end;
+ test_begin (t, "test version indicator overflow")
+ {
+ uint j;
+ sta->tx_tonemaps->intervals->version = 250;
+ /* First time we receive a MME from the CE, interval version is
+ * incremented twice. */
+ intervals_version = 252;
+
+ for (j=0; j<50; j++)
+ {
+ memset (mme_data, 0xFF, ETH_PACKET_MAX_SIZE);
+ ce_test_mme_cm_chan_est_ind_build_default (mme_data, &mme);
+ test_fail_if (ce_tx_cm_chan_est_ind_receive (&cp, &mme)
+ != CE_TX_MME_OK);
+ test_fail_if (sta->tx_tonemaps->intervals->version
+ != intervals_version++);
+ }
+ } test_end;
+
/* Clean. */
blk_release (sta);
dbg_check (mac_store_sta_remove (cp.mac_store, peer_tei));
diff --git a/cesar/cl/Config b/cesar/cl/Config
index c91d7c649d..34a2b65b17 100644
--- a/cesar/cl/Config
+++ b/cesar/cl/Config
@@ -1,5 +1,8 @@
+CONFIG_CL_EOC_CLASSIFY = n
CONFIG_GPIO_LED_CL_RX = n
CONFIG_GPIO_LED_CL_RX_GPIO = 0
CONFIG_GPIO_LED_CL_TX = n
CONFIG_GPIO_LED_CL_TX_GPIO = 0
-CONFIG_CL_DATA_RATE=n
+CONFIG_CL_EOC_ROUTE = n
+CONFIG_CL_DATA_RATE = y
+
diff --git a/cesar/cl/Module b/cesar/cl/Module
index 13768e9721..c0b57e5ac4 100644
--- a/cesar/cl/Module
+++ b/cesar/cl/Module
@@ -2,3 +2,6 @@ SOURCES := cl.c cl_mactotei.c bridge_table.c data_rate.c brg_rx.c
ifeq ($(CONFIG_TRACE),y)
SOURCES += trace.c
endif
+ifeq ($(CONFIG_CL_EOC_ROUTE),y)
+SOURCES += cl_eoc_mactotei.c
+endif
diff --git a/cesar/cl/cl_eoc_mactotei.h b/cesar/cl/cl_eoc_mactotei.h
new file mode 100644
index 0000000000..24357c94b8
--- /dev/null
+++ b/cesar/cl/cl_eoc_mactotei.h
@@ -0,0 +1,143 @@
+#ifndef CL_EOC_MACTOTEI_H_
+#define CL_EOC_MACTOTEI_H_
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/cl_eoc_mactotei.h
+ * \brief MAC to TEI table interface between the CL and the CP.
+ * \ingroup cl
+ *
+ * The MAC to TEI table associate a MAC address to a TEI and a timestamp. The
+ * timestamp is used to know if the entry is obsolete entry or not.
+ */
+#include "lib/list.h"
+#include "mac/common/timings.h"
+#include "cl/inc/context.h"
+
+#define MACTOTEI_NB_ENTRIES 512
+#define MACTOTEI_HASHSIZE 256
+#define MACTOTEI_HASHFUNC(mac) ((mac) >> 40)
+#define MAC_LIMITATION 9
+
+/** Duration after which the entry is obsolete (in seconds)*/
+#define MAX_ENTRY_AGE_SEC 1800
+#define MIN_ENTRY_AGE_SEC 60
+#define DEFAULT_ENTRY_AGE_SEC 300
+
+/** Single MAC to TEI entry contained in the table. Reserved entries do not age,
+ * they are reserved for multicast
+ */
+struct cl_eoc_mactotei_entry_t
+{
+ /** Station's TEI*/
+ uint tei;
+ /** MAC address of equipment behind TEI*/
+ mac_t mac_addr;
+ /** Entry's node in unique ageing list of all MAC adresses*/
+ list_node_t l_age;
+ /** Entry's node in hashing_list. */
+ list_node_t l_hash;
+ /** Time of creation or refresh of entry. */
+ uint timestamp;
+ /** Reserved entries do not age. */
+ bool reserved;
+};
+
+typedef struct cl_eoc_mactotei_entry_t cl_eoc_mactotei_entry_t;
+
+/** Table used to keep MAC to TEI mappings */
+struct cl_eoc_mactotei_table_t
+{
+ /** Unique ageing list. */
+ list_t ageing_list;
+ /** Hashing lists, take least significant byte of MAC address. */
+ list_t hashing_list[MACTOTEI_HASHSIZE];
+ /** Limited number of entries for each STA/CCo. */
+ cl_eoc_mactotei_entry_t cl_eoc_mtt_entries[MACTOTEI_NB_ENTRIES];
+ /** Duration after which entry is obsolete */
+ uint max_duration;
+ /** Current number mac addresses on STA side */
+ uint num_of_entries;
+ /** Number of allowed mac addresses on STA side */
+ uint max_entries;
+ /** STA's local time for entries expiration */
+ uint time_count;
+ /** Snapshot list of valid mac addresses in MAC to TEI table.*/
+ mac_t mac_snapshot[MACTOTEI_NB_ENTRIES];
+};
+
+typedef struct cl_eoc_mactotei_table_t cl_eoc_mactotei_table_t;
+
+BEGIN_DECLS
+
+/** Find TEI to which to route packests according to MAC address.
+ * \param ctx CL context
+ * \param mac_addr MAC address of source
+ */
+uint
+cl_eoc_mactotei_find_tei (cl_t *ctx, mac_t mac_addr);
+
+/** Initialization of EoC mactotei table.
+ * \param ctx CL context
+ */
+void
+cl_eoc_mactotei_init (cl_t *ctx);
+
+/** Put new entry in mactotei table.
+ * \param ctx CL context
+ * \param mac_addr MAC address of new entry
+ * \param tei TEI of new entry
+*/
+bool
+cl_eoc_mactotei_entry_insert (cl_t *ctx, mac_t mac_addr, uint tei);
+
+/** Remove all entries associated with given TEI from ageing and hashing lists
+ * of cl_eoc_mactotei_table.
+ * \param ctx CL context
+ * \param tei TEI of the STA whose entries should be removed from the table
+*/
+void
+cl_eoc_mactotei_entry_remove (cl_t *ctx, uint tei);
+
+/** Set time during which entry will be valid.
+ * \param ctx CL context
+ * \param max_dur_sec maximum duration of entry in seconds
+ */
+void
+cl_eoc_mactotei_set_entry_duration (cl_t * ctx, uint max_dur_sec);
+
+/** Keep local time updated for entry expiration purpose.
+ * \param ctx CL context
+ */
+void
+cl_eoc_time_update (cl_t *ctx);
+
+/** Return current local time value.
+ * \param ctx CL context
+ */
+uint
+cl_eoc_get_time (cl_t *ctx);
+
+/** Return number of valid entries in mactotei table and store MAC adresses of
+ * valid entries
+ * \param ctx CL context
+ */
+uint
+cl_eoc_mactotei_entry_count (cl_t *ctx);
+
+/** Return mac addresses of valid entries in mactotei table
+ * \param ctx CL context
+ * \param next_mac next element in mac snapshot list to be read
+ */
+mac_t
+cl_eoc_mactotei_get_mac (cl_t *ctx, uint next_mac);
+
+END_DECLS
+
+#endif /*CL_EOC_MACTOTEI_H_*/
diff --git a/cesar/cl/cl_mactotei.h b/cesar/cl/cl_mactotei.h
index dd103e1335..feccd7acb1 100644
--- a/cesar/cl/cl_mactotei.h
+++ b/cesar/cl/cl_mactotei.h
@@ -34,6 +34,18 @@ typedef struct mac_lookup_table_t cl_mactotei_table_t;
*/
typedef struct mac_lookup_block_header_t cl_mactotei_blk_t;
+/**
+ * A MAC address with a TEI.
+ */
+struct cl_mactotei_entry_t
+{
+ /** A MAC address*/
+ mac_t mac;
+ /** A TEI */
+ uint tei;
+};
+typedef struct cl_mactotei_entry_t cl_mactotei_entry_t;
+
BEGIN_DECLS
/**
@@ -156,6 +168,25 @@ cl_mactotei_copy_except_tei (cl_t *ctx, cl_mactotei_blk_t *table, uint tei);
void
cl_mactotei_cancel (cl_mactotei_blk_t *table);
+/**
+ * Add a temporary entry to the bridge table (if not already existing).
+ * \param cl the CL context.
+ * \param tei the TEI.
+ * \param mac the source MAC address.
+ */
+void
+cl_mactotei_add (cl_t *ctx, uint tei, mac_t mac);
+
+/**
+ * Get TEI associated to a given MAC address of a packet
+ * \param cl the CL context.
+ * \param mac the source MAC address of a packet
+ *
+ * This function is called every time CCo has to send_sack
+ */
+uint
+cl_mactotei_get_tei (cl_t *ctx, mac_t mac);
+
END_DECLS
#endif /*CL_MACTOTEI_H_*/
diff --git a/cesar/cl/inc/context.h b/cesar/cl/inc/context.h
index 9372864dea..965a190ccd 100644
--- a/cesar/cl/inc/context.h
+++ b/cesar/cl/inc/context.h
@@ -27,6 +27,9 @@
#include "cl/inc/bridge_table.h" // bridge_table_context_t
#include "cl/inc/trace.h"
+#include "config/cl/eoc.h"
+
+#include "cl/cl_eoc_mactotei.h"
#include "common/defs/igmp.h"
/** Define the delay at the one the data inside the cl_data_send_link_t are
@@ -126,6 +129,13 @@ struct cl_t
/** mactotei table to send data over the PLC. */
cl_mactotei_table_t *mactotei;
+#if CONFIG_CL_EOC_ROUTE
+ /** Table for routing packages in EoC, maps MAC to TEI of STA on CCo side
+ * and limits number of MAC address behind STA
+ */
+ cl_eoc_mactotei_table_t cl_eoc_mactotei_table;
+#endif
+
/** send data context. */
cl_data_tx_t data_tx;
diff --git a/cesar/cl/src/bridge_table.c b/cesar/cl/src/bridge_table.c
index 163919bd01..c5bd352e6b 100644
--- a/cesar/cl/src/bridge_table.c
+++ b/cesar/cl/src/bridge_table.c
@@ -35,6 +35,10 @@
#include "cl/inc/context.h" // cl_t
+#if CONFIG_CL_EOC_ROUTE
+#include "cl/cl_eoc_mactotei.h"
+#endif /* CONFIG_CL_EOC_ROUTE */
+
void
bridge_table_init (cl_t *ctx)
{
@@ -106,6 +110,12 @@ bridge_table_update (cl_t *ctx)
/* Check parameter. */
dbg_assert (ctx);
+ /* For EoC no bridge tables are sent, only time update. */
+#if CONFIG_CL_EOC_ROUTE
+ cl_eoc_time_update (ctx);
+ return false;
+#endif
+
/* Increment cycle counter. */
ctx->bridge_table.cycle_counter++;
@@ -182,8 +192,11 @@ bridge_table_size (cl_t *ctx)
{
/* Check parameter. */
dbg_assert (ctx);
-
+#if !CONFIG_CL_EOC_ROUTE
return mac_lookup_entry_count (ctx->bridge_table.table);
+#else
+ return cl_eoc_mactotei_entry_count (ctx);
+#endif
}
mac_t
@@ -191,7 +204,10 @@ bridge_table_get_entry (cl_t *ctx, uint position)
{
/* Check parameters. */
dbg_assert (ctx);
+#if !CONFIG_CL_EOC_ROUTE
dbg_assert (position < bridge_table_size (ctx));
-
return mac_lookup_get_mac (ctx->bridge_table.table, position);
+#else
+ return cl_eoc_mactotei_get_mac (ctx, position);
+#endif
}
diff --git a/cesar/cl/src/cl.c b/cesar/cl/src/cl.c
index 09cb93aa33..11d721149f 100644
--- a/cesar/cl/src/cl.c
+++ b/cesar/cl/src/cl.c
@@ -33,6 +33,7 @@
#include "mac/sar/sar.h"
#include <string.h>
+#include "config/cl/eoc.h"
#include "mac/common/store.h"
@@ -71,31 +72,49 @@ cl_lib_seq_check_cb (void *user, uint vlan, uint seq_expected,
* \param acs put true if the link should be process by the ACS
* \param drop put true if the data should be drop.
*/
-uint
-cl_classifer_get_lid (cl_t *ctx, uint tei, uint tag,
+static inline uint
+cl_classifer_get_lid_ (cl_t *ctx, uint tei, uint tag,
bool *bcast, bool *acs,
bool *drop)
{
static uint lid_table[] = { 1, 0, 0, 1, 2, 2, 3, 3 };
uint lid;
- dbg_assert (ctx);
- dbg_assert (bcast);
- dbg_assert (acs);
- dbg_assert (drop);
+
dbg_assert (tag < COUNT (lid_table));
+
if (tei == MAC_TEI_BCAST)
*bcast = true;
else
*bcast = false;
*acs = false;
*drop = false;
+
lid = lid_table[tag];
+
+ if (CONFIG_CL_EOC_CLASSIFY)
+ {
+ if ((tei == MAC_TEI_UNASSOCIATED || tei == MAC_TEI_BCAST))
+ lid = 0;
+ else
+ lid = MAC_LLID_MIN;
+ }
+
CL_TRACE (CLASSIFIER, phy_date (), tei, *bcast, *acs, *drop, lid);
/** TODO fill the classifier */
return lid;
}
-
+uint
+cl_classifer_get_lid (cl_t *ctx, uint tei, uint tag,
+ bool *bcast, bool *acs,
+ bool *drop)
+{
+ dbg_assert (ctx);
+ dbg_assert (bcast);
+ dbg_assert (acs);
+ dbg_assert (drop);
+ return cl_classifer_get_lid_ (ctx, tei, tag,bcast, acs, drop);
+}
/**
* Send a data once the TEI has been find.
*
@@ -109,7 +128,7 @@ cl_classifer_get_lid (cl_t *ctx, uint tei, uint tag,
* \param dmac the final destination mac address.
* \param smac the source mac address.
*/
-static void
+static inline void
cl_data_send_with_tei (cl_t *ctx, u8 *buffer, uint length, uint tei,
uint tag, cl_send_t *cl_data, u32 arrival_time_ntb,
mac_t dmac, mac_t smac)
@@ -119,16 +138,15 @@ cl_data_send_with_tei (cl_t *ctx, u8 *buffer, uint length, uint tei,
bool acs;
bool drop;
mfs_tx_t *mfs;
- sta_t* sta;
- dbg_assert (ctx);
- dbg_assert (buffer);
- dbg_assert ((length >= ETH_PACKET_MIN_SIZE_ALLOWED)
+ dbg_claim (ctx);
+ dbg_claim (buffer);
+ dbg_claim ((length >= ETH_PACKET_MIN_SIZE_ALLOWED)
&& (length <= ETH_PACKET_MAX_SIZE));
- dbg_assert (tei);
+ dbg_claim (tei);
/* Get some data from the classifier. */
- lid = cl_classifer_get_lid (ctx, tei, tag, &bcast, &acs, &drop);
+ lid = cl_classifer_get_lid_ (ctx, tei, tag, &bcast, &acs, &drop);
if (MAC_LID_IS_PLID (lid))
{
@@ -140,11 +158,25 @@ cl_data_send_with_tei (cl_t *ctx, u8 *buffer, uint length, uint tei,
if (added)
sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+#if CONFIG_CL_EOC_ROUTE
+ if (mfs && mfs->seg_nb >= MFS_TX_MAX_SEG_NB)
+ drop = true;
+ if (mfs)
+ blk_addref (mfs);
+#endif
}
else
{
/* try to get the mfs from the store. */
+#if !CONFIG_CL_EOC_ROUTE
mfs = mac_store_mfs_get_tx (ctx->mac_store, bcast, false, lid, tei);
+#else
+ mfs = mac_store_mfs_get_sta_tx_data (ctx->mac_store, lid, tei);
+ if (mfs)
+ blk_addref (mfs);
+ if (mfs && mfs->seg_nb >= MFS_TX_MAX_SEG_NB)
+ drop = true;
+#endif
}
if (!drop && !acs && mfs)
@@ -161,9 +193,10 @@ cl_data_send_with_tei (cl_t *ctx, u8 *buffer, uint length, uint tei,
/* update data rate informations associated to the TX
* from the local sta to the associated sta */
+
if (MAC_TEI_IS_STA (tei) && CONFIG_CL_DATA_RATE)
{
- sta = mac_store_sta_get (ctx->mac_store, tei);
+ sta_t * sta = mac_store_sta_get (ctx->mac_store, tei);
if (sta)
{
data_rate_update_info (&(sta->tx_data_rate), length);
@@ -177,10 +210,11 @@ cl_data_send_with_tei (cl_t *ctx, u8 *buffer, uint length, uint tei,
buffer, length);
dbg_assert (ctx->data_tx.cb);
(*ctx->data_tx.cb) (ctx->data_tx.user, buffer);
- /* Release the MFS */
+ /* release the mfs */
if (mfs)
blk_release (mfs);
}
+
}
/** Initialise the cl_send object.
@@ -256,7 +290,6 @@ cl_init (mac_store_t *mac_store, sar_t *sar, mac_config_t *mac_config)
dbg_assert (mac_config);
ctx = &cl_global;
-
cl_global.mac_store = mac_store;
/* Initialize the SAR */
@@ -303,6 +336,10 @@ cl_init (mac_store_t *mac_store, sar_t *sar, mac_config_t *mac_config)
bridge_table_init (ctx);
ctx->brg_rx = NULL;
+#if CONFIG_CL_EOC_ROUTE
+ cl_eoc_mactotei_init (ctx);
+ ctx->groups.nb = 0;
+#endif
/* Initialise the data link. */
ctx->data_send_link.mfs = NULL;
@@ -622,7 +659,7 @@ cl_data_send_prepare (cl_t *ctx, u8 *buffer, uint length, uint tag,
/* Add the source MAC address to the local bridge table if not our MAC
* address. */
dbg_assert (ctx->mac_config);
- if (ctx->mac_config->sta_mac_address != smac)
+ if (ctx->mac_config->sta_mac_address != smac && !CONFIG_CL_EOC_ROUTE)
bridge_table_add (ctx, smac);
/* Data are forbidden if not authenticated. */
@@ -636,11 +673,37 @@ cl_data_send_prepare (cl_t *ctx, u8 *buffer, uint length, uint tag,
/* Get the TEI from the mactotei table. */
uint tei;
- uint group;
- tei = cl_mactotei_table_find_tei_and_tag_from_mac (ctx, dmac, &group);
+ uint group=0;
+ if (!CONFIG_CL_EOC_ROUTE)
+ tei = cl_mactotei_table_find_tei_and_tag_from_mac (ctx, dmac, &group);
+ else
+ tei = MAC_TEI_UNASSOCIATED;
+#if CONFIG_CL_EOC_ROUTE
+ /* Find destination TEI */
+ if (MAC_TEI_IS_EOC_STA(ctx->mac_config->tei))
+ tei = MAC_TEI_CCO_DEF;
+ else if (tei == MAC_TEI_UNASSOCIATED)
+ tei = cl_eoc_mactotei_find_tei (ctx, dmac);
+ /* For STA, if tei is unassociated, or MAC limit is reached
+ * drop the packet */
+ if (MAC_TEI_IS_EOC_STA(ctx->mac_config->tei))
+ {
+ bool drop = false;
+ if (smac != ctx->mac_config->sta_mac_address)
+ drop = !cl_eoc_mactotei_entry_insert (ctx, smac,
+ ctx->mac_config->tei);
+ if ((tei == MAC_TEI_UNASSOCIATED) || drop)
+ {
+ dbg_assert (ctx->data_tx.cb);
+ (*ctx->data_tx.cb) (ctx->data_tx.user, buffer);
+ return;
+ }
+ }
+#endif
+
dbg_assert (tei != ctx->mac_config->tei);
- if (tei == MAC_TEI_BCAST)
+ if (tei == MAC_TEI_BCAST && ctx->groups.nb)
{
if (ctx->groups.nb_actual_members[group] > 1)
{
@@ -682,9 +745,14 @@ cl_data_send (cl_t *ctx, u8 *buffer, uint length, uint tag,
ctx->data_send_link.mfs->common.tei,
ctx->data_send_link.mfs->common.lid,
ctx->data_send_link.mfs->common.bcast);
- sar_msdu_add (ctx->sar, buffer, length,
- ctx->data_send_link.mfs, NULL,
- arrival_time_ntb);
+#if CONFIG_CL_EOC_ROUTE
+ if (ctx->data_send_link.mfs->seg_nb >= MFS_TX_MAX_SEG_NB)
+ (*ctx->data_tx.cb) (ctx->data_tx.user, buffer);
+ else
+#endif
+ sar_msdu_add (ctx->sar, buffer, length,
+ ctx->data_send_link.mfs, NULL,
+ arrival_time_ntb);
}
else
{
@@ -791,7 +859,9 @@ cl_mme_send (cl_t *ctx, u8 *buffer, uint length, uint tei)
{
CL_TRACE (MME_SEND_TO_DRIVER, phy_date (), length, buffer);
dbg_assert (ctx->mme_ul_send.cb);
+ arch_dsr_lock ();
(*ctx->mme_ul_send.cb) (ctx->mme_ul_send.user, buffer, length);
+ arch_dsr_unlock ();
}
}
@@ -852,7 +922,6 @@ void cl_mme_recv_done (cl_t *ctx, u8* buffer, bool mme_recv)
else
{
dbg_assert (ctx->mme.ul_mme_recv_done);
-
(*ctx->mme.ul_mme_recv_done) (ctx->mme.ul_mme_recv_done_user_data,
buffer);
}
@@ -933,7 +1002,6 @@ void cl_data_recv_init (cl_t *cl, cl_data_recv_cb_t cb, void *user)
void cl_data_recv (cl_t *ctx, u8 *buffer, uint length, mfs_rx_t *mfs)
{
uint tei;
- sta_t* sta;
dbg_assert (ctx);
dbg_assert (buffer);
@@ -945,28 +1013,34 @@ void cl_data_recv (cl_t *ctx, u8 *buffer, uint length, mfs_rx_t *mfs)
lib_seq_check_packet (&ctx->seq_check_rx_ctx, buffer, length);
dbg_assert (ctx->data_rx.cb);
-
mac_t smac, dmac;
bitstream_direct_read_macs (buffer, &dmac, &smac);
CL_TRACE (DATA_RECV, phy_date (), buffer, TRACE_U64 (dmac),
TRACE_U64 (smac), length);
(*ctx->data_rx.cb) (ctx->data_rx.user, buffer, length);
- cl_brg_rx_add (ctx, smac, mfs->common.tei);
+#if !CONFIG_CL_EOC_ROUTE
+ cl_brg_rx_add (ctx, smac, mfs->common.tei);
+#endif
/* update data rate informations associated to the RX
* from the associated sta to the local sta */
tei = mfs->common.tei;
+#if CONFIG_CL_EOC_ROUTE
+ bool ok = true;
+ if (MAC_TEI_IS_EOC_CCO(ctx->mac_config->tei))
+ ok = cl_eoc_mactotei_entry_insert (ctx, smac, tei);
+ dbg_assert (ok);
+#endif
if (MAC_TEI_IS_STA (tei) && CONFIG_CL_DATA_RATE)
{
- sta = mac_store_sta_get (ctx->mac_store, tei);
+ sta_t * sta = mac_store_sta_get (ctx->mac_store, tei);
if (sta)
{
data_rate_update_info(&(sta->rx_data_rate), length);
blk_release (sta);
}
}
-
/* Debug info. */
GPIO_TOGGLE (LED_CL_RX);
}
@@ -1000,7 +1074,7 @@ void cl_data_buffer_add (cl_t *ctx, u8 *buffer)
CL_TRACE (DATA_BUFFER_ADD, phy_date (), buffer);
- sar_data_buffer_add (ctx->sar, buffer);
+ sar_buffer_add (ctx->sar, buffer, true);
}
void
diff --git a/cesar/cl/src/cl_eoc_mactotei.c b/cesar/cl/src/cl_eoc_mactotei.c
new file mode 100644
index 0000000000..42e12143e8
--- /dev/null
+++ b/cesar/cl/src/cl_eoc_mactotei.c
@@ -0,0 +1,279 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/src/cl_eoc_mactotei.c
+ * \brief MAC to TEI mapping for the Convergence Layer
+ * \ingroup cl
+ *
+ */
+#include "common/std.h"
+#include "cl/inc/context.h"
+#include "cl/cl_eoc_mactotei.h"
+#include "hal/arch/arch.h"
+#include "lib/stats.h"
+
+void
+cl_eoc_time_update (cl_t *ctx)
+{
+ ctx->cl_eoc_mactotei_table.time_count++;
+}
+
+uint
+cl_eoc_get_time (cl_t *ctx)
+{
+ return ctx->cl_eoc_mactotei_table.time_count;
+}
+
+static inline int
+cl_eoc_is_obsolete (cl_t *ctx, cl_eoc_mactotei_entry_t *entry, uint timestamp)
+{
+ if (ctx->mac_config->sta_mac_address == entry->mac_addr)
+ return 0;
+ else
+ return lesseq_mod2p32(entry->timestamp +
+ ctx->cl_eoc_mactotei_table.max_duration, timestamp);
+}
+
+/** Initialization of EoC mactotei table.
+ * \param ctx CL context
+ */
+void
+cl_eoc_mactotei_init (cl_t *ctx)
+{
+ cl_eoc_mactotei_table_t *mtt_table = &ctx->cl_eoc_mactotei_table;
+ cl_eoc_mactotei_entry_t *entry;
+ int i;
+
+ list_init (&mtt_table->ageing_list);
+ for (i = 0; i < MACTOTEI_HASHSIZE; i++)
+ list_init (&mtt_table->hashing_list[i]);
+ for (i = 0; i < MACTOTEI_NB_ENTRIES; i++)
+ {
+ entry = &mtt_table->cl_eoc_mtt_entries[i];
+ list_init_node (&entry->l_hash);
+ list_init_node (&entry->l_age);
+ entry->timestamp = i;
+ entry->reserved = 0;
+ entry->mac_addr = 0;
+ list_push (&mtt_table->ageing_list,&entry->l_age);
+ }
+ mtt_table->num_of_entries = 0;
+ mtt_table->time_count = 0;
+ mtt_table->max_entries = MAC_LIMITATION;
+ cl_eoc_mactotei_set_entry_duration (ctx, DEFAULT_ENTRY_AGE_SEC);
+
+ lib_stats_set_stat_value_notype ("MAC_LIMITATION",
+ &mtt_table->max_entries,
+ LIB_STATS_ACCESS_READ_WRITE,
+ LIB_STATS_DEBUG);
+}
+
+/** Search for an entry in eoc_mactotei table with the given mac address.
+ * \param ctx CL context
+ * \param mac_addr MAC address of the entry to be found in table
+ */
+cl_eoc_mactotei_entry_t *cl_eoc_mactotei_entry_find (cl_t *ctx, mac_t mac_addr)
+{
+
+ u8 index = MACTOTEI_HASHFUNC (mac_addr);
+ cl_eoc_mactotei_entry_t *entry = NULL;
+ list_node_t *list_node = NULL;
+
+ list_node = list_begin (&ctx->cl_eoc_mactotei_table.hashing_list[index]);
+
+ while (list_node != &ctx->cl_eoc_mactotei_table.hashing_list[index].nil)
+ {
+ if (list_node)
+ entry = PARENT_OF (cl_eoc_mactotei_entry_t, l_hash, list_node);
+ if (entry && (mac_addr == entry->mac_addr))
+ return entry;
+ list_node = list_next (list_node);
+ }
+
+ return NULL;
+}
+
+/** Find TEI to which to route packets according to MAC address.
+ * \param ctx CL context
+ * \param mac_addr MAC address to be mapped to TEI
+ */
+uint
+cl_eoc_mactotei_find_tei (cl_t *ctx, mac_t mac_addr)
+{
+ cl_eoc_mactotei_entry_t *entry = NULL;
+
+ entry = cl_eoc_mactotei_entry_find (ctx, mac_addr);
+ if (entry && !cl_eoc_is_obsolete (ctx, entry, cl_eoc_get_time (ctx)))
+ {
+ entry->timestamp = cl_eoc_get_time (ctx);
+ return entry->tei;
+ }
+
+ return MAC_TEI_UNASSOCIATED;
+}
+
+/** Put new MAC address in mactotei table.
+ * \param ctx CL context
+ * \param mac_addr MAC address of the packet
+ * \param tei TEI of the packet
+*/
+bool
+cl_eoc_mactotei_entry_insert (cl_t *ctx, mac_t mac_addr, uint tei)
+{
+ cl_eoc_mactotei_entry_t *entry = NULL;
+ cl_eoc_mactotei_entry_t *entry1 = NULL;
+ uint i;
+ list_node_t *list_node = NULL;
+
+ entry = cl_eoc_mactotei_entry_find (ctx, mac_addr);
+
+ if (!entry || cl_eoc_is_obsolete (ctx, entry, cl_eoc_get_time (ctx)))
+ {
+ /* Check if limit of MAC addresses is reached */
+ if (ctx->mac_config->tei == tei)
+ {
+ if (ctx->cl_eoc_mactotei_table.num_of_entries ==
+ ctx->cl_eoc_mactotei_table.max_entries)
+ {
+ ctx->cl_eoc_mactotei_table.num_of_entries = 0;
+ /* Count number of valid entries */
+ for (i = 0; i < MACTOTEI_HASHSIZE; i++)
+ {
+ list_node = list_begin (&ctx->cl_eoc_mactotei_table.hashing_list[i]);
+ while (list_node != &ctx->cl_eoc_mactotei_table.hashing_list[i].nil)
+ {
+ if (list_node)
+ entry1 = PARENT_OF (cl_eoc_mactotei_entry_t, l_hash,
+ list_node);
+ if ((entry1->tei == tei) &&
+ !cl_eoc_is_obsolete (ctx, entry1, cl_eoc_get_time (ctx)))
+ {
+ ctx->cl_eoc_mactotei_table.num_of_entries++;
+ }
+ if (ctx->cl_eoc_mactotei_table.num_of_entries ==
+ ctx->cl_eoc_mactotei_table.max_entries)
+ return false;
+ list_node = list_next (list_node);
+ }
+ }
+ }
+ ctx->cl_eoc_mactotei_table.num_of_entries++;
+ }
+ }
+
+ u8 index = MACTOTEI_HASHFUNC (mac_addr);
+ if (!entry)
+ {
+ list_node = list_next (&ctx->cl_eoc_mactotei_table.ageing_list.nil);
+ list_remove (&ctx->cl_eoc_mactotei_table.ageing_list, list_node);
+ entry = PARENT_OF (cl_eoc_mactotei_entry_t, l_age, list_node);
+ if (entry->mac_addr)
+ {
+ u8 index1 = MACTOTEI_HASHFUNC (entry->mac_addr);
+ list_remove (&ctx->cl_eoc_mactotei_table.hashing_list[index1],
+ &entry->l_hash);
+ }
+ }
+ else
+ {
+ list_remove (&ctx->cl_eoc_mactotei_table.hashing_list[index],
+ &entry->l_hash);
+ list_remove (&ctx->cl_eoc_mactotei_table.ageing_list, &entry->l_age);
+ }
+ entry->tei = tei;
+ entry->mac_addr = mac_addr;
+ entry->reserved = 0;
+ entry->timestamp = cl_eoc_get_time (ctx);
+ list_push (&ctx->cl_eoc_mactotei_table.ageing_list, &entry->l_age);
+ list_push (&ctx->cl_eoc_mactotei_table.hashing_list[index], &entry->l_hash);
+ return true;
+}
+
+/** Remove all entries associated with given TEI from ageing and hashing lists
+ * of cl_eoc_mactotei_table
+ * \param ctx CL context
+ * \param tei TEI of the STA whose entries should be removed from the table
+*/
+void
+cl_eoc_mactotei_entry_remove (cl_t *ctx, uint tei)
+{
+ cl_eoc_mactotei_entry_t *entry = NULL;
+ list_node_t *list_node = NULL;
+
+ arch_dsr_lock ();
+ list_node = list_begin (&ctx->cl_eoc_mactotei_table.ageing_list);
+ while (list_node != &ctx->cl_eoc_mactotei_table.ageing_list.nil)
+ {
+ if (list_node)
+ entry = PARENT_OF (cl_eoc_mactotei_entry_t, l_age, list_node);
+ if (entry && (tei == entry->tei))
+ {
+ u8 index = MACTOTEI_HASHFUNC (entry->mac_addr);
+ list_remove (&ctx->cl_eoc_mactotei_table.hashing_list[index],
+ &entry->l_hash);
+ entry->tei = MAC_TEI_UNASSOCIATED;
+ entry->mac_addr = 0;
+ }
+ list_node = list_next (list_node);
+ }
+ arch_dsr_unlock ();
+}
+
+/** Set time during which entry will be valid
+ * \param ctx CL context
+ * \param max_dur_sec maximum duration of entry in seconds
+ */
+void
+cl_eoc_mactotei_set_entry_duration (cl_t * ctx, uint max_dur_sec)
+{
+ if ((max_dur_sec > MIN_ENTRY_AGE_SEC) && (max_dur_sec < MAX_ENTRY_AGE_SEC))
+ ctx->cl_eoc_mactotei_table.max_duration = max_dur_sec;
+}
+
+/** Return number of valid entries in mactotei table and store MAC adresses of
+ * valid entries
+ * \param ctx CL context
+ */
+uint
+cl_eoc_mactotei_entry_count (cl_t *ctx)
+{
+ uint valid_entries_nb = 0;
+ cl_eoc_mactotei_entry_t *entry = NULL;
+ list_node_t *list_node = NULL;
+
+ arch_dsr_lock ();
+ list_node = list_rbegin (&ctx->cl_eoc_mactotei_table.ageing_list);
+ while (list_node != &ctx->cl_eoc_mactotei_table.ageing_list.nil)
+ {
+ if (list_node)
+ entry = PARENT_OF (cl_eoc_mactotei_entry_t, l_age, list_node);
+ if (entry && !cl_eoc_is_obsolete (ctx, entry, cl_eoc_get_time (ctx)) &&
+ entry->mac_addr)
+ {
+ ctx->cl_eoc_mactotei_table.mac_snapshot[valid_entries_nb] =
+ entry->mac_addr;
+ valid_entries_nb++;
+ }
+ else
+ break;
+ list_node = list_prev (list_node);
+ }
+ arch_dsr_unlock ();
+
+ return valid_entries_nb;
+}
+
+/** Return mac addresses of valid entries in mactotei table
+ * \param ctx CL context
+ * \param next_mac next element in mac snapshot list to be read
+ */
+mac_t
+cl_eoc_mactotei_get_mac (cl_t *ctx, uint next_mac)
+{
+ return ctx->cl_eoc_mactotei_table.mac_snapshot[next_mac];
+}
diff --git a/cesar/cl/src/cl_mactotei.c b/cesar/cl/src/cl_mactotei.c
index e636bf9c80..5ace5a91ef 100644
--- a/cesar/cl/src/cl_mactotei.c
+++ b/cesar/cl/src/cl_mactotei.c
@@ -16,6 +16,8 @@
#include "cl/inc/cl.h"
#include "mac/common/defs.h"
+#include "config/cl/eoc.h"
+
/**
* Set a TEI and a tag in an extra information field.
* \param tei TEI to set.
diff --git a/cesar/cl/stub/Module b/cesar/cl/stub/Module
index 2ad195744b..91d67d50fc 100644
--- a/cesar/cl/stub/Module
+++ b/cesar/cl/stub/Module
@@ -1 +1,4 @@
SOURCES:=cl.c cl_mactotei.c bridge_table.c brg_rx.c
+ifeq ($(CONFIG_CL_EOC_ROUTE),y)
+SOURCES += cl_eoc_mactotei.c
+endif
diff --git a/cesar/cl/stub/src/cl_eoc_mactotei.c b/cesar/cl/stub/src/cl_eoc_mactotei.c
new file mode 100644
index 0000000000..031d51cc1d
--- /dev/null
+++ b/cesar/cl/stub/src/cl_eoc_mactotei.c
@@ -0,0 +1,30 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/src/cl_eoc_mactotei.c
+ * \brief MAC to TEI mapping for the Convergence Layer
+ * \ingroup cl
+ *
+ */
+#include "common/std.h"
+#include "cl/inc/context.h"
+#include "cl/cl_eoc_mactotei.h"
+#include "hal/arch/arch.h"
+#include "lib/stats.h"
+
+
+/** Put new MAC address in mactotei table.
+ * \param ctx CL context
+ * \param mac_addr MAC address of the packet
+ * \param tei TEI of the packet
+*/
+bool
+cl_eoc_mactotei_entry_insert (cl_t *ctx, mac_t mac_addr, uint tei)
+{
+ return true;
+}
diff --git a/cesar/cl/test/bridge_table/Makefile b/cesar/cl/test/bridge_table/Makefile
index 57bb69919f..cfd5bde28b 100644
--- a/cesar/cl/test/bridge_table/Makefile
+++ b/cesar/cl/test/bridge_table/Makefile
@@ -4,6 +4,7 @@ HOST_PROGRAMS = test_bridge_table
test_bridge_table_SOURCES = test_bridge_table.c
test_bridge_table_MODULES = lib cl
+test_bridge_table_CONFIG_MODULES = mac/common
# Overrides source of the cl module.
cl_MODULE_SOURCES = bridge_table.c
diff --git a/cesar/cl/test/utest_eoc/Config b/cesar/cl/test/utest_eoc/Config
new file mode 100644
index 0000000000..4d7a526742
--- /dev/null
+++ b/cesar/cl/test/utest_eoc/Config
@@ -0,0 +1,6 @@
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
diff --git a/cesar/cl/test/utest_eoc/Makefile b/cesar/cl/test/utest_eoc/Makefile
new file mode 100644
index 0000000000..9bee436431
--- /dev/null
+++ b/cesar/cl/test/utest_eoc/Makefile
@@ -0,0 +1,13 @@
+BASE = ../../../
+
+HOST_PROGRAMS = test_mactotei
+
+test_mactotei_SOURCES = test_mactotei.c ntb_stub.c
+
+test_mactotei_MODULES = lib cl mac/common mac/sar/stub
+
+mac_common_MODULE_SOURCES = config.c mfs.c store.c tonemap.c tonemask.c sta.c interval.c
+
+test_mactotei_MODULES_CONFIG = mac/sar
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cl/test/utest_eoc/src/ntb_stub.c b/cesar/cl/test/utest_eoc/src/ntb_stub.c
new file mode 100644
index 0000000000..3232410b0a
--- /dev/null
+++ b/cesar/cl/test/utest_eoc/src/ntb_stub.c
@@ -0,0 +1,33 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/ntb_stub.c
+ * \brief Stubs mac/common/ntb.c functions
+ * \ingroup utest_eoc
+ */
+#include "common/std.h"
+
+u32
+mac_ntb(void)
+{
+ static int i = 0;
+ i += 50000;
+ return i;
+}
+
+u32
+mac_date (void)
+{
+ return 0;
+}
+
+u32
+phy_date(void)
+{
+ return mac_ntb();
+}
diff --git a/cesar/cl/test/utest_eoc/src/test_mactotei.c b/cesar/cl/test/utest_eoc/src/test_mactotei.c
new file mode 100644
index 0000000000..c4cffb9561
--- /dev/null
+++ b/cesar/cl/test/utest_eoc/src/test_mactotei.c
@@ -0,0 +1,194 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_mactotei.c
+ * \brief Unit test for EoC mactotei table in the CL module.
+ * \ingroup cl
+ *
+ * This suite tests functions used for creating, refreshing and finding entries
+ * of EoC mactotei table.
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "lib/stats.h"
+#include "cl/inc/context.h"
+#include "cl/cl_eoc_mactotei.h"
+
+static cl_t cl;
+static mac_config_t mac_config;
+
+void
+test_entries (test_t test)
+{
+ cl.mac_config = &mac_config;
+ list_node_t *list_node = NULL;
+ cl_eoc_mactotei_entry_t *entry;
+ uint i,tei;
+ bool ok;
+
+ lib_stats_init ();
+ test_case_begin (test, "MACtoTEI table");
+ test_begin (test, "Initialize")
+ {
+ cl_eoc_mactotei_init (&cl);
+ i = 0;
+ list_node = list_next (&cl.cl_eoc_mactotei_table.ageing_list.nil);
+ do
+ {
+ entry = PARENT_OF (cl_eoc_mactotei_entry_t, l_age, list_node);
+ test_fail_unless (entry->timestamp == i);
+ i++;
+ list_node = list_next (list_node);
+ } while (list_node != &cl.cl_eoc_mactotei_table.ageing_list.nil);
+ test_fail_unless (i == MACTOTEI_NB_ENTRIES);
+ }
+ test_end;
+
+ test_begin (test, "Fill table")
+ {
+ cl.mac_config->tei = 1;
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445566ull, 4);
+ test_fail_if (!ok);
+ tei = cl_eoc_mactotei_find_tei (&cl, 0x0000112233445566ull);
+ test_fail_unless (tei == 4);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445577ull, 5);
+ test_fail_if (!ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445588ull, 10);
+ test_fail_if (!ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000122233445513ull, 5);
+ test_fail_if (!ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445599ull, 21);
+ test_fail_if (!ok);
+ tei = cl_eoc_mactotei_find_tei (&cl, 0x0000112233445588ull);
+ test_fail_unless (tei == 10);
+ cl_eoc_mactotei_entry_remove (&cl, 5);
+ cl_eoc_mactotei_entry_remove (&cl, 21);
+ cl_eoc_mactotei_entry_remove (&cl, 35);
+ tei = cl_eoc_mactotei_find_tei (&cl, 0x0000112233445577ull);
+ test_fail_unless (tei == MAC_TEI_UNASSOCIATED);
+
+ u64 mac_addr = 0x0000112233445512ull;
+ for (i = 0; i < 5 * MACTOTEI_NB_ENTRIES; i++)
+ {
+ mac_addr -= 0x1000000;
+ ok = cl_eoc_mactotei_entry_insert (&cl, mac_addr,
+ i % MACTOTEI_NB_ENTRIES);
+ test_fail_if (!ok);
+ }
+ cl_eoc_mactotei_entry_remove (&cl, 12);
+ }
+ test_end;
+
+ test_begin (test, "Obsoleteness & refresh")
+ {
+ list_node = list_prev (&cl.cl_eoc_mactotei_table.ageing_list.nil);
+ entry = PARENT_OF (cl_eoc_mactotei_entry_t, l_age, list_node);
+
+ /* increment time to exceed max age duration */
+ for (i = 0; i < 1.1*(cl.cl_eoc_mactotei_table.max_duration); i++)
+ cl_eoc_time_update (&cl);
+
+ tei = cl_eoc_mactotei_find_tei (&cl, entry->mac_addr);
+ test_fail_if (tei != MAC_TEI_UNASSOCIATED);
+
+ ok = cl_eoc_mactotei_entry_insert (&cl, entry->mac_addr, 111);
+ tei = cl_eoc_mactotei_find_tei (&cl, entry->mac_addr);
+ test_fail_if (tei != 111);
+ ok = cl_eoc_mactotei_entry_insert (&cl, entry->mac_addr, 111);
+ test_fail_if (!ok);
+
+ for (i = 0; i < 1234; i++)
+ {
+ ok = cl_eoc_mactotei_entry_insert (&cl, entry->mac_addr, 111);
+ test_fail_if (!ok);
+ }
+ }
+ test_end;
+
+ test_begin (test, "Limitation of entries")
+ {
+ cl.mac_config->tei = 5;
+ cl_eoc_mactotei_init (&cl);
+ u64 mac_addr = 0x0000112233445566ull;
+ for (i = 0; i < cl.cl_eoc_mactotei_table.max_entries; i++)
+ {
+ mac_addr += 0x123456789ull;
+ ok = cl_eoc_mactotei_entry_insert (&cl, mac_addr, 5);
+ test_fail_if (!ok);
+ }
+ /* no new addresses allowed from sta side, as source addresses */
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000132233445588ull, 5);
+ test_fail_if (ok);
+ /* new addresses allowed as destination addresses*/
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000132233445511ull, 1);
+ test_fail_unless (ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000132233442511ull, 1);
+ test_fail_unless (ok);
+ test_fail_unless (cl.cl_eoc_mactotei_table.num_of_entries ==
+ cl.cl_eoc_mactotei_table.max_entries);
+
+ /* increment time to exceed max age duration */
+ for (i = 0; i < 1.1*(cl.cl_eoc_mactotei_table.max_duration); i++)
+ cl_eoc_time_update (&cl);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000132233445588ull, 5);
+ test_fail_unless (ok);
+ test_fail_unless (cl.cl_eoc_mactotei_table.num_of_entries == 1);
+ }
+ test_end;
+
+ test_begin (test, "Bridge info")
+ {
+ uint nb_entry;
+ mac_t mac, mac_ref;
+ cl_eoc_mactotei_init (&cl);
+ cl.mac_config->tei = 1;
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445566ull, 4);
+ test_fail_if (!ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445577ull, 5);
+ test_fail_if (!ok);
+ for (i = 0; i < 0.9*(cl.cl_eoc_mactotei_table.max_duration); i++)
+ cl_eoc_time_update (&cl);
+ nb_entry = cl_eoc_mactotei_entry_count (&cl);
+ test_fail_unless (nb_entry == 2);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445512ull, 6);
+ test_fail_if (!ok);
+ nb_entry = cl_eoc_mactotei_entry_count (&cl);
+ test_fail_unless (nb_entry == 3);
+ for (i = 0; i < 0.3*(cl.cl_eoc_mactotei_table.max_duration); i++)
+ cl_eoc_time_update (&cl);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445513ull, 7);
+ test_fail_if (!ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445514ull, 8);
+ test_fail_if (!ok);
+ ok = cl_eoc_mactotei_entry_insert (&cl, 0x0000112233445515ull, 9);
+ test_fail_if (!ok);
+ nb_entry = cl_eoc_mactotei_entry_count (&cl);
+ test_fail_unless (nb_entry == 4);
+ mac_ref = 0x0000112233445515ull;
+ for (i = 0; i < nb_entry; i++)
+ {
+ mac = cl_eoc_mactotei_get_mac (&cl, i);
+ test_fail_unless (mac == mac_ref - i);
+ }
+ }
+ test_end;
+}
+
+int
+main (void)
+{
+ test_t test;
+ test_init (test, 0, NULL);
+
+ test_suite_begin (test, "Cl_EoC: MAC to Tei");
+ test_entries (test);
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/cesar/common/defs/ethernet.h b/cesar/common/defs/ethernet.h
index 2ca1fe8cbc..333f7cc547 100644
--- a/cesar/common/defs/ethernet.h
+++ b/cesar/common/defs/ethernet.h
@@ -22,7 +22,7 @@
#define ETH_PACKET_MIN_SIZE 60
/** Ethernet packet maximum size. */
-#define ETH_PACKET_MAX_SIZE 1518
+#define ETH_PACKET_MAX_SIZE 1522
/** Ethernet VLAN Tag complete size. */
#define ETH_VLAN_TAG_SIZE 4
diff --git a/cesar/common/defs/homeplugAV.h b/cesar/common/defs/homeplugAV.h
index 0a06f7da7c..6364ca435a 100644
--- a/cesar/common/defs/homeplugAV.h
+++ b/cesar/common/defs/homeplugAV.h
@@ -61,7 +61,7 @@
#define HPAV_CRC32_MAGIC 0x2144df1c
/** Nek change. */
-#define HPAV_NEK_CHANGE_MS 3600000
+#define HPAV_NEK_CHANGE_MS 3600000 * 24
/** Access or in home value. */
enum hpav_access_t
diff --git a/cesar/common/tests/tests b/cesar/common/tests/tests
index 83a7fe56b5..b5c46c5b5f 100644
--- a/cesar/common/tests/tests
+++ b/cesar/common/tests/tests
@@ -185,6 +185,10 @@ mac/ca/test/ca:
make: make COV=y
cov test_ca: ./obj/test_ca
+mac/ca/test/ca_eoc:
+make: make COV=y
+cov test_ca_eoc: ./obj/test_ca
+
mac/common/test/mfs:
make
run: ./obj/test_mfs
@@ -231,6 +235,10 @@ mac/pbproc/test/pbproc:
make: make COV=y
cov test_pbproc: ./obj/test_pbproc
+mac/pbproc/test/pbproc_eoc:
+make: make COV=y
+cov test_pbproc_eoc: ./obj/test_pbproc
+
mac/pbproc/test/int:
make
run: python py/host_test_pbproc.py --maximus
@@ -312,6 +320,17 @@ make
python test1.py -d false -t 2500000000
python test2.py -d false -t 2500000000
+test_general/maximus/integration/sar-pbproc-eoc:
+make
+python test1.py -d false -t 2500000000
+python test2.py -d false -t 2500000000
+python test_eoc_2sta.py -d false -t 2500000000
+python test_eoc_2sta_csmaonly.py -d false -t 2500000000
+python test_eoc_2stasound.py -d false -t 2500000000
+python test_eoc_3sta.py -d false -t 2500000000
+python test_eoc_3sta1bad.py -d false -t 2500000000
+python test_eoc_multista.py -d false -t 2500000000
+
test_general/maximus/integration/hle-cl-sar-pbproc:
make
python test1.py -d false -t 2500000000
@@ -479,7 +498,35 @@ region: ./obj/region
hal/phy/spoc/test:
make host.all
-test_spoc: ./obj/test_spoc
+spoc: ./obj/spoc_host_check_coeff
+
+cp/beacon/test/utest_eoc:
+make
+beaconeoc: ./obj/beacon.elf
+
+test_general/station/compliance-eoc:
+make
+test02_eoc_beacon: python py/test02_eoc_beacon.py --maximus
+
+cp/eoc/cco/action/test/utest:
+make: make COV=y
+cov test_fsm: ./obj/fsm/test_fsm
+cov test_actions: ./obj/actions/test_actions
+
+
+cp/eoc/sta/action/test/utest:
+make: make COV=y
+cov test_fsm: ./obj/fsm/test_fsm
+cov test_actions: ./obj/actions/test_actions
+
+cp/eoc/multi_sta_fsm/test/utest:
+make: make COV=y
+cov test_fsm: ./obj/test_fsm
+
+cp/eoc/multi_sta/action/test/utest:
+make: make COV=y
+cov test_fsm: ./obj/fsm/test_fsm
+cov test_actions: ./obj/actions/test_actions
test_general/station/compliance:
make
diff --git a/cesar/common/tools/build-info b/cesar/common/tools/build-info
index 8a6f81b07f..df1e6b100b 100755
--- a/cesar/common/tools/build-info
+++ b/cesar/common/tools/build-info
@@ -92,6 +92,7 @@ else
# Header output.
my $name = $header;
$name =~ tr#/\.#__#;
+ $name =~ s/\-/\_/g;
my $new = <<EOF;
#ifndef $name
#define $name
diff --git a/cesar/cp/Config b/cesar/cp/Config
new file mode 100644
index 0000000000..fdbc465023
--- /dev/null
+++ b/cesar/cp/Config
@@ -0,0 +1,2 @@
+CONFIG_CP_EOC_SCHEDULER = n
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 0
diff --git a/cesar/cp/beacon/Config b/cesar/cp/beacon/Config
index 876dd03ed0..f7a592de13 100644
--- a/cesar/cp/beacon/Config
+++ b/cesar/cp/beacon/Config
@@ -1,3 +1,6 @@
+CONFIG_CP_BEACON_REGION = y
+CONFIG_CP_BEACON_DISCOVER = y
CONFIG_GPIO_LED_BEACON_TX_RX = n
CONFIG_GPIO_LED_BEACON_TX_RX_GPIO = 0
-CONFIG_BEACON_SPOC_UPDATE_INTERVAL_DEFAULT_MS = 400
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = n
+CONFIG_BEACON_SPOC_UPDATE_INTERVAL_DEFAULT_MS = 0
diff --git a/cesar/cp/beacon/beacon.h b/cesar/cp/beacon/beacon.h
index ccecfa00d6..99f6df3a2e 100644
--- a/cesar/cp/beacon/beacon.h
+++ b/cesar/cp/beacon/beacon.h
@@ -116,6 +116,13 @@ void
cp_beacon_change_nek (cp_t *ctx, uint eks, cp_key_t nek, bool now);
/**
+ * Adjust the index value for nek.
+ * \param nek_index index to be applied as current.
+ */
+void
+cp_beacon_nek_index_adjust (cp_t *ctx, uint nek_index);
+
+/**
* Handover.
* \param ctx the CP context.
* \param tei the TEI of the new CCo on the AVLN.
diff --git a/cesar/cp/beacon/src/beacon.c b/cesar/cp/beacon/src/beacon.c
index 1ca8b03c64..227077da1b 100644
--- a/cesar/cp/beacon/src/beacon.c
+++ b/cesar/cp/beacon/src/beacon.c
@@ -32,9 +32,13 @@
#include "cp/beacon/discover.h"
#include "cp/inc/context.h"
#include "cp/inc/trace.h"
+#include "cp/eoc/cco/bw/bw.h"
#include "hal/gpio/gpio.h"
#include "bsu/beacon/beacon.h"
#include "bsu/bsu.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "config/cp/beacon.h"
+
#include "config/beacon.h"
/** Default interval between SPOC updates. */
@@ -48,9 +52,10 @@ static void
cp_beacon_timer_expires (cp_t *ctx)
{
dbg_assert (ctx);
-
// Post an event in the FSM beacon timer expires.
cp_fsm_post_urgent_new_event (ctx, bare, BEACON_TIMER_EXPIRES);
+ if (cp_sta_own_data_get_cco_status (ctx))
+ cp_beacon_cco_update_beacon_data (ctx);
}
/**
@@ -121,25 +126,30 @@ cp_beacon_fill (cp_t *ctx, bsu_beacon_t *beacon)
beacon->vf.aclsss = 0;
beacon->vf.hoip = ctx->beacon.hoip.hoip_flag;
beacon->vf.rtsbf = false;
- beacon->vf.nm =
- net == NULL ? BSU_BEACON_NM_CSMA_ONLY : cp_net_get_nm (ctx, net);
+ beacon->vf.nm = (CONFIG_CP_BEACON_EOC_SPC_CENTRAL) ?
+ BSU_BEACON_NM_COORDINATED :
+ net == NULL ? BSU_BEACON_NM_CSMA_ONLY : cp_net_get_nm (ctx, net);
beacon->vf.ccocap = CP_CCO_LEVEL;
- /* regions. */
- cp_cco_region_alloc_t *region;
-
- for (nb = 0, region = cp_cco_region_alloc_get_first (ctx,
- &ctx->region.region_list);
- region;
- region = cp_cco_region_alloc_get_next (ctx,
- &ctx->region.region_list, region),
- nb++)
+ if (!CONFIG_CP_BEACON_EOC_SPC_CENTRAL)
{
- beacon->bmis.region.region[nb].rt = region->type;
- beacon->bmis.region.region[nb].end_time_atu = region->end_time_atu;
+ /* regions. */
+ cp_cco_region_alloc_t *region;
+
+ for (nb = 0, region = cp_cco_region_alloc_get_first (ctx,
+ &ctx->region.region_list);
+ region;
+ region = cp_cco_region_alloc_get_next (ctx,
+ &ctx->region.region_list, region),
+ nb++)
+ {
+ beacon->bmis.region.region[nb].rt = region->type;
+ beacon->bmis.region.region[nb].end_time_atu = region->end_time_atu;
+ }
}
+ else
+ nb = 0;
beacon->bmis.region.nb = nb;
-
/* Store the persistent schedules. */
uint sched_id = 0;
cp_cco_bw_alloc_t *sched;
@@ -195,7 +205,8 @@ cp_beacon_fill (cp_t *ctx, bsu_beacon_t *beacon)
beacon->bmis.nps.ns = ns;
uint tei;
- if (cp_sta_own_data_get_cco_status (ctx)
+ if (!CONFIG_CP_BEACON_EOC_SPC_CENTRAL
+ && cp_sta_own_data_get_cco_status (ctx)
&& cp_beacon_discover_need_to_request (ctx, &tei))
{
beacon->bmis.discover.present = true;
@@ -438,14 +449,6 @@ cp_beacon_countdowns (cp_t *ctx)
intervals = (intervals + bp/2 - ctx->beacon.last_countdown_date) / bp;
- /** We missed too many beacon period we shouldn't be associated
- * anymore.
- */
- if (intervals > CP_MAX_NO_BEACON + 1)
- {
- return;
- }
-
ctx->beacon.last_countdown_date = ctx->beacon.countdown_limit_date;
/** Update the countdown limit for next time. */
@@ -521,7 +524,6 @@ cp_beacon_countdowns (cp_t *ctx)
bsu_nek_index_current (ctx->bsu)].eks == MAC_EKS_CLEAR)
/* Countdown elapsed and no NEK is available */
cp_fsm_trigger_new_event (ctx, bare, to_leave);
-
ctx->beacon.eks.kbc = BSU_BEACON_EKS_KBC_NB;
ctx->mac_config->nek[bsu_nek_index_next (ctx->bsu)].eks =
MAC_EKS_CLEAR;
@@ -685,14 +687,12 @@ cp_beacon_process_beacon_central (
}
if (beacon->bmis.eks.present)
{
- if ((beacon->bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK) &&
- (ctx->mac_config->nek[bsu_nek_index_next (ctx->bsu)].eks !=
+ if ((beacon->bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK)
+ && (beacon->bmis.eks.new_eks != bsu_nek_index_current (ctx->bsu))
+ && (ctx->mac_config->nek[bsu_nek_index_next (ctx->bsu)].eks !=
beacon->bmis.eks.new_eks))
- {
- /* POST the FSM event. */
- cp_fsm_post_new_event (ctx, bare, nek_request);
- }
-
+ /* POST the FSM event. */
+ cp_fsm_post_new_event (ctx, bare, sta_not_polled);
ctx->beacon.eks.kccd = beacon->bmis.eks.kccd;
ctx->beacon.eks.kbc = beacon->bmis.eks.kbc;
ctx->beacon.eks.new_eks =
@@ -949,9 +949,13 @@ cp_beacon_change_nek (cp_t *ctx, uint eks, cp_key_t nek, bool now)
else
{
index = bsu_nek_index_next (ctx->bsu);
- ctx->beacon.eks.kccd = CP_BEACON_COUNTDOWN_EKS;
- ctx->beacon.eks.kbc = BSU_BEACON_EKS_KBC_NEK;
- ctx->beacon.eks.new_eks = eks;
+ /* only cco could start nek exchange countdown */
+ if (cp_sta_own_data_get_cco_status (ctx))
+ {
+ ctx->beacon.eks.kccd = CP_BEACON_COUNTDOWN_EKS;
+ ctx->beacon.eks.kbc = BSU_BEACON_EKS_KBC_NEK;
+ ctx->beacon.eks.new_eks = eks;
+ }
}
cp_secu_pbb_dec_gen (nek, &rnek);
@@ -966,6 +970,12 @@ cp_beacon_change_nek (cp_t *ctx, uint eks, cp_key_t nek, bool now)
ctx->mac_config->nek[index].eks = eks;
}
+void
+cp_beacon_nek_index_adjust (cp_t *ctx, uint nek_index)
+{
+ dbg_assert (ctx);
+ bsu_nek_index_adjust (nek_index);
+}
/**
* Deactivate the Beacon module.
* \param ctx the CP context.
@@ -1046,7 +1056,6 @@ cp_beacon_reconfigure_timer (cp_t *ctx, bool cco)
else
date = bsu_aclf_beacon_period_start_date_next (ctx->bsu_aclf) +
CP_TIMER_OFFSET_STA;
-
// Program the timer.
hal_timer_instance_cancel (ctx->hal_timer, &ctx->beacon.leon_timer);
hal_timer_instance_program (ctx->hal_timer, &ctx->beacon.leon_timer,
diff --git a/cesar/cp/beacon/stub/src/beacon.c b/cesar/cp/beacon/stub/src/beacon.c
index 85f9dc09cb..415586261e 100644
--- a/cesar/cp/beacon/stub/src/beacon.c
+++ b/cesar/cp/beacon/stub/src/beacon.c
@@ -142,3 +142,21 @@ cp_beacon_fill (cp_t *ctx, bsu_beacon_t *beacon) __attribute__ ((weak));
void
cp_beacon_fill (cp_t *ctx, bsu_beacon_t *beacon) { };
+
+void
+cp_beacon_deactivate (cp_t *ctx) __attribute__ ((weak));
+
+void
+cp_beacon_deactivate (cp_t *ctx) {};
+
+void
+cp_beacon_poweron_init (cp_t *ctx) __attribute__ ((weak));
+
+void
+cp_beacon_poweron_init (cp_t *ctx){};
+
+void
+cp_beacon_nek_index_adjust (cp_t *ctx, uint nek_index) __attribute__ ((weak));
+
+void
+cp_beacon_nek_index_adjust (cp_t *ctx, uint nek_index) {};
diff --git a/cesar/cp/beacon/test/utest_eoc/Config b/cesar/cp/beacon/test/utest_eoc/Config
new file mode 100644
index 0000000000..8bcc395765
--- /dev/null
+++ b/cesar/cp/beacon/test/utest_eoc/Config
@@ -0,0 +1,6 @@
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_BEACON_REGION = n
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CL_EOC_ROUTE = y
diff --git a/cesar/cp/beacon/test/utest_eoc/Makefile b/cesar/cp/beacon/test/utest_eoc/Makefile
new file mode 100644
index 0000000000..778cb26894
--- /dev/null
+++ b/cesar/cp/beacon/test/utest_eoc/Makefile
@@ -0,0 +1,15 @@
+BASE = ../../../..
+
+ECOS = n
+
+TARGET_PROGRAMS = beacon
+
+beacon_SOURCES = beacon.c phy_stub.c
+
+beacon_MODULES = lib cp/beacon mac/common cp/cco/bw \
+ cp/cco/region cp/sta/mgr cp/fsm/stub \
+ cp/eoc/cco/bw
+
+beacon_MODULES_CONFIG = cp mac/sar cl
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/beacon/test/utest_eoc/ecos.ecc.sh b/cesar/cp/beacon/test/utest_eoc/ecos.ecc.sh
new file mode 100644
index 0000000000..e49dc132f3
--- /dev/null
+++ b/cesar/cp/beacon/test/utest_eoc/ecos.ecc.sh
@@ -0,0 +1,6 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new linux default
+cat >> $config <<EOF
+EOF
+ecosconfig --config=$config check
+
diff --git a/cesar/cp/beacon/test/utest_eoc/src/beacon.c b/cesar/cp/beacon/test/utest_eoc/src/beacon.c
new file mode 100644
index 0000000000..47cc4aabc9
--- /dev/null
+++ b/cesar/cp/beacon/test/utest_eoc/src/beacon.c
@@ -0,0 +1,261 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/beacon.c
+ * \brief Unit test of changes done for EoC in the beacon module.
+ * \ingroup cp_beacon
+ *
+ * This test checks beacon with bentries need for EoC. Packing at
+ * tx and unpacking at rx side
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+
+#include "cp/beacon/beacon.h"
+#include "cp/beacon/inc/beacon_discover.h"
+#include "cp/beacon/inc/unpack.h"
+#include "cp/beacon/inc/bentry_size.h"
+#include "cp/beacon/inc/unpack.h"
+
+#include "cp/cp.h"
+#include "cp/inc/context.h"
+#include "cp/eoc/cco/bw/bw.h"
+
+#include "config/atu/factor.h"
+
+static cp_t cp;
+
+void
+cp_eoc_cco_bw_bp_allocations (cp_t *ctx);
+
+/** EOC BEACON.
+ * \param test the test object.
+ *
+ * Pack - use cp_eoc_cco_bw_bp_allocations to add schedule
+ * bentry to beacon.
+ * Unpack - read content of beacon .
+ */
+void
+test_suite_beacon_eoc (test_t test)
+{
+ cp_beacon_unpack_t unpack_tx, unpack_rx;
+ cp_beacon_desc_t *beacon_tx, *beacon_rx;
+ cp_beacon_unpack_schedule_t *sched;
+ uint i;
+ bool ok;
+ set_t regions, schedules;
+
+ test_suite_begin (test, "EoC Beacon");
+
+ test_case_begin (test, "Pack");
+
+ cp_cco_bw_init (&cp);
+ cp_beacon_unpack_init (&unpack_tx, &cp.bw.alloc_list, &cp.region.region_list);
+
+ unpack_tx.variant_fields.nid_lsb = 2;
+ unpack_tx.variant_fields.nid_msb = 1;
+ unpack_tx.variant_fields.hm = 1;
+ unpack_tx.variant_fields.stei = 1;
+ unpack_tx.variant_fields.bt = CP_BEACON_CENTRAL_BEACON;
+ unpack_tx.variant_fields.ncnr = false;
+ unpack_tx.variant_fields.npsm = false;
+ unpack_tx.variant_fields.num_slots = 0;
+ unpack_tx.variant_fields.slot_usage = 0;
+ unpack_tx.variant_fields.slot_id = 0;
+ unpack_tx.variant_fields.aclss = true;
+ unpack_tx.variant_fields.hoip = false;
+ unpack_tx.variant_fields.rtsbf = false;
+ unpack_tx.variant_fields.nm = CP_BEACON_NM_UNCOORDINATED;
+ unpack_tx.variant_fields.cco_cap = CP_CCO_LEVEL;
+
+ unpack_tx.bmis.regions.present = false;
+ unpack_tx.bmis.schedules.present = true;
+ unpack_tx.bmis.mac_address.present = true;
+ unpack_tx.bmis.mac_address.mac_addr = 0x1234567890abull;
+ unpack_tx.bmis.bpsto.present = false;
+ unpack_tx.nbe = 2;
+
+ cp_eoc_cco_bw_bp_allocations (&cp);
+
+ beacon_tx = cp_beacon_unpack__pack (&cp, &unpack_tx);
+
+ test_begin (test, "Check tx benrty")
+ {
+ i = 0;
+ for (sched = cp_cco_bw_alloc_get_first (&cp, unpack_tx.bmis.schedules.set);
+ sched;
+ sched = cp_cco_bw_alloc_get_next (&cp, unpack_tx.bmis.schedules.set, sched),
+ i++)
+ {
+ if (i == 0)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_SPC_CENTRAL);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(MIN_SPC_CENTRAL_TCK));
+ }
+
+ if (i == 1)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_LOCAL_CSMA);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(CP_EOC_CSMA_STARTUP_PERIOD));
+ }
+
+ if (i == 2)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_CFPI);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(CP_PWL_BP_EOC));
+ }
+ }
+ test_fail_unless (i == 3);
+ }
+ test_end;
+
+ test_case_begin (test, "Unpack");
+
+ beacon_rx = beacon_tx;
+
+ test_begin (test, "Check rx benrty")
+ {
+ i = 0;
+ set_init (&schedules, cp_cco_bw_alloc_less);
+ set_init (&regions, cp_cco_region_alloc_less);
+ cp_beacon_unpack_init (&unpack_rx, &schedules, &regions);
+ ok = cp_beacon_unpack__unpack (&cp, &unpack_rx, beacon_rx);
+
+ test_fail_if (!ok);
+ test_fail_if (CONFIG_ATU_FACTOR != 3);
+
+ for (sched = cp_cco_bw_alloc_get_first (&cp, unpack_rx.bmis.schedules.set);
+ sched;
+ sched = cp_cco_bw_alloc_get_next (&cp, unpack_rx.bmis.schedules.set, sched),
+ i++)
+ {
+ if (i == 0)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_SPC_CENTRAL);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(MIN_SPC_CENTRAL_TCK));
+ }
+
+ if (i == 1)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_LOCAL_CSMA);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(CP_EOC_CSMA_STARTUP_PERIOD));
+ }
+
+ if (i == 2)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_CFPI);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(CP_PWL_BP_EOC));
+ }
+ }
+ test_fail_unless (i == 3);
+ }
+ test_end;
+
+ test_begin (test, "Startup_expiration")
+ {
+ /* wait for startup period to expire*/
+ uint expiration_date = CP_EOC_CCO_STARTUP_PERIOD / 50000;
+ for (i = 0; i < expiration_date + 1; i++)
+ phy_date ();
+
+ i = 0;
+ cp_eoc_cco_bw_bp_allocations (&cp);
+ beacon_tx = cp_beacon_unpack__pack (&cp, &unpack_tx);
+
+ for (sched = cp_cco_bw_alloc_get_first (&cp, unpack_tx.bmis.schedules.set);
+ sched;
+ sched = cp_cco_bw_alloc_get_next (&cp, unpack_tx.bmis.schedules.set, sched),
+ i++)
+ {
+ if (i == 1)
+ {
+ test_fail_unless (sched != NULL);
+ test_fail_unless (sched->persistence ==
+ CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT);
+ test_fail_unless (sched->pscd == 0);
+ test_fail_unless (sched->cscd == 0);
+ test_fail_unless (sched->stpf == false);
+ test_fail_unless (sched->glid == MAC_LID_LOCAL_CSMA);
+ test_fail_unless (sched->end_time_atu ==
+ MAC_TCK_TO_ATU(MIN_CSMA_EOC_TCK));
+ }
+ }
+ blk_release_desc ( (blk_t *) beacon_tx);
+ }
+ test_end;
+
+ blk_release_desc ( (blk_t *) beacon_rx);
+ cp_cco_bw_alloc_clean (&cp, &schedules);
+ cp_cco_region_alloc_clean (&cp, &regions);
+ cp_cco_bw_uninit (&cp);
+ cp_beacon_unpack_uninit (&cp, &unpack_tx);
+ cp_beacon_unpack_uninit (&cp, &unpack_rx);
+}
+
+int
+main (void)
+{
+ test_t test;
+ test_init (test, 0, NULL);
+
+ test_suite_beacon_eoc (test);
+
+ test_case_begin (test, "Memory allocation");
+ test_begin (test, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+
+ test_result (test);
+ HAL_PLATFORM_EXIT (test_nb_failed (test) == 0 ? 0 : 1);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/beacon/test/utest_eoc/src/phy_stub.c b/cesar/cp/beacon/test/utest_eoc/src/phy_stub.c
new file mode 100644
index 0000000000..ebdc0781ca
--- /dev/null
+++ b/cesar/cp/beacon/test/utest_eoc/src/phy_stub.c
@@ -0,0 +1,21 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/ntb_stub.c
+ * \brief Stubs mac/common/ntb.c functions
+ * \ingroup utest_eoc
+ */
+#include "common/std.h"
+
+u32
+phy_date(void)
+{
+ static int i = 0;
+ i += 50000;
+ return i;
+}
diff --git a/cesar/cp/cco/action/inc/cco_action.h b/cesar/cp/cco/action/inc/cco_action.h
index 35efccba91..5db3934c00 100644
--- a/cesar/cp/cco/action/inc/cco_action.h
+++ b/cesar/cp/cco/action/inc/cco_action.h
@@ -29,10 +29,11 @@
/* Return the next EKS value from the previous one. */
#define CP_CCO_ACTION_EKS_NEXT(val) \
- (((val) + 1 > MAC_EKS_MAX) ? MAC_EKS_MIN : val + 1)
+ (((val) + 1 == MAC_EKS_MAX) ? MAC_EKS_MIN : val + 1)
/* Timeout value for the EKS exchange MME. */
-#define CP_CCO_ACTION_EKS_TIMEOUT_MS 1000
+#define CP_CCO_ACTION_EKS_TIMEOUT_MS 3000
+#define CP_EOC_CCO_EKS_RETRY 3
struct cp_cco_action_t
{
@@ -43,6 +44,8 @@ struct cp_cco_action_t
cp_sta_core_timed_event_def_t nek_change;
/** EKS timeout. */
cp_sta_core_timed_event_def_t eks_timer;
+ /** Timer to remove unauthorized slaves */
+ cp_sta_core_timed_event_def_t leave_timer;
/** EKS value to change. */
uint eks_current;
/** The new NEK. */
@@ -51,7 +54,14 @@ struct cp_cco_action_t
cp_mme_peer_t eks_sta_current_peer;
/** EKS protocol run. */
cp_secu_protocol_run_t eks_prun;
-
+ /** EKS-EoC - number of retries in key change */
+ uint eks_eoc_retry;
+ /** CCo accept each station */
+ uint wl_accept_all;
+ /** Default output power for golden master*/
+ uint gm_default_output_power;
+ /** EoC last output date in ticks */
+ u32 last_date;
/** heap for the CCo selection process. */
heap_t selection_heap;
};
diff --git a/cesar/cp/cco/action/test/Makefile b/cesar/cp/cco/action/test/Makefile
index 36c719e479..6b420bd139 100644
--- a/cesar/cp/cco/action/test/Makefile
+++ b/cesar/cp/cco/action/test/Makefile
@@ -14,6 +14,7 @@ action_MODULES = lib cp/cco/action mac/common cp/sta/mgr \
cp/fsm/stub cp/beacon/stub cl/stub\
cp/secu cp/msg/stub bsu/stub cp/cco/region/stub \
cp/cco/bw/stub
+action_CONFIG_MODULES = cl
garbage_SOURCES = garbage.c core_stub.c \
sar_stub.c pbproc_stub.c sta_action.c
@@ -43,5 +44,6 @@ fsm_handover_MODULES= lib cp/cco/action mac/common cp/sta/mgr \
cp/fsm/stub cp/beacon/stub cp/sta/core/stub \
cp/msg/stub cl/stub mac/sar/stub \
bsu/stub cp/cco/region/stub cp/cco/bw/stub
+fsm_handover_CONFIG_MODULES = cl
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/cco/action/test/src/sar_stub.c b/cesar/cp/cco/action/test/src/sar_stub.c
index 4a65d0b9c1..94af975b13 100644
--- a/cesar/cp/cco/action/test/src/sar_stub.c
+++ b/cesar/cp/cco/action/test/src/sar_stub.c
@@ -35,11 +35,6 @@ sar_sta_remove (sar_t *ctx, u8 tei)
}
void
-sar_activate (sar_t *ctx, bool state)
-{
-}
-
-void
sar_cleanup (sar_t *ctx)
{
}
diff --git a/cesar/cp/cco/bw/test/Makefile b/cesar/cp/cco/bw/test/Makefile
index 258b0961e9..6638f1534f 100644
--- a/cesar/cp/cco/bw/test/Makefile
+++ b/cesar/cp/cco/bw/test/Makefile
@@ -5,5 +5,6 @@ INCLUDES=cp/cco/bw/test/override
HOST_PROGRAMS = bw
bw_SOURCES = bw.c
bw_MODULES = lib cp/cco/bw
+bw_CONFIG_MODULES = mac/common
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/cco/region/test/Makefile b/cesar/cp/cco/region/test/Makefile
index 5e6e88a54a..f58f346342 100644
--- a/cesar/cp/cco/region/test/Makefile
+++ b/cesar/cp/cco/region/test/Makefile
@@ -5,5 +5,6 @@ INCLUDES=cp/cco/region/test/override
HOST_PROGRAMS = region
region_SOURCES = region.c
region_MODULES = lib cp/cco/region
+region_CONFIG_MODULES = mac/common
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/cl_interf/src/cl_interf.c b/cesar/cp/cl_interf/src/cl_interf.c
index cf4a2d2936..defcc7e936 100644
--- a/cesar/cp/cl_interf/src/cl_interf.c
+++ b/cesar/cp/cl_interf/src/cl_interf.c
@@ -179,7 +179,7 @@ cp_cl_interf_process_mme (cp_t *ctx)
* we can drop it.
*
* http://standards.ieee.org/develop/regauth/oui/oui.txt */
- if (mme->mmtype < VS_MIN)
+ if (mme->mmtype < VS_MIN && msg->tei != MAC_TEI_FOREIGN)
{
bool last_mme;
uint ssn;
diff --git a/cesar/cp/cl_interf/test/Makefile b/cesar/cp/cl_interf/test/Makefile
index 6ba1ed3365..4eb62e91cb 100644
--- a/cesar/cp/cl_interf/test/Makefile
+++ b/cesar/cp/cl_interf/test/Makefile
@@ -9,5 +9,6 @@ test-cl-interf_MODULES = lib cp/cl_interf cp/sta/mgr mac/common \
cp/secu cp/fsm/stub cp/cco/action/stub \
cp/sta/core/stub mac/sar/stub cl/stub \
bsu/stub cp/msg/stub
+test-cl-interf_CONFIG_MODULES = cl
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/defs.h b/cesar/cp/defs.h
index f6ee325939..4fd5ae3ba2 100644
--- a/cesar/cp/defs.h
+++ b/cesar/cp/defs.h
@@ -158,7 +158,10 @@
#define CP_HOMEPLUG_AV101 0
/** Timer offset for beacon data update. */
-#define CP_TIMER_OFFSET_CCO MAC_MS_TO_TCK(20)
-#define CP_TIMER_OFFSET_STA MAC_MS_TO_TCK(5)
+#define CP_TIMER_OFFSET_CCO MAC_MS_TO_TCK(70)
+#define CP_TIMER_OFFSET_STA MAC_MS_TO_TCK(70)
+
+#define MAX_THROUGHPUT_MBPS 140
+#define DEFAULT_STREAM_QUALITY 226
#endif /* cp_defs_h */
diff --git a/cesar/cp/eoc/cco/action/Config b/cesar/cp/eoc/cco/action/Config
new file mode 100644
index 0000000000..4161d175da
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/Config
@@ -0,0 +1,2 @@
+CONFIG_CP_EOC_CCO_WL_ALLOWED = n
+CONFIG_CP_EOC_CCO_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..01bc39cdcd
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/Module
@@ -0,0 +1 @@
+SOURCES := cco_action.c vs_eoc.c
diff --git a/cesar/cp/eoc/cco/action/bridge.h b/cesar/cp/eoc/cco/action/bridge.h
new file mode 100644
index 0000000000..5caefabeaf
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/bridge.h
@@ -0,0 +1,32 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/bridge.h
+ * \brief STA action, bridge table related declarations.
+ * \ingroup cp_sta_action
+ *
+ * Bridge table request and reception implementations.
+ */
+//#include "common/std.h"
+
+#include "cp/mme.h" // cp_mme_rx_t
+#include "cp/msg/msg.h" // to include cp/msg/inc/msg_cm.h
+#include "cp/msg/inc/msg_cm.h" // cp_msg_cm_brg_info_cnf_receive_*
+#include "cp/sta/mgr/sta_mgr.h" // cp_sta_mgr_get_our_avln
+#include "cp/sta/mgr/sta.h" // cp_sta_get_peer
+#include "cp/sta/mgr/net.h" // cp_net_sta_get_*
+#include "cl/cl_mactotei.h" // cl_mactotei_*
+#include "cp/inc/context.h" // cp_t
+#include "cl/bridge_table.h" // bridge_table_*
+#include "lib/utils.h" // less_mod2p32
+#include "cp/sta/action/bridge.h"
+
+
+void
+cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta);
+
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..3e04b24a35
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/cco_action.h
@@ -0,0 +1,125 @@
+#ifndef cp_eoc_cco_action_h
+#define cp_eoc_cco_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/cco_action.h
+ * \brief CCo Public functions.
+ * \ingroup cp_eoc_cco
+ *
+ */
+#include "cp/inc/context.h"
+
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/beacon/beacon.h"
+#include "cp/sta/mgr/sta.h"
+
+#include "cp/eoc/cco/action/vs_eoc.h"
+#include "cp/eoc/cco/action/drv.h"
+#include "cp/eoc/cco/action/bridge.h"
+#include "cp/eoc/cco/action/misc.h"
+#include "cp/sta/action/vs.h"
+
+BEGIN_DECLS
+
+/**
+ * handle POWER_ON => CCO
+ * \param ctx the module context.
+ *
+ */
+void
+cp_eoc_cco_action__power_on_no_beacons (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);
+
+/**
+ * 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);
+/*
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req(cp_t *ctx, cp_mme_rx_t *mme);
+*/
+
+/**
+ * Start CCO side FSM.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_cco_action_poweron__idle__to_poweron (cp_t *ctx);
+
+/**
+ * Provide stations with new NEK
+ * \param ctx the CP context
+ */
+void
+cp_eoc_cco_action_nek_provide (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);
+
+void
+cp_eoc_cco_action_nek_change_timeout (cp_t *ctx);
+
+void
+cp_eoc_cco_action_vs__cco__cc_leave_ind(cp_t *ctx, cp_mme_peer_t *peer);
+
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx);
+
+END_DECLS
+
+#endif /* cp_eoc_cco_action_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..c5974f72ff
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/drv.h
@@ -0,0 +1,95 @@
+#ifndef cp_eoc_cco_action_drv_h
+#define cp_eoc_cco_action_drv_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/eoc/action/drv.h
+ * \brief Driver messages
+ * \ingroup cp_eoc_sta_action
+ *
+ * Entering and exiting sleep states
+ * ==========================
+ *
+ * This part relates to entering and exiting STA sleep states
+ *
+ * \image html
+ *
+ */
+
+BEGIN_DECLS
+
+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__stopped__vs_cco_get_wl_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx);
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_set_eoc_config_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/misc.h b/cesar/cp/eoc/cco/action/misc.h
new file mode 100644
index 0000000000..66c681c900
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/misc.h
@@ -0,0 +1,17 @@
+
+#ifndef cp_cco_action_misc_h
+#define cp_cco_action_misc_h
+
+BEGIN_DECLS
+
+void cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+END_DECLS
+
+#endif /* cp_sta_action_misc_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..c80766ca56
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/src/cco_action.c
@@ -0,0 +1,726 @@
+/* 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
+ *
+ */
+#include <string.h>
+#include "common/std.h"
+#include "common/defs/homeplugAV.h"
+
+#include "cp/beacon/beacon.h"
+#include "cp/eoc/cco/bw/bw.h"
+
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/multi_sta_fsm/inc/events.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/eoc/inc/dbg_print.h"
+
+#include "mac/common/defs.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/net.h"
+
+#include "hal/gpio/gpio.h"
+#include "hal/arch/arch.h"
+
+#include "config/cp/eoc/cco/wl/allowed.h"
+#include "config/cp/eoc/cco/con/allowed.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+
+#include "stdio.h"
+#if CONFIG_CP_EOC_CCO_CON_ALLOWED
+#include "mac/sar/inc/sar_context.h"
+#define CONFIG_CP_EOC_CCO_CON_TIMEOUT_TCK MAC_MS_TO_TCK (950)
+#endif
+#include "mac/pbproc/inc/context.h"
+#include "cp/eoc/sta/action/drv.h"
+
+/**
+ * Generate the NEK to be used right now.
+ * \param ctx the CP context.
+ *
+ * Called on CCo startup.
+ */
+static void
+cp_cco_action_gen_nek_now (cp_t *ctx)
+{
+ cp_key_t key;
+
+ dbg_assert (ctx);
+ cp_secu_generate_key (ctx, lib_rnd32 (&ctx->rnd),
+ CP_SECU_PBKDF1_ITERATION_NEK, &key);
+ cp_beacon_change_nek (ctx, 0, key, true /* now. */);
+}
+
+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);
+}
+
+
+/**
+ * Request the station for the NEK change.
+ * \param ctx the module context.
+ * \param sta the station to start the NEK exchange.
+ */
+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__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_change_nek);
+ cp_sta_core_gen_timed_event (ctx, &ctx->cco_action.nek_change,
+ event, HPAV_NEK_CHANGE_MS);
+}
+
+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)
+ {
+ ctx->cco_action.eks_current =
+ ctx->mac_config->nek[bsu_nek_index_current (ctx->bsu)].eks;
+
+ cp_secu_generate_key (ctx, lib_rnd32 (&ctx->rnd),
+ CP_SECU_PBKDF1_ITERATION_NEK,
+ &ctx->cco_action.nek_new);
+
+ 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.eks_current);
+ }
+ else
+ DBG_PRINT("key_exc: wrk");
+ cp_eoc_cco_action__change_nek (ctx);
+}
+
+/**
+ * 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_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;
+}
+
+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 = CP_CCO_ACTION_EKS_NEXT
+ (ctx->cco_action.eks_current);
+ for (i = 0; i < COUNT (ctx->cco_action.nek_new.key); i++)
+ data_req.new_key.key[i] = ctx->cco_action.nek_new.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 succesfully 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,
+ CP_CCO_ACTION_EKS_NEXT(ctx->cco_action.eks_current),
+ ctx->cco_action.nek_new,
+ false /* central beacon change. */);
+ /* Set the EKS_current to the new one. */
+ ctx->cco_action.eks_current =
+ CP_CCO_ACTION_EKS_NEXT(ctx->cco_action.eks_current);
+ ctx->cco_action.eks_sta_current_peer.tei = MAC_TEI_UNASSOCIATED;
+ DBG_PRINT("key_exc: e[%d]", ctx->cco_action.eks_current);
+ }
+ 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++;
+ /* exc is over. Timeout is late. Simply return */
+ if (ctx->cco_action.eks_sta_current_peer.tei == MAC_TEI_UNASSOCIATED)
+ 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;
+ 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__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);
+
+ ctx->sta_mgr.sta_own_data.state = CP_EOC_STA_STATE_AUTHENTICATED;
+ cp_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);
+ /* Generate current NEK value */
+ cp_cco_action_gen_nek_now (ctx);
+ /* 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, MASTER_GOLDEN_DPW,
+ strlen (MASTER_GOLDEN_DPW), CP_SECU_SALT_KEY_DAK);
+ cp_sta_own_data_set_dak (ctx, key);
+#endif
+}
+
+void
+cp_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_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)
+{
+}
+
+/**
+ * Generate and send a eoc central beacon.
+ * \param ctx the module context.
+ *
+ */
+#if CONFIG_CP_EOC_CCO_CON_ALLOWED
+static int mem = 0, auth_time = 0;
+u32 cp_eoc_time_get (void)
+{
+ return auth_time;
+}
+#endif
+
+/**
+ * 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)
+{
+ cp_t * ctx = (cp_t *)user_data;
+ dbg_assert (ctx);
+ cp_eoc_cco_bw_scheduler (ctx);
+}
+
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ if (CONFIG_TRACE)
+ {
+ static uint old_aifs = -1;
+ dbg_assert (old_aifs != ctx->pbproc->stats.aifs);
+ old_aifs = ctx->pbproc->stats.aifs;
+ }
+ arch_dsr_lock ();
+ cp_eoc_cco_bw_bp_allocations (ctx);
+ arch_dsr_unlock ();
+#if CONFIG_CP_EOC_CCO_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] pb[%d,%d]\n",
+ auth_time, blk_free_nb (),
+ ctx->sar->stats.rx_jobs_count,
+ ctx->sar->stats.rx_jobs_waiting_count,
+ ctx->sar->stats.rx_pb_count,
+ ctx->sar->stats.rx_pb_rejected,
+ ctx->sar->stats.rx_pb_crc_error_count,
+ ctx->sar->stats.tx_pb_expired,
+ ctx->sar->stats.rx_pb_expired,
+ 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 + 20);
+ strncpy (tmpa, temp1, len1 - pos);
+ tmpa[len1 - pos] = '\0';
+ printf (tmpa);
+ pos = len1;
+ }
+ ctx->sar->stats.rx_jobs_count =
+ ctx->sar->stats.rx_pb_rejected =
+ ctx->sar->stats.rx_pb_crc_error_count =
+ ctx->sar->stats.rx_pb_count =
+ ctx->sar->stats.rx_pb_expired =
+ ctx->sar->stats.tx_pb_expired = 0;
+ ctx->cco_action.last_date = phy_date ()
+ + CONFIG_CP_EOC_CCO_CON_TIMEOUT_TCK;
+ }
+#endif
+}
+
+cp_tei_t
+cp_eoc_multi_sta_action_compute_tei (cp_t *ctx)
+{
+ static uint tei = MAC_TEI_STA_MIN_EOC - 1;
+
+ tei++;
+ if (tei <= MAC_TEI_STA_MAX)
+ return tei;
+ else
+ return MAC_TEI_UNASSOCIATED;
+}
+
+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)
+ {
+ #if CONFIG_CP_EOC_CCO_WL_ALLOWED
+ {
+ sta = cp_sta_mgr_sta_get_from_mac (ctx, mme->peer.mac);
+ /* Accept all stations, no matter of white list */
+ if (ctx->cco_action.wl_accept_all)
+ {
+ DBG_PRINT ("sta: station 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)
+ + MAC_SEC_TO_MS(60);
+ }
+ 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) + MAC_SEC_TO_MS(60);
+ 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 in wl, 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) + MAC_SEC_TO_MS(60);
+ sta->multi_sta.allowed = true;
+ }
+ else
+ {
+ tei = cp_sta_get_tei(sta);
+ DBG_PRINT_2("sta: not_allowed in wl, tei = %d", tei);
+ if(tei)
+ {
+ sta = cp_sta_mgr_sta_add(ctx, net, MAC_TEI_UNASSOCIATED ,mme->peer.mac);
+ sta->expired_date_ms = cp_sta_core_get_date_ms (ctx) + MAC_SEC_TO_MS(60);
+ 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->poll_time = phy_date ();
+ 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);
+
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false, MAC_LLID_MIN,
+ tei, &added);
+ if(added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ blk_release (mfs);
+ }
+ }
+ #else
+ {
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+ 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->poll_time = phy_date ();
+
+ 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);
+
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false, MAC_LLID_MIN,
+ tei, &added);
+ if(added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ blk_release (mfs);
+ }
+ #endif /* CONFIG_CP_EOC_CCO_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)
+ {
+ 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));
+ ctx->sta_mgr.sta_own_data.num_leave ++;
+
+ slab_release(sta);
+ }
+}
+
+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/vs_eoc.c b/cesar/cp/eoc/cco/action/src/vs_eoc.c
new file mode 100644
index 0000000000..d276556769
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/src/vs_eoc.c
@@ -0,0 +1,792 @@
+/* Cesar-EoC project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/src/vs_eoc.c
+ * \brief CCo action, VS EoC MMEs req receive/cnf send functions definitions.
+ * \ingroup cp_eoc_cco_action
+ */
+
+#include "common/std.h"
+#include "cp/msg/msg.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+#include "cp/eoc/inc/dbg_print.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/inc/context.h"
+#include "lib/set.h"
+#include "cp/sta/action/action.h"
+#include "cp/fsm/fsm.h"
+#include "config/cp/eoc/cco/wl/allowed.h"
+#include "cp/eoc/cco/action/vs_eoc.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/cco/bw/service.h"
+#include "ce/rx/bitloading/inc/nsr.h"
+#include "mac/pbproc/inc/context.h"
+#include "math.h"
+
+#include "stdio.h"
+#include "cp/msg/inc/msg_vs_eoc.h"
+
+const mac_t MASTER_GOLDEN_MAC = 0xFFFFFFD71300ull; /* ff:ff:ff:d7:13:00 */
+
+/**
+ * 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)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (mme);
+
+ cp_net_t *net = NULL;
+
+ /* Received data: empty */
+
+ /* 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;
+ u8 agc_offset = 12;
+
+ set_node_t *current_node = NULL;
+ set_node_t *next_node = NULL;
+ cp_sta_t *current_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 */
+ 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_t *station = mac_store_sta_get(ctx->mac_store, ((cp_sta_private_t *) current_sta)->tei);
+
+ if(station && station->authenticated)
+ {
+ if(current_sta->authenticated_to_unassociated)
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (ctx, reply,
+ ((cp_sta_private_t *) current_sta)->mac_address,
+ 3 /* re-authenticated between
+ two successive get_topo calls*/,
+ station->upstream_att + agc_offset);
+ }
+ else
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (ctx, reply,
+ ((cp_sta_private_t *) current_sta)->mac_address,
+ 2 /* authenticated*/,
+ station->upstream_att + agc_offset);
+ }
+ }
+ else
+ {
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (ctx, reply,
+ ((cp_sta_private_t *) current_sta)->mac_address,
+ 1 /* associated*/,
+ station->upstream_att + agc_offset);
+
+ }
+
+ blk_release(station);
+ current_sta->authenticated_to_unassociated = false;
+ next_node = set_next (&net->associated_stas, current_node);
+ assoc_sta_nb--;
+ }
+ }
+ /* go through unassociated stations */
+ if (!set_empty (&net->unassociated_stas))
+ {
+ next_node = set_begin (&net->unassociated_stas);
+ while (unassoc_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);
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (ctx, reply,
+ ((cp_sta_private_t *) current_sta)->mac_address,
+ 0 /* unassociated */,
+ 0);
+
+ //current_sta->authenticated_to_unassociated = false;
+ next_node = set_next (&net->unassociated_stas, current_node);
+ unassoc_sta_nb--;
+ }
+ }
+
+ }
+
+ cp_msg_vs_eoc_get_topo_cnf_send_end (ctx, reply);
+}
+
+/* After sending a CC_LEAVE mme to a sta, wait 100ms before removing the sta from lists */
+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_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];
+ u8 stas_actions[MAC_TEI_STA_NB];
+
+ 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_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, 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_sta_mgr_sta_get_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);
+ }
+ }
+ }
+ 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_sta_mgr_sta_get_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;
+ }
+ 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;
+ }
+ }
+ }
+ }
+ /* 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);
+ DBG_PRINT ("wl: entries received");
+ }
+ #endif /* CONFIG_CP_EOC_CCO_WL_ALLOWED */
+}
+
+
+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_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];
+ 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_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_actions, first_wl_index_nb);
+ }
+ #endif /* CONFIG_CP_EOC_CCO_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;
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, stas_macs[i]);
+ if(!sta)
+ {
+ result = CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_FAILURE;
+ }
+ else
+ {
+ 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];
+ }
+ }
+ }
+ }
+ 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_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_GET_PORTS_REQ_RESULT_SUCCESS :
+ CP_MSG_VS_EOC_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_set_services_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert(ctx);
+ dbg_assert(mme);
+
+ uint i, j;
+ cp_msg_vs_eoc_set_services_req_result_t result = CP_MSG_VS_EOC_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_set_services_req_receive(ctx, mme, &command, &services_number, service_indexes,
+ classifier_rules, classifier_values, acses, parameters_numbers, parameters_lists);
+
+ if(ok)
+ {
+ if(command == 0) /* add services */
+ {
+ 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);
+ }
+ }
+ }
+ else if (command == 1) /* remove services */
+ {
+ 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_SET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ }
+ }
+ else if (command == 2) /* remove all services */
+ {
+ 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 (&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--;
+ }
+ }
+ else /* invalid command code */
+ {
+ result = CP_MSG_VS_EOC_SET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ }
+ else
+ {
+ result = CP_MSG_VS_EOC_SET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ cp_msg_vs_eoc_set_services_cnf_send (ctx, &mme->peer, VS_EOC_SET_SERVICES_CNF, result);
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_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_get_services_req_result_t result = CP_MSG_VS_EOC_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_GET_SERVICES_REQ_RESULT_FAILURE;
+ }
+ list_node = list_next(list_node);
+ }
+ }
+ else
+ {
+ result = CP_MSG_VS_EOC_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;
+ u8 attenuation = 0;
+ u8 attenuation_sum = 0;
+ u8 attenuation_sum_cnt = 0;
+ u8 agc_offset = 12;
+ 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->upstream_att + agc_offset;
+ 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;
+
+ }
+
+ output_power = 0; /* N.A. */
+
+ 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;
+ tx_crc_error_counter = 0; /* N.A. */
+ 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)
+ {
+ assoc_stat = 2; /* N.A */
+ nid = ctx->sta_mgr.our_avln->nid;
+ num_slots = 1;
+ he_mac_address = ctx->sta_mgr.sta_own_data.mac_addr;
+ est_avg_phy_rate = 0;
+ if(control == 1)
+ {
+ ctx->sta_mgr.sta_own_data.num_good_assoc_auth = 0;
+ ctx->sta_mgr.sta_own_data.num_bad_could_not_assoc = 0;
+ ctx->sta_mgr.sta_own_data.num_bad_assoc_failure = 0;
+ ctx->sta_mgr.sta_own_data.num_bad_could_not_auth = 0;
+ ctx->sta_mgr.sta_own_data.num_leave = 0;
+ }
+ num_good_assoc_auth = ctx->sta_mgr.sta_own_data.num_good_assoc_auth;
+ num_bad_could_not_assoc = ctx->sta_mgr.sta_own_data.num_bad_could_not_assoc;
+ num_bad_assoc_failure = ctx->sta_mgr.sta_own_data.num_bad_assoc_failure;
+ num_bad_could_not_auth = ctx->sta_mgr.sta_own_data.num_bad_could_not_auth;
+ num_leave = ctx->sta_mgr.sta_own_data.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..01bc39cdcd
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/Module
@@ -0,0 +1 @@
+SOURCES := cco_action.c vs_eoc.c
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..efaa11ae87
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/src/cco_action.c
@@ -0,0 +1,73 @@
+/* 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 function for the unit test of the other modules.
+ */
+#include "common/std.h"
+
+#include "cp/eoc/cco/action/cco_action.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__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_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_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)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/stub/src/vs_eoc.c b/cesar/cp/eoc/cco/action/stub/src/vs_eoc.c
new file mode 100644
index 0000000000..024be5c794
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/stub/src/vs_eoc.c
@@ -0,0 +1,104 @@
+/* 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
+ */
+
+
+#include "common/std.h"
+
+#include "cp/cp.h"
+#include "cp/mme.h"
+
+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_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__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__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_ports_req(cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_ports_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_services_req(cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_services_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_services_req(cp_t *ctx, cp_mme_rx_t *mme) __attribute__ ((weak));
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_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..eb322dc309
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/Config
@@ -0,0 +1,11 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_FSM_DEF = "cp/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_CP_MSG_EOC_VS = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_CCO_FSM = y
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..bdfdaf2d37
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/Makefile
@@ -0,0 +1,11 @@
+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
diff --git a/cesar/cp/eoc/cco/action/test/utest/actions-Config b/cesar/cp/eoc/cco/action/test/utest/actions-Config
new file mode 100644
index 0000000000..541f8445a7
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/actions-Config
@@ -0,0 +1,27 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_FSM_DEF = "cp/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_CP_MSG_EOC_DRV_MME = y
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+#CONFIG_CP_MSG_DRV_MME = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_CCO_FSM = 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_WL_ALLOWED = y
+CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED = y
+CONFIG_CL_EOC_ROUTE = y
+
diff --git a/cesar/cp/eoc/cco/action/test/utest/actions-Makefile b/cesar/cp/eoc/cco/action/test/utest/actions-Makefile
new file mode 100644
index 0000000000..295ef21b4a
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/actions-Makefile
@@ -0,0 +1,36 @@
+BASE = ../../../../../..
+
+VARIANT = actions
+
+DEFS = -DSTA_CORE_UNIT_TEST=1
+
+INCLUDES = cp/eoc/cco/action/test/utest cp/eoc/cco/action/test/utest/override
+
+HOST_PROGRAMS = test_actions
+
+test_actions_SOURCES = test_actions.c actions.c pbproc_stub.c pwl_stub.c msg_stub.c\
+ mac_common_store_stub.c dataplane_stub.c cp_eoc_sta_misc_stub.c\
+ cp_stub.c ce_stub.c events_stub.c beacon_stub.c sta_vs_eoc_stub.c
+
+test_actions_MODULES = lib lib/scenario cp/msg cp/msg/stub cp/eoc/sta/mgr cp/fsm \
+ cp/eoc/cco/action cp/eoc/multi_sta_fsm cp/eoc/cco/bw \
+ cp/beacon/stub cp/sta/mgr mac/common cp/cco/bw\
+ cp/eoc/multi_sta/action cp/sta/core/stub cp/secu/stub\
+ cl/stub cp/secu cp/eoc/sta/action/stub\
+ cp/cl_interf interface/stub ce/tx/stub cp/sta/action\
+ mac/sar/stub cp/eoc/sta/action bsu/stub
+
+test_actions_CONFIG_MODULES = cp/beacon cl mac/sar cp
+
+cp_sta_action_MODULE_SOURCES = vs.c
+cp_eoc_sta_action_MODULE_SOURCES = drv.c misc.c cco_stub.c
+cp_eoc_sta_action_stub_MODULE_SOURCES = bridge.c poweron.c
+cp_msg_MODULE_SOURCES = msg_drv.c mme.c
+cp_msg_stub_MODULE_SOURCES = msg_cc.c msg_cm.c msg_vs.c
+cp_fsm_MODULE_SOURCES = fsm.c tables.c
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_sta_core_MODULE_SOURCES = core.c
+cp_cl_MODULE_SOURCES = cl_interf.c
+mac_common_MODULE_SOURCES = config.c interval.c mfs.c ntb.c sta.c tonemap.c tonemask.c
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/cco/action/test/utest/fsm-Config b/cesar/cp/eoc/cco/action/test/utest/fsm-Config
new file mode 100644
index 0000000000..75f76e168d
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/fsm-Config
@@ -0,0 +1,12 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_FSM_DEF = "cp/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_CP_MSG_EOC_VS = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_CCO_FSM = y
diff --git a/cesar/cp/eoc/cco/action/test/utest/fsm-Makefile b/cesar/cp/eoc/cco/action/test/utest/fsm-Makefile
new file mode 100644
index 0000000000..5fa571562c
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/fsm-Makefile
@@ -0,0 +1,19 @@
+BASE = ../../../../../..
+
+VARIANT = fsm
+#DEFS = -DSTA_CORE_UNIT_TEST=1
+
+INCLUDES = cp/eoc/cco/action/test/utest cp/eoc/cco/action/test/utest/override
+
+HOST_PROGRAMS = test_fsm
+
+test_fsm_SOURCES = test_fsm.c fsm_stub.c actions.c
+test_fsm_MODULES = lib lib/scenario cp/fsm ce/tx/stub mac/sar/stub
+test_fsm_CONFIG_MODULES = cp/eoc/multi_sta_fsm cp/beacon cp/sta/mgr cp/msg mac/common cl mac/sar cp
+cp_fsm_MODULE_SOURCES = fsm.c events.c
+
+cp_sta_mgr_MODULE_SOURCES = net.c net_list.c sta.c
+
+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..b69a31364a
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/inc/scenario_defs.h
@@ -0,0 +1,304 @@
+#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/msg/msg.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/net.h"
+#include "cp/fsm/fsm.h"
+#include "cl/cl_mactotei.h"
+#include "mac/common/tonemap.h"
+#include "cp/eoc/cco/bw/service.h"
+#include "cp/msg/inc/msg_vs_eoc.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_get_ports_req,\
+ vs_eoc__cco__vs_eoc_get_services_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_get_ports_req)
+
+__m (vs_eoc__cco__vs_eoc_get_services_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_stats_req, \
+ 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,\
+ cp_msg_vs_get_tonemap_req_receive, \
+ cp_msg_vs_get_tonemap_cnf_send
+
+
+/* MME send event. */
+#define __ms(event, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ 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;
+
+
+__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_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_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 __mr
+#undef __p_
+
+typedef struct
+{
+ cp_fsm_branch_t branch;
+} scenario_event_transition_with_branch_t;
+
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_mac_addr_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_cco_pref_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_was_cco_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_dpw_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_nid_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_tonemask_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_key_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_dak_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_mac_start_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STARTED__poweron__idle__to_poweron_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STARTED__drv_sta_mac_stop_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__POWER_ON__beacon_not_received_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__POWER_ON__power_on_rx_beacon_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__POWER_ON__power_on_no_beacons_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__cco_drv_mac_stop_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__bridge_first_com_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__event_dispatch_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__send_central_beacon_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_topo_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_wl_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_wl_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_ports_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_ports_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_set_services_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_services_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_info_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_diagnostic_info_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__vs_eoc_get_real_time_stats_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__nek_provide_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__set_key_cnf_t;
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_fsm__CCO__nek_change_timeout_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__vs_eoc__cco__leave_remove_timeout_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__CCO__drv_sta_get_key_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__BCCO__bcco_no_beacons_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__BCCO__bcco_drv_mac_stop_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPING__poweron__many__to_idle_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPING__stopped_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_npw_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_sl_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_m_sta_hfid_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_u_sta_hfid_req_t;
+typedef scenario_empty_t
+scenario_event_cp_fsm__STOPPED__drv_sta_set_avln_hfid_req_t;
+
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/inc/test_cco_action.h b/cesar/cp/eoc/cco/action/test/utest/inc/test_cco_action.h
new file mode 100644
index 0000000000..c6c25bf850
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/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/override/cp/inc/context.h b/cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h
new file mode 100644
index 0000000000..c2c9db9fd5
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/cp/inc/context.h
@@ -0,0 +1,118 @@
+#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/cco/action/inc/cco_action.h"
+#include "cp/cco/action/cco_action.h"
+#include "cp/beacon/beacon.h"
+#include "cp/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"
+
+
+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;
+
+ mac_store_t *store;
+
+ 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;
+};
+
+
+void
+cp_sta_mgr_sta_remove_stub (cp_t *ctx, cp_sta_t * station);
+#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..930f5c4c92
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/cp/sta/core/core.h
@@ -0,0 +1,53 @@
+#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);
+
+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..9698b44e93
--- /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) 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/override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/cco/action/test/utest/override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..e380fb66e7
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/override/mac/sar/inc/sar_context.h
@@ -0,0 +1,37 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/actions.c b/cesar/cp/eoc/cco/action/test/utest/src/actions.c
new file mode 100644
index 0000000000..d3d2dd9aca
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/actions.c
@@ -0,0 +1,141 @@
+/* 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"
+
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_ports_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+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(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; \
+ mme.peks = CP_MME_PEKS_SPC_NOT_EMBEDDED; \
+ cp_sta_action_ ## ACTION (globals->cp, &mme); \
+}
+
+
+
+__m (vs__started__vs_get_tonemap_req)
+
+#undef __m
+
+#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; \
+ mme.peks = CP_MME_PEKS_SPC_NOT_EMBEDDED; \
+ cp_eoc_cco_action_ ## ACTION (globals->cp, &mme); \
+}
+
+__m (vs_eoc__cco__vs_eoc_get_ports_req)
+
+__m (vs_eoc__cco__vs_eoc_get_services_req)
+
+
+#undef __m
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/beacon_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/beacon_stub.c
new file mode 100644
index 0000000000..123dcb9f0b
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/beacon_stub.c
@@ -0,0 +1,30 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/beacon_stub.c
+ * \brief Beacon stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "cp/beacon/beacon.h"
+
+#include "lib/scenario/scenario.h"
+
+
+void
+cp_beacon_deactivate (cp_t *ctx)
+{
+
+}
+
+void
+cp_beacon_poweron_init (cp_t *ctx)
+{
+
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/ce_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/ce_stub.c
new file mode 100644
index 0000000000..8d99b65842
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/ce_stub.c
@@ -0,0 +1,24 @@
+/* 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;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/cp_eoc_sta_misc_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/cp_eoc_sta_misc_stub.c
new file mode 100644
index 0000000000..1613916912
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/cp_eoc_sta_misc_stub.c
@@ -0,0 +1,49 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest/src/cp_eoc_sta_misc_stub.c
+ * \brief STA action, miscellaneous definitions.
+ * \ingroup cp_sta_action
+ */
+ #include "common/std.h"
+ #include "cp/inc/context.h"
+ #include "cp/msg/msg.h"
+
+ #define CE_RX_BITLOADING_NOISE_NRJ_SIZE (sizeof (u32))
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+u8
+cp_sta_action_get_average_ble (cp_t *ctx, cp_tei_t tei, bool tx,
+ bool fc_format)
+{
+ return 0;
+}
+
+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/src/cp_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/cp_stub.c
new file mode 100644
index 0000000000..02d02ef988
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/cp_stub.c
@@ -0,0 +1,125 @@
+/* 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);
+}
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx)
+{
+ static uint time=0;
+ time+=2000;
+ return time;
+}
+
+// Does not decrement net->num_visible_stas
+void
+cp_sta_mgr_sta_remove_stub (cp_t *ctx, cp_sta_t * station)
+{
+ set_t *set;
+ cp_sta_private_t *sta = (cp_sta_private_t *) station;
+ cp_net_t *net;
+
+ dbg_assert (ctx);
+ dbg_assert (sta);
+ dbg_assert (sta->net);
+
+ net = sta->net;
+
+ // If the station is CCo, modify the net CCo pointer to NULL.
+ if (cp_sta_get_cco_status(station))
+ net->cco = NULL;
+
+ // If the station is PCo to communicate with the CCo, modify the
+ // pointer in the net.
+ if (net->pco == station)
+ net->pco = NULL;
+
+ if ((net == ctx->sta_mgr.our_avln)
+ && (MAC_TEI_IS_STA (sta->tei)))
+ sar_sta_remove (ctx->sar, sta->tei);
+
+ /* Remove the station from its net. */
+ if (cp_sta_get_tei (&sta->public_data))
+ {
+ if (cp_sta_mgr_sta_is_assoc (ctx, net, sta->tei))
+ {
+ set = &sta->net->associated_stas;
+ set_remove (set, &sta->public_data.node_net);
+ sta->net->num_associated_stas--;
+ }
+ else if (cp_sta_mgr_sta_is_unassoc(ctx, net, sta->mac_address))
+ {
+ set = &sta->net->unassociated_stas;
+ set_remove (set, &sta->public_data.node_net);
+ }
+ }
+ else
+ {
+ set = &sta->net->unassociated_stas;
+ if (cp_sta_mgr_sta_is_unassoc (ctx, net, sta->mac_address))
+ set_remove (set, &sta->public_data.node_net);
+ }
+
+ /* Remove the station from the station manager. If the mac address of the
+ * station is broadcast, the station is not in the set. */
+ if (sta->mac_address != MAC_BROADCAST)
+ set_remove (&ctx->sta_mgr.stas, &sta->public_data.node_sta_mgr);
+
+ /* decrease the number of stations. */
+ sta->net->num_stas --;
+
+ cp_sta_mgr_elects_sta_partial_ack (ctx);
+
+ /* Release the station. */
+ slab_release (sta);
+
+/* if (cp_sta_mgr_net_list_is_empty (ctx))
+ cp_fsm_trigger_new_event (ctx, bare, net_list_empty);*/
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/dataplane_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/dataplane_stub.c
new file mode 100644
index 0000000000..fd5a865de3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/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/sar_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/src/events_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/events_stub.c
new file mode 100644
index 0000000000..f34d993f19
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/events_stub.c
@@ -0,0 +1,76 @@
+/* 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_sta_core_stop_timed_or_cyclic_event(cp_t *cp_ctx,
+ cp_sta_core_timed_event_def_t *sta_core_timed_event)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/fsm_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/fsm_stub.c
new file mode 100644
index 0000000000..b3563d160f
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/fsm_stub.c
@@ -0,0 +1,534 @@
+/* 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_eoc_cco_action_drv__stopped__drv_cco_set_wl_req (cp_t *ctx, cp_mme_rx_t *mme) __attribute__
+((weak));
+
+void
+ce_tx_process__cm_chan_est_ind (cp_t *ctx, cp_mme_rx_t *mme) __attribute__
+((weak));
+
+void
+ce_tx_process__cm_chan_est_ind (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+ce_tx_process__cm_update_tm_ind (cp_t *ctx, cp_mme_rx_t *mme) __attribute__
+((weak));
+
+void
+ce_tx_process__cm_update_tm_ind (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_process_cm_brg_info_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_process_cm_brg_info_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_cco_action__power_on_rx_beacon (cp_t *ctx);
+
+void
+cp_eoc_cco_action__power_on_no_beacons (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);
+
+void
+cp_eoc_cco_action_send_central_beacon (cp_t *ctx);
+
+void
+cp_eoc_cco_action_nek_provide (cp_t *ctx);
+
+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);
+
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_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);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx);
+
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx);
+
+void
+cp_sta_action_poweron__idle__to_poweron (cp_t *ctx);
+
+void
+cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_cco_action_poweron__idle__to_poweron (cp_t *ctx);
+
+void
+cp_eoc_cco_action_event_dispatch (cp_t *ctx);
+
+void
+cp_beacon_beacon_not_received (cp_t *ctx);
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_set_eoc_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+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__stopped__vs_cco_get_wl_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+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_ports_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_services_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_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);
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_cco_action_vs__cco__vs_cco_get_link_info_req(cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx);
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_vs__started__vs_get_snr_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_ce_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+/* Include generated tables. */
+#include "cp_fsm_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_sta_action_poweron__idle__to_poweron (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STARTED__poweron__idle__to_poweron);
+}
+
+void
+cp_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)
+{
+ scenario_event (cp_fsm__CCO__event_dispatch);
+}
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme_rx)
+{
+}
+
+ void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_drv__drv_sta_set_eoc_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__CCO__drv_sta_get_key_req);
+}
+
+void
+cp_sta_action_vs__started__vs_get_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+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_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_vs_eoc__cco__vs_eoc_set_services_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_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)
+{
+}
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_cco_action_vs__cco__vs_cco_get_link_info_req(cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_eoc_cco_action__cco__leave_remove_timeout (cp_t *ctx)
+{
+ scenario_event (cp_fsm__CCO__vs_eoc__cco__leave_remove_timeout);
+}
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_snr_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_ce_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/mac_common_store_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/mac_common_store_stub.c
new file mode 100644
index 0000000000..ad52f8d9a4
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/mac_common_store_stub.c
@@ -0,0 +1,582 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file mac/common/src/store.c
+ * \brief MFS and STA store, store pointers to MFS and STA information.
+ * \ingroup mac_common
+ */
+#include "common/std.h"
+#include "mac/common/store.h"
+
+#include "hal/arch/arch.h"
+#include "mac/common/defs.h"
+#include "lib/blk.h"
+
+#include "config/mac/common.h"
+
+/** Define index into MFS tables tables. */
+enum mac_store_kind_t
+{
+ MAC_STORE_KIND_TXRX_MASK = 1,
+ MAC_STORE_KIND_RX = 0,
+ MAC_STORE_KIND_TX = 1,
+ MAC_STORE_KIND_BCAST_MASK = 2,
+ MAC_STORE_KIND_RX_BCAST = 2,
+ MAC_STORE_KIND_STA_NB = 3,
+ MAC_STORE_KIND_TX_BCAST = 3
+};
+typedef enum mac_store_kind_t mac_store_kind_t;
+
+/** Find MFS for any traffic from and to a peer. MFS for non associated STA
+ * are not recorded here (actually, they are recorded nowhere). */
+struct mac_store_sta_t
+{
+ /** Other information about a STA. */
+ sta_t sta;
+ /** PLID MFS for this STA. */
+ mfs_t *plid[MAC_STORE_KIND_STA_NB][MAC_PLID_NB];
+ /** MME MFS for this STA. */
+ mfs_t *mme[MAC_STORE_KIND_STA_NB];
+ /** LLID MFS for RX from this STA. Only allocated when really needed, the
+ * first four pointers are not used. */
+ mfs_t **rx_llid;
+#if CONFIG_MAC_COMMON_EOC_MFS
+ /** LLID MFS for tx to this station in EoC mode */
+ mfs_t **tx_llid;
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
+};
+typedef struct mac_store_sta_t mac_store_sta_t;
+
+/** MFS store context. */
+struct mac_store_t
+{
+ /* PLID MFS for broadcast TX from us. */
+ mfs_t *bcast_tx_plid[MAC_PLID_NB];
+ /* MME MFS for broadcast TX from us. */
+ mfs_t *bcast_tx_mme;
+ /** LLID MFS for TX and GLID MFS for TX/RX table.
+ * - 0x00-0x03: unused
+ * - 0x04-0x7f: TX LLID
+ * - 0x80-0xf7: TX/RX GLID
+ * - 0xf8-0xfd: unused & discover and central beacons */
+ mfs_t *lglid[MAC_LID_BEACON_MAX + 1];
+ /** Peers, indexed by TEI. */
+ mac_store_sta_t *sta[MAC_TEI_STA_MAX + 1];
+};
+/* Forward declaration in mac/common/store.h. */
+
+/** Global mac store context. */
+mac_store_t mac_store_global_context;
+
+mac_store_t *
+mac_store_init (void)
+{
+ uint i;
+ dbg_assert (BLK_SIZE == (MAC_LLID_MAX + 1) * sizeof (mfs_t *));
+ mac_store_t *ctx = &mac_store_global_context;
+ for (i = 0; i < COUNT (ctx->bcast_tx_plid); i++)
+ ctx->bcast_tx_plid[i] = NULL;
+ ctx->bcast_tx_mme = NULL;
+ for (i = 0; i < COUNT (ctx->lglid); i++)
+ ctx->lglid[i] = NULL;
+ for (i = 0; i < COUNT (ctx->sta); i++)
+ ctx->sta[i] = NULL;
+ return ctx;
+}
+
+void
+mac_store_uninit (mac_store_t *ctx)
+{
+ uint i;
+ for (i = 0; i < COUNT (ctx->bcast_tx_plid); i++)
+ dbg_assert (ctx->bcast_tx_plid[i] == NULL);
+ dbg_assert (ctx->bcast_tx_mme == NULL);
+ for (i = 0; i < COUNT (ctx->lglid); i++)
+ dbg_assert (ctx->lglid[i] == NULL);
+ for (i = 0; i < COUNT (ctx->sta); i++)
+ dbg_assert (ctx->sta[i] == NULL);
+}
+
+/**
+ * Factorise code to find a MFS.
+ * \param ctx store context
+ * \param tx true for a TX MFS
+ * \param bcast true for a broadcast MFS
+ * \param mme true for a MME MFS
+ * \param lid link id
+ * \param tei peer terminal equipment id
+ * \param add true if a MFS is being added
+ * \return pointer to an MFS pointer or NULL if no STA or no LLID table or
+ * GLID slot used
+ */
+static inline mfs_t **
+mac_store_mfs_slot_get (mac_store_t *ctx, bool tx, bool bcast, bool mme,
+ uint lid, uint tei, bool add __FL)
+{
+ dbg_assert (ctx);
+ dbg_blame ((mme && lid == MAC_LID_NONE)
+ || (!mme && (MAC_LID_IS_XLID (lid)
+ || lid == MAC_LID_DISCOVER
+ || lid == MAC_LID_SPC_CENTRAL)));
+ dbg_blame (((MAC_LID_IS_GLID (lid) /* Needed when tei is unknown. */
+ || lid == MAC_LID_DISCOVER
+ || lid == MAC_LID_SPC_CENTRAL) && tei == 0)
+ || (bcast && tx && tei == MAC_TEI_BCAST)
+ || (!(bcast && tx) && MAC_TEI_IS_STA (tei)));
+ if (!mme && (lid >= MAC_GLID_MIN))
+ {
+ /* GLID table contains TX and RX MFS, check it is the requested
+ * type. */
+ if (ctx->lglid[lid] && ctx->lglid[lid]->common.tx != tx)
+ {
+ dbg_blame (!add);
+ return NULL;
+ }
+ else
+ return &ctx->lglid[lid];
+ }
+ else if (!mme && (tx && lid >= MAC_LLID_MIN) && !CONFIG_MAC_COMMON_EOC_MFS)
+ return &ctx->lglid[lid];
+ else if (tx && bcast && !mme && MAC_LID_IS_PLID (lid))
+ return &ctx->bcast_tx_plid[lid];
+ else if (tx && bcast && mme)
+ return &ctx->bcast_tx_mme;
+ else
+ {
+ /* Here, we need a STA. */
+ if (add)
+ mac_store_sta_add_ (ctx, tei __fl);
+ mac_store_sta_t *sta = ctx->sta[tei];
+ if (!sta)
+ return NULL;
+ else
+ {
+ if (!mme && lid >= MAC_LLID_MIN)
+ {
+ dbg_blame ((!tx || CONFIG_MAC_COMMON_EOC_MFS) && lid <= MAC_LLID_MAX);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (tx)
+ {
+ if (!sta->tx_llid)
+ {
+ if (add)
+ {
+ /* Allocate a new table. */
+ sta->tx_llid = blk_alloc_zero_ (_fl);
+ return &sta->tx_llid[lid];
+ }
+ else
+ return NULL;
+ }
+ else
+ return &sta->tx_llid[lid];
+ }
+ else
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
+ {
+ if (!sta->rx_llid)
+ {
+ if (add)
+ {
+ /* Allocate a new table. */
+ sta->rx_llid = blk_alloc_zero_ (_fl);
+ return &sta->rx_llid[lid];
+ }
+ else
+ return NULL;
+ }
+ else
+ return &sta->rx_llid[lid];
+ }
+ }
+ else
+ {
+ mac_store_kind_t kind = (tx ? MAC_STORE_KIND_TXRX_MASK : 0)
+ | (bcast ? MAC_STORE_KIND_BCAST_MASK : 0);
+ if (mme)
+ return &sta->mme[kind];
+ else
+ {
+ dbg_blame (lid <= MAC_PLID_MAX);
+ return &sta->plid[kind][lid];
+ }
+ }
+ }
+ }
+}
+
+mfs_t *
+mac_store_mfs_get_ (mac_store_t *ctx, bool tx, bool bcast, bool mme, uint lid,
+ uint tei __FL)
+{
+ mfs_t *mfs = NULL;
+ dbg_assert (ctx);
+ arch_dsr_lock ();
+ mfs_t **slot = mac_store_mfs_slot_get (ctx, tx, bcast, mme, lid, tei,
+ false __fl);
+ if (slot && *slot)
+ {
+ mfs = *slot;
+ blk_addref_ (mfs __fl);
+ }
+ arch_dsr_unlock ();
+ return mfs;
+}
+
+mfs_t *
+mac_store_mfs_add_ (mac_store_t *ctx, bool tx, bool bcast, bool mme, uint lid,
+ uint tei, bool *added __FL)
+{
+ mfs_t *mfs;
+// dbg_assert (ctx);
+// dbg_assert (added);
+// arch_dsr_lock ();
+// mfs_t **slot = mac_store_mfs_slot_get (ctx, tx, bcast, mme, lid, tei,
+// true __fl);
+// dbg_assert (slot);
+// *added = false;
+// if (!*slot)
+// {
+// mfs = blk_alloc_ (_fl);
+// if (!tx)
+// mfs_rx_init (&mfs->rx, bcast, mme, lid, tei);
+// else
+// mfs_tx_init (&mfs->tx, bcast, mme, lid, tei);
+// arch_reorder_barrier ();
+// *slot = mfs;
+// *added = true;
+// }
+// else
+// {
+ mfs = NULL;
+ *added = false;
+// }
+// blk_addref_ (mfs __fl);
+// arch_dsr_unlock ();
+ return mfs;
+}
+
+void
+mac_store_mfs_alias_ (mac_store_t *ctx, mfs_t *mfs, uint glid __FL)
+{
+ dbg_assert (ctx);
+ dbg_blame (mfs);
+ dbg_blame (MAC_LID_IS_GLID (glid));
+ dbg_blame (MAC_LID_IS_LLID (mfs->common.lid));
+ dbg_blame (mfs->common.lid_alias == MAC_LID_NONE);
+ /* Add the MFS to the GLID slot. */
+ dbg_blame (ctx->lglid[glid] == NULL);
+ arch_dsr_lock ();
+ blk_addref_ (mfs __fl);
+ ctx->lglid[glid] = mfs;
+ /* Modify the MFS. */
+ mfs->common.lid_alias = mfs->common.lid;
+ mfs->common.lid = glid;
+ arch_dsr_unlock ();
+}
+
+void
+mac_store_mfs_remove_ (mac_store_t *ctx, mfs_t *mfs __FL)
+{
+ dbg_assert (ctx);
+ dbg_blame (mfs);
+ arch_dsr_lock ();
+ bool alias = mfs->common.lid_alias != MAC_LID_NONE;
+ /* Remove alias first. */
+ uint lid = alias ? mfs->common.lid_alias : mfs->common.lid;
+ mfs_t **slot =
+ mac_store_mfs_slot_get (ctx, mfs->common.tx, mfs->common.bcast,
+ mfs->common.mme, lid,
+ mfs->common.tei, false __fl);
+ if (slot && *slot)
+ {
+ /* Order is important. The code could be interrupted... */
+ dbg_assert (*slot == mfs);
+ arch_reorder_barrier (); /* ...here... */
+ *slot = NULL;
+ arch_reorder_barrier (); /* ...or here... */
+ blk_release_ (mfs __fl);
+ }
+ /* Now remove actual GLID if aliased. */
+ if (alias)
+ {
+ dbg_assert (MAC_LID_IS_LLID (lid));
+ dbg_assert (MAC_LID_IS_GLID (mfs->common.lid));
+ slot = &ctx->lglid[mfs->common.lid];
+ dbg_assert (*slot == mfs);
+ arch_reorder_barrier ();
+ *slot = NULL;
+ arch_reorder_barrier ();
+ blk_release_ (mfs __fl);
+ }
+ arch_dsr_unlock ();
+}
+
+/**
+ * Helper for the travel functions.
+ * \param ctx store context
+ * \param mfs MFS to travel or NULL
+ * \param travel callback function
+ * \param user user data
+ *
+ * Will unlock DSR.
+ */
+void
+mac_store_mfs_travel_mfs_and_unlock (mac_store_t *ctx, mfs_t *mfs,
+ mac_store_travel_t travel, void *user)
+{
+ if (mfs)
+ {
+ blk_addref (mfs);
+ arch_dsr_unlock ();
+ travel (ctx, mfs, user);
+ blk_release (mfs);
+ }
+ else
+ arch_dsr_unlock ();
+}
+
+void
+mac_store_mfs_travel (mac_store_t *ctx, mac_store_travel_t travel,
+ void *user)
+{
+ /* Will unlock DSR between each MFS fetch to reduce DSR latency. */
+ int i;
+ dbg_assert (ctx);
+ dbg_assert (travel);
+ /* First travel local MFS. */
+ for (i = 0; i < MAC_PLID_NB; i++)
+ {
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, ctx->bcast_tx_plid[i],
+ travel, user);
+ }
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, ctx->bcast_tx_mme, travel,
+ user);
+ for (i = MAC_LLID_MIN; i < MAC_LID_NB; i++)
+ {
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, ctx->lglid[i], travel,
+ user);
+ }
+ /* Do not forget beacon MFS. */
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, ctx->lglid[MAC_LID_DISCOVER],
+ travel, user);
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, ctx->lglid[MAC_LID_SPC_CENTRAL],
+ travel, user);
+ /* Now travel by TEI. */
+ for (i = MAC_TEI_STA_MIN; i <= MAC_TEI_STA_MAX; i++)
+ mac_store_mfs_travel_by_tei (ctx, i, travel, user);
+}
+
+void
+mac_store_mfs_travel_by_tei (mac_store_t *ctx, uint tei,
+ mac_store_travel_t travel, void *user)
+{
+ uint i, j;
+ mac_store_sta_t *sta;
+ dbg_assert (ctx);
+ dbg_assert (MAC_TEI_IS_STA (tei));
+ dbg_assert (travel);
+ arch_dsr_lock ();
+ sta = ctx->sta[tei];
+ if (!sta)
+ {
+ arch_dsr_unlock ();
+ }
+ else
+ {
+ /* Ensure we do not lose the STA. */
+ blk_addref (sta);
+ arch_dsr_unlock ();
+ /* Travel MFS. */
+ for (i = 0; i < MAC_STORE_KIND_STA_NB; i++)
+ {
+ for (j = 0; j < MAC_PLID_NB; j++)
+ {
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, sta->plid[i][j],
+ travel, user);
+ }
+ arch_dsr_lock ();
+ mac_store_mfs_travel_mfs_and_unlock (ctx, sta->mme[i], travel,
+ user);
+ }
+ for (i = MAC_LLID_MIN; i <= MAC_LLID_MAX; i++)
+ {
+ arch_dsr_lock ();
+ /* Do this test at each loop step as the scheduler is unlocked
+ * between each step. */
+ if (!sta->rx_llid)
+ {
+ arch_dsr_unlock ();
+ break;
+ }
+ mac_store_mfs_travel_mfs_and_unlock (ctx, sta->rx_llid[i],
+ travel, user);
+ }
+
+#if CONFIG_MAC_COMMON_EOC_MFS
+ for (i = MAC_LLID_MIN; i <= MAC_LLID_MAX; i++)
+ {
+ arch_dsr_lock ();
+ /* Do this test at each loop step as the scheduler is unlocked
+ * between each step. */
+ if (!sta->tx_llid)
+ {
+ arch_dsr_unlock ();
+ break;
+ }
+ mac_store_mfs_travel_mfs_and_unlock (ctx, sta->tx_llid[i],
+ travel, user);
+ }
+#endif
+ blk_release (sta);
+ }
+}
+
+sta_t *
+mac_store_sta_get_ (mac_store_t *ctx, uint tei __FL)
+{
+ dbg_assert (ctx);
+ dbg_blame (MAC_TEI_IS_STA (tei));
+ arch_dsr_lock ();
+ mac_store_sta_t *sta = ctx->sta[tei];
+ if (sta)
+ {
+ blk_addref_ (sta __fl);
+ arch_dsr_unlock ();
+ return &sta->sta;
+ }
+ else
+ {
+ arch_dsr_unlock ();
+ return NULL;
+ }
+}
+
+void
+mac_store_sta_add_ (mac_store_t *ctx, uint tei __FL)
+{
+ mac_store_sta_t *sta;
+ uint i, j;
+ dbg_assert (ctx);
+ dbg_blame (MAC_TEI_IS_STA (tei));
+ /* If the DSR lock time need to be decreased, the STA could be
+ * initialised, then existence be checked again. */
+ arch_dsr_lock ();
+ if (!ctx->sta[tei])
+ {
+ sta = blk_new_ ((blk_destructor_t) sta_uninit __fl);
+ sta_init (&sta->sta, tei);
+ /* Clear the new STA tables. */
+ for (i = 0; i < COUNT (sta->plid); i++)
+ {
+ for (j = 0; j < COUNT (sta->plid[i]); j++)
+ {
+ sta->plid[i][j] = NULL;
+ }
+ sta->mme[i] = NULL;
+ }
+ sta->rx_llid = NULL;
+ #if CONFIG_MAC_COMMON_EOC_MFS
+ sta->tx_llid = NULL;
+ #endif /* CONFIG_MAC_COMMON_EOC_MFS */
+ /* Done, ready to be used (order is important). */
+ arch_reorder_barrier ();
+ ctx->sta[tei] = sta;
+ }
+ arch_dsr_unlock ();
+}
+
+bool
+mac_store_sta_remove_ (mac_store_t *ctx, uint tei __FL)
+{
+ mac_store_sta_t *sta;
+ uint i, j;
+ dbg_assert (ctx);
+ dbg_blame (MAC_TEI_IS_STA (tei));
+ dbg_blame (ctx->sta[tei] != NULL);
+ arch_dsr_lock ();
+ /* Order is important! */
+ sta = ctx->sta[tei];
+ arch_reorder_barrier ();
+ /* Check the MFS are freed. */
+ bool ok = true;
+ for (i = 0; ok && i < COUNT (sta->plid); i++)
+ {
+ for (j = 0; ok && j < COUNT (sta->plid[i]); j++)
+ if (sta->plid[i][j])
+ ok = false;
+ if (sta->mme[i])
+ ok = false;
+ }
+ if (ok && sta->rx_llid)
+ {
+ for (i = 0; ok && i < MAC_LLID_MAX; i++)
+ if (sta->rx_llid[i])
+ ok = false;
+ }
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (ok && sta->tx_llid)
+ {
+ for (i = 0; ok && i < MAC_LLID_MAX; i++)
+ if (sta->tx_llid[i])
+ ok = false;
+ }
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
+ if (ok)
+ {
+ /* Can no longer be accessed by interrupts, order is important. */
+ arch_reorder_barrier ();
+ ctx->sta[tei] = NULL;
+ arch_reorder_barrier ();
+ /* Free the LLID table. If someone owns a reference, this is not the
+ * store and it does not care about rx_llid. */
+ if (sta->rx_llid)
+ blk_release_ (sta->rx_llid __fl);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (sta->tx_llid)
+ blk_release_ (sta->tx_llid __fl);
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
+ /* Release the STA information. */
+ blk_release_ (sta __fl);
+ }
+ arch_dsr_unlock ();
+ return ok;
+}
+
+int
+mac_store_get_free_tx_llid (mac_store_t *ctx)
+{
+ int i;
+ dbg_assert (ctx);
+ for (i = MAC_LLID_MIN; i <= MAC_LLID_MAX; i++)
+ {
+ if (ctx->lglid[i] == NULL)
+ return i;
+ }
+ return -1;
+}
+
+int
+mac_store_get_free_tei (mac_store_t *ctx)
+{
+ int i;
+ dbg_assert (ctx);
+ for (i = MAC_TEI_STA_MIN; i <= MAC_TEI_STA_MAX; i++)
+ {
+ if (ctx->sta[i] == NULL)
+ return i;
+ }
+ return -1;
+}
+
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/msg_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/msg_stub.c
new file mode 100644
index 0000000000..8a2796c788
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/msg_stub.c
@@ -0,0 +1,1160 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/msg.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+#include "cp/cp.h"
+#include "cp/msg/msg.h"
+
+#include "lib/scenario/scenario.h"
+#include "mac/common/tonemap.h"
+
+#include "cp/inc/context.h"
+
+#include "hal/phy/defs.h"
+#include "cp/msg/inc/vs_get_tonemap.h"
+#include "cp/msg/inc/allowed_mme.h"
+#include "cp/msg/inc/msg.h"
+
+#include "common/defs/homeplugAV.h"
+#include "common/defs/ethernet.h"
+
+
+#include "cp/mme.h"
+#include "common/defs/spidcom.h"
+
+#include "cp/sta/mgr/net.h"
+#include "cp/sta/mgr/sta_mgr.h"
+
+
+#include "cp/msg/inc/msg_vs_eoc.h"
+
+#include "cp/eoc/cco/bw/service.h"
+
+#include "stdio.h"
+
+#include "config/cp/msg/eoc/multi/sta/mme.h"
+#include "config/cp/msg/eoc.h"
+
+#define CP_MSG_CM_ENC_PLAYLOAD_RF_LEN_MAX_SIZE 15
+
+/**
+ * Name of the event when there is no event.
+ */
+#define NO_EVENT NB
+
+#define CP_MSG_MME_ALLOWED_ENTRY(mmtype, min_sta_status, encrypted, from_h1, \
+ cp_fsm_event) \
+{ \
+ mmtype, \
+ PASTE (CP_MSG_MME_, min_sta_status), \
+ PASTE (CP_MSG_MME_, encrypted), \
+ PASTE (CP_MSG_MME_, from_h1), \
+ PASTE (CP_FSM_EVENT_TYPE_, cp_fsm_event), \
+ trace_do (# mmtype) \
+}
+
+cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
+{
+ CP_MSG_MME_ALLOWED_ENTRY (CC_CCO_APPOINT_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_CCO_APPOINT_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_CCO_APPOINT_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_BACKUP_APPOINT_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_BACKUP_APPOINT_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_INFO_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_INFO_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_INFO_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_INFO_RSP, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_HANDOVER_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, CC_HANDOVER_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_HANDOVER_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, CC_HANDOVER_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_HANDOVER_INFO_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, CC_HANDOVER_INFO_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_HANDOVER_INFO_RSP, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, CC_HANDOVER_INFO_RSP),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DISCOVER_LIST_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DISCOVER_LIST_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DISCOVER_LIST_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_NEW_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_NEW_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_MOD_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_MOD_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_SQZ_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_SQZ_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_REL_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_REL_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DETECT_REPORT_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DETECT_REPORT_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_WHO_RU_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, CC_WHO_RU_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_WHO_RU_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_WHO_RU_CNF),
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ASSOC_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, MULTI_STA_MME),
+#else
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ASSOC_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_ASSOC_REQ),
+#endif /* CONFIG_CP_MSG_EOC_MULTI_STA_MME */
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ASSOC_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_ASSOC_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LEAVE_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_LEAVE_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LEAVE_CNF, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_LEAVE_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LEAVE_IND, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_LEAVE_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_LEAVE_RSP, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_LEAVE_RSP),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_SET_TEI_MAP_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_SET_TEI_MAP_IND, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_SET_TEI_MAP_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_RELAY_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_RELAY_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_RELAY_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_RELAY_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_BEACON_RELIABILITY_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_BEACON_RELIABILITY_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ALLOC_MOVE_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ALLOC_MOVE_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_NEW_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_NEW_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_NEW_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_NEW_RSP, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_REL_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_REL_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_REL_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ACCESS_REL_RSP, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DCPPC_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_DCPPC_RSP, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_HP1_DET_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_HP1_DET_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_BLE_UPDATE_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CP_PROXY_APPOINT_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CP_PROXY_APPOINT_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (PH_PROXY_APPOINT_IND, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CP_PROXY_WAKE_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_INL_REQ, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_INL_CNF, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_NEW_NET_REQ, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_NEW_NET_CNF, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_NEW_NET_IND, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_ADD_ALLOC_REQ, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_ADD_ALLOC_CNF, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_ADD_ALLOC_IND, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_REL_ALLOC_REQ, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_REL_ALLOC_CNF, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (NN_REL_NET_IND, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_UNASSOCIATED_STA_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_UNASSOCIATED_STA_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_ENCRYPTED_PAYLOAD_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_ENCRYPTED_PAYLOAD_RSP, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_SET_KEY_REQ, STA_ASSOC, NEK_ENC_YES, FROM_H1_YES, CM_SET_KEY_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_SET_KEY_CNF, STA_ASSOC, NEK_ENC_YES, FROM_H1_YES, CM_SET_KEY_CNF),
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+ CP_MSG_MME_ALLOWED_ENTRY (CM_GET_KEY_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, MULTI_STA_MME),
+#else
+ CP_MSG_MME_ALLOWED_ENTRY (CM_GET_KEY_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, CM_GET_KEY_REQ),
+#endif /* CONFIG_CP_MSG_EOC_MULTI_STA_MME */
+ CP_MSG_MME_ALLOWED_ENTRY (CM_GET_KEY_CNF, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, CM_GET_KEY_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_SC_JOIN_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_SC_JOIN_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_SC_JOIN_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_SC_JOIN_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CHAN_EST_IND, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CM_CHAN_EST_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_TM_UPDATE_IND, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CM_TM_UPDATE_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_AMP_MAP_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_AMP_MAP_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_BRG_INFO_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, CM_BRG_INFO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_BRG_INFO_CNF, STA_AUTH, NEK_ENC_NO, FROM_H1_NO, CM_BRG_INFO_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_NEW_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_NEW_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_REL_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_REL_RSP, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_MOD_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_MOD_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_INFO_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_CONN_INFO_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_STA_CAP_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, CM_STA_CAP_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_STA_CAP_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_NW_INFO_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, CM_NW_INFO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_NW_INFO_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_GET_BEACON_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_GET_BEACON_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_HFID_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, CM_HFID_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_HFID_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_HFID_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_MME_ERROR_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_MME_ERROR_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_NW_STATS_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, CM_NW_STATS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_NW_STATS_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_LINK_STATS_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, CM_LINK_STATS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CM_LINK_STATS_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_VERSION_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_VERSION_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_RESET_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_RESET_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_MFG_INFO_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_MFG_INFO_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_NVRAM_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_NVRAM_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_LOOPBACK_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_LOOPBACK_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_SET_LOOPBACK_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_SET_LOOPBACK_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_TONEMASK_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_TONEMASK_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_ETH_PHY_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_ETH_PHY_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_ETH_STATS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_ETH_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_PLC_STATS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_PLC_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_STATUS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_STATUS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_TONEMAP_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_TONEMAP_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_TONEMAP_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_SNR_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_SNR_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_SNR_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_SPECTRUM_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_SPECTRUM_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_SPECTRUM_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_LINK_STATS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_LINK_STATS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_LINK_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_AMP_MAP_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_AMP_MAP_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_AMP_MAP_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_STATS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_STATS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_GET_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+#if CONFIG_CP_MSG_EOC_VS
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_TOPO_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_GET_TOPO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_TOPO_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+#endif /* CONFIG_CP_MSG_EOC_VS */
+ CP_MSG_MME_ALLOWED_ENTRY (IMAC_GET_DISCOVER_LIST_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, IMAC_GET_DISCOVER_LIST_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (IMAC_GET_DISCOVER_LIST_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_MAC_ADDR_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_MAC_ADDR_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_MAC_ADDR_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_CCO_PREF_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_CCO_PREF_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_CCO_PREF_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_WAS_CCO_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_WAS_CCO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_WAS_CCO_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_NPW_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_NPW_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_NPW_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_DPW_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_DPW_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_DPW_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_SL_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_SL_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_SL_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_M_STA_HFID_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_M_STA_HFID_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_M_STA_HFID_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_U_STA_HFID_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_U_STA_HFID_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_U_STA_HFID_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_U_STA_HFID_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_AVLN_HFID_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_AVLN_HFID_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_AVLN_HFID_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_AVLN_HFID_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_TONEMASK_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_TONEMASK_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_TONEMASK_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_MAC_START_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_MAC_START_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_MAC_START_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_MAC_STOP_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_MAC_STOP_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_MAC_STOP_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SC_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SC_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SC_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_STATUS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_STATUS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_STATUS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_STATUS_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_KEY_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_KEY_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_KEY_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_KEY_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_GET_KEY_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_GET_KEY_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_GET_KEY_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_DAK_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_STA_SET_DAK_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_DAK_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+};
+
+uint cp_msg_mme_allowed_count = COUNT (cp_msg_mme_allowed);
+
+
+void
+cp_msg_init (cp_t *ctx) __attribute__((weak));
+
+void
+cp_msg_init (cp_t *ctx) {}
+
+void
+cp_msg_uninit (cp_t *ctx) __attribute__((weak));
+
+void
+cp_msg_uninit (cp_t *ctx) {}
+
+void
+cp_msg_dispatch (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+void
+cp_msg_dispatch (cp_t *ctx, cp_mme_rx_t *mme) {}
+
+bool
+cp_msg_imac_get_discover_list_req_receive (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_imac_get_discover_list_cnf_send_begin (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_imac_get_discover_list_cnf_result_t result, u8 version,
+ u8 num_stations) __attribute__((weak));
+
+void
+cp_msg_imac_get_discover_list_cnf_send (cp_t *ctx, cp_mme_tx_t *mme,
+ const cp_msg_imac_discover_list_sta_info_t *data) __attribute__((weak));
+
+void
+cp_msg_imac_get_discover_list_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_mme_init (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_mme_init (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype)
+{
+ cp_mme_tx_t my_mme;
+ cp_mme_tx_t *mme = &my_mme;
+
+ u64 data;
+ u8 buffer[1024];
+ 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))
+ {
+ 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 = swap16 (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 = swap16 (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;
+}
+
+cp_mme_tx_t *
+cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype,
+ cp_mme_peks_t peks,
+ const cp_secu_protocol_run_t *prun) __attribute__((weak));
+cp_mme_tx_t *
+cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype,
+ cp_mme_peks_t peks,
+ const cp_secu_protocol_run_t *prun)
+{
+ return NULL;
+}
+
+void
+cp_msg_mme_write_frag_header (cp_t *ctx, cp_mme_tx_t *msg, bitstream_t *bs,
+ cp_mmtype_t mmtype) __attribute__((weak));
+
+void
+cp_msg_mme_write_frag_header (cp_t *ctx, cp_mme_tx_t *msg, bitstream_t *bs,
+ cp_mmtype_t mmtype) {}
+
+cp_mme_tx_t *
+cp_msg_mme_init_frag (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ uint fmi_nbFrag, uint fmi_fnmi, uint fmi_ssn) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_mme_init_frag (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ uint fmi_nbFrag, uint fmi_fnmi, uint fmi_ssn)
+{
+ return NULL;
+}
+
+void
+cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme) __attribute__((weak));
+
+void
+cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme) {}
+
+cp_mme_rx_t *
+cp_msg_mme_read_header (cp_t *ctx, u8 *mme, uint length, cp_tei_t tei,
+ uint *fmi, bool cl_data) __attribute__((weak));
+
+cp_mme_rx_t *
+cp_msg_mme_read_header (cp_t *ctx, u8 *mme, uint length, cp_tei_t tei,
+ uint *fmi, bool cl_data)
+{
+ return NULL;
+}
+
+bool
+cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+bool
+cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ return true;
+}
+
+void
+cp_msg_mme_rx_change_buffer (cp_mme_rx_t *msg) __attribute__((weak));
+
+void
+cp_msg_mme_rx_change_buffer (cp_mme_rx_t *msg) {}
+
+void
+cp_msg_mme_tx_change_buffer (bitstream_t *bs, cp_mme_tx_t *mme) __attribute__((weak));
+
+void
+cp_msg_mme_tx_change_buffer (bitstream_t *bs, cp_mme_tx_t *mme) {}
+
+void
+cp_msg_mme_read_error_process (bitstream_t *ctx, void *user_data) __attribute__((weak));
+
+void
+cp_msg_mme_read_error_process (bitstream_t *ctx, void *user_data)
+{
+}
+
+bool
+cp_msg_imac_get_discover_list_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ return true;
+}
+
+cp_mme_tx_t *
+cp_msg_imac_get_discover_list_cnf_send_begin (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_imac_get_discover_list_cnf_result_t result, u8 version,
+ u8 num_stations)
+{
+ cp_mme_tx_t * mme;
+
+ dbg_assert (ctx);
+ dbg_assert (peer);
+
+ mme = cp_msg_mme_init (ctx, peer, IMAC_GET_DISCOVER_LIST_CNF);
+ dbg_assert (mme);
+
+ return mme;
+}
+
+void
+cp_msg_imac_get_discover_list_cnf_send (cp_t *ctx, cp_mme_tx_t *mme,
+ const cp_msg_imac_discover_list_sta_info_t *data)
+{
+}
+
+void
+cp_msg_imac_get_discover_list_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme)
+{
+}
+
+#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->vlan_tag == param->peer.vlan_tag); \
+ 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) \
+ } \
+}
+
+__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_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_ports (cp_msg_vs_eoc_cco_get_ports_cnf_send,
+ (cp_msg_vs_eoc_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))
+
+__mr (cp_msg_vs_eoc_cco_get_ports_req_receive,
+ (u8, first_mac_index_nb, assign))
+
+__ms_services (cp_msg_vs_eoc_cco_get_services_cnf_send,
+ (cp_msg_vs_eoc_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))
+
+bool
+cp_msg_vs_get_snr_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ mac_t *mac_addr,
+ cp_msg_vs_get_snr_req_int_t *tm_int_i,
+ u8 *int_id,
+ u8 *carrier_gr)
+{
+ return true;
+}
+
+void
+cp_msg_vs_get_snr_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ const cp_msg_vs_get_snr_cnf_t *data)
+{
+}
+
+cp_mme_tx_t *
+cp_msg_cm_nw_stats_cnf_send_begin (cp_t *ctx, cp_mme_peer_t *peer_info,
+ const uint num_stats)
+{
+ return NULL;
+}
+
+void
+cp_msg_cm_nw_stats_cnf_send (cp_t *ctx, cp_mme_tx_t *mme,
+ mac_t mac, uint phy_dr_tx, uint phy_dr_rx)
+{
+}
+
+void
+cp_msg_cm_nw_stats_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme)
+{
+}
+
+void
+data_rate_update_info (cl_data_rate_t *p_dr, uint data_size)
+{
+}
+
+bool
+cp_msg_cm_set_key_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cm_set_key_cnf_t *data)
+{
+ return true;
+}
+/**
+ * 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 (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,
+ u8 up_att)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (auth_status <= 1);
+
+ bitstream_write_large (&mme->bitstream, mac_addr, 48);
+ bitstream_write (&mme->bitstream, auth_status, 8);
+ bitstream_write (&mme->bitstream, 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, 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_actions);
+
+ uint number_of_stations; /* Number of stations in the current MME */
+ 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(&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, cp_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 (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, 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_actions);
+
+ /* One MME can contain maximum of 43 WL entries*/
+ total_wl_index_nb = numStas;
+
+ if (first_wl_index_nb > total_wl_index_nb)
+ wl_index_nb = 0;
+ else
+ wl_index_nb = ((total_wl_index_nb - first_wl_index_nb) >= 43) ?
+ 43 : total_wl_index_nb - first_wl_index_nb;
+
+ tx = cp_msg_mme_init (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(&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 (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, cp_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 (ctx, peer, mmtype);
+ dbg_check (msg);
+
+ bitstream_access (&msg->bitstream, &result, 8);
+
+ cp_msg_mme_send (ctx, msg);
+}
+
+bool
+cp_msg_vs_eoc_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_set_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ cp_msg_vs_eoc_set_services_req_result_t result)
+{
+ cp_mme_tx_t *msg;
+
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+
+ msg = cp_msg_mme_init (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)
+{
+ return true;
+}
+
+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, u8 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,%u,%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)
+{
+ return true;
+}
+
+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)
+{
+ 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_stats_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);
+
+}
+
+void
+cp_msg_vs_get_ce_stats_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ u8 version,
+ u8 result,
+ sta_t *sta,
+ tonemask_info_t *ti)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/pbproc_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/pbproc_stub.c
new file mode 100644
index 0000000000..f556b2976d
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/pbproc_stub.c
@@ -0,0 +1,31 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest_eoc/src/pbproc_stub.c
+ * \brief General PB Processing functions.
+ * \ingroup pbproc
+ */
+#include "common/std.h"
+
+#include "mac/pbproc/inc/context.h"
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{
+}
+
+void pbproc_parameters_adjust (pbproc_t *ctx, bool adjust)
+{
+}
+
+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/src/pwl_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/pwl_stub.c
new file mode 100644
index 0000000000..59cdea8ec2
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/pwl_stub.c
@@ -0,0 +1,21 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file stub/pwl.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/pwl/pwl.h"
+
+void
+cp_pwl_reset (cp_t *ctx)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/sta_vs_eoc_stub.c b/cesar/cp/eoc/cco/action/test/utest/src/sta_vs_eoc_stub.c
new file mode 100644
index 0000000000..b27beb38a5
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/sta_vs_eoc_stub.c
@@ -0,0 +1,85 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest/src/sta_vs_eoc_stub.c
+ * \brief STA action stub, VS_EOC related definitions.
+ * \ingroup
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+
+#include "cp/msg/msg.h"
+#include "cp/inc/context.h"
+#include "cp/fsm/fsm.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "lib/stats.h"
+#include "ce/rx/bitloading/inc/nsr.h"
+#include "mac/pbproc/inc/context.h"
+
+#include "cp/msg/inc/msg_vs_eoc.h"
+#include "cp/eoc/sta/action/vs_eoc.h"
+
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ bool ok;
+ cp_msg_vs_eoc_get_info_req_result_t status =
+ CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_SUCCESS;
+ u8 clear;
+ real_time_stats_t rt_stats;
+
+ dbg_assert(ctx);
+ dbg_assert(mme);
+
+ ok = cp_msg_vs_eoc_cco_get_real_time_stats_req_receive (ctx, mme, &clear);
+ if (ok)
+ {
+ if(clear == 1)
+ {
+ rt_stats.nb_unicast_packets_rx = 0;
+ rt_stats.nb_unicast_packets_tx = 0;
+ rt_stats.total_nb_bytes_rx = 0;
+ rt_stats.total_nb_bytes_tx = 0;
+ rt_stats.nb_broadcast_packets_rx = 0;
+ rt_stats.nb_broadcast_packets_tx = 0;
+ rt_stats.nb_multicast_packets_rx = 0;
+ rt_stats.nb_multicast_packets_tx = 0;
+ rt_stats.nb_packets_rx_crc = 0;
+ rt_stats.nb_packets_rx_short = 0;
+ rt_stats.nb_packets_tx_short = 0;
+ rt_stats.nb_packets_tx_dropped = 0;
+ rt_stats.nb_packets_rx_discarded = 0;
+ rt_stats.avg_pre_fec_bit_error_rate = 0;
+ }
+ 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 = 60;
+ }
+ else
+ {
+ status = CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_FAILURE;
+ }
+
+ cp_msg_vs_eoc_cco_get_real_time_stats_cnf_send (ctx, &mme->peer, status, &rt_stats);
+}
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..77573d0b1b
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/test_actions.c
@@ -0,0 +1,3598 @@
+/* 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/sar_context.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]; \
+ } \
+ }
+
+#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] = 0; \
+ 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]; \
+ } \
+ }
+
+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_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_reset (test_sta_action_t *ctx)
+{
+ cp_sta_mgr_uninit (&ctx->cp);
+ cp_sta_mgr_init (&ctx->cp);
+}
+
+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
+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] __attribute__((aligned(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_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;
+
+ //set our avln
+ 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);
+
+ // Build the MME.
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ //Mac address
+ 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] __attribute__((aligned(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] __attribute__((aligned(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] __attribute__((aligned(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] __attribute__((aligned(1024)));
+ char m_sta_hfid[CP_HFID_SIZE + 1];
+
+ //sample manufacturer human friendly identifier: Spidcom_SPC_300_EoC_m_HFID_123;
+ strcpy(m_sta_hfid, "Spidcom_SPC_300_EoC_m_HFID_123");
+
+ //zero padding
+ memset((m_sta_hfid + sizeof("Spidcom_SPC_300_EoC_m_HFID_123")), '\0',
+ (sizeof(m_sta_hfid) - sizeof("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] __attribute__((aligned(1024)));
+ char u_sta_hfid[CP_HFID_SIZE + 1];
+
+ //sample user human friendly identifier: Spidcom_SPC_300_EoC_u_HFID_123;
+ strcpy(u_sta_hfid, "Spidcom_SPC_300_EoC_u_HFID_123");
+
+ //zero padding
+ memset((u_sta_hfid + sizeof("Spidcom_SPC_300_EoC_u_HFID_123")), '\0',
+ (sizeof(u_sta_hfid) - sizeof("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] __attribute__((aligned(1024)));
+ char avln_hfid[CP_HFID_SIZE + 1];
+
+ //sample avln human friendly identifier: Spidcom_SPC_300_EoC_avln_HFID_123;
+ strcpy(avln_hfid, "Spidcom_SPC_300_EoC_avln_HFID_123");
+
+ //zero padding
+ memset((avln_hfid + sizeof("Spidcom_SPC_300_EoC_avln_HFID_123")), '\0',
+ (sizeof(avln_hfid) - sizeof("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] __attribute__((aligned(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_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] __attribute__((aligned(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_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] __attribute__((aligned(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] __attribute__((aligned(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_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];
+ u8 buffer[1024] __attribute__((aligned(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;
+ 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_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]);
+ 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]);
+ }
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ }
+ }
+ 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_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];
+ u8 buffer[1024] __attribute__((aligned(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;
+ 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_access(&bitstream, &stas_actions[i], 8);
+ }
+
+ bitstream_finalise (&bitstream);
+
+ 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] = true;
+ 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;
+ 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_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);
+
+ if(stas_authorizations[i] == true)
+ test_fail_unless(tei == stas_teis[i]);
+ else
+ test_fail_unless(tei == MAC_TEI_UNASSOCIATED);
+
+ 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]);
+ }
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ }
+ }
+ 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_sta_t *sta_1;
+ cp_sta_t *sta_2;
+ cp_sta_t *sta_3;
+ 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_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];
+ u8 buffer[1024] __attribute__((aligned(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;
+ stas_actions[0] = 0x00;
+ stas_actions[1] = 0x00;
+ stas_actions[2] = 0x00;
+
+ sta_1 = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, stas_macs[0]);
+ sta_2 = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, stas_macs[1]);
+ sta_3 = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, stas_macs[2]);
+
+ 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_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]);
+ }
+ test_fail_unless(sta->multi_sta.action == stas_actions[i]);
+ }
+ }
+ 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_sta_t *sta_1;
+ cp_sta_t *sta_2;
+ cp_sta_t *sta_3;
+ 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_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] __attribute__((aligned(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;
+
+ sta_1 = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, stas_macs[0]);
+ sta_2 = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, stas_macs[1]);
+ sta_3 = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, stas_macs[2]);
+
+ 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);
+ }
+ 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_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_upstream_attenuations[3];
+ u8 buffer[1024] __attribute__((aligned(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);
+
+ 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_upstream_attenuations[0] = 0x6D;
+ stas_upstream_attenuations[1] = 0x6E;
+ stas_upstream_attenuations[2] = 0x6F;
+
+ 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;
+ cp_sta_t *sta_1;
+ cp_sta_t *sta_2;
+ cp_sta_t *sta_3;
+ 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_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] __attribute__((aligned(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;
+
+ sta_1 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[0], stas_macs[0]);
+ sta_2 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[1], stas_macs[1]);
+ sta_3 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[2], stas_macs[2]);
+
+ 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]);
+ }
+ }
+ }
+ 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_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_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)
+ {
+ printf("DBG: \"vs_eoc__cco__vs_eoc_get_ports_req\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"vs_eoc__cco__vs_eoc_get_ports_req\" test failed\n");
+ test_fail_nb_temp = test->fail_nb;
+ }
+
+ 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_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_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)
+ {
+ printf("DBG: \"vs_eoc__cco__vs_eoc_get_ports_req, data from stations not correct\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"vs_eoc__cco__vs_eoc_get_ports_req, data from stations not correct\" test failed\n");
+ test_fail_nb_temp = test->fail_nb;
+ }
+
+ test_sta_action_uninit (&ctx);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_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] __attribute__((aligned(1024)));
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_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);
+
+ mme->mmtype = VS_EOC_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_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 = NULL;
+ srv = cp_eoc_cco_bw_service_alloc (&ctx);
+
+ 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_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 = NULL;
+ srv = cp_eoc_cco_bw_service_alloc (&ctx);
+ 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_set_services_req (&ctx, mme);
+
+ test_fail_unless (ctx.schedule.services.service_nb == 0);
+
+ }
+ 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_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);
+ 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_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_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)
+ {
+ printf("DBG: \"vs_eoc__cco__vs_eoc_get_services_req\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"vs_eoc__cco__vs_eoc_get_services_req\" test failed\n");
+ test_fail_nb_temp = test->fail_nb;
+ }
+
+ 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;
+ uint cl;
+ ctx.cl = (cl_t *) &cl;
+ pbproc_t pbproc;
+
+ u8 buffer[1024] __attribute__((aligned(1024)));
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ ctx.pbproc = &pbproc;
+ cp_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);
+
+ 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;
+ FILE *fp;
+
+ //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;
+ 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);
+
+ 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
+ {
+ printf("DBG: test, Receiving and processing VS_EOC_GET_INFO_REQ, Error opening get_info.txt\n");
+ }
+
+ 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;
+ uint cl;
+ ctx.cl = (cl_t *) &cl;
+
+ u8 buffer[1024] __attribute__((aligned(1024)));
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_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);
+
+ 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;
+ FILE *fp;
+
+ 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.num_good_assoc_auth;
+ uint num_bad_could_not_assoc = ctx.sta_mgr.sta_own_data.num_bad_could_not_assoc;
+ uint num_bad_assoc_failure = ctx.sta_mgr.sta_own_data.num_bad_assoc_failure;
+ uint num_bad_could_not_auth = ctx.sta_mgr.sta_own_data.num_bad_could_not_auth;
+ uint num_leave = ctx.sta_mgr.sta_own_data.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);
+
+ 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
+ {
+ printf("DBG: test, Receiving and processing VS_EOC_GET_INFO_REQ, Error opening get_info.txt\n");
+ }
+
+ 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_STATS_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;
+ uint cl;
+ ctx.cl = (cl_t *) &cl;
+
+ u8 buffer[1024] __attribute__((aligned(1024)));
+
+ ctx.mac_store = mac_store_init ();
+ sar.mac_store = ctx.mac_store;
+ ctx.sar = &sar;
+ ctx.mac_config = &mac_config;
+ cp_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);
+
+ mme->mmtype = VS_EOC_GET_INFO_REQ;
+ cp_secu_protocol_run_new (&mme->prun, 0, &ctx.rnd);
+
+ u8 clear = 0;
+ FILE *fp;
+
+
+
+ /* Dummy values for the statistics */
+ cp_msg_vs_eoc_get_real_time_stats_req_result_t status =
+ CP_MSG_VS_EOC_GET_REAL_TIME_STATS_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 = 60;
+
+ uint status_read = 0;
+
+ real_time_stats_t rt_stats_read;
+
+ rt_stats_read.nb_unicast_packets_rx = 0;
+ rt_stats_read.nb_unicast_packets_tx= 0;
+ rt_stats_read.total_nb_bytes_rx= 0;
+ rt_stats_read.total_nb_bytes_tx = 0;
+ rt_stats_read.nb_broadcast_packets_rx = 0;
+ rt_stats_read.nb_broadcast_packets_tx = 0;
+ rt_stats_read.nb_multicast_packets_rx = 0;
+ rt_stats_read.nb_multicast_packets_tx = 0;
+ rt_stats_read.nb_packets_rx_crc = 0;
+ rt_stats_read.nb_packets_rx_short = 0;
+ rt_stats_read.nb_packets_tx_short = 0;
+ rt_stats_read.nb_packets_tx_dropped = 0;
+ rt_stats_read.nb_packets_rx_discarded = 0;
+ rt_stats_read.avg_pre_fec_bit_error_rate = 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, &clear, 8);
+ bitstream_finalise (&bitstream);
+
+ cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (&ctx, mme);
+
+ 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
+ {
+ printf("DBG: test, Receiving and processing VS_EOC_GET_REAL_TIME_STATS_REQ, \
+Error opening get_info.txt\n");
+ }
+
+ 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);
+
+ printf("DBG: test, Receiving and processing VS_EOC_GET_REAL_TIME_STATS PASSED\n");
+ }
+ test_end;
+
+
+ test_begin (test, "Receiving and processing CM_NW_STATS_REQ new")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ 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 stas_authorizations[3];
+ u8 buffer[1024] __attribute__((aligned(1024)));
+
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_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;
+ stas_authorizations[0] = true;
+ stas_authorizations[1] = false;
+ stas_authorizations[2] = true;
+
+ 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]);
+ cp_sta_2 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[1], stas_macs[1]);
+ cp_sta_3 = cp_sta_mgr_sta_add (&ctx, net, stas_teis[2], stas_macs[2]);
+
+ 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);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing VS_EOC_CCO_SET_OUT_LEV")
+ {
+ 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_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);
+
+ sta->multi_sta.output_level = 30;
+
+ cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (&ctx, mme);
+ }
+ test_end;
+}
+
+void
+test_case_sta_assoc_and_auth_procedure_action (test_t test)
+{
+ cp_t ctx;
+ cp_trace_init (&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[256] __attribute__((aligned(256)));
+ uint req_type = CP_MSG_CC_ASSOC_REQ_TYPE_NEW;
+ u64 nid = 1;
+ uint cco_cap = 2;
+ uint pco_cap = true;
+
+ 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_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)
+ {
+ printf("DBG: sucess: station state is unassociated (sta not in the wl)\n");
+ }
+ }
+ 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)
+ {
+ printf("DBG: success: station state is unassociated (mac address registered but no tei assigned)\n");
+ }
+
+ }
+ 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;
+
+ 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)
+ {
+ printf("DBG: success: station state is associated (sta in the wl)\n");
+ }
+ }
+ test_end;
+
+ test_begin (test, "cp_sta_action_assoc_init")
+ {
+ cp_t ctx;
+ cp_sta_action_assoc_init(&ctx);
+ test_fail_unless(ctx.sta_action.assoc.assoc_req_retry_nb == 0);
+ }
+ test_end
+
+ test_begin (test, "Receiving a CM_GET_KEY.REQ and transfering to multi_sta")
+ {
+ bitstream_t bitstream;
+ u64 data;
+ u8 buffer[1024] __attribute__((aligned(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 = swap16 (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 = swap16 (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)
+ {
+ printf("DBG: station state is authenticated\n");
+ }
+ }
+ test_end;
+ slab_release(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_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);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mac);
+ mac_store_sta_add_ (ctx.mac_store, tei __fl);
+ mac_store_sta_get_ (ctx.mac_store, tei)->tdma_poll = false;
+ mac_store_sta_get_ (ctx.mac_store, tei)->authenticated = true;
+ ctx.sta_mgr.sta_own_data.is_cco = true;
+
+ test_fail_unless(net->num_stas != 0);
+ test_fail_unless(net->num_associated_stas != 0);
+ test_fail_unless(net->num_visible_stas != 0);
+
+ // First test case: STA is authenticated (TEI != 0)
+ cp_cco_action_garbage(&ctx);
+
+ test_fail_unless(net->num_associated_stas == 0);
+ test_fail_unless(net->num_visible_stas == 0);
+
+ test_fail_unless(net->num_stas == 0);
+
+ // Second test case: STA is unassociated (TEI = 0)
+ sta = cp_sta_mgr_sta_add (&ctx, net, MAC_TEI_UNASSOCIATED, mac);
+ cp_sta_set_authenticated (&ctx, sta, false);
+ mac_config.authenticated = false;
+ sta->expired_date_ms = 0;
+
+ test_fail_unless(net->num_stas != 0);
+ test_fail_unless(net->num_associated_stas == 0);
+ test_fail_unless(net->num_visible_stas != 0);
+
+ cp_cco_action_garbage(&ctx);
+
+ test_fail_unless(net->num_stas == 0);
+ test_fail_unless(net->num_associated_stas == 0);
+ test_fail_unless(net->num_visible_stas == 0);
+
+ slab_release(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_sta_mgr_init (&ctx);
+ cp_cco_action_init (&ctx);
+ tei = 5;
+ mac = 0x004444444444ull;
+ nek_old.key[0] = ctx.cco_action.nek_new.key[0];
+ nek_old.key[1] = ctx.cco_action.nek_new.key[1];
+ nek_old.key[2] = ctx.cco_action.nek_new.key[2];
+ nek_old.key[3] = ctx.cco_action.nek_new.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.nek_new.key[0]);
+ test_fail_unless(nek_old.key[1] != ctx.cco_action.nek_new.key[1]);
+ test_fail_unless(nek_old.key[2] != ctx.cco_action.nek_new.key[2]);
+ test_fail_unless(nek_old.key[3] != ctx.cco_action.nek_new.key[3]);
+
+ slab_release(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;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 result, cco_cap;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ cp_tei_t tei;
+ u8 buffer[1024] __attribute__((aligned(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;
+ ctx.sar = &sar;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ 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);
+
+ 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);
+ }
+ 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_sta_t *sta, *sta1;
+ 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;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ ctx.sar = &sar;
+ cp_cl_interf_init (&ctx);
+ cp_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;
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, snid, nid);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, ctx.cco_action.eks_sta_current_peer.tei, \
+ ctx.cco_action.eks_sta_current_peer.mac);
+ sta1 = 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);
+ }
+ 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;
+
+ 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_sta_mgr_init (&ctx);
+ tei = 5;
+ mac = 0x004444444444ull;
+
+ 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_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_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.vlan_tag == 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_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);
+ }
+ 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_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;
+
+ 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);
+
+ test_fail_unless(net->num_stas == 1);
+ test_fail_unless(net->num_associated_stas == 1);
+ test_fail_unless(net->num_visible_stas == 1);
+ }
+ 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;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+
+ 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_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_begin (t, "set_insert")
+ {
+ cp_tei_t tei_1 = 3;
+ mac_t mac_1 = 0x0000010000D71300ull;
+ cp_sta_t *sta_1 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_1);
+ if(!sta_1)
+ {
+ sta_1 = cp_sta_mgr_sta_add(&ctx, net, tei_1, mac_1);
+ sta_1->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_1 != NULL);
+
+ cp_tei_t tei_2 = 4;
+ mac_t mac_2 = 0x0000020000D71300ull;
+ cp_sta_t *sta_2 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_2);
+ if(!sta_2)
+ sta_2 = cp_sta_mgr_sta_add(&ctx, net, tei_2, mac_2);
+ sta_2->multi_sta.allowed = true;
+ if(!sta_2)
+ {
+ sta_2 = cp_sta_mgr_sta_add(&ctx, net, tei_2, mac_2);
+ sta_2->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_2 != NULL);
+
+ cp_tei_t tei_3 = 5;
+ mac_t mac_3 = 0x0000030000D71300ull;
+ cp_sta_t *sta_3 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_3);
+ if(!sta_3)
+ {
+ sta_3 = cp_sta_mgr_sta_add(&ctx, net, tei_3, mac_3);
+ sta_3->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_3 != NULL);
+
+ cp_tei_t tei_4 = 6;
+ mac_t mac_4 = 0x0000040000D71300ull;
+ cp_sta_t *sta_4 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_4);
+ if(!sta_4)
+ {
+ sta_4 = cp_sta_mgr_sta_add(&ctx, net, tei_4, mac_4);
+ sta_4->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_4 != NULL);
+
+ cp_tei_t tei_5 = 7;
+ mac_t mac_5 = 0x0000050000D71300ull;
+ cp_sta_t *sta_5 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_5);
+ if(!sta_5)
+ {
+ sta_5 = cp_sta_mgr_sta_add(&ctx, net, tei_5, mac_5);
+ sta_5->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_5 != NULL);
+
+ cp_tei_t tei_6 = 8;
+ mac_t mac_6 = 0x0000060000D71300ull;
+ cp_sta_t *sta_6 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_6);
+ if(!sta_6)
+ {
+ sta_6 = cp_sta_mgr_sta_add(&ctx, net, tei_6, mac_6);
+ sta_6->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_6 != NULL);
+
+ cp_tei_t tei_7 = 9;
+ mac_t mac_7 = 0x0000070000D71300ull;
+ cp_sta_t *sta_7 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_7);
+ if(!sta_7)
+ {
+ sta_7 = cp_sta_mgr_sta_add(&ctx, net, tei_7, mac_7);
+ sta_7->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_7 != NULL);
+
+ cp_tei_t tei_8 = 10;
+ mac_t mac_8 = 0x0000080000D71300ull;
+ cp_sta_t *sta_8 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_8);
+ if(!sta_8)
+ {
+ sta_8 = cp_sta_mgr_sta_add(&ctx, net, tei_8, mac_8);
+ sta_8->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_8 != NULL);
+
+ cp_tei_t tei_9 = 11;
+ mac_t mac_9 = 0x0000090000D71300ull;
+ cp_sta_t *sta_9 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_9);
+ if(!sta_9)
+ {
+ sta_9 = cp_sta_mgr_sta_add(&ctx, net, tei_9, mac_9);
+ sta_9->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_9 != NULL);
+
+ cp_tei_t tei_10 = 12;
+ mac_t mac_10 = 0x00000A0000D71300ull;
+ cp_sta_t *sta_10 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_10);
+ if(!sta_10)
+ {
+ sta_10 = cp_sta_mgr_sta_add(&ctx, net, tei_10, mac_10);
+ sta_10->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_10 != NULL);
+
+ cp_tei_t tei_11 = 13;
+ mac_t mac_11 = 0x00000B0000D71300ull;
+ cp_sta_t *sta_11 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_11);
+ if(!sta_11)
+ {
+ sta_11 = cp_sta_mgr_sta_add(&ctx, net, tei_11, mac_11);
+ sta_11->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_11 != NULL);
+
+ cp_tei_t tei_12 = 14;
+ mac_t mac_12 = 0x00000C0000D71300ull;
+ cp_sta_t *sta_12 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_12);
+ if(!sta_12)
+ {
+ sta_12 = cp_sta_mgr_sta_add(&ctx, net, tei_12, mac_12);
+ sta_12->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_12 != NULL);
+
+ cp_tei_t tei_13 = 15;
+ mac_t mac_13 = 0x00000D0000D71300ull;
+ cp_sta_t *sta_13 = cp_sta_mgr_sta_get_from_mac(&ctx, mac_13);
+ if(!sta_13)
+ {
+ sta_13 = cp_sta_mgr_sta_add(&ctx, net, tei_13, mac_13);
+ sta_13->multi_sta.allowed = true;
+ }
+ test_fail_unless(sta_13 != NULL);
+ }
+ 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;
+
+ /* 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_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)
+ {
+ printf("DBG: \"get_tonemap_req_receive return false\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"get_tonemap_req_receive return false\" test failed\n");
+ 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)
+ {
+ printf("DBG: \"invalid mac address\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"invalid mac address\" test failed\n");
+ 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);
+
+ 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)
+ {
+ printf("DBG: \"only get intervals and tonemaps\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"only get intervals and tonemaps\" test failed\n");
+ 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)
+ {
+ printf("DBG: \"tonemap doesn't exist\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"tonemap doesn't exist\" test failed\n");
+ 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)
+ {
+ printf("DBG: \"correct tonemap\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"correct tonemap\" test failed\n");
+ 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)
+ {
+ printf("DBG: \"wrong interval list index\" successfully tested\n");
+ }
+ else
+ {
+ printf("DBG: \"wrong interval list index\" test failed\n");
+ 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 ();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
+
+/**
+ * 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;
+ bool vlantag_present;
+ u64 unused;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (mme->p_mme);
+ dbg_assert (mme->length < ETH_PACKET_MAX_SIZE);
+ dbg_assert (data);
+
+ if (bitstream_direct_read (mme->p_mme + 12, 0, 16) == swap16(HPAV_MTYPE_MME))
+ vlantag_present = false;
+ else
+ vlantag_present = true;
+
+ // 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);
+ if (vlantag_present)
+ bitstream_access (&mme->bitstream, &mme->peer.vlan_tag, 32);
+ bitstream_access (&mme->bitstream, &unused, 16);
+ 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);
+
+ if (vlantag_present)
+ offset = 41;
+ else
+ offset = 37;
+
+ memcpy (mme->p_mme + offset, &data->hash_key, mme->length - offset);
+
+ return true;
+}
+
diff --git a/cesar/cp/eoc/cco/action/test/utest/src/test_fsm.c b/cesar/cp/eoc/cco/action/test/utest/src/test_fsm.c
new file mode 100644
index 0000000000..fff76d0f5c
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest/src/test_fsm.c
@@ -0,0 +1,423 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_fsm.c
+ * \brief Test FSM module.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/blk.h"
+#include "lib/test.h"
+#include "lib/scenario/scenario.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_change_nek),
+ 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_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_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_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/Config b/cesar/cp/eoc/cco/action/test/utest_eoc/Config
new file mode 100644
index 0000000000..607c1bca7a
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/Config
@@ -0,0 +1,11 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF = "cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CP_EOC_CCO_CON_ALLOWED = n
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..129cc3ec51
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/Makefile
@@ -0,0 +1,26 @@
+BASE = ../../../../../..
+
+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 mgr_stub.c pbproc_stub.c interface_stub.c
+test_actions_MODULES = lib cp/eoc/multi_sta_fsm cp/sta/mgr cp/eoc/sta/mgr cp/msg \
+ cp/msg/stub lib/scenario mac/common cp/fsm/stub cp/eoc/cco/action \
+ cp/eoc/multi_sta/action cp/eoc/cco/bw cp/beacon/stub \
+ cp/cco/bw cp/secu/stub mac/sar/stub cp/sta/core/stub \
+ cp/cco/action/stub cl/stub cp/eoc/sta/action/stub \
+ cp/secu bsu/stub
+test_actions_CONFIG_MODULES = cp cl
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_eoc_sta_action_MODULE_SOURCES = drv.c poweron.c
+cp_msg_MODULE_SOURCES = msg.c mme.c msg_vs_eoc.c
+cp_msg_stub_MODULE_SOURCES = msg_cc.c msg_cm.c msg_drv.c msg_vs.c
+
+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..fac7e642c9
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/inc/scenario_defs.h
@@ -0,0 +1,139 @@
+#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_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..a6f67320c9
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/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/beacon/beacon.h"
+#include "cp/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/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"
+
+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;
+};
+
+#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..4e4fd823e2
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/override/cp/sta/core/core.h
@@ -0,0 +1,31 @@
+#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"
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx);
+
+BEGIN_DECLS
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx);
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx);
+
+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..71be233993
--- /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) 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_eoc/override/mac/sar/inc/context.h b/cesar/cp/eoc/cco/action/test/utest_eoc/override/mac/sar/inc/context.h
new file mode 100644
index 0000000000..b74c7a57e3
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/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_eoc/src/interface_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/interface_stub.c
new file mode 100644
index 0000000000..68d5683537
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/interface_stub.c
@@ -0,0 +1,27 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/interface_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+#include "cp/cp.h"
+
+/**
+ * Inform the Data plane when the MME as been processed by the CP.
+ * \param ctx the interface context
+ * \param mme_recv the cl data (as a void pointer).
+ */
+void
+interface_mme_recv_done (interface_t *ctx, void *mme_recv)
+{
+}
diff --git a/cesar/cp/eoc/cco/action/test/utest_eoc/src/mgr_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/mgr_stub.c
new file mode 100644
index 0000000000..467284f59f
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/mgr_stub.c
@@ -0,0 +1,65 @@
+/* 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"
+
+
+bool
+cp_msg_cc_assoc_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cc_assoc_cnf_t *data)
+{
+ dbg_assert (ctx);
+ return true;
+}
+
+void
+cp_cco_action_tei_release (cp_t *ctx, u8 tei)
+{
+ dbg_assert (ctx);
+ dbg_assert (tei);
+}
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx)
+{
+ return 0;
+}
+
+void
+cp_sta_core_checkpoint (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_sta_mgr_get_ports (cp_t *ctx, uint *numStas, mac_t *stas_macs, bool stas_port_ed[][PORT_NB],
+ u8 stas_port_service[][PORT_NB])
+{
+
+}
+
+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_eoc/src/pbproc_stub.c b/cesar/cp/eoc/cco/action/test/utest_eoc/src/pbproc_stub.c
new file mode 100644
index 0000000000..c38af10138
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/pbproc_stub.c
@@ -0,0 +1,19 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest_eoc/src/pbproc_stub.c
+ * \brief General PB Processing functions.
+ * \ingroup pbproc
+ */
+#include "common/std.h"
+
+#include "mac/pbproc/inc/context.h"
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{}
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..eb8180cd01
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/test/utest_eoc/src/test_actions.c
@@ -0,0 +1,304 @@
+/* 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/cco/action/vs_eoc.h"
+#include "cp/msg/msg.h"
+#include "cp/msg/inc/vs_eoc_get_topo.h"
+#include "mac/sar/inc/context.h"
+#include "common/defs/spidcom.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;
+ cp_mmtype_t mmtype;
+ uint fmi_inf;
+ uint fmi_mi;
+ uint fmi_ssn;
+};
+typedef struct mme_header_t mme_header_t;
+
+static u8 buffer[2048] __attribute__((aligned(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, 1518, BITSTREAM_WRITE);
+
+ bitstream_write_large (pstream, pheader->oda, 48);
+ bitstream_write_large (pstream, pheader->osa, 48);
+ bitstream_write (pstream, swap16 (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, 1518, 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 = swap16 (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 (pheader->mmtype >= VS_MIN && pheader->mmtype <= VS_MAX)
+ 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")
+ {
+ uint i;
+ bitstream_t stream;
+ mme_header_t header;
+ mme_header_t expected;
+ uint fmi;
+ u64 data;
+ cp_mme_rx_t *rx_mme;
+ bool res;
+
+ /* init msg */
+ cp_msg_init (&cp);
+
+ /* add my sta to avln */
+ cp_sta_t *my_sta;
+ cp_tei_t my_tei = 5;
+ my_sta = cp_sta_mgr_sta_add (&cp, net, my_tei, my_mac_addr);
+
+ /*********************************/
+ /* 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, 1518, peer.tei, &fmi, false);
+ test_fail_unless (rx_mme != NULL);
+ test_fail_unless (rx_mme->mmtype == VS_EOC_GET_TOPO_REQ);
+ data = cp_msg_mme_read_error (&cp, rx_mme);
+ test_fail_unless (data == true);
+
+ cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req (&cp, 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");
+
+ for(i = 0 ; i < sta_nb ; i++)
+ {
+ bitstream_access (&stream, &data, 48);
+ test_fail_if ((data != my_mac_addr), "Wrong mac address [%d]",i);
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != 1, "Wrong authorization status [%d]",i);
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != 12, "Wrong upstream attenuation [%d]",i);
+ }
+
+ /* End TEST VS_EOC_GET_TOPO.REQ Receive */
+ slab_release (rx_mme);
+ 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 (&cp, my_mac_addr);
+
+ /* uninit msg */
+ cp_msg_uninit (&cp);
+ }
+ 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_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.vlan_tag = 0x0;
+ peer.tei = MAC_TEI_FOREIGN;
+
+ /* 1. test VS_EOC_GET_TOPO */
+ test_case_vs_eoc_get_topo (test);
+
+ /* 2. 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();
+
+ /* 3. check memory usage */
+ test_begin (test, "Memory verification")
+ {
+ test_fail_if (blk_check_memory() == false, "Memory not freed");
+ }
+ test_end;
+
+ /* 4. 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;
+}
+
+void
+cp_cl_interf_add_buffer_tx (cp_t *ctx, u8 * 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/vs_eoc.h b/cesar/cp/eoc/cco/action/vs_eoc.h
new file mode 100644
index 0000000000..681e745fad
--- /dev/null
+++ b/cesar/cp/eoc/cco/action/vs_eoc.h
@@ -0,0 +1,60 @@
+#ifndef cp_eoc_cco_action_vs_eoc_h
+#define cp_eoc_cco_action_vs_eoc_h
+/* Cesar-EoC project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/vs_eoc.h
+ * \brief CCo action, Vendor Specific EoC MME related prototypes.
+ * \ingroup cp_eoc_cco_action
+ */
+
+/* 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
+
+/**
+ * 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);
+
+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__stopped__vs_cco_get_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);
+
+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_ports_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_services_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_cco_action_vs_eoc__cco__vs_eoc_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);
+
+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_h */
diff --git a/cesar/cp/eoc/cco/bw/Module b/cesar/cp/eoc/cco/bw/Module
new file mode 100644
index 0000000000..970baa70b2
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/Module
@@ -0,0 +1 @@
+SOURCES:= bw.c service.c
diff --git a/cesar/cp/eoc/cco/bw/bw.h b/cesar/cp/eoc/cco/bw/bw.h
new file mode 100644
index 0000000000..26ba7a9e9d
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/bw.h
@@ -0,0 +1,73 @@
+#ifndef cp_eoc_cco_bw_bw_h
+#define cp_eoc_cco_bw_bw_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/bw.h
+ * \brief Beacon Period allocation management
+ * \ingroup cp_eoc_cco_bw
+*/
+#include "cp/cp.h"
+#include "lib/list.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+
+BEGIN_DECLS
+
+/**
+ * Create schedule bentry to be transmitted in EOC beacon
+ * \param ctx the CP module context
+ */
+void
+cp_eoc_cco_bw_bp_allocations (cp_t *ctx);
+
+/** Create allocations at CCo startup or for station that has missed some
+ * beacons
+ * \param ctx module context
+ */
+void
+cp_eoc_cco_bw_sta_allocations (cp_t *ctx);
+
+/**
+ * Initialise scheduler context
+ * \param ctx the CP module context
+ */
+void
+cp_eoc_cco_bw_sched_init (cp_t * ctx);
+
+/**
+ * Uninitialize scheduler context
+ * \param ctx the CP context
+ */
+void
+cp_eoc_cco_bw_sched_uninit (cp_t * ctx);
+
+/** Scheduler function to read elements from scheduler list
+ * \param ctx Control Plane context
+ */
+cp_eoc_cco_bw_sched_alloc_t *
+cp_eoc_cco_bw_sched_read (cp_t *ctx, list_node_t **node);
+
+/** Scheduler function for making scheduling allocations to be used by CA
+ * \param ctx Control Plane context
+ */
+void
+cp_eoc_cco_bw_scheduler (cp_t *ctx);
+
+/**
+ * Adjust scheduling parameters according to number of carriers
+ * \param ctx the module context
+ * \param num_of_carriers actual number of carriers
+ * Info: number of carriers should not be less than 250, otherwise
+ * behavior of PBProc/CA could be problematic.
+ */
+void
+cp_eoc_cco_bw_allocations_adjust (cp_t *ctx, bool adjust);
+
+END_DECLS
+
+#endif /* cp_eoc_cco_bw_bw_h */
diff --git a/cesar/cp/eoc/cco/bw/doc/bandwidth_scheduler.odt b/cesar/cp/eoc/cco/bw/doc/bandwidth_scheduler.odt
new file mode 100644
index 0000000000..eff6099934
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/doc/bandwidth_scheduler.odt
Binary files differ
diff --git a/cesar/cp/eoc/cco/bw/doc/beacon_period.odt b/cesar/cp/eoc/cco/bw/doc/beacon_period.odt
new file mode 100644
index 0000000000..558d5b43d7
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/doc/beacon_period.odt
Binary files differ
diff --git a/cesar/cp/eoc/cco/bw/inc/bw.h b/cesar/cp/eoc/cco/bw/inc/bw.h
new file mode 100644
index 0000000000..918b1ea701
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/inc/bw.h
@@ -0,0 +1,95 @@
+#ifndef cp_eoc_cco_bw_inc_bw_h
+#define cp_eoc_cco_bw_inc_bw_h
+/* Cesar project {{{
+ *
+ * Cppyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+#include "mac/common/timings.h"
+#include "cp/eoc/cco/bw/inc/service.h"
+#include "lib/slab.h"
+#include "lib/list.h"
+
+/** Minimal duration of CSMA period in EoC (ticks). Should not be less than 3ms*/
+#define MIN_CSMA_EOC_TCK MAX((3 * CP_PWL_BP_EOC / 100), MAC_US_TO_TCK (4300))
+/** Duration of allocation beacon */
+#define MIN_SPC_CENTRAL_TCK MAC_US_TO_TCK (1300)
+#define MIN_SPC_HOLE_TCK 5000
+#define NUM_SYM_ONE_POLL 49
+#define NUM_SYM_ONE_POLL_SLOW 72
+
+#define SHORT_FRAME_TCK MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+#define SHORT_FRAME_TCK_EMPTY_SOF 2*(MAC_PREAMBLE_HYBRID_TCK\
+ + MAC_FC_10_TCK \
+ + MAC_DX567_TCK \
+ + MAC_FC_AV_TCK)\
+ + MAC_RIFS_DEFAULT_TCK
+#define SCHEDULING_PERIOD CP_PWL_BP_EOC\
+ - cp_eoc_cco_bw_csma_duration - cp_eoc_cco_bw_central_tck
+#define ONE_POLL_TCK 2 * (SHORT_FRAME_TCK + 2 * MAC_DX567_TCK + \
+ cp_eoc_cco_bw_symbol_nb * MAC_DX417_TCK)\
+ + MAC_RIFS_DEFAULT_TCK + MAC_AIFS_TCK
+
+/** Duration of startup period on CCo */
+#define CP_EOC_CCO_STARTUP_PERIOD MAC_MS_TO_TCK (MAC_SEC_TO_MS (20))
+/** Duration of CSMA period in beacon during statrup */
+#define CP_EOC_CSMA_STARTUP_PERIOD MAC_MS_TO_TCK (25)
+
+/** Number of beacon periods with no answer from station. */
+#define CP_EOC_NO_POLL_ONE 1
+#define CP_EOC_NO_POLL_TWO 2
+#define CP_EOC_NO_POLL_THREE 4
+
+/** Maximum number of symbols per one frame*/
+#define MAX_SYMBOLS_PER_FRAME 48
+/** Minimum nuber of symbols per one sound frame. */
+#define MIN_SYMBOLS_PER_SOUND_FRAME 30
+/** Minimum number of symbols per one PB in ROBO frame. */
+#define MIN_SYMBOLS_PER_PB_ROBO 20
+/** Number of polls per bp for stations with no bw limitation*/
+#define POLL_NB_UNLIMITED 0xff
+
+/** Scheduling context of CP */
+struct cp_eoc_cco_bw_sched_t
+{
+ /** Slab allocator for sched_alloc */
+ slab_cache_t slab;
+ /** Array of associated stations */
+ sta_t **sta_array;
+ /** Scheduling list. */
+ list_t sched_list;
+ /** Scheduling Period - time to be divided between hosts*/
+ uint sched_period;
+ /** Last scheduled station - its index in station array */
+ uint last_sta;
+ /** Service pool of scheduling context*/
+ cp_eoc_cco_services_t services;
+ /** Table of durations*/
+ uint symbol_nb_to_tick_table [MAX_SYMBOLS_PER_FRAME + 1];
+};
+typedef struct cp_eoc_cco_bw_sched_t cp_eoc_cco_bw_sched_t;
+
+/**
+ * Scheduling allocation unit, used for allocating frame duration, from CCo
+ * and from station in reverse, for one MFS
+ */
+struct cp_eoc_cco_bw_sched_alloc_t
+{
+ /** tei of associated station */
+ u8 tei;
+ /** Link ID for which to send (and receive) */
+ u8 lid;
+ /** duration of frame from CCo */
+ uint cco_tx_duration;
+ /** duration of frame from station */
+ uint sta_tx_duration;
+ /** Node for scheduling list */
+ list_node_t sched_node;
+ /** Numer of polls per beacon period */
+ u8 poll;
+};
+typedef struct cp_eoc_cco_bw_sched_alloc_t cp_eoc_cco_bw_sched_alloc_t;
+
+#endif /* cp_eoc_cco_bw_inc_bw_h */
diff --git a/cesar/cp/eoc/cco/bw/inc/service.h b/cesar/cp/eoc/cco/bw/inc/service.h
new file mode 100644
index 0000000000..47f16e1831
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/inc/service.h
@@ -0,0 +1,66 @@
+#ifndef cp_eoc_cco_bw_inc_service_h
+#define cp_eoc_cco_bw_inc_service_h
+/* Cesar project {{{
+ *
+ * Cppyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+#include "lib/slab.h"
+#include "lib/list.h"
+#include "lib/blk.h"
+
+#define MAX_NUMBER_OF_SERVICES 128
+#define SERVICE_PARAMETERS_NB 7
+
+/* Currently, maximum number of services is 128 */
+#define SERVICE_NOT_LIMITED 0x00
+
+/** Set of available services */
+struct cp_eoc_cco_services_t
+{
+ /** Slab allocator for services */
+ slab_cache_t slab;
+ /** List of services */
+ list_t service_list;
+ /** Number of services */
+ int service_nb;
+};
+typedef struct cp_eoc_cco_services_t cp_eoc_cco_services_t;
+
+/** Service parameters and classifying rules */
+struct cp_eoc_cco_bw_service_t
+{
+ /** Unique index specifying the service */
+ u8 service_index;
+ /** Classifying part */
+ u8 classsif_rule;
+ u16 classif_value;
+ /** Latency (ms) */
+ u16 latency;
+ /** Jitter (ms) */
+ u16 jitter;
+ /** Best effort bandwidth (10kbps) */
+ u16 dload_pir;
+ u16 uload_pir;
+ /** Promised bandwidth (10kbps) */
+ u16 dload_cir;
+ u16 uload_cir;
+ /** Priority */
+ u16 qos_prio;
+ /** Node for service list */
+ list_node_t service_node;
+ /** Automatic Connection Service, enabled/disabled */
+ bool acs;
+ /** Scheduling private part */
+ uint dload_pir_to_bp_bits;
+ uint uload_pir_to_bp_bits;
+ uint dload_cir_to_bp_bits;
+ uint uload_cir_to_bp_bits;
+ u8 polls_per_bp;
+};
+
+typedef struct cp_eoc_cco_bw_service_t cp_eoc_cco_bw_service_t;
+
+#endif /* cp_eoc_cco_bw_inc_service_h */
diff --git a/cesar/cp/eoc/cco/bw/service.h b/cesar/cp/eoc/cco/bw/service.h
new file mode 100644
index 0000000000..2905eca971
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/service.h
@@ -0,0 +1,68 @@
+#ifndef cp_eoc_cco_bw_service_h
+#define cp_eoc_cco_bw_service_h
+/* Cesar project {{{
+ *
+ * Cppyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/service.h
+ * \brief Services allocation and update
+ * \ingroup cp_eoc_cco_bw
+*/
+#include "cp/cp.h"
+#include "lib/list.h"
+#include "cp/eoc/cco/bw/inc/service.h"
+
+BEGIN_DECLS
+
+/**
+ * Initialise services
+ * \param ctx the CP module context
+ */
+void
+cp_eoc_cco_services_init (cp_t *ctx);
+
+/**
+ * Initialise scheduler context
+ * \param ctx the CP module context
+ */
+void
+cp_eoc_cco_services_uninit (cp_t *ctx);
+
+/**
+ * Allocate memory for new service
+ * \param ctx the CP module context
+ */
+cp_eoc_cco_bw_service_t *
+cp_eoc_cco_bw_service_alloc (cp_t *ctx);
+
+/**
+ * Find specified service from list of available services
+ * \param ctx the CP module context
+ * \param service_index index of wanted service
+ */
+cp_eoc_cco_bw_service_t *
+cp_eoc_cco_bw_service_find (cp_t *ctx, uint service_index);
+
+/**
+ * Add new service to list of available services
+ * \param ctx the CP module context
+ * \param srv newly created service entry
+ */
+void
+cp_eoc_cco_bw_service_add (cp_t *ctx, cp_eoc_cco_bw_service_t *srv);
+
+/**
+ * Remove service from list of available services
+ * \param ctx the CP module context
+ * \param service_index service to be removed
+ */
+bool
+cp_eoc_cco_bw_service_remove (cp_t *ctx, uint service_index);
+
+END_DECLS
+
+#endif /* cp_eoc_cco_bw_service_h */
diff --git a/cesar/cp/eoc/cco/bw/src/bw.c b/cesar/cp/eoc/cco/bw/src/bw.c
new file mode 100644
index 0000000000..188d085b09
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/src/bw.c
@@ -0,0 +1,527 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/src/bw.c
+ * \brief Create the alloctions for beacon period and create CCo schedule
+ * \ingroup cp_eoc_cco_bw
+ *
+*/
+#include "common/std.h"
+#include "lib/blk.h"
+#include "lib/slab.h"
+#include "lib/list.h"
+
+#include "cp/defs.h"
+#include "cp/cp.h"
+#include "cp/cco/bw/bw.h"
+
+#include "cp/inc/context.h"
+#include "mac/ca/inc/context.h"
+#include "cp/cco/bw/inc/context.h"
+
+#include "cp/eoc/cco/bw/bw.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "cp/eoc/cco/bw/service.h"
+#include "cp/sta/mgr/sta.h"
+
+#include "mac/common/sta.h"
+#define CP_PWL_BP_EOC 2500000
+
+static uint cp_eoc_cco_bw_csma_duration = MAC_US_TO_TCK (4300);
+static uint cp_eoc_cco_bw_central_tck = MIN_SPC_CENTRAL_TCK;
+static uint cp_eoc_cco_bw_symbol_nb_drv = NUM_SYM_ONE_POLL;
+static uint cp_eoc_cco_bw_symbol_nb = NUM_SYM_ONE_POLL;
+
+/**
+ * Adjust scheduling parameters according to number of carriers
+ * \param ctx the module context
+ * \param adjust number of carriers is low
+ * Info: number of carriers should not be less than 250, otherwise
+ * behavior of PBProc/CA could be problematic.
+ */
+void
+cp_eoc_cco_bw_allocations_adjust (cp_t *ctx, bool adjust)
+{
+ dbg_assert (ctx);
+ if (!adjust)
+ {
+ cp_eoc_cco_bw_csma_duration = MIN_CSMA_EOC_TCK;
+ cp_eoc_cco_bw_central_tck = MIN_SPC_CENTRAL_TCK;
+ cp_eoc_cco_bw_symbol_nb_drv = NUM_SYM_ONE_POLL;
+ }
+ else
+ {
+ cp_eoc_cco_bw_csma_duration = MAC_MS_TO_TCK (7);
+ cp_eoc_cco_bw_central_tck = MAC_MS_TO_TCK (2);
+ cp_eoc_cco_bw_symbol_nb_drv = NUM_SYM_ONE_POLL_SLOW;
+ }
+ dbg_assert (cp_eoc_cco_bw_csma_duration - cp_eoc_cco_bw_central_tck >=
+ MAC_MS_TO_TCK (3));
+}
+
+/**
+ * Create schedule bentry to be transmitted in EOC beacon
+ * \param ctx the module context
+ */
+void
+cp_eoc_cco_bw_bp_allocations (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_cco_bw_alloc_t *alloc;
+ static bool startup_period = true;
+ static bool update_end_date = true;
+ static u32 startup_date_end;
+ if (update_end_date)
+ {
+#if MODULE_INCLUDED (hal_phy_maximus)
+ startup_date_end = phy_date () + MAC_MS_TO_TCK (3000);
+#else
+ startup_date_end = phy_date () + CP_EOC_CCO_STARTUP_PERIOD;
+#endif
+ update_end_date = false;
+ }
+
+ if (startup_period && !less_mod2p32 (phy_date (), startup_date_end))
+ startup_period = false;
+
+ cp_cco_bw_alloc_clean (ctx, &ctx->bw.alloc_list);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_SPC_CENTRAL;
+ alloc->end_time_atu = MAC_TCK_TO_ATU(cp_eoc_cco_bw_central_tck);
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_LOCAL_CSMA;
+ if (startup_period)
+ {
+ alloc->end_time_atu = MAC_TCK_TO_ATU(CP_EOC_CSMA_STARTUP_PERIOD);
+ cp_eoc_cco_bw_symbol_nb = cp_eoc_cco_bw_symbol_nb_drv >> 1;
+ }
+ else
+ {
+ alloc->end_time_atu = MAC_TCK_TO_ATU(cp_eoc_cco_bw_csma_duration);
+ cp_eoc_cco_bw_symbol_nb = cp_eoc_cco_bw_symbol_nb_drv;
+ }
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_CFPI;
+ alloc->end_time_atu = MAC_TCK_TO_ATU(CP_PWL_BP_EOC);
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+}
+
+/** Create allocations at CCo startup or for station that has missed some
+ * beacons
+ * \param ctx module context
+ */
+void
+cp_eoc_cco_bw_sta_allocations (cp_t *ctx)
+{
+ cp_cco_bw_alloc_t *alloc;
+ dbg_assert (ctx);
+
+ cp_cco_bw_alloc_clean (ctx, &ctx->bw.alloc_list);
+
+ alloc = cp_cco_bw_alloc_init (ctx);
+ alloc->stpf = false;
+ alloc->glid = MAC_LID_SPC_CENTRAL;
+ alloc->end_time_atu = MAC_TCK_TO_ATU(CP_PWL_BP_EOC);
+ alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT;
+ cp_cco_bw_alloc_add (ctx, &ctx->bw.alloc_list, alloc);
+ slab_release (alloc);
+}
+
+#if CONFIG_CP_STA_MGR_EOC
+/** Make tables needed in all scheduler calculations, to save time
+ * \param ctx Control Plane context
+ */
+void
+cp_eoc_cco_bw_sched_tables_init (cp_t *ctx)
+{
+ uint i;
+ dbg_assert (ctx);
+ /* Convert number of symbols in the frame to time duration of the frame */
+ ctx->schedule.symbol_nb_to_tick_table [0] = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK +
+ MAC_RIFS_DEFAULT_TCK;
+ for (i = 1; i < MAX_SYMBOLS_PER_FRAME + 1; i++)
+ {
+ if (i < 3)
+ ctx->schedule.symbol_nb_to_tick_table [i] =
+ ctx->schedule.symbol_nb_to_tick_table [i - 1] + MAC_DX567_TCK;
+ else
+ ctx->schedule.symbol_nb_to_tick_table [i] =
+ ctx->schedule.symbol_nb_to_tick_table [i - 1] + MAC_DX417_TCK;
+ }
+}
+
+void
+cp_eoc_cco_bw_sched_init (cp_t * ctx)
+{
+ dbg_assert (ctx);
+
+ /* Set size of memory allocations*/
+ slab_cache_init (&ctx->schedule.slab, "Scheduler slab",
+ sizeof (cp_eoc_cco_bw_sched_alloc_t), NULL);
+
+ /* Memory for array of associated stations */
+ ctx->schedule.sta_array = blk_alloc_zero ();
+
+ /* Initialize the list */
+ list_init (&ctx->schedule.sched_list);
+
+ ctx->schedule.last_sta = 0;
+
+ cp_eoc_cco_services_init (ctx);
+ cp_eoc_cco_bw_sched_tables_init (ctx);
+}
+
+/** Check which services station has, if any
+ * \param ctx Control Plane context
+ * \param sta data plane station
+ */
+cp_eoc_cco_bw_service_t *
+cp_eoc_cco_bw_check_service (cp_t *ctx, sta_t *sta)
+{
+ cp_sta_t *cp_sta = NULL;
+ cp_net_t *net;
+ u8 service = 0;
+
+ dbg_assert (ctx);
+ dbg_assert (sta);
+
+ net = cp_sta_mgr_get_our_avln (ctx);
+ cp_sta = cp_sta_mgr_sta_get_assoc (ctx, net, sta->tei);
+ /* Check which service station has */
+ if (cp_sta)
+ {
+ if (cp_sta->multi_sta.ports.port[0].enabled)
+ service = cp_sta->multi_sta.ports.port[0].index_of_service;
+ slab_release (cp_sta);
+ }
+ return cp_eoc_cco_bw_service_find (ctx, service);
+}
+
+/** Clean allocations of previous scheduling period
+ * \param ctx Control Plane context
+ */
+void
+cp_eoc_cco_bw_sched_clean (cp_t *ctx)
+{
+ cp_eoc_cco_bw_sched_alloc_t *sched;
+ cp_eoc_cco_bw_service_t *srv;
+ list_node_t *list_node;
+ sta_t *sta = NULL;
+ int j = 0;
+
+ while (!list_empty (&ctx->schedule.sched_list))
+ {
+ list_node = list_pop (&ctx->schedule.sched_list);
+ sched = PARENT_OF (cp_eoc_cco_bw_sched_alloc_t, sched_node, list_node);
+ slab_release (sched);
+ }
+
+ while (ctx->schedule.sta_array[j] != NULL)
+ {
+ sta = ctx->schedule.sta_array[j];
+ if (sta)
+ {
+ /* Manage stations not replying to poll */
+ srv = cp_eoc_cco_bw_check_service (ctx, sta);
+ if (srv)
+ {
+ if (sta->poll_off)
+ {
+ sta->tdma_poll = false;
+ sta->poll_off = 0;
+ }
+ }
+ else
+ {
+ if (sta->poll_off == CP_EOC_NO_POLL_ONE)
+ sta->poll_off = CP_EOC_NO_POLL_TWO;
+ else if (sta->poll_off == CP_EOC_NO_POLL_ONE + CP_EOC_NO_POLL_TWO)
+ sta->poll_off = CP_EOC_NO_POLL_TWO + CP_EOC_NO_POLL_THREE;
+ else if (sta->poll_off == CP_EOC_NO_POLL_ONE + CP_EOC_NO_POLL_TWO +
+ CP_EOC_NO_POLL_THREE)
+ {
+ sta->tdma_poll = false;
+ sta->poll_off = 0;
+ }
+ else if (!(sta->poll_off & CP_EOC_NO_POLL_ONE))
+ sta->poll_off = 0;
+ }
+ /* Release previously polled stations. */
+ blk_release (sta);
+ ctx->schedule.sta_array[j] = NULL;
+ }
+ j++;
+ }
+}
+
+void
+cp_eoc_cco_bw_sched_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ cp_eoc_cco_bw_sched_clean (ctx);
+ dbg_assert (list_empty (&ctx->schedule.sched_list));
+
+ blk_release (ctx->schedule.sta_array);
+ slab_cache_uninit (&ctx->schedule.slab);
+
+ cp_eoc_cco_services_uninit (ctx);
+}
+
+cp_eoc_cco_bw_sched_alloc_t *
+cp_eoc_cco_bw_sched_alloc (cp_t *ctx)
+{
+ cp_eoc_cco_bw_sched_alloc_t *sched_alloc;
+
+ dbg_assert (ctx);
+
+ sched_alloc = slab_alloc (&ctx->schedule.slab);
+ list_init_node (&sched_alloc->sched_node);
+
+ return sched_alloc;
+
+}
+
+/**
+ * Scheduling function for finding all associated stations
+ * \param ctx Control Plane context
+ */
+void
+cp_eoc_cco_bw_sched_find (cp_t *ctx)
+{
+ mac_store_t *mac_store;
+ sta_t *sta = NULL;
+ int i,j = 0;
+
+ dbg_assert (ctx);
+
+ mac_store = ctx->mac_store;
+
+ for (i = MAC_TEI_STA_MIN_EOC; i < MAC_TEI_STA_MAX; i++)
+ {
+ sta = mac_store_sta_get (mac_store, i);
+ if (sta)
+ {
+ if (sta->tdma_poll)
+ ctx->schedule.sta_array[j++] = sta;
+ else
+ blk_release (sta);
+ }
+ }
+ ctx->schedule.sta_array[j] = NULL;
+ ctx->schedule.last_sta = j;
+}
+
+/** Calculate duration of frames (in symbols) for given service
+ * \param ctx Control Plane context
+ * \param sta data plane station
+ * \param services service for which to calculate duration
+ * \param cco_ends direction of frame
+ */
+uint
+cp_eoc_cco_bw_sched_calc (cp_t *ctx, sta_t *sta,
+ cp_eoc_cco_bw_service_t *services, bool cco_sends)
+{
+ uint bits, symbol_nb;
+ dbg_assert (ctx);
+
+ /* Bcast */
+ if (sta == NULL)
+ return MAX_SYMBOLS_PER_FRAME;
+ /* No valid tonemaps, yet */
+ if (sta->tx_tonemaps->default_tmi > TONEMAP_INDEX_NULL
+ || (sta->rx_tonemaps->default_tmi > TONEMAP_INDEX_NULL))
+ return MIN_SYMBOLS_PER_SOUND_FRAME;
+ /* Unicast */
+ if (services == NULL)
+ return MAX_SYMBOLS_PER_FRAME;
+ /* Take service parameters */
+ if (cco_sends)
+ {
+ bits = services->dload_pir_to_bp_bits;
+ /* Calculate symbol number depending on channel quality */
+ tonemaps_t *tms = sta->tx_tonemaps;
+ uint tmi = tms->default_tmi;
+ tonemap_t *tm = tms->tm[tmi];
+ if (tmi >= PHY_MOD_ROBO_NB)
+ {
+ if(tm->bits_per_symbol)
+ symbol_nb = (bits + tm->bits_per_symbol - 1)
+ / tm->bits_per_symbol + 1;
+ else
+ symbol_nb = MIN_SYMBOLS_PER_PB_ROBO;
+ }
+ else
+ symbol_nb = MIN_SYMBOLS_PER_PB_ROBO;
+ return symbol_nb;
+ }
+ else
+ {
+ bits = services->uload_pir_to_bp_bits;
+ /* Calculate symbol number depending on channel quality */
+ tonemaps_t *tms = sta->rx_tonemaps;
+ uint tmi = tms->default_tmi;
+ tonemap_t *tm = tms->tm[tmi];
+ if (tmi >= PHY_MOD_ROBO_NB)
+ {
+ if(tm->bits_per_symbol)
+ symbol_nb = (bits + tm->bits_per_symbol - 1)
+ / tm->bits_per_symbol + 1;
+ else
+ symbol_nb = MIN_SYMBOLS_PER_PB_ROBO;
+ }
+ else
+ symbol_nb = MIN_SYMBOLS_PER_PB_ROBO;
+ return symbol_nb;
+ }
+}
+
+/** Scheduler function to read elements from scheduler list
+ * \param ctx Control Plane context
+ */
+cp_eoc_cco_bw_sched_alloc_t *
+cp_eoc_cco_bw_sched_read (cp_t *ctx, list_node_t **node)
+{
+
+ list_node_t *list_node;
+ cp_eoc_cco_bw_sched_alloc_t *sched_alloc = NULL;
+
+ dbg_assert (ctx);
+
+ if (*node == NULL)
+ {
+ list_node = list_begin (&ctx->schedule.sched_list);
+ }
+ else
+ {
+ list_node = list_next (*node);
+ if(list_node == &ctx->schedule.sched_list.nil)
+ list_node = NULL;
+ }
+
+ if(list_node)
+ {
+ sched_alloc = PARENT_OF (cp_eoc_cco_bw_sched_alloc_t,
+ sched_node, list_node);
+ *node = list_node;
+ }
+
+ return sched_alloc;
+}
+
+/** Function to copy scheduler records to Channel Access
+ * \param ctx CP context
+ */
+void
+cp_eoc_cco_fill_ca_sched (cp_t *ctx)
+{
+ ca_eoc_sched_t *ca_eoc_sched;
+ ca_eoc_sched_record_t *ca_sched;
+ cp_eoc_cco_bw_sched_alloc_t *sched_alloc;
+ int i, toggle;
+ list_node_t *list_node = NULL;
+
+ toggle = 1 - ctx->ca->ca_eoc_sched.toggle;
+
+ ca_eoc_sched = &ctx->ca->ca_eoc_sched;
+ ca_eoc_sched->record_nb[toggle] = 0;
+ ca_eoc_sched->offset[toggle] = 0;
+ ca_eoc_sched->offset0[toggle] = 0;
+ for (i = 0; i < CA_EOC_SCHED_NB; i++)
+ {
+ ca_sched = &ca_eoc_sched->sched_record[toggle][i];
+ sched_alloc = cp_eoc_cco_bw_sched_read (ctx, &list_node);
+ if (sched_alloc == NULL
+ || sched_alloc->cco_tx_duration <= SHORT_FRAME_TCK_EMPTY_SOF)
+ break;
+ ca_sched->tei = sched_alloc->tei;
+ ca_sched->lid = sched_alloc->lid;
+ ca_sched->poll = sched_alloc->poll;
+ ca_sched->cco_tx_duration = sched_alloc->cco_tx_duration;
+ ca_sched->sta_tx_duration = sched_alloc->sta_tx_duration;
+ ca_eoc_sched->record_nb[toggle]++;
+ }
+}
+
+/** Scheduler function for making scheduling allocations to be used by CA
+ * \param ctx Control Plane context
+ */
+void
+cp_eoc_cco_bw_scheduler (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ sta_t *sta = NULL;
+ uint i, j, symbol_nb;
+ cp_eoc_cco_bw_sched_alloc_t *sched = NULL;
+ u32 now = phy_date ();
+
+ cp_eoc_cco_bw_sched_clean (ctx);
+ cp_eoc_cco_bw_sched_find (ctx);
+
+ dbg_assert (list_empty (&ctx->schedule.sched_list));
+
+ ctx->schedule.sched_period = 0;
+ j = ctx->schedule.last_sta;
+
+ /* Broadcast */
+ sched = cp_eoc_cco_bw_sched_alloc (ctx);
+ dbg_assert (sched);
+ sched->tei = MAC_TEI_BCAST;
+ sched->sta_tx_duration = 0;
+ sched->lid = 0;
+ symbol_nb = cp_eoc_cco_bw_sched_calc (ctx, NULL, NULL, true);
+ sched->cco_tx_duration = ctx->schedule.symbol_nb_to_tick_table [symbol_nb];
+ sched->poll = 1;
+ ctx->schedule.sched_period += sched->cco_tx_duration;
+ list_push (&ctx->schedule.sched_list, &sched->sched_node);
+ /* Unicast */
+ for(i = 0; i < j; i++)
+ {
+ sta = ctx->schedule.sta_array[i];
+ if (sta)
+ {
+ sched = cp_eoc_cco_bw_sched_alloc (ctx);
+ dbg_assert (sched);
+ sched->tei = sta->tei;
+ symbol_nb = cp_eoc_cco_bw_sched_calc (ctx, sta, NULL, true);
+ sched->cco_tx_duration = ctx->schedule.
+ symbol_nb_to_tick_table [symbol_nb];
+ symbol_nb = cp_eoc_cco_bw_sched_calc (ctx, sta, NULL, false);
+ sched->sta_tx_duration = ctx->schedule.
+ symbol_nb_to_tick_table [symbol_nb];
+ sched->lid = MAC_LLID_MIN;
+ if (lesseq_mod2p32 (sta->poll_time, now))
+ sched->poll = 1;
+ else
+ sched->poll = 0;
+ ctx->schedule.sched_period += sched->sta_tx_duration;
+ ctx->schedule.sched_period += sched->cco_tx_duration;
+ list_push (&ctx->schedule.sched_list, &sched->sched_node);
+ }
+ else
+ break;
+ }
+
+ cp_eoc_cco_fill_ca_sched (ctx);
+}
+#endif /* CONFIG_CP_STA_MGR_EOC */
diff --git a/cesar/cp/eoc/cco/bw/src/service.c b/cesar/cp/eoc/cco/bw/src/service.c
new file mode 100644
index 0000000000..e78ab2e646
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/src/service.c
@@ -0,0 +1,144 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/src/service.c
+ * \brief Manages update of services availiable on CCo
+ * \ingroup cp_eoc_cco_bw
+ *
+*/
+#include "common/std.h"
+#include "cp/eoc/cco/bw/inc/service.h"
+#include "cp/inc/context.h"
+
+void
+cp_eoc_cco_services_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ /* Set size of memory allocations*/
+ slab_cache_init (&ctx->schedule.services.slab, "Service slab",
+ sizeof (cp_eoc_cco_bw_service_t), NULL);
+
+ /* Initialize the list */
+ list_init (&ctx->schedule.services.service_list);
+
+ ctx->schedule.services.service_nb = 0;
+}
+
+void
+cp_eoc_cco_services_uninit (cp_t *ctx)
+{
+ cp_eoc_cco_bw_service_t * service;
+ list_node_t *list_node;
+
+ while (!list_empty (&ctx->schedule.services.service_list))
+ {
+ list_node = list_pop (&ctx->schedule.services.service_list);
+ service = PARENT_OF (cp_eoc_cco_bw_service_t, service_node, list_node);
+ slab_release (service);
+ }
+
+ slab_cache_uninit (&ctx->schedule.services.slab);
+}
+
+cp_eoc_cco_bw_service_t *
+cp_eoc_cco_bw_service_alloc (cp_t *ctx)
+{
+ cp_eoc_cco_bw_service_t * service;
+
+ dbg_assert (ctx);
+
+ service = slab_alloc (&ctx->schedule.services.slab);
+ list_init_node (&service->service_node);
+
+ return service;
+}
+
+/**
+ * Find specified service from list of available services
+ * \param ctx the CP module context
+ * \param service_index index of wanted service
+ */
+cp_eoc_cco_bw_service_t *
+cp_eoc_cco_bw_service_find (cp_t *ctx, uint service_index)
+{
+ cp_eoc_cco_bw_service_t * service = NULL;
+ list_node_t *list_node = NULL;
+
+ dbg_assert (ctx);
+
+ list_node = list_begin (&ctx->schedule.services.service_list);
+
+ while (list_node != &ctx->schedule.services.service_list.nil)
+ {
+ if (list_node)
+ service = PARENT_OF (cp_eoc_cco_bw_service_t, service_node, list_node);
+ if (service && (service_index == service->service_index))
+ return service;
+ list_node = list_next (list_node);
+ }
+
+ return NULL;
+}
+
+/** Convert bandwidth to bits per one beacon period.
+ * bandwidth is multiple of 1kbps, in bits (* 1000), to get value per one BP
+ * it is divided by 10, so finally (* 100)
+ * convert bandwidth in bytes per one PB (>> 3)
+ * in one PB there is 512 bytes of payload (>> 9)
+ * to send one PB it takes 5460 bits (* 5460)
+ * \param srv specified service to be calculated
+*/
+void
+cp_eoc_cco_bw_service_bits_per_bp (cp_eoc_cco_bw_service_t *srv)
+{
+ dbg_assert (srv);
+ srv->dload_pir_to_bp_bits = (((uint)(srv->dload_pir * 100) >> 3) * 5460) >> 9;
+ srv->uload_pir_to_bp_bits = (((uint)(srv->uload_pir * 100) >> 3) * 5460) >> 9;
+ srv->dload_cir_to_bp_bits = (((uint)(srv->dload_cir * 100) >> 3) * 5460) >> 9;
+ srv->uload_cir_to_bp_bits = (((uint)(srv->uload_cir * 100) >> 3) * 5460) >> 9;
+}
+
+/** Add new service to list of available services. Before calling it memory has
+ * to allocated using cp_eoc_cco_bw_service_alloc
+ * \param ctx the CP module context
+ * \param srv newly created service entry
+ */
+void
+cp_eoc_cco_bw_service_add (cp_t *ctx, cp_eoc_cco_bw_service_t *srv)
+{
+ dbg_assert (ctx);
+ dbg_assert (srv);
+ list_push (&ctx->schedule.services.service_list, &srv->service_node);
+ ctx->schedule.services.service_nb++;
+ cp_eoc_cco_bw_service_bits_per_bp (srv);
+}
+
+/** Remove service from list of supported services and release allocation
+ * \param ctx the CP module context
+ * \param service_index index to be removed
+ */
+bool
+cp_eoc_cco_bw_service_remove (cp_t *ctx, uint service_index)
+{
+ cp_eoc_cco_bw_service_t * service = NULL;
+
+ dbg_assert (ctx);
+
+ service = cp_eoc_cco_bw_service_find (ctx, service_index);
+ if (service)
+ {
+ list_remove (&ctx->schedule.services.service_list,
+ &service->service_node);
+ slab_release (service);
+ ctx->schedule.services.service_nb--;
+ dbg_assert (ctx->schedule.services.service_nb >= 0);
+ return true;
+ }
+ return false;
+}
diff --git a/cesar/cp/eoc/cco/bw/stub/Module b/cesar/cp/eoc/cco/bw/stub/Module
new file mode 100644
index 0000000000..6cc8dbfd33
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/stub/Module
@@ -0,0 +1 @@
+SOURCES:= bw.c \ No newline at end of file
diff --git a/cesar/cp/eoc/cco/bw/stub/src/bw.c b/cesar/cp/eoc/cco/bw/stub/src/bw.c
new file mode 100644
index 0000000000..7254b29308
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/stub/src/bw.c
@@ -0,0 +1,35 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/src/bw.c
+ * \brief Create the alloctions for beacon period and create CCo schedule
+ * \ingroup cp_eoc_cco_bw
+ *
+*/
+#include "common/std.h"
+#include "cp/msg/msg.h"
+#include "cp/cp.h"
+#include "cp/inc/context.h"
+
+void
+cp_eoc_cco_bw_allocations_adjust (cp_t *ctx, bool adjust)
+{
+ dbg_assert (ctx);
+}
+
+void
+cp_eoc_cco_bw_sta_allocations (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+/* TODO: ugly, but dont want to create stub in mac/pbproc */
+void
+pbproc_parameters_adjust (pbproc_t *ctx, bool adjust)
+{
+}
diff --git a/cesar/cp/eoc/cco/bw/test/utest/Config b/cesar/cp/eoc/cco/bw/test/utest/Config
new file mode 100644
index 0000000000..26d2281542
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/Config
@@ -0,0 +1,5 @@
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 2
diff --git a/cesar/cp/eoc/cco/bw/test/utest/Makefile b/cesar/cp/eoc/cco/bw/test/utest/Makefile
new file mode 100644
index 0000000000..6102ccea0d
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/Makefile
@@ -0,0 +1,24 @@
+BASE = ../../../../../..
+
+INCLUDES = cp/eoc/cco/bw/test/utest/override
+
+HOST_PROGRAMS = sched serv
+
+sched_SOURCES = sched.c bw_stub.c
+
+sched_MODULES = lib mac/common cp/cco/bw cp/eoc/cco/bw \
+cp/eoc/multi_sta_fsm cp/fsm/stub cp/eoc/multi_sta/action cp/msg/stub mac/sar/stub cp/secu/stub cp/eoc/cco/action/stub cp/sta/mgr mac/ca cl/stub
+
+sched_CONFIG_MODULES = cp mac/sar cl cp/eoc/cco/action
+
+ca_MODULE_SOURCES = alloc.c
+
+cl_stub_MODULE_SOURCES = cl_mactotei.c cl.c brg_rx.c
+
+serv_SOURCES = serv.c bw_stub.c
+
+serv_MODULES = lib mac/common cp/cco/bw cp/eoc/cco/bw
+
+serv_CONFIG_MODULES = mac/sar cl
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/cco/bw/test/utest/override/cp/inc/context.h b/cesar/cp/eoc/cco/bw/test/utest/override/cp/inc/context.h
new file mode 100644
index 0000000000..ad4ed4626a
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/override/cp/inc/context.h
@@ -0,0 +1,52 @@
+#ifndef override_cp_inc_context_h
+#define override_cp_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "cp/cp.h"
+#include "cp/cco/bw/bw.h"
+#include "cp/cco/bw/inc/context.h"
+#include "mac/common/store.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/net.h"
+#include "cp/sta/mgr/inc/net.h"
+#include "cp/inc/trace.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta_mgr.h"
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+#include "config/cp/sta/mgr/eoc.h"
+#include "config/cp/eoc/dbg/print/level.h"
+#include "cp/cco/action/inc/cco_action.h"
+#include "mac/sar/inc/sar_context.h"
+#include "bsu/inc/context.h"
+
+struct cp_t
+{
+ cp_cco_bw_t bw;
+ mac_store_t *mac_store;
+ cp_eoc_cco_bw_sched_t schedule;
+ ca_t *ca;
+ cp_sta_mgr_t sta_mgr;
+ cp_fsm_t fsm;
+ cp_cco_action_t cco_action;
+ sar_t *sar;
+ mac_config_t *mac_config;
+ bsu_t *bsu;
+ lib_rnd_t rnd;
+ cl_t *cl;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/core.h b/cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/core.h
new file mode 100644
index 0000000000..1d87ac67b0
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/core.h
@@ -0,0 +1,28 @@
+#ifndef override_cp_sta_core_core_h
+#define override_cp_sta_core_core_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 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);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/defs.h b/cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..4bdff91cba
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/override/cp/sta/core/defs.h
@@ -0,0 +1,58 @@
+#ifndef cp_sta_core_defs_h
+#define cp_sta_core_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/sta/core/defs.h
+ * \brief STA core defs override.
+ * \ingroup test
+ *
+ */
+#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/bw/test/utest/override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/cco/bw/test/utest/override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..5b345b7e71
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/override/mac/sar/inc/sar_context.h
@@ -0,0 +1,39 @@
+#ifndef override_mac_sar_inc_sar_context_h
+#define override_mac_sar_inc_sar_context_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief SAR context override
+ * \ingroup test
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /*override_mac_sar_inc_sar_context_h*/
diff --git a/cesar/cp/eoc/cco/bw/test/utest/src/bw_stub.c b/cesar/cp/eoc/cco/bw/test/utest/src/bw_stub.c
new file mode 100644
index 0000000000..e77c3c2693
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/src/bw_stub.c
@@ -0,0 +1,133 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/test/src/bw_stub.c
+ * \brief stub functions for bw test
+ * \ingroup test
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/sta/mgr/sta_own_data.h"
+#include "cp/sta/mgr/net.h"
+#include "cp/sta/mgr/inc/net.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/sta/mgr/inc/sta_mgr.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/inc/context.h"
+
+cp_net_t *
+cp_sta_mgr_get_our_avln (cp_t *ctx) __attribute__ ((weak));
+
+cp_net_t *
+cp_sta_mgr_get_our_avln (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->sta_mgr.our_avln);
+ dbg_assert (ctx->sta_mgr.our_avln->present);
+ return ctx->sta_mgr.our_avln;
+}
+
+cp_sta_t *
+cp_sta_mgr_sta_get_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei) __attribute__ ((weak));
+
+cp_sta_t *
+cp_sta_mgr_sta_get_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei)
+{
+ return NULL;
+}
+
+void
+cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (cp_t *ctx, cp_mme_peer_t *peer)
+{
+}
+
+uint
+bsu_nek_index_next (bsu_t *ctx)
+{
+ dbg_assert (ctx);
+ return !ctx->nek_switch;
+}
+
+uint
+bsu_nek_index_current (bsu_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->nek_switch;
+}
+
+void
+bsu_update_nid (bsu_t *ctx, u64 nid) {}
+
+void
+bsu_avln_remove (bsu_t *ctx, u64 nid, u8 snid, mac_t mac) {}
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx)
+{
+ static uint time=0;
+ time+=2000;
+ return time;
+}
+
+void
+pbproc_mfs_remove_all (mfs_tx_t *mfs)
+{
+ if (mfs->head)
+ blk_release_desc ((blk_t*) mfs->head);
+}
+
+void
+cp_cco_action_tei_release (cp_t *ctx, u8 tei)
+{
+ dbg_assert (ctx);
+ dbg_assert (tei);
+}
+
+void
+phy_access_timer_cancel (phy_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+void
+phy_rx_activate (phy_t *ctx, bool now, u32 date, bool flag)
+{
+ dbg_assert (ctx);
+}
+
+void
+phy_access_backoff_start (phy_t *ctx, u32 date, uint cap)
+{
+ dbg_assert (ctx);
+}
+
+void
+phy_access_timer_program (phy_t *ctx, u32 date)
+{
+ dbg_assert (ctx);
+}
+
+void
+phy_access_backoff_update (phy_t *ctx, uint cap)
+{
+ dbg_assert (ctx);
+}
+
+void
+phy_access_timer_update (phy_t *ctx, u32 date)
+{
+ dbg_assert (ctx);
+}
+u32
+phy_date(void)
+{
+ static int i = 0;
+ i += 50000;
+ return i;
+}
diff --git a/cesar/cp/eoc/cco/bw/test/utest/src/sched.c b/cesar/cp/eoc/cco/bw/test/utest/src/sched.c
new file mode 100644
index 0000000000..988ac76777
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/src/sched.c
@@ -0,0 +1,198 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/test/utest/src/sched.c
+ * \brief Bandwidth scheduler unit tests.
+ * \ingroup cp_eoc_cco_bw
+ *
+ */
+#include "common/std.h"
+#include "lib/test.h"
+
+#include "cp/cp.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "cp/inc/context.h"
+#include "mac/ca/inc/context.h"
+#include "cp/eoc/cco/bw/bw.h"
+
+void
+cp_eoc_cco_bw_scheduler (cp_t *ctx);
+
+void
+cp_eoc_cco_bw_sched_clean (cp_t *ctx);
+
+void
+cp_eoc_cco_fill_ca_sched (cp_t *ctx);
+
+static cp_t cp;
+static ca_t ca;
+static ca_eoc_sched_t ca_eoc_sched_gl;
+static ca_eoc_sched_record_t ca_eoc_sched_record_0;
+static ca_eoc_sched_record_t ca_eoc_sched_record_1;
+
+#define SHORT_FRAME_TCK MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_RIFS_DEFAULT_TCK
+#define STA_NB 32
+
+uint sum[STA_NB + 3];
+
+
+void
+test_bw_util (test_t test)
+{
+ bool result;
+ cp_eoc_cco_bw_sched_alloc_t *sched;
+ list_node_t *list_node = NULL;
+ca_eoc_sched_gl.sched_record[0] = &ca_eoc_sched_record_0;
+ca_eoc_sched_gl.sched_record[1] = &ca_eoc_sched_record_1;
+
+ test_case_begin (test, "Assign");
+ cp.mac_store = mac_store_init ();
+ cp_eoc_cco_bw_sched_init (&cp);
+ cp.ca = &ca;
+ cp.ca->ca_eoc_sched = ca_eoc_sched_gl;
+ mac_store_sta_add_ (cp.mac_store, 5 __fl);
+ mac_store_sta_get_noref (cp.mac_store, 5)->tdma_poll = true;
+ mac_store_sta_add_ (cp.mac_store, 6 __fl);
+ mac_store_sta_get_noref (cp.mac_store, 6)->tdma_poll = true;
+ mac_store_sta_add_ (cp.mac_store, 8 __fl);
+ mac_store_sta_get_noref (cp.mac_store, 8)->tdma_poll = true;
+
+ test_begin (test, "Sched and read")
+ {
+ cp_eoc_cco_bw_scheduler (&cp);
+
+ sched = cp_eoc_cco_bw_sched_read (&cp, &list_node);
+
+ test_fail_if (sched->tei != MAC_TEI_BCAST);
+ test_fail_if (sched->lid != 0);
+ test_fail_if (sched->cco_tx_duration !=
+ 2 * MAC_DX567_TCK + (MAX_SYMBOLS_PER_FRAME - 2) * MAC_DX417_TCK + SHORT_FRAME_TCK);
+
+ sched = cp_eoc_cco_bw_sched_read (&cp, &list_node);
+ test_fail_if (sched->tei != 5);
+ test_fail_if (sched->lid != MAC_LLID_MIN);
+ test_fail_if (sched->cco_tx_duration !=
+ 2 * MAC_DX567_TCK + (MIN_SYMBOLS_PER_SOUND_FRAME - 2) * MAC_DX417_TCK + SHORT_FRAME_TCK);
+ sched = cp_eoc_cco_bw_sched_read (&cp, &list_node);
+ test_fail_if (sched->tei != 6);
+ test_fail_if (sched->lid != MAC_LLID_MIN);
+ test_fail_if (sched->cco_tx_duration !=
+ 2 * MAC_DX567_TCK + (MIN_SYMBOLS_PER_SOUND_FRAME - 2) * MAC_DX417_TCK + SHORT_FRAME_TCK);
+
+ sched = cp_eoc_cco_bw_sched_read (&cp, &list_node);
+ test_fail_if (sched->tei != 8);
+ test_fail_if (sched->lid != MAC_LLID_MIN);
+ test_fail_if (sched->cco_tx_duration !=
+ 2 * MAC_DX567_TCK + (MIN_SYMBOLS_PER_SOUND_FRAME - 2) * MAC_DX417_TCK + SHORT_FRAME_TCK);
+
+ result = mac_store_sta_remove_ (cp.mac_store, 5 __fl);
+ test_fail_unless (result);
+ result = mac_store_sta_remove_ (cp.mac_store, 6 __fl);
+ test_fail_unless (result);
+ result = mac_store_sta_remove_ (cp.mac_store, 8 __fl);
+ test_fail_unless (result);
+ /* the switch of schedules that CA does in real life */
+ cp.ca->ca_eoc_sched.toggle = 1 - cp.ca->ca_eoc_sched.toggle;
+ }
+ test_end;
+
+ test_begin (test, "Read and fill")
+ {
+ uint i,j;
+ ca_eoc_sched_t *ca_sched;
+ ca_eoc_sched_record_t *ca_rec;
+ mac_config_t mac_config;
+ cp.mac_config = &mac_config;
+ sar_t sar;
+ cp.sar = &sar;
+ uint cl;
+ cp.cl = (cl_t *) &cl;
+ cp_net_t *net;
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ for (i = 0; i < STA_NB; i++)
+ {
+ mac_store_sta_add_ (cp.mac_store, i + 3 __fl);
+ mac_store_sta_get_noref (cp.mac_store, i + 3)->tdma_poll = true;
+ }
+
+ cp_eoc_cco_bw_scheduler (&cp);
+ cp.ca->ca_eoc_sched.toggle = 1 - cp.ca->ca_eoc_sched.toggle;
+ ca_sched = &(cp.ca->ca_eoc_sched);
+
+ for (i = 0; i < ca_sched->record_nb[ca_sched->toggle]; i++)
+ {
+ ca_rec = &ca_sched->sched_record[ca_sched->toggle][i];
+ test_fail_unless (ca_rec->lid == MAC_LLID_MIN || ca_rec->lid == 0);
+ test_fail_unless ((ca_rec->cco_tx_duration ==
+ 2 * MAC_DX567_TCK + (MAX_SYMBOLS_PER_FRAME - 2) * MAC_DX417_TCK
+ + SHORT_FRAME_TCK)
+ || (2 * MAC_DX567_TCK + (MIN_SYMBOLS_PER_SOUND_FRAME - 2)
+ * MAC_DX417_TCK + SHORT_FRAME_TCK)
+ || (ca_rec->cco_tx_duration == 0));
+ test_fail_unless (ca_rec->sta_tx_duration ==
+ 2 * MAC_DX567_TCK + (MIN_SYMBOLS_PER_SOUND_FRAME - 2) * MAC_DX417_TCK
+ + SHORT_FRAME_TCK || ca_rec->sta_tx_duration == 0);
+ }
+
+ test_fail_unless (i == 33);
+ cp.schedule.last_sta = 0;
+ /* the switch of schedules that CA does in real life */
+ cp.ca->ca_eoc_sched.toggle = 1 - cp.ca->ca_eoc_sched.toggle;
+
+ /* Make number of consecutive schedules */
+ for(i = 0; i < 400; i++)
+ {
+ cp_eoc_cco_bw_scheduler (&cp);
+ /* sum up assigned time */
+ for(j = 0; j < ca_sched->record_nb[ca_sched->toggle]; j++)
+ {
+ ca_rec = &ca_sched->sched_record[ca_sched->toggle][j];
+ sum[ca_rec->tei] += ca_rec->sta_tx_duration;
+ }
+ cp.ca->ca_eoc_sched.toggle = 1 - cp.ca->ca_eoc_sched.toggle;
+ }
+
+ /* Test ratio of assigned time, should be less than 1/2%.
+ * Test done for first and last authenticated station*/
+ test_fail_unless ((double)sum[STA_NB + 2]/sum[3] > 0.995);
+
+ for (i = 0; i < STA_NB; i++)
+ {
+ result = mac_store_sta_remove_ (cp.mac_store, i + 3 __fl);
+ test_fail_unless (result);
+ }
+
+ }
+ test_end;
+
+ mac_store_uninit (cp.mac_store);
+ cp_eoc_cco_bw_sched_uninit (&cp);
+}
+
+int
+main (void)
+{
+ test_t test;
+ test_init (test, 0, NULL);
+
+ test_suite_begin (test, "Bandwidth Scheduler");
+ test_bw_util (test);
+
+ test_case_begin (test, "Memory test");
+
+ test_begin (test, "Memory verification")
+ {
+ test_fail_if (blk_check_memory() == false, "Memory not freed");
+ }
+ test_end;
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/cco/bw/test/utest/src/serv.c b/cesar/cp/eoc/cco/bw/test/utest/src/serv.c
new file mode 100644
index 0000000000..5405ea5cbb
--- /dev/null
+++ b/cesar/cp/eoc/cco/bw/test/utest/src/serv.c
@@ -0,0 +1,92 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/bw/test/utest/src/serv.c
+ * \brief Services management unit tests.
+ * \ingroup cp_eoc_cco_bw
+ *
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "cp/inc/context.h"
+#include "cp/eoc/cco/bw/service.h"
+
+static cp_t cp;
+
+void
+test_service (test_t test)
+{
+ cp_eoc_cco_bw_service_t *srv = NULL;
+ bool ok;
+ uint i;
+ test_begin (test, "Utils")
+ {
+ cp_eoc_cco_services_init (&cp);
+ srv = cp_eoc_cco_bw_service_alloc (&cp);
+ srv->service_index = 4;
+ srv->dload_pir = 200;
+ cp_eoc_cco_bw_service_add (&cp, srv);
+ test_fail_unless (cp.schedule.services.service_nb == 1);
+ srv = cp_eoc_cco_bw_service_find (&cp, 5);
+ test_fail_if (srv);
+ srv = cp_eoc_cco_bw_service_find (&cp, 4);
+ test_fail_if (!srv);
+ test_fail_if (srv->dload_pir != 200);
+ ok = cp_eoc_cco_bw_service_remove (&cp, 4);
+ test_fail_unless (ok);
+ test_fail_unless (cp.schedule.services.service_nb == 0);
+
+ for (i = 0; i < 30; i++)
+ {
+ srv = cp_eoc_cco_bw_service_alloc (&cp);
+ srv->service_index = i + 5;
+ srv->dload_pir = i * 20;
+ cp_eoc_cco_bw_service_add (&cp, srv);
+ }
+
+ srv = cp_eoc_cco_bw_service_find (&cp, 23);
+ test_fail_unless (srv);
+ test_fail_unless (srv->dload_pir == 360);
+
+ for (i = 7; i < 20; i++)
+ {
+ ok = cp_eoc_cco_bw_service_remove (&cp, i);
+ test_fail_unless (ok);
+ }
+ srv = cp_eoc_cco_bw_service_find (&cp, 10);
+ test_fail_if (srv);
+ test_fail_unless (cp.schedule.services.service_nb == 17);
+ srv = cp_eoc_cco_bw_service_find (&cp, 20);
+ test_fail_if (!srv);
+ test_fail_if (srv->dload_pir != 300);
+ cp_eoc_cco_services_uninit (&cp);
+ }
+ test_end;
+}
+
+int
+main (void)
+{
+ test_t test;
+ test_init (test, 0, NULL);
+
+ test_case_begin (test, "Services");
+
+ test_service (test);
+
+ test_case_begin (test, "Memory test");
+
+ test_begin (test, "Memory verification")
+ {
+ test_fail_if (blk_check_memory() == false, "Memory not freed");
+ }
+ test_end;
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/inc/dbg_print.h b/cesar/cp/eoc/inc/dbg_print.h
new file mode 100644
index 0000000000..4113259d5b
--- /dev/null
+++ b/cesar/cp/eoc/inc/dbg_print.h
@@ -0,0 +1,41 @@
+#ifndef cp_eoc_inc_dbg_print_h
+#define cp_eoc_inc_dbg_print_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/inc/dbg_print.h
+ * \brief Define macros for printing sta status (associated, authenticated, white_list).
+ * \ingroup cp/eoc
+ */
+
+#include "stdio.h"
+#include "config/cp/eoc/dbg/print/level.h"
+
+/* CONFIG_CP_EOC_DBG_PRINT_LEVEL == 0 => no messages will be printed */
+/* CONFIG_CP_EOC_DBG_PRINT_LEVEL == 1 => messages will be printed without a path to the file and the line number */
+/* CONFIG_CP_EOC_DBG_PRINT_LEVEL == 2 => messages will be printed with a path to the file and the line number */
+
+
+#define DBG_PRINT(args...){ \
+ if(CONFIG_CP_EOC_DBG_PRINT_LEVEL == 1){\
+ printf(args);\
+ printf("\n");\
+ }\
+ else if(CONFIG_CP_EOC_DBG_PRINT_LEVEL == 2){\
+ printf("DBG: ");\
+ printf(__FILE__); printf(", line: %d\n ", __LINE__);\
+ printf(args);\
+ printf("\n");\
+ }\
+}
+
+#define DBG_PRINT_2(args...) \
+ if(CONFIG_CP_EOC_DBG_PRINT_LEVEL >= 2) DBG_PRINT(args)
+
+#endif /* cp_eoc_inc_dbg_print_h */
diff --git a/cesar/cp/eoc/multi_sta/action/Config b/cesar/cp/eoc/multi_sta/action/Config
new file mode 100644
index 0000000000..5ae012ceb2
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/Config
@@ -0,0 +1 @@
+CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED = n \ No newline at end of file
diff --git a/cesar/cp/eoc/multi_sta/action/Module b/cesar/cp/eoc/multi_sta/action/Module
new file mode 100644
index 0000000000..1bb6efbf51
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/Module
@@ -0,0 +1 @@
+SOURCES := multi_sta_action.c
diff --git a/cesar/cp/eoc/multi_sta/action/multi_sta_action.h b/cesar/cp/eoc/multi_sta/action/multi_sta_action.h
new file mode 100644
index 0000000000..e9d64fa4f4
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/multi_sta_action.h
@@ -0,0 +1,121 @@
+#ifndef cp_eoc_multi_sta_action_h
+#define cp_eoc_multi_sta_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_action.h
+ * \brief multi_sta Public functions.
+ * \ingroup cp_multi_sta
+ *
+ */
+
+
+/**
+ * manage association of a station.
+ * \param ctx the module context.
+ * \param assoc_req CM_ASSOC.REQ MME msg having being received
+ */
+void
+cp_eoc_multi_sta_action__assoc_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_multi_sta_action__assoc_req_common(cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * manage authentication of a station.
+ * \param ctx the module context.
+ * \param get_key_req CM_GET_KEY.REQ MME msg having being decrypted
+ */
+void
+cp_eoc_multi_sta_action__get_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+cp_tei_t
+cp_eoc_multi_sta_action_compute_tei (cp_t *ctx);
+
+void
+cp_eoc_cco_action__cco__cm_get_key_req_pid0 (cp_t *ctx, cp_mme_rx_t * get_key_req);
+
+
+void
+cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__unassociated__timeout_assoc(cp_t *ctx);
+
+
+
+void
+cp_eoc_multi_sta_fsm__unassociated__timeout_assoc(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ(cp_t *ctx);
+
+
+
+void
+cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__timeout_auth(cp_t *ctx);
+
+
+
+void
+cp_eoc_multi_sta_fsm__associated__timeout_auth(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__cc_leave(cp_t *ctx);
+
+
+
+void
+cp_eoc_multi_sta_fsm__associated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__cc_leave(cp_t *ctx);
+
+
+
+void
+cp_eoc_multi_sta_fsm__authenticated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx);
+
+
+void
+cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action_put_sta_unassociated (cp_t *ctx, cp_sta_t *station) __attribute__((weak));
+
+
+
+
+#endif /* cp_eoc_multi_sta_action_h */
diff --git a/cesar/cp/eoc/multi_sta/action/src/multi_sta_action.c b/cesar/cp/eoc/multi_sta/action/src/multi_sta_action.c
new file mode 100644
index 0000000000..1ebda0f40d
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/src/multi_sta_action.c
@@ -0,0 +1,480 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta/action/src/multi_sta_action.c
+ * \brief multi_sta Action functions.
+ * \ingroup cp_multi_sta
+ *
+ */
+
+#include "common/std.h"
+#include "cl/inc/context.h"
+#include "cp/inc/context.h"
+#include "cp/types.h"
+#include "cp/eoc/cco/action/vs_eoc.h"
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+#include "cp/eoc/multi_sta_fsm/inc/tables.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/eoc/inc/dbg_print.h"
+#include "cp/msg/msg.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "hal/arch/arch.h"
+
+#include "config/cp/eoc/multi/sta/wl/allowed.h"
+
+#include "config/cl/eoc.h"
+
+#include "stdio.h"
+
+
+/**
+ * manage association of a station.
+ * \param ctx the module context.
+ * \param assoc_req CM_ASSOC.REQ MME msg having being received
+ */
+
+#define _BRANCH(state, event, to) \
+ ((CP_EOC_MULTI_STA_FSM_STATE_ ## state) << 16 \
+ | (CP_EOC_MULTI_STA_FSM_EVENT_TYPE_ ## event) << 8 \
+ | (CP_EOC_MULTI_STA_FSM_STATE_ ## to))
+
+void
+cp_eoc_multi_sta_action__assoc_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_msg_cc_assoc_req_t assoc;
+
+ dbg_assert_ptr(ctx);
+ dbg_assert_ptr(mme);
+
+ cp_sta_t *sta;
+ cp_tei_t tei = MAC_TEI_UNASSOCIATED;
+
+ /* TODO take in consideration request type, is it new or renew*/
+ if (cp_msg_cc_assoc_req_receive(ctx, mme, &assoc))
+ {
+ cp_eoc_multi_sta_action__assoc_req_common(ctx, mme);
+ }
+ else
+ {
+
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+ tei = cp_sta_get_tei (sta);
+ sta->fsm.handled_event = NULL;
+ DBG_PRINT("Wrong assoc request type, tei = %d \n", tei);
+ slab_release (sta);
+ }
+}
+
+/**
+ * manage authentication of a station.
+ * \param ctx the module context.
+ * \param get_key_req CM_GET_KEY.REQ MME msg having being decrypted
+ */
+void
+cp_eoc_multi_sta_action__get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_eoc_cco_action__cco__cm_get_key_req_pid0(ctx, mme);
+}
+
+void cp_eoc_multi_sta_action__assoc_req_common(cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+ cp_eoc_multi_sta_fsm_event_t event;
+ cp_net_t *net;
+ cp_tei_t tei = MAC_TEI_UNASSOCIATED;
+ cp_msg_cc_assoc_cnf_t cnf;
+ cp_sta_t *sta;
+ bool added;
+ mfs_tx_t *mfs;
+
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ /* Add the station to the AVLN. */
+ net = cp_sta_mgr_get_our_avln (ctx);
+
+ cnf.nid = cp_net_get_nid (ctx, net);
+ cnf.snid = cp_net_get_snid (ctx, net);
+
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+
+#if CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED
+ {
+ // The station already exists get the TEI.
+ if (sta)
+ tei = cp_sta_get_tei (sta);
+
+ // Check the White List restriction
+ if ((MAC_TEI_IS_STA (tei)) && (sta->multi_sta.allowed == true)
+ && (sta->multi_sta.to_leave == false))
+ {
+ cnf.result = ctx->cco_action.wl_accept_all ?
+ CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS_WL_ACCEPT_ALL
+ : CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS;
+ cnf.lease_time_min = CP_LEASE_ASSOC_MIN;
+ }
+ else
+ {
+ cnf.result =
+ CP_MSG_CC_ASSOC_CNF_RESULT_FAILURE_TEMPORARY_RESSOURCE_EXHAUSTION;
+ ctx->sta_mgr.sta_own_data.num_bad_assoc_failure ++;
+ }
+ }
+#else
+ {
+ // The station already exists get the TEI.
+ if (sta)
+ tei = cp_sta_get_tei (sta);
+
+ if (MAC_TEI_IS_STA (tei))
+ {
+ cnf.result = CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS;
+ cnf.lease_time_min = CP_LEASE_ASSOC_MIN;
+ }
+ else
+ {
+ cnf.result =
+ CP_MSG_CC_ASSOC_CNF_RESULT_FAILURE_TEMPORARY_RESSOURCE_EXHAUSTION;
+ }
+ }
+#endif /* CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED */
+
+ /* Send the answer. */
+ cnf.sta_tei = tei;
+
+ /* find and change properly */
+ mme->peer.tei = MAC_TEI_BCAST;
+
+#if CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED
+ {
+ // check allowed field
+ if ((MAC_TEI_IS_STA (tei)) && (sta->multi_sta.allowed == true))
+ {
+ if(sta->multi_sta.to_leave == false)
+ {
+ CP_TRACE (MULTI_STA_ASSOC, TRACE_U64 (mme->peer.mac), tei);
+ cp_msg_cc_assoc_cnf_send (ctx, &mme->peer, &cnf);
+
+ 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);
+
+ /* Branch */
+ cp_eoc_multi_sta_fsm_event_t *e = &event;
+ cp_eoc_multi_sta_fsm_event_new (ctx,
+ CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_ASSOC_REQ, e);
+
+ sta->fsm.handled_event = e;
+
+ /*sta in the white list*/
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_disconnected)
+ {
+ cp_eoc_multi_sta_fsm_branch_
+ (ctx, _BRANCH (disconnected, CC_ASSOC_REQ, associated), sta);
+ sta->associated_date_ms = cp_sta_core_get_date_ms (ctx);
+ DBG_PRINT_2("sta: disconn-->assoc, tei = %d", tei);
+ }
+ else if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_unassociated)
+ {
+ cp_eoc_multi_sta_fsm_branch_
+ (ctx, _BRANCH (unassociated, CC_ASSOC_REQ, associated), sta);
+ sta->associated_date_ms = cp_sta_core_get_date_ms (ctx);
+ DBG_PRINT_2("sta: unassoc-->assoc, tei = %d", tei);
+ }
+
+ slab_release (sta);
+ }
+ }
+
+ /* sta not registered or not in the white list*/
+ else
+ {
+ cp_eoc_multi_sta_fsm_event_t *e = &event;
+ cp_eoc_multi_sta_fsm_event_new (ctx,
+ CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_ASSOC_REQ, e);
+ sta->fsm.handled_event = e;
+ cp_msg_cc_assoc_cnf_send (ctx, &mme->peer, &cnf);
+ if(sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_disconnected)
+ {
+ cp_eoc_multi_sta_fsm_branch_
+ (ctx, _BRANCH (disconnected, CC_ASSOC_REQ, unassociated), sta);
+ DBG_PRINT("sta: disconn-->unassoc, tei = %d", tei);
+ }
+ else if (sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_unassociated)
+ {
+ DBG_PRINT("sta: unassoc, tei = %d", tei);
+ sta->fsm.handled_event = NULL;
+ }
+
+ slab_release (sta);
+ }
+ }
+#else
+ {
+ if (tei)
+ {
+ cp_sta_mgr_commit_to_dataplane (ctx);
+ /* Update the last request date in the sta. */
+ /*cp_sta_set_assoc_confirmed (ctx, sta, false);*/
+
+ CP_TRACE (MULTI_STA_ASSOC, TRACE_U64 (mme->peer.mac), tei);
+ cp_msg_cc_assoc_cnf_send (ctx, &mme->peer, &cnf);
+
+ 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);
+ /* Branch */
+ cp_eoc_multi_sta_fsm_event_t *e = &event;
+ cp_eoc_multi_sta_fsm_event_new (ctx,
+ CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_ASSOC_REQ, e);
+
+ sta->fsm.handled_event = e;
+
+ /*sta in the white list*/
+ cp_eoc_multi_sta_fsm_branch_
+ (ctx, _BRANCH (disconnected, CC_ASSOC_REQ, associated), sta);
+ slab_release (sta);
+
+ }
+ // check allowed field as well for WL implementation
+ if (!tei)
+ {
+ sta = cp_sta_mgr_sta_add (ctx, net, 0, mme->peer.mac);
+
+ cp_eoc_multi_sta_fsm_event_t *e = &event;
+ cp_eoc_multi_sta_fsm_event_new (ctx,
+ CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_ASSOC_REQ, e);
+
+ sta->fsm.handled_event = e;
+
+ /*sta not in the white list*/
+ cp_eoc_multi_sta_fsm_branch_
+ (ctx, _BRANCH (disconnected, CC_ASSOC_REQ, unassociated), sta);
+
+ slab_release (sta);
+ }
+ }
+#endif /* CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED */
+}
+
+
+void
+cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__unassociated__timeout_assoc(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__associated__timeout_auth(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__associated__cc_leave(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__authenticated__cc_leave(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__authenticated__lost_connection(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection(cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx)
+{
+}
+
+
+/**
+ * manage authentication of a station.
+ * \param ctx the module context.
+ * \param get_key_req CM_GET_KEY.REQ MME msg having being decrypted
+ */
+void
+cp_eoc_cco_action__cco__cm_get_key_req_pid0 (cp_t *ctx, cp_mme_rx_t * get_key_req)
+{
+ cp_eoc_multi_sta_fsm_event_t event;
+ cp_msg_cm_get_key_req_t req;
+ cp_msg_cm_get_key_cnf_t cnf;
+ cp_net_t *net = NULL;
+ cp_sta_t *sta = NULL;
+ bool added, acceptable = false;
+ mfs_tx_t *mfs;
+
+ dbg_assert (ctx);
+ dbg_assert (get_key_req);
+
+ if (cp_msg_cm_get_key_req_receive (ctx, get_key_req, &req)
+ && cp_secu_protocol_check (NULL, &get_key_req->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEW)
+ && MAC_TEI_IS_STA (get_key_req->peer.tei))
+ acceptable = true;
+
+ // get the data in the payload of the mme.
+ if (acceptable)
+ {
+ if (req.key_type == CP_MSG_KEY_NEK)
+ {
+ // Get the network.
+ net = cp_sta_mgr_get_our_avln (ctx);
+ // Get the station.
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, get_key_req->peer.tei);
+
+ if (sta)
+ {
+ cnf.result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ cp_sta_set_assoc_confirmed (ctx, sta, true);
+ sta->fsm.handled_event = NULL;
+
+ /* all keys granted*/
+ uint i;
+
+ cnf.eks = ctx->mac_config->nek[bsu_nek_index_current (ctx->bsu)].eks;
+ for (i = 0; i < COUNT (ctx->mac_config->nek[0].nek_enc); i++)
+ cnf.key.key[i] =
+ ctx->mac_config->nek[bsu_nek_index_current (ctx->bsu)].nek_enc[i];
+
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false,
+ MAC_LLID_MIN, get_key_req->peer.tei, &added);
+ if(added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ blk_release (mfs);
+
+ /* Send the TEI map: Not needed in EoC */
+ slab_release (sta);
+ }
+ else
+ {
+ cnf.result = CP_MSG_CM_GET_KEY_CNF_RESULT_REQUEST_REFUSED;
+
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, get_key_req->peer.mac);
+ if(sta)
+ {
+ sta->fsm.handled_event = NULL;
+ DBG_PRINT("Station not authenticated, all keys not granted, tei = %d",
+ get_key_req->peer.tei);
+ slab_release (sta);
+ }
+ }
+ cp_secu_protocol_next (&get_key_req->prun, &ctx->rnd, false);
+ } /* Use it to ack previous neck key */
+ else if (req.key_type == CP_MSG_KEY_TEK)
+ {
+ uint i;
+
+ cnf.eks = ctx->mac_config->nek[bsu_nek_index_current (ctx->bsu)].eks;
+ for (i = 0; i < COUNT (ctx->mac_config->nek[0].nek_enc); i++)
+ cnf.key.key[i] =
+ ctx->mac_config->nek[bsu_nek_index_current (ctx->bsu)].nek_enc[i];
+
+ /* Get the network. */
+ net = cp_sta_mgr_get_our_avln (ctx);
+ /* Get the station */
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, get_key_req->peer.tei);
+
+ if (sta)
+ {
+ cnf.result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ cp_sta_set_authenticated (ctx, sta, true);
+
+ cp_eoc_multi_sta_fsm_event_t *e = &event;
+ cp_eoc_multi_sta_fsm_event_new (ctx,
+ CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_GET_KEY_REQ, e);
+
+ sta->fsm.handled_event = e;
+
+ /* all keys granted*/
+ cp_eoc_multi_sta_fsm_branch_
+ (ctx, _BRANCH (associated, CC_GET_KEY_REQ, authenticated), sta);
+
+ sta->authenticated_to_unassociated = true;
+#if CONFIG_CL_EOC_ROUTE
+ arch_dsr_lock ();
+ added = cl_eoc_mactotei_entry_insert (ctx->cl,
+ get_key_req->peer.mac,
+ get_key_req->peer.tei);
+ arch_dsr_unlock ();
+ dbg_assert (added);
+#endif
+ slab_release (sta);
+ }
+ cp_secu_protocol_next (&get_key_req->prun, &ctx->rnd, true);
+ }
+ }
+ // Refuse the request.
+ else
+ {
+ cnf.result = CP_MSG_CM_GET_KEY_CNF_RESULT_REQUEST_REFUSED;
+
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, get_key_req->peer.mac);
+ if(sta)
+ {
+ sta->fsm.handled_event = NULL;
+ DBG_PRINT("Station not authenticated, all keys not granted, tei = %d",
+ get_key_req->peer.tei);
+ slab_release (sta);
+ }
+ }
+
+ /* Send message to peer. Mark station authenticated. */
+ cnf.key_type = req.key_type;
+ cnf.nid = req.nid;
+ cp_msg_cm_get_key_cnf_send (ctx, &get_key_req->peer, get_key_req->peks,
+ &get_key_req->prun, &cnf);
+
+ if((req.key_type == CP_MSG_KEY_TEK)
+ && (cnf.result == CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED))
+ {
+ cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind(ctx, &get_key_req->peer);
+ DBG_PRINT("sta: auth, tei = %d", get_key_req->peer.tei);
+ ctx->sta_mgr.sta_own_data.num_good_assoc_auth ++;
+ }
+}
+
+void
+cp_eoc_multi_sta_action_put_sta_unassociated (cp_t *ctx, cp_sta_t *station)
+{
+ dbg_assert (ctx);
+ dbg_assert (station);
+
+ station->fsm.state = CP_EOC_MULTI_STA_FSM_STATE_unassociated;
+}
+
+#undef _BRANCH
diff --git a/cesar/cp/eoc/multi_sta/action/stub/Module b/cesar/cp/eoc/multi_sta/action/stub/Module
new file mode 100644
index 0000000000..1bb6efbf51
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/stub/Module
@@ -0,0 +1 @@
+SOURCES := multi_sta_action.c
diff --git a/cesar/cp/eoc/multi_sta/action/stub/src/multi_sta_action.c b/cesar/cp/eoc/multi_sta/action/stub/src/multi_sta_action.c
new file mode 100644
index 0000000000..5aa212c320
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/stub/src/multi_sta_action.c
@@ -0,0 +1,136 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/multi_sta_action.c
+ * \brief Multi STA functions stub.
+ * \ingroup cp_eoc_multi_sta_action
+ *
+ * Stub function for the unit test of the other modules.
+ */
+#include "common/std.h"
+
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+
+void
+cp_eoc_multi_sta_action__assoc_req (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+void
+cp_eoc_multi_sta_action__assoc_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_multi_sta_action__get_key_req (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+void
+cp_eoc_multi_sta_action__get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_multi_sta_action__disconnected__CC_ASSOC_REQ(cp_t *ctx, cp_sta_t *sta);
+
+void
+cp_eoc_multi_sta_action__unassociated__CC_ASSOC_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__unassociated__timeout_assoc(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__associated__CC_GET_KEY_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__associated__timeout_auth(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__associated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__authenticated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__sleep_authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx);
+
+/* Include generated tables. */
+#include "cp_eoc_multi_sta_fsm_tables.h"
+
+void
+cp_eoc_multi_sta_action__disconnected__CC_ASSOC_REQ(cp_t *ctx, cp_sta_t *sta)
+{
+ scenario_event (cp_eoc_multi_sta_action__disconnected__CC_ASSOC_REQ);
+}
+
+void
+cp_eoc_multi_sta_action__unassociated__CC_ASSOC_REQ(cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_action__unassociated__CC_ASSOC_REQ);
+}
+
+void
+cp_eoc_multi_sta_action__unassociated__timeout_assoc(cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_action__unassociated__timeout_assoc);
+}
+
+void
+cp_eoc_multi_sta_action__associated__CC_GET_KEY_REQ(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__associated__CC_GET_KEY_REQ);
+}
+
+void
+cp_eoc_multi_sta_action__associated__timeout_auth(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__associated__timeout_auth);
+}
+
+void
+cp_eoc_multi_sta_action__associated__cc_leave(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__associated__cc_leave);
+}
+
+void
+cp_eoc_multi_sta_action__authenticated__cc_leave(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__authenticated__cc_leave);
+}
+
+void
+cp_eoc_multi_sta_action__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__authenticated__CC_SLEEP_ENTER_REQ);
+}
+
+void
+cp_eoc_multi_sta_action__authenticated__lost_connection(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__authenticated__lost_connection);
+}
+
+void
+cp_eoc_multi_sta_action__sleep_authenticated__lost_connection(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_action__sleep_authenticated__lost_connection);
+}
+
+void
+cp_eoc_multi_sta_action__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx)
+{
+ scenario_event
+ (cp_eoc_multi_sta_action__sleep_authenticated__CC_SLEEP_EXIT_IND);
+}
+
+#endif
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/Makefile b/cesar/cp/eoc/multi_sta/action/test/utest/Makefile
new file mode 100644
index 0000000000..bdfdaf2d37
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/Makefile
@@ -0,0 +1,11 @@
+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
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/actions-Config b/cesar/cp/eoc/multi_sta/action/test/utest/actions-Config
new file mode 100644
index 0000000000..20b7584c03
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/actions-Config
@@ -0,0 +1,13 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_TRACE_ON_FATAL = y
+CONFIG_TRACE = n
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/actions-Makefile b/cesar/cp/eoc/multi_sta/action/test/utest/actions-Makefile
new file mode 100644
index 0000000000..f557d6a442
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/actions-Makefile
@@ -0,0 +1,31 @@
+BASE = ../../../../../..
+
+VARIANT = actions
+
+DEFS = -DSTA_CORE_UNIT_TEST=1
+
+INCLUDES = cp/eoc/multi_sta/action/test/utest \
+ cp/eoc/multi_sta/action/test/utest/actions-override
+
+HOST_PROGRAMS = test_actions
+
+test_actions_SOURCES = test_actions.c pbproc_stub.c pwl_stub.c actions_stub.c ce_stub.c beacon_stub.c\
+ cp_eoc_sta_misc_stub.c
+test_actions_MODULES = lib cp/eoc/multi_sta_fsm cp/sta/mgr cp/eoc/sta/mgr cp/msg/stub \
+ cp/msg lib/scenario mac/common cp/fsm cp/eoc/cco/action cp/eoc/cco/action/stub \
+ cp/eoc/multi_sta/action cp/eoc/cco/bw cp/beacon/stub \
+ cp/cco/bw cp/secu/stub mac/sar/stub cp/sta/core/stub \
+ cp/cco/action/stub cl/stub cp/eoc/sta/action/stub \
+ cp/cl_interf interface/stub cp/secu ce/tx/stub cp/sta/action bsu/stub
+
+test_actions_CONFIG_MODULES = cl mac/sar cp
+
+cp_sta_action_MODULE_SOURCES = vs.c
+cp_eoc_sta_action_MODULE_SOURCES = drv.c poweron.c
+cp_eoc_cco_action_MODULE_SOURCES = cco_action.c
+cp_eoc_cco_action_stub_MODULE_SOURCES = vs_eoc.c
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_msg_stub_MODULE_SOURCES = msg_cc.c msg_cm.c
+cp_msg_MODULE_SOURCES = msg.c mme.c msg_drv.c msg_vs.c msg_vs_eoc.c
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/inc/context.h b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/inc/context.h
new file mode 100644
index 0000000000..0614ca4166
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/inc/context.h
@@ -0,0 +1,85 @@
+#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/beacon/beacon.h"
+#include "cp/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/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/cco/action/inc/cco_action.h"
+#include "ce/tx/inc/tx.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;
+ /** station manager context*/
+ cp_sta_mgr_t sta_mgr;
+ /** Mac store /dataplane */
+ mac_store_t *mac_store;
+ /** MAC config contest*/
+ mac_config_t *mac_config;
+ /** Convergence Layer context */
+ cl_t *cl;
+ /** Segmentation and reassembly context */
+ sar_t *sar;
+ /** PBProc. */
+ pbproc_t *pbproc;
+
+ cp_beacon_t beacon;
+ cp_msg_t msg;
+ lib_rnd_t rnd;
+ interface_t *interface;
+ cp_sta_action_t sta_action;
+ cp_eoc_cco_bw_sched_t schedule;
+ ca_t *ca;
+ cp_cco_bw_t bw;
+ cp_cl_interf_t cl_interf;
+ cp_cco_action_t cco_action;
+ ce_tx_t ce_tx;
+ ce_rx_t *ce_rx;
+
+ /** BSU context. */
+ bsu_t *bsu;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/core.h b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/core.h
new file mode 100644
index 0000000000..8ca46f4ef3
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/core.h
@@ -0,0 +1,27 @@
+#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);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/defs.h b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..9698b44e93
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/actions-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/multi_sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..e380fb66e7
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h
@@ -0,0 +1,37 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/fsm-Config b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-Config
new file mode 100644
index 0000000000..9e2999ca04
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-Config
@@ -0,0 +1,11 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/fsm-Makefile b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-Makefile
new file mode 100644
index 0000000000..1cd005f8e2
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-Makefile
@@ -0,0 +1,30 @@
+BASE = ../../../../../..
+
+VARIANT = fsm
+
+DEFS = -DSTA_CORE_UNIT_TEST=1
+
+INCLUDES = cp/eoc/multi_sta/action/test/utest \
+ cp/eoc/multi_sta/action/test/utest/fsm-override
+
+HOST_PROGRAMS = test_fsm
+
+test_fsm_SOURCES = test_fsm.c fsm_stub.c actions.c pbproc_stub.c pwl_stub.c beacon_stub.c cp_eoc_sta_misc_stub.c
+test_fsm_MODULES = lib lib/scenario cp/eoc/multi_sta_fsm cp/fsm \
+cp/sta/mgr cp/cco/action/stub cp/eoc/sta/action/stub cp/msg cp/msg/stub \
+cp/sta/core/stub cp/eoc/cco/action mac/common cp/secu \
+cp/beacon/stub cp/secu/stub cp/sta/core/stub cp/eoc/sta/mgr mac/sar/stub cp/cco/bw \
+cp/eoc/cco/bw cp/cl_interf interface/stub cl/stub ce/tx/stub bsu/stub
+
+test_fsm_CONFIG_MODULES = cp cl mac/sar
+
+
+cp_MODULE_MODULES =
+cp_eoc_multi_sta_fsm_MODULE_SOURCES = fsm.c events.c
+cp_eoc_sta_action_MODULE_SOURCES = drv.c poweron.c
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_msg_stub_MODULE_SOURCES = msg_cc.c msg_cm.c
+cp_msg_MODULE_SOURCES = msg.c mme.c msg_drv.c msg_vs.c msg_vs_eoc.c
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/inc/context.h b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/inc/context.h
new file mode 100644
index 0000000000..8fe662cec7
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/inc/context.h
@@ -0,0 +1,88 @@
+#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/beacon/beacon.h"
+#include "cp/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/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/cl_interf/cl_interf.h"
+#include "cp/cl_interf/inc/context.h"
+#include "cp/cco/action/inc/cco_action.h"
+#include "ce/tx/inc/tx.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;
+ /** station manager context*/
+ cp_sta_mgr_t sta_mgr;
+ /** Mac store /dataplane */
+ mac_store_t *mac_store;
+ /** MAC config contest*/
+ mac_config_t *mac_config;
+ /** Convergence Layer context */
+ cl_t *cl;
+ /** Segmentation and reassembly context */
+ sar_t *sar;
+ /** PBProc. */
+ pbproc_t *pbproc;
+
+ cp_beacon_t beacon;
+ cp_cco_bw_t bw;
+ cp_msg_t msg;
+ lib_rnd_t rnd;
+ interface_t *interface;
+ cp_sta_action_t sta_action;
+ cp_eoc_cco_bw_sched_t schedule;
+ ca_t *ca;
+ cp_cl_interf_t cl_interf;
+ cp_cco_action_t cco_action;
+ ce_tx_t ce_tx;
+ ce_rx_t *ce_rx;
+ /** BSU context. */
+ bsu_t *bsu;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/core.h b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/core.h
new file mode 100644
index 0000000000..2bd5fa51cd
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/core.h
@@ -0,0 +1,28 @@
+#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);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/defs.h b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..9698b44e93
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-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/multi_sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..6bbe720571
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h
@@ -0,0 +1,38 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/inc/scenario_defs.h b/cesar/cp/eoc/multi_sta/action/test/utest/inc/scenario_defs.h
new file mode 100644
index 0000000000..e004a95476
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/inc/scenario_defs.h
@@ -0,0 +1,135 @@
+#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/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_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__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/multi_sta/action/test/utest/src/actions.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/actions.c
new file mode 100644
index 0000000000..6438b5e34e
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/actions.c
@@ -0,0 +1,41 @@
+/* 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/multi_sta_fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/inc/events.h"
+#include "cp/inc/context.h"
+
+
+static cp_eoc_multi_sta_fsm_event_t event;
+
+static
+cp_eoc_multi_sta_fsm_event_t *scenario_action_make_event (cp_t *cp,
+scenario_action_param_t *ap)
+{
+
+ cp_eoc_multi_sta_fsm_event_t *e = &event;
+ cp_eoc_multi_sta_fsm_event_new (cp, ap->type, e);
+ return e;
+}
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ scenario_action_process_t *p = (scenario_action_process_t*)params;
+ cp_eoc_multi_sta_fsm_handled_event (globals->cp, p->sta,
+ scenario_action_make_event(globals->cp, p));
+}
+
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/actions_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/actions_stub.c
new file mode 100644
index 0000000000..adc3ccde9e
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/actions_stub.c
@@ -0,0 +1,95 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/actions_stub.c
+ * \brief Override Multi STA FSM tables.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+
+void
+cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__unassociated__timeout_assoc(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__timeout_auth(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__assoc_req(cp_t *ctx,cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_eoc_multi_sta_action__get_key_req(cp_t *ctx,cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+
+void
+cp_eoc_cco_action_vs__cco__vs_set_out_lev_ind (cp_t *ctx, cp_mme_peer_t *peer)
+{
+}
+// u8
+// cp_sta_action_get_average_ble (cp_t *ctx, cp_tei_t tei, bool tx,
+// bool fc_format)
+// {
+// return 0;
+// }
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/beacon_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/beacon_stub.c
new file mode 100644
index 0000000000..123dcb9f0b
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/beacon_stub.c
@@ -0,0 +1,30 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/beacon_stub.c
+ * \brief Beacon stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "cp/beacon/beacon.h"
+
+#include "lib/scenario/scenario.h"
+
+
+void
+cp_beacon_deactivate (cp_t *ctx)
+{
+
+}
+
+void
+cp_beacon_poweron_init (cp_t *ctx)
+{
+
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/ce_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/ce_stub.c
new file mode 100644
index 0000000000..8d99b65842
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/ce_stub.c
@@ -0,0 +1,24 @@
+/* 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;
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/cp_eoc_sta_misc_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/cp_eoc_sta_misc_stub.c
new file mode 100644
index 0000000000..405fc46de9
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/cp_eoc_sta_misc_stub.c
@@ -0,0 +1,45 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest/src/cp_eoc_sta_misc_stub.c
+ * \brief STA action, miscellaneous definitions.
+ * \ingroup cp_sta_action
+ */
+ #include "common/std.h"
+ #include "cp/inc/context.h"
+ #include "cp/msg/msg.h"
+
+// void
+// cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+// {
+// }
+//
+// void
+// cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+// {
+// }
+//
+// void
+// cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+// {
+// }
+
+u8
+cp_sta_action_get_average_ble (cp_t *ctx, cp_tei_t tei, bool tx,
+ bool fc_format)
+{
+ return 0;
+}
+
+void
+cp_eoc_sta_mgr_get_ports (cp_t *ctx, uint *numStas, mac_t *stas_macs, bool stas_port_ed[][PORT_NB],
+ u8 stas_port_service[][PORT_NB])
+{
+
+}
+
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/fsm_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/fsm_stub.c
new file mode 100644
index 0000000000..6ae66f7a6b
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/fsm_stub.c
@@ -0,0 +1,199 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/fsm_stub.c
+ * \brief Override Multi STA FSM tables.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/inc/tables.h"
+
+
+void
+cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__unassociated__timeout_assoc(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__timeout_auth(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__associated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__cc_leave(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx);
+
+void
+cp_eoc_multi_sta_action__assoc_req(cp_t *ctx,cp_mme_rx_t *mme);
+
+void
+cp_eoc_multi_sta_action__get_key_req(cp_t *ctx,cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_vs__started__vs_get_snr_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_ce_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+
+/* Include generated tables. */
+#include "cp_eoc_multi_sta_fsm_tables.h"
+
+
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_multi_sta_action__assoc_req(cp_t *ctx,cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__disconnected__CC_ASSOC_REQ, param);
+ cp_eoc_multi_sta_fsm_branch_ (ctx, param->branch, param->sta);
+}
+
+
+void
+cp_eoc_multi_sta_action__get_key_req(cp_t *ctx,cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ, param);
+ cp_eoc_multi_sta_fsm_branch_ (ctx, param->branch, param->sta);
+}
+
+
+void
+cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ(cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__unassociated__CC_ASSOC_REQ);
+}
+
+void
+cp_eoc_multi_sta_fsm__unassociated__timeout_assoc(cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__unassociated__timeout_assoc);
+}
+
+void
+cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ);
+}
+
+void
+cp_eoc_multi_sta_fsm__associated__timeout_auth(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__associated__timeout_auth);
+}
+
+void
+cp_eoc_multi_sta_fsm__associated__cc_leave(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__associated__cc_leave);
+}
+
+void
+cp_eoc_multi_sta_fsm__authenticated__cc_leave(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__authenticated__cc_leave);
+}
+
+void
+cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__authenticated__CC_SLEEP_ENTER_REQ);
+}
+
+void
+cp_eoc_multi_sta_fsm__authenticated__lost_connection(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__authenticated__lost_connection);
+}
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection(cp_t *ctx)
+{
+ scenario_event(cp_eoc_multi_sta_fsm__sleep_authenticated__lost_connection);
+}
+
+
+void
+cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND(cp_t *ctx)
+{
+ scenario_event
+ (cp_eoc_multi_sta_fsm__sleep_authenticated__CC_SLEEP_EXIT_IND);
+}
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_snr_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_ce_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/mgr_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/mgr_stub.c
new file mode 100644
index 0000000000..d6fe512dce
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/mgr_stub.c
@@ -0,0 +1,63 @@
+/* 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"
+
+bool
+cp_msg_cc_assoc_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cc_assoc_cnf_t *data)
+{
+ dbg_assert (ctx);
+ return true;
+}
+
+void
+cp_msg_cc_assoc_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ const cp_msg_cc_assoc_cnf_t *data)
+{
+ dbg_assert (ctx);
+ dbg_assert (peer);
+ dbg_assert (data);
+}
+
+void
+cp_cco_action_tei_release (cp_t *ctx, u8 tei)
+{
+ dbg_assert (ctx);
+ dbg_assert (tei);
+}
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx)
+{
+ return 0;
+}
+
+void
+cp_sta_core_checkpoint (cp_t *ctx)
+{
+}
+
+void
+sar_activate (sar_t *ctx, bool activate)
+{
+}
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/pb_proc_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/pb_proc_stub.c
new file mode 100644
index 0000000000..bcc638c356
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/pb_proc_stub.c
@@ -0,0 +1,34 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi/sta/action/test/utest/src.pb_proc_stub.c
+ * \brief General PB Processing functions.
+ * \ingroup pbproc
+ */
+
+
+#include "common/std.h"
+#include "mac/pbproc/inc/context.h"
+
+#include "hal/gpio/gpio.h"
+#include "mac/common/timings.h"
+
+#include "mac/pbproc/inc/fsm_top.h"
+#include "mac/pbproc/inc/fsm_handle_fc.h"
+#include "mac/pbproc/inc/fsm_rx_data.h"
+#include "mac/pbproc/inc/fsm_rx_beacon.h"
+#include "mac/pbproc/inc/fsm_rx_sound.h"
+#include "mac/pbproc/inc/fsm_tx_rts_cts.h"
+#include "mac/pbproc/inc/fsm_tx_data.h"
+#include "mac/pbproc/inc/fsm_tx_sound.h"
+
+
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/pbproc_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/pbproc_stub.c
new file mode 100644
index 0000000000..f556b2976d
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/pbproc_stub.c
@@ -0,0 +1,31 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/action/test/utest_eoc/src/pbproc_stub.c
+ * \brief General PB Processing functions.
+ * \ingroup pbproc
+ */
+#include "common/std.h"
+
+#include "mac/pbproc/inc/context.h"
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{
+}
+
+void pbproc_parameters_adjust (pbproc_t *ctx, bool adjust)
+{
+}
+
+u8
+ce_rx_bl_nsr_compute_total_mean (ce_rx_bitloading_t *bl)
+{
+ return 1;
+}
+
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/pwl_stub.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/pwl_stub.c
new file mode 100644
index 0000000000..59cdea8ec2
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/pwl_stub.c
@@ -0,0 +1,21 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file stub/pwl.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/pwl/pwl.h"
+
+void
+cp_pwl_reset (cp_t *ctx)
+{
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/test_actions.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/test_actions.c
new file mode 100644
index 0000000000..75b5b4b7bf
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/test_actions.c
@@ -0,0 +1,319 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_actions.c
+ * \brief Test multi_sta module.
+ * \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/action/multi_sta_action.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/inc/context.h"
+#include "cp/inc/trace.h"
+#include "cp/sta/core/core.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/msg/msg.h"
+#include "lib/test.h"
+#include "lib/utils.h"
+#include "lib/swap.h"
+#include "lib/slab.h"
+#include "cl/cl.h"
+#include "cl/inc/context.h"
+#include "mac/sar/inc/sar_context.h"
+
+
+void
+test_case_sta_assoc_procedure (test_t test)
+{
+ cp_t cp;
+ mac_config_t mac_config;
+
+ cp_sta_t *sta;
+
+ bitstream_t bitstream;
+ u8 buffer[256] __attribute__((aligned(256)));
+ uint req_type = CP_MSG_CC_ASSOC_REQ_TYPE_NEW;
+ uint cl;
+ cp_tei_t tei = 5;
+ cp_net_t *net;
+ cp_nid_t nid = 12;
+ cp_snid_t snid = 34;
+ uint cco_cap = 2;
+ uint pco_cap = true;
+ cp_mme_rx_t mme_rx;
+
+ slab_cache_t sta_slab_cache;
+
+ slab_cache_init (&sta_slab_cache,
+ "Station cache",
+ sizeof (cp_sta_private_t),
+ (slab_object_destructor_t) cp_sta_uninit);
+
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&mac_config, 0, sizeof (mac_config_t));
+
+ sta = cp_sta_init (&sta_slab_cache);
+
+ sar_t sar;
+ cp.sar = &sar;
+ cp.cl = (cl_t *) &cl;
+ cp.mac_store = mac_store_init ();
+
+ cp_sta_mgr_init (&cp);
+ cp_msg_init (&cp);
+ cp_sta_own_data_init (&cp);
+ cp_cl_interf_init (&cp);
+
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+
+ cp.sta_mgr.our_avln->snid = snid;
+ cp.sta_mgr.our_avln->nid = nid;
+
+
+ test_case_begin (test, "Receiving CC_ASSOC.REQ");
+
+ cp_trace_init (&cp);
+
+ test_begin (test, "Test 1: Receiving a CC_ASSOC.REQ join")
+ {
+ // Construct the MME to associate the first station.
+ mme_rx.peer.mac = 2;
+ mme_rx.peer.vlan_tag = 0;
+ mme_rx.peer.tei = 0;
+
+ printf("DBG: Receiving a CC_ASSOC.REQ join ENTERED\n");
+
+ // 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_rx.p_mme = buffer;
+ mme_rx.length = 60;
+
+ sta = cp_sta_mgr_sta_add (&cp, net, tei, mme_rx.peer.mac);
+
+ cp_eoc_multi_sta_action__assoc_req (&cp, &mme_rx);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, mme_rx.peer.mac);
+
+ test_fail_unless (sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_associated);
+
+ cp_eoc_multi_sta_fsm_uninit (&cp, sta);
+ }
+ test_end;
+
+ #if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+
+
+void
+test_case_sta_authentication (test_t test)
+{
+ test_case_begin (test, "Authentication status.");
+
+ cp_t cp;
+ cp_net_t *net;
+ mfs_rx_t mfs;
+ bitstream_t bitstream;
+ cp_mme_rx_t mme;
+ u64 data;
+ u8 buffer[1024];
+ cl_t cl;
+ sar_t sar;
+ cp_sta_t *sta;
+ mac_config_t mac_config;
+
+ cp_cco_action_init (&cp);
+ cp_sta_mgr_init (&cp);
+ cp_beacon_init (&cp);
+ lib_rnd_init (&cp.rnd, 1234);
+ memset (&cp.beacon, 0, sizeof (cp_beacon_t));
+
+ cp.cl = &cl;
+ cl.mactotei = NULL;
+ cp.sar = &sar;
+ sar.mac_store = mac_store_init ();
+ cp.mac_store = sar.mac_store;
+ cp.mac_config = &mac_config;
+
+ // Update the net NID and SNID.
+ cp_sta_own_data_set_nid (&cp, 0x1);
+ cp_sta_own_data_set_snid (&cp, 0x2);
+
+ net = cp_sta_mgr_add_avln (&cp, 2, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+ cp_sta_own_data_set_tei (&cp, 1);
+ cp_sta_own_data_set_cco_status (&cp, true);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 2, 2);
+ cp_sta_set_assoc_confirmed (&cp, sta, false);
+ cp_eoc_multi_sta_fsm_init (&cp,sta);
+ sta->fsm.state = CP_EOC_MULTI_STA_FSM_STATE_associated;
+
+
+ test_case_begin (test, "Sta authentication procedure");
+ cp_trace_init (&cp);
+
+ test_begin (test, "assoc")
+ {
+ // 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 = swap16 (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 (&cp, 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 = 0x2;
+ mme.peer.mac = 2;
+ mme.bitstream.data = bitstream.data;
+ mme.bitstream.data_bits = bitstream.data_bits;
+ mfs.common.tei = 0x1;
+ cp_secu_protocol_run_new (&mme.prun, 0, &cp.rnd);
+
+ cp_eoc_multi_sta_action__get_key_req (&cp, &mme);
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, mme.peer.mac);
+ test_fail_unless (sta->fsm.state == CP_EOC_MULTI_STA_FSM_STATE_authenticated);
+
+ slab_release (sta);
+ cp_sta_mgr_uninit (&cp);
+ cp_cco_action_uninit (&cp);
+ cp_beacon_uninit (&cp);
+ }
+ test_end;
+ #if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+ #endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+
+void
+test_action_test_suite (test_t t)
+{
+ test_suite_begin (t, "multi_sta fsm");
+ test_case_sta_assoc_procedure (t);
+ test_case_sta_authentication(t);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ lib_stats_init();
+ trace_init ();
+ test_init (t, argc, argv);
+ test_action_test_suite (t);
+ trace_uninit ();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
+
+/**
+ * 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;
+ bool vlantag_present;
+ u64 unused;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (mme->p_mme);
+ dbg_assert (mme->length < ETH_PACKET_MAX_SIZE);
+ dbg_assert (data);
+
+ if (bitstream_direct_read (mme->p_mme + 12, 0, 16) == swap16(HPAV_MTYPE_MME))
+ vlantag_present = false;
+ else
+ vlantag_present = true;
+
+ // 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);
+ if (vlantag_present)
+ bitstream_access (&mme->bitstream, &mme->peer.vlan_tag, 32);
+ bitstream_access (&mme->bitstream, &unused, 16);
+ 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);
+
+ if (vlantag_present)
+ offset = 41;
+ else
+ offset = 37;
+
+ memcpy (mme->p_mme + offset, &data->hash_key, mme->length - offset);
+ return true;
+}
diff --git a/cesar/cp/eoc/multi_sta/action/test/utest/src/test_fsm.c b/cesar/cp/eoc/multi_sta/action/test/utest/src/test_fsm.c
new file mode 100644
index 0000000000..b7d1d5f706
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta/action/test/utest/src/test_fsm.c
@@ -0,0 +1,119 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_fsm.c
+ * \brief Test multi_sta module.
+ * \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/msg/msg.h"
+#include "lib/test.h"
+#include "lib/utils.h"
+#include "lib/swap.h"
+#include "lib/slab.h"
+
+
+void
+test_fsm_basic_test_case (test_t t)
+{
+ test_case_begin (t, "basic");
+ cp_t cp;
+ cp_sta_t sta;
+ cp.sta_core_urgent_flag = false;
+ cp_trace_init (&cp);
+
+ test_begin (t, "Disconnected-Authenticated")
+ {
+ cp_eoc_multi_sta_fsm_init (&cp, &sta);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* Disconnected */
+ SCENARIO_ACTION (process,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_ASSOC_REQ,
+ .sta = &sta),
+
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__disconnected__CC_ASSOC_REQ,
+ .sta = &sta,
+ .branch =
+ CP_EOC_MULTI_STA_FSM_BRANCH(disconnected, CC_ASSOC_REQ, sta_in_wl)), //state, event, branch
+
+
+
+
+ SCENARIO_ACTION (process,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_CC_GET_KEY_REQ,
+ .sta = &sta),
+
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__associated__CC_GET_KEY_REQ,
+ .sta = &sta,
+ .branch =
+ CP_EOC_MULTI_STA_FSM_BRANCH(associated, CC_GET_KEY_REQ, all_keys_granted)),
+
+ SCENARIO_END
+ };
+
+
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+
+ test_fail_unless (sta.fsm.state == CP_EOC_MULTI_STA_FSM_STATE_authenticated);
+
+ cp_eoc_multi_sta_fsm_uninit (&cp, &sta);
+ } 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, "multi_sta fsm");
+ test_fsm_basic_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_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/cp/eoc/multi_sta_fsm/Config b/cesar/cp/eoc/multi_sta_fsm/Config
new file mode 100644
index 0000000000..d84f18d9da
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/Config
@@ -0,0 +1 @@
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF = "cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
diff --git a/cesar/cp/eoc/multi_sta_fsm/Module b/cesar/cp/eoc/multi_sta_fsm/Module
new file mode 100644
index 0000000000..138c989aa7
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/Module
@@ -0,0 +1,40 @@
+SOURCES := tables.c fsm.c events.c
+
+ifndef $(MODULE_VAR)_ONCE
+$(MODULE_VAR)_ONCE := 1$(CONFIG_CP_EOC_MULTI_STA_FSM_DEF)
+
+cp_eoc_multi_sta_fsm_defs_h = $(OBJ_DIR)/inc/cp_eoc_multi_sta_fsm_defs.h
+cp_eoc_multi_sta_fsm_tables_h = $(OBJ_DIR)/inc/cp_eoc_multi_sta_fsm_tables.h
+CLEAN_FILES += $(cp_eoc_multi_sta_fsm_defs_h) $(cp_eoc_multi_sta_fsm_tables_h)
+
+COMPILE_DEPS += $(cp_eoc_multi_sta_fsm_defs_h)
+
+vpath %.fsm $(BASE)
+vpath %.conf $(BASE)
+vpath %_defs.h $(BASE)
+vpath %_tables.h $(BASE)
+
+cp_eoc_multi_sta_fsm_deps = $(CONFIG_CP_EOC_MULTI_STA_FSM_DEF:"%"=%) \
+ $(call src2src,multi_sta.conf template_defs.h \
+ template_tables.h,cp/eoc/multi_sta_fsm/src/fsm)
+
+$(cp_eoc_multi_sta_fsm_defs_h) $(cp_eoc_multi_sta_fsm_tables_h): $(cp_eoc_multi_sta_fsm_deps) $(DFAGEN) \
+ $(OBJ_INC_DIR_STAMP)
+ python $(DFAGEN) -O $(OBJ_INC_DIR) \
+ -o c -d $< -c $(filter %.conf,$^) -p cp_eoc_multi_sta_fsm
+
+CLEAN_FILES += $(OBJ_DIR)/cp_eoc_multi_sta_fsm.png $(OBJ_DIR)/cp_eoc_multi_sta_fsm.dot
+
+$(OBJ_DIR)/cp_eoc_multi_sta_fsm.png: $(OBJ_DIR)/cp_eoc_multi_sta_fsm.dot
+ dot -Tpng -o $@ $<
+
+$(OBJ_DIR)/cp_eoc_multi_sta_fsm.dot: $(cp_eoc_multi_sta_fsm_deps)
+ python $(DFAGEN) -O $(OBJ_DIR) \
+ -o dot -d $< -p cp_eoc_multi_sta_fsm
+else
+# This module rules depend on a configuration item, it need work to be used in
+# several build type.
+ifneq ($($(MODULE_VAR)_ONCE),1$(CONFIG_CP_EOC_MULTI_STA_FSM_DEF))
+$(error Module not safe for multiple build types)
+endif
+endif
diff --git a/cesar/cp/eoc/multi_sta_fsm/doc/cp_eoc_multi_sta_fsm.odt b/cesar/cp/eoc/multi_sta_fsm/doc/cp_eoc_multi_sta_fsm.odt
new file mode 100644
index 0000000000..aba756d326
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/doc/cp_eoc_multi_sta_fsm.odt
Binary files differ
diff --git a/cesar/cp/eoc/multi_sta_fsm/forward.h b/cesar/cp/eoc/multi_sta_fsm/forward.h
new file mode 100644
index 0000000000..fe92df5540
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/forward.h
@@ -0,0 +1,19 @@
+#ifndef cp_eoc_multi_sta_fsm_forward_h
+#define cp_eoc_multi_sta_fsm_forward_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/forward.h
+ * \brief Control plane Multi STA FSM forward declarations.
+ * \ingroup cp_eoc_mult_sta_fsm
+ */
+
+/* Forward declaration. */
+typedef struct cp_eoc_multi_sta_fsm_event_t cp_eoc_multi_sta_fsm_event_t;
+
+#endif /* cp_eoc_multi_sta_fsm_forward_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/fsm.h b/cesar/cp/eoc/multi_sta_fsm/fsm.h
new file mode 100644
index 0000000000..fd19fa3b31
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/fsm.h
@@ -0,0 +1,68 @@
+#ifndef cp_eoc_multi_sta_fsm_h
+#define cp_eoc_multi_sta_fsm_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/multi_sta_fsm.h
+ * \brief Control plane Multi STA FSM
+ * \ingroup cp_eoc_multi_sta_fsm
+ *
+ *
+ */
+#include "cp/cp.h"
+#include "forward.h"
+
+#include "inc/events.h"
+#include "cp/sta/mgr/sta.h"
+
+BEGIN_DECLS
+
+/**
+ * Initialise the Multi STA FSM
+ * \param ctx control plane context
+ */
+void
+cp_eoc_multi_sta_fsm_init (cp_t *ctx, cp_sta_t* sta);
+
+/**
+ * Uninitialise the Multi STA FSM
+ * \param ctx control plane context
+ */
+void
+cp_eoc_multi_sta_fsm_uninit (cp_t *ctx, cp_sta_t* sta);
+
+/**
+ * Process one event
+ * \param ctx control plane context
+ * \param sta active station
+ * \param event event to process
+ */
+void
+cp_eoc_multi_sta_fsm_handled_event (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *e);
+
+
+
+/**
+ * Select a branch during a transition.
+ * \param ctx control plane context
+ * \param branch branch to select
+ * \param sta active station
+ *
+ * The selected branch must correspond to the current handled transition.
+ */
+void
+cp_eoc_multi_sta_fsm_branch_ (cp_t *ctx, cp_eoc_multi_sta_fsm_branch_t branch,
+cp_sta_t *sta);
+#define cp_eoc_multi_sta_fsm_branch(ctx, state, event, branch, sta) \
+ cp_eoc_multi_sta_fsm_branch_ \
+ ((ctx), CP_EOC_MULTI_STA_FSM_BRANCH (state, event,branch), (sta))
+
+END_DECLS
+
+#endif /* cp_eoc_multi_sta_fsm_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/inc/context.h b/cesar/cp/eoc/multi_sta_fsm/inc/context.h
new file mode 100644
index 0000000000..efbcb16591
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/inc/context.h
@@ -0,0 +1,33 @@
+#ifndef cp_eoc_multi_sta_fsm_inc_context_h
+#define cp_eoc_multi_sta_fsm_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/inc/context.h
+ * \brief Multi STA FSM private context.
+ * \ingroup cp_eoc_multi_sta_fsm
+ */
+
+#include "lib/slab.h"
+
+#include "cp/eoc/multi_sta_fsm/forward.h" // for 'cp_eoc_multi_sta_fsm_event_t'
+#include "cp_eoc_multi_sta_fsm_defs.h" // for 'cp_eoc_multi_sta_fsm_state_t'
+
+/** Multi STA FSM context. */
+struct cp_eoc_multi_sta_fsm_t
+{
+ /** current state */
+ cp_eoc_multi_sta_fsm_state_t state;
+
+ /** event currently handled*/
+ cp_eoc_multi_sta_fsm_event_t *handled_event;
+};
+
+typedef struct cp_eoc_multi_sta_fsm_t cp_eoc_multi_sta_fsm_t;
+
+#endif /* cp_eoc_multi_sta_fsm_inc_context_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/inc/events.h b/cesar/cp/eoc/multi_sta_fsm/inc/events.h
new file mode 100644
index 0000000000..154f73fcca
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/inc/events.h
@@ -0,0 +1,74 @@
+#ifndef cp_eoc_multi_sta_fsm_inc_events_h
+#define cp_eoc_multi_sta_fsm_inc_events_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/inc/events.h
+ * \brief MUlti STA FSM events
+ * \ingroup cp_eoc_multi_sta_fsm
+ */
+
+/* This is a auto-generated file, check your Makefile if it is not found. */
+#include "cp_eoc_multi_sta_fsm_defs.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/net.h"
+
+/**
+ * Call the transition associated with an event.
+ * \param ctx control plane context
+ * \param sta station
+ * \param event handled event
+ * \param transition transition function to call
+ */
+typedef void (*cp_eoc_multi_sta_fsm_handler_t) (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *event,
+ cp_eoc_multi_sta_fsm_transition_t transition);
+
+
+void
+cp_eoc_multi_sta_fsm_event_handler (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *event,
+ cp_eoc_multi_sta_fsm_transition_t transition);
+
+
+/** Event base structure. */
+struct cp_eoc_multi_sta_fsm_event_t
+{
+ /** Event type. */
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ /** Handle transition callback. */
+ cp_eoc_multi_sta_fsm_handler_t handler;
+};
+
+struct cp_eoc_multi_sta_fsm_event_mme_t
+{
+ /** Parent event. */
+ cp_eoc_multi_sta_fsm_event_t event;
+ /** Associated MME. */
+ cp_mme_rx_t *mme;
+};
+typedef struct cp_eoc_multi_sta_fsm_event_mme_t
+cp_eoc_multi_sta_fsm_event_mme_t;
+/* Forward declaration in cp/eoc/multi_sta_fsm/forward.h. */
+
+BEGIN_DECLS
+
+void
+cp_eoc_multi_sta_fsm_event_new (cp_t *ctx,
+ cp_eoc_multi_sta_fsm_event_type_t type,
+ cp_eoc_multi_sta_fsm_event_t *event);
+
+
+
+cp_eoc_multi_sta_fsm_event_t *
+cp_eoc_multi_sta_fsm_event_mme_new (cp_t *ctx, cp_eoc_multi_sta_fsm_event_type_t
+type, cp_mme_rx_t *mme);
+
+END_DECLS
+
+#endif /* cp_eoc_multi_sta_fsm_inc_events_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/inc/tables.h b/cesar/cp/eoc/multi_sta_fsm/inc/tables.h
new file mode 100644
index 0000000000..ae1a552761
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/inc/tables.h
@@ -0,0 +1,52 @@
+#ifndef cp_eoc_multi_sta_fsm_inc_tables_h
+#define cp_eoc_multi_sta_fsm_inc_tables_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/multi_sta_fsm/inc/tables.h
+ * \brief Multi STA FSM tables declaration
+ * \ingroup cp_eoc_multi_sta_fsm
+ */
+
+#include "config/trace.h"
+
+/** Control Plane Multi STA FSM transition table. */
+extern const cp_eoc_multi_sta_fsm_transition_t
+ cp_eoc_multi_sta_fsm_transition_table
+ [CP_EOC_MULTI_STA_FSM_STATE_NB][CP_EOC_MULTI_STA_FSM_EVENT_TYPE_NB];
+
+/** Control Plane Multi STA FSM only branch table. */
+extern const cp_eoc_multi_sta_fsm_state_t
+ cp_eoc_multi_sta_fsm_only_branch_table
+ [CP_EOC_MULTI_STA_FSM_STATE_NB][CP_EOC_MULTI_STA_FSM_EVENT_TYPE_NB];
+
+/* Control Plane Multi STA FSM state enter table. */
+const cp_eoc_multi_sta_fsm_enter_leave_t
+cp_eoc_multi_sta_fsm_enter_table[CP_EOC_MULTI_STA_FSM_STATE_NB] ;
+
+/* Control Plane Multi STA FSM state leave table. */
+const cp_eoc_multi_sta_fsm_enter_leave_t
+cp_eoc_multi_sta_fsm_leave_table[CP_EOC_MULTI_STA_FSM_STATE_NB];
+
+/* Control Plane Multi STA FSM initial states table. */
+const cp_eoc_multi_sta_fsm_state_t
+cp_eoc_multi_sta_fsm_initials_table[CP_EOC_MULTI_STA_FSM_INITIAL_NB];
+
+#if CONFIG_TRACE
+
+/* Control Plane Multi STA FSM state names table. */
+extern const char *
+cp_eoc_multi_sta_fsm_state_names_table[CP_EOC_MULTI_STA_FSM_STATE_NB];
+
+/* Control Plane Multi STA event names table. */
+const char *
+cp_eoc_multi_sta_fsm_event_names_table[CP_EOC_MULTI_STA_FSM_EVENT_TYPE_NB];
+
+#endif /* CONFIG_TRACE */
+
+#endif /* cp_eoc_multi_sta_fsm_inc_tables_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/events.c b/cesar/cp/eoc/multi_sta_fsm/src/events.c
new file mode 100644
index 0000000000..bde3da77b4
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/events.c
@@ -0,0 +1,71 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/src/events.c
+ * \brief Multi STA FSM events.
+ * \ingroup cp_eoc_multi_sta_fsm
+ */
+#include "common/std.h"
+
+#include "cp/inc/context.h"
+#include "fsm.h"
+#include "inc/tables.h"
+
+
+typedef void (*cp_eoc_multi_sta_fsm_event_transition_t) (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_eoc_multi_sta_fsm_event_handler (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *event,
+ cp_eoc_multi_sta_fsm_transition_t transition)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (event);
+ dbg_assert (transition);
+ dbg_assert_ptr (sta);
+ cp_eoc_multi_sta_fsm_event_transition_t t = transition;
+
+ cp_eoc_multi_sta_fsm_event_mme_t *event_mme =
+ PARENT_OF (cp_eoc_multi_sta_fsm_event_mme_t, event, event);
+ /* Call transition. */
+ t (ctx, event_mme->mme);
+}
+
+void
+cp_eoc_multi_sta_fsm_event_new (cp_t *ctx,
+ cp_eoc_multi_sta_fsm_event_type_t type,
+ cp_eoc_multi_sta_fsm_event_t *event)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert (type < CP_EOC_MULTI_STA_FSM_EVENT_TYPE_NB);
+ dbg_assert_ptr (event);
+ event->type = type;
+ event->handler = cp_eoc_multi_sta_fsm_event_handler;
+ return;
+}
+
+
+
+
+cp_eoc_multi_sta_fsm_event_t *
+cp_eoc_multi_sta_fsm_event_mme_new (cp_t *ctx, cp_eoc_multi_sta_fsm_event_type_t
+type, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (type < CP_EOC_MULTI_STA_FSM_EVENT_TYPE_NB);
+ cp_eoc_multi_sta_fsm_event_mme_t *e;
+ e = slab_alloc (&ctx->fsm.event_mme_cache);
+ e->event.type = type;
+ e->event.handler = cp_eoc_multi_sta_fsm_event_handler;
+// slab_addref (mme);
+ e->mme = mme;
+ return &e->event;
+}
+
+
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/fsm.c b/cesar/cp/eoc/multi_sta_fsm/src/fsm.c
new file mode 100644
index 0000000000..3a6c7bc469
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/fsm.c
@@ -0,0 +1,158 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/src/fsm.c
+ * \brief FSM slave station engine.
+ * \ingroup cp_eoc_multi_sta_fsm
+ */
+#include "common/std.h"
+#include "cp/inc/context.h"
+#include "fsm.h"
+#include "inc/tables.h"
+#include "cp/sta/core/core.h"
+#include "cp/sta/mgr/sta.h"
+#include "stdio.h"
+
+void
+cp_eoc_multi_sta_fsm_init (cp_t *ctx, cp_sta_t *sta)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (sta);
+ /* only one initial state allowed */
+ dbg_assert (CP_EOC_MULTI_STA_FSM_INITIAL_NB==1);
+ sta->fsm.state = cp_eoc_multi_sta_fsm_initials_table[0];
+ if (cp_eoc_multi_sta_fsm_enter_table[0])
+ cp_eoc_multi_sta_fsm_enter_table[0](ctx,sta);
+}
+
+void
+cp_eoc_multi_sta_fsm_uninit (cp_t *ctx, cp_sta_t *sta)
+{
+}
+
+/**
+ * Execute callbacks attached to enter and leave action of states.
+ * \param ctx control plane context
+ * \param sta active station
+ * \param to state entered
+ */
+static void
+cp_eoc_multi_sta_fsm_leave_enter (cp_t *ctx, cp_sta_t *sta, cp_eoc_multi_sta_fsm_state_t to)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (sta);
+ dbg_assert (to < CP_EOC_MULTI_STA_FSM_STATE_NB);
+ cp_eoc_multi_sta_fsm_state_t from = sta->fsm.state;
+ dbg_assert (from < CP_EOC_MULTI_STA_FSM_STATE_NB);
+ /* Do not call leave/enter callbacks if staying in the same state. */
+ if (from != to)
+ {
+ CP_TRACE (MULTI_STA_FSM_CHANGE_STATE, from, to);
+ if (cp_eoc_multi_sta_fsm_leave_table[from])
+ cp_eoc_multi_sta_fsm_leave_table[from] (ctx, sta);
+ sta->fsm.state = to;
+ if (cp_eoc_multi_sta_fsm_enter_table[to])
+ cp_eoc_multi_sta_fsm_enter_table[to] (ctx, sta);
+ }
+}
+
+
+/**
+ * Handle event for one active state.
+ * \param ctx control plane context
+ * \param e event to handle
+ * \param sta active station
+ */
+
+void
+cp_eoc_multi_sta_fsm_handled_event (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *e)
+{
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (e);
+ dbg_assert_ptr (sta);
+
+ cp_eoc_multi_sta_fsm_transition_t t =
+ cp_eoc_multi_sta_fsm_transition_table[sta->fsm.state][e->type];
+ if (t)
+ {
+ /* Transition with action. */
+ sta->fsm.handled_event = e;
+ e->handler (ctx, sta, e, t);
+
+ /* If state has not been set, this means that there is one and
+ * only one branch for this transition. Check this and change
+ * state. */
+ if (sta->fsm.handled_event)
+ {
+ cp_eoc_multi_sta_fsm_state_t to =
+ cp_eoc_multi_sta_fsm_only_branch_table
+ [sta->fsm.state][e->type];
+ dbg_assert_print (to != CP_EOC_MULTI_STA_FSM_STATE_NB,
+ "no branch selected");
+ dbg_assert (to < CP_EOC_MULTI_STA_FSM_STATE_NB);
+ if (to != CP_EOC_MULTI_STA_FSM_STATE_NB)
+ /* Be clement for errors.*/
+ cp_eoc_multi_sta_fsm_leave_enter (ctx, sta, to);
+ sta->fsm.handled_event = NULL;
+ }
+ }
+ else
+ {
+ /* Transition without action. */
+ cp_eoc_multi_sta_fsm_state_t to =
+ cp_eoc_multi_sta_fsm_only_branch_table
+ [sta->fsm.state][e->type];
+ if (to != CP_EOC_MULTI_STA_FSM_STATE_NB)
+ {
+ dbg_assert (to < CP_EOC_MULTI_STA_FSM_STATE_NB);
+ cp_eoc_multi_sta_fsm_leave_enter (ctx, sta, to);
+ sta->fsm.handled_event = NULL;
+ }
+ }
+}
+
+/**
+ * Select a branch during a transition.
+ * \param ctx control plane context
+ * \param branch branch to select
+ * \param sta active station
+ *
+ * The selected branch must correspond to the current handled transition.
+ *
+ */
+
+void
+cp_eoc_multi_sta_fsm_branch_ (cp_t *ctx, cp_eoc_multi_sta_fsm_branch_t branch,
+cp_sta_t *sta)
+{
+
+ dbg_assert_ptr (ctx);
+ dbg_assert_ptr (sta);
+ /* Check handled transition. */
+ dbg_assert (sta->fsm.state < CP_EOC_MULTI_STA_FSM_STATE_NB);
+ dbg_assert_print (sta->fsm.handled_event,
+ "not in transition or duplicated branch");
+ /* Check there is actually several branches. */
+ dbg_assert_print
+ (cp_eoc_multi_sta_fsm_only_branch_table[sta->fsm.state]
+ [sta->fsm.handled_event->type] ==
+ CP_EOC_MULTI_STA_FSM_STATE_NB,
+ "no branch");
+ /* Check this correspond to the current transition. */
+ cp_eoc_multi_sta_fsm_state_t state = ((uint) branch >> 16) & 0xff;
+ cp_eoc_multi_sta_fsm_event_type_t event_type = ((uint) branch >> 8) &
+0xff;
+ dbg_assert_print (state == sta->fsm.state
+ && event_type == sta->fsm.handled_event->type,
+ "bad branch");
+ /* Select this branch. */
+ cp_eoc_multi_sta_fsm_state_t to = ((uint) branch) & 0xff;
+ cp_eoc_multi_sta_fsm_leave_enter (ctx, sta, to);
+ sta->fsm.handled_event = NULL;
+}
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.conf b/cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.conf
new file mode 100644
index 0000000000..2c50e8d998
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.conf
@@ -0,0 +1,6 @@
+[user]
+template-dir = .
+
+[templates]
+template_defs.h = %_defs.h
+template_tables.h = %_tables.h
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm b/cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm
new file mode 100644
index 0000000000..93a5d43efd
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm
@@ -0,0 +1,45 @@
+Multi STA FSM
+ FSM for slave stations
+
+States:
+ disconnected
+ unassociated
+ associated
+ authenticated
+ sleep_authenticated
+
+Events:
+ CC_ASSOC_REQ
+ timeout_assoc
+ CC_GET_KEY_REQ
+ timeout_auth
+ cc_leave
+ CC_SLEEP_ENTER_REQ
+ lost_connection
+ CC_SLEEP_EXIT_IND
+
+
+disconnected:
+ CC_ASSOC_REQ: sta_in_wl -> associated [cp_eoc_multi_sta_action__assoc_req]
+ CC_ASSOC_REQ: sta_not_in_wl -> unassociated
+
+unassociated:
+ CC_ASSOC_REQ: sta_in_wl -> associated [cp_eoc_multi_sta_action__assoc_req]
+ CC_ASSOC_REQ: sta_not_in_wl -> unassociated
+ timeout_assoc -> disconnected
+
+associated:
+ CC_GET_KEY_REQ: all_keys_granted -> authenticated[cp_eoc_multi_sta_action__get_key_req]
+ CC_GET_KEY_REQ: more_to_grant -> .
+ timeout_auth -> disconnected
+ cc_leave -> disconnected
+
+authenticated:
+ CC_GET_KEY_REQ -> . [cp_eoc_multi_sta_action__get_key_req]
+ CC_SLEEP_ENTER_REQ -> sleep_authenticated
+ cc_leave -> disconnected
+ lost_connection -> disconnected
+
+sleep_authenticated:
+ CC_SLEEP_EXIT_IND -> authenticated
+ lost_connection -> disconnected
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/fsm/template_defs.h b/cesar/cp/eoc/multi_sta_fsm/src/fsm/template_defs.h
new file mode 100644
index 0000000000..224552483b
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/fsm/template_defs.h
@@ -0,0 +1,53 @@
+#ifndef %(prefix)s_defs_h
+#define %(prefix)s_defs_h
+/*
+ * THIS IS AN AUTOMATICALLY GENERATED FILE, DO NOT EDIT!
+ *
+ * %(name)s
+ *
+%(*comments)s */
+
+/* %(name)s states. */
+enum %(prefix)s_state_t
+{
+%(states)s %(PREFIX)s_STATE_NB
+};
+typedef enum %(prefix)s_state_t %(prefix)s_state_t;
+
+/* %(name)s events types. */
+enum %(prefix)s_event_type_t
+{
+%(events,%(PREFIX)s_EVENT_TYPE_%(event)s)s %(PREFIX)s_EVENT_TYPE_NB
+};
+typedef enum %(prefix)s_event_type_t %(prefix)s_event_type_t;
+
+/* This macro enables checks for branches used in the wrong state/event
+ * combination. */
+#define _BRANCH(state, event, to) \
+ ((%(PREFIX)s_STATE_ ## state) << 16 \
+ | (%(PREFIX)s_EVENT_TYPE_ ## event) << 8 \
+ | (%(PREFIX)s_STATE_ ## to))
+
+/* %(name)s branches. */
+enum %(prefix)s_branch_t
+{
+%(branches)s};
+typedef enum %(prefix)s_branch_t %(prefix)s_branch_t;
+
+#undef _BRANCH
+
+/* %(name)s transition type. */
+typedef void *%(prefix)s_transition_t;
+
+/* %(name)s enter/leave type. */
+struct cp_sta_t;
+typedef void (*%(prefix)s_enter_leave_t) (cp_t *ctx, struct cp_sta_t *sta);
+
+/* Value to use to follow a given branch. */
+#define %(PREFIX)s_BRANCH(state, event, branch) \
+ %(PREFIX)s_BRANCH__ ## state ## __ ## event ## __ ## branch
+
+/* %(name)s number of initial states. */
+#define %(PREFIX)s_INITIAL_NB %(initials_nb)s
+
+#endif /* %(prefix)s_defs_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/fsm/template_tables.h b/cesar/cp/eoc/multi_sta_fsm/src/fsm/template_tables.h
new file mode 100644
index 0000000000..c13300cd28
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/fsm/template_tables.h
@@ -0,0 +1,46 @@
+/*
+ * THIS IS AN AUTOMATICALLY GENERATED FILE, DO NOT EDIT!
+ *
+ * %(name)s
+ *
+%(*comments)s */
+
+/* %(name)s transition table. */
+const %(prefix)s_transition_t
+%(prefix)s_transition_table[%(PREFIX)s_STATE_NB][%(PREFIX)s_EVENT_TYPE_NB] = {
+%(transition_table)s};
+
+/* %(name)s only branch table. */
+const %(prefix)s_state_t
+%(prefix)s_only_branch_table[%(PREFIX)s_STATE_NB][%(PREFIX)s_EVENT_TYPE_NB] = {
+%(only_branch_table)s};
+
+/* %(name)s state enter table. */
+const %(prefix)s_enter_leave_t
+%(prefix)s_enter_table[%(PREFIX)s_STATE_NB] = {
+%(states,%(@enter|NULL)s)s};
+
+/* %(name)s state leave table. */
+const %(prefix)s_enter_leave_t
+%(prefix)s_leave_table[%(PREFIX)s_STATE_NB] = {
+%(states,%(@leave|NULL)s)s};
+
+/* %(name)s initial states table. */
+const %(prefix)s_state_t
+%(prefix)s_initials_table[%(PREFIX)s_INITIAL_NB] = {
+%(initials)s};
+
+#if CONFIG_TRACE
+
+/* %(name)s state names table. */
+const char *
+%(prefix)s_state_names_table[%(PREFIX)s_STATE_NB] = {
+%(states,"%(state)s")s};
+
+/* %(name)s event names table. */
+const char *
+%(prefix)s_event_names_table[%(PREFIX)s_EVENT_TYPE_NB] = {
+%(events,"%(event)s")s};
+
+#endif /* CONFIG_TRACE */
+
diff --git a/cesar/cp/eoc/multi_sta_fsm/src/tables.c b/cesar/cp/eoc/multi_sta_fsm/src/tables.c
new file mode 100644
index 0000000000..bdf257846b
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/src/tables.c
@@ -0,0 +1,25 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/src/tables.c
+ * \brief Multi STA FSM tables.
+ * \ingroup cp_eoc_multi_sta_fsm
+ */
+#include "common/std.h"
+
+#include "fsm.h"
+#include "inc/tables.h"
+
+#include "cp/sta/action/action.h"
+#include "cp/beacon/beacon.h"
+#include "cp/cco/action/cco_action.h"
+#include "ce/tx/tx.h"
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+
+/* Include generated tables. */
+#include "cp_eoc_multi_sta_fsm_tables.h"
diff --git a/cesar/cp/eoc/multi_sta_fsm/stub/Module b/cesar/cp/eoc/multi_sta_fsm/stub/Module
new file mode 100644
index 0000000000..eb71a07a82
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/stub/Module
@@ -0,0 +1,3 @@
+SOURCES := fsm_stub.c
+
+cp_multi_sta_fsm_MODULE_SOURCES := $(call default,cp_multi_sta_fsm_MODULE_SOURCES,)
diff --git a/cesar/cp/eoc/multi_sta_fsm/stub/src/fsm_stub.c b/cesar/cp/eoc/multi_sta_fsm/stub/src/fsm_stub.c
new file mode 100644
index 0000000000..1df1d57eb9
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/stub/src/fsm_stub.c
@@ -0,0 +1,69 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi_sta_fsm/stub/src/fsm_stub.c
+ * \brief Generic multi STA FSM stub.
+ * \ingroup stub
+ */
+#include "common/std.h"
+
+//#include "cp/eoc/multi_sta_fsm/inc/context.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/inc/tables.h"
+
+void
+cp_eoc_multi_sta_fsm_init (cp_t *ctx, cp_sta_t *sta) __attribute__ ((weak));
+void
+cp_eoc_multi_sta_fsm_init (cp_t *ctx, cp_sta_t *sta)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm_uninit (cp_t *ctx, cp_sta_t* sta) __attribute__ ((weak));
+void
+cp_eoc_multi_sta_fsm_uninit (cp_t *ctx, cp_sta_t* sta)
+{
+}
+
+void
+cp_fsm_process (cp_t *ctx) __attribute__ ((weak));
+void
+cp_fsm_process (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm_handled_event (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *e) __attribute__ ((weak));
+void
+cp_eoc_multi_sta_fsm_handled_event (cp_t *ctx, cp_sta_t *sta,
+ cp_eoc_multi_sta_fsm_event_t *e)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm_branch_ (cp_t *ctx, cp_eoc_multi_sta_fsm_branch_t branch,
+ cp_sta_t *sta) __attribute__ ((weak));
+void
+cp_eoc_multi_sta_fsm_branch_ (cp_t *ctx, cp_eoc_multi_sta_fsm_branch_t branch,
+ cp_sta_t *sta)
+{
+}
+
+void
+cp_eoc_multi_sta_fsm_event_new (cp_t *ctx,
+ cp_eoc_multi_sta_fsm_event_type_t type,
+ cp_eoc_multi_sta_fsm_event_t *event) __attribute__ ((weak));
+
+void
+cp_eoc_multi_sta_fsm_event_new (cp_t *ctx,
+ cp_eoc_multi_sta_fsm_event_type_t type,
+ cp_eoc_multi_sta_fsm_event_t *event)
+{
+}
+
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/Config b/cesar/cp/eoc/multi_sta_fsm/test/utest/Config
new file mode 100644
index 0000000000..0e03f6aec1
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/Config
@@ -0,0 +1,4 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/test/utest/src/utest.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/Makefile b/cesar/cp/eoc/multi_sta_fsm/test/utest/Makefile
new file mode 100644
index 0000000000..c18825d039
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/Makefile
@@ -0,0 +1,26 @@
+BASE = ../../../../..
+
+DEFS = -DSTA_CORE_UNIT_TEST=1
+
+INCLUDES = cp/eoc/multi_sta_fsm/test/utest cp/eoc/multi_sta_fsm/test/utest/override
+
+HOST_PROGRAMS = test_fsm
+test_fsm_SOURCES = test_fsm.c fsm_stub.c actions.c
+test_fsm_MODULES = lib lib/scenario mac/sar/stub cp/eoc/multi_sta_fsm mac/common cp/fsm\
+cp/sta/mgr cp/eoc/sta/mgr cp/sta/core/stub cl/stub cp/secu cp/secu/stub cp/cco/action/stub\
+cp/msg cp/cl_interf interface/stub cp/fsm/stub bsu/stub
+
+
+test_fsm_MODULES_CONFIG = cp/sta/mgr #cp/msg
+test_fsm_MODULES_CONFIG = cp cl mac/sar
+cp_msg_MODULE_SOURCES = msg.c mme.c msg_cc.c
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_eoc_sta_mgr_MODULE_SOURCES = sta_mgr.c sta_own_data.c
+cp_eoc_multi_sta_fsm_MODULE_SOURCES = fsm.c events.c
+cp_fsm_MODULE_SOURCES = events.c
+cp_fsm_stub_MODULE_SOURCES = fsm_stub.c
+cp_MODULE_MODULES =
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
+
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/inc/scenario_defs.h b/cesar/cp/eoc/multi_sta_fsm/test/utest/inc/scenario_defs.h
new file mode 100644
index 0000000000..73cb6431d6
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/inc/scenario_defs.h
@@ -0,0 +1,107 @@
+#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/eoc/multi_sta_fsm/fsm.h"
+
+/* Scenario globals. */
+#define SCENARIO_DEFS_GLOBALS \
+ cp_t *cp;
+
+/* Scenario actions. */
+#define SCENARIO_DEFS_ACTIONS \
+ process
+
+typedef struct
+{
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ cp_mme_rx_t *mme;
+ cp_sta_t *sta;
+} scenario_action_param_t;
+
+typedef scenario_action_param_t scenario_action_process_t;
+
+void scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+
+#define SCENARIO_DEFS_EVENTS \
+ cp_eoc_multi_sta_fsm__STATE1__enter, \
+ cp_eoc_multi_sta_fsm__STATE1__event1, \
+ cp_eoc_multi_sta_fsm__STATE2__event2, \
+ cp_eoc_multi_sta_fsm__STATE3__event1, \
+ cp_eoc_multi_sta_fsm__STATE3__event2, \
+ cp_eoc_multi_sta_fsm__STATE4__event1, \
+ cp_eoc_multi_sta_fsm__STATE4__event4, \
+ cp_eoc_multi_sta_fsm__STATE5__event1, \
+ cp_eoc_multi_sta_fsm__STATE5__event5, \
+ cp_eoc_multi_sta_fsm__STATE6__event1, \
+ cp_eoc_multi_sta_fsm__STATE6__event6, \
+ cp_eoc_multi_sta_fsm__STATE6__enter, \
+ cp_eoc_multi_sta_fsm__STATE6__leave
+
+typedef struct
+{
+ cp_mme_rx_t *mme;
+ cp_sta_t *sta;
+ cp_eoc_multi_sta_fsm_branch_t branch;
+} scenario_event_transition_with_branch_t;
+
+typedef struct
+{
+ cp_mme_rx_t *mme;
+ cp_sta_t *sta;
+} scenario_event_transition_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE1__enter_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE1__event1_t;
+
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE2__event2_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE3__event1_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE3__event2_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE4__event1_t;
+
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE4__event4_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE5__event1_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE5__event5_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE6__event1_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE6__event6_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE6__enter_t;
+
+typedef scenario_event_transition_t
+scenario_event_cp_eoc_multi_sta_fsm__STATE6__leave_t;
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/inc/context.h b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/inc/context.h
new file mode 100644
index 0000000000..99c0c3e6c8
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/inc/context.h
@@ -0,0 +1,66 @@
+#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/multi_sta_fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/inc/context.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 "mac/sar/inc/sar_context.h"
+#include "cp/inc/trace.h"
+#include "cp/msg/inc/context.h"
+#include "lib/rnd.h"
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+#include "cp/cl_interf/cl_interf.h"
+#include "cp/cl_interf/inc/context.h"
+#include "interface/interface.h"
+#include "cl/cl.h"
+
+
+struct cp_t
+{
+
+ /** FSM context. */
+ cp_fsm_t fsm;
+
+ cp_sta_mgr_t sta_mgr;
+ /** Mac store /dataplane */
+ mac_store_t *mac_store;
+
+ /** MAC config contest*/
+ mac_config_t *mac_config;
+
+ cl_t *cl;
+ /** Segmentation and reassembly context */
+ sar_t *sar;
+
+ cp_msg_t msg;
+
+ lib_rnd_t rnd;
+
+ cp_cl_interf_t cl_interf;
+
+ interface_t *interface;
+
+ /** BSU context. */
+ bsu_t *bsu;
+
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/core.h b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/core.h
new file mode 100644
index 0000000000..2bd5fa51cd
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/core.h
@@ -0,0 +1,28 @@
+#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);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/defs.h b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..e9871e09e2
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/cp/sta/core/defs.h
@@ -0,0 +1,58 @@
+#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/multi_sta_fsm/test/utest/override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..22437397b9
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/override/mac/sar/inc/sar_context.h
@@ -0,0 +1,39 @@
+#ifndef override_mac_sar_inc_sar_context_h
+#define override_mac_sar_inc_sar_context_h
+
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /*override_mac_sar_inc_sar_context_h*/
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/src/actions.c b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/actions.c
new file mode 100644
index 0000000000..9114b993d1
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/actions.c
@@ -0,0 +1,37 @@
+/* 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/multi_sta_fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/inc/events.h"
+
+
+static cp_eoc_multi_sta_fsm_event_t event;
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ scenario_action_process_t *p = (scenario_action_process_t*) params;
+
+ cp_eoc_multi_sta_fsm_event_mme_t e;
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ type = p->type;
+ e.event.type = type;
+ e.event.handler = cp_eoc_multi_sta_fsm_event_handler;
+ e.mme = p->mme;
+ cp_eoc_multi_sta_fsm_handled_event (globals->cp, p->sta, &(e.event));
+}
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/src/fsm_stub.c b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/fsm_stub.c
new file mode 100644
index 0000000000..9a8f2e5658
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/fsm_stub.c
@@ -0,0 +1,185 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/fsm_stub.c
+ * \brief Override Multi STA FSM tables.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/eoc/multi_sta_fsm/inc/tables.h"
+
+int cp_fsm__STATE1__enter_nb;
+
+extern cp_sta_t *
+cp_sta_mgr_sta_get_from_mac (cp_t *ctx, mac_t mac_addr);
+
+void
+cp_eoc_multi_sta_fsm__STATE1__enter (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE1__event1 (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE2__event2 (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_multi_sta_fsm__STATE2__event2 (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_multi_sta_fsm__STATE3__event1 (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE3__event2 (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE4__event1 (cp_t *ctx);
+void
+cp_eoc_multi_sta_fsm__STATE4__event4 (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE5__event1 (cp_t *ctx);
+void
+cp_eoc_multi_sta_fsm__STATE5__event5 (cp_t *ctx);
+void
+cp_eoc_multi_sta_fsm__STATE6__event1 (cp_t *ctx);
+void
+cp_eoc_multi_sta_fsm__STATE6__event6 (cp_t *ctx);
+void
+cp_eoc_multi_sta_fsm__STATE1__error_event_no_branch (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE1__error_event_bad_branch (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE1__error_event_dup_branch (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE6__enter (cp_t *ctx, cp_mme_rx_t *mme);
+void
+cp_eoc_multi_sta_fsm__STATE6__leave (cp_t *ctx, cp_mme_rx_t *mme);
+
+/* Include generated tables. */
+#include "cp_eoc_multi_sta_fsm_tables.h"
+
+void
+cp_eoc_multi_sta_fsm__STATE1__enter (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_fsm__STATE1__enter_nb++;
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE1__event1 (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE1__event1);
+}
+
+
+void
+cp_eoc_multi_sta_fsm__STATE2__event2 (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE2__event2, param);
+ test_fail_unless(mme == param->mme);
+ cp_sta_t *sta;
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+ cp_eoc_multi_sta_fsm_branch_ (ctx, param->branch, sta);
+}
+
+
+
+
+void
+cp_eoc_multi_sta_fsm__STATE3__event1 (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE3__event1);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE3__event2 (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE3__event2);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE4__event1 (cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE4__event1);
+}
+
+
+void
+cp_eoc_multi_sta_fsm__STATE4__event4 (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE4__event4, param);
+ cp_sta_t *sta;
+ test_fail_unless(mme == param->mme);
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+ cp_eoc_multi_sta_fsm_branch_ (ctx, param->branch, sta);
+}
+
+
+
+void
+cp_eoc_multi_sta_fsm__STATE5__event1 (cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE5__event1);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE5__event5 (cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE5__event5);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE6__event1 (cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE6__event1);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE6__event6 (cp_t *ctx)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE6__event6);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE1__error_event_no_branch (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ /* Do not choose branch. */
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE1__error_event_bad_branch (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+ cp_sta_t *sta;
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+ cp_eoc_multi_sta_fsm_branch (ctx, STATE4, event4, branch1, sta);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE1__error_event_dup_branch (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+ cp_sta_t *sta;
+ sta = cp_sta_mgr_sta_get_from_mac(ctx, mme->peer.mac);
+ cp_eoc_multi_sta_fsm_branch (ctx, STATE1, error_event_dup_branch,
+ branch1, sta);
+ cp_eoc_multi_sta_fsm_branch (ctx, STATE1, error_event_dup_branch,
+ branch2, sta);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE6__enter (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE6__enter);
+}
+
+void
+cp_eoc_multi_sta_fsm__STATE6__leave (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_eoc_multi_sta_fsm__STATE6__leave);
+}
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/src/test_fsm.c b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/test_fsm.c
new file mode 100644
index 0000000000..c408ce15e0
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/test_fsm.c
@@ -0,0 +1,287 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_fsm.c
+ * \brief Test Multi STA FSM module.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/blk.h"
+#include "lib/test.h"
+#include "lib/scenario/scenario.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "cp/sta/mgr/sta_mgr.h"
+
+#include "config/trace.h"
+#include "cp/eoc/multi_sta_fsm/fsm.h"
+#include "cp/inc/context.h"
+
+
+extern int cp_fsm__STATE1__enter_nb;
+
+void
+test_fsm_basic_test_case (test_t t)
+{
+ test_case_begin (t, "basic");
+ cp_t ctx;
+ cp_trace_init (&ctx);
+ cp_net_t *net;
+ cp_tei_t tei = 5;
+ uint cl;
+
+ sar_t sar;
+ ctx.sar = &sar;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp_sta_t *sta;
+ mac_config_t mac_config;
+
+ ctx.mac_config = &mac_config;
+ ctx.cl = (cl_t *) &cl;
+ ctx.mac_store = mac_store_init ();
+
+ cp_sta_mgr_init (&ctx);
+
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1); // snid = 1, nid = 1
+ cp_sta_mgr_set_our_avln (&ctx, net);
+ mme->peer.mac = 2;
+ mme->peer.tei = 0;
+ sta = cp_sta_mgr_sta_add (&ctx, net, tei, mme->peer.mac);
+
+ test_begin (t, "regular")
+ {
+ cp_fsm__STATE1__enter_nb = 0;
+ cp_eoc_multi_sta_fsm_init(&ctx, sta);
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE1__event1,
+ .sta = sta,
+ .mme = mme),
+ /* STATE2 */
+ SCENARIO_ACTION (process,
+ .sta = sta,
+ .mme = mme,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event2),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE2__event2,
+ .mme = mme,
+ .sta = sta,
+ .branch =
+ CP_EOC_MULTI_STA_FSM_BRANCH(STATE2, event2, branch1)),
+ /* STATE3*/
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event3),
+ /*no SCENARIO_EVENT */
+ /* STATE4 */
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event4),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE4__event4,
+ .mme = mme,
+ .sta = sta,
+ .branch =
+ CP_EOC_MULTI_STA_FSM_BRANCH(STATE4, event4, branch4)),
+ /* STATE4 */
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event4),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE4__event4,
+ .mme = mme,
+ .sta = sta,
+ .branch =
+ CP_EOC_MULTI_STA_FSM_BRANCH(STATE4, event4, branch1)),
+ /* STATE5*/
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event5),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE5__event5,
+ .mme = mme,
+ .sta=sta),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE6__enter,
+ .mme = mme,
+ .sta=sta),
+ /* STATE6 */
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event6),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE6__event6,
+ .mme = mme,
+ .sta=sta),
+ /* STATE6 */
+ SCENARIO_ACTION (process,
+ .mme = mme,
+ .sta = sta,
+ .type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE6__event1,
+ .mme = mme,
+ .sta=sta),
+ SCENARIO_EVENT (cp_eoc_multi_sta_fsm__STATE6__leave,
+ .mme = mme,
+ .sta=sta),
+ /* STATE1 */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &ctx,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (sta->fsm.state ==
+ CP_EOC_MULTI_STA_FSM_STATE_STATE1);
+ test_fail_unless (cp_fsm__STATE1__enter_nb == 2);
+ cp_eoc_multi_sta_fsm_uninit (&ctx, sta);
+
+ } test_end;
+ cp_sta_mgr_uninit (&ctx);
+ slab_release (sta);
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+void
+test_fsm_error_test_case (test_t t)
+{
+ test_case_begin (t, "error");
+ cp_t cp;
+ cp_trace_init (&cp);
+ cp_net_t *net;
+ cp_tei_t tei = 5;
+ uint cl;
+
+ cp_sta_t *sta;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ cp.cl = (cl_t *) &cl;
+ cp.mac_store = mac_store_init ();
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+ mme->peer.mac = 2;
+ mme->peer.tei = 0;
+ sta = cp_sta_mgr_sta_add (&cp, net, tei, mme->peer.mac);
+
+ test_begin (t, "no branch")
+ {
+ cp_eoc_multi_sta_fsm_init (&cp, sta);
+
+ cp_eoc_multi_sta_fsm_event_mme_t e;
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_error_event_no_branch;
+ e.event.type = type;
+ e.event.handler = cp_eoc_multi_sta_fsm_event_handler;
+ e.mme = mme;
+
+
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_eoc_multi_sta_fsm_handled_event (&cp, sta, &(e.event));
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ cp_eoc_multi_sta_fsm_uninit (&cp, sta);
+ } test_end;
+ test_begin (t, "bad branch")
+ {
+ cp_eoc_multi_sta_fsm_init (&cp, sta);
+
+ cp_eoc_multi_sta_fsm_event_mme_t e;
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_error_event_bad_branch;
+ e.event.type = type;
+ e.event.handler = cp_eoc_multi_sta_fsm_event_handler;
+ e.mme = mme;
+
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_eoc_multi_sta_fsm_handled_event (&cp, sta, &(e.event));
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ cp_eoc_multi_sta_fsm_uninit (&cp, sta);
+ } test_end;
+ test_begin (t, "dup branch")
+ {
+ cp_eoc_multi_sta_fsm_init (&cp, sta);
+
+ cp_eoc_multi_sta_fsm_event_mme_t e;
+ cp_eoc_multi_sta_fsm_event_type_t type;
+ type = CP_EOC_MULTI_STA_FSM_EVENT_TYPE_error_event_dup_branch;
+ e.event.type = type;
+ e.event.handler = cp_eoc_multi_sta_fsm_event_handler;
+ e.mme = mme;
+
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_eoc_multi_sta_fsm_handled_event (&cp, sta, &(e.event));
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ cp_eoc_multi_sta_fsm_uninit (&cp, sta);
+ } test_end;
+
+ cp_sta_mgr_uninit (&cp);
+ slab_release (sta);
+
+#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, "fsm");
+ test_fsm_basic_test_case (t);
+ test_fsm_error_test_case (t);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ lib_stats_init();
+ trace_init ();
+ test_init (t, argc, argv);
+ test_fsm_test_suite (t);
+ trace_uninit ();
+ lib_stats_uninit();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/multi_sta_fsm/test/utest/src/utest.fsm b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/utest.fsm
new file mode 100644
index 0000000000..fc03163b41
--- /dev/null
+++ b/cesar/cp/eoc/multi_sta_fsm/test/utest/src/utest.fsm
@@ -0,0 +1,53 @@
+Slave STA FSM
+ FSM for slave stations
+
+States:
+ STATE1 [enter=cp_eoc_multi_sta_fsm__STATE1__enter]
+ STATE2
+ STATE3
+ STATE4
+ STATE5
+ STATE6 [enter=cp_eoc_multi_sta_fsm__STATE6__enter leave=cp_eoc_multi_sta_fsm__STATE6__leave]
+
+Events:
+ CC_ASSOC_REQ
+ event1
+ event2
+ event3
+ event4
+ event5
+ event6
+ error_event_no_branch
+ test error conditions: no branch selected
+ error_event_bad_branch
+ test error conditions: branch not for this event
+ error_event_dup_branch
+ test error conditions: branch selected two times
+
+STATE1:
+ event1 -> STATE2
+ error_event_no_branch: branch1 -> .
+ error_event_no_branch: branch2 -> .
+ error_event_bad_branch: branch1 -> .
+ error_event_bad_branch: branch2 -> .
+ error_event_dup_branch: branch1 -> .
+ error_event_dup_branch: branch2 -> .
+STATE2:
+ event2: branch1 -> STATE3
+ event2: branch2 -> STATE1
+STATE3:
+ event1 -> STATE1
+ event3 -> STATE4 [NULL]
+ event2 -> STATE2
+STATE4:
+ event1 -> STATE1
+ event4: branch1 -> STATE5
+ event4: branch2 -> STATE2
+ event4: branch3 -> STATE3
+ event4: branch4 -> STATE4
+STATE5:
+ event1 -> STATE1
+ event5 -> STATE6
+STATE6:
+ event1 -> STATE1
+ event6 -> .
diff --git a/cesar/cp/eoc/sta/action/Config b/cesar/cp/eoc/sta/action/Config
new file mode 100644
index 0000000000..28cb71ccf5
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/Config
@@ -0,0 +1 @@
+CONFIG_CP_EOC_STA_CON_ALLOWED = n \ No newline at end of file
diff --git a/cesar/cp/eoc/sta/action/Module b/cesar/cp/eoc/sta/action/Module
new file mode 100644
index 0000000000..b3c3b71307
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/Module
@@ -0,0 +1 @@
+SOURCES := action.c assoc.c sleep.c poweron.c drv.c cco_stub.c vs_eoc.c
diff --git a/cesar/cp/eoc/sta/action/action.h b/cesar/cp/eoc/sta/action/action.h
new file mode 100644
index 0000000000..4ef4e81c99
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/action.h
@@ -0,0 +1,119 @@
+#ifndef cp_eoc_sta_action_action_h
+#define cp_eoc_sta_action_action_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/cco/cco_action.h
+ * \brief CCo Public functions.
+ * \ingroup cp_eoc_cco
+ *
+ */
+#include "cp/inc/context.h"
+
+#include "cp/eoc/sta/action/sleep.h"
+#include "cp/eoc/sta/action/assoc.h"
+#include "cp/eoc/sta/action/poweron.h"
+#include "cp/eoc/sta/action/drv.h"
+#include "cp/eoc/sta/action/bridge.h"
+#include "cp/eoc/sta/action/vs_eoc.h"
+#include "cp/sta/action/vs.h"
+
+
+void
+cp_eoc_sta_action_sta_clear_status (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__detecting_detected (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__detecting_timeout (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_eoc_sta_action_assoc__associating_timeout (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+
+void
+cp_eoc_sta_action_assoc__associating_no_beacons (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__unassociated_retry (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__associated_key_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+
+void
+cp_eoc_sta_action_auth__authenticated_key_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+
+void
+cp_eoc_sta_action_assoc__associated_no_beacons (cp_t *ctx);
+
+
+
+void
+cp_eoc_sta_action_assoc__associated_timeout (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__associated_leave (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_assoc__authenticated_leave (cp_t *ctx, cp_mme_rx_t *mme);
+
+
+
+void
+cp_eoc_sta_action_assoc__authenticated_no_beacons (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__beacon_not_received (cp_t *ctx);
+
+
+void
+cp_sta_action_assoc__start_retry_timer (cp_t *ctx);
+
+
+void
+cp_sta_action_assoc__stop_retry_timer (cp_t *ctx);
+
+
+void
+cp_sta_action_unassoc__start_retry_timer (cp_t *ctx);
+
+
+void
+cp_sta_action_unassoc__stop_retry_timer (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons (cp_t *ctx);
+
+
+void
+cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+#endif
diff --git a/cesar/cp/eoc/sta/action/assoc.h b/cesar/cp/eoc/sta/action/assoc.h
new file mode 100644
index 0000000000..64588b8fe2
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/assoc.h
@@ -0,0 +1,192 @@
+#ifndef cp_eoc_sta_action_assoc_h
+#define cp_eoc_sta_action_assoc_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/eoc/action/assoc.h
+ * \brief STA action, association related definitions.
+ * \ingroup cp_eoc_sta_action
+ *
+ * Association/authentication
+ * ==========================
+ *
+ * This part relates to association and authentication for a slave STA. A
+ * state machine is used to handle the association status of the station:
+ *
+ * \image html assoc.png "Association state machine"
+ *
+ */
+#include "cp/sta/mgr/net.h"
+
+BEGIN_DECLS
+
+/**
+ * Start a association procedure.
+ * \param ctx control plane context
+ *
+ * nd_beacon is detected, and association is triggered
+ */
+void
+cp_eoc_sta_action_assoc__detecting_detected (cp_t *ctx);
+
+/**
+ * Timeout occurred while station was in the detecting state.
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__detecting_timeout (cp_t *ctx);
+
+/**
+ * Timeout occurred while station was in associating state.
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__associating_timeout (cp_t *ctx);
+
+/**
+ * CC_ASSOC.CNF was received
+ * \param ctx control plane context
+ * \param mme received MME handle
+ */
+void
+cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * Several beacons was not detected while station was in asscoiating state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__associating_no_beacons (cp_t *ctx);
+
+/**
+ * Handle UNASSOCIATED => DETECTING transition
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__unassociated_retry (cp_t *ctx);
+
+/**
+ * GET_KEY.CNF was received
+ * \param ctx control plane context
+ * \param mme received MME handle
+ */
+void
+cp_eoc_sta_action_assoc__associated_key_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * GET_KEY.CNF was received for TEK_KEY (used to authenticate station)
+ * \param ctx control plane context
+ * \param mme received MME handle
+ */
+void
+cp_eoc_sta_action_auth__authenticated_key_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * CM_ENCRYPTED_PAYLOAD.RSP was received
+ * \param ctx control plane context
+ * \param mme received MME handle
+ *
+ */
+void
+cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+/**
+ * Several beacons was not detected while station was in asscoiated state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__associated_no_beacons (cp_t *ctx);
+
+/**
+ * Timeout during asscoiated state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__associated_timeout (cp_t *ctx);
+
+/**
+ * CC_LEAVE.IND was received while station in associated state
+ * \param ctx control plane context
+ * \param mme received MME handle
+ *
+ */
+void
+cp_eoc_sta_action_assoc__associated_leave (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * Several beacons was not detected while station was in authenticated
+ * state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__authenticated_no_beacons (cp_t *ctx);
+
+/**
+ * CC_LEAVE.IND was received while station in authenticated state
+ * \param ctx control plane context
+ * \param mme received MME handle
+ *
+ */
+void
+cp_eoc_sta_action_assoc__authenticated_leave (cp_t *ctx, cp_mme_rx_t *mme);
+
+/**
+ * Several beacons was not detected while station was in sleep
+ * authenticated state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+void
+cp_eoc_sta_action_detect__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_eoc_sta_action_auth__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_eoc_sta_action_assoc__beacon_not_received (cp_t *ctx);
+
+void
+cp_eoc_sta_action_sta_clear_status (cp_t *ctx);
+
+void
+cp_sta_action_unassoc__stop_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_unassoc__start_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_assoc__stop_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_assoc__start_retry_timer (cp_t *ctx);
+
+void
+cp_eoc_sta_action_auth__authenticated_set_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_auth__authenticated_set_out_lev (cp_t *ctx, cp_mme_rx_t *mme);
+
+END_DECLS
+
+#endif /* cp_eoc_sta_action_assoc_h */
diff --git a/cesar/cp/eoc/sta/action/bridge.h b/cesar/cp/eoc/sta/action/bridge.h
new file mode 100644
index 0000000000..3679caca4e
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/bridge.h
@@ -0,0 +1,32 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/bridge.h
+ * \brief STA action, bridge table related declarations.
+ * \ingroup cp_sta_action
+ *
+ * Bridge table request and reception implementations.
+ */
+//#include "common/std.h"
+
+#include "cp/mme.h" // cp_mme_rx_t
+#include "cp/msg/msg.h" // to include cp/msg/inc/msg_cm.h
+#include "cp/msg/inc/msg_cm.h" // cp_msg_cm_brg_info_cnf_receive_*
+#include "cp/sta/mgr/sta_mgr.h" // cp_sta_mgr_get_our_avln
+#include "cp/sta/mgr/sta.h" // cp_sta_get_peer
+#include "cp/sta/mgr/net.h" // cp_net_sta_get_*
+#include "cl/cl_mactotei.h" // cl_mactotei_*
+#include "cp/inc/context.h" // cp_t
+#include "cl/bridge_table.h" // bridge_table_*
+#include "lib/utils.h" // less_mod2p32
+#include "cp/sta/action/bridge.h"
+
+
+void
+cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta);
+
diff --git a/cesar/cp/eoc/sta/action/cco_action.h b/cesar/cp/eoc/sta/action/cco_action.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/cco_action.h
diff --git a/cesar/cp/eoc/sta/action/doc/Makefile b/cesar/cp/eoc/sta/action/doc/Makefile
new file mode 100644
index 0000000000..053351b0de
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/doc/Makefile
@@ -0,0 +1,48 @@
+PAGES = assoc
+GRAPHS = assoc
+
+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/sta/action/doc/assoc.sdl b/cesar/cp/eoc/sta/action/doc/assoc.sdl
new file mode 100644
index 0000000000..681e1b6672
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/doc/assoc.sdl
@@ -0,0 +1,41 @@
+((start)) -> (detecting_beacon)
+
+detecting_beacon:
+(detecting_beacon) -nd beacon -> (associating)
+(detecting_beacon) -nd beacon\n timeout -> (unassociated)
+
+associating:
+(associating) -associating\ntime out -> <:retry?> -y -> (detecting_beacon)
+ <:retry?> -n -> (unassociated)
+(associating) -CC_ASSOC.CNF -> <:result?> -success -> (associated)
+ <:result?> -unsuccess -> (unassociated)
+ <:result?> -unrelated -> (unassociated)
+(associating) -no beacons -> (unassociated)
+
+unassociated:
+(unassociated) -enter sleep_unassociated -> (sleep_unassociated)
+(unassociated) -retry -> (detecting_beacon)
+
+sleep_unassociated:
+(sleep_unassociated) -exit sleep -> (unassociated)
+
+associated:
+(associated) -CC_GET_KEY.CNF -> <:result=key granted> -y -> <:all keys granted?> -y -> (authenticated)
+ <:all keys granted?> -n -> (associated)
+ <:result=key granted> -n -> (unassociated)
+ <:result=key granted> -unrelated -> (unassociated)
+
+(associated) -CM_ENCRYPT_PAYLOAD.RSP -> (unassociated)
+(associated) -authenticating\ntimeout -> (unassociated)
+(associated) -no beacons -> (unassociated)
+(associated) -CC_LEAVE.IND -> (detecting_beacon)
+
+authenticated:
+(authenticated) -CC_SLEEP_ENTER.CNF -> (sleep_authenticated)
+(authenticated) -no beacons -> (unassociated)
+(authenticated) -CC_LEAVE.IND -> (detecting_beacon)
+
+sleep_authenticated:
+(sleep_authenticated) -CC_SLEEP_EXIT.RSP -> (authenticated)
+(sleep_authenticated) -no beacons -> (unassociated)
+
diff --git a/cesar/cp/eoc/sta/action/doc/cp_eoc_sta_action.odt b/cesar/cp/eoc/sta/action/doc/cp_eoc_sta_action.odt
new file mode 100644
index 0000000000..0a85ee703b
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/doc/cp_eoc_sta_action.odt
Binary files differ
diff --git a/cesar/cp/eoc/sta/action/drv.h b/cesar/cp/eoc/sta/action/drv.h
new file mode 100644
index 0000000000..8c73611016
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/drv.h
@@ -0,0 +1,84 @@
+#ifndef cp_eoc_sta_action_drv_h
+#define cp_eoc_sta_action_drv_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/eoc/action/drv.h
+ * \brief Driver messages
+ * \ingroup cp_eoc_sta_action
+ *
+ * Entering and exiting sleep states
+ * ==========================
+ *
+ * This part relates to entering and exiting STA sleep states
+ *
+ * \image html
+ *
+ */
+
+BEGIN_DECLS
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx);
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_get_status_ind(cp_t *ctx);
+
+END_DECLS
+
+#endif /* cp_eoc_sta_action_sleep_h */
diff --git a/cesar/cp/eoc/sta/action/misc.h b/cesar/cp/eoc/sta/action/misc.h
new file mode 100644
index 0000000000..1b47cca0a0
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/misc.h
@@ -0,0 +1,31 @@
+#ifndef cp_sta_action_misc_h
+#define cp_sta_action_misc_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/eoc/action/misc.h
+ * \brief STA action, miscellaneous definitions.
+ * \ingroup cp_sta_action
+ *
+ * Miscellaneous
+ * =============
+ *
+ * This part handle other miscellaneous STA function, most of theses are
+ * simple enough to be handled without any remembered state.
+ */
+
+BEGIN_DECLS
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+END_DECLS
+
+#endif /* cp_sta_action_misc_h */ \ No newline at end of file
diff --git a/cesar/cp/eoc/sta/action/poweron.h b/cesar/cp/eoc/sta/action/poweron.h
new file mode 100644
index 0000000000..e13548757b
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/poweron.h
@@ -0,0 +1,32 @@
+#ifndef cp_eoc_sta_action_poweron_h
+#define cp_eoc_sta_action_poweron_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/poweron.h
+ * \brief CCo Public functions.
+ * \ingroup cp_eoc_sta_action
+ *
+ */
+
+void
+cp_sta_action_poweron_start (cp_t *ctx);
+
+void
+cp_sta_action_poweron_stop (cp_t *ctx);
+
+void
+cp_sta_action_poweron__idle__to_poweron (cp_t *ctx);
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx);
+
+void
+cp_eoc_sta_action__power_on_no_beacons (cp_t *ctx);
+
+#endif
diff --git a/cesar/cp/eoc/sta/action/sleep.h b/cesar/cp/eoc/sta/action/sleep.h
new file mode 100644
index 0000000000..7682e16722
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/sleep.h
@@ -0,0 +1,60 @@
+#ifndef cp_eoc_sta_action_sleep_h
+#define cp_eoc_sta_action_sleep_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/eoc/action/sleep.h
+ * \brief Entering/exiting STA sleep states
+ * \ingroup cp_eoc_sta_action
+ *
+ * Entering and exiting sleep states
+ * ==========================
+ *
+ * This part relates to entering and exiting STA sleep states
+ *
+ * \image html
+ *
+ */
+
+BEGIN_DECLS
+
+/**
+ * Handle UNASSOCIATED => SLEEP_UNASSOCIATED state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_sleep__unassociated_enter_sleep (cp_t *ctx);
+
+/**
+ * Handle SLEEP_UNASSOCIATED => UNASSOCIATED state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_sleep__sleep_unassociated_exit_sleep (cp_t *ctx);
+
+/**
+ * Handle AUTHENTICATED => SLEEP_AUTHENTICATED state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_sleep__authenticated_sleep_enter (cp_t *ctx);
+
+/**
+ * Handle SLEEP_AUTHENTICATED => AUTHENTICATED state
+ * \param ctx control plane context
+ *
+ */
+void
+cp_eoc_sta_action_sleep__sleep_authenticated_exit (cp_t *ctx);
+
+END_DECLS
+
+#endif /* cp_eoc_sta_action_sleep_h */
diff --git a/cesar/cp/eoc/sta/action/src/action.c b/cesar/cp/eoc/sta/action/src/action.c
new file mode 100644
index 0000000000..54cd85aa64
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/action.c
@@ -0,0 +1,37 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/action/src/action.c
+ * \brief STA action.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+#include "cp/inc/context.h" // cp_t
+#include "cp/sta/action/bridge.h"
+#include "cp/av/cco/bw/bw.h"
+#include "ce/tx/tx.h"
+
+void
+cp_sta_action_init (cp_t *ctx)
+{
+ cp_sta_action_assoc_init (ctx);
+ /* Initialize the STA action bridge module. */
+ cp_sta_action_bridge_init (ctx);
+}
+
+void
+cp_sta_action_garbage (cp_t *ctx)
+{
+ /* Update tone map list for CE in TX. */
+ ce_tx_update_tone_map (ctx);
+ /* Update local bridge table. */
+ cp_sta_action_update_bridge_table (ctx);
+}
+
diff --git a/cesar/cp/eoc/sta/action/src/assoc.c b/cesar/cp/eoc/sta/action/src/assoc.c
new file mode 100644
index 0000000000..7d05a0c304
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/assoc.c
@@ -0,0 +1,686 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/src/assoc.c
+ * \brief STA action, association related definitions.
+ * \ingroup cp_eoc_sta_action
+ */
+#include "common/std.h"
+#include <stdio.h>
+#include "cp/sta/action/action.h"
+
+#include "cp/inc/context.h"
+#include "cp/fsm/fsm.h"
+#include "cp/msg/msg.h"
+#include "cp/beacon/beacon.h"
+#include "mac/sar/sar.h"
+#include "mac/sar/inc/sar_context.h"
+#include "mac/pbproc/inc/context.h"
+#include "mac/common/ntb.h"
+#include "hal/gpio/gpio.h"
+#include "cp/eoc/inc/dbg_print.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "cp/eoc/sta/action/drv.h"
+#include "cp/msg/inc/msg_vs_eoc.h"
+#include "config/cp/eoc/sta/con/allowed.h"
+
+#define UNASSOC_RETRY_TIMEOUT_MS 15*1000
+#define RETRY_TIMEOUT_MS 1200
+#define LEAVING_TIMEOUT_MS (40 * 3)
+#define LEAVE_WAIT_TIMEOUT_MS 1000
+#define CP_EOC_NUM_RETRY 3
+#define CP_EOC_NOT_POLLED_NB 20
+#define CP_EOC_BEACON_RECEIVE_STABLE 10
+#define CP_EOC_BEACON_1S_NB 10
+#define CP_EOC_BEACON_FIRST_OFFSET_NB 50
+#define CP_EOC_ASSOC_REQ_RETRY_LIMIT 10
+
+#define CP_EOC_STA_ASSOC_REQ_OFFSET CP_EOC_BEACON_FIRST_OFFSET_NB \
+ + ((ctx->mac_config->sta_mac_address >> 40) & 0x1F)
+/* Clear status of one station */
+void
+cp_eoc_sta_action_sta_clear_status (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_sta_own_data_set_authenticated_status (ctx, false);
+ cp_sta_own_data_set_tei (ctx, MAC_TEI_UNASSOCIATED);
+ ctx->sta_action.assoc.retry = 0;
+ ctx->sta_action.assoc.beacon_loss = 0;
+ ctx->sta_action.assoc.beacon_succ = 0;
+ ctx->sta_action.assoc.init_count = CP_EOC_STA_ASSOC_REQ_OFFSET;
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (ctx);
+ cp_net_t * net = cp_sta_mgr_get_our_avln (ctx);
+
+ cp_sta_t * sta = NULL;
+ if (own_data->tei_track != MAC_TEI_UNASSOCIATED)
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, own_data->tei_track);
+ if (sta)
+ {
+ ctx->sta_mgr.sta_own_data.state = CP_EOC_STA_STATE_UNASSOCIATED;
+ cp_sta_action_drv__drv_sta_get_status_ind(ctx);
+
+ cp_sta_set_authenticated (ctx, sta, false);
+ cp_sta_mgr_sta_remove (ctx, sta);
+ slab_release (sta);
+ }
+ own_data->tei_track = MAC_TEI_UNASSOCIATED;
+ own_data->cco_mac_addr_track = MAC_ZERO;
+ bsu_untrack_avln (ctx->bsu);
+ cp_eoc_cco_bw_sta_allocations (ctx);
+ dbg_assert (ctx->sta_action.assoc.assoc_req_retry_nb
+ < CP_EOC_ASSOC_REQ_RETRY_LIMIT);
+}
+
+void
+cp_eoc_sta_action_assoc__detecting_detected (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ /* Send association request. */
+ cp_msg_cc_assoc_req_t data = {
+ CP_MSG_CC_ASSOC_REQ_TYPE_NEW,
+ cp_sta_own_data_get_nid (ctx),
+ CP_CCO_LEVEL,
+ CP_PCO_CAP
+ };
+ cp_msg_cc_assoc_req_send (ctx, &ctx->sta_action.assoc.peer, &data);
+ /* Increase global number of assoc request */
+ ctx->sta_action.assoc.assoc_req_retry_nb ++;
+}
+
+void
+cp_eoc_sta_action_assoc__detecting_timeout (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_fsm_trigger_new_event (ctx, bare, nd_beacon_timeout);
+}
+
+void
+cp_eoc_sta_action_detect__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ dbg_assert (ctx);
+ dbg_assert (beacon);
+ dbg_assert (net);
+ dbg_assert (sta);
+
+ cp_nid_t our_nid = cp_sta_own_data_get_nid (ctx);
+ cp_nid_t its_nid = cp_net_get_nid (ctx, net);
+ ctx->sta_action.assoc.beacon_loss = 0;
+ if (ctx->sta_action.assoc.beacon_succ < CP_EOC_BEACON_RECEIVE_STABLE)
+ ctx->sta_action.assoc.beacon_succ++;
+ if (ctx->sta_action.assoc.init_count > 0)
+ ctx->sta_action.assoc.init_count--;
+
+ if (ctx->sta_action.assoc.init_count <= 0)
+ {
+ if (its_nid == our_nid)
+ {
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (ctx);
+ /* set proper data for tracked AVLN. on secon call send assoc */
+ if (own_data->tei_track != MAC_TEI_UNASSOCIATED)
+ cp_fsm_post_new_event (ctx, bare, nd_beacon);
+ }
+ }
+
+ if (its_nid == our_nid)
+ {
+ cp_sta_get_peer (sta, &ctx->sta_action.assoc.peer);
+ /* track beacon as soon as possible, sync is important */
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (ctx);
+ /* set proper data for tracked AVLN. on secon call send assoc */
+ if (own_data->tei_track == MAC_TEI_UNASSOCIATED)
+ {
+ own_data->tei_track = ctx->sta_action.assoc.peer.tei;
+ own_data->cco_mac_addr_track = ctx->sta_action.assoc.peer.mac;
+ bsu_track_avln (ctx->bsu, cp_net_get_nid (ctx, net),
+ cp_net_get_snid (ctx, net),
+ ctx->sta_action.assoc.peer.tei,
+ ctx->sta_action.assoc.peer.mac);
+ }
+ }
+}
+
+void
+cp_eoc_sta_action_assoc__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ dbg_assert (ctx);
+ dbg_assert (beacon);
+ dbg_assert (net);
+ dbg_assert (sta);
+
+ ctx->sta_action.assoc.beacon_loss = 0;
+ if (ctx->sta_action.assoc.beacon_succ < CP_EOC_BEACON_RECEIVE_STABLE)
+ ctx->sta_action.assoc.beacon_succ++;
+}
+
+bool
+cp_beacon_succ_received (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return (ctx->sta_action.assoc.beacon_succ >= CP_EOC_BEACON_RECEIVE_STABLE);
+}
+
+#if CONFIG_CP_EOC_STA_CON_ALLOWED
+static u32 mem=0, auth_time=0;
+u32 cp_eoc_time_get (void)
+{
+ return auth_time;
+}
+#endif
+void
+cp_eoc_sta_action_auth__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ dbg_assert (ctx);
+ dbg_assert (beacon);
+ dbg_assert (net);
+ dbg_assert (sta);
+
+ ctx->sta_action.assoc.beacon_loss = 0;
+ if (ctx->sta_action.assoc.beacon_succ < CP_EOC_BEACON_RECEIVE_STABLE)
+ ctx->sta_action.assoc.beacon_succ++;
+ /* check consecc polling count */
+ if (ctx->pbproc->polled)
+ {
+ ctx->sta_action.assoc.retry=0;
+ ctx->pbproc->polled = false;
+ }
+ else
+ {
+ if (cp_sta_own_data_get_authenticated_status (ctx)
+ && ++ctx->sta_action.assoc.retry >= CP_EOC_NOT_POLLED_NB)
+ {
+ ctx->sta_action.assoc.retry = 0;
+ cp_fsm_post_new_event (ctx, bare, sta_not_polled);
+ return;
+ }
+ }
+#if CONFIG_CP_EOC_STA_CON_ALLOWED
+ if (++mem >= CP_EOC_BEACON_1S_NB)
+ {
+ auth_time++;
+ mem = 0;
+ char temp[128];
+ sprintf (temp, "sta=%d blk=%d sar[%d,%d,%d,%d,%d,%d,%d] pb[%d]\n",
+ auth_time, blk_free_nb (),
+ ctx->sar->stats.rx_jobs_count,
+ ctx->sar->stats.rx_jobs_waiting_count,
+ ctx->sar->stats.rx_pb_count,
+ ctx->sar->stats.rx_pb_rejected,
+ ctx->sar->stats.rx_pb_crc_error_count,
+ ctx->sar->stats.tx_pb_expired,
+ ctx->sar->stats.rx_pb_expired,
+ ctx->pbproc->stats.tx_data_cancel
+ + ctx->pbproc->stats.tx_data_wack_noack);
+ ctx->sar->stats.rx_jobs_count =
+ ctx->sar->stats.rx_pb_rejected =
+ ctx->sar->stats.rx_pb_crc_error_count =
+ ctx->sar->stats.rx_pb_expired =
+ ctx->sar->stats.tx_pb_expired =
+ ctx->sar->stats.rx_pb_count = 0;
+ int pos = 0, len = strlen (temp), len1;
+ while (pos < len)
+ {
+ char * temp1 = temp + pos, tmpa[32];
+ len1 = MIN (len, pos + 20);
+ strncpy (tmpa, temp1, len1 - pos);
+ tmpa[len1 - pos] = '\0';
+ printf (tmpa);
+ pos = len1;
+ }
+ }
+#endif
+}
+
+/* return station to detect beacon state */
+void
+cp_eoc_sta_action_assoc__associating_timeout (cp_t *ctx)
+{
+ ctx->sta_mgr.sta_own_data.num_bad_could_not_assoc ++;
+ if (ctx->sta_action.assoc.retry++ < CP_EOC_NUM_RETRY)
+ {
+ cp_fsm_branch (ctx, ASSOCIATING, timeout_associating, retry);
+ }
+ else
+ {
+ cp_fsm_branch (ctx, ASSOCIATING, timeout_associating, no_retry);
+ cp_eoc_sta_action_sta_clear_status (ctx);
+ }
+}
+
+void
+cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_msg_cc_assoc_cnf_t cnf;
+ bool added;
+ mfs_tx_t *mfs;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ /* confirmation is received, reset counter
+ * result is not relevant, only that ASSOC.CNF is received. */
+ ctx->sta_action.assoc.assoc_req_retry_nb = 0;
+ bool status = cp_msg_cc_assoc_cnf_receive (ctx, mme, &cnf);
+ /* change dak and result */
+ if (status && cnf.result
+ == CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS_WL_ACCEPT_ALL)
+ {
+ cp_key_t key = cp_secu_generate_keys (ctx, MASTER_GOLDEN_DPW,
+ strlen (MASTER_GOLDEN_DPW), CP_SECU_SALT_KEY_DAK);
+ cp_sta_own_data_set_dak (ctx, key);
+ cnf.result = CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS;
+ }
+ else if (status && cnf.result == CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS)
+ cp_sta_own_data_set_dak (ctx, cp_sta_own_data_get_original_dak (ctx));
+ /* Check response. */
+ if (mme->peer.mac != ctx->sta_action.assoc.peer.mac
+ || mme->peer.tei == 0
+ || !status
+ || cnf.nid != cp_sta_own_data_get_nid (ctx))
+ {
+ /* Unrelated message, drop. */
+ cp_fsm_branch (ctx, ASSOCIATING, CC_ASSOC_CNF, unrelated);
+ }
+ else if (cnf.result != CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS)
+ {
+ /* Negative result, station not associated */
+ ctx->sta_mgr.sta_own_data.num_bad_assoc_failure ++;
+ cp_fsm_branch (ctx, ASSOCIATING, CC_ASSOC_CNF, unsuccess);
+ }
+ else
+ {
+ /* Update state. */
+ cp_sta_own_data_set_tei (ctx, cnf.sta_tei);
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (ctx);
+ own_data->tei_track = ctx->sta_action.assoc.peer.tei;
+
+ /* Create request for KEYs */
+ cp_msg_cm_get_key_req_t get_key = {
+ .relayed = false, .key_type = CP_MSG_KEY_NEK,
+ .nid = cp_sta_own_data_get_nid (ctx) };
+ cp_secu_protocol_run_new (&ctx->sta_action.assoc.prun, 0, &ctx->rnd);
+
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, true, MAC_LID_NONE,
+ mme->peer.tei, &added);
+ if(added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+
+ if (mfs)
+ blk_release (mfs);
+
+ /*STA is authenticated data can be transferred */
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false, MAC_LLID_MIN,
+ mme->peer.tei, &added);
+ if(added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+
+ if (mfs)
+ blk_release (mfs);
+
+ cp_msg_cm_get_key_req_send (ctx, &mme->peer, CP_MME_PEKS_DAK,
+ &ctx->sta_action.assoc.prun, &get_key);
+ /* Change state. */
+ cp_fsm_branch (ctx, ASSOCIATING, CC_ASSOC_CNF, success);
+ DBG_PRINT("sta: assoc");
+
+ ctx->sta_mgr.sta_own_data.state = CP_EOC_STA_STATE_ASSOCIATED;
+ cp_sta_action_drv__drv_sta_get_status_ind(ctx);
+ }
+}
+
+void
+cp_eoc_sta_action_assoc__associating_no_beacons (cp_t *ctx)
+{
+ cp_eoc_sta_action_sta_clear_status (ctx);
+}
+
+/* Simply goto detecting beacon and wait for beacon to start assoc */
+void
+cp_eoc_sta_action_assoc__unassociated_retry (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_key_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ cp_msg_cm_get_key_cnf_t cnf;
+ bool added, accepted = true;
+ mfs_tx_t *mfs;
+ /* Check response. */
+ if (!cp_mme_peer_cmp (&mme->peer, &ctx->sta_action.assoc.peer)
+ || !cp_msg_cm_get_key_cnf_receive (ctx, mme, &cnf)
+ || !cp_secu_protocol_check (&ctx->sta_action.assoc.prun, &mme->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEXT)
+ || cnf.nid != cp_sta_own_data_get_nid (ctx)
+ || (mme->peks != CP_MME_PEKS_DAK))
+ accepted = false;
+
+ if (!accepted)
+ {
+ /* Unrelated message, drop. */
+ cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF, unrelated);
+ }
+ else if (cnf.result != CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED)
+ {
+ /* Failure indication. */
+ cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF, not_granted);
+ }
+ else if (cnf.key_type == CP_MSG_KEY_NEK)
+ {
+ /* Use the first nex_index from msg, BEACON */
+ /* Use the new key. */
+ cp_beacon_nek_index_adjust (ctx, cnf.eks);
+ cp_beacon_change_nek (ctx, cnf.eks, cnf.key, true);
+ /*STA is authenticated data can be transferred */
+ mfs = mac_store_mfs_add_tx (ctx->mac_store, false, false, MAC_LLID_MIN,
+ mme->peer.tei, &added);
+ if(added)
+ sar_mfs_add (ctx->sar, (mfs_t *)mfs);
+ if (mfs)
+ blk_release (mfs);
+ /* Signal joined state.
+ * TODO: cp_fsm_trigger_new_event (ctx, bare, joined); */
+ /* Reset beacon loss counter. */
+ ctx->sta_action.assoc.beacon_loss = 0;
+ cp_fsm_branch (ctx, ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted);
+ ctx->sta_mgr.sta_own_data.num_good_assoc_auth ++;
+
+ /* Create request for KEYs */
+ cp_msg_cm_get_key_req_t get_key = {
+ .relayed = false, .key_type = CP_MSG_KEY_TEK,
+ .nid = cp_sta_own_data_get_nid (ctx) };
+ cp_secu_protocol_run_new (&ctx->sta_action.assoc.prun, 0, &ctx->rnd);
+
+ cp_msg_cm_get_key_req_send (ctx, &mme->peer, CP_MME_PEKS_DAK,
+ &ctx->sta_action.assoc.prun, &get_key);
+ ctx->sta_mgr.sta_own_data.state = CP_EOC_STA_STATE_AUTHENTICATED;
+ cp_sta_action_drv__drv_sta_get_status_ind(ctx);
+ }
+}
+
+void
+cp_eoc_sta_action_auth__authenticated_key_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ cp_msg_cm_get_key_cnf_t cnf;
+ bool accepted = true;
+
+ /* Check response. */
+ if (!cp_mme_peer_cmp (&mme->peer, &ctx->sta_action.assoc.peer)
+ || !cp_msg_cm_get_key_cnf_receive (ctx, mme, &cnf)
+ || !cp_secu_protocol_check (&ctx->sta_action.assoc.prun, &mme->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_LAST)
+ || cnf.nid != cp_sta_own_data_get_nid (ctx)
+ || (mme->peks != CP_MME_PEKS_DAK))
+ accepted = false;
+
+ if (accepted
+ && cnf.key_type == CP_MSG_KEY_TEK
+ && cnf.result == CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED)
+ {
+ /* Use the new key. TODO Stop time timer */
+ cp_sta_own_data_set_authenticated_status (ctx, true);
+ // Get the network.
+ cp_net_t * net = cp_sta_mgr_get_our_avln (ctx);
+ cp_sta_t * sta =
+ cp_sta_mgr_sta_get_assoc (ctx, net, mme->peer.tei);
+
+ if (sta)
+ {
+ cp_sta_set_authenticated (ctx, sta, true);
+ slab_release (sta);
+ }
+ DBG_PRINT("sta: auth eks=%d", cnf.eks);
+ }
+}
+
+void
+cp_eoc_sta_action_auth__authenticated_set_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ /* Get our CCo. */
+ cp_net_t *net = cp_sta_mgr_get_our_avln (ctx);
+ cp_mme_peer_t peer;
+ cp_net_get_cco_peer (ctx, net, &peer);
+ /* Check received message. */
+ cp_msg_cm_set_key_req_t req;
+
+ if (cp_mme_peer_cmp (&mme->peer, &peer)
+ && cp_msg_cm_set_key_req_receive (ctx, mme, &req)
+ && req.nid == cp_sta_own_data_get_nid (ctx))
+ {
+ if ((req.key_type == CP_MSG_KEY_NEK)
+ && (mme->peks == CP_MME_PEKS_DAK)
+ && (cp_secu_protocol_check
+ (&ctx->sta_action.nek_prun, &mme->prun,
+ CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEXT)))
+ {
+
+ ctx->sta_action.nek_prun = mme->prun;
+ /* Send response. */
+ cp_msg_cm_set_key_cnf_t cnf = {
+ CP_MSG_CM_SET_KEY_CNF_RESULT_SUCCESS,
+ CP_CCO_LEVEL };
+ cp_secu_protocol_next (&ctx->sta_action.nek_prun, &ctx->rnd,
+ true);
+ cp_msg_cm_set_key_cnf_send (ctx, &peer, CP_MME_PEKS_DAK,
+ &ctx->sta_action.nek_prun,
+ &cnf);
+ /* Update NEK. */
+ cp_beacon_change_nek (ctx, req.new_eks, req.new_key, false);
+ DBG_PRINT("key_exc: eks=%d", req.new_eks);
+ }
+ else if ((req.key_type == CP_MSG_KEY_NONCE_ONLY)
+ && (mme->peks == CP_MME_PEKS_DAK)
+ && (cp_secu_protocol_check
+ (NULL, &mme->prun, CP_SECU_PROTOCOL_RUN_CHECK_RESULT_NEW)))
+ {
+
+ /* Send response. */
+ cp_msg_cm_set_key_cnf_t cnf = {
+ CP_MSG_CM_SET_KEY_CNF_RESULT_SUCCESS,
+ CP_CCO_LEVEL };
+
+ ctx->sta_action.nek_prun = mme->prun;
+ cp_secu_protocol_next (&ctx->sta_action.nek_prun, &ctx->rnd,
+ false);
+ ctx->sta_action.nek_prun.my_nonce = lib_rnd32 (&ctx->rnd);
+ cp_msg_cm_set_key_cnf_send (ctx, &peer, CP_MME_PEKS_DAK,
+ &ctx->sta_action.nek_prun,
+ &cnf);
+ }
+ }
+ else
+ {
+ /* Send response. */
+ cp_msg_cm_set_key_cnf_t cnf = {
+ CP_MSG_CM_SET_KEY_CNF_RESULT_FAILURE,
+ CP_CCO_LEVEL };
+ cp_secu_protocol_run_t prun = mme->prun;
+ prun.my_nonce = lib_rnd32 (&ctx->rnd);
+ cp_secu_protocol_next (&prun, &ctx->rnd, true);
+ cp_msg_cm_set_key_cnf_send (ctx, &peer, CP_MME_PEKS_DAK, &prun,
+ &cnf);
+ }
+}
+
+/* Leave state and start detection again */
+void
+cp_eoc_sta_action_assoc__associated_no_beacons (cp_t *ctx)
+{
+ cp_eoc_sta_action_sta_clear_status (ctx);
+}
+
+/* Left assosiation and goto unassoc state and go again: */
+void
+cp_eoc_sta_action_assoc__associated_timeout (cp_t *ctx)
+{
+ ctx->sta_mgr.sta_own_data.num_bad_could_not_auth ++;
+ cp_eoc_sta_action_sta_clear_status (ctx);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_leave (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+
+ /* Check received message. */
+ enum cp_msg_cc_leave_ind_reason_t reason;
+ cp_nid_t nid;
+
+ ctx->sta_mgr.sta_own_data.num_leave ++;
+ if (cp_msg_cc_leave_ind_receive (ctx, mme, &reason, &nid)
+ && nid == cp_sta_own_data_get_nid (ctx))
+ {
+ cp_msg_cc_leave_rsp_send (ctx, &mme->peer);
+ cp_fsm_branch (ctx, ASSOCIATED, CC_LEAVE_IND, ok);
+ cp_eoc_sta_action_sta_clear_status (ctx);
+ }
+ else
+ {
+ cp_fsm_branch (ctx, ASSOCIATED, CC_LEAVE_IND, nok);
+ }
+}
+
+/* start LEAVE process: TODO */
+void
+cp_eoc_sta_action_assoc__authenticated_leave (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+
+ /* Check received message. */
+ enum cp_msg_cc_leave_ind_reason_t reason;
+ cp_nid_t nid;
+
+ ctx->sta_mgr.sta_own_data.num_leave ++;
+ if (cp_msg_cc_leave_ind_receive (ctx, mme, &reason, &nid)
+ && nid == cp_sta_own_data_get_nid (ctx))
+ {
+ cp_msg_cc_leave_rsp_send (ctx, &mme->peer);
+ cp_fsm_branch (ctx, AUTHENTICATED, CC_LEAVE_IND, ok);
+ cp_eoc_sta_action_sta_clear_status (ctx);
+ }
+ else
+ {
+ cp_fsm_branch (ctx, AUTHENTICATED, CC_LEAVE_IND, nok);
+ }
+}
+
+/* Actions to left auth state: start LEAVE process TODO */
+void
+cp_eoc_sta_action_assoc__authenticated_no_beacons (cp_t *ctx)
+{
+ cp_eoc_sta_action_sta_clear_status (ctx);
+}
+
+void
+cp_eoc_sta_action_assoc__beacon_not_received (cp_t *ctx)
+{
+ static int ltra = 0;
+ if (ltra > 5) ltra = 0; else ltra++;
+ GPIO_SET (LED_TRAFFIC, !ltra);
+
+ dbg_assert (ctx);
+ ctx->sta_action.assoc.beacon_loss++;
+ ctx->sta_action.assoc.beacon_succ = 0;
+ if (ctx->sta_action.assoc.beacon_loss > CP_MAX_NO_BEACON)
+ {
+ ctx->sta_action.assoc.beacon_loss = 0;
+ cp_fsm_trigger_new_event (ctx, bare, no_beacons);
+ }
+#if CONFIG_CP_EOC_STA_CON_ALLOWED
+ DBG_PRINT ("d=%u bcn_not_rcv", phy_date () / MAC_MS_TO_TCK(1));
+#endif
+}
+
+void
+cp_sta_action_assoc__start_retry_timer (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ ctx, CP_FSM_EVENT_TYPE_timeout_associating);
+ cp_sta_core_gen_timed_event (ctx, &ctx->sta_action.assoc.timer, event,
+ RETRY_TIMEOUT_MS);
+}
+
+void
+cp_sta_action_assoc__stop_retry_timer (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_sta_core_stop_timed_or_cyclic_event (
+ ctx, &ctx->sta_action.assoc.timer);
+}
+
+void
+cp_sta_action_unassoc__start_retry_timer (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ /* randomize start of assoc process */
+ ctx->sta_action.assoc.init_count = CP_EOC_STA_ASSOC_REQ_OFFSET;
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ ctx, CP_FSM_EVENT_TYPE_timeout_unassociating);
+ cp_sta_core_gen_timed_event (ctx, &ctx->sta_action.assoc.timer, event,
+ UNASSOC_RETRY_TIMEOUT_MS);
+}
+
+void
+cp_sta_action_unassoc__stop_retry_timer (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_sta_core_stop_timed_or_cyclic_event (
+ ctx, &ctx->sta_action.assoc.timer);
+}
+
+/* release fsm, goto UNASSOC state: SLEEP, no action, normal situation */
+void
+cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+/* Find the place for this function and meaning TODO */
+void
+cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+}
+
+
+void
+cp_eoc_sta_action_auth__authenticated_set_out_lev(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert(ctx);
+
+ uint output_level;
+ bool ok;
+
+ ok = cp_msg_eoc_sta_vs_set_out_lev_ind_receive(ctx, mme, &output_level);
+ if (ok)
+ {
+ /* Check if output_level has reserved value i.e. 0 */
+ if (output_level)
+ ctx->sta_mgr.sta_own_data.output_level = output_level;
+
+ cp_mme_peer_t peer;
+ peer.tei = MAC_TEI_FOREIGN;
+ peer.mac = ctx->sta_mgr.sta_own_data.mac_addr;
+ peer.vlan_tag = 0;
+ cp_msg_vs_eoc_cco_set_out_lev_ind_send (ctx, &peer,
+ ctx->sta_mgr.sta_own_data.output_level);
+ DBG_PRINT_2 ("out_lev = %d", ctx->sta_mgr.sta_own_data.output_level);
+ }
+}
diff --git a/cesar/cp/eoc/sta/action/src/cco_stub.c b/cesar/cp/eoc/sta/action/src/cco_stub.c
new file mode 100644
index 0000000000..8c5985ef41
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/cco_stub.c
@@ -0,0 +1,127 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/src/assoc.c
+ * \brief STA action, association related definitions.
+ * \ingroup cp_eoc_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+
+#include "cp/inc/context.h"
+#include "cp/fsm/fsm.h"
+#include "cp/msg/msg.h"
+#include "cp/beacon/beacon.h"
+#include "cp/eoc/multi_sta/action/multi_sta_action.h"
+#include "cp/eoc/inc/dbg_print.h"
+
+#define CP_EOC_STA_ASSOCIATED_TIMEOUT_MS 5*1000
+
+void
+cp_sta_action_assoc_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->sta_action.assoc.assoc_req_retry_nb = 0;
+}
+
+void
+cp_sta_action_assoc_leave (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ /* Trigger to_leave event. */
+ cp_fsm_trigger_new_event (ctx, bare, no_beacons);
+}
+
+/**
+ * initialisation of CCo action module.
+ * \param ctx the module context.
+ * FAKE: TODO
+ */
+void
+cp_cco_action_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ memset (&ctx->cco_action, 0, sizeof (cp_cco_action_t));
+}
+
+/**
+ * Uninitialisation of CCo action module.
+ * \param ctx the module context.
+ * FAKE: TODO
+ */
+void
+cp_cco_action_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+void
+cp_net_garbage_station_list (cp_t *ctx, cp_net_t *net, u32 date_ms,
+ cp_net_sta_status_t assoc);
+/**
+ * perform garbage actions of CCo's responsibility.
+ * \param ctx the module context.
+ */
+void
+cp_cco_action_garbage (cp_t *ctx)
+{
+ int i;
+ 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? realy 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))))
+ {
+ cp_eoc_multi_sta_action_put_sta_unassociated (ctx, station);
+ /* Start release procedure */
+ cp_sta_mgr_release_station (ctx, i);
+ DBG_PRINT("sta: released, 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);
+}
+
+/**
+ * Release a TEI.
+ * \param ctx the module context.
+ * \param tei The TEI value to release.
+ */
+void
+cp_cco_action_tei_release (cp_t *ctx, u8 tei)
+{
+ uint row;
+
+ dbg_assert (ctx);
+ dbg_assert (tei);
+
+ row = tei / CP_CCO_ACTION_TEI_FLAGS_ROW_SIZE_BITS;
+
+ ctx->cco_action.tei_flags[row] &= ~(1 << ((tei
+ % CP_CCO_ACTION_TEI_FLAGS_ROW_SIZE_BITS)-1));
+}
diff --git a/cesar/cp/eoc/sta/action/src/drv.c b/cesar/cp/eoc/sta/action/src/drv.c
new file mode 100644
index 0000000000..d090a5c26b
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/drv.c
@@ -0,0 +1,423 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/action/src/drv.c
+ * \brief STA action, driver related definitions.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+
+#include "cp/msg/msg.h"
+#include "cp/inc/context.h"
+#include "cp/fsm/fsm.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "lib/stats.h"
+#include "cp/msg/inc/msg_vs_eoc.h"
+#include "config/cp/msg/eoc.h"
+
+#include "stdio.h"
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ mac_t mac;
+ bool ok = cp_msg_drv_sta_set_mac_addr_req_receive (ctx, mme, &mac);
+ if (ok)
+ cp_sta_own_data_set_mac_address (ctx, mac);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_MAC_ADDR_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ bool cco_pref;
+ bool ok = cp_msg_drv_sta_set_cco_pref_req_receive (ctx, mme, &cco_pref);
+ if (ok)
+ {
+ cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (ctx);
+ own->cco_prefered = cco_pref;
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_CCO_PREF_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ bool was_cco;
+ bool ok = cp_msg_drv_sta_set_was_cco_req_receive (ctx, mme, &was_cco);
+ if (ok)
+ cp_sta_own_data_set_was_cco (ctx, was_cco);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_WAS_CCO_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ char npw[CP_NPW_MAX_SIZE + 1];
+ bool ok = cp_msg_drv_sta_set_npw_req_receive (ctx, mme, npw);
+ if (ok)
+ {
+ /* Compute NID from received information. */
+ cp_security_level_t sl;
+ sl = cp_sta_own_data_get_security_level (ctx);
+ cp_sta_own_data_set_npw (ctx, npw);
+ cp_compute_nmk_and_nid_from_npw (ctx, npw, sl);
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_NPW_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ char dpw[CP_DPW_MAX_SIZE + 1];
+ bool ok = cp_msg_drv_sta_set_dpw_req_receive (ctx, mme, dpw);
+ if (ok)
+ cp_sta_own_data_set_dpw (ctx, dpw);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_DPW_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ cp_security_level_t sl;
+ bool ok = cp_msg_drv_sta_set_sl_req_receive (ctx, mme, &sl);
+ if (ok)
+ {
+ /* Compute NID from received information. */
+ const char *npw;
+ npw = cp_sta_own_data_get_npw (ctx);
+
+ cp_sta_own_data_set_security_level (ctx, sl);
+ cp_compute_nmk_and_nid_from_npw (ctx, npw, sl);
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_SL_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ cp_nid_t nid;
+ bool ok = cp_msg_drv_sta_set_nid_req_receive (ctx, mme, &nid);
+ if (ok)
+ cp_sta_own_data_set_nid (ctx, nid);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_NID_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+#if CONFIG_CP_MSG_EOC_DRV_MME
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ u32 tonemask[PHY_TONEMASK_WORDS];
+ bool ok = cp_msg_drv_sta_set_tonemask_req_receive (ctx, mme, tonemask);
+ if (ok)
+ {
+ /* Commit to mac configuration and update tonemask informations. */
+ memcpy (ctx->mac_config->tonemask_info.tonemask, tonemask,
+ sizeof (tonemask));
+ bool adjust =
+ tonemask_carrier_nb (ctx->mac_config->tonemask_info.tonemask) < 375;
+ pbproc_parameters_adjust (ctx->pbproc, adjust);
+ cp_eoc_cco_bw_allocations_adjust (ctx, adjust);
+ tonemask_update (&ctx->mac_config->tonemask_info);
+ /* Tonemask will be programmed once the PBProc is activated. */
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_TONEMASK_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+#else
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ u32 tonemask[PHY_TONEMASK_WORDS];
+ bool ok = cp_msg_drv_sta_set_tonemask_req_receive (ctx, mme, tonemask);
+ if (ok)
+ {
+ /* TODO. */
+ bool adjust =
+ tonemask_carrier_nb (ctx->mac_config->tonemask_info.tonemask) < 375;
+ pbproc_parameters_adjust (ctx->pbproc, adjust);
+ cp_eoc_cco_bw_allocations_adjust (ctx, adjust);
+ tonemask_update (&ctx->mac_config->tonemask_info);
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_TONEMASK_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+#endif
+
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ bool ok = cp_msg_drv_sta_mac_start_req_receive (ctx, mme);
+ if (ok)
+ {
+ /* Start power-on procedure. */
+ cp_sta_action_poweron_start (ctx);
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_MAC_START_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+
+}
+
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ bool ok = cp_msg_drv_sta_mac_stop_req_receive (ctx, mme);
+ /* This come from the driver, it should be OK. */
+ dbg_assert (ok);
+ /* Save driver address. */
+ ctx->sta_action.drv_peer = mme->peer;
+ /* Stop station. */
+ cp_sta_action_poweron_stop (ctx);
+}
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ /* Signal the station is stopped. */
+ cp_msg_drv_any_cnf_send (ctx, &ctx->sta_action.drv_peer,
+ DRV_STA_MAC_STOP_CNF, CP_MSG_DRV_RESULT_SUCCESS);
+}
+
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_key_t nmk;
+ enum cp_msg_drv_sta_set_key_type_t type;
+ cp_nid_t nid;
+ cp_security_level_t sl;
+
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ /* Try to decode the DRV MME. */
+ if (cp_msg_drv_sta_set_key_req_receive (ctx, mme, &nmk, &type, &nid, &sl))
+ {
+ /* Set the NMK. */
+ cp_sta_own_data_set_nmk (ctx, nmk, type);
+ /* We need to have a NID; let's build it if we do not have one. */
+ if (type == CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_SECURITY_LEVEL)
+ {
+ /* Build NID from SL and NMK. */
+ cp_sta_own_data_set_security_level (ctx, sl);
+ nid = cp_secu_nmk2nid (ctx, nmk, sl);
+ }
+ /* Always setup NID. */
+ cp_sta_own_data_set_nid (ctx, nid);
+ dbg_do (
+ if (type == CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_SECURITY_LEVEL)
+ dbg_assert (sl == cp_sta_own_data_get_security_level (ctx));
+ );
+
+ /* Reply with success. */
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_KEY_CNF,
+ CP_MSG_DRV_RESULT_SUCCESS);
+ }
+ else
+ {
+ /* Error in decoding, let's reply with an error. */
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_KEY_CNF,
+ CP_MSG_DRV_RESULT_FAILURE);
+ }
+}
+
+
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_key_t dak;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_drv_sta_set_dak_req_receive (ctx, mme, &dak))
+ {
+ cp_sta_own_data_set_dak (ctx, dak);
+ cp_sta_own_data_set_original_dak (ctx, dak);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_DAK_CNF,
+ CP_MSG_DRV_RESULT_SUCCESS);
+ }
+ else
+ {
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_DAK_CNF,
+ CP_MSG_DRV_RESULT_FAILURE);
+ }
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ char m_sta_hfid[CP_HFID_SIZE + 1];
+ bool ok = cp_msg_drv_sta_set_m_sta_hfid_req_receive (ctx, mme,
+ m_sta_hfid);
+ if (ok)
+ cp_sta_own_data_set_hfid_manufacturer (ctx, m_sta_hfid);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_M_STA_HFID_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ char u_sta_hfid[CP_HFID_SIZE + 1];
+ bool ok = cp_msg_drv_sta_set_u_sta_hfid_req_receive (ctx, mme,
+ u_sta_hfid);
+ if (ok)
+ cp_sta_own_data_set_hfid_user (ctx, u_sta_hfid);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_U_STA_HFID_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ char avln_hfid[CP_HFID_SIZE + 1];
+ bool ok = cp_msg_drv_sta_set_avln_hfid_req_receive (ctx, mme, avln_hfid);
+ if (ok)
+ cp_sta_own_data_set_hfid_avln (ctx, avln_hfid);
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_AVLN_HFID_CNF,
+ ok ? CP_MSG_DRV_RESULT_SUCCESS
+ : CP_MSG_DRV_RESULT_FAILURE);
+}
+
+void
+cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ cp_msg_drv_sta_get_key_t data;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ memset (&data, 0, sizeof (cp_msg_drv_sta_get_key_t));
+ if (cp_msg_drv_sta_get_key_req_receive (ctx, mme))
+ {
+ data.result = CP_MSG_DRV_RESULT_SUCCESS;
+ data.nmk = cp_sta_own_data_get_nmk (ctx);
+ data.nid = cp_sta_own_data_get_nid (ctx);
+ data.sl = cp_sta_own_data_get_security_level (ctx);
+
+ cp_msg_drv_sta_get_key_cnf_send (ctx, &mme->peer, &data);
+ }
+ else
+ {
+ data.result = CP_MSG_DRV_RESULT_FAILURE;
+ cp_msg_drv_sta_get_key_cnf_send (ctx, &mme->peer, &data);
+ }
+}
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ /* Check parameter. */
+ dbg_assert (mme);
+
+ char config[HPAV_MME_PAYLOAD_MAX_SIZE];
+ cp_msg_drv_result_t result = CP_MSG_DRV_RESULT_FAILURE;
+
+ if (cp_msg_drv_sta_set_config_req_receive (ctx, mme, config))
+ {
+ /* Correctly decoded, let's try to set it up. */
+ if (lib_stats_write_stats (config))
+ /* Success. */
+ result = CP_MSG_DRV_RESULT_SUCCESS;
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_STA_SET_CONFIG_CNF, result);
+}
+
+void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ /* Check parameter. */
+ dbg_assert (mme);
+
+ char config[HPAV_MME_PAYLOAD_MAX_SIZE];
+ cp_msg_drv_result_t result = CP_MSG_DRV_RESULT_FAILURE;
+
+ if (cp_msg_drv_sta_set_slave_req_receive (ctx, mme, config))
+ {
+ /* Correctly decoded, let's try to set it up. */
+ if (lib_stats_write_stats (config))
+ {
+ /* Success. */
+ result = CP_MSG_DRV_RESULT_SUCCESS;
+ }
+ }
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_EOC_STA_SET_SLAVE_CONFIG_CNF, result);
+}
+
+ void
+cp_sta_action_drv__drv_sta_set_eoc_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ uint exp, value;
+ cp_msg_drv_result_t result = CP_MSG_DRV_RESULT_FAILURE;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_drv_sta_set_eoc_req_receive (ctx, mme, &exp, &value))
+ {
+ result = CP_MSG_DRV_RESULT_SUCCESS;
+ phy_tx_scale_adapt_exp_set (ctx->phy, exp);
+ phy_tx_scale_adapt_set (ctx->phy, value);
+ }
+
+ cp_msg_drv_any_cnf_send (ctx, &mme->peer, DRV_EOC_STA_SET_EOC_CONFIG_CNF, result);
+}
+
+void
+cp_sta_action_drv__drv_sta_get_status_ind(cp_t *ctx)
+{
+ dbg_assert(ctx);
+
+ cp_mme_peer_t peer;
+ cp_eoc_sta_state_t state = 0;
+
+ peer.tei = MAC_TEI_FOREIGN;
+ peer.mac = ctx->sta_mgr.sta_own_data.mac_addr;
+ peer.vlan_tag = 0;
+ state = ctx->sta_mgr.sta_own_data.state;
+ cp_msg_drv_get_status_ind_send (ctx, &peer, DRV_STA_STATUS_IND, state);
+}
diff --git a/cesar/cp/eoc/sta/action/src/misc.c b/cesar/cp/eoc/sta/action/src/misc.c
new file mode 100644
index 0000000000..52153887c8
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/misc.c
@@ -0,0 +1,121 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/src/misc.c
+ * \brief STA action, miscellaneous definitions.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+#include "cl/data_rate.h"
+#include "mac/common/store.h"
+
+#include "action.h"
+
+#include "cp/inc/context.h"
+#include "cp/inc/trace.h"
+#include "cp/msg/msg.h"
+
+#include "hal/arch/arch.h" // for dsr lock and unlock
+
+#include "common/defs/spidcom.h"
+#include "mac/common/timings.h"
+
+
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (rx_mme);
+
+ cp_mme_tx_t *tx_mme;
+ cp_net_t* our_avln;
+ cp_sta_t* sta_list = NULL;
+ sta_t* sta;
+ uint NumSTAs = 0;
+
+ //Req receive /TODO
+ //if (cp_msg_cm_nw_stats_req_receive (ctx, rx_mme))
+ bool ok = true;
+ if(ok)
+ {
+ /* Make sure we have an avln */
+ if (MAC_TEI_IS_STA (cp_sta_own_data_get_tei (ctx)))
+ {
+ our_avln = cp_sta_mgr_get_our_avln (ctx);
+
+ /* Get authenticated stas */
+ sta_list = cp_net_sta_get_first (ctx, our_avln, CP_NET_STA_ASSOC);
+ while (sta_list)
+ {
+ if (cp_sta_get_authenticated (ctx, sta_list))
+ {
+ NumSTAs++;
+ }
+
+ sta_list = cp_net_sta_get_next (ctx, our_avln, sta_list);
+ }
+ }
+ else
+ {
+ NumSTAs = 0;
+ }
+
+ tx_mme = cp_msg_cm_nw_stats_cnf_send_begin (ctx, &rx_mme->peer,
+ NumSTAs);
+
+ if (NumSTAs)
+ {
+ sta_list = cp_net_sta_get_first (ctx, our_avln, CP_NET_STA_ASSOC);
+
+ while (sta_list)
+ {
+ if (cp_sta_get_authenticated (ctx, sta_list))
+ {
+ mac_t mac;
+ uint phy_dr_tx;
+ uint phy_dr_rx;
+ cl_data_rate_t tx_data_rate;
+ cl_data_rate_t rx_data_rate;
+
+ mac = cp_sta_get_mac_address(sta_list);
+
+ /* Get TX : local STA -> avln STA */
+ /* Get RX : avln STA -> local STA */
+ sta = mac_store_sta_get (ctx->mac_store,
+ cp_sta_get_tei(sta_list));
+
+ arch_dsr_lock();
+ tx_data_rate = sta->tx_data_rate;
+ rx_data_rate = sta->rx_data_rate;
+ arch_dsr_unlock();
+
+ /* Update DR with delay between last DR update and now */
+ data_rate_update_info(&tx_data_rate, 0);
+ data_rate_update_info(&rx_data_rate, 0);
+
+ /* Convert DR from octets/s to Mbit/s */
+ phy_dr_tx = (uint)((tx_data_rate.data_rate * 8 + 500000)
+ /1000000);
+ phy_dr_rx = (uint)((rx_data_rate.data_rate * 8 + 500000)
+ /1000000);
+
+ cp_msg_cm_nw_stats_cnf_send (ctx, tx_mme, mac,
+ phy_dr_tx, phy_dr_rx);
+
+ /* Clean. */
+ blk_release (sta);
+ }
+
+ sta_list = cp_net_sta_get_next (ctx, our_avln, sta_list);
+ }
+ }
+
+ cp_msg_cm_nw_stats_cnf_send_end (ctx, tx_mme);
+ }
+}
diff --git a/cesar/cp/eoc/sta/action/src/poweron.c b/cesar/cp/eoc/sta/action/src/poweron.c
new file mode 100644
index 0000000000..69c32ebc89
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/poweron.c
@@ -0,0 +1,125 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/action/src/poweron.c
+ * \brief STA action, power on procedure related definitions.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+
+#include "cp/defs.h"
+#include "cp/msg/msg.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/fsm/fsm.h"
+#include "cp/beacon/beacon.h"
+#include "cp/cco/action/cco_action.h"
+#include "cp/eoc/cco/bw/bw.h"
+
+#include "cp/inc/context.h"
+
+/* Initial settings for station */
+void
+cp_eoc_sta_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);
+
+ tei = MAC_TEI_UNASSOCIATED;
+ cp_sta_own_data_set_tei (ctx, tei);
+ cp_sta_own_data_set_authenticated_status (ctx, false);
+
+ /* 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, false);
+ own->tei_track = MAC_TEI_UNASSOCIATED;
+ /* set start values */
+ ctx->sta_action.assoc.retry = 0;
+ ctx->sta_action.assoc.beacon_loss = 0;
+ ctx->sta_action.assoc.beacon_succ = 0;
+
+ /* Call the beacon module to send the central beacon. */
+}
+
+void
+cp_sta_action_poweron_start (cp_t *ctx)
+{
+ cp_fsm_trigger_new_event (ctx, bare, to_poweron);
+}
+
+void
+cp_sta_action_poweron_stop (cp_t *ctx)
+{
+ cp_fsm_trigger_new_event (ctx, bare, to_stop);
+}
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ /* Cleanup. */
+ pbproc_activate (ctx->pbproc, false);
+ sar_activate (ctx->sar, false);
+ sar_cleanup (ctx->sar);
+ cp_beacon_deactivate (ctx);
+ /* Signal station is stopped. */
+ cp_fsm_trigger_new_event (ctx, bare, stopped);
+}
+
+void
+cp_sta_action_poweron__idle__to_poweron (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_eoc_sta_action__power_on_no_beacons (ctx);
+ cp_eoc_cco_bw_sta_allocations (ctx);
+ cp_beacon_poweron_init (ctx);
+ bsu_power_on (ctx->bsu, cp_sta_own_data_get_snid (ctx));
+ bsu_activate (ctx->bsu, true);
+ /* force beacon tracking on startup */
+ bsu_untrack_avln (ctx->bsu);
+ cp_beacon_reconfigure_timer (ctx, false);
+ sar_activate (ctx->sar, true);
+ pbproc_activate (ctx->pbproc, true);
+ ctx->sta_action.assoc.peer = CP_MME_PEER (MAC_BROADCAST,
+ MAC_TEI_UNASSOCIATED);
+}
+
+// void
+// cp_sta_action_poweron__poweron__beacon (cp_t *ctx, cp_beacon_desc_t *beacon,
+// cp_net_t *net, cp_sta_t *sta)
+// {
+// dbg_assert (ctx);
+// dbg_assert (beacon);
+// dbg_assert (net);
+// dbg_assert (sta);
+// cp_sta_action_poweron_beacon_match_and_join (
+// ctx, beacon, net, sta,
+// CP_FSM_BRANCH (POWERON, BEACON, nid_match),
+// CP_FSM_BRANCH (POWERON, BEACON, no_nid_match));
+// }
+
+// void
+// cp_sta_action_poweron__sta__to_stop (cp_t *ctx)
+// {
+// dbg_assert (ctx);
+// cp_sta_action_assoc_leave (ctx);
+// }
+//
diff --git a/cesar/cp/eoc/sta/action/src/sleep.c b/cesar/cp/eoc/sta/action/src/sleep.c
new file mode 100644
index 0000000000..d925c312e0
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/sleep.c
@@ -0,0 +1,36 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/src/sleep.c
+ * \brief STA sleep action.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+#include "cp/sta/action/action.h"
+#include "cp/inc/context.h"
+
+void
+cp_eoc_sta_action_sleep__unassociated_enter_sleep (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_sta_action_sleep__sleep_unassociated_exit_sleep (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_sta_action_sleep__authenticated_sleep_enter (cp_t *ctx)
+{
+}
+
+void
+cp_eoc_sta_action_sleep__sleep_authenticated_exit (cp_t *ctx)
+{
+}
+
diff --git a/cesar/cp/eoc/sta/action/src/vs_eoc.c b/cesar/cp/eoc/sta/action/src/vs_eoc.c
new file mode 100644
index 0000000000..9b586f9435
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/src/vs_eoc.c
@@ -0,0 +1,297 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/action/src/vs_eoc.c
+ * \brief STA action, VS_EOC related definitions.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+
+#include "cp/msg/msg.h"
+#include "cp/inc/context.h"
+#include "cp/fsm/fsm.h"
+#include "cp/eoc/cco/bw/bw.h"
+#include "lib/stats.h"
+#include "ce/rx/bitloading/inc/nsr.h"
+#include "mac/pbproc/inc/context.h"
+#include "mac/sar/inc/sar_context.h"
+#include "math.h"
+#include "cp/msg/inc/msg_vs_eoc.h"
+#include "cp/eoc/sta/action/vs_eoc.h"
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_info_req(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert(ctx);
+ dbg_assert(mme);
+
+ sta_t *sta = NULL;
+
+ 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;
+ u8 attenuation = 0;
+ u8 snr = 0;
+ u8 snr_sum = 0;
+ u16 phy_uplink_speed = 0;
+ u16 phy_downlink_speed = 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;
+ u8 agc_offset = 12;
+
+ 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;
+
+ if (tei != MAC_TEI_UNASSOCIATED)
+ {
+ sta = mac_store_sta_get(ctx->mac_store, ctx->sta_action.assoc.peer.tei);
+ if (sta)
+ {
+ if (sta->authenticated)
+ {
+ snr_sum = ce_rx_bl_nsr_compute_total_mean (&sta->ce_rx_bt);
+ snr = 10*log(snr_sum);
+ attenuation = sta->upstream_att + agc_offset;
+ }
+ blk_release (sta);
+ }
+
+ phy_uplink_speed = cp_sta_action_get_average_ble (ctx, ctx->sta_action.assoc.peer.tei,
+ true, false) * MAX_THROUGHPUT_MBPS /
+ DEFAULT_STREAM_QUALITY;
+ phy_downlink_speed = cp_sta_action_get_average_ble (ctx, ctx->sta_action.assoc.peer.tei,
+ false, false) * MAX_THROUGHPUT_MBPS
+ / DEFAULT_STREAM_QUALITY;
+ }
+
+ output_power = ctx->sta_mgr.sta_own_data.output_level;
+ 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;
+ tx_crc_error_counter = 0; /* N.A. */
+ 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_sta_action_vs_eoc__sta__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)
+ {
+ if(ctx->sta_mgr.sta_own_data.tei == MAC_TEI_UNASSOCIATED)
+ {
+ assoc_stat = 0;
+ }
+ else if(!ctx->mac_config->authenticated)
+ {
+ assoc_stat = 1;
+ }
+ else
+ {
+ assoc_stat = 2;
+ }
+
+ nid = ctx->sta_mgr.our_avln->nid;
+ num_slots = 1;
+ he_mac_address = ctx->sta_action.assoc.peer.mac;
+ est_avg_phy_rate = 0;
+ if(control == 1)
+ {
+ ctx->sta_mgr.sta_own_data.num_good_assoc_auth = 0;
+ ctx->sta_mgr.sta_own_data.num_bad_could_not_assoc = 0;
+ ctx->sta_mgr.sta_own_data.num_bad_assoc_failure = 0;
+ ctx->sta_mgr.sta_own_data.num_bad_could_not_auth = 0;
+ ctx->sta_mgr.sta_own_data.num_leave = 0;
+ }
+ num_good_assoc_auth = ctx->sta_mgr.sta_own_data.num_good_assoc_auth;
+ num_bad_could_not_assoc = ctx->sta_mgr.sta_own_data.num_bad_could_not_assoc;
+ num_bad_assoc_failure = ctx->sta_mgr.sta_own_data.num_bad_assoc_failure;
+ num_bad_could_not_auth = ctx->sta_mgr.sta_own_data.num_bad_could_not_auth;
+ num_leave = ctx->sta_mgr.sta_own_data.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);
+}
+
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ bool ok;
+ cp_msg_vs_eoc_get_info_req_result_t status = CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_SUCCESS;
+ u8 clear;
+ real_time_stats_t rt_stats;
+
+ static uint nb_unicast_packets_rx_offset = 0;
+ static uint nb_unicast_packets_tx_offset = 0;
+ static uint rx_pb_count_offset = 0;
+ static uint nb_broadcast_packets_rx_offset = 0;
+ static uint nb_broadcast_packets_tx_offset = 0;
+ static uint nb_packets_rx_crc_offset = 0;
+ static uint nb_packets_rx_discarded_offset = 0;
+ static uint ber_sum_tmp_offset = 0;
+ static uint rx_pb_crc_error_count_tmp_offset;
+
+ uint ber_sum_tmp = 0;
+ uint rx_pb_crc_error_count_tmp = 0;
+ uint rx_pb_count_tmp = 0;
+
+ uint num;
+ uint div;
+
+ dbg_assert(ctx);
+ dbg_assert(mme);
+
+ ok = cp_msg_vs_eoc_cco_get_real_time_stats_req_receive (ctx, mme, &clear);
+
+ if (ok)
+ {
+ if(clear == 1)
+ {
+ rt_stats.nb_unicast_packets_rx = 0;
+ rt_stats.nb_unicast_packets_tx = 0;
+ rt_stats.total_nb_bytes_rx = 0;
+ rt_stats.total_nb_bytes_tx = 0;
+ rt_stats.nb_broadcast_packets_rx = 0;
+ rt_stats.nb_broadcast_packets_tx = 0;
+ rt_stats.nb_multicast_packets_rx = 0;
+ rt_stats.nb_multicast_packets_tx = 0;
+ rt_stats.nb_packets_rx_crc = 0;
+ rt_stats.nb_packets_rx_short = 0;
+ rt_stats.nb_packets_tx_short = 0;
+ rt_stats.nb_packets_tx_dropped = 0;
+ rt_stats.nb_packets_rx_discarded = 0;
+ rt_stats.avg_pre_fec_bit_error_rate = 0;
+
+ nb_unicast_packets_rx_offset = ctx->pbproc->stats.rx_data;
+ nb_unicast_packets_tx_offset = ctx->pbproc->stats.tx_data;
+
+ nb_broadcast_packets_rx_offset = ctx->pbproc->stats.rx_data_woack +
+ ctx->pbproc->stats.rx_beacon;
+ nb_broadcast_packets_tx_offset = ctx->pbproc->stats.tx_data_woack +
+ ctx->pbproc->stats.tx_data_beacon;
+ nb_packets_rx_crc_offset = ctx->pbproc->stats.rx_crc_error +
+ ctx->pbproc->stats.rx_fc_unknown;
+ nb_packets_rx_discarded_offset = ctx->pbproc->stats.rx_data_error;
+
+#if CONFIG_STATS
+ rx_pb_count_offset = ctx->sar->stats.rx_pb_count;
+ ber_sum_tmp_offset = ctx->sar->stats.ber_sum;
+ rx_pb_crc_error_count_tmp_offset = ctx->sar->stats.rx_pb_crc_error_count;
+#else
+ rx_pb_count_offset = 0;
+ ber_sum_tmp_offset = 0;
+ rx_pb_crc_error_count_tmp_offset = 0;
+#endif
+ }
+
+ rt_stats.nb_unicast_packets_rx = ctx->pbproc->stats.rx_data - nb_unicast_packets_rx_offset;
+ rt_stats.nb_unicast_packets_tx = ctx->pbproc->stats.tx_data - nb_unicast_packets_tx_offset;
+
+ rt_stats.total_nb_bytes_tx = 0;
+ rt_stats.nb_broadcast_packets_rx = ctx->pbproc->stats.rx_data_woack +
+ ctx->pbproc->stats.rx_beacon -
+ nb_broadcast_packets_rx_offset;
+ rt_stats.nb_broadcast_packets_tx = ctx->pbproc->stats.tx_data_woack +
+ ctx->pbproc->stats.tx_data_beacon -
+ nb_broadcast_packets_tx_offset;
+ rt_stats.nb_multicast_packets_rx = 0;
+ rt_stats.nb_multicast_packets_tx = 0;
+ rt_stats.nb_packets_rx_crc = ctx->pbproc->stats.rx_crc_error +
+ ctx->pbproc->stats.rx_fc_unknown -
+ nb_packets_rx_crc_offset;
+ rt_stats.nb_packets_rx_short = 0;
+ rt_stats.nb_packets_tx_short = 0;
+ rt_stats.nb_packets_tx_dropped = 0;
+ rt_stats.nb_packets_rx_discarded = ctx->pbproc->stats.rx_data_error - nb_packets_rx_discarded_offset;
+#if CONFIG_STATS
+ rt_stats.total_nb_bytes_rx = (ctx->sar->stats.rx_pb_count - rx_pb_count_offset)* MAC_PB520_BYTES;
+ ber_sum_tmp = ctx->sar->stats.ber_sum;
+ rx_pb_crc_error_count_tmp = ctx->sar->stats.rx_pb_crc_error_count;
+ rx_pb_count_tmp = ctx->sar->stats.rx_pb_count;
+
+#else
+ rt_stats.total_nb_bytes_rx = 0;
+ ber_sum_tmp = 0;
+ rx_pb_crc_error_count_tmp = 0;
+ rx_pb_count_tmp = 0;
+#endif
+ num = (ber_sum_tmp - ber_sum_tmp_offset);
+
+ div = ((rx_pb_count_tmp - rx_pb_count_offset) -
+ (rx_pb_crc_error_count_tmp - rx_pb_crc_error_count_tmp_offset)) * MAC_PB520_BYTES * 8 ;
+
+ if (div!=0)
+ rt_stats.avg_pre_fec_bit_error_rate = (num * 10000) / div;
+ else
+ rt_stats.avg_pre_fec_bit_error_rate = 0;
+ }
+ else
+ {
+ status = CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_FAILURE;
+ }
+
+ cp_msg_vs_eoc_cco_get_real_time_stats_cnf_send (ctx, &mme->peer, status, &rt_stats);
+}
diff --git a/cesar/cp/eoc/sta/action/stub/Module b/cesar/cp/eoc/sta/action/stub/Module
new file mode 100644
index 0000000000..f077ef0776
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/stub/Module
@@ -0,0 +1 @@
+SOURCES := drv.c poweron.c bridge.c
diff --git a/cesar/cp/eoc/sta/action/stub/src/bridge.c b/cesar/cp/eoc/sta/action/stub/src/bridge.c
new file mode 100644
index 0000000000..3276577d03
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/stub/src/bridge.c
@@ -0,0 +1,43 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/stub/src/bridge.c
+ * \brief STA action, bridge table related implementations.
+ * \ingroup cp_sta_action
+ *
+ * Bridge table request and reception implementations.
+ */
+#include "common/std.h"
+
+#include "cp/mme.h" // cp_mme_rx_t
+#include "cp/msg/msg.h" // to include cp/msg/inc/msg_cm.h
+#include "cp/msg/inc/msg_cm.h" // cp_msg_cm_brg_info_cnf_receive_*
+#include "cp/sta/mgr/sta_mgr.h" // cp_sta_mgr_get_our_avln
+#include "cp/sta/mgr/sta.h" // cp_sta_get_peer
+#include "cp/sta/mgr/net.h" // cp_net_sta_get_*
+#include "cl/cl_mactotei.h" // cl_mactotei_*
+#include "cp/inc/context.h" // cp_t
+#include "cl/bridge_table.h" // bridge_table_*
+#include "lib/utils.h" // less_mod2p32
+#include "cp/sta/action/bridge.h"
+
+void
+cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta)
+{
+}
+
+void
+cp_sta_action_process_cm_brg_info_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_process_cm_brg_info_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
diff --git a/cesar/cp/eoc/sta/action/stub/src/drv.c b/cesar/cp/eoc/sta/action/stub/src/drv.c
new file mode 100644
index 0000000000..e58f3ef012
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/stub/src/drv.c
@@ -0,0 +1,159 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/action/stub/src/drv.c
+ * \brief STA action, driver related definitions.
+ * \ingroup cp_sta_action
+ */
+#include "common/std.h"
+
+#include "cp/sta/action/action.h"
+
+#include "cp/msg/msg.h"
+#include "cp/inc/context.h"
+#include "cp/fsm/fsm.h"
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+
+}
+
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx)
+{
+
+}
+
+void
+cp_sta_action_drv__drv_sta_get_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__drv_sta_get_status_ind(cp_t *ctx)
+{
+
+}
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+}
+
+void
+cp_sta_action_drv__drv_sta_set_eoc_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+
+}
diff --git a/cesar/cp/eoc/sta/action/stub/src/poweron.c b/cesar/cp/eoc/sta/action/stub/src/poweron.c
new file mode 100644
index 0000000000..a1970f7501
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/stub/src/poweron.c
@@ -0,0 +1,34 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/stub/src/poweron.c
+ * \brief STA action, poweron related definitions.
+ * \ingroup cp_eoc_sta_action_stub
+ */
+#include "common/std.h"
+
+#include "cp/inc/context.h"
+
+void
+cp_sta_action_poweron__idle__to_poweron (cp_t *ctx)
+{}
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx)
+{
+}
+
+void
+cp_sta_action_poweron_start (cp_t *ctx)
+{
+}
+
+void
+cp_sta_action_poweron_stop (cp_t *ctx)
+{
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/Makefile b/cesar/cp/eoc/sta/action/test/utest/Makefile
new file mode 100644
index 0000000000..bdfdaf2d37
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/Makefile
@@ -0,0 +1,11 @@
+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
diff --git a/cesar/cp/eoc/sta/action/test/utest/actions-Config b/cesar/cp/eoc/sta/action/test/utest/actions-Config
new file mode 100644
index 0000000000..6d6215daab
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/actions-Config
@@ -0,0 +1,11 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_sta.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_GPIO_LED_TRAFFIC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_EOC_STA_CON_ALLOWED = n
+CONFIG_MAC_COMMON_EOC_SCHED = y
diff --git a/cesar/cp/eoc/sta/action/test/utest/actions-Makefile b/cesar/cp/eoc/sta/action/test/utest/actions-Makefile
new file mode 100644
index 0000000000..a21d94c624
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/actions-Makefile
@@ -0,0 +1,31 @@
+BASE = ../../../../../..
+
+VARIANT = actions
+
+INCLUDES = cp/eoc/sta/action/test/utest cp/eoc/sta/action/test/utest/actions-override
+
+HOST_PROGRAMS = test_actions
+test_actions_SOURCES = test_actions.c pb_proc_stub.c beacon_stub.c cp_stub.c msg_stub.c actions.c\
+dataplane_stub.c bw_stub.c actions_stub.c ce_stub.c phy_stub.c
+
+test_actions_MODULES = lib lib/scenario cp/fsm cp cp/msg cp/msg/stub cp/eoc/sta/action\
+cp/eoc/sta/mgr cp/secu/stub mac/common cp/beacon/stub cp/sta/mgr mac/sar/stub\
+cp/sta/core/stub cp/cco/action/stub cl/stub cp/cl_interf\
+interface/stub cp/secu ce/tx/stub\
+cp/eoc/sta/action/stub cp/sta/action bsu/stub
+
+test_actions_CONFIG_MODULES = mac/pbproc cl mac/sar
+
+cp_eoc_sta_action_MODULE_SOURCES = drv.c poweron.c assoc.c sleep.c vs_eoc.c cco_stub.c
+cp_eoc_sta_action_stub_MODULE_SOURCES = bridge.c
+cp_eoc_sta_mgr_MODULE_SOURCES = sta_own_data.c sta_mgr.c
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_sta_action_MODULE_SOURCES = vs.c
+cp_msg_MODULE_SOURCES = msg_drv.c mme.c
+cp_msg_stub_MODULE_SOURCES = msg_cc.c msg_cm.c msg_vs.c
+
+cp_MODULE_MODULES =
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
+
+include $(BASE)/common/make/top.mk
+
diff --git a/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/inc/context.h b/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/inc/context.h
new file mode 100644
index 0000000000..969dc76f9d
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/inc/context.h
@@ -0,0 +1,85 @@
+#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/tables.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 "cp/sta/core/defs.h"
+#include "cp/sta/action/inc/context.h"
+#include "cp/msg/inc/context.h"
+#include "lib/rnd.h"
+#include "interface/interface.h"
+#include "mac/sar/sar.h"
+#include "mac/sar/inc/sar_context.h"
+#include "cl/cl.h"
+#include "cl/inc/context.h"
+#include "cp/cl_interf/cl_interf.h"
+#include "cp/cl_interf/inc/context.h"
+#include "hal/phy/phy.h"
+#include "cp/beacon/inc/beacon.h"
+#include "cp/beacon/beacon.h"
+#include "ce/tx/inc/tx.h"
+#include "cp/cco/action/inc/cco_action.h"
+
+#define CP_NID_SIZE_BITS 54
+
+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;
+ /** station manager context*/
+ cp_sta_mgr_t sta_mgr;
+ /** MAC config contest*/
+ mac_config_t *mac_config;
+ cp_sta_action_t sta_action;
+ cp_msg_t msg;
+ lib_rnd_t rnd;
+ interface_t *interface;
+ /** Mac store /dataplane */
+ mac_store_t *mac_store;
+ /** Convergence Layer context */
+ cl_t *cl;
+ /** Segmentation and reassembly context */
+ sar_t *sar;
+ /** PBProc. */
+ pbproc_t *pbproc;
+ cp_cl_interf_t cl_interf;
+ /** Phy context. */
+ phy_t *phy;
+
+ cp_beacon_t beacon;
+ ce_tx_t ce_tx;
+ ce_rx_t *ce_rx;
+
+ bsu_t *bsu;
+ cp_cco_action_t cco_action;
+};
+
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/core.h b/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/core.h
new file mode 100644
index 0000000000..2bd5fa51cd
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/core.h
@@ -0,0 +1,28 @@
+#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);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/defs.h b/cesar/cp/eoc/sta/action/test/utest/actions-override/cp/sta/core/defs.h
new file mode 100644
index 0000000000..9698b44e93
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/actions-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/sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..6bbe720571
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/actions-override/mac/sar/inc/sar_context.h
@@ -0,0 +1,38 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/fsm-Config b/cesar/cp/eoc/sta/action/test/utest/fsm-Config
new file mode 100644
index 0000000000..37922ef4cf
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/fsm-Config
@@ -0,0 +1,7 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_sta.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_MSG_EOC_DRV_MME = y
+#CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
diff --git a/cesar/cp/eoc/sta/action/test/utest/fsm-Makefile b/cesar/cp/eoc/sta/action/test/utest/fsm-Makefile
new file mode 100644
index 0000000000..de78a138b6
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/fsm-Makefile
@@ -0,0 +1,16 @@
+BASE = ../../../../../..
+
+VARIANT = fsm
+
+INCLUDES = cp/eoc/sta/action/test/utest cp/eoc/sta/action/test/utest/fsm-override
+
+HOST_PROGRAMS = test_fsm
+test_fsm_SOURCES = test_fsm.c fsm_stub.c actions.c
+test_fsm_MODULES = lib lib/scenario cp/fsm cp mac/sar/stub
+test_fsm_CONFIG_MODULES = cp/sta/mgr cp/msg mac/common cl mac/sar
+cp_fsm_MODULE_SOURCES = fsm.c events.c
+cp_MODULE_MODULES =
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
+
+include $(BASE)/common/make/top.mk
+
diff --git a/cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/inc/context.h b/cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/inc/context.h
new file mode 100644
index 0000000000..edc1fde804
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/inc/context.h
@@ -0,0 +1,35 @@
+#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"
+
+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;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/sta/core/core.h b/cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/sta/core/core.h
new file mode 100644
index 0000000000..352368b45b
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/fsm-override/cp/sta/core/core.h
@@ -0,0 +1,26 @@
+#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
+ */
+
+BEGIN_DECLS
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx);
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..6bbe720571
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/fsm-override/mac/sar/inc/sar_context.h
@@ -0,0 +1,38 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/inc/scenario_defs.h b/cesar/cp/eoc/sta/action/test/utest/inc/scenario_defs.h
new file mode 100644
index 0000000000..c415b7a55d
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/inc/scenario_defs.h
@@ -0,0 +1,263 @@
+#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/msg/msg.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/sta/mgr/net.h"
+#include "cp/fsm/fsm.h"
+#include "cl/cl_mactotei.h"
+#include "mac/common/tonemap.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
+
+
+/* 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)
+
+#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_sta_action_drv__drv_sta_set_config_req, \
+ cp_fsm__STARTED__poweron__idle__to_poweron, \
+ cp_fsm__STOPPING__poweron__many__to_idle,\
+ cp_fsm__STOPPING__drv__stopping__stopped,\
+ cp_fsm__DETECTING_BEACON__sta_clear_status, \
+ cp_fsm__DETECTING_BEACON__BEACON, \
+ cp_fsm__DETECTING_BEACON__BEACON_NOT_RECEIVED, \
+ cp_fsm__DETECTING_BEACON__nd_beacon, \
+ cp_fsm__DETECTING_BEACON__nd_beacon_timeout, \
+ cp_fsm__ASSOCIATING__start_retry_timer, \
+ cp_fsm__ASSOCIATING__timeout_associating, \
+ cp_fsm__ASSOCIATING__CC_ASSOC_CNF, \
+ cp_fsm__ASSOCIATING__no_beacons, \
+ cp_fsm__ASSOCIATING__beacon_not_received, \
+ cp_fsm__ASSOCIATING__stop_retry_timer, \
+ cp_fsm__UNASSOCIATED__start_retry_timer, \
+ cp_fsm__UNASSOCIATED__enter_sleep_unassociated, \
+ cp_fsm__UNASSOCIATED__retry_unassociated, \
+ cp_fsm__UNASSOCIATED__stop_retry_timer, \
+ cp_fsm__SLEEP_UNASSOCIATED__exit_sleep_unassociated, \
+ cp_fsm__ASSOCIATED__no_beacons, \
+ cp_fsm__ASSOCIATED__CC_LEAVE_IND, \
+ cp_fsm__ASSOCIATED__CM_GET_KEY_CNF, \
+ cp_fsm__ASSOCIATED__timeout_associating, \
+ cp_fsm__ASSOCIATED__encrypt_payload_rsp, \
+ cp_fsm__ASSOCIATED__cm_chan_est_ind, \
+ cp_fsm__ASSOCIATED__cm_update_tm_ind, \
+ cp_fsm__AUTHENTICATED__no_beacons, \
+ cp_fsm__AUTHENTICATED__BEACON, \
+ cp_fsm__AUTHENTICATED__CC_LEAVE_IND, \
+ cp_fsm__AUTHENTICATED__sleep_enter_cnf, \
+ cp_fsm__AUTHENTICATED__drv__started__drv_sta_mac_stop_req,\
+ cp_fsm__AUTHENTICATED__process_cm_brg_info_req,\
+ cp_fsm__AUTHENTICATED__process_cm_brg_info_cnf,\
+ cp_fsm__AUTHENTICATED__CM_SET_KEY_REQ,\
+ cp_fsm__AUTHENTICATED__CM_NW_STATS_REQ,\
+ cp_fsm__AUTHENTICATED__set_out_lev_ind,\
+ cp_fsm__SLEEP_AUTHENTICATED__no_beacons, \
+ cp_fsm__SLEEP_AUTHENTICATED__sleep_exit_rsp,\
+ cp_fsm__CCO__bridge_first_com,\
+ cp_msg_vs_get_tonemap_req_receive, \
+ cp_msg_vs_get_tonemap_cnf_send
+
+
+/* MME send event. */
+#define __ms(event, param...) \
+typedef struct \
+{ \
+ cp_mme_peer_t peer; \
+ 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;
+
+
+__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)
+
+#undef __ms
+#undef __mr
+#undef __p_
+
+typedef struct
+{
+ cp_fsm_branch_t branch;
+} scenario_event_transition_with_branch_t;
+
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_mac_addr_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_cco_pref_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_was_cco_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_dpw_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_nid_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_tonemask_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_key_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_dak_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_mac_start_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_npw_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_sl_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPING__poweron__many__to_idle_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPING__drv__stopping__stopped_t;
+typedef scenario_empty_t scenario_event_cp_fsm__CCO__bridge_first_com_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_m_sta_hfid_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_u_sta_hfid_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STOPPED__drv_sta_set_avln_hfid_req_t;
+typedef scenario_empty_t scenario_event_cp_sta_action_drv__drv_sta_set_config_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STARTED__poweron__idle__to_poweron_t;
+typedef scenario_empty_t scenario_event_cp_fsm__DETECTING_BEACON__sta_clear_status_t;
+typedef scenario_empty_t scenario_event_cp_fsm__DETECTING_BEACON__BEACON_t;
+typedef scenario_empty_t scenario_event_cp_fsm__DETECTING_BEACON__BEACON_NOT_RECEIVED_t;
+typedef scenario_empty_t scenario_event_cp_fsm__DETECTING_BEACON__nd_beacon_t;
+typedef scenario_empty_t scenario_event_cp_fsm__DETECTING_BEACON__nd_beacon_timeout_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATING__start_retry_timer_t;
+typedef scenario_event_transition_with_branch_t scenario_event_cp_fsm__ASSOCIATING__timeout_associating_t;
+typedef scenario_event_transition_with_branch_t scenario_event_cp_fsm__ASSOCIATING__CC_ASSOC_CNF_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATING__no_beacons_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATING__beacon_not_received_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATING__stop_retry_timer_t;
+typedef scenario_empty_t scenario_event_cp_fsm__UNASSOCIATED__start_retry_timer_t;
+typedef scenario_empty_t scenario_event_cp_fsm__UNASSOCIATED__enter_sleep_unassociated_t;
+typedef scenario_empty_t scenario_event_cp_fsm__UNASSOCIATED__retry_unassociated_t;
+typedef scenario_empty_t scenario_event_cp_fsm__UNASSOCIATED__stop_retry_timer_t;
+typedef scenario_empty_t scenario_event_cp_fsm__SLEEP_UNASSOCIATED__exit_sleep_unassociated_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATED__no_beacons_t;
+//typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATED__CC_LEAVE_IND_t;
+typedef scenario_event_transition_with_branch_t scenario_event_cp_fsm__ASSOCIATED__CC_LEAVE_IND_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATED__timeout_associating_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATED__cm_chan_est_ind_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATED__cm_update_tm_ind_t;
+typedef scenario_event_transition_with_branch_t scenario_event_cp_fsm__ASSOCIATED__CM_GET_KEY_CNF_t;
+typedef scenario_empty_t scenario_event_cp_fsm__ASSOCIATED__encrypt_payload_rsp_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__no_beacons_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__BEACON_t;
+//typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__CC_LEAVE_IND_t;
+typedef scenario_event_transition_with_branch_t scenario_event_cp_fsm__AUTHENTICATED__CC_LEAVE_IND_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__sleep_enter_cnf_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__drv__started__drv_sta_mac_stop_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__process_cm_brg_info_req_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__process_cm_brg_info_cnf_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__CM_SET_KEY_REQ_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__CM_NW_STATS_REQ_t;
+typedef scenario_empty_t scenario_event_cp_fsm__AUTHENTICATED__set_out_lev_ind_t;
+typedef scenario_empty_t scenario_event_cp_fsm__SLEEP_AUTHENTICATED__no_beacons_t;
+typedef scenario_empty_t scenario_event_cp_fsm__SLEEP_AUTHENTICATED__sleep_exit_rsp_t;
+
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest/inc/test_sta_action.h b/cesar/cp/eoc/sta/action/test/utest/inc/test_sta_action.h
new file mode 100644
index 0000000000..48172abd46
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/inc/test_sta_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_sta_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/sta/action/test/utest/src/actions.c b/cesar/cp/eoc/sta/action/test/utest/src/actions.c
new file mode 100644
index 0000000000..81eaca3c0c
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/actions.c
@@ -0,0 +1,119 @@
+/* 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/sta/action/action.h"
+
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+
+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(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; \
+ mme.peks = CP_MME_PEKS_SPC_NOT_EMBEDDED; \
+ cp_sta_action_ ## ACTION (globals->cp, &mme); \
+}
+
+
+
+__m (vs__started__vs_get_tonemap_req)
+
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/actions_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/actions_stub.c
new file mode 100644
index 0000000000..2c934644ad
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/actions_stub.c
@@ -0,0 +1,96 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/actions_stub.c
+ * \brief Override STA FSM tables.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/scenario/scenario.h"
+#include "cp/inc/context.h"
+#include "cp/eoc/sta/action/drv.h"
+
+
+void cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+void cp_sta_action_poweron__idle__to_poweron (cp_t *ctx);
+void cp_sta_action_poweron__many__to_idle (cp_t *ctx);
+void cp_eoc_sta_action_assoc__beacon_received (cp_t *ctx);
+void cp_eoc_sta_action_assoc__beacon_not_received (cp_t *ctx);
+void cp_eoc_sta_action_assoc__detecting_detected (cp_t *ctx);
+void cp_eoc_sta_action_assoc__detecting_timeout (cp_t *ctx);
+void cp_eoc_sta_action_sleep__unassociated_enter_sleep (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associating_timeout (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associating_no_beacons (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx);
+void cp_eoc_sta_action_auth__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+void cp_eoc_sta_action_assoc__associated_timeout (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associated_no_beacons (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associated_leave (cp_t *ctx);
+void cp_eoc_sta_action_assoc__associated_key_cnf (cp_t *ctx);
+void ce_tx_process__cm_chan_est_ind (cp_t *ctx, cp_mme_rx_t *mme);
+void ce_tx_process__cm_update_tm_ind (cp_t *ctx, cp_mme_rx_t *mme);
+void cp_eoc_sta_action_assoc__authenticated_no_beacons (cp_t *ctx);
+void cp_beacon_beacon_not_received (cp_t *ctx);
+void cp_eoc_sta_action_sleep__authenticated_sleep_enter (cp_t *ctx);
+void cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta);
+void cp_eoc_sta_action_auth__authenticated_set_out_lev(cp_t *ctx, cp_mme_rx_t *mme);
+void cp_eoc_sta_action_auth__authenticated_set_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+void cp_eoc_sta_action_auth__authenticated_key_cnf(cp_t *ctx);
+void cp_sta_action_process_cm_brg_info_req (cp_t *ctx, cp_mme_rx_t *mme);
+void cp_sta_action_process_cm_brg_info_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+void cp_eoc_sta_action_sleep__sleep_unassociated_exit_sleep (cp_t *ctx);
+void cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons (cp_t *ctx);
+void cp_eoc_sta_action_sleep__sleep_authenticated_exit (cp_t *ctx);
+void cp_eoc_sta_action_assoc__authenticated_leave (cp_t *ctx);
+void cp_sta_action_unassoc__start_retry_timer (cp_t *ctx);
+void cp_sta_action_unassoc__stop_retry_timer (cp_t *ctx);
+void cp_sta_action_assoc__start_retry_timer (cp_t *ctx);
+void cp_sta_action_assoc__stop_retry_timer (cp_t *ctx);
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+uint
+log (u8 value);
+
+void cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+u8
+cp_sta_action_get_average_ble (cp_t *ctx, cp_tei_t tei, bool tx,
+ bool fc_format)
+{
+ return 0;
+}
+
+uint
+log (u8 value)
+{
+return value;
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/beacon_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/beacon_stub.c
new file mode 100644
index 0000000000..66add568fb
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/beacon_stub.c
@@ -0,0 +1,29 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/beacon_stub.c
+ * \brief Beacon stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "cp/beacon/beacon.h"
+
+#include "lib/scenario/scenario.h"
+
+
+void
+cp_beacon_deactivate (cp_t *ctx)
+{
+
+}
+
+void
+cp_beacon_poweron_init (cp_t *ctx)
+{
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/bw_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/bw_stub.c
new file mode 100644
index 0000000000..b4a249feec
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/bw_stub.c
@@ -0,0 +1,28 @@
+#include "common/std.h"
+#include "lib/blk.h"
+#include "lib/slab.h"
+#include "lib/list.h"
+
+#include "cp/defs.h"
+#include "cp/cp.h"
+#include "cp/cco/bw/bw.h"
+
+#include "cp/inc/context.h"
+#include "mac/ca/inc/context.h"
+#include "cp/cco/bw/inc/context.h"
+
+#include "cp/eoc/cco/bw/bw.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+
+#include "mac/common/sta.h"
+
+void
+cp_eoc_cco_bw_allocations_adjust (cp_t *ctx, bool adjust)
+{
+}
+
+void
+cp_eoc_cco_bw_sta_allocations (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/ce_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/ce_stub.c
new file mode 100644
index 0000000000..8d99b65842
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/ce_stub.c
@@ -0,0 +1,24 @@
+/* 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;
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/cp_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/cp_stub.c
new file mode 100644
index 0000000000..672ffb388b
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/cp_stub.c
@@ -0,0 +1,48 @@
+/* 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"
+
+/**
+ * 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_nmk (ctx, nmk, 0);
+ cp_sta_own_data_set_nid (ctx, nid);
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/dataplane_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/dataplane_stub.c
new file mode 100644
index 0000000000..d8b7edd8fc
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/dataplane_stub.c
@@ -0,0 +1,28 @@
+/* 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"
+
+void
+sar_sta_remove (sar_t *ctx, u8 tei)
+{
+ cp_t *cp = (void *) ctx;
+ dbg_check (mac_store_sta_remove (cp->mac_store, tei));
+}
+
+
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/fsm_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/fsm_stub.c
new file mode 100644
index 0000000000..d2755d03ae
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/fsm_stub.c
@@ -0,0 +1,637 @@
+/* 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_eoc_sta_action_auth__authenticated_key_cnf(cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__detecting_detected (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__detecting_timeout (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associating_timeout (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associating_no_beacons (cp_t *ctx);
+
+void
+cp_eoc_sta_action_sleep__unassociated_enter_sleep (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__unassociated_retry (cp_t *ctx);
+
+void
+cp_eoc_sta_action_sleep__sleep_unassociated_exit_sleep (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associated_key_cnf (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associated_no_beacons (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associated_timeout (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__associated_leave (cp_t *ctx);
+
+void
+cp_eoc_sta_action_sleep__authenticated_sleep_enter (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__authenticated_no_beacons (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__authenticated_leave (cp_t *ctx);
+
+void
+cp_eoc_sta_action_sleep__sleep_authenticated_exit (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__beacon_received (cp_t *ctx);
+
+void
+cp_eoc_sta_action_assoc__beacon_not_received (cp_t *ctx);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_was_cco_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dpw_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_nid_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_tonemask_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_dak_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_mac_start_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_poweron__idle__to_poweron (cp_t *ctx);
+
+void
+cp_beacon_beacon_not_received (cp_t *ctx);
+
+void
+ce_tx_process__cm_chan_est_ind (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+ce_tx_process__cm_update_tm_ind (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_process_cm_brg_info_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_process_cm_brg_info_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_sta_clear_status (cp_t *ctx);
+
+void
+cp_sta_action_unassoc__start_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_assoc__start_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_unassoc__stop_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_assoc__stop_retry_timer (cp_t *ctx);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_npw_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_sl_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx,
+ cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx);
+
+void
+cp_sta_action_bridge_first_com (cp_t *ctx, cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx);
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_eoc_sta_action_auth__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_eoc_sta_action_auth__authenticated_set_key_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme_rx);
+
+void
+cp_eoc_sta_action_auth__authenticated_set_out_lev(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_vs__started__vs_get_snr_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme);
+
+void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_drv__drv_sta_set_eoc_config_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_detect__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_info_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_diagnostic_info_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_sta_action_vs__started__vs_get_ce_stats_req (cp_t *ctx, cp_mme_rx_t *mme);
+
+/* Include generated tables. */
+#include "cp_fsm_tables.h"
+
+void
+cp_sta_action_drv__drv_sta_set_config_req (cp_t *ctx, cp_mme_rx_t *mme_rx)
+{
+ scenario_event (cp_sta_action_drv__drv_sta_set_config_req);
+}
+
+void
+cp_eoc_sta_action_auth__authenticated_set_out_lev(cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__set_out_lev_ind);
+}
+
+void
+cp_sta_action_process_cm_sta_cap_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+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_poweron__idle__to_poweron (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STARTED__poweron__idle__to_poweron);
+}
+
+void
+cp_beacon_beacon_not_received (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATING__beacon_not_received);
+}
+
+void
+cp_eoc_sta_action_assoc__detecting_detected (cp_t *ctx)
+{
+ scenario_event (cp_fsm__DETECTING_BEACON__nd_beacon);
+}
+
+void
+cp_eoc_sta_action_assoc__detecting_timeout (cp_t *ctx)
+{
+ scenario_event (cp_fsm__DETECTING_BEACON__nd_beacon_timeout);
+}
+
+void
+cp_eoc_sta_action_assoc__associating_timeout (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATING__timeout_associating, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATING__CC_ASSOC_CNF, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_eoc_sta_action_assoc__associating_no_beacons (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATING__no_beacons);
+}
+
+void
+cp_eoc_sta_action_sleep__unassociated_enter_sleep (cp_t *ctx)
+{
+ scenario_event (cp_fsm__UNASSOCIATED__enter_sleep_unassociated);
+}
+
+void
+cp_eoc_sta_action_assoc__unassociated_retry (cp_t *ctx)
+{
+ scenario_event (cp_fsm__UNASSOCIATED__retry_unassociated);
+}
+
+void
+cp_eoc_sta_action_sleep__sleep_unassociated_exit_sleep (cp_t *ctx)
+{
+ scenario_event (cp_fsm__SLEEP_UNASSOCIATED__exit_sleep_unassociated);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_key_cnf (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATED__encrypt_payload_rsp);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_no_beacons (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATED__no_beacons);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_timeout (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATED__timeout_associating);
+}
+
+void
+cp_eoc_sta_action_assoc__associated_leave (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATED__CC_LEAVE_IND, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_eoc_sta_action_sleep__authenticated_sleep_enter (cp_t *ctx)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__sleep_enter_cnf);
+}
+
+void
+cp_eoc_sta_action_assoc__authenticated_no_beacons (cp_t *ctx)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__no_beacons);
+}
+
+void
+cp_eoc_sta_action_assoc__authenticated_leave (cp_t *ctx)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__CC_LEAVE_IND, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_eoc_sta_action_sleep__sleep_authenticated_exit (cp_t *ctx)
+{
+ scenario_event (cp_fsm__SLEEP_AUTHENTICATED__sleep_exit_rsp);
+}
+
+void
+cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons (cp_t *ctx)
+{
+ scenario_event (cp_fsm__SLEEP_AUTHENTICATED__no_beacons);
+}
+
+void
+cp_eoc_sta_action_assoc__beacon_received (cp_t *ctx)
+{
+
+}
+
+void
+cp_eoc_sta_action_assoc__beacon_not_received (cp_t *ctx)
+{
+ scenario_event (cp_fsm__DETECTING_BEACON__BEACON_NOT_RECEIVED);
+}
+
+void
+ce_tx_process__cm_chan_est_ind (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__ASSOCIATED__cm_chan_est_ind);
+}
+
+void
+ce_tx_process__cm_update_tm_ind (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__ASSOCIATED__cm_update_tm_ind);
+}
+
+void
+cp_eoc_sta_action_sta_clear_status (cp_t *ctx)
+{
+ scenario_event (cp_fsm__DETECTING_BEACON__sta_clear_status);
+}
+
+void
+cp_sta_action_unassoc__start_retry_timer (cp_t *ctx)
+{
+ scenario_event (cp_fsm__UNASSOCIATED__start_retry_timer);
+}
+
+void
+cp_sta_action_assoc__start_retry_timer (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATING__start_retry_timer);
+}
+
+void
+cp_sta_action_unassoc__stop_retry_timer (cp_t *ctx)
+{
+ scenario_event (cp_fsm__UNASSOCIATED__stop_retry_timer);
+}
+
+void
+cp_sta_action_assoc__stop_retry_timer (cp_t *ctx)
+{
+ scenario_event (cp_fsm__ASSOCIATING__stop_retry_timer);
+}
+
+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_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_sta_action_auth__authenticated_key_cnf(cp_t *ctx)
+{
+}
+
+void
+cp_sta_action_poweron__many__to_idle (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STOPPING__poweron__many__to_idle);
+}
+
+void
+cp_sta_action_drv__stopping__stopped (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STOPPING__drv__stopping__stopped);
+}
+
+void
+cp_sta_action_drv__started__drv_sta_mac_stop_req (cp_t *ctx,
+ cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__drv__started__drv_sta_mac_stop_req);
+}
+
+void
+cp_sta_action_process_cm_brg_info_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__process_cm_brg_info_req);
+}
+
+void
+cp_sta_action_process_cm_brg_info_cnf (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__process_cm_brg_info_cnf);
+}
+
+void
+cp_sta_action_vs__started__vs_get_tonemap_req (cp_t *ctx, cp_mme_rx_t *mme_rx)
+{
+}
+
+void
+cp_eoc_sta_action_auth__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__BEACON);
+}
+
+void
+cp_eoc_sta_action_auth__authenticated_set_key_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__CM_SET_KEY_REQ);
+}
+
+void
+cp_sta_action_vs__started__vs_get_snr_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_info_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+ scenario_event (cp_fsm__AUTHENTICATED__CM_NW_STATS_REQ);
+}
+
+void
+cp_sta_action_process_cm_link_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
+{
+}
+
+void
+cp_sta_action_drv__drv_sta_set_slave_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_drv__drv_sta_set_eoc_config_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_eoc_sta_action_detect__beacon_received (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+scenario_event (cp_fsm__DETECTING_BEACON__BEACON);
+}
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_info_req (cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_diagnostic_info_req (cp_t *ctx, cp_mme_rx_t *mme)
+{}
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
+
+void
+cp_sta_action_vs__started__vs_get_ce_stats_req (cp_t *ctx, cp_mme_rx_t *mme)
+{
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/msg_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/msg_stub.c
new file mode 100644
index 0000000000..7666adbfb6
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/msg_stub.c
@@ -0,0 +1,476 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/msg.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+#include "cp/cp.h"
+#include "cp/msg/msg.h"
+
+#include "lib/scenario/scenario.h"
+#include "mac/common/tonemap.h"
+
+#include "cp/inc/context.h"
+
+#include "hal/phy/defs.h"
+#include "cp/msg/inc/vs_get_tonemap.h"
+#include "cp/msg/inc/cm_key.h"
+
+#include <string.h>
+
+#include "cp/msg/inc/msg_vs_eoc.h"
+
+void
+cp_msg_init (cp_t *ctx) __attribute__((weak));
+
+void
+cp_msg_init (cp_t *ctx) {}
+
+void
+cp_msg_uninit (cp_t *ctx) __attribute__((weak));
+
+void
+cp_msg_uninit (cp_t *ctx) {}
+
+void
+cp_msg_dispatch (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+void
+cp_msg_dispatch (cp_t *ctx, cp_mme_rx_t *mme) {}
+
+cp_mme_tx_t *
+cp_msg_mme_init (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype) __attribute__((weak));
+
+bool
+cp_msg_imac_get_discover_list_req_receive (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_imac_get_discover_list_cnf_send_begin (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_imac_get_discover_list_cnf_result_t result, u8 version,
+ u8 num_stations) __attribute__((weak));
+
+void
+cp_msg_imac_get_discover_list_cnf_send (cp_t *ctx, cp_mme_tx_t *mme,
+ const cp_msg_imac_discover_list_sta_info_t *data) __attribute__((weak));
+
+void
+cp_msg_imac_get_discover_list_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme) __attribute__((weak));
+
+bool
+cp_msg_vs_eoc_cco_get_real_time_stats_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *control) __attribute__((weak));
+
+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_stats_req_result_t status, real_time_stats_t *rt_stats ) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_mme_init (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype)
+{
+
+ cp_mme_tx_t my_mme;
+ cp_mme_tx_t *mme = &my_mme;
+
+ u64 data;
+ u8 buffer[1024];
+ bitstream_t bitstream;
+
+ if ((mmtype == DRV_STA_GET_KEY_CNF) || (mmtype == VS_EOC_CCO_SET_OUT_LEV_IND))
+ {
+ 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 = swap16 (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 = my_mme.bitstream.data;
+ mme->bitstream.data_bits = my_mme.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 = swap16 (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;
+}
+
+cp_mme_tx_t *
+cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype,
+ cp_mme_peks_t peks,
+ const cp_secu_protocol_run_t *prun) __attribute__((weak));
+cp_mme_tx_t *
+cp_msg_mme_init_encrypted (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype,
+ cp_mme_peks_t peks,
+ const cp_secu_protocol_run_t *prun)
+{
+ return NULL;
+}
+
+void
+cp_msg_mme_write_frag_header (cp_t *ctx, cp_mme_tx_t *msg, bitstream_t *bs,
+ cp_mmtype_t mmtype) __attribute__((weak));
+
+void
+cp_msg_mme_write_frag_header (cp_t *ctx, cp_mme_tx_t *msg, bitstream_t *bs,
+ cp_mmtype_t mmtype) {}
+
+cp_mme_tx_t *
+cp_msg_mme_init_frag (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ uint fmi_nbFrag, uint fmi_fnmi, uint fmi_ssn) __attribute__((weak));
+
+cp_mme_tx_t *
+cp_msg_mme_init_frag (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ uint fmi_nbFrag, uint fmi_fnmi, uint fmi_ssn)
+{
+ return NULL;
+}
+
+void
+cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme) __attribute__((weak));
+
+void
+cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme) {}
+
+cp_mme_rx_t *
+cp_msg_mme_read_header (cp_t *ctx, u8 *mme, uint length, cp_tei_t tei,
+ uint *fmi, bool cl_data) __attribute__((weak));
+
+cp_mme_rx_t *
+cp_msg_mme_read_header (cp_t *ctx, u8 *mme, uint length, cp_tei_t tei,
+ uint *fmi, bool cl_data)
+{
+ return NULL;
+}
+
+bool
+cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme) __attribute__((weak));
+
+bool
+cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ return true;
+}
+
+void
+cp_msg_mme_rx_change_buffer (cp_mme_rx_t *msg) __attribute__((weak));
+
+void
+cp_msg_mme_rx_change_buffer (cp_mme_rx_t *msg) {}
+
+void
+cp_msg_mme_tx_change_buffer (bitstream_t *bs, cp_mme_tx_t *mme) __attribute__((weak));
+
+void
+cp_msg_mme_tx_change_buffer (bitstream_t *bs, cp_mme_tx_t *mme) {}
+
+void
+cp_msg_mme_read_error_process (bitstream_t *ctx, void *user_data) __attribute__((weak));
+
+void
+cp_msg_mme_read_error_process (bitstream_t *ctx, void *user_data)
+{
+}
+
+bool
+cp_msg_imac_get_discover_list_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ return true;
+}
+
+cp_mme_tx_t *
+cp_msg_imac_get_discover_list_cnf_send_begin (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_msg_imac_get_discover_list_cnf_result_t result, u8 version,
+ u8 num_stations)
+{
+ cp_mme_tx_t * mme;
+
+ dbg_assert (ctx);
+ dbg_assert (peer);
+
+ mme = cp_msg_mme_init (ctx, peer, IMAC_GET_DISCOVER_LIST_CNF);
+ dbg_assert (mme);
+
+ return mme;
+}
+
+void
+cp_msg_imac_get_discover_list_cnf_send (cp_t *ctx, cp_mme_tx_t *mme,
+ const cp_msg_imac_discover_list_sta_info_t *data)
+{
+}
+
+void
+cp_msg_imac_get_discover_list_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme)
+{
+}
+
+
+#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_pdecl_(TYPE, PARAM, KIND) , TYPE PARAM
+#define __ms_test_peer \
+ test_fail_unless (peer->mac == param->peer.mac); \
+ test_fail_unless (peer->vlan_tag == param->peer.vlan_tag); \
+ 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) \
+}
+
+__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_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))
+
+bool
+cp_msg_vs_get_snr_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ mac_t *mac_addr,
+ cp_msg_vs_get_snr_req_int_t *tm_int_i,
+ u8 *int_id,
+ u8 *carrier_gr)
+{
+ return true;
+}
+
+void
+cp_msg_vs_get_snr_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ const cp_msg_vs_get_snr_cnf_t *data)
+{
+}
+
+bool
+cp_msg_cc_assoc_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cc_assoc_cnf_t *data)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (data);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ data->result = 0;
+ data->nid = cp_sta_own_data_get_nid (ctx);
+ data->snid = cp_sta_own_data_get_snid (ctx);
+ data->sta_tei = cp_sta_own_data_get_tei (ctx);
+
+ /* Verify. */
+ if ((data->nid >> CP_NID_SIZE_BITS)
+ || (data->result >= CP_MSG_CC_ASSOC_CNF_RESULT_NB)
+ || (!MAC_TEI_IS_STA (data->sta_tei)))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool
+cp_msg_cm_get_key_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cm_get_key_cnf_t *data)
+{
+ // Within the first function call, key type will be CP_MSG_KEY_NEK. Within the second
+ // call, key type will be CP_MSG_KEY_TEK
+ static enum cp_msg_key_type_t key_type = CP_MSG_KEY_NEK;
+ data->nid = cp_sta_own_data_get_nid (ctx);
+ data->result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ data->key_type = key_type;
+ key_type++;
+ return true;
+}
+
+bool
+cp_msg_cm_set_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cm_set_key_req_t *data)
+{
+ data->key_type = CP_MSG_KEY_NEK;
+ data->nid = cp_sta_own_data_get_nid (ctx);
+ return true;
+}
+
+bool
+cp_msg_cc_leave_ind_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ enum cp_msg_cc_leave_ind_reason_t *reason,
+ cp_nid_t *nid)
+{
+ *nid = cp_sta_own_data_get_nid (ctx);
+ return true;
+}
+
+bool
+cp_msg_eoc_sta_vs_set_out_lev_ind_receive(cp_t *ctx, cp_mme_rx_t *mme, uint *output_level)
+{
+ return true;
+}
+
+bool
+cp_msg_vs_eoc_cco_get_info_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *internal_eoc_index, u8 *control)
+{
+return true;
+}
+
+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, u8 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)
+{
+}
+
+
+bool
+cp_msg_vs_eoc_cco_diagnostic_info_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *internal_eoc_index, u8 *control)
+{
+return true;
+}
+
+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)
+{
+}
+
+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 (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_vs_eoc_cco_get_real_time_stats_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *control)
+{
+ 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_stats_req_result_t status, real_time_stats_t *rt_stats )
+{
+}
+
+void
+cp_msg_vs_get_ce_stats_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ u8 version,
+ u8 result,
+ sta_t *sta,
+ tonemask_info_t *ti)
+{
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/pb_proc_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/pb_proc_stub.c
new file mode 100644
index 0000000000..f4c27d9ec4
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/pb_proc_stub.c
@@ -0,0 +1,44 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/multi/sta/action/test/utest/src.pb_proc_stub.c
+ * \brief General PB Processing functions.
+ * \ingroup pbproc
+ */
+
+
+#include "common/std.h"
+#include "mac/pbproc/inc/context.h"
+
+#include "hal/gpio/gpio.h"
+#include "mac/common/timings.h"
+
+#include "mac/pbproc/inc/fsm_top.h"
+#include "mac/pbproc/inc/fsm_handle_fc.h"
+#include "mac/pbproc/inc/fsm_rx_data.h"
+#include "mac/pbproc/inc/fsm_rx_beacon.h"
+#include "mac/pbproc/inc/fsm_rx_sound.h"
+#include "mac/pbproc/inc/fsm_tx_rts_cts.h"
+#include "mac/pbproc/inc/fsm_tx_data.h"
+#include "mac/pbproc/inc/fsm_tx_sound.h"
+
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{
+}
+
+void pbproc_parameters_adjust (pbproc_t *ctx, bool adjust)
+{
+}
+
+u8
+ce_rx_bl_nsr_compute_total_mean (ce_rx_bitloading_t *bl)
+{
+ return 1;
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/phy_stub.c b/cesar/cp/eoc/sta/action/test/utest/src/phy_stub.c
new file mode 100644
index 0000000000..ba991fe957
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/phy_stub.c
@@ -0,0 +1,26 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file
+ * \brief
+ * \ingroup
+ */
+
+#include "common/std.h"
+#include "cp/inc/context.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/sta/action/test/utest/src/test_actions.c b/cesar/cp/eoc/sta/action/test/utest/src/test_actions.c
new file mode 100644
index 0000000000..bf7edf50f9
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/test_actions.c
@@ -0,0 +1,1792 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_actions.c
+ * \brief Test FSM module.
+ * \ingroup test
+ */
+
+#include "stdio.h"
+#include "common/std.h"
+#include "lib/blk.h"
+#include "lib/scenario/scenario.h"
+#include "cp/inc/context.h"
+#include "cp/msg/msg.h"
+#include "lib/test.h"
+#include "lib/utils.h"
+#include "lib/swap.h"
+#include "lib/slab.h"
+#include "cp/eoc/sta/action/drv.h"
+#include "cp/fsm/fsm.h"
+#include "cp/inc/context.h"
+#include "cp/fsm/inc/tables.h"
+#include "cp/sta/core/core.h"
+#include "inc/test_sta_action.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "mac/pbproc/inc/context.h"
+#include "cp/eoc/sta/action/action.h"
+
+
+void
+test_case_association_and_authentication_action (test_t test)
+{
+ test_case_begin (test, "Asssociation and authentication");
+
+ 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;
+
+ bitstream_t bitstream;
+ u64 data;
+ 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_MAC_ADDR_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);
+ //Mac address
+ 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_NPW_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 npw[CP_NPW_MAX_SIZE + 1];
+
+ //sample network password: SPC-300_EoC_200MBps
+ strcpy(npw, "SPC-300_EoC_200MBps");
+
+ //zero padding
+ memset((npw + sizeof("SPC-300_EoC_200MBps")), '\0',
+ (sizeof(npw) - sizeof("SPC-300_EoC_200MBps")));
+
+ 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_NPW_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_NPW_MAX_SIZE; i++)
+ {
+ bitstream_access(&bitstream, &npw[i], 8);
+ }
+ bitstream_finalise(&bitstream);
+
+ cp_sta_action_drv__stopped__drv_sta_set_npw_req (&ctx, mme);
+
+ test_fail_unless (!(strcmp(ctx.sta_mgr.sta_own_data.npw, npw)));
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_SET_DPW_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 dpw[CP_NPW_MAX_SIZE + 1];
+
+ //sample device password: Spidcom_Eoc_Modem_user_121
+ strcpy(dpw, "Spidcom_Eoc_Modem_user_121");
+
+ //zero padding
+ memset((dpw + sizeof("Spidcom_Eoc_Modem_user_121")), '\0',
+ (sizeof(dpw) - sizeof("Spidcom_Eoc_Modem_user_121")));
+
+ 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_DPW_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_NPW_MAX_SIZE; i++)
+ {
+ bitstream_access(&bitstream, &dpw[i], 8);
+ }
+ bitstream_finalise(&bitstream);
+
+ cp_sta_action_drv__stopped__drv_sta_set_dpw_req (&ctx, mme);
+
+ test_fail_unless (!(strcmp(ctx.sta_mgr.sta_own_data.dpw, dpw)));
+ }
+ 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);
+
+ // 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);
+
+ 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_NID_REQ")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ uint cl;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ cp_nid_t nid;
+ cp_net_t *net;
+ sar_t sar;
+
+ //sample network id: 0x11223344556677
+ nid = 0x11223344556677ull;
+
+ 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_sta_mgr_init (&ctx);
+ ctx.sar = &sar;
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->mmtype = DRV_STA_SET_NID_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, &nid, 56);
+ bitstream_finalise (&bitstream);
+
+ mme->length = 7;
+
+ cp_sta_action_drv__stopped__drv_sta_set_nid_req (&ctx, mme);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nid == nid);
+
+ test_fail_unless (ctx.sta_mgr.our_avln->nid == nid);
+ }
+ 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;
+ strcpy(m_sta_hfid, "Spidcom_SPC_300_EoC_m_HFID_123");
+
+ //zero padding
+ memset((m_sta_hfid + sizeof("Spidcom_SPC_300_EoC_m_HFID_123")), '\0',
+ (sizeof(m_sta_hfid) - sizeof("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;
+ strcpy(u_sta_hfid, "Spidcom_SPC_300_EoC_u_HFID_123");
+
+ //zero padding
+ memset((u_sta_hfid + sizeof("Spidcom_SPC_300_EoC_u_HFID_123")), '\0',
+ (sizeof(u_sta_hfid) - sizeof("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;
+ strcpy(avln_hfid, "Spidcom_SPC_300_EoC_avln_HFID_123");
+
+ //zero padding
+ memset((avln_hfid + sizeof("Spidcom_SPC_300_EoC_avln_HFID_123")), '\0',
+ (sizeof(avln_hfid) - sizeof("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_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 == nid);
+
+ test_fail_unless (ctx.sta_mgr.our_avln->nid == 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_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);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.security_level == sl);
+
+ for (i = 0; i < COUNT (nmk.key); i++)
+ {
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nmk.key[i] == nmk.key[i]);
+ }
+
+ //STA that changes Security Level shall discard the previous NMK.
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nid != nid);
+
+ test_fail_unless (ctx.sta_mgr.our_avln->nid != 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 DRV_STA_SET_CONFIG_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 test_config[6] = "tei:1";
+
+ 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);
+ lib_stats_init ();
+
+ mme->mmtype = DRV_STA_SET_CONFIG_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 < 6; i++)
+ {
+ bitstream_access(&bitstream, &test_config[i], 8);
+ }
+ bitstream_finalise (&bitstream);
+
+ mme->length = 6;
+
+ cp_sta_action_drv__drv_sta_set_config_req (&ctx, mme);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_GET_KEY_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 buffer[1024];
+ cp_nid_t nid;
+ uint cl;
+ cp_net_t *net;
+ cp_key_t nmk;
+ cp_security_level_t sl;
+ u8 i;
+
+ //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_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sl = CP_SECURITY_LEVEL_SC;
+ cp_sta_own_data_set_nmk (&ctx, nmk, 0);
+ nid = cp_secu_nmk2nid (&ctx, nmk, sl);
+ cp_sta_own_data_set_nid (&ctx, nid);
+
+ mme->mmtype = DRV_STA_GET_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);
+
+ bitstream_finalise (&bitstream);
+
+ cp_sta_action_drv__drv_sta_get_key_req (&ctx, mme);
+
+ test_fail_unless (ctx.sta_mgr.sta_own_data.nid == nid);
+
+ 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);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_MAC_START_REQ")
+ {
+ cp_t ctx;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+ //cp_fsm_event_type_t result;
+
+ cp_fsm_init(&ctx);
+
+ mme->mmtype = DRV_STA_MAC_START_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_sta_action_drv__stopped__drv_sta_mac_start_req (&ctx, mme);
+ }
+ test_end;
+
+ test_begin (test, "Receiving and processing DRV_STA_MAC_STOP_REQ")
+ {
+ cp_t ctx;
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ bitstream_t bitstream;
+ u8 buffer[1024];
+
+ cp_fsm_init(&ctx);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ mme->peer.vlan_tag = 6;
+ mme->mmtype = DRV_STA_MAC_STOP_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_sta_action_drv__started__drv_sta_mac_stop_req (&ctx, mme);
+
+ test_fail_unless (ctx.sta_action.drv_peer.tei == mme->peer.tei);
+ test_fail_unless (ctx.sta_action.drv_peer.mac == mme->peer.mac);
+ test_fail_unless (ctx.sta_action.drv_peer.vlan_tag == mme->peer.vlan_tag);
+ }
+ test_end;
+
+ test_begin (test, "cp_eoc_sta_action_sta_clear_status")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ cp_sta_action_assoc_init (&ctx);
+ cp_eoc_sta_action_sta_clear_status(&ctx);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "Call to cp_eoc_sta_action_assoc__detecting_detected")
+ {
+ cp_t ctx;
+
+ cp_eoc_sta_action_assoc__detecting_detected (&ctx);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_assoc__detecting_timeout")
+ {
+ cp_t ctx;
+
+ cp_eoc_sta_action_assoc__detecting_timeout (&ctx);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_assoc__beacon_received")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bsu_beacon_t beacon;
+ bsu_beacon_t *pbeacon = &beacon;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ test_fail_unless(ctx.sta_action.assoc.beacon_succ == 0);
+
+ cp_eoc_sta_action_assoc__beacon_received (&ctx, pbeacon, net, sta);
+
+ test_fail_unless(ctx.sta_action.assoc.beacon_succ == 1);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_auth__beacon_received")
+ {
+ static pbproc_t ARCH_DLRAM_BSS pbproc_global;
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bsu_beacon_t beacon;
+ bsu_beacon_t *pbeacon = &beacon;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ ctx.pbproc = &pbproc_global;
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ ctx.pbproc->polled = true;
+ ((cp_sta_private_t *)sta)->is_cco = true;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_AUTHENTICATED;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_BEACON;
+
+ cp_eoc_sta_action_auth__beacon_received (&ctx, pbeacon, net, sta);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_AUTHENTICATED);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_assoc__associating_cnf")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 result;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ cp_tei_t tei;
+ u16 lease_time;
+ 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;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ result = 0;
+ lease_time = 2;
+ nid = 0x11223344556677ull;
+ snid = 5;
+ mme->peer.tei = tei = ctx.sta_mgr.sta_own_data.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);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ mme->mmtype = CC_ASSOC_CNF;
+ 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);
+ //Mac address
+ bitstream_access (&bitstream, &result, 8);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &snid, 8);
+ bitstream_access (&bitstream, &tei, 8);
+ bitstream_access (&bitstream, &lease_time, 16);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 12;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_ASSOCIATING;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF;
+
+ cp_eoc_sta_action_assoc__associating_cnf (&ctx, mme);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_ASSOCIATED);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_assoc__associating_no_beacons")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ cp_eoc_sta_action_assoc__associating_no_beacons(&ctx);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_assoc__unassociated_retry")
+ {
+ cp_t ctx;
+
+ cp_eoc_sta_action_assoc__unassociated_retry(&ctx);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_assoc__associated_key_cnf")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 result, eks, req_key_type;
+ cp_nid_t nid;
+ cp_snid_t snid=0;
+ cp_tei_t tei;
+ u8 buffer[1024];
+ cp_key_t nmk;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ mme->prun.my_nonce = ctx.sta_action.assoc.prun.my_nonce = lib_rnd32 (&ctx.rnd);
+ mme->prun.your_nonce = ctx.sta_action.assoc.prun.your_nonce = lib_rnd32 (&ctx.rnd);
+
+ result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ req_key_type = CP_MSG_KEY_NEK;
+ mme->prun.prn = ctx.sta_action.assoc.prun.prn = 1;
+ nid = 0x11223344556677ull;
+ eks = 0;
+ mme->prun.pid = ctx.sta_action.assoc.prun.pid = 2;
+ ctx.sta_action.assoc.prun.pmn = 1;
+ mme->prun.pmn = ctx.sta_action.assoc.prun.pmn + 1;
+ mme->peks = CP_MME_PEKS_DAK;
+
+ //sample network membership key:
+ nmk.key[0] = 0x11111111;
+ nmk.key[1] = 0x22222222;
+ nmk.key[2] = 0x33333333;
+ nmk.key[3] = 0x44444444;
+ 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);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ mme->mmtype = CM_GET_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, &req_key_type, 8);
+ bitstream_access (&bitstream, &mme->prun.my_nonce, 32);
+ bitstream_access (&bitstream, &mme->prun.your_nonce, 32);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &eks, 8);
+ bitstream_access (&bitstream, &mme->prun.pid, 8);
+ bitstream_access (&bitstream, &mme->prun.prn, 16);
+ bitstream_access (&bitstream, &mme->prun.pmn, 8);
+ bitstream_access (&bitstream, &nmk.key[0], 32);
+ bitstream_access (&bitstream, &nmk.key[1], 32);
+ bitstream_access (&bitstream, &nmk.key[2], 32);
+ bitstream_access (&bitstream, &nmk.key[3], 32);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 38;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_ASSOCIATED;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF;
+
+ cp_eoc_sta_action_assoc__associated_key_cnf (&ctx, mme);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_AUTHENTICATED);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_auth__authenticated_key_cnf")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 result, eks, req_key_type;
+ cp_nid_t nid;
+ cp_snid_t snid=0;
+ cp_tei_t tei;
+ u8 buffer[1024];
+ cp_key_t nmk;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ mme->prun.my_nonce = ctx.sta_action.assoc.prun.my_nonce = lib_rnd32 (&ctx.rnd);
+ mme->prun.your_nonce = ctx.sta_action.assoc.prun.your_nonce = lib_rnd32 (&ctx.rnd);
+
+ result = CP_MSG_CM_GET_KEY_CNF_RESULT_KEY_GRANTED;
+ req_key_type = CP_MSG_KEY_TEK;
+ mme->prun.prn = ctx.sta_action.assoc.prun.prn = 1;
+ nid = 0x11223344556677ull;
+ eks = 0;
+ mme->prun.pid = ctx.sta_action.assoc.prun.pid = 2;
+ ctx.sta_action.assoc.prun.pmn = 1;
+ mme->prun.pmn = 0xFF;
+ mme->peks = CP_MME_PEKS_DAK;
+
+ //sample network membership key:
+ nmk.key[0] = 0x11111111;
+ nmk.key[1] = 0x22222222;
+ nmk.key[2] = 0x33333333;
+ nmk.key[3] = 0x44444444;
+ 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);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ mme->mmtype = CM_GET_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, &req_key_type, 8);
+ bitstream_access (&bitstream, &mme->prun.my_nonce, 32);
+ bitstream_access (&bitstream, &mme->prun.your_nonce, 32);
+ bitstream_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &eks, 8);
+ bitstream_access (&bitstream, &mme->prun.pid, 8);
+ bitstream_access (&bitstream, &mme->prun.prn, 16);
+ bitstream_access (&bitstream, &mme->prun.pmn, 8);
+ bitstream_access (&bitstream, &nmk.key[0], 32);
+ bitstream_access (&bitstream, &nmk.key[1], 32);
+ bitstream_access (&bitstream, &nmk.key[2], 32);
+ bitstream_access (&bitstream, &nmk.key[3], 32);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 38;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_AUTHENTICATED;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF;
+
+ cp_eoc_sta_action_auth__authenticated_key_cnf (&ctx, mme);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_AUTHENTICATED);
+ test_fail_unless(cp_sta_get_authenticated (&ctx, sta));
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_auth__authenticated_set_key_req")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 eks, req_key_type, cco_cap;
+ cp_nid_t nid;
+ cp_snid_t snid=0;
+ cp_tei_t tei;
+ u8 buffer[1024];
+ cp_key_t nmk;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+ mme->prun.my_nonce = ctx.sta_action.nek_prun.my_nonce = lib_rnd32 (&ctx.rnd);
+ mme->prun.your_nonce = ctx.sta_action.nek_prun.your_nonce = lib_rnd32 (&ctx.rnd);
+
+ req_key_type = CP_MSG_KEY_NEK;
+ mme->prun.prn = ctx.sta_action.nek_prun.prn = 1;
+ nid = 0x11223344556677ull;
+ cco_cap = 1;
+ eks = 0;
+ mme->prun.pid = ctx.sta_action.nek_prun.pid = 2;
+ ctx.sta_action.nek_prun.pmn = 1;
+ mme->prun.pmn = ctx.sta_action.nek_prun.pmn + 1;
+ mme->peks = CP_MME_PEKS_DAK;
+
+ //sample network membership key:
+ nmk.key[0] = 0x11111111;
+ nmk.key[1] = 0x22222222;
+ nmk.key[2] = 0x33333333;
+ nmk.key[3] = 0x44444444;
+ 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);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ net->cco = sta;
+
+ mme->mmtype = CM_SET_KEY_REQ;
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer), BITSTREAM_READ);
+
+ // Build the MME.
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &req_key_type, 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_access (&bitstream, &nid, 56);
+ bitstream_access (&bitstream, &eks, 8);
+ bitstream_access (&bitstream, &nmk.key[0], 32);
+ bitstream_access (&bitstream, &nmk.key[1], 32);
+ bitstream_access (&bitstream, &nmk.key[2], 32);
+ bitstream_access (&bitstream, &nmk.key[3], 32);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 38;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_AUTHENTICATED;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CM_SET_KEY_REQ;
+
+ cp_eoc_sta_action_auth__authenticated_set_key_req (&ctx, mme);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_AUTHENTICATED);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_assoc__associated_no_beacons")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ cp_eoc_sta_action_assoc__associated_no_beacons(&ctx);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_assoc__associated_timeout")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ //cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ cp_eoc_sta_action_assoc__associated_timeout(&ctx);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_assoc__associated_leave")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 reason;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ 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;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ reason = 0;
+ nid = 0x11223344556677ull;
+ snid = 4;
+
+ mme->peer.tei = 5;
+ mme->peer.mac = 0x2;
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, snid, nid);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ mme->mmtype = CC_LEAVE_IND;
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer), BITSTREAM_READ);
+
+ // Build the MME.
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &reason, 8);
+ bitstream_access (&bitstream, &nid, 56);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 8;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_ASSOCIATED;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CC_LEAVE_IND;
+
+ cp_eoc_sta_action_assoc__associated_leave (&ctx, mme);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_DETECTING_BEACON);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "Call cp_eoc_sta_action_assoc__authenticated_leave")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 reason;
+ cp_nid_t nid;
+ cp_snid_t snid;
+ 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;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ reason = 0;
+ nid = 0x11223344556677ull;
+ snid = 4;
+
+ mme->peer.tei = 5;
+ mme->peer.mac = 0x2;
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, snid, nid);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ mme->mmtype = CC_LEAVE_IND;
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer), BITSTREAM_READ);
+
+ // Build the MME.
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &reason, 8);
+ bitstream_access (&bitstream, &nid, 56);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 8;
+
+ cp_fsm_event_t event;
+ ctx.fsm.handled_event = &event;
+ ctx.fsm.active_states[0] = CP_FSM_STATE_AUTHENTICATED;
+ ctx.fsm.handled_event->type = CP_FSM_EVENT_TYPE_CC_LEAVE_IND;
+
+ cp_eoc_sta_action_assoc__authenticated_leave (&ctx, mme);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless(ctx.fsm.active_states[0] == CP_FSM_STATE_DETECTING_BEACON);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_assoc__authenticated_no_beacons")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ cp_mme_rx_t my_mme;
+ cp_mme_rx_t *mme = &my_mme;
+ ctx.mac_store = mac_store_init ();
+ ctx.mac_config = &mac_config;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+
+ //set our avln
+ net = cp_sta_mgr_add_avln (&ctx, 1, 1);
+ cp_sta_mgr_set_our_avln (&ctx, net);
+
+ mme->peer.mac = 2;
+ mme->peer.tei = 5;
+ sta = cp_sta_mgr_sta_add (&ctx, net, mme->peer.tei, mme->peer.mac);
+
+ cp_eoc_sta_action_assoc__authenticated_no_beacons(&ctx);
+
+ cp_sta_own_data_t *own_data = cp_sta_mgr_get_sta_own_data (&ctx);
+ test_fail_unless (own_data->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_authenticated_status (&ctx) == false);
+ test_fail_unless (ctx.sta_action.assoc.retry == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless (ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_assoc__beacon_not_received")
+ {
+ cp_t ctx;
+
+ ctx.sta_action.assoc.beacon_loss = CP_MAX_NO_BEACON + 1;
+
+ cp_eoc_sta_action_assoc__beacon_not_received(&ctx);
+
+ test_fail_unless (ctx.sta_action.assoc.beacon_loss == 0);
+ }
+ test_end
+
+ test_begin (test, "cp_eoc_sta_action_auth__authenticated_set_out_lev")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ uint cl;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ bitstream_t bitstream;
+ u8 out_level;
+ 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;
+ cp_msg_init(&ctx);
+ ctx.cl = (cl_t *) &cl;
+ cp_cl_interf_init (&ctx);
+ cp_sta_mgr_init (&ctx);
+ lib_rnd_init (&ctx.rnd, 1234);
+
+ mme->peer.tei = 5;
+ mme->peer.mac = 0x2;
+ out_level = 120;
+
+ //set our avln
+ 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, mme->peer.tei, mme->peer.mac);
+
+ mme->mmtype = CC_LEAVE_IND;
+ bitstream_init (&my_mme.bitstream, buffer, sizeof(buffer), BITSTREAM_READ);
+
+ // Build the MME.
+ bitstream_init (&bitstream, buffer, sizeof(buffer), BITSTREAM_WRITE);
+
+ bitstream_access (&bitstream, &out_level, 8);
+
+ bitstream_finalise (&bitstream);
+
+ mme->length = 1;
+
+ cp_eoc_sta_action_auth__authenticated_set_out_lev(&ctx, mme);
+ }
+ test_end
+}
+
+
+void
+test_case_poweron (test_t test)
+{
+ test_case_begin (test, "Poweron");
+
+ test_begin (test, "Receiving and processing cp_eoc_sta_action__power_on_no_beacons")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ cp_sta_own_data_t *own;
+ cl_t cl;
+ sar_t sar;
+
+ ctx.mac_config = &mac_config;
+ cp_sta_mgr_init (&ctx);
+ ctx.cl=&cl;
+ ctx.sar=&sar;
+
+ ctx.sta_mgr.sta_own_data.nid = 1;
+ ctx.sta_mgr.sta_own_data.snid = 1;
+
+ cp_eoc_sta_action__power_on_no_beacons (&ctx);
+
+ own = cp_sta_mgr_get_sta_own_data (&ctx);
+
+ test_fail_unless(cp_sta_own_data_get_tei(&ctx) == MAC_TEI_UNASSOCIATED);
+ test_fail_unless(cp_sta_own_data_get_authenticated_status(&ctx) == false);
+ 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) == false);
+ test_fail_unless(own->tei_track == MAC_TEI_UNASSOCIATED);
+ test_fail_unless(ctx.sta_action.assoc.retry == 0);
+ test_fail_unless(ctx.sta_action.assoc.beacon_loss == 0);
+ test_fail_unless(ctx.sta_action.assoc.beacon_succ == 0);
+ }
+ test_end
+
+ test_begin (test, "Receiving and processing cp_sta_action_poweron__idle__to_poweron")
+ {
+ cp_t ctx;
+ mac_config_t mac_config;
+ sar_t sar;
+
+ ctx.mac_config = &mac_config;
+ cp_sta_mgr_init (&ctx);
+ ctx.sar=&sar;
+
+ ctx.sta_mgr.sta_own_data.nid = 1;
+ ctx.sta_mgr.sta_own_data.snid = 1;
+
+ cp_sta_action_poweron__idle__to_poweron (&ctx);
+
+ test_fail_unless(ctx.sta_action.assoc.peer.mac == \
+ CP_MME_PEER (MAC_BROADCAST, MAC_TEI_UNASSOCIATED).mac);
+ test_fail_unless(ctx.sta_action.assoc.peer.vlan_tag == \
+ CP_MME_PEER (MAC_BROADCAST, MAC_TEI_UNASSOCIATED).vlan_tag);
+ test_fail_unless(ctx.sta_action.assoc.peer.tei == \
+ CP_MME_PEER (MAC_BROADCAST, MAC_TEI_UNASSOCIATED).tei);
+ }
+ test_end
+}
+
+
+void
+test_action_test_suite (test_t t)
+{
+ test_suite_begin (t, "sta_action");
+ test_case_association_and_authentication_action (t);
+ test_case_poweron (t);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ lib_stats_init();
+ trace_init ();
+ test_init (t, argc, argv);
+ test_action_test_suite (t);
+ trace_uninit ();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest/src/test_fsm.c b/cesar/cp/eoc/sta/action/test/utest/src/test_fsm.c
new file mode 100644
index 0000000000..66087a9325
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest/src/test_fsm.c
@@ -0,0 +1,685 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_fsm.c
+ * \brief Test FSM module.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/blk.h"
+#include "lib/test.h"
+#include "lib/scenario/scenario.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, "successuful authentication")
+ {
+ 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_SET_MAC_ADDR_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_mac_addr_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_CCO_PREF_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_cco_pref_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_WAS_CCO_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_was_cco_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_NPW_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_npw_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_DPW_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_dpw_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_SL_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_sl_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_NID_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_nid_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_TONEMASK_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_tonemask_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_KEY_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_key_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_DAK_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_dak_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_M_STA_HFID_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_m_sta_hfid_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_U_STA_HFID_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_u_sta_hfid_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_AVLN_HFID_REQ),
+ SCENARIO_EVENT (cp_fsm__STOPPED__drv_sta_set_avln_hfid_req),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_SET_CONFIG_REQ),
+ SCENARIO_EVENT (cp_sta_action_drv__drv_sta_set_config_req),
+ /* 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),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__BEACON),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /*Enter ASSOC timer */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATING*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, granted_more_to_grant)),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, granted_more_to_grant)),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* AUTHENTICATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_BEACON),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__BEACON),
+ /* AUTHENTICATED -> VS_EOC_CCO_SET_OUT_LEV_IND -> AUTHENTICATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_VS_EOC_CCO_SET_OUT_LEV_IND),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__set_out_lev_ind),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_AUTHENTICATED);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "associating, beacon timeout => sleep_unassociated")
+ {
+ 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),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon_timeout),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon_timeout),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_enter_sleep_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__enter_sleep_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* SLEEP_UNASSOCIATED */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_SLEEP_UNASSOCIATED);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "bad association")
+ {
+ 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),
+ /* DETECTING_BEACON, beacon detected */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /*Enter ACCOC timer */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATING, timeout, retry */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_timeout_associating),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__timeout_associating,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, timeout_associating, retry)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* DETECTING_BEACON, beacon detected */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /*Enter ACCOC timer */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATING, timeout, no retries*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_timeout_associating),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__timeout_associating,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, timeout_associating, no_retry)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_enter_sleep_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__enter_sleep_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* SLEEP_UNASSOCIATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_exit_sleep_unassociated),
+ SCENARIO_EVENT (cp_fsm__SLEEP_UNASSOCIATED__exit_sleep_unassociated),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON, beacon detected */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATING, assoc_cnf, unrelated */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, unrelated)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON, beacon detected */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATING, no beacons*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_no_beacons),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__no_beacons),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON, beacon detected */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING, assoc_cnf, unsuccess*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, unsuccess)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_UNASSOCIATED);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "associated")
+ {
+ 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),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /*Enter ACCOC timer */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATING*/
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED, get_key_cnf, unrelated */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, unrelated)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED,get_key_cnf, not granted */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, not_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED, encrypt_payload */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_encrypt_payload_rsp),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__encrypt_payload_rsp),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED, no beacons */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_no_beacons),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__no_beacons),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED, leave */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_LEAVE_IND),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CC_LEAVE_IND,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CC_LEAVE_IND, ok)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED, timeout_authenticating */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_timeout_associating),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__timeout_associating),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED, get_key */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, granted_more_to_grant)),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* AUTHENTICATED */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_AUTHENTICATED);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "authenticated")
+ {
+ 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),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /*Enter ACCOC timer */
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* AUTHENTICATED, sleep */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_sleep_enter_cnf),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__sleep_enter_cnf),
+ /* SLEEP_AUTHENTICATED, exit sleep */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_sleep_exit_rsp),
+ SCENARIO_EVENT (cp_fsm__SLEEP_AUTHENTICATED__sleep_exit_rsp),
+ /* AUTHENTICATED, sleep */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_sleep_enter_cnf),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__sleep_enter_cnf),
+ /* SLEEP_AUTHENTICATED, no beacons */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_no_beacons),
+ SCENARIO_EVENT (cp_fsm__SLEEP_AUTHENTICATED__no_beacons),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* ASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* AUTHENTICATED, NEK change request */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_SET_KEY_REQ),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__CM_SET_KEY_REQ),
+ /* AUTHENTICATED, no beacons */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_no_beacons),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__no_beacons),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon_timeout),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon_timeout),
+ /* UNASSOCIATED */
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_retry_unassociated),
+ SCENARIO_EVENT (cp_fsm__UNASSOCIATED__stop_retry_timer),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* AUTHENTICATED, CM_NW_STATS */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_NW_STATS_REQ),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__CM_NW_STATS_REQ),
+ /* AUTHENTICATED, leave => OK */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_LEAVE_IND),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__CC_LEAVE_IND,
+ .branch = CP_FSM_BRANCH (AUTHENTICATED, CC_LEAVE_IND, ok)),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_DETECTING_BEACON);
+ cp_fsm_uninit (&cp);
+ } test_end;
+
+ test_begin (t, "stopped")
+ {
+ 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),
+ /* DETECTING_BEACON */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_nd_beacon),
+ SCENARIO_EVENT (cp_fsm__DETECTING_BEACON__nd_beacon),
+ /* ASSOCIATING*/
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_ASSOC_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__CC_ASSOC_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATING, CC_ASSOC_CNF, success)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__start_retry_timer),
+ /* ASSOCIATED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CM_GET_KEY_CNF),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATED__CM_GET_KEY_CNF,
+ .branch = CP_FSM_BRANCH (ASSOCIATED, CM_GET_KEY_CNF, all_keys_granted)),
+ SCENARIO_EVENT (cp_fsm__ASSOCIATING__stop_retry_timer),
+ /* AUTHENTICATED, leave => not OK */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_CC_LEAVE_IND),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__CC_LEAVE_IND,
+ .branch = CP_FSM_BRANCH (AUTHENTICATED, CC_LEAVE_IND, nok)),
+ /* STOPPED */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_DRV_STA_MAC_STOP_REQ),
+ SCENARIO_EVENT (cp_fsm__AUTHENTICATED__drv__started__drv_sta_mac_stop_req),
+ /* STOPPING */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_to_stop),
+ SCENARIO_EVENT (cp_fsm__STOPPING__poweron__many__to_idle),
+ /* STOPPING */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_stopped),
+ SCENARIO_EVENT (cp_fsm__STOPPING__drv__stopping__stopped),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STOPPED);
+ 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, "fsm");
+ test_fsm_basic_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_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/Config b/cesar/cp/eoc/sta/action/test/utest_eoc/Config
new file mode 100644
index 0000000000..e6f38e5980
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/Config
@@ -0,0 +1,8 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_sta.fsm"
+CONFIG_CP_EOC_STA_CON_ALLOWED = n
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 0
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_CP_EOC_STA_CON_ALLOWED = n
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/Makefile b/cesar/cp/eoc/sta/action/test/utest_eoc/Makefile
new file mode 100644
index 0000000000..4129a5f133
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/Makefile
@@ -0,0 +1,18 @@
+BASE = ../../../../../..
+
+INCLUDES = cp/eoc/sta/action/test/utest_eoc/override
+
+HOST_PROGRAMS = assoc
+
+assoc_SOURCES = assoc.c mgr_stub.c core_stub.c cp_stub.c msg_stub.c phy_stub.c
+
+assoc_MODULES = lib cp/sta/mgr mac/common cp/eoc/sta/action \
+ cp/fsm/stub cl/stub mac/sar/stub cp/eoc/sta/mgr \
+ cp/msg/stub cp/secu cp/beacon/stub bsu/stub cp/eoc/cco/bw/stub
+
+assoc_MODULES_CONFIG = cp mac
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_eoc_sta_action_MODULE_SOURCES = assoc.c sleep.c poweron.c drv.c
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/inc/context.h b/cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/inc/context.h
new file mode 100644
index 0000000000..b421f966a8
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/inc/context.h
@@ -0,0 +1,73 @@
+#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 "common/std.h"
+#include "lib/rnd.h"
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+#include "cp/inc/trace.h"
+
+#include "cp/cp.h"
+#include "mac/common/store.h"
+#include "cp/types.h"
+#include "cp/sta/action/inc/context.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 "mac/pbproc/inc/context.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;
+
+ /** 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;
+
+ /** Random generator. */
+ lib_rnd_t rnd;
+
+ /** messages context. */
+ cp_msg_t msg;
+ pbproc_t *pbproc;
+
+ bsu_t *bsu;
+ phy_t *phy;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/sta/core/core.h b/cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/sta/core/core.h
new file mode 100644
index 0000000000..6acb01cb29
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/override/cp/sta/core/core.h
@@ -0,0 +1,43 @@
+#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/types.h"
+#include "cp/fsm/forward.h"
+
+struct cp_sta_core_timed_event_def_t
+{
+};
+
+typedef struct cp_sta_core_timed_event_def_t cp_sta_core_timed_event_def_t;
+
+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);
+
+BEGIN_DECLS
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx);
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/override/mac/sar/inc/context.h b/cesar/cp/eoc/sta/action/test/utest_eoc/override/mac/sar/inc/context.h
new file mode 100644
index 0000000000..b74c7a57e3
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/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/sta/action/test/utest_eoc/override/mac/sar/inc/sar_context.h b/cesar/cp/eoc/sta/action/test/utest_eoc/override/mac/sar/inc/sar_context.h
new file mode 100644
index 0000000000..e380fb66e7
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/override/mac/sar/inc/sar_context.h
@@ -0,0 +1,37 @@
+#ifndef overide_mac_sar_inc_context_h
+#define overide_mac_sar_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/sar/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+struct sar_stats_t
+{
+ /** Total number of PB received by ourself (from anyone). */
+ u32 rx_pb_count;
+ /** Total number of PB with a CRC error received by ourself (from
+ * anyone). */
+ u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** BER sum of all PBs correct received from any station in the AVLN. */
+ u64 ber_sum;
+};
+typedef struct sar_stats_t sar_stats_t;
+
+struct sar_t
+{
+ mac_store_t *mac_store;
+ sar_stats_t stats;
+};
+
+#endif /* overide_mac_sar_inc_context_h */
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/src/assoc.c b/cesar/cp/eoc/sta/action/test/utest_eoc/src/assoc.c
new file mode 100644
index 0000000000..737b1d0bf1
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/src/assoc.c
@@ -0,0 +1,48 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file eoc/sta/action/test/utest/src/assoc.c
+ * \brief Unit test of sta action after receiving/sending association messages
+ * \ingroup test
+ *
+ * This test checks reception of CC_ASSOC_CNF msg at station side and state
+ * transition depending on result of msg.
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/inc/context.h"
+
+void
+cp_eoc_sta_action_assoc__associating_cnf (cp_t *ctx, cp_mme_rx_t *mme);
+
+static cp_t cp;
+static cp_mme_rx_t mme;
+
+int
+main (void)
+{
+ test_t test;
+ test_init (test, 0, NULL);
+
+ test_begin (test, "Basic");
+ {
+ cp_eoc_sta_action_assoc__associating_cnf (&cp, &mme);
+ }
+ test_end;
+
+ test_begin (test, "Memory verification")
+ {
+ test_fail_if (blk_check_memory() == false, "Memory not freed");
+ }
+ test_end;
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/src/core_stub.c b/cesar/cp/eoc/sta/action/test/utest_eoc/src/core_stub.c
new file mode 100644
index 0000000000..c44446385a
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/src/core_stub.c
@@ -0,0 +1,36 @@
+/* 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);
+/* scenario_event (cp_sta_core_gen_timed_event, param);
+ test_fail_unless (event_delay_ms >= param->delay_min_ms);
+ test_fail_unless (event_delay_ms <= param->delay_max_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)
+{
+ dbg_assert (cp_ctx);
+ dbg_assert (sta_core_timed_event);
+// scenario_event (cp_sta_core_stop_timed_or_cyclic_event);
+}
+
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/src/cp_stub.c b/cesar/cp/eoc/sta/action/test/utest_eoc/src/cp_stub.c
new file mode 100644
index 0000000000..672ffb388b
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/src/cp_stub.c
@@ -0,0 +1,48 @@
+/* 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"
+
+/**
+ * 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_nmk (ctx, nmk, 0);
+ cp_sta_own_data_set_nid (ctx, nid);
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/src/mgr_stub.c b/cesar/cp/eoc/sta/action/test/utest_eoc/src/mgr_stub.c
new file mode 100644
index 0000000000..ef3d52049c
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/src/mgr_stub.c
@@ -0,0 +1,89 @@
+/* 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"
+
+// void
+// cp_sta_mgr_set_our_avln (cp_t *ctx, cp_net_t *net)
+// {
+// }
+//
+// void
+// cp_sta_mgr_sta_remove (cp_t *ctx, cp_sta_t * sta)
+// {
+// }
+//
+// cp_sta_t *
+// cp_sta_mgr_sta_get_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei)
+// {
+// return NULL;
+// }
+//
+// cp_sta_t *
+// cp_sta_mgr_sta_add (cp_t *ctx, cp_net_t *net, cp_tei_t tei, mac_t mac_address)
+// {
+// return NULL;
+// }
+//
+// cp_sta_own_data_t *
+// cp_sta_mgr_get_sta_own_data (cp_t *ctx)
+// {
+// dbg_assert (ctx);
+//
+// return (cp_sta_own_data_t *) &ctx->sta_mgr.sta_own_data;
+// }
+//
+// cp_net_t *
+// cp_sta_mgr_get_our_avln (cp_t *ctx)
+// {
+// dbg_assert (ctx);
+// dbg_assert (ctx->sta_mgr.our_avln);
+//
+// return ctx->sta_mgr.our_avln;
+// }
+
+bool
+cp_msg_cc_assoc_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_msg_cc_assoc_cnf_t *data)
+{
+ dbg_assert (ctx);
+ return true;
+}
+
+void
+cp_cco_action_tei_release (cp_t *ctx, u8 tei)
+{
+ dbg_assert (ctx);
+ dbg_assert (tei);
+}
+
+u32
+cp_sta_core_get_date_ms (cp_t *ctx)
+{
+ return 0;
+}
+
+void
+cp_sta_core_checkpoint (cp_t *ctx)
+{
+}
+
+void
+pbproc_activate (pbproc_t *ctx, bool flag)
+{
+}
+
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/src/msg_stub.c b/cesar/cp/eoc/sta/action/test/utest_eoc/src/msg_stub.c
new file mode 100644
index 0000000000..a48f4afb21
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/src/msg_stub.c
@@ -0,0 +1,72 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/src/msg_drv.c
+ * \brief MME Driver.
+ * \ingroup cp_msg
+ *
+ */
+#include "common/std.h"
+#include "common/defs/ethernet.h"
+#include "cp/cp.h"
+#include "cp/mme.h"
+#include "cp/msg/msg.h"
+
+#include "cp/msg/inc/msg_drv.h"
+#include "cp/msg/inc/msg.h"
+
+bool
+cp_msg_drv_sta_set_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_key_t *nmk,
+ enum cp_msg_drv_sta_set_key_type_t *type,
+ cp_nid_t *nid,
+ cp_security_level_t *sl)
+{
+ uint i;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (nmk);
+ dbg_assert (type);
+ dbg_assert (nid);
+ dbg_assert (sl);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ for (i = 0; i < COUNT (nmk->key); i++)
+ nmk->key[i] = bitstream_read (&mme->bitstream, 32);
+ *type = bitstream_read (&mme->bitstream, 8);
+ *nid = bitstream_read_large (&mme->bitstream, 56);
+ *sl = bitstream_read (&mme->bitstream, 8);
+
+ if ((*type >= CP_MSG_DRV_STA_SET_KEY_TYPE_NB)
+ || (*sl >= CP_SECURITY_LEVEL_NB)
+ || (*nid >> 56))
+ return false;
+ return true;
+ }
+ return false;
+}
+
+bool
+cp_msg_drv_sta_set_dak_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ cp_key_t *dak)
+{
+ uint i;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (dak);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ for (i = 0; i < COUNT (dak->key); i++)
+ dak->key[i] = bitstream_read (&mme->bitstream, 32);
+
+ return true;
+ }
+ return false;
+}
diff --git a/cesar/cp/eoc/sta/action/test/utest_eoc/src/phy_stub.c b/cesar/cp/eoc/sta/action/test/utest_eoc/src/phy_stub.c
new file mode 100644
index 0000000000..92ff6578ef
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/test/utest_eoc/src/phy_stub.c
@@ -0,0 +1,15 @@
+
+
+#include "common/std.h"
+#include "cp/inc/context.h"
+
+
+void
+phy_tx_scale_adapt_exp_set (phy_t *ctx, u8 exp)
+{
+}
+
+void
+phy_tx_scale_adapt_set (phy_t *ctx, u16 value)
+{
+} \ No newline at end of file
diff --git a/cesar/cp/eoc/sta/action/vs_eoc.h b/cesar/cp/eoc/sta/action/vs_eoc.h
new file mode 100644
index 0000000000..8c1ccea3b6
--- /dev/null
+++ b/cesar/cp/eoc/sta/action/vs_eoc.h
@@ -0,0 +1,50 @@
+#ifndef cp_eoc_sta_action_vs_eoc_h
+#define cp_eoc_sta_action_vs_eoc_h
+/* Cesar-EoC project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/action/vs_eoc.h
+ * \brief sta action, Vendor Specific EoC MME related prototypes.
+ * \ingroup cp_eoc_sta_action
+ */
+
+
+struct real_time_stats_t {
+ uint nb_unicast_packets_rx;
+ uint nb_unicast_packets_tx;
+ uint total_nb_bytes_rx;
+ uint total_nb_bytes_tx;
+ uint nb_broadcast_packets_rx;
+ uint nb_broadcast_packets_tx;
+ uint nb_multicast_packets_rx;
+ uint nb_multicast_packets_tx;
+ uint nb_packets_rx_crc;
+ uint nb_packets_rx_short;
+ uint nb_packets_tx_short;
+ uint nb_packets_tx_dropped;
+ uint nb_packets_rx_discarded;
+ uint avg_pre_fec_bit_error_rate;
+};
+typedef struct real_time_stats_t real_time_stats_t;
+
+
+BEGIN_DECLS
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_info_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_diagnostic_info_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req(cp_t *ctx, cp_mme_rx_t *mme);
+
+
+END_DECLS
+
+#endif /* cp_eoc_sta_action_vs_eoc_h */
diff --git a/cesar/cp/eoc/sta/mgr/Config b/cesar/cp/eoc/sta/mgr/Config
new file mode 100644
index 0000000000..b61f26f167
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/Config
@@ -0,0 +1 @@
+CONFIG_CP_STA_MGR_CCO_EOC = n
diff --git a/cesar/cp/eoc/sta/mgr/Module b/cesar/cp/eoc/sta/mgr/Module
new file mode 100644
index 0000000000..4c1c9cc32b
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/Module
@@ -0,0 +1 @@
+SOURCES:= sta_mgr.c sta_own_data.c
diff --git a/cesar/cp/eoc/sta/mgr/doc/sta_manager.odt b/cesar/cp/eoc/sta/mgr/doc/sta_manager.odt
new file mode 100644
index 0000000000..63c28efa0f
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/doc/sta_manager.odt
Binary files differ
diff --git a/cesar/cp/eoc/sta/mgr/doc/sta_mgr.xmi b/cesar/cp/eoc/sta/mgr/doc/sta_mgr.xmi
new file mode 100644
index 0000000000..000727a5bc
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/doc/sta_mgr.xmi
@@ -0,0 +1,1832 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XMI xmlns:UML="http://schema.omg.org/spec/UML/1.3" verified="false" timestamp="2008-11-13T17:12:40" xmi.version="1.2" >
+ <XMI.header>
+ <XMI.documentation>
+ <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
+ <XMI.exporterVersion>1.5.5</XMI.exporterVersion>
+ <XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
+ </XMI.documentation>
+ <XMI.metamodel xmi.name="UML" href="UML.xml" xmi.version="1.3" />
+ </XMI.header>
+ <XMI.content>
+ <UML:Model isSpecification="false" isLeaf="false" isRoot="false" xmi.id="m1" isAbstract="false" name="Modèle UML" >
+ <UML:Namespace.ownedElement>
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="2" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="folder" isRoot="false" isAbstract="false" name="folder" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="datatype" isRoot="false" isAbstract="false" name="datatype" />
+ <UML:Stereotype isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="enum" isRoot="false" isAbstract="false" name="enum" />
+ <UML:Model stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Logical View" isRoot="false" isAbstract="false" name="Logical View" >
+ <UML:Namespace.ownedElement>
+ <UML:Package stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="Datatypes" isRoot="false" isAbstract="false" name="Datatypes" >
+ <UML:Namespace.ownedElement>
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="WHsGhr6cL3qV" isRoot="false" isAbstract="false" name="int" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="1lLAIoXrLdtJ" isRoot="false" isAbstract="false" name="char" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="BsXuVmQldfSS" isRoot="false" isAbstract="false" name="bool" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="l2nnsImcbvsP" isRoot="false" isAbstract="false" name="float" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="Shk6a1xmtUeN" isRoot="false" isAbstract="false" name="double" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="G46rjYKTY5EP" isRoot="false" isAbstract="false" name="short" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="O01xtrLMY3S6" isRoot="false" isAbstract="false" name="long" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="5NqwrUH5XNxE" isRoot="false" isAbstract="false" name="unsigned int" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="tFhSKvrguqen" isRoot="false" isAbstract="false" name="unsigned short" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="hz7D2ZH5u80l" isRoot="false" isAbstract="false" name="unsigned long" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="aHp7fmMY11yJ" isRoot="false" isAbstract="false" name="string" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="vntVp1gw0ZB8" isRoot="false" isAbstract="false" name="cp_reassembly_ctx_t *" elementReference="nyW3ZjsRDxWm" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="oZHHg64PKBaq" isRoot="false" isAbstract="false" name="uint" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="DcaQZXHCYAUY" isRoot="false" isAbstract="false" name="cp_sta_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="nnvOyvzkSE17" isRoot="false" isAbstract="false" name="u8" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="J5WdE6USg2qD" isRoot="false" isAbstract="false" name="u16" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="X7Q5Iud3fXPb" isRoot="false" isAbstract="false" name="u32" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="QPMsbNxuTUYh" isRoot="false" isAbstract="false" name="u64" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="TRzc3eNXqLr1" isRoot="false" isAbstract="false" name="cp_net_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="Q4TYO2bRfXJq" isRoot="false" isAbstract="false" name="mac_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="RTeIWtKTDaZV" isRoot="false" isAbstract="false" name="cp_reassembly_ctx_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="yVCl3jm3PB1C" isRoot="false" isAbstract="false" name="cp_sta_own_data_t *" />
+ <UML:DataType stereotype="datatype" comment="This value is equal to 8 bytes." isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="sXqfrqwPid2x" isRoot="false" isAbstract="false" name="NPW_MIN_SIZE" />
+ <UML:DataType stereotype="datatype" comment="NPW max size. 64 bytes." isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="ZsN7qO5uod0W" isRoot="false" isAbstract="false" name="NPW_MAX_SIZE" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="LyzcKuBtjfar" isRoot="false" isAbstract="false" name="u8 *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="2TKfUnESr7J6" isRoot="false" isAbstract="false" name="const u8 *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="bdvfq1CcRFQV" isRoot="false" isAbstract="false" name="const u8" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="cignRXiUIpXF" isRoot="false" isAbstract="false" name="cp_net_list_t *" elementReference="nyW3ZjsRDxWm" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="nyW3ZjsRDxWm" isRoot="false" isAbstract="false" name="undef" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="OF2Sin3o242W" isRoot="false" isAbstract="false" name="set_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="6agIp7Rg7jXE" isRoot="false" isAbstract="false" name="cp_sta_mgr_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="EhNquCdzHTzv" isRoot="false" isAbstract="false" name="cp_key_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="GXVTJzZt05VA" isRoot="false" isAbstract="false" name="cp_key_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="F0y42ZDGGZ49" isRoot="false" isAbstract="false" name="const cp_key_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="NMq7yPI15TF8" isRoot="false" isAbstract="false" name="const char" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="8MlMJZOa2gQQ" isRoot="false" isAbstract="false" name="const char *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="m7hYSy5qW7Uv" isRoot="false" isAbstract="false" name="cp_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="0mEev7QHu3Xw" isRoot="false" isAbstract="false" name="cp_snid_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="f1lxWwdNwvpr" isRoot="false" isAbstract="false" name="cp_nid_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="emAuInlIaxvV" isRoot="false" isAbstract="false" name="cp_tei_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="15653" isRoot="false" isAbstract="false" name="cp_mme_peer_t *" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="12443" isRoot="false" isAbstract="false" name="list_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="21195" isRoot="false" isAbstract="false" name="const cp_key_t" />
+ <UML:DataType stereotype="datatype" isSpecification="false" isLeaf="false" visibility="public" namespace="Datatypes" xmi.id="33858" isRoot="false" isAbstract="false" name="set_t" />
+ </UML:Namespace.ownedElement>
+ </UML:Package>
+ <UML:Class comment="Station own data." isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="dQQc692tOFUS" isRoot="false" isAbstract="false" name="cp_sta_own_data_t" >
+ <UML:Classifier.feature>
+ <UML:Attribute comment="station's TEI." isSpecification="false" visibility="private" xmi.id="hcbUh4JlIu5E" type="emAuInlIaxvV" name="tei" />
+ <UML:Attribute comment="Station's Mac address." isSpecification="false" visibility="private" xmi.id="MyhwT7zZG8oO" type="Q4TYO2bRfXJq" name="mac_addr" />
+ <UML:Attribute comment="Network Password, use by the station to crypt MMEs." isSpecification="false" visibility="private" xmi.id="x5HJsnaGxZDg" type="1lLAIoXrLdtJ" name="npw [NPW_MAX_SIZE + 1]" />
+ <UML:Attribute comment="AVLN's NMK." isSpecification="false" visibility="private" xmi.id="RrbeL3wI6BZy" type="EhNquCdzHTzv" name="nmk" />
+ <UML:Attribute comment="Device password." isSpecification="false" visibility="private" xmi.id="I16y7R8xSEes" type="1lLAIoXrLdtJ" name="dpw [DPW_MAX_SIZE + 1]" />
+ <UML:Attribute comment="Indicate if the station was CCo during the last use." isSpecification="false" visibility="private" xmi.id="VZjK8y2Pz9L4" type="BsXuVmQldfSS" name="was_cco" />
+ <UML:Attribute comment="Indicate if the station is CCo." isSpecification="false" visibility="private" xmi.id="20601" type="BsXuVmQldfSS" name="is_cco" />
+ <UML:Attribute comment="Security level. It can be changed by a specific message or by the HLE. See section 7.10.3.1.3 and section 13.3" isSpecification="false" visibility="private" xmi.id="0grlCK0Zd2kv" type="SsuRPlPUGZjG" name="security_level" />
+ <UML:Attribute comment="The PCO Glid." isSpecification="false" visibility="private" xmi.id="roOeP5mqSzsY" type="nnvOyvzkSE17" name="pco_glid" />
+ <UML:Attribute comment="Indicate if the station is authenticated or not." isSpecification="false" visibility="private" xmi.id="20651" type="1lLAIoXrLdtJ" name="authenticated" />
+ <UML:Attribute comment="The Station NID." isSpecification="false" visibility="private" xmi.id="20701" type="f1lxWwdNwvpr" name="nid" />
+ <UML:Attribute comment="The station SNID." isSpecification="false" visibility="private" xmi.id="20751" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Attribute comment="Indicate if the station was CCo prefered." isSpecification="false" visibility="public" xmi.id="TO2c4YFuL4qQ" type="BsXuVmQldfSS" name="cco_prefered" />
+ <UML:Attribute comment="The user HFID." isSpecification="false" visibility="public" xmi.id="Rxzl1nBWMvpT" type="NMq7yPI15TF8" name="hfid_user [HFID_SIZE + 1]" />
+ <UML:Attribute comment="The manufacturer HFID." isSpecification="false" visibility="public" xmi.id="gBfRCRdglWVE" type="NMq7yPI15TF8" name="hfid_manufacturer [HFID_SIZE + 1]" />
+ <UML:Attribute comment="The AVLN HFID." isSpecification="false" visibility="public" xmi.id="3951" type="NMq7yPI15TF8" name="hfid_avln[HFID_SIZE + 1]" />
+ <UML:Attribute comment="Current hybrid mode." isSpecification="false" visibility="public" xmi.id="xAmypZKxOlvo" type="nnvOyvzkSE17" name="hybrid_mode" />
+ <UML:Attribute comment="The current snid being tracked for the ntb synchronization." isSpecification="false" visibility="public" xmi.id="919bTPKjqxKs" type="0mEev7QHu3Xw" name="snid_track" />
+ <UML:Attribute comment="The current nid being track for the ntb synchronization." isSpecification="false" visibility="public" xmi.id="MW7N3XqbJLli" type="f1lxWwdNwvpr" name="nid_track" />
+ <UML:Attribute comment="The PCo to discuss with." isSpecification="false" visibility="public" xmi.id="aTEnETRcBPSB" type="DcaQZXHCYAUY" name="pco" />
+ <UML:Operation comment="Initialise the station own data to default values." isSpecification="false" isLeaf="false" visibility="public" xmi.id="l9iApQ5k7p4V" isRoot="false" isAbstract="false" isQuery="false" name="init" />
+ <UML:Operation comment="Unitialise the station own data to default values." isSpecification="false" isLeaf="false" visibility="public" xmi.id="20899" isRoot="false" isAbstract="false" isQuery="false" name="uninit" />
+ <UML:Operation comment="Set the TEI of the station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="PNzGVGMN7IZO" isRoot="false" isAbstract="false" isQuery="false" name="set_tei" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The the TEI station." isSpecification="false" visibility="private" xmi.id="IChxmt614D8Y" value="" type="emAuInlIaxvV" name="tei" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the value of the constante TEI." isSpecification="false" isLeaf="false" visibility="public" xmi.id="oS3q3CNSaLg5" isRoot="false" isAbstract="false" isQuery="false" name="get_tei" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36644" type="emAuInlIaxvV" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the station Mac address." isSpecification="false" isLeaf="false" visibility="public" xmi.id="9tv3PTcwJuk2" isRoot="false" isAbstract="false" isQuery="false" name="set_mac_address" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The Mac address of the station." isSpecification="false" visibility="private" xmi.id="GmJdTFwP5LIE" value="" type="Q4TYO2bRfXJq" name="mac_addr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the station mac address." isSpecification="false" isLeaf="false" visibility="public" xmi.id="DbAcS8Pc1KdP" isRoot="false" isAbstract="false" isQuery="false" name="get_mac_address" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36645" type="Q4TYO2bRfXJq" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the Station NPW." isSpecification="false" isLeaf="false" visibility="public" xmi.id="lEJ2633MpMzJ" isRoot="false" isAbstract="false" isQuery="false" name="set_npw" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The new npw." isSpecification="false" visibility="private" xmi.id="99dfWsqi6SFH" value="" type="8MlMJZOa2gQQ" name="npw" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Return the pointer to the NPW as a constante data. The user shall call the set_npw function to modify the NPW." isSpecification="false" isLeaf="false" visibility="public" xmi.id="bLozAc1Tby5t" isRoot="false" isAbstract="false" isQuery="false" name="get_npw" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36646" type="8MlMJZOa2gQQ" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the station NMK." isSpecification="false" isLeaf="false" visibility="public" xmi.id="QacAXGqLr88z" isRoot="false" isAbstract="false" isQuery="false" name="set_nmk" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The nmk to set." isSpecification="false" visibility="private" xmi.id="V67Yq0lvqWek" value="" type="21195" name="nmk" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the NMK of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="XBpdlbprByih" isRoot="false" isAbstract="false" isQuery="false" name="get_nmk" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36647" type="F0y42ZDGGZ49" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the device password." isSpecification="false" isLeaf="false" visibility="public" xmi.id="x2pgMFGxFwzE" isRoot="false" isAbstract="false" isQuery="false" name="set_dpw" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The new device password." isSpecification="false" visibility="private" xmi.id="K4OvTT41dteO" value="" type="8MlMJZOa2gQQ" name="dpw" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Return the Device password." isSpecification="false" isLeaf="false" visibility="public" xmi.id="YWiBOMZqmmSC" isRoot="false" isAbstract="false" isQuery="false" name="get_dpw" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36648" type="8MlMJZOa2gQQ" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the security level. And send a message to the HLE." isSpecification="false" isLeaf="false" visibility="public" xmi.id="gkXbpZt9r3e4" isRoot="false" isAbstract="false" isQuery="false" name="set_security_level" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The security level." isSpecification="false" visibility="private" xmi.id="DPaRU282XpEv" value="" type="SsuRPlPUGZjG" name="sl" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Return the security level." isSpecification="false" isLeaf="false" visibility="public" xmi.id="Cgo2iS6vpgKJ" isRoot="false" isAbstract="false" isQuery="false" name="get_security_level" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36649" type="SsuRPlPUGZjG" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the CCo status of the station. It shall send a message to the Linux Driver." isSpecification="false" isLeaf="false" visibility="public" xmi.id="4vv3FEH8vlii" isRoot="false" isAbstract="false" isQuery="false" name="set_was_cco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The current CCo status of the station." isSpecification="false" visibility="private" xmi.id="ZoePxqjuXWU6" value="" type="BsXuVmQldfSS" name="status" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the the CCo status of the station after a reboot." isSpecification="false" isLeaf="false" visibility="public" xmi.id="h933zRw1Mr2a" isRoot="false" isAbstract="false" isQuery="false" name="get_was_cco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36650" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the HFID value." isSpecification="false" isLeaf="false" visibility="public" xmi.id="Z2pjniRb4U5p" isRoot="false" isAbstract="false" isQuery="false" name="set_hfid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The HFID to set (user or manufacturer)." isSpecification="false" visibility="private" xmi.id="EuSjWJa3LNm8" value="" type="8MlMJZOa2gQQ" name="hfid" />
+ <UML:Parameter comment="The new HFID value to set." isSpecification="false" visibility="private" xmi.id="VAPcPDExC4vS" value="" type="8MlMJZOa2gQQ" name="data" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set thenew User HFID in the station own data." isSpecification="false" isLeaf="false" visibility="public" xmi.id="6Di8flw9tLlH" isRoot="false" isAbstract="true" isQuery="false" name="set_hfid_user" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="Set the new User HFID." isSpecification="false" visibility="private" xmi.id="YxEj17BGzexV" value="" type="8MlMJZOa2gQQ" name="data" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the new manufacturer HFID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="xXWGuINyU377" isRoot="false" isAbstract="true" isQuery="false" name="set_hfid_manufacturer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The new Manufacturer HFID." isSpecification="false" visibility="private" xmi.id="m3GgO0xwx9fz" value="" type="8MlMJZOa2gQQ" name="data" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the GLID to send proxy data." isSpecification="false" isLeaf="false" visibility="public" xmi.id="b2NRxvTAG4Im" isRoot="false" isAbstract="false" isQuery="false" name="set_pco_glid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The glid to use when a proxy beacon shall be sent." isSpecification="false" visibility="private" xmi.id="QRFWIDV91tnP" value="" type="nnvOyvzkSE17" name="glid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the PCO GLID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="wXFOX5u66GX3" isRoot="false" isAbstract="false" isQuery="false" name="get_pco_glid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36651" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the PCO status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="4DPM1C2ZHS5c" isRoot="false" isAbstract="false" isQuery="false" name="get_pco_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36652" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the PCO status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="tS98bISnuM92" isRoot="false" isAbstract="false" isQuery="false" name="set_pco_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The PCO status." isSpecification="false" visibility="private" xmi.id="es20nPIqcgCb" value="" type="BsXuVmQldfSS" name="pco" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the CCo status of the station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="21441" isRoot="false" isAbstract="false" isQuery="false" name="set_cco_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The status." isSpecification="false" visibility="private" xmi.id="21442" value="" type="BsXuVmQldfSS" name="cco" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the CCo status of the station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="21541" isRoot="false" isAbstract="false" isQuery="false" name="get_cco_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36653" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the authenticated status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="4536" isRoot="false" isAbstract="false" isQuery="false" name="set_authenticated_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The authenfication status." isSpecification="false" visibility="private" xmi.id="4537" value="" type="BsXuVmQldfSS" name="authenticated" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the authentication status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="4636" isRoot="false" isAbstract="false" isQuery="false" name="get_authenticated_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36654" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Update the station NID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="21592" isRoot="false" isAbstract="false" isQuery="false" name="set_nid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station NID." isSpecification="false" visibility="private" xmi.id="21593" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the sstation NID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="21694" isRoot="false" isAbstract="false" isQuery="false" name="get_nid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36655" type="f1lxWwdNwvpr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Update the station SNID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="21746" isRoot="false" isAbstract="false" isQuery="false" name="set_snid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station NID." isSpecification="false" visibility="private" xmi.id="21747" value="" type="0mEev7QHu3Xw" name="snid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the station SNID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="21851" isRoot="false" isAbstract="false" isQuery="false" name="get_snid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36656" type="0mEev7QHu3Xw" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="L2ASUCoHdFZ0" isRoot="false" isAbstract="false" name="cp_sta_mgr_t" >
+ <UML:Classifier.feature>
+ <UML:Attribute comment="List of released station. Use to keep the TEI and the connection to finalise the leave of the station." isSpecification="false" visibility="private" xmi.id="12890" type="12443" name="release_sta_list" />
+ <UML:Attribute comment="A set containing all the stations added to the station manager sorted by the mac addresses." isSpecification="false" visibility="private" xmi.id="33908" type="OF2Sin3o242W" name="stas" />
+ <UML:Operation comment="Add a AVLN to the manager list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="QXnrJp4mc3nZ" isRoot="false" isAbstract="false" isQuery="false" name="add_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36657" type="TRzc3eNXqLr1" />
+ <UML:Parameter comment="The AVLN's SNID to add." isSpecification="false" visibility="private" xmi.id="xXla9cfmTC0K" value="" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Parameter comment="The AVLN's nid to add." isSpecification="false" visibility="private" xmi.id="Dq4iCYzb5lSM" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Remove an AVLN," isSpecification="false" isLeaf="false" visibility="public" xmi.id="bxBBvbAGs7Q5" isRoot="false" isAbstract="false" isQuery="false" name="remove_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The AVLN's snid to remove." isSpecification="false" visibility="private" xmi.id="CwB2Bb8CvUZS" value="" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Parameter comment="The AVLN's nid to remove." isSpecification="false" visibility="private" xmi.id="c8bNpTbQOlcJ" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get an AVLN from the net_list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="vk7FSeQIaeIS" isRoot="false" isAbstract="false" isQuery="false" name="get_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36658" type="TRzc3eNXqLr1" />
+ <UML:Parameter comment="The AVLN's snid to get." isSpecification="false" visibility="private" xmi.id="5KU6Vjz8WLNP" value="" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Parameter comment="The AVLN's nid to get." isSpecification="false" visibility="private" xmi.id="Jy7i8GX3ycIR" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Initialise the sta manager." isSpecification="false" isLeaf="false" visibility="public" xmi.id="qHxkg2dtESUh" isRoot="false" isAbstract="false" isQuery="false" name="init" />
+ <UML:Operation comment="Uninitialise the sta manager." isSpecification="false" isLeaf="false" visibility="public" xmi.id="2gQknmKqTzYm" isRoot="false" isAbstract="false" isQuery="false" name="uninit" />
+ <UML:Operation comment="Lookup and return all the snids already in use in the different AVLN. The return data is a flag of 16 bits. The bit0 corresponds to the the snid 0, the bit1 to the snid 1 and so on." isSpecification="false" isLeaf="false" visibility="public" xmi.id="DC8mABArXbfX" isRoot="false" isAbstract="false" isQuery="false" name="get_present_snids" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36659" type="J5WdE6USg2qD" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Call all the sub garbage functions." isSpecification="false" isLeaf="false" visibility="public" xmi.id="MulJvMHR2JsJ" isRoot="false" isAbstract="false" isQuery="false" name="garbage" />
+ <UML:Operation comment="Returns a reference on our own station data." isSpecification="false" isLeaf="false" visibility="public" xmi.id="i2znmIk8bVQ3" isRoot="false" isAbstract="false" isQuery="false" name="get_sta_own_data" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36660" type="yVCl3jm3PB1C" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the network slot usage." isSpecification="false" isLeaf="false" visibility="public" xmi.id="o7bH8l102RHc" isRoot="false" isAbstract="false" isQuery="false" name="get_slot_usage" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36661" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the number of discovered stations." isSpecification="false" isLeaf="false" visibility="public" xmi.id="NDGrlwJSDY8B" isRoot="false" isAbstract="false" isQuery="false" name="get_num_discovered_sta" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36662" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the number of discovered networks." isSpecification="false" isLeaf="false" visibility="public" xmi.id="HwdXOmbaswch" isRoot="false" isAbstract="false" isQuery="false" name="get_num_discovered_net" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36663" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get our AVLN network." isSpecification="false" isLeaf="false" visibility="public" xmi.id="5SqO4seTjRSa" isRoot="false" isAbstract="false" isQuery="false" name="get_our_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36664" type="TRzc3eNXqLr1" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set our network." isSpecification="false" isLeaf="false" visibility="public" xmi.id="7000" isRoot="false" isAbstract="false" isQuery="false" name="set_our_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The network to be considered as our." isSpecification="false" visibility="private" xmi.id="7001" value="" type="TRzc3eNXqLr1" name="net" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Move the station to the release list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="7802" isRoot="false" isAbstract="false" isQuery="false" name="release_station" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station's TEI." isSpecification="false" visibility="private" xmi.id="7803" value="" type="emAuInlIaxvV" name="tei" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Add a station to the station manager." isSpecification="false" isLeaf="false" visibility="public" xmi.id="34154" isRoot="false" isAbstract="false" isQuery="false" name="sta_add" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station's AVLN." isSpecification="false" visibility="private" xmi.id="34255" value="" type="TRzc3eNXqLr1" name="net" />
+ <UML:Parameter comment="The station TEI." isSpecification="false" visibility="private" xmi.id="34155" value="" type="emAuInlIaxvV" name="tei" />
+ <UML:Parameter comment="The station mac address." isSpecification="false" visibility="private" xmi.id="34205" value="" type="Q4TYO2bRfXJq" name="mac_addr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Removes the station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="34599" isRoot="false" isAbstract="false" isQuery="false" name="sta_remove" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station to remove." isSpecification="false" visibility="private" xmi.id="34847" value="" type="DcaQZXHCYAUY" name="sta" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Remove a station from the net by its TEI." isSpecification="false" isLeaf="false" visibility="public" xmi.id="34897" isRoot="false" isAbstract="false" isQuery="false" name="sta_remove_assoc" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station's AVLN." isSpecification="false" visibility="private" xmi.id="34898" value="" type="TRzc3eNXqLr1" name="net" />
+ <UML:Parameter comment="The station's TEI." isSpecification="false" visibility="private" xmi.id="34948" value="" type="emAuInlIaxvV" name="tei" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Removes a station by its mac address.
+The commit to dataplane function shall be called if the station is in our AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="35047" isRoot="false" isAbstract="false" isQuery="false" name="sta_remove_from_mac" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station mac address." isSpecification="false" visibility="private" xmi.id="35048" value="" type="Q4TYO2bRfXJq" name="mac_addr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the associated station by its TEI in the net." isSpecification="false" isLeaf="false" visibility="public" xmi.id="35147" isRoot="false" isAbstract="false" isQuery="false" name="sta_get_assoc" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36665" type="DcaQZXHCYAUY" />
+ <UML:Parameter comment="The station's Network." isSpecification="false" visibility="private" xmi.id="35148" value="" type="TRzc3eNXqLr1" name="net" />
+ <UML:Parameter comment="The station's TEI." isSpecification="false" visibility="private" xmi.id="35198" value="" type="emAuInlIaxvV" name="tei" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the station using its mac address.
+If no station found, NULL value returned." isSpecification="false" isLeaf="false" visibility="public" xmi.id="35298" isRoot="false" isAbstract="false" isQuery="false" name="sta_get_from_mac" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36666" type="DcaQZXHCYAUY" />
+ <UML:Parameter comment="The station's mac address." isSpecification="false" visibility="private" xmi.id="35299" value="" type="Q4TYO2bRfXJq" name="mac_addr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Verify the net list status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="35605" isRoot="false" isAbstract="false" isQuery="false" name="net_list_is_empty" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36667" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Commit the modification of our AVLN to the dataplane." isSpecification="false" isLeaf="false" visibility="public" xmi.id="35866" isRoot="false" isAbstract="false" isQuery="false" name="commit_to_dataplane" />
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class comment="Control plane station." isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="tftTuiZXSv4R" isRoot="false" isAbstract="false" name="cp_sta_t" >
+ <UML:Classifier.feature>
+ <UML:Attribute comment="Station's tei." isSpecification="false" visibility="private" xmi.id="w2lpqlcRNBky" type="emAuInlIaxvV" name="tei" />
+ <UML:Attribute comment="Station's mac address." isSpecification="false" visibility="private" xmi.id="KjxDjNipVmH6" type="Q4TYO2bRfXJq" name="mac_address" />
+ <UML:Attribute comment="Indicate if the station is Visible by our station." isSpecification="false" visibility="private" xmi.id="nJw1e6ulB8mV" type="BsXuVmQldfSS" name="visible" />
+ <UML:Attribute comment="Indicate if the station is CCo." isSpecification="false" visibility="private" xmi.id="9SydFFh3ENAt" type="BsXuVmQldfSS" name="is_cco" />
+ <UML:Attribute comment="GLID provided to the PCO to transmit a proxy beacon." isSpecification="false" visibility="private" xmi.id="76E3M1i7iJGy" type="nnvOyvzkSE17" name="pco_glid" />
+ <UML:Attribute comment="Indicate the state of the station." isSpecification="false" visibility="private" xmi.id="njbBHkqZRmmB" type="pBzpcllJMdsq" name="station_state" />
+ <UML:Attribute comment="The network whithin the station is associatied." isSpecification="false" visibility="private" xmi.id="30115" type="TRzc3eNXqLr1" name="net" />
+ <UML:Attribute comment="Indicate if the station is Backup CCo." isSpecification="false" visibility="public" xmi.id="15VSrGbyiZbv" type="BsXuVmQldfSS" name="is_backup_cco" />
+ <UML:Attribute comment="Last date seen in the AVLN." isSpecification="false" visibility="public" xmi.id="7SdojrmkwHBl" type="oZHHg64PKBaq" name="last_seen_ms" />
+ <UML:Attribute comment="The Reassembly context for the cl_interf." isSpecification="false" visibility="public" xmi.id="61vH7gnD8O1s" type="RTeIWtKTDaZV" name="reassembly_ctx" />
+ <UML:Attribute comment="The tei expiration date." isSpecification="false" visibility="public" xmi.id="O3jgPKW1znfn" type="oZHHg64PKBaq" name="tei_lease_ms" />
+ <UML:Attribute comment="The station CCo capability." isSpecification="false" visibility="public" xmi.id="uZ2PRCIQqOal" type="nnvOyvzkSE17" name="cco_cap" />
+ <UML:Attribute comment="Indicate if the station can be PCo." isSpecification="false" visibility="public" xmi.id="SKPVcXpzB5Y4" type="BsXuVmQldfSS" name="pco_cap" />
+ <UML:Attribute comment="Indicate if the stations can be backup CCo." isSpecification="false" visibility="public" xmi.id="FcAqRxkJWmhw" type="BsXuVmQldfSS" name="backup_cco_cap" />
+ <UML:Attribute comment="Number of discover stations." isSpecification="false" visibility="public" xmi.id="R3na9McOwmEN" type="nnvOyvzkSE17" name="numDisSta" />
+ <UML:Attribute comment="Number of discover networks." isSpecification="false" visibility="public" xmi.id="jwhEhOAeLWRh" type="nnvOyvzkSE17" name="numDisNet" />
+ <UML:Attribute comment="The Average BLE." isSpecification="false" visibility="public" xmi.id="27448" type="nnvOyvzkSE17" name="average_ble" />
+ <UML:Operation comment="Return a station object initialised." isSpecification="false" isLeaf="false" visibility="private" xmi.id="AaNPCwE5GYpL" isRoot="false" isAbstract="false" isQuery="false" name="init" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36668" type="DcaQZXHCYAUY" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Uninitialise the station." isSpecification="false" isLeaf="false" visibility="private" xmi.id="1HLA3MQK09Yr" isRoot="false" isAbstract="false" isQuery="false" name="uninit" />
+ <UML:Operation comment="Get the station's TEI." isSpecification="false" isLeaf="false" visibility="public" xmi.id="BxTRzdcxFOCK" isRoot="false" isAbstract="false" isQuery="false" name="get_tei" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36669" type="emAuInlIaxvV" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the station's mac address." isSpecification="false" isLeaf="false" visibility="public" xmi.id="feEeHoZUCjo5" isRoot="false" isAbstract="false" isQuery="false" name="get_mac_address" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36670" type="Q4TYO2bRfXJq" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the station's cco status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="MEr8fhvtbOQD" isRoot="false" isAbstract="false" isQuery="false" name="get_cco_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36671" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the Proxy CCo status of the station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="aCtLsOAUOvwU" isRoot="false" isAbstract="false" isQuery="false" name="get_pco_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36672" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the visible status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="28593" isRoot="false" isAbstract="false" isQuery="false" name="set_visible" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The visible status." isSpecification="false" visibility="private" xmi.id="28594" value="" type="7PSrs3lMwQVn" name="status" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the visible status of the station on the medium." isSpecification="false" isLeaf="false" visibility="public" xmi.id="OSlCnQfCxj2t" isRoot="false" isAbstract="false" isQuery="false" name="get_visible_status" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36673" type="7PSrs3lMwQVn" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Return the PCO GLID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="H29zTi1CMn0S" isRoot="false" isAbstract="false" isQuery="false" name="get_pco_glid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36674" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the station GLID to use as PCO." isSpecification="false" isLeaf="false" visibility="public" xmi.id="xjmXt0pRpbh7" isRoot="false" isAbstract="false" isQuery="false" name="set_pco_glid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The station GLID." isSpecification="false" visibility="private" xmi.id="SNF25bArqwZ3" value="" type="nnvOyvzkSE17" name="glid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Fill peer structure with station TEI and MAC address." isSpecification="false" isLeaf="false" visibility="public" xmi.id="19160" isRoot="false" isAbstract="false" isQuery="false" name="get_peer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="peer structure to fill." isSpecification="false" visibility="private" xmi.id="19161" value="" type="15653" name="peer" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the authenticated status." isSpecification="false" isLeaf="false" visibility="public" xmi.id="28699" isRoot="false" isAbstract="false" isQuery="false" name="set_authenticated" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The authentication status." isSpecification="false" visibility="private" xmi.id="28700" value="" type="BsXuVmQldfSS" name="auth" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Return the authenticated status of the station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="28805" isRoot="false" isAbstract="false" isQuery="false" name="get_authenticated" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36675" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="QCdiA5hU9IAb" isRoot="false" isAbstract="false" name="cp_net_t" >
+ <UML:Classifier.feature>
+ <UML:Attribute comment="AVLN's SNID." isSpecification="false" visibility="private" xmi.id="9PZYdnDFOfZz" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Attribute comment="AVLN's NID." isSpecification="false" visibility="private" xmi.id="I2w0DZg3Mq2z" type="f1lxWwdNwvpr" name="nid" />
+ <UML:Attribute comment="The pointer to the CCo station." isSpecification="false" visibility="private" xmi.id="HiveU00Ud1Ud" type="DcaQZXHCYAUY" name="cco" />
+ <UML:Attribute comment="the pointer to the Pco station." isSpecification="false" visibility="private" xmi.id="tVZmk23YSl2D" type="DcaQZXHCYAUY" name="pco" />
+ <UML:Attribute comment="The pointer to the UCCo." isSpecification="false" visibility="private" xmi.id="4144" type="DcaQZXHCYAUY" name="ucco" />
+ <UML:Attribute comment="The expiration date at the one this AVLN should be removed from the list. This will be verified in the garbage function." isSpecification="false" visibility="private" xmi.id="fU07vNLGT9Ie" type="oZHHg64PKBaq" name="expiration_ms" />
+ <UML:Attribute comment="The list of associated stations in the AVLN." isSpecification="false" visibility="private" xmi.id="bJPnIIOxkO2f" type="OF2Sin3o242W" name="associated_stas" />
+ <UML:Attribute comment="The list of unassociated stations in the AVLN." isSpecification="false" visibility="private" xmi.id="kNvDWBsghjTC" type="OF2Sin3o242W" name="unassociated_stas" />
+ <UML:Attribute comment="AVLN slot id." isSpecification="false" visibility="private" xmi.id="AqQWPXxzCapd" type="nnvOyvzkSE17" name="avln_slot_id" />
+ <UML:Attribute comment="The slot usage read in the AVLN's central beacon." isSpecification="false" visibility="private" xmi.id="p8FRmwBNLQgP" type="nnvOyvzkSE17" name="avln_slot_usage" />
+ <UML:Attribute comment="Number of visible stations in the AVLN, correspond to the station visible or discovered by the station." isSpecification="false" visibility="private" xmi.id="kr6KLUaiRjIH" type="nnvOyvzkSE17" name="num_visible_stas" />
+ <UML:Attribute comment="The number of stations contained in the network." isSpecification="false" visibility="private" xmi.id="0qvffRz2S8ru" type="nnvOyvzkSE17" name="num_stas" />
+ <UML:Attribute comment="The network mode." isSpecification="false" visibility="private" xmi.id="S6pIWhJZQV41" type="cxkkcPlqeSGi" name="network_mode" />
+ <UML:Attribute comment="Present flag" isSpecification="false" visibility="private" xmi.id="17196" type="BsXuVmQldfSS" name="present" />
+ <UML:Attribute comment="The access status of the Network." isSpecification="false" visibility="private" xmi.id="29018" type="27023" name="access" />
+ <UML:Operation isSpecification="false" isLeaf="false" visibility="public" xmi.id="L8nWSpKOxfIH" isRoot="false" isAbstract="false" isQuery="false" name="init" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="Indicate if it corresponds to the station's avln." isSpecification="false" visibility="private" xmi.id="GVgAWD6b5uCt" value="" type="BsXuVmQldfSS" name="station_avln" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Unitialise the network." isSpecification="false" isLeaf="false" visibility="public" xmi.id="025OblSx0TOi" isRoot="false" isAbstract="false" isQuery="false" name="uninit" />
+ <UML:Operation comment="Set the CCo in the Network list.
+Shall update the data bases." isSpecification="false" isLeaf="false" visibility="public" xmi.id="3UBqgc2KKU2C" isRoot="false" isAbstract="false" isQuery="false" name="set_cco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The Station's TEI which is the CCo." isSpecification="false" visibility="private" xmi.id="tUrReG3DLDos" value="" type="emAuInlIaxvV" name="tei" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the CCo of this AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="3ABOLzFXlfcB" isRoot="false" isAbstract="false" isQuery="false" name="get_cco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36676" type="DcaQZXHCYAUY" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the peer structure of the CCo of this AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="15942" isRoot="false" isAbstract="false" isQuery="false" name="get_cco_peer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="peer structure pointer." isSpecification="false" visibility="private" xmi.id="15943" value="" type="15653" name="peer" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the PCo for this station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="3tINqVucAXnG" isRoot="false" isAbstract="false" isQuery="false" name="set_pco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="PCo's tei." isSpecification="false" visibility="private" xmi.id="nQGtNqOhHcnd" value="" type="emAuInlIaxvV" name="tei" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the PCo of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="iaLbV3XXwoul" isRoot="false" isAbstract="false" isQuery="false" name="get_pco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36677" type="DcaQZXHCYAUY" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get eh perr structure of the PCo of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="16040" isRoot="false" isAbstract="false" isQuery="false" name="get_pco_peer" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="Peer structure pointer." isSpecification="false" visibility="private" xmi.id="16041" value="" type="15653" name="peer" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Returns the first station of an AVLN. The user has the responsibility to release the reference on the returned station." isSpecification="false" isLeaf="false" visibility="public" xmi.id="W8rOQJZys2Nh" isRoot="false" isAbstract="false" isQuery="false" name="sta_get_first" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36678" type="DcaQZXHCYAUY" />
+ <UML:Parameter comment="to search in the associated stations or unassociated STAs." isSpecification="false" visibility="private" xmi.id="uegtnCaW6HvZ" value="" type="pBzpcllJMdsq" name="assoc" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the next station from the AVLN stating by the previous one already request. This function shall be call after get_first.
+The user have the responsibility to release the reference on both stations i.e. prev_sta and the returned sta." isSpecification="false" isLeaf="false" visibility="public" xmi.id="LSNW129OipWM" isRoot="false" isAbstract="false" isQuery="false" name="sta_get_next" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36679" type="DcaQZXHCYAUY" />
+ <UML:Parameter comment="The previous station requested." isSpecification="false" visibility="private" xmi.id="QpgFnJlzqGcm" value="" type="DcaQZXHCYAUY" name="prev_sta" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the network SNID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="ihLtnkq61iHr" isRoot="false" isAbstract="false" isQuery="false" name="get_snid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36680" type="0mEev7QHu3Xw" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Garbage function for the unassociated station list and the associated station list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="17437" isRoot="false" isAbstract="false" isQuery="false" name="garbage_stations" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The current date in milliseconds." isSpecification="false" visibility="private" xmi.id="17438" value="" type="X7Q5Iud3fXPb" name="date_ms" />
+ <UML:Parameter comment="The station status." isSpecification="false" visibility="private" xmi.id="17487" value="" type="pBzpcllJMdsq" name="assoc" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the AVLN NID." isSpecification="false" isLeaf="false" visibility="public" xmi.id="ljJ5Ao4US5yj" isRoot="false" isAbstract="false" isQuery="false" name="get_nid" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36681" type="f1lxWwdNwvpr" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the AVLN slot id." isSpecification="false" isLeaf="false" visibility="public" xmi.id="Nsj0r8ybFTqj" isRoot="false" isAbstract="false" isQuery="false" name="set_slot_id_and_usage" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The AVLN Slot id." isSpecification="false" visibility="private" xmi.id="YBDZ7f07dRHq" value="" type="nnvOyvzkSE17" name="slot_id" />
+ <UML:Parameter comment="The slot usage mask." isSpecification="false" visibility="private" xmi.id="A9M6Rbk9UhsU" value="" type="nnvOyvzkSE17" name="slot_usage" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the slot identifier of the network." isSpecification="false" isLeaf="false" visibility="public" xmi.id="tXX7yCe6ABln" isRoot="false" isAbstract="false" isQuery="false" name="get_slot_id" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36682" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Return the slot usage mask of the AVLN read in the central beacon of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="po8WMv8qvmgP" isRoot="false" isAbstract="false" isQuery="false" name="get_slot_usage_mask" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36683" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the number of station discovered in this AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="eOkr2PyKZULL" isRoot="false" isAbstract="false" isQuery="false" name="get_num_discovered_stas" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36684" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the number of station of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="pq6Gp6gvxZjX" isRoot="false" isAbstract="false" isQuery="false" name="get_num_stas" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36685" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Set the current network mode of the network." isSpecification="false" isLeaf="false" visibility="public" xmi.id="EQSO9Nrh7vtl" isRoot="false" isAbstract="false" isQuery="false" name="set_nm" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The current network mode of the network." isSpecification="false" visibility="private" xmi.id="0k5Hjgz6Os8M" value="" type="cxkkcPlqeSGi" name="nm" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the current network mode of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="z1wK2LaEl0as" isRoot="false" isAbstract="false" isQuery="false" name="get_nm" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36686" type="cxkkcPlqeSGi" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the status of the network." isSpecification="false" isLeaf="false" visibility="public" xmi.id="16667" isRoot="false" isAbstract="false" isQuery="false" name="is_empty" />
+ <UML:Operation comment="Set the UCCo of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="16715" isRoot="false" isAbstract="false" isQuery="false" name="set_ucco" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The sation which is Ucco." isSpecification="false" visibility="private" xmi.id="16716" value="" type="DcaQZXHCYAUY" name="sta" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the UCCo of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="16811" isRoot="false" isAbstract="false" isQuery="false" name="get_ucco" />
+ <UML:Operation comment="Set the access of the AVLN," isSpecification="false" isLeaf="false" visibility="public" xmi.id="29723" isRoot="false" isAbstract="false" isQuery="false" name="set_access" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The access state of the station." isSpecification="false" visibility="private" xmi.id="29724" value="" type="27023" name="access" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the access type of the AVLN." isSpecification="false" isLeaf="false" visibility="public" xmi.id="29869" isRoot="false" isAbstract="false" isQuery="false" name="get_access" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36687" type="27023" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="qIWnFzBd9oKJ" isRoot="false" isAbstract="false" name="cp_net_list_t" >
+ <UML:Classifier.feature>
+ <UML:Operation comment="Inititliase the network list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="Qd9Ie0K9YadK" isRoot="false" isAbstract="false" isQuery="false" name="init" />
+ <UML:Operation comment="Unitialise the network list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="fhhadu0Xv5sq" isRoot="false" isAbstract="false" isQuery="false" name="uninit" />
+ <UML:Operation comment="Calls the sub modules garbage to remove old data." isSpecification="false" isLeaf="false" visibility="public" xmi.id="qF2AzTzTvsRh" isRoot="false" isAbstract="false" isQuery="false" name="garbage_net" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The current date in milliseconds." isSpecification="false" visibility="private" xmi.id="YBhJPHujWWR7" value="" type="X7Q5Iud3fXPb" name="date_ms" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Add an AVLN to the list." isSpecification="false" isLeaf="false" visibility="public" xmi.id="dvGudEhkvNbD" isRoot="false" isAbstract="false" isQuery="false" name="add_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36688" type="TRzc3eNXqLr1" />
+ <UML:Parameter comment="The AVLN's SNID to add." isSpecification="false" visibility="private" xmi.id="k5UOGYbYkzwv" value="" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Parameter comment="The AVLN's NID to add." isSpecification="false" visibility="private" xmi.id="WkkbSbh3Uxx8" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Removes an AVLN from the sta manager." isSpecification="false" isLeaf="false" visibility="public" xmi.id="Ads5yTHiXj5l" isRoot="false" isAbstract="false" isQuery="false" name="remove_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter comment="The AVLN's SNID to remove." isSpecification="false" visibility="private" xmi.id="FgKxfGs90bkR" value="" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Parameter comment="The AVLN's NID to remove." isSpecification="false" visibility="private" xmi.id="5rhaamLoQfl3" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Returns the AVLN corresponding to the snid and nid." isSpecification="false" isLeaf="false" visibility="public" xmi.id="vcDuDxLNPn0k" isRoot="false" isAbstract="false" isQuery="false" name="get_avln" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36689" type="TRzc3eNXqLr1" />
+ <UML:Parameter comment="The AVLN's snid to get." isSpecification="false" visibility="private" xmi.id="DlHEPrDSht2F" value="" type="0mEev7QHu3Xw" name="snid" />
+ <UML:Parameter comment="The AVLN's NID to get." isSpecification="false" visibility="private" xmi.id="dN341p7uPKoa" value="" type="f1lxWwdNwvpr" name="nid" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Verify if the network list is empty and return true if it is." isSpecification="false" isLeaf="false" visibility="public" xmi.id="thTkEhFFV82W" isRoot="false" isAbstract="false" isQuery="false" name="is_empty" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36690" type="BsXuVmQldfSS" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Create a 16 bits flag indicating which SNID are in use." isSpecification="false" isLeaf="false" visibility="public" xmi.id="fEG2VdimBUrx" isRoot="false" isAbstract="false" isQuery="false" name="get_snid_present" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36691" type="J5WdE6USg2qD" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the slot usage of the AVLNs computed on the slots IDs of each AVLN present.
+It corresponds to a 8 bits field." isSpecification="false" isLeaf="false" visibility="public" xmi.id="dEIri7aEIlnP" isRoot="false" isAbstract="false" isQuery="false" name="get_slot_usage" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36692" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the number of discovered station on all AVLNs." isSpecification="false" isLeaf="false" visibility="public" xmi.id="0swcx8FCE83L" isRoot="false" isAbstract="false" isQuery="false" name="get_num_discover_stas" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36693" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ <UML:Operation comment="Get the quantity of network discovered." isSpecification="false" isLeaf="false" visibility="public" xmi.id="iz4t8GAcZAqw" isRoot="false" isAbstract="false" isQuery="false" name="get_num_discovered_net" >
+ <UML:BehavioralFeature.parameter>
+ <UML:Parameter kind="return" xmi.id="36694" type="nnvOyvzkSE17" />
+ </UML:BehavioralFeature.parameter>
+ </UML:Operation>
+ </UML:Classifier.feature>
+ </UML:Class>
+ <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="pBzpcllJMdsq" isRoot="false" isAbstract="false" name="cp_net_sta_status_t" >
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="pBzpcllJMdsq" xmi.id="AYBjv2FiBCYl" isRoot="false" isAbstract="false" name="UNASSOC" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="pBzpcllJMdsq" xmi.id="TS9huSQ4zbmu" isRoot="false" isAbstract="false" name="ASSOCIATED" />
+ </UML:Enumeration>
+ <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="SsuRPlPUGZjG" isRoot="false" isAbstract="false" name="cp_security_level_t" >
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="SsuRPlPUGZjG" xmi.id="YGOeDlDfb740" isRoot="false" isAbstract="false" name="CP_SECURITY_LEVEL_SC" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="SsuRPlPUGZjG" xmi.id="8rMiHZwnqIP3" isRoot="false" isAbstract="false" name="CP_SECURITY_LEVEL_HS" />
+ </UML:Enumeration>
+ <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="cxkkcPlqeSGi" isRoot="false" isAbstract="false" name="cp_net_network_mode_t" >
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="cxkkcPlqeSGi" xmi.id="7AfLHTarQIb0" isRoot="false" isAbstract="false" name="CP_NET_NM_UNCOORDINATED" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="cxkkcPlqeSGi" xmi.id="1IbnbOCiWr4l" isRoot="false" isAbstract="false" name="CP_NET_NM_COORDINATED" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="cxkkcPlqeSGi" xmi.id="UsJ25EL4Uwr6" isRoot="false" isAbstract="false" name="CP_NET_NM_CSMA_ONLY" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="cxkkcPlqeSGi" xmi.id="MWptygBQWUQa" isRoot="false" isAbstract="false" name="CP_NET_NM_ASSERT" />
+ </UML:Enumeration>
+ <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="7PSrs3lMwQVn" isRoot="false" isAbstract="false" name="cp_sta_visible_state_t" >
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="7PSrs3lMwQVn" xmi.id="200XB2ebUTRX" isRoot="false" isAbstract="false" name="CP_STA_VISIBLE_STATE_HIDDEN" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="7PSrs3lMwQVn" xmi.id="v7wHq2ss2qNB" isRoot="false" isAbstract="false" name="CP_STA_VISIBLE_STATE_VISIBLE" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="7PSrs3lMwQVn" xmi.id="VkDZ8Ke4QYJG" isRoot="false" isAbstract="false" name="CP_STA_VISIBLE_STATE_ASSERT" />
+ </UML:Enumeration>
+ <UML:Package stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="rLUcIo7kRV6u" isRoot="false" isAbstract="false" name="sequences" >
+ <UML:Namespace.ownedElement/>
+ </UML:Package>
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="22789" isRoot="false" isAbstract="false" name="sta_mgr" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="22946" isRoot="false" isAbstract="false" name="net_list" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="22999" isRoot="false" isAbstract="false" name="sta_own_data" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="23052" isRoot="false" isAbstract="false" name="net" />
+ <UML:Class isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="23105" isRoot="false" isAbstract="false" name="sta" />
+ <UML:Package stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="25613" isRoot="false" isAbstract="false" name="Classes" >
+ <UML:Namespace.ownedElement/>
+ <XMI.extension xmi.extender="umbrello" >
+ <diagrams>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="972" snapy="10" showatts="1" xmi.id="25666" documentation="" type="1" showops="1" showpackage="0" name="manager" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="842" >
+ <widgets>
+ <classwidget usesdiagramfillcolour="0" width="352" showattsigs="601" usesdiagramusefillcolour="0" x="201" y="76" showopsigs="601" linewidth="none" fillcolour="#ffffc0" height="375" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="L2ASUCoHdFZ0" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ </widgets>
+ <messages/>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="972" snapy="10" showatts="1" xmi.id="25979" documentation="" type="1" showops="1" showpackage="0" name="own_data" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="842" >
+ <widgets>
+ <classwidget usesdiagramfillcolour="1" width="296" showattsigs="601" usesdiagramusefillcolour="1" x="281" y="19" showopsigs="601" linewidth="none" fillcolour="none" height="780" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="dQQc692tOFUS" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,50,1,0,0,0,0" linecolor="none" />
+ </widgets>
+ <messages/>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="972" snapy="10" showatts="1" xmi.id="26240" documentation="" type="1" showops="1" showpackage="0" name="net_list" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="842" >
+ <widgets>
+ <classwidget usesdiagramfillcolour="1" width="324" showattsigs="601" usesdiagramusefillcolour="1" x="250" y="177" showopsigs="601" linewidth="none" fillcolour="none" height="187" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="qIWnFzBd9oKJ" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="none" />
+ </widgets>
+ <messages/>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="972" snapy="10" showatts="1" xmi.id="26501" documentation="" type="1" showops="1" showpackage="0" name="net" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="842" >
+ <widgets>
+ <classwidget usesdiagramfillcolour="0" width="397" showattsigs="601" usesdiagramusefillcolour="0" x="179" y="30" showopsigs="601" linewidth="none" fillcolour="#ffffc0" height="615" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="QCdiA5hU9IAb" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ </widgets>
+ <messages/>
+ <associations/>
+ </diagram>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="972" snapy="10" showatts="1" xmi.id="26710" documentation="" type="1" showops="1" showpackage="0" name="sta" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="842" >
+ <widgets>
+ <classwidget usesdiagramfillcolour="0" width="271" showattsigs="601" usesdiagramusefillcolour="0" x="317" y="139" showopsigs="601" linewidth="none" fillcolour="#ffffc0" height="465" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="tftTuiZXSv4R" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ </widgets>
+ <messages/>
+ <associations/>
+ </diagram>
+ </diagrams>
+ </XMI.extension>
+ </UML:Package>
+ <UML:Enumeration stereotype="enum" isSpecification="false" isLeaf="false" visibility="public" namespace="Logical View" xmi.id="27023" isRoot="false" isAbstract="false" name="hpav_access_t" >
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="27023" xmi.id="27076" isRoot="false" isAbstract="false" name="HPAV_IN_HOME" />
+ <UML:EnumerationLiteral isSpecification="false" isLeaf="false" visibility="public" namespace="27023" xmi.id="27129" isRoot="false" isAbstract="false" name="HPAV_ACCESS" />
+ </UML:Enumeration>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="12189" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="12190" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="12191" aggregation="none" type="dQQc692tOFUS" name="sta_own_data" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="13891" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="13892" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="13893" aggregation="none" type="qIWnFzBd9oKJ" name="network_list" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="14924" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="14925" aggregation="composite" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="14926" aggregation="none" type="QCdiA5hU9IAb" name="networks" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="18563" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="18564" aggregation="none" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="18565" aggregation="none" type="QCdiA5hU9IAb" name="our_net" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="12189" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="12190" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="12191" aggregation="none" type="dQQc692tOFUS" name="sta_own_data" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="13891" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="13892" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="13893" aggregation="none" type="qIWnFzBd9oKJ" name="network_list" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="14924" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="14925" aggregation="composite" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="14926" aggregation="none" type="QCdiA5hU9IAb" name="networks" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="18563" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="18564" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="18565" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="19407" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="19408" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="19409" aggregation="none" type="tftTuiZXSv4R" name="associated_stas" multiplicity="254" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="19563" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="19564" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="19565" aggregation="none" type="tftTuiZXSv4R" name="unassociated_stas" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23366" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23367" aggregation="composite" type="22789" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23368" aggregation="none" type="22946" name="network_list" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23473" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23474" aggregation="composite" type="22789" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23475" aggregation="none" type="22999" name="sta_own_data" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23580" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23581" aggregation="composite" type="22946" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23582" aggregation="none" type="23052" name="networks" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23687" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23688" aggregation="aggregate" type="23052" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23689" aggregation="none" type="23105" name="associated_stas" multiplicity="254" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="24650" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="24651" aggregation="aggregate" type="23052" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="24652" aggregation="none" type="23105" name="unassociated_stas" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="24913" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="24914" aggregation="composite" type="22946" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="24915" aggregation="none" type="23052" name="networks" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="25292" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="25293" aggregation="aggregate" type="23052" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="25294" aggregation="none" type="23105" name="associated_stas" multiplicity="254" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="12189" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="12190" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="12191" aggregation="none" type="dQQc692tOFUS" name="sta_own_data" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="13891" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="13892" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="13893" aggregation="none" type="qIWnFzBd9oKJ" name="network_list" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="14924" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="14925" aggregation="composite" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="14926" aggregation="none" type="QCdiA5hU9IAb" name="networks" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="18563" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="18564" aggregation="none" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="18565" aggregation="none" type="QCdiA5hU9IAb" name="our_net" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="BzDeGrof35i3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="lQBEo3VLdIiB" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="yIVQyeIGHNsQ" aggregation="none" type="QCdiA5hU9IAb" name="" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="DWwHbcINxulG" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="L3waWG7FgHRS" aggregation="aggregate" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="KwlxER9BkcZg" aggregation="none" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="UODsawo5TGgC" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="EqxWDnuWpq6J" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="4BZiS08nxui9" aggregation="none" type="tftTuiZXSv4R" name="" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="c6v3mGeXVqXR" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="LpI3SskggfAt" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="S4PFsTZuc8c5" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="T1xzpUO46GR3" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="8lq3fWDyKT2m" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="LkQ1PZspdF5U" aggregation="none" type="tftTuiZXSv4R" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="rvcDZX0ujXxy" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="g5L0YLks59tS" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="ikIJzLnexCvh" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5IZpnXnsVu7G" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="BHXvPRI3Ud43" aggregation="aggregate" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="zmv2vmVbWlvU" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="5eDSOP8QymCv" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="6i63s1i3IFyh" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="fGk9smCpX5rQ" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="10345" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10346" aggregation="composite" type="qIWnFzBd9oKJ" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="10347" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="12189" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="12190" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="12191" aggregation="none" type="dQQc692tOFUS" name="sta_own_data" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="13891" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="13892" aggregation="composite" type="L2ASUCoHdFZ0" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="13893" aggregation="none" type="qIWnFzBd9oKJ" name="network_list" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="14924" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="14925" aggregation="composite" type="qIWnFzBd9oKJ" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="14926" aggregation="none" type="QCdiA5hU9IAb" name="networks" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="18563" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="18564" aggregation="none" type="L2ASUCoHdFZ0" name="" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="18565" aggregation="none" type="QCdiA5hU9IAb" name="" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="19407" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="19408" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="19409" aggregation="none" type="tftTuiZXSv4R" name="associated_stas" multiplicity="254" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="19563" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="19564" aggregation="aggregate" type="QCdiA5hU9IAb" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="19565" aggregation="none" type="tftTuiZXSv4R" name="unassociated_stas" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23366" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23367" aggregation="composite" type="22789" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23368" aggregation="none" type="22946" name="network_list" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23473" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23474" aggregation="composite" type="22789" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23475" aggregation="none" type="22999" name="sta_own_data" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23580" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23581" aggregation="composite" type="22946" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23582" aggregation="none" type="23052" name="networks" multiplicity="8" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="23687" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="23688" aggregation="aggregate" type="23052" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="23689" aggregation="none" type="23105" name="associated_stas" multiplicity="254" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="24650" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="24651" aggregation="aggregate" type="23052" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="24652" aggregation="none" type="23105" name="unassociated_stas" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="24913" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="24914" aggregation="composite" type="22946" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="24915" aggregation="none" type="23052" name="networks" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="25292" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="25293" aggregation="aggregate" type="23052" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="25294" aggregation="none" type="23105" name="associated_stas" multiplicity="254" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="32027" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="true" xmi.id="32028" aggregation="aggregate" type="22789" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="32029" aggregation="none" type="23105" name="stas" multiplicity="*" />
+ </UML:Association.connection>
+ </UML:Association>
+ <UML:Association isSpecification="false" visibility="public" namespace="Logical View" xmi.id="32575" name="" >
+ <UML:Association.connection>
+ <UML:AssociationEnd isSpecification="false" visibility="public" changeability="changeable" isNavigable="false" xmi.id="32576" aggregation="none" type="23105" name="" multiplicity="1" />
+ <UML:AssociationEnd isSpecification="false" visibility="private" changeability="changeable" isNavigable="true" xmi.id="32577" aggregation="none" type="23052" name="net" multiplicity="1" />
+ </UML:Association.connection>
+ </UML:Association>
+ </UML:Namespace.ownedElement>
+ <XMI.extension xmi.extender="umbrello" >
+ <diagrams>
+ <diagram snapgrid="0" showattsig="1" fillcolor="#ffffc0" linewidth="0" zoom="100" showgrid="0" showopsig="1" usefillcolor="1" snapx="10" canvaswidth="972" snapy="10" showatts="1" xmi.id="22684" documentation="" type="1" showops="1" showpackage="0" name="Package_class" localid="900000" showstereotype="0" showscope="1" snapcsgrid="0" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="#ff0000" canvasheight="842" >
+ <widgets>
+ <classwidget usesdiagramfillcolour="0" width="71" showattsigs="601" usesdiagramusefillcolour="0" x="402" y="86" showopsigs="601" linewidth="none" fillcolour="#ffffc0" height="29" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="22789" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="#ff0000" />
+ <classwidget usesdiagramfillcolour="1" width="57" showattsigs="601" usesdiagramusefillcolour="1" x="275" y="170" showopsigs="601" linewidth="none" fillcolour="none" height="29" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="22946" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="none" />
+ <classwidget usesdiagramfillcolour="1" width="98" showattsigs="601" usesdiagramusefillcolour="1" x="552" y="173" showopsigs="601" linewidth="none" fillcolour="none" height="29" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="22999" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="none" />
+ <classwidget usesdiagramfillcolour="1" width="32" showattsigs="601" usesdiagramusefillcolour="1" x="458" y="271" showopsigs="601" linewidth="none" fillcolour="none" height="32" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="23052" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="none" />
+ <classwidget usesdiagramfillcolour="1" width="30" showattsigs="601" usesdiagramusefillcolour="1" x="459" y="378" showopsigs="601" linewidth="none" fillcolour="none" height="29" usefillcolor="1" showpubliconly="0" showattributes="1" isinstance="0" xmi.id="23105" showoperations="1" showpackage="0" showscope="1" font="Sans Serif,9,-1,5,75,0,0,0,0,0" linecolor="none" />
+ </widgets>
+ <messages/>
+ <associations>
+ <assocwidget totalcounta="3" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="22946" widgetaid="22789" xmi.id="23366" linecolor="none" >
+ <linepath>
+ <startpoint startx="425" starty="115" />
+ <endpoint endx="303" endy="170" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="411" y="115" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="209" showstereotype="1" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="284" y="138" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="210" showstereotype="1" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="85" usesdiagramusefillcolour="1" x="305" y="149" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="209" showstereotype="1" text="network_list" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ <assocwidget totalcounta="3" indexa="2" totalcountb="2" indexb="1" linewidth="none" widgetbid="22999" widgetaid="22789" xmi.id="23473" linecolor="none" >
+ <linepath>
+ <startpoint startx="449" starty="115" />
+ <endpoint endx="601" endy="173" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="431" y="115" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="212" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="587" y="140" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="213" showstereotype="1" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="95" usesdiagramusefillcolour="1" x="504" y="152" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="211" text="sta_own_data" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="23105" widgetaid="23052" xmi.id="24650" linecolor="none" >
+ <linepath>
+ <startpoint startx="490" starty="287" />
+ <endpoint endx="489" endy="392" />
+ <point x="555" y="287" />
+ <point x="555" y="392" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="492" y="253" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="215" showstereotype="1" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="491" y="358" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="216" showstereotype="1" text="*" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="124" usesdiagramusefillcolour="1" x="491" y="394" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="214" text="unassociated_stas" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ <assocwidget totalcounta="2" indexa="1" totalcountb="3" indexb="1" linewidth="none" widgetbid="23052" widgetaid="22946" xmi.id="24913" linecolor="none" >
+ <linepath>
+ <startpoint startx="303" starty="199" />
+ <endpoint endx="458" endy="281" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="282" y="202" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="218" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="446" y="246" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="219" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="69" usesdiagramusefillcolour="1" x="387" y="260" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="217" text="networks" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ <assocwidget totalcounta="3" indexa="2" totalcountb="3" indexb="1" linewidth="none" widgetbid="23105" widgetaid="23052" xmi.id="25292" linecolor="none" >
+ <linepath>
+ <startpoint startx="458" starty="292" />
+ <endpoint endx="459" endy="387" />
+ <point x="392" y="292" />
+ <point x="392" y="387" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="424" y="258" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="221" showstereotype="1" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="437" y="355" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="222" showstereotype="1" text="254" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="110" usesdiagramusefillcolour="1" x="334" y="364" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="220" text="associated_stas" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ <assocwidget totalcounta="2" indexa="1" totalcountb="3" indexb="2" linewidth="none" widgetbid="23105" widgetaid="22789" xmi.id="32027" linecolor="none" >
+ <linepath>
+ <startpoint startx="402" starty="100" />
+ <endpoint endx="459" endy="397" />
+ <point x="225" y="100" />
+ <point x="225" y="397" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="368" y="66" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="224" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="425" y="407" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="225" text="*" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="42" usesdiagramusefillcolour="1" x="228" y="343" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="223" text="stas" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ <assocwidget totalcounta="2" indexa="1" totalcountb="2" indexb="1" linewidth="none" widgetbid="23052" widgetaid="23105" xmi.id="32575" linecolor="none" >
+ <linepath>
+ <startpoint startx="474" starty="378" />
+ <endpoint endx="474" endy="303" />
+ </linepath>
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="476" y="344" linewidth="none" posttext="" role="701" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="227" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="32" usesdiagramusefillcolour="1" x="476" y="305" linewidth="none" posttext="" role="702" fillcolour="none" height="32" usefillcolor="1" pretext="" isinstance="0" xmi.id="228" text="1" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ <floatingtext usesdiagramfillcolour="1" width="35" usesdiagramusefillcolour="1" x="437" y="305" linewidth="none" posttext="" role="710" fillcolour="none" height="19" usefillcolor="1" pretext="-" isinstance="0" xmi.id="226" text="net" font="Sans Serif,9,-1,5,50,0,0,0,0,0" linecolor="none" />
+ </assocwidget>
+ </associations>
+ </diagram>
+ </diagrams>
+ </XMI.extension>
+ </UML:Model>
+ <UML:Model stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Use Case View" isRoot="false" isAbstract="false" name="Use Case View" >
+ <UML:Namespace.ownedElement>
+ <UML:Actor isSpecification="false" isLeaf="false" visibility="public" namespace="Use Case View" xmi.id="g2RmQlkG6CqM" isRoot="false" isAbstract="false" name="CP" />
+ </UML:Namespace.ownedElement>
+ </UML:Model>
+ <UML:Model stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Component View" isRoot="false" isAbstract="false" name="Component View" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ <UML:Model stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Deployment View" isRoot="false" isAbstract="false" name="Deployment View" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ <UML:Model stereotype="2" isSpecification="false" isLeaf="false" visibility="public" namespace="m1" xmi.id="Entity Relationship Model" isRoot="false" isAbstract="false" name="Entity Relationship Model" >
+ <UML:Namespace.ownedElement/>
+ </UML:Model>
+ </UML:Namespace.ownedElement>
+ </UML:Model>
+ </XMI.content>
+ <XMI.extensions xmi.extender="umbrello" >
+ <docsettings viewid="26710" documentation="" uniqueid="36694" />
+ <listview>
+ <listitem open="1" type="800" label="Views" >
+ <listitem open="1" type="801" id="Logical View" >
+ <listitem open="1" type="803" id="25613" >
+ <listitem open="0" type="807" id="25666" label="manager" />
+ <listitem open="0" type="807" id="26501" label="net" />
+ <listitem open="0" type="807" id="26240" label="net_list" />
+ <listitem open="0" type="807" id="25979" label="own_data" />
+ <listitem open="0" type="807" id="26710" label="sta" />
+ </listitem>
+ <listitem open="0" type="803" id="rLUcIo7kRV6u" >
+ <listitem open="0" type="810" id="AP5TiteE7LRQ" label="add_avln" />
+ <listitem open="0" type="810" id="7H0owQzfSQY2" label="add_one_sta" />
+ <listitem open="0" type="810" id="RSnHUDavlWhS" label="add_some_stas" />
+ <listitem open="0" type="810" id="neR6JQh9hknw" label="get_avln" />
+ <listitem open="0" type="810" id="fx8vI9va2Fiw" label="get_sta" />
+ <listitem open="0" type="810" id="poqwIOBuIxHD" label="remove_avln" />
+ <listitem open="0" type="810" id="TXHwr69BCMDJ" label="remove_some_stas" />
+ <listitem open="0" type="810" id="m64ppNaUHAGt" label="remove_sta" />
+ </listitem>
+ <listitem open="0" type="807" id="22684" label="Package_class" />
+ <listitem open="0" type="807" id="bZ62yFKbgidF" label="diagramme de classes" />
+ <listitem open="0" type="813" id="qIWnFzBd9oKJ" >
+ <listitem open="0" type="815" id="Qd9Ie0K9YadK" />
+ <listitem open="0" type="815" id="fhhadu0Xv5sq" />
+ <listitem open="0" type="815" id="qF2AzTzTvsRh" />
+ <listitem open="0" type="815" id="dvGudEhkvNbD" />
+ <listitem open="0" type="815" id="Ads5yTHiXj5l" />
+ <listitem open="0" type="815" id="vcDuDxLNPn0k" />
+ <listitem open="0" type="815" id="thTkEhFFV82W" />
+ <listitem open="0" type="815" id="fEG2VdimBUrx" />
+ <listitem open="0" type="815" id="dEIri7aEIlnP" />
+ <listitem open="0" type="815" id="0swcx8FCE83L" />
+ <listitem open="0" type="815" id="iz4t8GAcZAqw" />
+ </listitem>
+ <listitem open="0" type="813" id="QCdiA5hU9IAb" >
+ <listitem open="0" type="814" id="9PZYdnDFOfZz" />
+ <listitem open="0" type="814" id="I2w0DZg3Mq2z" />
+ <listitem open="0" type="814" id="HiveU00Ud1Ud" />
+ <listitem open="0" type="814" id="tVZmk23YSl2D" />
+ <listitem open="0" type="814" id="4144" />
+ <listitem open="0" type="814" id="fU07vNLGT9Ie" />
+ <listitem open="0" type="814" id="bJPnIIOxkO2f" />
+ <listitem open="0" type="814" id="kNvDWBsghjTC" />
+ <listitem open="0" type="814" id="AqQWPXxzCapd" />
+ <listitem open="0" type="814" id="p8FRmwBNLQgP" />
+ <listitem open="0" type="814" id="kr6KLUaiRjIH" />
+ <listitem open="0" type="814" id="0qvffRz2S8ru" />
+ <listitem open="0" type="814" id="S6pIWhJZQV41" />
+ <listitem open="0" type="814" id="17196" />
+ <listitem open="0" type="814" id="29018" />
+ <listitem open="0" type="815" id="L8nWSpKOxfIH" />
+ <listitem open="0" type="815" id="025OblSx0TOi" />
+ <listitem open="0" type="815" id="3UBqgc2KKU2C" />
+ <listitem open="0" type="815" id="3ABOLzFXlfcB" />
+ <listitem open="0" type="815" id="15942" />
+ <listitem open="0" type="815" id="3tINqVucAXnG" />
+ <listitem open="0" type="815" id="iaLbV3XXwoul" />
+ <listitem open="0" type="815" id="16040" />
+ <listitem open="0" type="815" id="W8rOQJZys2Nh" />
+ <listitem open="0" type="815" id="LSNW129OipWM" />
+ <listitem open="0" type="815" id="ihLtnkq61iHr" />
+ <listitem open="0" type="815" id="17437" />
+ <listitem open="0" type="815" id="ljJ5Ao4US5yj" />
+ <listitem open="0" type="815" id="Nsj0r8ybFTqj" />
+ <listitem open="0" type="815" id="tXX7yCe6ABln" />
+ <listitem open="0" type="815" id="po8WMv8qvmgP" />
+ <listitem open="0" type="815" id="eOkr2PyKZULL" />
+ <listitem open="0" type="815" id="pq6Gp6gvxZjX" />
+ <listitem open="0" type="815" id="EQSO9Nrh7vtl" />
+ <listitem open="0" type="815" id="z1wK2LaEl0as" />
+ <listitem open="0" type="815" id="16667" />
+ <listitem open="0" type="815" id="16715" />
+ <listitem open="0" type="815" id="16811" />
+ <listitem open="0" type="815" id="29723" />
+ <listitem open="0" type="815" id="29869" />
+ </listitem>
+ <listitem open="1" type="813" id="L2ASUCoHdFZ0" >
+ <listitem open="0" type="814" id="12890" />
+ <listitem open="0" type="814" id="33908" />
+ <listitem open="0" type="815" id="QXnrJp4mc3nZ" />
+ <listitem open="0" type="815" id="bxBBvbAGs7Q5" />
+ <listitem open="0" type="815" id="vk7FSeQIaeIS" />
+ <listitem open="0" type="815" id="qHxkg2dtESUh" />
+ <listitem open="0" type="815" id="2gQknmKqTzYm" />
+ <listitem open="0" type="815" id="DC8mABArXbfX" />
+ <listitem open="0" type="815" id="MulJvMHR2JsJ" />
+ <listitem open="0" type="815" id="i2znmIk8bVQ3" />
+ <listitem open="0" type="815" id="o7bH8l102RHc" />
+ <listitem open="0" type="815" id="NDGrlwJSDY8B" />
+ <listitem open="0" type="815" id="HwdXOmbaswch" />
+ <listitem open="0" type="815" id="5SqO4seTjRSa" />
+ <listitem open="0" type="815" id="7000" />
+ <listitem open="0" type="815" id="7802" />
+ <listitem open="0" type="815" id="34154" />
+ <listitem open="0" type="815" id="34599" />
+ <listitem open="0" type="815" id="34897" />
+ <listitem open="0" type="815" id="35047" />
+ <listitem open="0" type="815" id="35147" />
+ <listitem open="0" type="815" id="35298" />
+ <listitem open="0" type="815" id="35605" />
+ <listitem open="0" type="815" id="35866" />
+ </listitem>
+ <listitem open="0" type="813" id="dQQc692tOFUS" >
+ <listitem open="0" type="814" id="hcbUh4JlIu5E" />
+ <listitem open="0" type="814" id="MyhwT7zZG8oO" />
+ <listitem open="0" type="814" id="x5HJsnaGxZDg" />
+ <listitem open="0" type="814" id="RrbeL3wI6BZy" />
+ <listitem open="0" type="814" id="I16y7R8xSEes" />
+ <listitem open="0" type="814" id="VZjK8y2Pz9L4" />
+ <listitem open="0" type="814" id="20601" />
+ <listitem open="0" type="814" id="0grlCK0Zd2kv" />
+ <listitem open="0" type="814" id="roOeP5mqSzsY" />
+ <listitem open="0" type="814" id="20651" />
+ <listitem open="0" type="814" id="20701" />
+ <listitem open="0" type="814" id="20751" />
+ <listitem open="0" type="814" id="TO2c4YFuL4qQ" />
+ <listitem open="0" type="814" id="Rxzl1nBWMvpT" />
+ <listitem open="0" type="814" id="gBfRCRdglWVE" />
+ <listitem open="0" type="814" id="3951" />
+ <listitem open="0" type="814" id="xAmypZKxOlvo" />
+ <listitem open="0" type="814" id="919bTPKjqxKs" />
+ <listitem open="0" type="814" id="MW7N3XqbJLli" />
+ <listitem open="0" type="814" id="aTEnETRcBPSB" />
+ <listitem open="0" type="815" id="l9iApQ5k7p4V" />
+ <listitem open="0" type="815" id="20899" />
+ <listitem open="0" type="815" id="PNzGVGMN7IZO" />
+ <listitem open="0" type="815" id="oS3q3CNSaLg5" />
+ <listitem open="0" type="815" id="9tv3PTcwJuk2" />
+ <listitem open="0" type="815" id="DbAcS8Pc1KdP" />
+ <listitem open="0" type="815" id="lEJ2633MpMzJ" />
+ <listitem open="0" type="815" id="bLozAc1Tby5t" />
+ <listitem open="0" type="815" id="QacAXGqLr88z" />
+ <listitem open="0" type="815" id="XBpdlbprByih" />
+ <listitem open="0" type="815" id="x2pgMFGxFwzE" />
+ <listitem open="0" type="815" id="YWiBOMZqmmSC" />
+ <listitem open="0" type="815" id="gkXbpZt9r3e4" />
+ <listitem open="0" type="815" id="Cgo2iS6vpgKJ" />
+ <listitem open="0" type="815" id="4vv3FEH8vlii" />
+ <listitem open="0" type="815" id="h933zRw1Mr2a" />
+ <listitem open="0" type="815" id="Z2pjniRb4U5p" />
+ <listitem open="0" type="815" id="6Di8flw9tLlH" />
+ <listitem open="0" type="815" id="xXWGuINyU377" />
+ <listitem open="0" type="815" id="b2NRxvTAG4Im" />
+ <listitem open="0" type="815" id="wXFOX5u66GX3" />
+ <listitem open="0" type="815" id="4DPM1C2ZHS5c" />
+ <listitem open="0" type="815" id="tS98bISnuM92" />
+ <listitem open="0" type="815" id="21441" />
+ <listitem open="0" type="815" id="21541" />
+ <listitem open="0" type="815" id="4536" />
+ <listitem open="0" type="815" id="4636" />
+ <listitem open="0" type="815" id="21592" />
+ <listitem open="0" type="815" id="21694" />
+ <listitem open="0" type="815" id="21746" />
+ <listitem open="0" type="815" id="21851" />
+ </listitem>
+ <listitem open="0" type="813" id="tftTuiZXSv4R" >
+ <listitem open="0" type="814" id="w2lpqlcRNBky" />
+ <listitem open="0" type="814" id="KjxDjNipVmH6" />
+ <listitem open="0" type="814" id="nJw1e6ulB8mV" />
+ <listitem open="0" type="814" id="9SydFFh3ENAt" />
+ <listitem open="0" type="814" id="76E3M1i7iJGy" />
+ <listitem open="0" type="814" id="njbBHkqZRmmB" />
+ <listitem open="0" type="814" id="30115" />
+ <listitem open="0" type="814" id="15VSrGbyiZbv" />
+ <listitem open="0" type="814" id="7SdojrmkwHBl" />
+ <listitem open="0" type="814" id="61vH7gnD8O1s" />
+ <listitem open="0" type="814" id="O3jgPKW1znfn" />
+ <listitem open="0" type="814" id="uZ2PRCIQqOal" />
+ <listitem open="0" type="814" id="SKPVcXpzB5Y4" />
+ <listitem open="0" type="814" id="FcAqRxkJWmhw" />
+ <listitem open="0" type="814" id="R3na9McOwmEN" />
+ <listitem open="0" type="814" id="jwhEhOAeLWRh" />
+ <listitem open="0" type="814" id="27448" />
+ <listitem open="0" type="815" id="AaNPCwE5GYpL" />
+ <listitem open="0" type="815" id="1HLA3MQK09Yr" />
+ <listitem open="0" type="815" id="BxTRzdcxFOCK" />
+ <listitem open="0" type="815" id="feEeHoZUCjo5" />
+ <listitem open="0" type="815" id="MEr8fhvtbOQD" />
+ <listitem open="0" type="815" id="aCtLsOAUOvwU" />
+ <listitem open="0" type="815" id="28593" />
+ <listitem open="0" type="815" id="OSlCnQfCxj2t" />
+ <listitem open="0" type="815" id="H29zTi1CMn0S" />
+ <listitem open="0" type="815" id="xjmXt0pRpbh7" />
+ <listitem open="0" type="815" id="19160" />
+ <listitem open="0" type="815" id="28699" />
+ <listitem open="0" type="815" id="28805" />
+ </listitem>
+ <listitem open="1" type="813" id="23052" />
+ <listitem open="1" type="813" id="22946" />
+ <listitem open="1" type="813" id="23105" />
+ <listitem open="1" type="813" id="22789" />
+ <listitem open="1" type="813" id="22999" />
+ <listitem open="1" type="830" id="Datatypes" >
+ <listitem open="1" type="829" id="ZsN7qO5uod0W" />
+ <listitem open="1" type="829" id="sXqfrqwPid2x" />
+ <listitem open="1" type="829" id="BsXuVmQldfSS" />
+ <listitem open="1" type="829" id="1lLAIoXrLdtJ" />
+ <listitem open="1" type="829" id="NMq7yPI15TF8" />
+ <listitem open="1" type="829" id="8MlMJZOa2gQQ" />
+ <listitem open="0" type="829" id="21195" />
+ <listitem open="1" type="829" id="F0y42ZDGGZ49" />
+ <listitem open="1" type="829" id="bdvfq1CcRFQV" />
+ <listitem open="1" type="829" id="2TKfUnESr7J6" />
+ <listitem open="1" type="829" id="EhNquCdzHTzv" />
+ <listitem open="1" type="829" id="GXVTJzZt05VA" />
+ <listitem open="0" type="829" id="15653" />
+ <listitem open="0" type="829" id="cignRXiUIpXF" />
+ <listitem open="1" type="829" id="TRzc3eNXqLr1" />
+ <listitem open="1" type="829" id="f1lxWwdNwvpr" />
+ <listitem open="1" type="829" id="RTeIWtKTDaZV" />
+ <listitem open="0" type="829" id="vntVp1gw0ZB8" />
+ <listitem open="1" type="829" id="0mEev7QHu3Xw" />
+ <listitem open="1" type="829" id="6agIp7Rg7jXE" />
+ <listitem open="1" type="829" id="yVCl3jm3PB1C" />
+ <listitem open="1" type="829" id="DcaQZXHCYAUY" />
+ <listitem open="1" type="829" id="m7hYSy5qW7Uv" />
+ <listitem open="1" type="829" id="emAuInlIaxvV" />
+ <listitem open="1" type="829" id="Shk6a1xmtUeN" />
+ <listitem open="1" type="829" id="l2nnsImcbvsP" />
+ <listitem open="1" type="829" id="WHsGhr6cL3qV" />
+ <listitem open="0" type="829" id="12443" />
+ <listitem open="1" type="829" id="O01xtrLMY3S6" />
+ <listitem open="1" type="829" id="Q4TYO2bRfXJq" />
+ <listitem open="0" type="829" id="33858" />
+ <listitem open="1" type="829" id="OF2Sin3o242W" />
+ <listitem open="1" type="829" id="G46rjYKTY5EP" />
+ <listitem open="1" type="829" id="aHp7fmMY11yJ" />
+ <listitem open="1" type="829" id="J5WdE6USg2qD" />
+ <listitem open="1" type="829" id="X7Q5Iud3fXPb" />
+ <listitem open="1" type="829" id="QPMsbNxuTUYh" />
+ <listitem open="1" type="829" id="nnvOyvzkSE17" />
+ <listitem open="1" type="829" id="LyzcKuBtjfar" />
+ <listitem open="1" type="829" id="oZHHg64PKBaq" />
+ <listitem open="0" type="829" id="nyW3ZjsRDxWm" />
+ <listitem open="1" type="829" id="5NqwrUH5XNxE" />
+ <listitem open="1" type="829" id="hz7D2ZH5u80l" />
+ <listitem open="1" type="829" id="tFhSKvrguqen" />
+ </listitem>
+ <listitem open="0" type="831" id="cxkkcPlqeSGi" >
+ <listitem open="0" type="839" id="7AfLHTarQIb0" />
+ <listitem open="0" type="839" id="1IbnbOCiWr4l" />
+ <listitem open="0" type="839" id="UsJ25EL4Uwr6" />
+ <listitem open="0" type="839" id="MWptygBQWUQa" />
+ </listitem>
+ <listitem open="0" type="831" id="pBzpcllJMdsq" >
+ <listitem open="0" type="839" id="AYBjv2FiBCYl" />
+ <listitem open="0" type="839" id="TS9huSQ4zbmu" />
+ </listitem>
+ <listitem open="0" type="831" id="SsuRPlPUGZjG" >
+ <listitem open="0" type="839" id="YGOeDlDfb740" />
+ <listitem open="0" type="839" id="8rMiHZwnqIP3" />
+ </listitem>
+ <listitem open="0" type="831" id="7PSrs3lMwQVn" >
+ <listitem open="0" type="839" id="200XB2ebUTRX" />
+ <listitem open="0" type="839" id="v7wHq2ss2qNB" />
+ <listitem open="0" type="839" id="VkDZ8Ke4QYJG" />
+ </listitem>
+ <listitem open="1" type="831" id="27023" >
+ <listitem open="0" type="839" id="27076" />
+ <listitem open="0" type="839" id="27129" />
+ </listitem>
+ </listitem>
+ <listitem open="1" type="802" id="Use Case View" >
+ <listitem open="1" type="811" id="g2RmQlkG6CqM" />
+ </listitem>
+ <listitem open="1" type="821" id="Component View" />
+ <listitem open="1" type="827" id="Deployment View" />
+ <listitem open="1" type="836" id="Entity Relationship Model" />
+ </listitem>
+ </listview>
+ <codegeneration>
+ <codegenerator language="Java" />
+ </codegeneration>
+ </XMI.extensions>
+</XMI>
diff --git a/cesar/cp/eoc/sta/mgr/src/sta_mgr.c b/cesar/cp/eoc/sta/mgr/src/sta_mgr.c
new file mode 100644
index 0000000000..9dcdc73cb3
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/src/sta_mgr.c
@@ -0,0 +1,1184 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008-2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/mgr/src/sta_mgr.c
+ * \brief Station manager source.
+ * \ingroup cp_eoc_sta_mgr
+ *
+ */
+#include "common/std.h"
+#include "lib/rnd.h"
+
+#include "cp/defs.h"
+#include "cp/cp.h"
+#include "cp/fsm/fsm.h"
+#include "cp/eoc/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/sta_own_data.h"
+#include "cp/sta/core/core.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cl/cl_mactotei.h"
+#include "mac/sar/sar.h"
+
+#include "cp/inc/context.h"
+#include "cp/sta/mgr/inc/sta.h"
+#include "config/cp/sta/mgr/cco/eoc.h"
+
+#include "stdio.h"
+
+/**
+ * Elects a station in our AVLN to be the acknowledge station for all the
+ * station to which the packet is send.
+ * \param ctx the module context.
+ *
+ * This function choose the station using the data of the tone maps in the
+ * station contained in the mac store. It shall insert in the mac config the
+ * station's TEI which will acknowledge the packets.
+ * The station manager is responsible to elects another station if the current
+ * one is removed or if another one shall become the acknowledge station.
+ */
+
+void
+cp_sta_mgr_elects_sta_partial_ack (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_net_t *net = ctx->sta_mgr.our_avln;
+ cp_tei_t pack = MAC_TEI_BCAST;
+ if (net)
+ {
+ cp_sta_t *sta;
+ u8 *tei_table = blk_alloc ();
+ uint tei_nb = 0;
+ /* Get all the TEI of the network and store it into the tei table. */
+ /* Store the TEI of the station. */
+ for (sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_ASSOC);
+ sta;
+ sta = cp_net_sta_get_next (ctx, net, sta))
+ tei_table[tei_nb++] = cp_sta_get_tei (sta);
+ if (tei_nb)
+ {
+ /* Choose the TEI of the partial ACK station, */
+ uint pos = lib_rnd_uniform (&ctx->rnd, tei_nb);
+ pack = tei_table[pos];
+ }
+ /* Release the block used. */
+ blk_release (tei_table);
+ }
+ ctx->mac_config->partial_ack_tei_default = pack;
+}
+
+/**
+ * Compare two station with the mac address.
+ * \param left the left station.
+ * \param right the right station.
+ */
+static bool
+cp_sta_mgr_sta_mac_address_less (set_node_t *left, set_node_t *right)
+{
+ cp_sta_private_t *sta_left;
+ cp_sta_private_t *sta_right;
+
+ dbg_assert (left);
+ dbg_assert (right);
+
+ sta_left = (cp_sta_private_t *) PARENT_OF (cp_sta_t,
+ node_sta_mgr,
+ left);
+ sta_right = (cp_sta_private_t *) PARENT_OF (cp_sta_t,
+ node_sta_mgr,
+ right);
+
+ if (sta_left->mac_address < sta_right->mac_address)
+ return true;
+ else
+ return false;
+}
+
+/**
+ * Get the first station from the release station list.
+ * \param ctx the CP context.
+ * \return the first station of the list.
+ *
+ * \warn It does not add a reference on the list, so a slab_release on the
+ * station will free the station data, without removing it from the dataplane.
+ */
+static cp_sta_t *
+cp_sta_mgr_release_sta_get_first (cp_t *ctx)
+{
+ cp_sta_t *sta = NULL;
+
+ dbg_assert (ctx);
+
+ if (!list_empty (&ctx->sta_mgr.release_sta_list))
+ {
+ sta = PARENT_OF (cp_sta_t, release_node,
+ list_begin (&ctx->sta_mgr.release_sta_list));
+ dbg_check (sta);
+ }
+
+ return sta;
+}
+
+/**
+ * Add a station to the station manager.
+ * \param ctx the CP context.
+ * \param net the network within the station exists.
+ * \param tei the station's TEI.
+ * \param mac_address the station's mac address.
+ * \return the newly created station.
+ */
+static cp_sta_t*
+cp_sta_mgr_sta_add_realy (cp_t *ctx, cp_net_t *net, cp_tei_t tei,
+ mac_t mac_address)
+{
+ cp_sta_private_t *sta;
+ bool state;
+
+ sta = (cp_sta_private_t *) cp_sta_init (&ctx->sta_mgr.sta_slab_cache);
+
+ sta->tei = tei;
+ sta->mac_address = mac_address;
+ sta->net = net;
+
+ if (MAC_TEI_IS_STA (tei))
+ sta->net->num_associated_stas ++;
+
+ net->num_visible_stas ++;
+ net->num_stas ++;
+ sta->visible = true;
+ sta->association_confirmed = true;
+
+ /* Add the station to the station manager set only if the mac address is
+ * not a broadcast one. */
+ if (mac_address != MAC_BROADCAST)
+ {
+ state = set_insert (&ctx->sta_mgr.stas,
+ &sta->public_data.node_sta_mgr);
+ dbg_check (state);
+ }
+
+
+ // Add the station to the non unassociated list.
+ if (tei == MAC_TEI_UNASSOCIATED)
+ {
+ state = set_insert (&net->unassociated_stas,
+ &sta->public_data.node_net);
+ dbg_check (state);
+ }
+ // Add the station to the authenticated list.
+ else
+ {
+ state = set_insert (&net->associated_stas,
+ &sta->public_data.node_net);
+ dbg_check (state);
+
+ if (net == ctx->sta_mgr.our_avln)
+ {
+ dbg_assert (ctx->mac_store);
+ dbg_assert (ctx->cl);
+
+ mac_store_sta_add (ctx->mac_store, tei);
+ cp_sta_set_assoc_confirmed (ctx, (cp_sta_t *) sta, true);
+ cp_sta_mgr_commit_to_dataplane (ctx);
+ }
+ }
+
+ // Add a reference on the station.
+ slab_addref (sta);
+
+ return &sta->public_data;
+}
+
+
+/**
+ * Add a station to the associated or unassociated list.
+ * \param ctx the CP context.
+ * \param net the network within the station exists.
+ * \param tei the station's TEI.
+ * \param mac_address the station's mac address.
+ * \param sta the station.
+ */
+void
+cp_sta_mgr_sta_add_to_assoc_or_unassoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei,
+ mac_t mac_address, cp_sta_private_t *sta)
+{
+ bool state;
+
+ if (MAC_TEI_IS_STA (tei))
+ sta->net->num_associated_stas ++;
+
+ if(MAC_TEI_IS_STA (tei))
+ {
+ if(!((cp_sta_mgr_sta_is_assoc (ctx, net, tei)) || (cp_sta_mgr_sta_is_unassoc (ctx, net, mac_address))))
+ {
+ net->num_visible_stas ++;
+ net->num_stas ++;
+ sta->visible = true;
+ sta->association_confirmed = true;
+ }
+ }
+ else if(!(cp_sta_mgr_sta_is_unassoc (ctx, net, mac_address)))
+ {
+ net->num_visible_stas ++;
+ net->num_stas ++;
+ sta->visible = true;
+ sta->association_confirmed = true;
+ }
+
+
+ // Add the station to the non unassociated list.
+ if (tei == MAC_TEI_UNASSOCIATED)
+ {
+ if (! set_empty (&net->associated_stas))
+ {
+ if(cp_sta_mgr_sta_is_assoc (ctx, net, sta->tei))
+ {
+ set_remove(&net->associated_stas, &sta->public_data.node_net);
+ if (MAC_TEI_IS_STA (cp_sta_get_tei (&sta->public_data)))
+ sta->net->num_associated_stas--;
+ }
+ }
+ if(!(cp_sta_mgr_sta_is_unassoc (ctx, net, mac_address)))
+ {
+ state = set_insert (&net->unassociated_stas,
+ &sta->public_data.node_net);
+ dbg_check (state);
+ }
+ }
+ // Add the station to the associated list.
+ else
+ {
+ if (! set_empty (&net->unassociated_stas))
+ {
+ if(cp_sta_mgr_sta_is_unassoc (ctx, net, mac_address))
+ {
+ set_remove(&net->unassociated_stas, &sta->public_data.node_net);
+ }
+ }
+
+ dbg_assert (ctx->mac_store);
+ dbg_assert (ctx->cl);
+
+ mac_store_sta_add (ctx->mac_store, tei);
+ state = set_insert (&net->associated_stas,
+ &sta->public_data.node_net);
+ dbg_check (state);
+ cp_sta_set_assoc_confirmed (ctx, (cp_sta_t *) sta, true);
+ cp_sta_mgr_commit_to_dataplane (ctx);
+ }
+
+}
+
+/**
+ * Add a station to the stas list.
+ * \param ctx the CP context.
+ * \param station the station.
+ */
+
+void
+cp_eoc_sta_mgr_sta_insert_into_stas_list(cp_t *ctx, cp_sta_private_t *station)
+{
+ bool state;
+ state = set_insert (&ctx->sta_mgr.stas,
+ &station->public_data.node_sta_mgr);
+ dbg_check (state);
+ slab_addref(station);
+}
+
+
+void
+cp_sta_mgr_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ memset (&ctx->sta_mgr, 0, sizeof (cp_sta_mgr_t));
+
+ // Initialise the station own data.
+ cp_sta_own_data_init (ctx);
+
+ // Initialise the list of releasing stations.
+ list_init (&ctx->sta_mgr.release_sta_list);
+
+ // Initialise the slab cache.
+ slab_cache_init (&ctx->sta_mgr.sta_slab_cache,
+ "Station cache",
+ sizeof (cp_sta_private_t),
+ (slab_object_destructor_t) cp_sta_uninit);
+
+ // Initialise the set of station sorted by mac addresses.
+ set_init (&ctx->sta_mgr.stas, cp_sta_mgr_sta_mac_address_less);
+
+ lib_stats_set_stat_value_notype ("OUTPUT_LEVEL_ALL",
+ &ctx->sta_mgr.sta_own_data.output_level,
+ LIB_STATS_ACCESS_READ_WRITE,
+ LIB_STATS_DEBUG);
+}
+
+void
+cp_sta_mgr_uninit (cp_t *ctx)
+{
+ cp_net_t *net;
+ dbg_assert (ctx);
+
+ // Uninitialise the station contained in the release list.
+ if (ctx->sta_mgr.our_avln)
+ {
+ cp_sta_t *sta;
+ while ((sta = cp_sta_mgr_release_sta_get_first (ctx)))
+ {
+ sar_sta_remove (ctx->sar, cp_sta_get_tei (sta));
+ /* Remove the station from the list. */
+ list_remove (&ctx->sta_mgr.release_sta_list,
+ &sta->release_node);
+ slab_release (sta);
+ }
+
+ while ((sta = cp_net_sta_get_first (ctx, ctx->sta_mgr.our_avln,
+ CP_NET_STA_ASSOC)))
+ {
+ cp_sta_mgr_sta_remove (ctx, sta);
+ slab_release (sta);
+ }
+ }
+
+ /* Remove all the AVLN present in the station manager. */
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ cp_sta_mgr_remove_avln (
+ ctx, cp_net_get_snid (ctx, net), cp_net_get_nid (ctx, net));
+ // Uninitialise the station own data.
+ cp_sta_own_data_uninit (ctx);
+}
+
+cp_net_t *
+cp_sta_mgr_add_avln (cp_t *ctx, cp_snid_t snid, cp_nid_t nid)
+{
+ dbg_assert (ctx);
+ dbg_assert (HPAV_NID_IS_VALID (nid));
+ /* Search in the network list. */
+ cp_net_t *net = cp_sta_mgr_get_avln (ctx, snid, nid);
+ if (!net)
+ {
+ uint i;
+ for (i = 0; i < HPAV_AVLNS_NB_MAX && !net; i++)
+ {
+ if (ctx->sta_mgr.networks[i].present == false)
+ {
+ net = &ctx->sta_mgr.networks[i];
+ cp_net_init (ctx, net);
+ net->present = true;
+ net->snid = snid;
+ net->nid = nid;
+ }
+ }
+ }
+ return net;
+}
+
+void
+cp_sta_mgr_remove_avln (cp_t *ctx, cp_snid_t snid, cp_nid_t nid)
+{
+ dbg_assert (ctx);
+ dbg_assert (HPAV_NID_IS_VALID (nid));
+ cp_net_t *net = cp_sta_mgr_get_avln (ctx, snid, nid);
+ if (net)
+ {
+ /* Is it our net ? */
+ if (ctx->sta_mgr.our_avln == net)
+ cp_sta_mgr_set_our_avln (ctx, NULL);
+ /* Get the CCo to inform the BSU. */
+ mac_t cco_mac = MAC_ZERO;
+ cp_sta_t *cco = cp_net_get_cco (ctx, net);
+ if (cco)
+ {
+ cco_mac = cp_sta_get_mac_address (cco);
+ /* Mac address can be broadcast. */
+ if (cco_mac == MAC_BROADCAST)
+ cco_mac = MAC_ZERO;
+ slab_release (cco);
+ }
+ if (net == ctx->sta_mgr.our_avln)
+ cp_sta_mgr_set_our_avln (ctx, NULL);
+ /* Inform BSU. */
+ bsu_avln_remove (ctx->bsu, nid, snid, cco_mac);
+ cp_net_uninit (ctx, net);
+ }
+}
+
+cp_net_t *
+cp_sta_mgr_get_avln (cp_t *ctx, cp_snid_t snid, cp_nid_t nid)
+{
+ dbg_assert (ctx);
+ dbg_assert (HPAV_NID_IS_VALID (nid));
+ cp_net_t *net = NULL;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ {
+ if (net->nid == nid && net->snid == snid)
+ return net;
+ }
+ return NULL;
+}
+
+cp_net_t *
+cp_sta_mgr_get_first_avln (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ uint i;
+ cp_net_t *net = NULL;
+ for (i = 0; i < HPAV_AVLNS_NB_MAX && !net; i++)
+ {
+ if (ctx->sta_mgr.networks[i].present)
+ net = &ctx->sta_mgr.networks[i];
+ }
+ return net;
+}
+
+cp_net_t *
+cp_sta_mgr_get_next_avln (cp_t *ctx, cp_net_t *prev)
+{
+ dbg_assert (ctx);
+ dbg_assert (prev);
+ dbg_assert (prev <= &ctx->sta_mgr.networks[HPAV_AVLNS_NB_MAX-1]);
+ cp_net_t *net = NULL;
+ /* Two possibilities, prev is already the last AVLN. */
+ if (prev == &ctx->sta_mgr.networks[HPAV_AVLNS_NB_MAX-1])
+ return NULL;
+ else
+ for (net = prev + 1;
+ !net->present
+ && net != &ctx->sta_mgr.networks[HPAV_AVLNS_NB_MAX-1];
+ net++)
+ ;
+ /* If net is present return it. */
+ if (net->present)
+ return net;
+ else
+ return NULL;
+}
+
+u16
+cp_sta_mgr_get_present_snids (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ uint snidflags = 0;
+ cp_net_t *net;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ snidflags |= (u16) (1 << (net->snid));
+ return snidflags;
+}
+
+void
+cp_sta_mgr_garbage (cp_t *ctx)
+{
+ cp_sta_t *sta;
+ cp_net_t *net;
+ dbg_assert (ctx);
+ u32 now = cp_sta_core_get_date_ms (ctx);
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ if (net != ctx->sta_mgr.our_avln)
+ cp_net_garbage_stations (ctx, net, now);
+ /* Release the release stations if possible. */
+ while ((sta = cp_sta_mgr_release_sta_get_first (ctx))
+ && (less_mod2p32 (sta->tei_lease_date_ms, now)))
+ {
+ /* remove the station from the list. */
+ list_remove (&ctx->sta_mgr.release_sta_list,
+ &sta->release_node);
+
+ sar_sta_remove (ctx->sar, cp_sta_get_tei (sta));
+
+ if (cp_sta_own_data_get_cco_status (ctx))
+ {
+ /* Request the CCo to release the TEI. */
+ cp_cco_action_tei_release (ctx, cp_sta_get_tei (sta));
+ }
+ slab_release (sta);
+ }
+ cp_sta_mgr_elects_sta_partial_ack (ctx);
+}
+
+cp_sta_own_data_t *
+cp_sta_mgr_get_sta_own_data (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return (cp_sta_own_data_t *) &ctx->sta_mgr.sta_own_data;
+}
+
+u8
+cp_sta_mgr_get_slot_usage (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ uint slot_usage = 0;
+ cp_net_t *net;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ slot_usage |= 1 << (net->avln_slot_id);
+ return slot_usage;
+}
+
+u8
+cp_sta_mgr_get_num_discovered_stas (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ uint num = 0;
+ cp_net_t *net;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ num += cp_net_get_num_discovered_stas (ctx, net);
+ return num;
+}
+
+u8
+cp_sta_mgr_get_num_discovered_net (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ uint num = 0;
+ cp_net_t *net;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ {
+ if (ctx->sta_mgr.our_avln != net)
+ num ++;
+ }
+ return num;
+}
+
+bool
+cp_sta_mgr_net_list_is_empty (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ cp_net_t *net;
+ for (net = cp_sta_mgr_get_first_avln (ctx);
+ net;
+ net = cp_sta_mgr_get_next_avln (ctx, net))
+ {
+ if (net != ctx->sta_mgr.our_avln)
+ return false;
+ }
+ /* If we are here, all the AVLNs are empty, test our one. */
+ if (ctx->sta_mgr.our_avln)
+ return (set_empty (&ctx->sta_mgr.our_avln->associated_stas)
+ && set_empty (&ctx->sta_mgr.our_avln->unassociated_stas));
+ else
+ return true;
+}
+
+cp_net_t *
+cp_sta_mgr_get_our_avln (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->sta_mgr.our_avln);
+ dbg_assert (ctx->sta_mgr.our_avln->present);
+ return ctx->sta_mgr.our_avln;
+}
+
+void
+cp_sta_mgr_set_our_avln (cp_t *ctx, cp_net_t *net)
+{
+ cp_sta_t *sta;
+ dbg_assert (ctx);
+ dbg_assert (ctx->cl);
+ dbg_assert (ctx->sar);
+
+ /* If our AVLN was already setted, remove the station from the store. */
+ if (ctx->sta_mgr.our_avln)
+ {
+ cp_sta_t *sta;
+ /* Release the CL's mac to tei table. */
+ cl_mactotei_release_table (ctx->cl);
+
+ /* Release the station from the mac store. */
+ sta = cp_net_sta_get_first (ctx, ctx->sta_mgr.our_avln, CP_NET_STA_ASSOC);
+ while (sta)
+ {
+ sar_sta_remove (ctx->sar, cp_sta_get_tei (sta));
+ sta = cp_net_sta_get_next (ctx, net, sta);
+ }
+
+ /* Release the station in the release state. */
+ if (cp_sta_own_data_get_cco_status (ctx))
+ {
+ while ((sta = cp_sta_mgr_release_sta_get_first (ctx)))
+ {
+ sar_sta_remove (ctx->sar, cp_sta_get_tei (sta));
+ /* Remove the station from the list. */
+ list_remove (&ctx->sta_mgr.release_sta_list,
+ &sta->release_node);
+ slab_release (sta);
+ }
+ }
+
+ sar_cleanup (ctx->sar);
+ }
+
+ ctx->sta_mgr.our_avln = net;
+
+ if (net)
+ {
+ // Store the nid and the snid to the station own data.
+ cp_sta_own_data_set_nid (ctx, cp_net_get_nid (ctx, net));
+ cp_sta_own_data_set_snid (ctx, cp_net_get_snid (ctx, net));
+
+ /* Commit the new list. */
+ cp_sta_mgr_commit_to_dataplane (ctx);
+
+ /* Add the station to the store. */
+ for (sta = cp_net_sta_get_first (ctx, net, CP_NET_STA_ASSOC);
+ sta;
+ sta = cp_net_sta_get_next (ctx, net, sta))
+ {
+ mac_store_sta_add (ctx->mac_store, cp_sta_get_tei (sta));
+ }
+ }
+}
+
+void
+cp_sta_mgr_release_station (cp_t *ctx, cp_tei_t tei)
+{
+ cp_sta_t *sta;
+ cp_net_t *net;
+
+ dbg_assert (ctx);
+ dbg_assert (tei);
+ dbg_assert (cp_sta_own_data_get_cco_status (ctx));
+
+ net = cp_sta_mgr_get_our_avln (ctx);
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, tei);
+ dbg_assert (sta);
+
+ /* Remove the station from the set of the net. */
+ set_remove (&net->associated_stas, &sta->node_net);
+ set_insert (&net->unassociated_stas, &sta->node_net);
+ net->num_associated_stas--;
+ /* Remove the station from the sta mgr set. */
+ if(((cp_sta_private_t *)sta)->tei == MAC_TEI_UNASSOCIATED)
+ {
+ set_remove (&ctx->sta_mgr.stas, &sta->node_sta_mgr);
+ }
+
+ list_init_node (&sta->release_node);
+ list_push (&ctx->sta_mgr.release_sta_list, &sta->release_node);
+
+ /* Remove the reference provided. */
+ slab_release (sta);
+}
+
+cp_sta_t *
+cp_sta_mgr_sta_add (cp_t *ctx, cp_net_t *net, cp_tei_t tei, mac_t mac_address)
+{
+ cp_sta_private_t *sta = NULL;
+
+ dbg_assert (ctx);
+ dbg_assert (net);
+ dbg_assert ((tei && mac_address == MAC_BROADCAST)
+ || (mac_address & ~MAC_BROADCAST) == 0);
+
+ /* Try to get the station by the TEI. */
+ if (tei)
+ sta = (cp_sta_private_t *) cp_sta_mgr_sta_get_assoc (ctx, net, tei);
+
+ /* Try to get the station by the mac address. */
+ if (!sta && (mac_address != MAC_BROADCAST))
+ sta = (cp_sta_private_t *) cp_sta_mgr_sta_get_from_mac (ctx,
+ mac_address);
+
+ if (!sta)
+ {
+ sta = (cp_sta_private_t *) cp_sta_mgr_sta_add_realy (ctx, net,
+ tei, mac_address);
+ }
+ else
+ {
+ /* Last case. The network change. */
+ if (sta->net != net)
+ {
+ cp_sta_mgr_sta_remove (ctx, (cp_sta_t *) sta);
+ slab_release (sta);
+
+ sta = (cp_sta_private_t *) cp_sta_mgr_sta_add_realy (ctx, net,
+ tei,
+ mac_address);
+ }
+ /* First case only the TEI change from the previous state. */
+ else if ((sta->tei == MAC_TEI_UNASSOCIATED)
+ && (tei != MAC_TEI_UNASSOCIATED)
+ && (sta->mac_address == mac_address))
+ {
+ /* Remove the station. */
+ cp_sta_mgr_sta_remove (ctx, (cp_sta_t *) sta);
+ slab_release (sta);
+
+ /* Add the station with the new TEI. */
+ sta = (cp_sta_private_t *) cp_sta_mgr_sta_add_realy (ctx, net,
+ tei,
+ mac_address);
+ if (net == ctx->sta_mgr.our_avln)
+ mac_store_sta_add (ctx->mac_store, tei);
+ }
+ /* Second case,
+ * - station's TEI != TEI and != MAC_TEI_UNASSOCIATED.
+ * - station's Mac address was broadcast. */
+ else if ((sta->tei == tei)
+ && (tei != MAC_TEI_UNASSOCIATED)
+ && (sta->mac_address != mac_address)
+ && (sta->mac_address == MAC_BROADCAST))
+ {
+ /* Add the station mgr node to the set. */
+ sta->mac_address = mac_address;
+ set_insert (&ctx->sta_mgr.stas,
+ &sta->public_data.node_sta_mgr);
+ }
+ /* Third case, only the station's TEI change. */
+ else if ((sta->tei != tei)
+ && (tei != MAC_TEI_UNASSOCIATED)
+ && (sta->mac_address == mac_address)
+ && (mac_address != MAC_BROADCAST))
+ {
+ /* Only change the station's TEI. */
+ sta->tei = tei;
+ }
+ /* Fourth case, only the station's TEI change from a associated tei to
+ * the unassociated TEI.. */
+ else if ((sta->tei != tei)
+ && (tei == MAC_TEI_UNASSOCIATED)
+ && (sta->mac_address == mac_address)
+ && (mac_address != MAC_BROADCAST))
+ {
+ if(!(cp_sta_mgr_sta_is_unassoc (ctx, net, mac_address)))
+ cp_sta_mgr_sta_add_to_assoc_or_unassoc (ctx, net, tei, mac_address, sta);
+ }
+ /* Fifth case, Same TEI only the mac address change from A to B
+ * without being null or broadcast. */
+ else if ((sta->mac_address != mac_address)
+ && (mac_address != MAC_BROADCAST)
+ && (mac_address != 0))
+ {
+ cp_sta_mgr_sta_remove (ctx, (cp_sta_t *) sta);
+ slab_release (sta);
+
+ sta = (cp_sta_private_t *) cp_sta_mgr_sta_add_realy (ctx, net,
+ tei,
+ mac_address);
+ }
+ /* Sixth case, Same TEI, same mac address, but the sta is not in the associated list */
+ else if ((sta->mac_address == mac_address)
+ && (sta->tei == tei)
+ && (tei != MAC_TEI_UNASSOCIATED))
+ {
+ if(!(cp_sta_mgr_sta_is_assoc (ctx, net, tei)))
+ cp_sta_mgr_sta_add_to_assoc_or_unassoc (ctx, net, tei, mac_address, sta);
+ }
+ }
+
+ /* Update the last seen value. */
+ ((cp_sta_t *)sta)->expired_date_ms = cp_sta_core_get_date_ms (ctx);
+ return (cp_sta_t *) sta;
+}
+
+void
+cp_sta_mgr_sta_remove (cp_t *ctx, cp_sta_t * station)
+{
+ set_t *set;
+ cp_sta_private_t *sta = (cp_sta_private_t *) station;
+ cp_net_t *net;
+
+ dbg_assert (ctx);
+ dbg_assert (sta);
+ dbg_assert (sta->net);
+
+ net = sta->net;
+
+ // If the station is CCo, modify the net CCo pointer to NULL.
+ if (cp_sta_get_cco_status(station))
+ net->cco = NULL;
+
+ // If the station is PCo to communicate with the CCo, modify the
+ // pointer in the net.
+ if (net->pco == station)
+ net->pco = NULL;
+
+ if ((net == ctx->sta_mgr.our_avln)
+ && (MAC_TEI_IS_STA (sta->tei)))
+ sar_sta_remove (ctx->sar, sta->tei);
+
+ /* Remove the station from its net. */
+ if (cp_sta_get_tei (&sta->public_data))
+ {
+ if (cp_sta_mgr_sta_is_assoc (ctx, net, sta->tei))
+ {
+ set = &sta->net->associated_stas;
+ set_remove (set, &sta->public_data.node_net);
+ sta->net->num_associated_stas--;
+ sta->net->num_stas --;
+ }
+ else if (cp_sta_mgr_sta_is_unassoc(ctx, net, sta->mac_address))
+ {
+ set = &sta->net->unassociated_stas;
+ set_remove (set, &sta->public_data.node_net);
+ sta->net->num_stas --;
+ }
+ }
+ else
+ {
+ set = &sta->net->unassociated_stas;
+ if (cp_sta_mgr_sta_is_unassoc (ctx, net, sta->mac_address))
+ {
+ set_remove (set, &sta->public_data.node_net);
+ sta->net->num_stas --;
+ }
+ }
+
+ /* Remove the station from the station manager. If the mac address of the
+ * station is broadcast, the station is not in the set. */
+ if ((sta->mac_address != MAC_BROADCAST) && (!station->sta_in_wl))
+ set_remove (&ctx->sta_mgr.stas, &sta->public_data.node_sta_mgr);
+
+ /* decrease the visible counter. */
+ if (sta->visible)
+ sta->net->num_visible_stas --;
+
+ cp_sta_mgr_elects_sta_partial_ack (ctx);
+
+ /* Release the station. */
+ slab_release (sta);
+
+/* if (cp_sta_mgr_net_list_is_empty (ctx))
+ cp_fsm_trigger_new_event (ctx, bare, net_list_empty);*/
+}
+
+void
+cp_sta_mgr_sta_remove_from_mac (cp_t *ctx, mac_t mac_addr)
+{
+ cp_sta_t *sta;
+ dbg_assert (ctx);
+ dbg_assert (mac_addr && (mac_addr < MAC_BROADCAST));
+
+ sta = cp_sta_mgr_sta_get_from_mac (ctx, mac_addr);
+ /* Remove the reference provided by the station manager. */
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove (ctx, sta);
+}
+
+void
+cp_sta_mgr_sta_remove_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei)
+{
+ cp_sta_t *sta;
+
+ dbg_assert (ctx);
+ dbg_assert (net);
+ dbg_assert (MAC_TEI_IS_STA(tei));
+
+ sta = cp_sta_mgr_sta_get_assoc (ctx, net, tei);
+
+ if (sta)
+ {
+ // The get STA returns another reference on the station which we
+ // want to release this reference is not useful, this release
+ // allows to remove the reference just added by the get STA.
+ slab_release (sta);
+
+ /* Release the station. */
+ cp_sta_mgr_sta_remove (ctx, sta);
+ }
+}
+
+
+cp_sta_t *
+cp_sta_mgr_sta_get_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei)
+{
+ cp_sta_t *sta = NULL;
+ cp_sta_private_t sta_cmp;
+ set_node_t *node;
+
+ dbg_assert (ctx);
+ dbg_assert (net);
+ dbg_assert (tei);
+
+ if (! set_empty (&net->associated_stas))
+ {
+ memset (&sta_cmp, 0, sizeof (cp_sta_private_t));
+ sta_cmp.tei = tei;
+
+ node = set_find (&net->associated_stas,
+ &sta_cmp.public_data.node_net);
+
+ if (node)
+ {
+ sta = PARENT_OF (cp_sta_t, node_net, node);
+ slab_addref (sta);
+ }
+ }
+ return sta;
+}
+
+bool
+cp_sta_mgr_sta_is_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei)
+{
+ set_node_t *node = NULL;
+
+ dbg_assert (ctx);
+ dbg_assert (net);
+ dbg_assert (tei);
+
+ if (! set_empty (&net->associated_stas))
+ {
+ cp_sta_private_t sta_cmp;
+ memset (&sta_cmp, 0, sizeof (cp_sta_private_t));
+ sta_cmp.tei = tei;
+
+ node = set_find (&net->associated_stas,
+ &sta_cmp.public_data.node_net);
+ }
+
+ return (node);
+}
+
+cp_sta_t *
+cp_sta_mgr_sta_get_unassoc (cp_t *ctx, cp_net_t *net, mac_t mac)
+{
+ cp_sta_t *sta = NULL;
+ cp_sta_private_t sta_cmp;
+ set_node_t *node;
+
+ dbg_assert (ctx);
+ dbg_assert (net);
+ dbg_assert (mac);
+
+ if (! set_empty (&net->unassociated_stas))
+ {
+ memset (&sta_cmp, 0, sizeof (cp_sta_private_t));
+ sta_cmp.mac_address = mac;
+
+ node = set_find (&net->unassociated_stas,
+ &sta_cmp.public_data.node_net);
+
+ if (node)
+ {
+ sta = PARENT_OF (cp_sta_t, node_net, node);
+ slab_addref (sta);
+ }
+ }
+ return sta;
+}
+
+bool
+cp_sta_mgr_sta_is_unassoc (cp_t *ctx, cp_net_t *net, mac_t mac)
+{
+ set_node_t *node = NULL;
+
+ dbg_assert (ctx);
+ dbg_assert (net);
+ dbg_assert (mac);
+
+ if (! set_empty (&net->unassociated_stas))
+ {
+ cp_sta_private_t sta_cmp;
+ memset (&sta_cmp, 0, sizeof (cp_sta_private_t));
+ sta_cmp.mac_address = mac;
+
+ node = set_find (&net->unassociated_stas,
+ &sta_cmp.public_data.node_net);
+ }
+
+ return (node);
+}
+
+
+
+
+cp_sta_t *
+cp_sta_mgr_sta_get_from_mac (cp_t *ctx, mac_t mac_addr)
+{
+ cp_sta_private_t sta;
+ set_node_t *node;
+ cp_sta_t *sta_found = NULL;
+
+ dbg_assert (ctx);
+ dbg_assert (mac_addr);
+ dbg_assert (mac_addr < MAC_BROADCAST);
+
+
+ if (!set_empty (&ctx->sta_mgr.stas))
+ {
+ sta.mac_address = mac_addr;
+ set_node_init (&sta.public_data.node_sta_mgr);
+ node = set_find (&ctx->sta_mgr.stas, &sta.public_data.node_sta_mgr);
+
+ if (node)
+ {
+ sta_found = PARENT_OF (cp_sta_t, node_sta_mgr, node);
+ slab_addref (sta_found);
+ }
+ }
+
+ return sta_found;
+}
+
+void
+cp_sta_mgr_commit_to_dataplane (cp_t *ctx)
+{
+ cp_sta_t *sta;
+ cl_mactotei_blk_t *mactotei;
+
+ dbg_assert (ctx);
+ dbg_assert (ctx->cl);
+
+ // If the net does not correspond to the AVLN, do not commit.
+ if (!ctx->sta_mgr.our_avln)
+ return;
+
+ // Get the first station from the set.
+ if (set_empty (&ctx->sta_mgr.our_avln->associated_stas))
+ {
+ cl_mactotei_release_table (ctx->cl);
+ }
+ else
+ {
+ // There is at least a station in the network list.
+ mactotei = cl_mactotei_new ();
+
+ for (sta = cp_net_sta_get_first (ctx, ctx->sta_mgr.our_avln,
+ CP_NET_STA_ASSOC);
+ sta; sta = cp_net_sta_get_next (ctx, ctx->sta_mgr.our_avln, sta))
+ {
+ cp_sta_private_t *sta_private = (cp_sta_private_t *) sta;
+ // Copy all the bridge table from the previous list.
+ cl_mactotei_copy_tei_and_tag (ctx->cl, mactotei, sta_private->tei,
+ sta_private->tei);
+ // Add the current station.
+ cl_mactotei_addr_add (mactotei, sta_private->mac_address,
+ sta_private->tei, MAC_TEI_UNASSOCIATED);
+
+ }
+
+ // Request the CL to use the table.
+ cl_mactotei_use_table (ctx->cl, mactotei);
+ }
+}
+
+void
+cp_sta_mgr__assoc__timeout (cp_t *ctx, uint time_ms)
+{
+ cp_sta_t *sta;
+ cp_net_t *net;
+ dbg_assert (ctx);
+ dbg_assert (cp_sta_own_data_get_cco_status (ctx));
+
+ net = ctx->sta_mgr.our_avln;
+
+ if (net)
+ {
+ /* Parse only the 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))
+ {
+ if (!cp_sta_get_assoc_confirmed (ctx, sta)
+ && lesseq_mod2p32 (sta->assoc_req_last_ms + CP_ASSOC_FULL_TIMEOUT_MS, time_ms))
+ cp_sta_set_assoc_confirmed (ctx, sta, true);
+ }
+ }
+}
+
+
+#if CONFIG_CP_STA_MGR_CCO_EOC
+void
+cp_eoc_sta_mgr_get_wl (cp_t *ctx, 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, u8 *stas_actions)
+{
+ dbg_assert (ctx);
+ 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_actions);
+
+ set_node_t *node;
+ cp_sta_t *sta = NULL;
+ uint i = 0;
+ (*numStas) = 0;
+
+ if (!set_empty (&ctx->sta_mgr.stas))
+ {
+ node = set_begin(&ctx->sta_mgr.stas);
+ while (node)
+ {
+ sta = PARENT_OF (cp_sta_t, node_sta_mgr, node);
+ stas_authorizations[i] = sta->multi_sta.allowed;
+ stas_output_levels[i] = sta->multi_sta.output_level;
+ stas_start_times[i] = sta->multi_sta.start_time;
+ stas_end_times[i] = sta->multi_sta.end_time;
+ stas_daks[i] = sta->multi_sta.dak;
+ stas_actions[i] = sta->multi_sta.action;
+ stas_teis[i] = ((cp_sta_private_t *)sta)->tei;
+ stas_macs[i] = ((cp_sta_private_t *)sta)->mac_address;
+ node = set_next(&ctx->sta_mgr.stas, node);
+ i++;
+ }
+ (*numStas) = i;
+ }
+}
+
+
+void
+cp_eoc_sta_mgr_get_ports (cp_t *ctx, uint *numStas, mac_t *stas_macs, bool stas_port_ed[][PORT_NB],
+ u8 stas_port_service[][PORT_NB])
+{
+ dbg_assert (ctx);
+ dbg_assert (numStas);
+ dbg_assert (stas_macs);
+ dbg_assert (stas_port_ed);
+ dbg_assert (stas_port_service);
+
+ set_node_t *node;
+ cp_sta_t *sta = NULL;
+ uint i = 0;
+ uint j = 0;
+ (*numStas) = 0;
+
+ if (!set_empty (&ctx->sta_mgr.stas))
+ {
+ node = set_begin(&ctx->sta_mgr.stas);
+ while (node)
+ {
+ sta = PARENT_OF (cp_sta_t, node_sta_mgr, node);
+ if (((cp_sta_private_t *)sta)->tei != 0)
+ {
+ stas_macs[i] = ((cp_sta_private_t *)sta)->mac_address;
+ for(j = 0; j < PORT_NB; j++)
+ {
+ stas_port_ed[i][j] = sta->multi_sta.ports.port[j].enabled;
+ stas_port_service[i][j] = sta->multi_sta.ports.port[j].index_of_service;
+ }
+ i++;
+ }
+ node = set_next(&ctx->sta_mgr.stas, node);
+ }
+ (*numStas) = i;
+
+ }
+}
+
+#endif /* CONFIG_CP_STA_MGR_CCO_EOC */
+
diff --git a/cesar/cp/eoc/sta/mgr/src/sta_own_data.c b/cesar/cp/eoc/sta/mgr/src/sta_own_data.c
new file mode 100644
index 0000000000..b32aed886d
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/src/sta_own_data.c
@@ -0,0 +1,670 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008-2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/data/src/sta_own_data.c
+ * \brief Station data source.
+ * \ingroup cp_eoc_sta_data
+ *
+ */
+#include "common/std.h"
+#include "lib/rnd.h"
+#include "string.h"
+
+#include "lib/dbg.h"
+#include "lib/bitstream.h"
+#include "cp/fsm/fsm.h"
+
+#include "hal/gpio/gpio.h"
+
+/* Public interfaces. */
+#include "cp/sta/mgr/sta_own_data.h"
+#include "cp/msg/msg.h"
+
+/* Private interfaces. */
+#include "cp/inc/context.h"
+#include "cp/sta/mgr/inc/sta_own_data.h"
+
+#include "config/av/only/mode.h"
+
+/**
+ * Initialise the station own data to default values.
+ * \param ctx the module context.
+ */
+void
+cp_sta_own_data_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ memset ((u8*) &ctx->sta_mgr.sta_own_data,
+ 0, sizeof (cp_sta_own_data_private_t));
+
+ /* Store the hybrid mode. */
+ if (CONFIG_AV_ONLY_MODE)
+ {
+ ctx->sta_mgr.sta_own_data.public.hybrid_mode = MAC_COEXISTENCE_AV_ONLY_MODE;
+ }
+ else
+ {
+ ctx->sta_mgr.sta_own_data.public.hybrid_mode = MAC_COEXISTENCE_FULL_HYBRID_MODE;
+ }
+
+ /* Debug only. */
+ GPIO_SETUP (LED_IS_CCO_GPIO, GPIO_DIRECTION_OUT);
+ GPIO_SET (LED_IS_CCO_GPIO, 0);
+}
+
+/**
+ * Uninitialise the station own data to default values.
+ * \param ctx the module context.
+ */
+void
+cp_sta_own_data_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ memset ((u8*) &ctx->sta_mgr.sta_own_data,
+ 0, sizeof (cp_sta_own_data_private_t));
+}
+
+/**
+ * Set the TEI of the station.
+ * \param ctx the module context.
+ * \param tei The TEI station.
+ */
+void
+cp_sta_own_data_set_tei (cp_t * ctx, u8 tei)
+{
+ dbg_assert (ctx);
+// dbg_assert (ctx->mac_config);
+
+ if (tei != ctx->sta_mgr.sta_own_data.tei)
+ {
+ ctx->sta_mgr.sta_own_data.tei = tei;
+ ctx->mac_config->tei = tei;
+
+// cp_fsm_post_new_event (ctx, bare, sta_status_changed);
+ }
+}
+
+/**
+ * Get the value of the constant TEI.
+ * \param ctx the module context.
+ * \return Get the station TEI.
+ */
+cp_tei_t
+cp_sta_own_data_get_tei (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.tei;
+}
+
+/**
+ * Set the station Mac address.
+ * \param ctx the module context.
+ * \param mac_addr The Mac address of the station.
+ */
+void
+cp_sta_own_data_set_mac_address (cp_t *ctx, mac_t mac_addr)
+{
+ dbg_assert (ctx);
+ dbg_assert (mac_addr);
+ dbg_assert (ctx->mac_config);
+
+ // Add the mac address to the sta own data.
+ ctx->sta_mgr.sta_own_data.mac_addr = mac_addr;
+
+ // Add the mac address to the mac config referred in the CP.
+ ctx->mac_config->sta_mac_address = mac_addr;
+}
+
+/**
+ * Get the station mac address.
+ * \param ctx the module context.
+ * \return Get the station Mac address.
+ *
+ */
+mac_t
+cp_sta_own_data_get_mac_address (cp_t *ctx)
+{
+ return ctx->sta_mgr.sta_own_data.mac_addr;
+}
+
+/**
+ * Set the Station NPW.
+ * \param ctx the module context.
+ * \param npw The new NPW.
+ *
+ * TODO : inform the driver ?
+ */
+void
+cp_sta_own_data_set_npw (cp_t *ctx, const char * npw)
+{
+ dbg_assert (ctx);
+ dbg_assert (npw);
+
+ // Store the NPW.
+ strcpy(ctx->sta_mgr.sta_own_data.npw, npw);
+
+ // TODO : inform the driver ?
+}
+
+/**
+ * Return the pointer to the NPW as a constant data.
+ * \param ctx the module context.
+ * \return Get the station NPW.
+ *
+ * The user shall call the set_npw function to modify the NPW
+ */
+const char *
+cp_sta_own_data_get_npw (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->sta_mgr.sta_own_data.npw;
+}
+
+/**
+ * Set the station NMK.
+ * \param ctx the module context.
+ * \param nmk The NMK to set.
+ * \param length The NMK length.
+ *
+ * \todo Call the MSG to send a MME to the linux Driver.
+ */
+bool
+cp_sta_own_data_set_nmk (cp_t *ctx, const cp_key_t nmk,
+ cp_msg_drv_sta_set_key_type_t type)
+{
+ dbg_assert (ctx);
+ dbg_assert (type < CP_MSG_DRV_STA_SET_KEY_TYPE_NB);
+
+ uint i;
+ cp_key_t current_key = cp_sta_own_data_get_nmk (ctx);
+
+ for (i = 0; i < COUNT(nmk.key) ;i++)
+ if (nmk.key[i] != current_key.key[i])
+ break;
+
+ if (i < COUNT(nmk.key))
+ {
+ ctx->sta_mgr.sta_own_data.nmk = nmk;
+ /* Not implemented for now */
+#if 0
+ /* Report new computed values to HLE. */
+ cp_mme_peer_t peer = CP_MME_PEER (cp_sta_own_data_get_mac_address (ctx),
+ MAC_TEI_FOREIGN);
+ cp_nid_t nid = 0;
+ cp_security_level_t sl = 0;
+
+ if (type == CP_MSG_DRV_STA_SET_KEY_TYPE_CHANGE_NID)
+ nid = cp_sta_own_data_get_nid (ctx);
+ else
+ sl = cp_sta_own_data_get_security_level (ctx);
+
+ cp_msg_drv_sta_set_key_ind_send (ctx, &peer,
+ nmk,
+ type,
+ nid,
+ sl);
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Get the NMK of the AVLN.
+ * \param ctx the module context.
+ * \return Get the station NMK
+ */
+cp_key_t
+cp_sta_own_data_get_nmk (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->sta_mgr.sta_own_data.nmk;
+}
+
+/**
+ * Set the device password.
+ * \param ctx the module context.
+ * \param dpw The new device password.
+ * \param length The length in bytes of the DPW provided.
+ *
+ * // TODO : inform the driver ?
+ */
+void
+cp_sta_own_data_set_dpw (cp_t *ctx, const char *dpw)
+{
+ dbg_assert (ctx);
+ dbg_assert (dpw);
+
+ strcpy (ctx->sta_mgr.sta_own_data.dpw, dpw);
+
+ // TODO : inform the driver ?
+}
+
+/**
+ * Return the Device password.
+ * \param ctx the module context.
+ * \return Get the station DPW.
+ */
+const char*
+cp_sta_own_data_get_dpw (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.dpw;
+}
+
+/**
+ * Set the security level.
+ * \param ctx the module context.
+ * \param sl The security level.
+ *
+ * // TODO : inform the driver ?
+ */
+void
+cp_sta_own_data_set_security_level (cp_t *ctx,
+ cp_security_level_t sl)
+{
+ dbg_assert (ctx);
+
+ ctx->sta_mgr.sta_own_data.security_level = sl;
+
+ // TODO : inform the driver ?
+}
+
+/**
+ * Return the security level.
+ * \param ctx the module context.
+ * \return Get the security level.
+ *
+ */
+cp_security_level_t
+cp_sta_own_data_get_security_level (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->sta_mgr.sta_own_data.security_level;
+}
+
+/**
+ * Set the CCo status of the station.
+ * \param ctx the module context.
+ * \param status The current CCo status of the station.
+ *
+ * It shall send a message to the Linux Driver
+ */
+void
+cp_sta_own_data_set_was_cco (cp_t *ctx, bool status)
+{
+ dbg_assert (ctx);
+ ctx->sta_mgr.sta_own_data.was_cco = status;
+
+ // inform the driver
+ // TODO.
+}
+
+/**
+ * Get the CCo status of the station after a reboot.
+ * \param ctx the module context.
+ * \return \todo fill this
+ *
+ */
+bool
+cp_sta_own_data_get_was_cco (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->sta_mgr.sta_own_data.was_cco;
+}
+
+/**
+ * Set the HFID.
+ *
+ * \param hfid the HFID to set.
+ * \param data the human identifier.
+ */
+static void
+cp_sta_own_data_set_hfid (const char *hfid, const char *data)
+{
+ dbg_assert (data);
+ dbg_assert (hfid);
+
+ strcpy ((char *) hfid, (char *) data);
+}
+
+/**
+ * Set the AVLN HFID.
+ *
+ * \param ctx the module context.
+ * \param data the human identifier.
+ */
+void
+cp_sta_own_data_set_hfid_avln (cp_t *ctx, const char* data)
+{
+ cp_sta_own_data_t *sta;
+
+ dbg_assert (ctx);
+ sta = cp_sta_mgr_get_sta_own_data (ctx);
+ cp_sta_own_data_set_hfid (sta->hfid_avln, data);
+}
+
+/**
+ * Set the User HFID.
+ *
+ * \param ctx the module context.
+ * \param data the human identifier.
+ */
+void
+cp_sta_own_data_set_hfid_user (cp_t *ctx, const char* data)
+{
+ cp_sta_own_data_t *sta;
+
+ dbg_assert (ctx);
+ sta = cp_sta_mgr_get_sta_own_data (ctx);
+ cp_sta_own_data_set_hfid (sta->hfid_user, data);
+}
+
+/**
+ * Set the Manufacturer HFID.
+ *
+ * \param ctx the module context.
+ * \param data the human identifier.
+ */
+void
+cp_sta_own_data_set_hfid_manufacturer (cp_t *ctx, const char* data)
+{
+ cp_sta_own_data_t *sta;
+
+ dbg_assert (ctx);
+ sta = cp_sta_mgr_get_sta_own_data (ctx);
+ cp_sta_own_data_set_hfid (sta->hfid_manufacturer, data);
+}
+
+/**
+ * Set the GLID to send proxy data.
+ * \param ctx the module context.
+ * \param glid The GLID to use when a proxy beacon shall be sent.
+ */
+void
+cp_sta_own_data_set_pco_glid (cp_t *ctx, u8 glid)
+{
+ dbg_assert (ctx);
+ dbg_assert ((glid >= MAC_GLID_MIN) || (glid == 0));
+
+ ctx->sta_mgr.sta_own_data.pco_glid = glid;
+}
+
+/**
+ * Get the PCO GLID.
+ * \param ctx the module context.
+ * \return The GLID to send proxy data.
+ */
+u8
+cp_sta_own_data_get_pco_glid (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return (ctx->sta_mgr.sta_own_data.pco_glid);
+}
+
+/**
+ * Get the PCO status.
+ * \param ctx the module context.
+ * \return The PCO status.
+ *
+ */
+bool
+cp_sta_own_data_get_pco_status (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return (ctx->sta_mgr.sta_own_data.pco_glid);
+}
+
+/**
+ * Set the PCO status.
+ * \param ctx the module context.
+ * \param pco The PCO status.
+ *
+ */
+void
+cp_sta_own_data_set_pco_status (cp_t *ctx, bool pco)
+{
+ dbg_assert (ctx);
+
+ if (cp_sta_own_data_get_pco_status (ctx) != pco)
+ {
+ if (pco == false)
+ ctx->sta_mgr.sta_own_data.pco_glid = 0;
+ else
+ ctx->sta_mgr.sta_own_data.pco_glid |= (pco << 7);
+// cp_fsm_post_new_event (ctx, bare, sta_status_changed);
+ }
+}
+
+/**
+ * Set the CCo status of the station.
+ * \param ctx the CP context.
+ */
+void
+cp_sta_own_data_set_cco_status (cp_t *ctx, bool cco)
+{
+ cp_sta_t *sta;
+ cp_net_t *net;
+ dbg_assert (ctx);
+
+ if (ctx->sta_mgr.sta_own_data.is_cco != cco)
+ {
+ dbg_assert (ctx->sta_mgr.sta_own_data.tei != MAC_TEI_UNASSOCIATED);
+ ctx->sta_mgr.sta_own_data.is_cco = cco;
+
+ // If the net has already a CCo.
+ if (cco)
+ {
+ net = cp_sta_mgr_get_our_avln (ctx);
+ sta = cp_net_get_cco (ctx, net);
+ if (sta)
+ {
+ cp_net_set_cco (ctx, net, MAC_TEI_UNASSOCIATED);
+ slab_release (sta);
+ }
+ }
+
+// cp_fsm_post_new_event (ctx, bare, sta_status_changed);
+ }
+
+}
+
+
+/**
+ * Get the CCo status of the station.
+ * \param ctx the CP context.
+ * \return the boolean indicating the state.
+ */
+bool
+cp_sta_own_data_get_cco_status (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.is_cco;
+
+}
+
+/**
+ * Set the authentication status.
+ * \param ctx the CP context.
+ * \param authenticated the station status.
+ */
+void
+cp_sta_own_data_set_authenticated_status (cp_t *ctx, bool authenticated)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_config);
+
+ if (ctx->sta_mgr.sta_own_data.authenticated != authenticated)
+ {
+ ctx->sta_mgr.sta_own_data.authenticated = authenticated;
+ ctx->mac_config->authenticated = authenticated;
+// cp_fsm_post_new_event (ctx, bare, sta_status_changed);
+ }
+}
+
+/**
+ * Get the authentication status.
+ * \param ctx the CP context.
+ * \return the station authentication status.
+ */
+bool
+cp_sta_own_data_get_authenticated_status (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.authenticated;
+}
+
+/**
+ * Set the Station NID.
+ * \param ctx the Control plane context.
+ * \param nid the station NID.
+ */
+void
+cp_sta_own_data_set_nid (cp_t *ctx, cp_nid_t nid)
+{
+ dbg_assert (ctx);
+ dbg_assert (HPAV_NID_IS_VALID (nid));
+
+ ctx->sta_mgr.sta_own_data.nid = nid;
+
+ /* If the station AVLN is setted, modified the network. */
+ if (ctx->sta_mgr.our_avln)
+ ctx->sta_mgr.our_avln->nid = nid;
+
+ bsu_update_nid (ctx->bsu, nid);
+}
+
+/**
+ * Get the Station NID.
+ * \param ctx the Control plane context.
+ * \param nid the station NID.
+ */
+cp_nid_t
+cp_sta_own_data_get_nid (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.nid;
+}
+
+/**
+ * Set the Station SNID.
+ * \param ctx the Control plane context.
+ * \param snid the station SNID.
+ */
+void
+cp_sta_own_data_set_snid (cp_t *ctx, cp_snid_t snid)
+{
+ dbg_assert (ctx);
+
+ ctx->sta_mgr.sta_own_data.snid = snid;
+
+ if (ctx->sta_mgr.our_avln)
+ ctx->sta_mgr.our_avln->snid = snid;
+}
+
+/**
+ * Get the Station SNID.
+ * \param ctx the Control plane context.
+ * \return the station SNID.
+ */
+cp_snid_t
+cp_sta_own_data_get_snid (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.snid;
+}
+
+void
+cp_sta_own_data_set_tek (cp_t *ctx, const cp_key_t key)
+{
+ dbg_assert (ctx);
+
+ memcpy (&ctx->sta_mgr.sta_own_data.tek, &key, sizeof (cp_key_t));
+}
+
+cp_key_t
+cp_sta_own_data_get_tek (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.tek;
+}
+
+bool
+cp_sta_own_data_get_backup_cco_status (cp_t *ctx)
+{
+ /* FIXME: this is a temporary fix. As soon we have implement CCo backup
+ * functionality, we should return it. */
+ return CP_BACKUP_CCO_CAP;
+}
+
+void
+cp_sta_own_data_set_dak (cp_t *ctx, cp_key_t dak)
+{
+ uint i;
+ dbg_assert (ctx);
+
+ for (i = 0; i < COUNT (dak.key); i++)
+ ctx->sta_mgr.sta_own_data.dak.key[i] = dak.key[i];
+}
+
+cp_key_t
+cp_sta_own_data_get_dak (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.dak;
+}
+
+void
+cp_sta_own_data_set_original_dak (cp_t *ctx, cp_key_t dak)
+{
+ uint i;
+ dbg_assert (ctx);
+
+ for (i = 0; i < COUNT (dak.key); i++)
+ ctx->sta_mgr.sta_own_data.original_dak.key[i] = dak.key[i];
+}
+
+cp_key_t
+cp_sta_own_data_get_original_dak (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.original_dak;
+}
+
+void
+cp_sta_own_data_set_sc (cp_t *ctx, bool status)
+{
+ dbg_assert (ctx);
+
+ if (ctx->sta_mgr.sta_own_data.sc != status)
+ {
+ ctx->sta_mgr.sta_own_data.sc = status;
+// cp_fsm_post_new_event (ctx, bare, sta_status_changed);
+ }
+}
+
+bool
+cp_sta_own_data_get_sc (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->sta_mgr.sta_own_data.sc;
+}
diff --git a/cesar/cp/eoc/sta/mgr/sta_mgr.h b/cesar/cp/eoc/sta/mgr/sta_mgr.h
new file mode 100644
index 0000000000..b28511dffe
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/sta_mgr.h
@@ -0,0 +1,66 @@
+#ifndef cp_eoc_sta_mgr_h
+#define cp_eoc_sta_mgr_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/eoc/sta/mgr/sta_mgr.h
+ * \brief Station Manager.
+ * \ingroup cp_sta_mgr
+ *
+ * Station and AVLN manager.
+ */
+#include "cp/sta/mgr/net.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta.h"
+
+
+BEGIN_DECLS
+
+
+void
+cp_sta_mgr_sta_add_to_assoc_or_unassoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei,
+ mac_t mac_address, cp_sta_private_t *sta);
+
+void
+cp_eoc_sta_mgr_sta_insert_into_stas_list(cp_t *ctx, cp_sta_private_t *station);
+
+bool
+cp_sta_mgr_sta_is_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei);
+
+bool
+cp_sta_mgr_sta_is_unassoc (cp_t *ctx, cp_net_t *net, mac_t mac);
+
+void
+cp_sta_mgr_elects_sta_partial_ack (cp_t *ctx);
+
+/**
+ * Verify the net list status.
+ * \param ctx the module context.
+ * \return true if empty, false otherwise.
+ */
+bool
+cp_sta_mgr_net_list_is_empty (cp_t *ctx);
+
+/**
+ * Get first AVLN from the net_list.
+ * \param ctx the module context.
+ * \return Get a reference on the AVLN.
+ */
+cp_net_t *
+cp_sta_mgr_get_first_avln (cp_t *ctx);
+
+/**
+ * Get next AVLN from the net_list.
+ * \param ctx the module context.
+ * \param prev previous one.
+ * \return Get a reference on the AVLN.
+ */
+cp_net_t *
+cp_sta_mgr_get_next_avln (cp_t *ctx, cp_net_t *prev);
+
+#endif /* cp_sta_eoc_mgr_h */
diff --git a/cesar/cp/eoc/sta/mgr/test/Config b/cesar/cp/eoc/sta/mgr/test/Config
new file mode 100644
index 0000000000..6bbff0b2f2
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/Config
@@ -0,0 +1,3 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_RESTRACK = y
+CONFIG_AV_ONLY_MODE = y \ No newline at end of file
diff --git a/cesar/cp/eoc/sta/mgr/test/Makefile b/cesar/cp/eoc/sta/mgr/test/Makefile
new file mode 100644
index 0000000000..0aa8295cd2
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/Makefile
@@ -0,0 +1,13 @@
+BASE = ../../../../..
+
+INCLUDES = cp/sta/mgr/test/overide
+
+HOST_PROGRAMS = test_sta_mgr
+test_sta_mgr_SOURCES = core_stub.c net_test.c sar_stub.c sta_mgr.c \
+ sta-test.c station_test.c test_sta_mgr.c
+test_sta_mgr_MODULES = lib cp/sta/mgr mac/common cp/fsm/stub \
+ cp/cco/action/stub cl/stub bsu/stub cp/msg/stub
+
+test_sta_mgr_CONFIG_MODULES = cp cl mac/sar
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/sta/mgr/test/doc/Makefile b/cesar/cp/eoc/sta/mgr/test/doc/Makefile
new file mode 100644
index 0000000000..25c6b6b03d
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/doc/Makefile
@@ -0,0 +1,20 @@
+PAGES= sta_mgr.txt sta.txt net.txt net_list.txt
+
+ODT=$(PAGES:%.txt=%.odt)
+HTML=$(PAGES:%.txt=%.html)
+
+all: $(ODT) $(HTML)
+
+odt: $(ODT)
+
+html: $(HTML)
+
+%.odt: %.txt
+ rst2odt.py $< $@
+
+%.html: %.txt
+ rst2html $< $@
+
+clean:
+ rm -f $(ODT)
+ rm -f $(HTML)
diff --git a/cesar/cp/eoc/sta/mgr/test/doc/net.txt b/cesar/cp/eoc/sta/mgr/test/doc/net.txt
new file mode 100644
index 0000000000..3424c2ba52
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/doc/net.txt
@@ -0,0 +1,190 @@
+Network test
+============
+
+Test the APIs available in the cp_net.
+
+sta_add
+-------
+
+Test 1 : Unassociated STAs
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add some station to the net list and verify the data. The STA are added with a
+TEI null and a known mac address.
+
+The Station shall be added as unassociated stations and be added in the set of
+unassociated stations.
+
+Their status shall be equal to CP_STA_STATE_EXISTS.
+The Mac address shall be set.
+
+Test 2 : Associated STAs
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add some stations to the net list and verify the data. The STA are added with
+a TEI different of any one already present in the Net list.
+
+The mac address is not necessary if the TEI is set, the station status shall
+be equal to CP_STA_STATE_ASSOCIATED.
+
+Test 3 : Authenticated STAs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add some authenticated stations to the net list. The STAs are added with a TEI
+different of any one already present in the Net list.
+
+The stations status shall be equal to CP_STA_STATE_AUTHENTICATED.
+
+Test 4 : Modifying the CCo in the NET
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add a station authenticated and set it as a CCo in the AVLN.
+
+The station shall be in the CP_STA_STATE_AUTHENTICATED, and the AVLN shall
+have a pointer to this station in the cco variable.
+
+Test 5 : Modifying the PCo in the NET
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add a station authenticated and set it as a PCo in the AVLN.
+
+The station shall be in the CP_STA_STATE_AUTHENTICATED, and the AVLN shall
+have a pointer to this station in the pco variable.
+
+Remove Sta
+----------
+
+Test 1 : Removing a Associated station (not CCo, not PCo)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add some station and remove it.
+At the end the list must be empty.
+
+Test 2 : Removing the CCo station of the net.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add some station in the net list as associated, one of those stations is the
+CCo (TEI = 3 for examples).
+
+At the beginning of the test, the station with the TEI = 3, shall have its
+status cco flag setted and the network has its cco pointer corresponding to
+this station.
+
+At the end, the station shall not exist in the network and the pointer to the
+CCo in the network shall be null.
+The other stations of the AVLN shall remain present.
+
+Test 3 : Removing the PCo Station of the net.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add some station in the net list as associated, one of those stations is the
+PCo (TEI = 3 for examples).
+
+At the beginning of the test, the station with the TEI = 3, shall have its
+status pco flag setted and the network has its pco pointer corresponding to
+this station.
+
+At the end, the station shall not exist in the network and the pointer to the
+PCo in the network shall be null.
+The other stations of the AVLN shall remain present.
+
+Commit to data plane
+--------------------
+
+Add some station to the list and call the commit to data plane function.
+
+The function of the CL have been overwritten in the cl_stub.c file (see in the
+src directory).
+
+It will normally allocate a block and all the station present in the network
+list will be present in it.
+
++-----+-----+-------+
+| Tag | TEI | MAC @ |
++-----+-----+-------+
+
+Garbage
+-------
+
+Verify the expiration date of all the station in the network. It the network
+is empty it shall post an event in the FSM.
+
+Environment
+~~~~~~~~~~~
+
+Add an AVLN and some station with different status.
+
+Three associated and three not associated stations.
+
++-----+-------+-----+-------+-----------+
+| sta | assoc | tei | mac @ | last seen |
++-----+-------+-----+-------+-----------+
+| 1 | false | 0 | 1 | 5 |
++-----+-------+-----+-------+-----------+
+| 2 | false | 0 | 2 | 7 |
++-----+-------+-----+-------+-----------+
+| 3 | false | 0 | 3 | 9 |
++-----+-------+-----+-------+-----------+
+| 4 | true | 1 | 1 | 6 |
++-----+-------+-----+-------+-----------+
+| 5 | true | 2 | 5 | 8 |
++-----+-------+-----+-------+-----------+
+| 6 | true | 3 | 9 | 10 |
++-----+-------+-----+-------+-----------+
+
+Result
+~~~~~~
+
+The station 1 and the station 4 shall be expired and shall not appear in the
+list after the garbage.
+
+The others shall be still present.
+
+Set slot id
+-----------
+
+Add an AVLN and set the slot id to 5.
+
+Result
+ The slot id shall be equal to 5.
+
+Network mode
+------------
+
+This test case shall test the function to set and get the network mode of an
+AVLN.
+
+Net configuration
+ After the initialization of the network the network mode is CSMA-Only.
+ At the second modification the network mode shall be setted to coordinated mode.
+
+Result
+ The network shall be in CSMA only mode at the first read of the network mode.
+ The network shall be in Coordinated mode at the second read.
+
+Set sta visible
+---------------
+
+This function has for job to set the neighbour station as visible allowing to
+increase or decrease the counter of visible stations in the network.
+
+Test 1 : Adding a STA
+~~~~~~~~~~~~~~~~~~~~~
+
+Environment
+ Add a station to the network and set it as visible.
+
+Result
+ The network shall have one station as visible.
+
+Test 2 : Adding two STAs
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Environment
+ Add two station to the AVLN configured as followed :
+
+ * STA 1 : visible
+ * STA 2 : hidden
+
+Result
+ The network shall have two station and only one visible.
diff --git a/cesar/cp/eoc/sta/mgr/test/doc/net_list.txt b/cesar/cp/eoc/sta/mgr/test/doc/net_list.txt
new file mode 100644
index 0000000000..758b4754b5
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/doc/net_list.txt
@@ -0,0 +1,114 @@
+Network list
+============
+
+Initialise
+-----------
+
+Shall initialise all the networks list (index greater than 1, the index 0 corresponds to the station AVLN):
+ - present flag shall be false.
+ - snid = 0
+ - nid = 0
+ - cco = null
+ - pco = null
+ - expiration_ntb = CP_NET_EXPIRATION_DELAY (see defs file in cp)
+ - associated_stas shall be empty.
+ - unssociated_stas shall be empty.
+
+The AVLN with the index 0 (the Stations AVLN) shall be present, i.e. the present flag shall be setted.
+
+Uninitialise
+------------
+
+Shall reset all the networks and call on each one the uninit function.
+
+For that some station will be create in each AVLN.
+
+AVLN 0:
+ - Station 1, TEI = 1, Mac @ = 11, is_cco = true.
+ - Station 2, TEI = 2, Mac @ = 12, is_cco = false, is_pco = true.
+
+AVLN 1:
+ - Station 1, TEI = 1, Mac @ = 21, is_cco = true.
+ - Station 2, TEI = 2, Mac @ = 22, is_cco = false, is_pco = true.
+ - Station 3, TEI = 3, Mac @ = 23.
+ - Station 4, TEI = 4, Mac @ = 24.
+
+AVLN 2:
+ - Station 1, TEI = 1, Mac @ = 31, is_cco = true.
+ - Station 2, TEI = 2, Mac @ = 32.
+ - Station 3, TEI = 3, Mac @ = 33.
+ - Station 4, TEI = 4, Mac @ = 34.
+
+At the end of this test case, all the station list shall be empty and the CCo, PCo pointer reseted.
+
+
+Add an AVLN
+-----------
+
+Create the AVLN and verify that it is possible to get it back using the get
+AVLN function.
+
+AVLN data:
+ - SNID = 1
+ - NID = 1
+
+The AVLN returned by the add function shall be in the following state:
+ - SNID = 1
+ - NID = 1
+ - present = true
+ - station_avln = false
+ - cco = null
+ - pco = null
+ - expiration_ntb = CP_NET_EXPIRATION_DELAY (see cp/defs.h)
+ - associated_stas = empty (use set_empty function).
+ - unassociated_stas = empty (use set_empty function).
+
+Remove an AVLN
+--------------
+
+Same thing as uninitializing an AVLN.
+
+Add an AVLN and remove it only using the SNID and NID.
+
+AVLN Data:
+ - SNID = 1
+ - NID = 1.
+
+At the end of the test this AVLN shall not exists.
+
+Update Station's SNID
+---------------------
+
+Modify the AVLN's SNID.
+
+Is empty
+--------
+
+Verify the presence of others AVLN on the medium.
+
+SNID present
+------------
+
+Return a flag indicating which SNID is currently in use.
+
+Environment 3 AVLNs with SNID 1, 5, 10.
+
+At the end of the test the flag shall contain 0x211.
+
+Get slot usage
+--------------
+
+Environment
+
+Result
+ This function shall return 0x94.
+ Add three AVLN in the station manager configured as followed:
+
+ * AVLN 1 : Slot id = 4;
+ * AVLN 2 : Slot id = 7;
+ * AVLN 3 : Slot id = 2;
+
+ This makes a slot usage equal to 0x94.
+
+Result
+ This function shall return 0x94.
diff --git a/cesar/cp/eoc/sta/mgr/test/doc/sta.txt b/cesar/cp/eoc/sta/mgr/test/doc/sta.txt
new file mode 100644
index 0000000000..e711621277
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/doc/sta.txt
@@ -0,0 +1,44 @@
+Station
+=======
+
+Get tei
+-------
+
+Allow any user to get a copy of the station TEI.
+
+Result
+~~~~~~
+
+Returns the correct value.
+
+Get Mac address
+---------------
+
+Allow any user to get a copy of the Station's Mac address.
+
+Result
+~~~~~~
+
+Returns the correct value.
+
+Get CCo status
+--------------
+
+Allow any user to get a copy of the station CCo status.
+
+Result
+~~~~~~
+
+Returns the correct value.
+
+
+Get PCo status
+---------------
+
+Allow any user to get a copy of the Station's Pco.
+
+Result
+~~~~~~
+
+Returns the correct value.
+
diff --git a/cesar/cp/eoc/sta/mgr/test/doc/sta_mgr.txt b/cesar/cp/eoc/sta/mgr/test/doc/sta_mgr.txt
new file mode 100644
index 0000000000..6fcf407725
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/doc/sta_mgr.txt
@@ -0,0 +1,14 @@
+Station Manager
+===============
+
+Initialise
+----------
+
+This shall call the function init of the net_list and the init function of the
+STA own data.
+
+Uninitialise
+------------
+
+This will call the uninit function to the net_list and the station own data.
+
diff --git a/cesar/cp/eoc/sta/mgr/test/doc/sta_own_data.txt b/cesar/cp/eoc/sta/mgr/test/doc/sta_own_data.txt
new file mode 100644
index 0000000000..ab302bcdd0
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/doc/sta_own_data.txt
@@ -0,0 +1,111 @@
+Sta own data
+============
+
+Test the Sta own data private attributes which shall only be modified by the
+accessors.
+
+Status
+------
+
+Tested : under test.
+
+Initialise
+----------
+
+Initialise the private structure (this structure contains the public
+structure) and verify if all the data are setted to 0.
+
+Result
+~~~~~~
+
+- If all the values are equals to 0, the test succeed.
+- If any value is not equal to 0, the test fail.
+
+TEI
+---
+
+Shall update the STA own data to set the station TEI, and modified the Mac
+config structure data referenced in the CP to update the station TEI.
+
+Result
+~~~~~~
+
+- The mac config contains the correct TEI.
+- The station own data contains the correct TEI.
+
+Mac address
+-----------
+
+Shall update the sta own data to set the mac address and modified the mac
+config structure referenced in the CP to update the mac address.
+
+Result
+~~~~~~
+
+- The mac config contains the correct Mac address
+- The station own data contains the correct mac address.
+
+NPW
+---
+
+Shall set up the NPW in the station own data and request the module MSG to
+send a MME to the PLC Driver to store the modification in the flash memory.
+
+*TODO* : Add the API in the MSG module.
+
+Result
+~~~~~~
+
+- The NPW is stored correctly in the STA own data.
+
+NMK
+---
+
+Shall set up the NMK in the station own data and request the module MSG to
+send a MME to the PLC Driver to store the modification in the flash memory.
+
+*TODO* : Add the API in the MSG module.
+
+Result
+~~~~~~
+
+- The NMK is stored correctly in the STA own data.
+
+DPW
+---
+
+Shall set up the DPW in the station own data and request the module MSG to
+send a MME to the PLC Driver to store the modification in the flash memory.
+
+*TODO* : Add the API in the MSG module.
+
+Result
+~~~~~~
+
+- The DPW is stored correctly in the STA own data.
+
+Security level
+--------------
+
+Shall set the security level of the station and send a message to the PLC
+driver to store the SL in the flash memory.
+
+*TODO* : Add the API in the MSG module.
+
+Result
+~~~~~~
+
+- The security level is setted correctly in the station own data.
+
+Was CCo Status
+--------------
+
+Shall set the was CCo status and send a MME to the PLC driver to store the
+station cco status in the flash memory.
+
+*TODO* : Add the API in the MSG module.
+
+Result
+~~~~~~
+
+- The was_cco status is setted in the station own data.
diff --git a/cesar/cp/eoc/sta/mgr/test/overide/cp/cco/action/inc/context.h b/cesar/cp/eoc/sta/mgr/test/overide/cp/cco/action/inc/context.h
new file mode 100644
index 0000000000..ca3da3cf61
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/overide/cp/cco/action/inc/context.h
@@ -0,0 +1,26 @@
+#ifndef overide_cp_cco_action_inc_context_h
+#define overide_cp_cco_action_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/cp/cco/action/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+
+#define CP_CCO_ACTION_TEI_FLAGS_ROW 8
+
+struct cp_cco_action_t
+{
+ /** TEI in use. */
+ uint tei_flags [CP_CCO_ACTION_TEI_FLAGS_ROW];
+};
+
+#endif /* overide_cp_cco_action_inc_context_h */
diff --git a/cesar/cp/eoc/sta/mgr/test/overide/cp/inc/context.h b/cesar/cp/eoc/sta/mgr/test/overide/cp/inc/context.h
new file mode 100644
index 0000000000..5fc77af264
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/overide/cp/inc/context.h
@@ -0,0 +1,55 @@
+#ifndef cp_inc_cp_h
+#define cp_inc_cp_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/inc/cp_private.h
+ * \brief Control plane context.
+ * \ingroup cp
+ *
+ */
+#include "lib/rnd.h"
+
+/* Public interfaces. */
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/cco/action/cco_action.h"
+#include "cl/cl.h"
+#include "mac/common/config.h"
+#include "mac/sar/sar.h"
+
+/* Private interfaces. */
+#include "cp/sta/mgr/inc/sta_mgr.h"
+
+/* Override ones. */
+#include "cp/cco/action/inc/context.h"
+
+struct cp_t
+{
+ /** station manager context. */
+ cp_sta_mgr_t sta_mgr;
+
+ /** Cl context. */
+ cl_t *cl;
+
+ /** Mac config */
+ mac_config_t *mac_config;
+
+ /** Mac store. */
+ mac_store_t *mac_store;
+
+ /** SAR layer context pointer. */
+ sar_t *sar;
+
+ /** CCo action */
+ cp_cco_action_t cco_action;
+
+ /** Random context. */
+ lib_rnd_t rnd;
+};
+
+#endif /* cp_inc_cp_h */
diff --git a/cesar/cp/eoc/sta/mgr/test/overide/cp/sta/core/core.h b/cesar/cp/eoc/sta/mgr/test/overide/cp/sta/core/core.h
new file mode 100644
index 0000000000..a00e59f744
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/overide/cp/sta/core/core.h
@@ -0,0 +1,21 @@
+#ifndef overide_cp_sta_core_core_h
+#define overide_cp_sta_core_core_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/cp/sta/core/core.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+
+u32
+cp_sta_core_get_date_ms (cp_t *cp);
+
+#endif /* overide_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/sta/mgr/test/overide/mac/sar/inc/context.h b/cesar/cp/eoc/sta/mgr/test/overide/mac/sar/inc/context.h
new file mode 100644
index 0000000000..9e7c6f07ca
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/overide/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) 2008 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/sta/mgr/test/src/core_stub.c b/cesar/cp/eoc/sta/mgr/test/src/core_stub.c
new file mode 100644
index 0000000000..c2dfaceccb
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/core_stub.c
@@ -0,0 +1,23 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/core_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+
+u32
+cp_sta_core_get_date_ms (cp_t *cp)
+{
+ return 1;
+}
+
diff --git a/cesar/cp/eoc/sta/mgr/test/src/net_test.c b/cesar/cp/eoc/sta/mgr/test/src/net_test.c
new file mode 100644
index 0000000000..e9590f0cfa
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/net_test.c
@@ -0,0 +1,225 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/net_test.c
+ * \brief Test the net APIs
+ * \ingroup cp_sta_mgr
+ *
+ */
+#include "common/std.h"
+#include "cp/sta/mgr/test/test_sta_mgr.h"
+
+bool
+cp_net_station_assoc_less (set_node_t *left, set_node_t *right);
+
+bool
+cp_net_station_unassoc_less (set_node_t *left, set_node_t *right);
+
+void
+test_case_cp_net_init (test_t test)
+{
+ cp_t ctx;
+ cp_net_t net;
+ test_case_begin (test, "NET init");
+ test_begin (test, "init")
+ {
+ cp_net_init (&ctx, &net);
+ test_fail_unless (net.present == false);
+ }
+ test_end;
+}
+
+void
+test_case_cp_net_uninit (test_t test)
+{
+ cp_t cp;
+ test_sta_mgr_init (&cp);
+ test_case_begin (test, "uninit");
+ test_begin (test, "Net empty")
+ {
+ cp_net_t net;
+ cp_net_init (&cp, &net);
+ cp_net_uninit (&cp, &net);
+ test_fail_unless (set_empty (&net.associated_stas));
+ test_fail_unless (set_empty (&net.unassociated_stas));
+ test_fail_unless (!net.present);
+ }
+ test_end;
+
+ test_begin (test, "NET empty with NID SNID")
+ {
+ cp_net_t *net;
+ /* Initialise the comparison net. */
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ test_fail_unless (net->present);
+ cp_sta_mgr_remove_avln (&cp, net->snid, net->nid);
+ test_fail_unless (set_empty (&net->associated_stas));
+ test_fail_unless (set_empty (&net->unassociated_stas));
+ test_fail_unless (!net->present);
+ }
+ test_end;
+ test_sta_mgr_uninit (&cp);
+}
+
+void
+test_case_cp_net_get_snid_nid (test_t test)
+{
+ test_case_begin (test, "Get snid");
+
+ test_begin (test, "Get snid and nid from a NET")
+ {
+ cp_t cp;
+ cp_net_t net;
+
+ /* Configure the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&net, 0, sizeof (cp_net_t));
+
+ net.snid = 0x1;
+ net.nid = 0x133456789ABCull;
+
+ test_fail_if (cp_net_get_snid (&cp, &net) != net.snid);
+ test_fail_if (cp_net_get_nid (&cp, &net) != net.nid);
+ }
+ test_end;
+}
+
+void
+test_case_cp_net_slot_usage (test_t test)
+{
+ test_case_begin (test, "Set, get slots and get slot mask");
+
+ test_begin (test, "Set slot id and mask")
+ {
+ cp_t cp;
+ cp_net_t net;
+
+ /* Configure the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&net, 0, sizeof (cp_net_t));
+
+ cp_net_set_slot_id_and_usage (&cp, &net, 1, 2);
+
+ test_fail_if (cp_net_get_slot_id (&cp, &net) != 1);
+ test_fail_if (cp_net_get_slot_usage_mask (&cp, &net) != 2);
+ }
+ test_end;
+}
+
+void
+test_case_cp_net_nm (test_t test)
+{
+ test_case_begin (test, "Network mode");
+
+ test_begin (test, "Set the NM and GET it.")
+ {
+ cp_t cp;
+ cp_net_t net;
+
+ /* Configure the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&net, 0, sizeof (cp_net_t));
+
+ cp_net_set_nm (&cp, &net, CP_NET_NM_COORDINATED);
+ test_fail_if (cp_net_get_nm (&cp, &net) != CP_NET_NM_COORDINATED);
+
+ cp_net_set_nm (&cp, &net, CP_NET_NM_CSMA_ONLY);
+ test_fail_if (cp_net_get_nm (&cp, &net) != CP_NET_NM_CSMA_ONLY);
+
+ cp_net_set_nm (&cp, &net, CP_NET_NM_UNCOORDINATED);
+ test_fail_if (cp_net_get_nm (&cp, &net) != CP_NET_NM_UNCOORDINATED);
+ }
+ test_end;
+}
+
+void
+test_case_cp_net_sta_visible (test_t test)
+{
+ test_case_begin (test, "visible stations");
+
+ test_begin (test, "Set")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ /* Configure the test. */
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+ cp_sta_own_data_set_tei (&cp, 254);
+ /* the test. */
+ cp_sta_set_visible_status (
+ &cp, sta, CP_STA_VISIBLE_STATE_VISIBLE);
+ test_fail_unless (net->num_visible_stas == 1);
+ cp_sta_set_visible_status (
+ &cp, sta, CP_STA_VISIBLE_STATE_HIDDEN);
+ test_fail_unless (net->num_visible_stas == 0);
+ slab_release (sta);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_net_access (test_t test)
+{
+ test_case_begin (test, "Network Access type");
+
+ test_begin (test, "Network access type")
+ {
+ cp_t cp;
+ cp_net_t net;
+
+ /* Configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&net, 0, sizeof (cp_net_t));
+
+ /* Test. */
+ cp_net_set_access (&cp, &net, HPAV_ACCESS_ACCESS);
+ test_fail_if (net.access != HPAV_ACCESS_ACCESS);
+
+ cp_net_set_access (&cp, &net, HPAV_ACCESS_IN_HOME);
+ test_fail_if (net.access != HPAV_ACCESS_IN_HOME);
+ }
+ test_end;
+}
+
+void
+test_case_get_net (test_t test)
+{
+ test_case_begin (test, "Net of a STA");
+
+ test_begin (test, "Get the net of a STA")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ /* Initialize. */
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ test_fail_unless (cp_sta_get_net (sta) == net);
+ slab_release (sta);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_suite_net (test_t test)
+{
+ test_suite_begin (test, "Net");
+ test_case_cp_net_init (test);
+ test_case_cp_net_uninit (test);
+ test_case_cp_net_get_snid_nid (test);
+ test_case_cp_net_slot_usage (test);
+ test_case_cp_net_nm (test);
+ test_case_cp_net_sta_visible (test);
+ test_case_cp_net_access (test);
+}
diff --git a/cesar/cp/eoc/sta/mgr/test/src/sar_stub.c b/cesar/cp/eoc/sta/mgr/test/src/sar_stub.c
new file mode 100644
index 0000000000..a9847bef57
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/sar_stub.c
@@ -0,0 +1,50 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/sar_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "mac/sar/sar.h"
+#include "mac/sar/inc/context.h"
+
+/**
+ * Remove a station from the SAR and the mac store.
+ * \param ctx the CP context.
+ * \param tei the station tei.
+ *
+ * Remove all the MFS from the expiration mechanism of the SAR and ends to
+ * remove the station from the mac store.
+ */
+void
+sar_sta_remove (sar_t *ctx, u8 tei)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_store);
+ dbg_assert (tei);
+
+ dbg_check (mac_store_sta_remove (ctx->mac_store, tei));
+}
+
+void
+sar_cleanup (sar_t *ctx)
+{
+ mfs_tx_t *mfs;
+ dbg_assert (ctx);
+
+ mfs = mac_store_mfs_get_tx (ctx->mac_store, true, false, 1,
+ MAC_TEI_BCAST);
+ if (mfs)
+ {
+ mac_store_mfs_remove (ctx->mac_store, (mfs_t *) mfs);
+ blk_release (mfs);
+ }
+}
diff --git a/cesar/cp/eoc/sta/mgr/test/src/sta-test.c b/cesar/cp/eoc/sta/mgr/test/src/sta-test.c
new file mode 100644
index 0000000000..d8effc6c7d
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/sta-test.c
@@ -0,0 +1,688 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/sta-test.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "lib/bitstream.h"
+
+#include "cp/sta/mgr/sta_own_data.h"
+
+#include "cp/inc/context.h"
+#include "cp/sta/mgr/inc/sta_own_data.h"
+
+#include "cl/inc/context.h"
+#include "mac/sar/inc/context.h"
+#include <string.h>
+#include "cp/fsm/fsm.h"
+
+static bool fsm_posted;
+
+static void
+test_sta_own_init (cp_t *cp)
+{
+ static mac_config_t mac_config;
+ static cl_t cl;
+ static sar_t sar;
+ memset (&mac_config, 0, sizeof (mac_config));
+ memset (&cl, 0, sizeof (cl_t));
+ memset (&sar, 0, sizeof (sar_t));
+ memset (cp, 0, sizeof (cp_t));
+ cp->mac_config = &mac_config;
+ cp->cl = &cl;
+ cp->sar = &sar;
+ cp->mac_store = sar.mac_store = mac_store_init ();
+ lib_rnd_init (&cp->rnd, 1234);
+ cp_sta_mgr_init (cp);
+}
+
+static void
+test_sta_own_uninit (cp_t *cp)
+{
+ cp_sta_mgr_uninit (cp);
+ mac_store_uninit (cp->mac_store);
+}
+
+
+void
+cp_fsm_post (cp_t *ctx, cp_fsm_event_t *event)
+{
+ fsm_posted = true;
+}
+
+void
+test_case_cp_sta_own_data_init (test_t test)
+{
+ test_case_begin (test, "init");
+
+ test_begin (test, "init")
+ {
+ cp_t cp;
+ cp_sta_own_data_private_t cmp;
+ cp_sta_own_data_private_t *real;
+
+ memset (&cmp, 0, sizeof (cp_sta_own_data_private_t));
+ cmp.public.hybrid_mode = MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ cmp.snid = cp_sta_own_data_get_snid (&cp);
+
+ real = (cp_sta_own_data_private_t*) cp_sta_mgr_get_sta_own_data(&cp);
+ test_fail_if (
+ memcmp(&cmp, real, sizeof (cp_sta_own_data_private_t)) != 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__set_and_get_tei (test_t test)
+{
+ test_case_begin (test, "Set Get tei");
+
+ test_begin (test, "Set")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ test_sta_own_init (&cp);
+ // Add an AVLN.
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_tei (&cp, 2);
+
+ test_fail_if (cp_sta_own_data_get_tei (&cp) != 2);
+ test_fail_unless (fsm_posted == true);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_tei (&cp, 2);
+ test_fail_if (cp_sta_own_data_get_tei (&cp) != 2);
+ test_fail_unless (fsm_posted == false);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_tei (&cp, MAC_TEI_UNASSOCIATED);
+ test_fail_unless (cp_sta_own_data_get_tei (&cp) ==
+ MAC_TEI_UNASSOCIATED);
+ test_fail_unless (fsm_posted == true);
+ test_sta_own_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__mac_address (test_t test)
+{
+ test_case_begin (test, "Mac address");
+
+ test_begin (test, "Set and Get the mac address")
+ {
+ cp_t cp;
+
+ mac_config_t mac_config;
+ cp.mac_config = &mac_config;
+ lib_rnd_init (&cp.rnd, 0x432);
+
+ cp_sta_mgr_init (&cp);
+ cp_sta_own_data_set_mac_address (&cp, 0x123456789ABCull);
+
+ test_fail_if (cp_sta_own_data_get_mac_address (&cp) !=
+ 0x123456789ABCull);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__npw (test_t test)
+{
+ test_case_begin (test, "Set and get the NPW");
+
+ test_begin (test, "NPW")
+ {
+ cp_t cp;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ cp_sta_own_data_set_npw (&cp, "Hello world");
+
+ test_fail_if (
+ strcmp (cp_sta_own_data_get_npw (&cp), "Hello world") != 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__nmk (test_t test)
+{
+ test_case_begin (test, "Set and get the NMK");
+
+ test_begin (test, "NMK")
+ {
+ cp_t cp;
+ cp_key_t key;
+ cp_key_t res;
+ bool changed;
+
+ key.key[0] = 0x1234;
+ key.key[1] = 0x5678;
+ key.key[2] = 0x9abc;
+ key.key[3] = 0xdef0;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ changed = cp_sta_own_data_set_nmk (&cp, key, 0);
+
+ res = cp_sta_own_data_get_nmk (&cp);
+
+ test_fail_if (changed == false);
+ test_fail_if (memcmp (&res, &key, sizeof (cp_key_t)) != 0);
+
+ changed = cp_sta_own_data_set_nmk (&cp, key, 0);
+ test_fail_if (changed == true);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__dpw (test_t test)
+{
+ test_case_begin (test, "Set and get the DPW");
+
+ test_begin (test, "DPW")
+ {
+ cp_t cp;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ cp_sta_own_data_set_dpw (&cp, "Hello world");
+
+ test_fail_if (
+ strcmp (cp_sta_own_data_get_dpw (&cp), "Hello world") != 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__security_level (test_t test)
+{
+ test_case_begin (test, "Set and get the SL");
+
+ test_begin (test, "SL")
+ {
+ cp_t cp;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ cp_sta_own_data_set_security_level (&cp, CP_SECURITY_LEVEL_SC);
+
+ test_fail_if (cp_sta_own_data_get_security_level (&cp) !=
+ CP_SECURITY_LEVEL_SC);
+
+ cp_sta_own_data_set_security_level (&cp, CP_SECURITY_LEVEL_HS);
+
+ test_fail_if (cp_sta_own_data_get_security_level (&cp) !=
+ CP_SECURITY_LEVEL_HS);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__was_cco (test_t test)
+{
+ test_case_begin (test, "Set and get was_cco");
+
+ test_begin (test, "was_cco")
+ {
+ cp_t cp;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ cp_sta_own_data_set_was_cco (&cp, true);
+ test_fail_if (cp_sta_own_data_get_was_cco(&cp) != true);
+ cp_sta_own_data_set_was_cco (&cp, false);
+ test_fail_if (cp_sta_own_data_get_was_cco (&cp) != false);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+}
+
+void
+test_case_cp_sta_own_data__hfid_avln (test_t test)
+{
+ test_case_begin (test, "Set and get the AVLN HFID");
+
+ test_begin (test, "AVLN HFID")
+ {
+ cp_t cp;
+ cp_sta_own_data_t *sta;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_hfid_avln (&cp, "Hello world");
+
+ test_fail_if (
+ strcmp (sta->hfid_avln, "Hello world") != 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__hfid_user (test_t test)
+{
+ test_case_begin (test, "Set and get the USER HFID");
+
+ test_begin (test, "USER HFID")
+ {
+ cp_t cp;
+ cp_sta_own_data_t *sta;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_hfid_user (&cp, "Hello world");
+
+ test_fail_if (
+ strcmp (sta->hfid_user, "Hello world") != 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__hfid_manufacturer (test_t test)
+{
+ test_case_begin (test, "Set and get the MANUFACTURER HFID");
+
+ test_begin (test, "MANUFACTURER HFID")
+ {
+ cp_t cp;
+ cp_sta_own_data_t *sta;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_hfid_manufacturer (&cp, "Hello world");
+
+ test_fail_if (
+ strcmp (sta->hfid_manufacturer, "Hello world") != 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__pco_glid (test_t test)
+{
+ test_case_begin (test, "Set and get the PCO glid");
+
+ test_begin (test, "PCo")
+ {
+ cp_t cp;
+ cp_sta_own_data_t *sta;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_pco_glid (&cp, 0x90);
+ test_fail_if (cp_sta_own_data_get_pco_glid (&cp) != 0x90);
+ cp_sta_own_data_set_pco_glid (&cp, 0x0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__pco_status (test_t test)
+{
+ test_case_begin (test, "Set and get the PCO status");
+
+ test_begin (test, "PCo")
+ {
+ cp_t cp;
+ cp_sta_own_data_t *sta;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_pco_status (&cp, true);
+ test_fail_if (cp_sta_own_data_get_pco_status (&cp) != true);
+ test_fail_unless (fsm_posted == true);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_pco_status (&cp, true);
+ test_fail_if (cp_sta_own_data_get_pco_status (&cp) != true);
+ test_fail_unless (fsm_posted == false);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_pco_status (&cp, false);
+ test_fail_if (cp_sta_own_data_get_pco_status (&cp) != false);
+ test_fail_unless (fsm_posted == true);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "PCo and glid")
+ {
+ cp_t cp;
+ cp_sta_own_data_t *sta;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_pco_status (&cp, true);
+ cp_sta_own_data_set_pco_glid (&cp, 0x85);
+
+ test_fail_if (cp_sta_own_data_get_pco_status (&cp) != true);
+ test_fail_if (cp_sta_own_data_get_pco_glid (&cp) != 0x85);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__cco_status (test_t test)
+{
+ test_case_begin (test, "Set and get the CCo status");
+
+ test_begin (test, "CCo")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ mac_config_t mac_config;
+ cp_sta_own_data_t *sta;
+ cl_t cl;
+ sar_t sar;
+
+ cp.mac_config = &mac_config;
+ cl.mactotei = NULL;
+ cp.cl = &cl;
+ cp.sar = &sar;
+ cp.mac_store = mac_store_init ();
+ sar.mac_store = cp.mac_store;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_tei (&cp, 1);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_cco_status (&cp, true);
+ test_fail_if (cp_sta_own_data_get_cco_status (&cp) != true);
+ test_fail_unless (fsm_posted == true);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_cco_status (&cp, true);
+ test_fail_if (cp_sta_own_data_get_cco_status (&cp) != true);
+ test_fail_unless (fsm_posted == false);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_cco_status (&cp, false);
+ test_fail_if (cp_sta_own_data_get_cco_status (&cp) != false);
+ test_fail_unless (fsm_posted == true);
+
+ cp_sta_mgr_uninit (&cp);
+ mac_store_uninit (cp.mac_store);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__authenticated_status (test_t test)
+{
+ test_case_begin (test, "Set and get the CCo authenticated");
+
+ test_begin (test, "CCo")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ mac_config_t mac_config;
+ cp_sta_own_data_t *sta;
+ cl_t cl;
+ sar_t sar;
+
+ cp.mac_config = &mac_config;
+ cl.mactotei = NULL;
+ cp.cl = &cl;
+ cp.sar = &sar;
+ cp.mac_store = mac_store_init ();
+ sar.mac_store = cp.mac_store;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ sta = cp_sta_mgr_get_sta_own_data (&cp);
+ cp_sta_own_data_set_tei (&cp, 1);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_authenticated_status (&cp, true);
+ test_fail_if (cp_sta_own_data_get_authenticated_status (&cp) != true);
+ test_fail_unless (fsm_posted == true);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_authenticated_status (&cp, true);
+ test_fail_if (cp_sta_own_data_get_authenticated_status (&cp) != true);
+ test_fail_unless (fsm_posted == false);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_authenticated_status (&cp, false);
+ test_fail_if (cp_sta_own_data_get_authenticated_status (&cp) != false);
+ test_fail_unless (fsm_posted == true);
+
+ cp_sta_mgr_uninit (&cp);
+ mac_store_uninit (cp.mac_store);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__nid (test_t test)
+{
+ test_case_begin (test, "Set/Get NID & SL");
+
+ test_begin (test, "")
+ {
+ cp_t cp;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+
+ lib_rnd_t rnd;
+ lib_rnd_init (&rnd, 0x4224);
+
+ cp_security_level_t sl;
+ for (sl = CP_SECURITY_LEVEL_SC; sl < CP_SECURITY_LEVEL_NB; sl++)
+ {
+ uint i;
+ for (i = 0; i < 1234; i++)
+ {
+ cp_nid_t nid = ((u64) sl) << (HPAV_NID_SIZE_BITS - 2)
+ | lib_rnd_uniform (&rnd, -1);
+ cp_sta_own_data_set_nid (&cp, nid);
+ test_fail_if (cp_sta_own_data_get_nid (&cp) != nid);
+ test_fail_if (cp_sta_own_data_get_security_level (&cp) != sl);
+ }
+ }
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__snid (test_t test)
+{
+ test_case_begin (test, "Set and GET SNID");
+
+ test_begin (test, "")
+ {
+ cp_t cp;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+
+ cp_sta_own_data_set_snid (&cp, 0x2);
+ test_fail_if (cp_sta_own_data_get_snid (&cp) != 0x2);
+ cp_sta_own_data_set_snid (&cp, 0x1);
+ test_fail_if (cp_sta_own_data_get_snid (&cp) != 0x1);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__tek (test_t test)
+{
+ test_case_begin (test, "Set the TEK");
+
+ test_begin (test, "TEK")
+ {
+ cp_t cp;
+ cp_key_t key;
+ cp_key_t tek;
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+
+ key.key[0] = 0x12345678;
+ key.key[1] = 0x12345678;
+ key.key[2] = 0x12345678;
+ key.key[3] = 0x12345678;
+
+ cp_sta_own_data_set_tek (&cp, key);
+
+ tek = cp_sta_own_data_get_tek (&cp);
+
+ test_fail_unless (memcmp (&tek, &key, sizeof (cp_key_t)) == 0);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__dak (test_t test)
+{
+ test_case_begin (test, "DAK");
+
+ test_begin (test, "store dak")
+ {
+ cp_t cp;
+ uint i;
+ cp_key_t dak = { {0x11111111, 0x22222222, 0x33333333, 0x44444444} };
+ cp_key_t own_dak;
+
+ memset (&cp, 0, sizeof (cp_t));
+
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+
+ cp_sta_own_data_set_dak (&cp, dak);
+ own_dak = cp_sta_own_data_get_dak (&cp);
+
+ for (i = 0; i < COUNT (dak.key); i++)
+ test_fail_unless (dak.key[i] == own_dak.key[i]);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case_cp_sta_own_data__sc (test_t test)
+{
+ test_case_begin (test, "Simple connect");
+
+ test_begin (test, "")
+ {
+ cp_t cp;
+
+ memset (&cp, 0, sizeof (cp_t));
+ lib_rnd_init (&cp.rnd, 0x432);
+ cp_sta_mgr_init (&cp);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_sc (&cp, true);
+ test_fail_unless (cp.sta_mgr.sta_own_data.sc == true);
+ test_fail_unless (cp_sta_own_data_get_sc (&cp) == true);
+ test_fail_unless (fsm_posted == true);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_sc (&cp, true);
+ test_fail_unless (cp.sta_mgr.sta_own_data.sc == true);
+ test_fail_unless (cp_sta_own_data_get_sc (&cp) == true);
+ test_fail_unless (fsm_posted == false);
+
+ fsm_posted = false;
+ cp_sta_own_data_set_sc (&cp, false);
+ test_fail_unless (cp.sta_mgr.sta_own_data.sc == false);
+ test_fail_unless (cp_sta_own_data_get_sc (&cp) == false);
+ test_fail_unless (fsm_posted == true);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_suite_sta_own (test_t test)
+{
+ test_suite_begin (test, "station own data");
+ test_case_cp_sta_own_data_init (test);
+ test_case_cp_sta_own_data__set_and_get_tei (test);
+ test_case_cp_sta_own_data__mac_address (test);
+ test_case_cp_sta_own_data__npw (test);
+ test_case_cp_sta_own_data__nmk (test);
+ test_case_cp_sta_own_data__dpw (test);
+ test_case_cp_sta_own_data__security_level (test);
+ test_case_cp_sta_own_data__was_cco (test);
+ test_case_cp_sta_own_data__hfid_avln (test);
+ test_case_cp_sta_own_data__hfid_user (test);
+ test_case_cp_sta_own_data__hfid_manufacturer (test);
+ test_case_cp_sta_own_data__pco_glid (test);
+ test_case_cp_sta_own_data__pco_status (test);
+ test_case_cp_sta_own_data__cco_status (test);
+ test_case_cp_sta_own_data__authenticated_status (test);
+ test_case_cp_sta_own_data__nid (test);
+ test_case_cp_sta_own_data__snid (test);
+ test_case_cp_sta_own_data__tek (test);
+ test_case_cp_sta_own_data__dak (test);
+ test_case_cp_sta_own_data__sc (test);
+}
diff --git a/cesar/cp/eoc/sta/mgr/test/src/sta_mgr.c b/cesar/cp/eoc/sta/mgr/test/src/sta_mgr.c
new file mode 100644
index 0000000000..e2b9db7458
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/sta_mgr.c
@@ -0,0 +1,1695 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/sta_mgr.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "test_sta_mgr.h"
+
+void
+cp_sta_mgr_elects_sta_partial_ack (cp_t *ctx);
+
+void
+test_case__cp_sta_mgr_sta (test_t test)
+{
+ test_case_begin (test, "Station manager using stations");
+
+ test_begin (test, "Station Unassociated")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ mac_t mac_addr;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add the station. */
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, mac_addr);
+ test_fail_if (sta == NULL);
+ slab_release (sta);
+
+ /* Find the station by the mac address. */
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, mac_addr);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addr);
+ slab_release (sta);
+
+ /* Remove the station. */
+ cp_sta_mgr_sta_remove_from_mac (&cp, mac_addr);
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, mac_addr);
+ test_fail_if (sta != NULL);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "Station associated")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ mac_t mac_addr;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station associated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addr);
+ test_fail_if (sta == NULL);
+ slab_release (sta);
+
+ /* Get the station by the TEI. */
+ sta = cp_sta_mgr_sta_get_assoc (&cp, net, sta_tei);
+ test_fail_if (sta == NULL);
+ slab_release (sta);
+
+ /* Get the station by the mac address. */
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, mac_addr);
+ test_fail_if (sta == NULL);
+ slab_release (sta);
+
+ /* Remove the station by the TEI. */
+ cp_sta_mgr_sta_remove_assoc (&cp, net, sta_tei);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 1: Nothing change")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station unassociated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, mac_addr);
+ test_fail_if (sta == NULL);
+
+ /* Add a station with the same mac address and TEI. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, 0, mac_addr);
+ test_fail_if (sta != sta2);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 2: Same TEI, Mac address change from bcast to unique")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station unassociated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei, MAC_BROADCAST);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != MAC_BROADCAST);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != true);
+
+ /* Add a station with the real mac address. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addr);
+ test_fail_if (sta != sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 2: Same TEI, Mac address change from A to B")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addrA;
+ mac_t mac_addrB;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addrA = 0x12345678ABCull;
+ mac_addrB = 0x2345678ABCDull;
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station unassociated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addrA);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addrA);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+
+ /* Add a station with the real mac address. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addrB);
+ test_fail_if (sta == sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addrB);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 2: Change the TEI, Mac address unchanged")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station unassociated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, mac_addr);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != 0);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != true);
+ test_fail_if (set_empty(&net->unassociated_stas) != false);
+
+ /* Add a station with the real TEI. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addr);
+ test_fail_if (sta == sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 2: Change the TEI A to B, Mac address unchanged")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei_A;
+ cp_tei_t sta_tei_B;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+
+ sta_tei_A = 0xB;
+ sta_tei_B = 0xF;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station associated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei_A, mac_addr);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != sta_tei_A);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* Add a station with the real TEI. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, sta_tei_B, mac_addr);
+ test_fail_if (sta == sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei_B);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 2: Change the TEI A to 0, Mac address unchanged")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei_A;
+ cp_tei_t sta_tei_B;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+
+ sta_tei_A = 0xB;
+ sta_tei_B = 0;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station associated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei_A, mac_addr);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != sta_tei_A);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* Add a station with the real TEI. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, sta_tei_B, mac_addr);
+ test_fail_if (sta == sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei_B);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != true);
+ test_fail_if (set_empty(&net->unassociated_stas) != false);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+
+ test_begin (test, "station Case 4: Change the Mac address from A to bcast")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+
+ /* Add a station associated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addr);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* Add a station with the new Mac address. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net, sta_tei, MAC_BROADCAST);
+ test_fail_if (sta != sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "station Case 2: Change the network")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_net_t *net2;
+ cp_sta_t *sta;
+ cp_sta_t *sta2;
+ mac_t mac_addr;
+ cp_tei_t sta_tei;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ mac_addr = 0x12345678ABCull;
+
+ sta_tei = 0xB;
+
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ dbg_check (net);
+ net2 = cp_sta_mgr_add_avln (&cp, 2, 2);
+ dbg_check (net2);
+
+ /* Add a station associated. */
+ sta = cp_sta_mgr_sta_add (&cp, net, sta_tei, mac_addr);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* Add a station in another network. */
+ sta2 = cp_sta_mgr_sta_add (&cp, net2, sta_tei, mac_addr);
+ test_fail_if (sta == sta2);
+
+ test_fail_if (cp_sta_get_tei (sta2) != sta_tei);
+ test_fail_if (cp_sta_get_mac_address (sta2) != mac_addr);
+
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != false);
+ test_fail_if (set_empty(&net->associated_stas) != true);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ test_fail_if (set_empty(&net2->associated_stas) != false);
+ test_fail_if (set_empty(&net2->unassociated_stas) != true);
+
+ /* release the stations. */
+ slab_release (sta);
+ slab_release (sta2);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_case_begin (test, "Sta Remove");
+
+ test_begin (test, "remove from mac")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, 1);
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove_from_mac (&cp, 1);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+
+ /* set our avln. */
+ cp_sta_mgr_set_our_avln (&cp, net);
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, 1);
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove_from_mac (&cp, 1);
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove_from_mac (&cp, 1);
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "remove from assoc")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove_assoc (&cp, net, 1);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+
+ /* set our avln. */
+ cp_sta_mgr_set_our_avln (&cp, net);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove_assoc (&cp, net, 1);
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "remove")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+
+ cp_sta_mgr_sta_remove (&cp, sta);
+ slab_release (sta);
+
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+
+ /* set our avln. */
+ cp_sta_mgr_set_our_avln (&cp, net);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ slab_release (sta);
+
+ cp_sta_mgr_sta_remove (&cp, sta);
+ sta = cp_sta_mgr_sta_get_from_mac(&cp, 1);
+ test_fail_unless (sta == NULL);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_net_uninit (test_t test)
+{
+ test_case_begin (test, "Uninitialise the network with some stations");
+
+ test_begin (test, "net")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ cp_sta_mgr_init (&cp);
+
+ /* Add an AVLN. */
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+
+ test_fail_if (set_empty(&net->associated_stas) != true);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+
+ /* Add some stations. */
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, 1);
+ slab_release (sta);
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, 2);
+ slab_release (sta);
+ sta = cp_sta_mgr_sta_add (&cp, net, 0, 3);
+ slab_release (sta);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 4);
+ slab_release (sta);
+ sta = cp_sta_mgr_sta_add (&cp, net, 2, 5);
+ slab_release (sta);
+ sta = cp_sta_mgr_sta_add (&cp, net, 3, 6);
+ slab_release (sta);
+
+ test_fail_if (set_empty(&net->associated_stas) != false);
+ test_fail_if (set_empty(&net->unassociated_stas) != false);
+
+ cp_sta_mgr_uninit (&cp);
+
+ test_fail_if (set_empty(&net->associated_stas) != true);
+ test_fail_if (set_empty(&net->unassociated_stas) != true);
+ test_fail_if (set_empty(&cp.sta_mgr.stas) != true);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_manager_garbage (test_t test)
+{
+ test_case_begin (test, "Garbage function");
+
+ test_begin (test, "Garbage outside our AVLN.")
+ {
+ cp_t cp;
+ cp_net_t *net1;
+ cp_net_t *net2;
+ cp_sta_t *sta;
+ cl_t cl;
+ uint i;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ cp_sta_mgr_init (&cp);
+ cp.cl = &cl;
+
+ /* Add an AVLN. */
+ net1 = cp_sta_mgr_add_avln (&cp, 1, 1);
+ net2 = cp_sta_mgr_add_avln (&cp, 2, 2);
+
+ for (i = 0; i < 10; i++)
+ {
+ sta = cp_sta_mgr_sta_add (&cp, net1, i + 1, i + 1);
+ sta->expired_date_ms = cp_sta_core_get_date_ms (&cp)
+ - HPAV_DISCOVERED_LIST_EXPIRE_TIME_MS;
+ slab_release (sta);
+
+ sta = cp_sta_mgr_sta_add (&cp, net2, i + 1, (i + 1) * 20);
+ sta->expired_date_ms = cp_sta_core_get_date_ms (&cp)
+ - HPAV_DISCOVERED_LIST_EXPIRE_TIME_MS;
+ slab_release (sta);
+ }
+
+ /* Release the stations. */
+ cp_sta_mgr_garbage (&cp);
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp));
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "Associated stations")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ mac_config_t mac_config;
+ cl_t cl;
+ sar_t sar;
+
+ /* configure the test.*/
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&cl, 0, sizeof (cl_t));
+ memset (&sar, 0, sizeof (sar_t));
+ memset (&mac_config, 0, sizeof (mac_config_t));
+
+ cp.mac_config=&mac_config;
+ cp_sta_mgr_init (&cp);
+ mac_ntb_init (&mac_config);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp.sta_mgr.our_avln = net;
+ cp.mac_store = mac_store_init ();
+ cp.mac_config = &mac_config;
+ cp.cl = &cl;
+ cp.sar = &sar;
+ sar.mac_store = cp.mac_store;
+
+ cp_sta_own_data_set_tei (&cp, 34);
+ cp_sta_own_data_set_cco_status (&cp, true);
+
+ /* Add some stations. */
+ sta = cp_sta_mgr_sta_add (&cp, net, 0x1, 123);
+ cp_sta_set_assoc_confirmed (&cp, sta, false);
+ sta->assoc_req_last_ms = 130000; /* > 2 min. */
+ slab_release (sta);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 0x3, 124);
+ cp_sta_set_assoc_confirmed (&cp, sta, false);
+ sta->assoc_req_last_ms = 60000; /* 1 min. */
+ slab_release (sta);
+
+ /* Test. */
+ cp_sta_mgr__assoc__timeout (&cp, 60000);
+
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, 123);
+ test_fail_if (cp_sta_get_assoc_confirmed (&cp, sta) != false);
+ slab_release (sta);
+
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, 124);
+ test_fail_if (cp_sta_get_assoc_confirmed (&cp, sta) != false);
+ slab_release (sta);
+
+ /* Test. */
+ cp_sta_mgr__assoc__timeout (&cp, 120000);
+
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, 123);
+ test_fail_if (cp_sta_get_assoc_confirmed (&cp, sta) != false);
+ slab_release (sta);
+
+ sta = cp_sta_mgr_sta_get_from_mac (&cp, 124);
+ test_fail_if (cp_sta_get_assoc_confirmed (&cp, sta) != true);
+ slab_release (sta);
+
+ /* Station manager uninitialise. */
+ cp_sta_mgr_sta_remove_from_mac (&cp, 123);
+ cp_sta_mgr_sta_remove_from_mac (&cp, 124);
+ cp_sta_mgr_uninit (&cp);
+ mac_store_uninit (cp.mac_store);
+ }
+ test_end;
+
+ test_begin (test, "Garbage the network")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ sar_t sar;
+ cl_t cl;
+ mac_config_t mac_config;
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&sar, 0, sizeof (sar_t));
+ memset (&cl, 0, sizeof (cl_t));
+ memset (&mac_config, 0, sizeof (mac_config_t));
+ cp.sar = &sar;
+ cp.cl = &cl;
+ cp.mac_config = &mac_config;
+ cp.mac_store = mac_store_init ();
+ sar.mac_store = cp.mac_store;
+ cp_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ /* Add some stations in the first AVLN. */
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ sta->expired_date_ms = cp_sta_core_get_date_ms (&cp)
+ - HPAV_DISCOVERED_LIST_EXPIRE_TIME_MS - 10;
+ slab_release (sta);
+ /* Set our AVLN. */
+ cp_sta_mgr_set_our_avln (&cp, net);
+ /* Launch the test. */
+ cp_sta_mgr_garbage (&cp);
+ /* Its our AVLN and the station is not CCo. It should not remove the
+ * station. */
+ test_fail_unless (!cp_net_is_empty (&cp, net));
+ /* Now the net is no more our AVLN. */
+ cp_sta_mgr_set_our_avln (&cp, NULL);
+ test_fail_unless (!cp_net_is_empty (&cp, net));
+ cp_sta_mgr_garbage (&cp);
+ test_fail_unless (cp_net_is_empty (&cp, net));
+ test_fail_unless (!net->present);
+ cp_sta_mgr_uninit (&cp);
+ mac_store_uninit (sar.mac_store);
+ }
+ test_end;
+}
+
+void
+test_case__cp_net_pco (test_t test)
+{
+ test_case_begin (test, "Net pco");
+
+ test_begin (test, "PCo on the net")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ cp_sta_mgr_init (&cp);
+
+ /* Add an AVLN. */
+ net = cp_sta_mgr_add_avln (&cp, 2, 2);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+
+ /* Set the station as PCo. */
+ cp_net_set_pco (&cp, net, 1);
+
+ test_fail_if (cp_sta_get_pco_status (sta) != true);
+ test_fail_if (net->pco != sta);
+
+ /* Unset the PCo. */
+ cp_net_set_pco (&cp, net, 0);
+
+ test_fail_if (cp_sta_get_pco_status (sta) != false);
+ test_fail_if (net->pco != NULL);
+
+ slab_release (sta);
+ cp_sta_mgr_uninit (&cp);
+
+ }
+ test_end;
+}
+
+void
+test_case__cp_net_sta_get_first_next (test_t test)
+{
+ test_case_begin (test, "Get first and next");
+
+ test_begin (test, "Get the first and next station")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta1;
+ cp_sta_t *sta2;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ cp_sta_mgr_init (&cp);
+
+ /* Add an AVLN. */
+ net = cp_sta_mgr_add_avln (&cp, 2, 2);
+
+ sta1 = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ sta2 = cp_sta_mgr_sta_add (&cp, net, 2, 2);
+ slab_release (sta1);
+ slab_release (sta2);
+
+ /* Get the first station. */
+ sta1 = cp_net_sta_get_first (&cp, net, CP_NET_STA_ASSOC);
+ test_fail_if (sta1 == NULL);
+ test_fail_if (cp_sta_get_tei (sta1) != 1);
+
+ /* Get the next station. */
+ sta2 = cp_net_sta_get_next (&cp, net, sta1);
+ test_fail_if (sta2 == NULL);
+ test_fail_if (cp_sta_get_tei (sta2) != 2);
+
+ slab_release (sta2);
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_get_avln (test_t test)
+{
+ test_case_begin (test, "Get AVLN");
+
+ test_begin (test, "Get an AVLN")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ uint i, j;
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ cp_sta_mgr_init (&cp);
+ for (i = 0; i < HPAV_AVLNS_NB_MAX; i++)
+ net = cp_sta_mgr_add_avln (&cp, i, i);
+ for (i = 0; i < HPAV_AVLNS_NB_MAX; i++)
+ {
+ test_fail_unless (cp.sta_mgr.networks[i].present);
+ for (j = 0; j < HPAV_AVLNS_NB_MAX; j++)
+ {
+ if (i != j)
+ {
+ test_fail_unless (
+ cp.sta_mgr.networks[i].snid
+ != cp.sta_mgr.networks[j].snid);
+ test_fail_unless (
+ cp.sta_mgr.networks[i].nid
+ != cp.sta_mgr.networks[j].nid);
+ }
+ }
+ }
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_get_first_next_avln (test_t test)
+{
+ test_case_begin (test, "Get first and next AVLN");
+
+ test_begin (test, "Get first and next AVLN")
+ {
+ cp_t cp;
+ cp_net_t *net_cmp[3];
+ cp_net_t *net;
+
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+
+ cp_sta_mgr_init (&cp);
+
+ /* Add AVLN. */
+ net_cmp[0] = cp_sta_mgr_add_avln (&cp, 2, 2);
+ net_cmp[1] = cp_sta_mgr_add_avln (&cp, 3, 3);
+ net_cmp[2] = cp_sta_mgr_add_avln (&cp, 4, 4);
+
+ /* Get the AVLN. */
+ net = cp_sta_mgr_get_first_avln (&cp);
+ test_fail_if (net_cmp[0] != net);
+ net = cp_sta_mgr_get_next_avln (&cp, net);
+ test_fail_if (net_cmp[1] != net);
+ net = cp_sta_mgr_get_next_avln (&cp, net);
+ test_fail_if (net_cmp[2] != net);
+ net = cp_sta_mgr_get_next_avln (&cp, net);
+ test_fail_if (NULL != net);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_net_is_empty (test_t test)
+{
+ test_case_begin (test, "Network is empty");
+
+ test_begin (test, "Network is empty")
+ {
+ cp_t cp;
+ cl_t cl;
+ sar_t sar;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ uint i;
+ /* configuring the test. */
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ cp.sar = &sar;
+ cp.cl = &cl;
+ cl.mactotei = NULL;
+ sar.mac_store = mac_store_init ();
+ cp.mac_store = sar.mac_store;
+ cp_sta_mgr_init (&cp);
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == true);
+ for (i = 0; i < HPAV_AVLNS_NB_MAX; i++)
+ {
+ net = cp_sta_mgr_add_avln (&cp, i, i);
+ test_fail_unless (net);
+ }
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == false);
+ /* Set our AVLN. */
+ cp_sta_mgr_set_our_avln (&cp, cp_sta_mgr_get_avln (&cp, 0, 0));
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == false);
+ /* add a station per AVLN. */
+ for (i = 0; i < HPAV_AVLNS_NB_MAX; i++)
+ {
+ net = cp_sta_mgr_get_avln (&cp, i, i);
+ test_fail_unless (net);
+ sta = cp_sta_mgr_sta_add (&cp, net, i+1, i+1);
+ slab_release (sta);
+ }
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == false);
+ /* Remove AVLN by AVLN unless our AVLN. */
+ for (i = 1; i < HPAV_AVLNS_NB_MAX; i++)
+ {
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == false);
+ cp_sta_mgr_remove_avln (&cp, i, i);
+ }
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == false);
+ /* Set present flag in our AVLN. This is just to verify that present
+ * flag in our AVLN is not used. */
+ net = cp_sta_mgr_get_our_avln (&cp);
+ net->present = false;
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == false);
+ /* Remove the station in this AVLN. */
+ cp_sta_mgr_sta_remove_from_mac (&cp, 1);
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == true);
+ net->present = true;
+ test_fail_unless (cp_sta_mgr_net_list_is_empty (&cp) == true);
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_set_our_avln__no_net (test_t test)
+{
+ test_case_begin (test, "Set our AVLN, coming from unassociated state");
+
+ test_begin (test, "start")
+ {
+ cp_t cp;
+ test_sta_mgr_init (&cp);
+ cp.cl->mactotei = NULL;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ uint i;
+ sta_t *sta_store;
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ for (i = 1; i < 4; i ++)
+ {
+ sta = cp_sta_mgr_sta_add (&cp, net, i, i);
+ slab_release (sta);
+ }
+
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ /* The table of the CL mac to tei as been stubbed for this test, the
+ * real CL mactotei does not allow the user to get data as the
+ * following instructions. To do some, use the functions API's in the
+ * CL mactotei module. */
+ cl_mactotei_t *table;
+ table = (cl_mactotei_t*) cp.cl->mactotei;
+ for (i = 1; i < 4; i++)
+ {
+ sta_store = mac_store_sta_get (cp.mac_store, i);
+ sta = cp_sta_mgr_sta_get_assoc (&cp, net, i);
+ test_fail_if (table[i-1].tei != i);
+ test_fail_if (table[i-1].mac != i);
+ test_fail_if (sta_store == NULL);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != table[i-1].tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != table[i-1].mac);
+
+ slab_release (sta);
+ blk_release (sta_store);
+ }
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_set_our_avln__with_net (test_t test)
+{
+ test_case_begin (test, "Set our AVLN, coming from associated state");
+
+ test_begin (test, "start")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ uint i;
+ sta_t *sta_store;
+ mfs_tx_t *mfs;
+ bool added;
+ test_sta_mgr_init (&cp);
+ /* Store a broadcast MFS. */
+ mfs = mac_store_mfs_add_tx (cp.mac_store, true, false, 1,
+ MAC_TEI_BCAST,
+ &added);
+ dbg_assert (added);
+ blk_release (mfs);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+
+ for (i = 1; i < 4; i ++)
+ {
+ sta = cp_sta_mgr_sta_add (&cp, net, i, i);
+ slab_release (sta);
+ }
+
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ /* The table of the CL mac to tei as been stubbed for this test, the
+ * real CL mactotei does not allow the user to get data as the
+ * following instructions. To do some, use the functions API's in the
+ * CL mactotei module. */
+ cl_mactotei_t *table;
+ table = (cl_mactotei_t*) cp.cl->mactotei;
+ for (i = 1; i < 4; i++)
+ {
+ sta_store = mac_store_sta_get (cp.mac_store, i);
+ sta = cp_sta_mgr_sta_get_assoc (&cp, net, i);
+ test_fail_if (table[i-1].tei != i);
+ test_fail_if (table[i-1].mac != i);
+ test_fail_if (sta_store == NULL);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != table[i-1].tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != table[i-1].mac);
+
+ slab_release (sta);
+ blk_release (sta_store);
+ }
+
+ net = cp_sta_mgr_add_avln (&cp, 2, 2);
+
+ for (i = 1; i < 4; i ++)
+ {
+ sta = cp_sta_mgr_sta_add (&cp, net, i + 3, i + 3);
+ slab_release (sta);
+ }
+
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ /* The table of the CL mac to tei as been stubbed for this test, the
+ * real CL mactotei does not allow the user to get data as the
+ * following instructions. To do some, use the functions API's in the
+ * CL mactotei module. */
+ table = (cl_mactotei_t*) cp.cl->mactotei;
+ for (i = 1; i < 4; i++)
+ {
+ sta_store = mac_store_sta_get (cp.mac_store, i + 3);
+ sta = cp_sta_mgr_sta_get_assoc (&cp, net, i + 3);
+ test_fail_if (table[i-1].tei != i + 3);
+ test_fail_if (table[i-1].mac != i + 3);
+ test_fail_if (sta_store == NULL);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != table[i-1].tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != table[i-1].mac);
+
+ slab_release (sta);
+ blk_release (sta_store);
+ }
+
+ for (i = 1; i < 4; i++)
+ {
+ sta_store = mac_store_sta_get (cp.mac_store, i);
+ test_fail_if (sta_store != NULL);
+ }
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_set_our_avln__with_net_to_unassoc (test_t test)
+{
+ test_case_begin (test, "Set our AVLN, coming from associated to unassoc");
+
+ test_begin (test, "start")
+ {
+ uint i;
+ cp_sta_t *sta;
+ sta_t *sta_store;
+ cp_net_t *net;
+ cp_t cp;
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+
+ for (i = 1; i < 4; i ++)
+ {
+ sta = cp_sta_mgr_sta_add (&cp, net, i, i);
+ slab_release (sta);
+ }
+
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ /* The table of the CL mac to tei as been stubbed for this test, the
+ * real CL mactotei does not allow the user to get data as the
+ * following instructions. To do some, use the functions API's in the
+ * CL mactotei module. */
+ cl_mactotei_t *table;
+ table = (cl_mactotei_t*) cp.cl->mactotei;
+ for (i = 1; i < 4; i++)
+ {
+ sta_store = mac_store_sta_get (cp.mac_store, i);
+ sta = cp_sta_mgr_sta_get_assoc (&cp, net, i);
+ test_fail_if (table[i-1].tei != i);
+ test_fail_if (table[i-1].mac != i);
+ test_fail_if (sta_store == NULL);
+ test_fail_if (sta == NULL);
+ test_fail_if (cp_sta_get_tei (sta) != table[i-1].tei);
+ test_fail_if (cp_sta_get_mac_address (sta) != table[i-1].mac);
+
+ slab_release (sta);
+ blk_release (sta_store);
+ }
+
+ dbg_fatal_try_begin
+ {
+ cp_sta_mgr_set_our_avln (&cp, NULL);
+
+ test_fail_if (cp.cl->mactotei != NULL);
+
+ for (i = 1; i < 4; i++)
+ {
+ sta_store = mac_store_sta_get (cp.mac_store, i);
+ test_fail_if (sta_store != NULL);
+ }
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ test_verbose_print (fatal_message);
+ }
+ dbg_fatal_try_end;
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_release_station (test_t test)
+{
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ sta_t *sta_store;
+ test_case_begin (test, "Release station");
+ test_begin (test, "No AVLN")
+ {
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+
+ dbg_fatal_try_begin
+ {
+ cp_sta_mgr_release_station (&cp, 1);
+ }
+ dbg_fatal_try_catch (const char *fail)
+ {
+ test_verbose_print (fail);
+ test_fail_if (cp_sta_own_data_get_cco_status (&cp) == true);
+ }
+ dbg_fatal_try_end;
+
+ // The same as CCo.
+ cp_sta_own_data_set_tei (&cp, 2);
+ cp_sta_own_data_set_cco_status (&cp, true);
+ cp_sta_mgr_release_station (&cp, 1);
+
+ test_fail_if (sta->tei_lease_date_ms != CP_STA_MGR_STATION_RELEASE_MS +
+ cp_sta_core_get_date_ms (&cp));
+
+ /* Launch the garbage. */
+ cp_sta_mgr_garbage (&cp);
+
+ test_fail_if (list_empty (&cp.sta_mgr.release_sta_list) == true);
+
+ /* modify the lease to make the station expire. */
+ sta->tei_lease_date_ms = 0;
+ slab_release (sta);
+
+ cp_sta_mgr_garbage (&cp);
+ test_fail_if (list_empty (&cp.sta_mgr.release_sta_list) == false);
+
+ /* Verify the store. */
+ sta_store = mac_store_sta_get (cp.mac_store, 1);
+ test_fail_if (sta_store != NULL);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "Change AVLN")
+ {
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+
+ // The same as CCo.
+ cp_sta_own_data_set_tei (&cp, 2);
+ cp_sta_own_data_set_cco_status (&cp, true);
+ cp_sta_mgr_release_station (&cp, 1);
+
+ test_fail_if (sta->tei_lease_date_ms != CP_STA_MGR_STATION_RELEASE_MS +
+ cp_sta_core_get_date_ms (&cp));
+
+ slab_release (sta);
+ cp_sta_mgr_set_our_avln (&cp, NULL);
+ test_fail_if (list_empty (&cp.sta_mgr.release_sta_list) == false);
+
+ /* Verify the store. */
+ sta_store = mac_store_sta_get (cp.mac_store, 1);
+ test_fail_if (sta_store != NULL);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "AVLN1 to AVLN2")
+ {
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ slab_release (sta);
+
+ // The same as CCo.
+ cp_sta_own_data_set_tei (&cp, 2);
+ cp_sta_own_data_set_cco_status (&cp, true);
+ cp_sta_mgr_release_station (&cp, 1);
+
+ net = cp_sta_mgr_add_avln (&cp, 2, 2);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+
+ // The same as CCo.
+ cp_sta_own_data_set_tei (&cp, 2);
+ cp_sta_own_data_set_cco_status (&cp, true);
+ cp_sta_mgr_release_station (&cp, 1);
+
+ test_fail_if (sta->tei_lease_date_ms != CP_STA_MGR_STATION_RELEASE_MS +
+ cp_sta_core_get_date_ms (&cp));
+
+ slab_release (sta);
+ cp_sta_mgr_set_our_avln (&cp, NULL);
+ test_fail_if (list_empty (&cp.sta_mgr.release_sta_list) == false);
+
+ /* Verify the store. */
+ sta_store = mac_store_sta_get (cp.mac_store, 1);
+ test_fail_if (sta_store != NULL);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_case__cp_sta_mgr_partial_ack (test_t test)
+{
+ test_case_begin (test, "Partial acknowledge");
+
+// test_begin (test, "Partial ACK")
+// {
+// cp_t cp;
+// cl_t cl;
+// sar_t sar;
+// mac_config_t mac_config;
+// cp_net_t *net;
+// cp_sta_t *sta;
+// sta_t *sta_store;
+// uint i;
+// uint nbsta = 10;
+// lib_rnd_t rand;
+//
+// memset (&cl, 0, sizeof (cl_t));
+// memset (&sar, 0, sizeof (sar_t));
+// memset (&mac_config, 0, sizeof (mac_config_t));
+// cp_sta_mgr_init (&cp);
+// cp.mac_store = mac_store_init ();
+// cp.cl = (cl_t *) &cl;
+// cp.sar = &sar;
+// sar.mac_store = cp.mac_store;
+// cp.mac_config = &mac_config;
+//
+// lib_rnd_init (&rand, 0x123);
+// memset (&mac_config, 0, sizeof (mac_config));
+//
+// /* First test, elects a station when our station does not makes part
+// * of any AVLN. */
+// cp_sta_mgr_elects_sta_partial_ack (&cp);
+// test_fail_unless (mac_config.partial_ack_tei_default == 0);
+//
+// /* Add the AVLN and configure it as our AVLN. */
+// net = cp_sta_mgr_add_avln (&cp, 1, 1);
+// cp_sta_mgr_set_our_avln (&cp, net);
+//
+// /* Create some stations. */
+// for (i = 1; i < nbsta; i++)
+// {
+// /* Add the station in the station manager and at the same time in
+// * the mac store. */
+// sta = cp_sta_mgr_sta_add (&cp, net, i, i);
+//
+// /* Get the station from the mac store. */
+// sta_store = mac_store_sta_get (cp.mac_store, i);
+// dbg_assert (sta_store);
+//
+// /* Modify the default tone map to configure the BLE.*/
+// if (sta_store->tx_tonemaps)
+// {
+// /* Allocate the tone map. */
+// sta_store->tx_tonemaps->tm[4] = tonemap_alloc ();
+// sta_store->tx_tonemaps->default_tmi = 4;
+// sta_store->tx_tonemaps->tm[4]->ble = lib_rnd32 (&rand);
+// }
+//
+// blk_release (sta_store);
+// slab_release (sta);
+// }
+//
+// cp_sta_mgr_elects_sta_partial_ack (&cp);
+// test_fail_unless (mac_config.partial_ack_tei_default == 2);
+//
+// /* Modify the BLE for station 2. */
+// sta_store = mac_store_sta_get (cp.mac_store, 2);
+// dbg_assert (sta_store);
+// sta_store->tx_tonemaps->tm[0]->ble = 51;
+// blk_release (sta_store);
+//
+// cp_sta_mgr_elects_sta_partial_ack (&cp);
+// test_fail_unless (mac_config.partial_ack_tei_default == 3);
+//
+//
+// /* Removes the current acknowledge station from the network. */
+// cp_sta_mgr_sta_remove_assoc (&cp, net, 3);
+// test_fail_unless (mac_config.partial_ack_tei_default == 8);
+//
+// /* Ends the test. */
+// cp_sta_mgr_set_our_avln (&cp, NULL);
+//
+// mac_store_uninit (cp.mac_store);
+// cp_sta_mgr_uninit (&cp);
+// }
+// test_end;
+//
+// test_begin (test, "Partial ACK no Tone maps")
+// {
+// cp_t cp;
+// cl_t cl;
+// sar_t sar;
+// mac_config_t mac_config;
+// cp_net_t *net;
+// cp_sta_t *sta;
+// uint i;
+// uint nbsta = 10;
+// lib_rnd_t rand;
+//
+// memset (&cl, 0, sizeof (cl_t));
+// memset (&sar, 0, sizeof (sar_t));
+// memset (&mac_config, 0, sizeof (mac_config_t));
+// cp_sta_mgr_init (&cp);
+// cp.mac_store = mac_store_init ();
+// cp.cl = (cl_t *) &cl;
+// cp.sar = &sar;
+// sar.mac_store = cp.mac_store;
+// cp.mac_config = &mac_config;
+//
+// lib_rnd_init (&rand, 0x123);
+// memset (&mac_config, 0, sizeof (mac_config));
+//
+// /* First test, elects a station when our station does not makes part
+// * of any AVLN. */
+// cp_sta_mgr_elects_sta_partial_ack (&cp);
+// test_fail_unless (mac_config.partial_ack_tei_default == 0);
+//
+// /* Add the AVLN and configure it as our AVLN. */
+// net = cp_sta_mgr_add_avln (&cp, 1, 1);
+// cp_sta_mgr_set_our_avln (&cp, net);
+//
+// /* Create some stations. */
+// for (i = 1; i < nbsta; i++)
+// {
+// /* Add the station in the station manager and at the same time in
+// * the mac store. */
+// sta = cp_sta_mgr_sta_add (&cp, net, i, i);
+// slab_release (sta);
+// }
+//
+// cp_sta_mgr_elects_sta_partial_ack (&cp);
+// test_fail_unless (mac_config.partial_ack_tei_default == 0);
+//
+// /* Ends the test. */
+// cp_sta_mgr_set_our_avln (&cp, NULL);
+//
+// mac_store_uninit (cp.mac_store);
+// cp_sta_mgr_uninit (&cp);
+// }
+// test_end;
+}
+
+void
+test_case__cp_sta_mgr_change_snid (test_t test)
+{
+ test_case_begin (test, "Change snid");
+
+ test_begin (test, "CCo")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+ cp_sta_own_data_set_tei (&cp, 1);
+ cp_sta_own_data_set_authenticated_status (&cp, true);
+ cp_sta_own_data_set_cco_status (&cp, true);
+
+ /* Change our AVLN. */
+ cp_sta_own_data_set_snid (&cp, 0x3);
+
+ test_fail_unless (cp_sta_own_data_get_snid (&cp) == 0x3);
+ test_fail_unless (net->snid == 0x3);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "Station")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+
+ test_fail_unless (net->snid == 0x1);
+
+ /* Change our AVLN. */
+ cp_sta_own_data_set_snid (&cp, 0x3);
+
+ test_fail_unless (cp_sta_own_data_get_snid (&cp) == 0x3);
+ test_fail_unless (net->snid == 0x1);
+
+ cp_sta_own_data_set_snid (&cp, 0x1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+
+ cp_sta_own_data_set_snid (&cp, 0x3);
+
+ test_fail_unless (cp_sta_own_data_get_snid (&cp) == 0x3);
+ test_fail_unless (net->snid == 0x3);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+/** SNID present
+ *
+ * \param test the test object.
+ *
+ * Return a flag indicating which SNID is currently in use.
+ * environment 3 AVLNs with SNID 1, 5, 10.
+ * At the end of the test the flag shall contain 0x211.
+ */
+void
+test_case_snid_present (test_t test)
+{
+ cp_t cp;
+ uint i;
+ u16 snidFlags, snidfcmp = 0;
+ memset (&cp, 0, sizeof (cp_t));
+ test_case_begin (test, "Getting present SNID");
+ cp_snid_t snid [] = {1, 5, 10};
+ for (i = 0; i < COUNT (snid); i++)
+ {
+ cp_sta_mgr_add_avln (&cp, snid[i], i);
+ snidfcmp = snidfcmp | ((u16) 1 << snid[i]);
+ }
+ snidFlags = cp_sta_mgr_get_present_snids (&cp);
+ test_begin (test, "Verifying the flags")
+ {
+ test_fail_unless (snidFlags == snidfcmp);
+ }
+ test_end;
+}
+
+/** Get slot usage
+ * \param test the test object.
+ *
+ * Environment
+ * Add three AVLN in the station manager configured as followed:
+ *
+ * * AVLN 1 : Slot id = 4;
+ * * AVLN 2 : Slot id = 7;
+ * * AVLN 3 : Slot id = 2;
+ *
+ * This makes a slot usage equal to 0x94.
+ *
+ * Result
+ * This function shall return 0x94.
+ */
+void
+test_case_slot_usage (test_t test)
+{
+ cp_t cp;
+ cp_net_t *net;
+
+ lib_rnd_init (&cp.rnd, 0x3421);
+ cp_sta_mgr_init (&cp);
+
+ test_case_begin (test, "Getting the slot usage");
+
+ // Add the first AVLN.
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_net_set_slot_id_and_usage (&cp, net, 4, 5);
+
+ net = cp_sta_mgr_add_avln (&cp, 2, 2);
+ cp_net_set_slot_id_and_usage (&cp, net, 7, 7);
+
+ net = cp_sta_mgr_add_avln (&cp, 3, 3);
+ cp_net_set_slot_id_and_usage (&cp, net, 2, 3);
+
+ test_begin (test, "Verify")
+ {
+ test_fail_if (cp_sta_mgr_get_slot_usage (&cp) != 0x94,
+ "Wrong Slot usage bit fields");
+ }
+ test_end;
+}
+
+void
+test_case__cp_net_num_sta_associated (test_t test)
+{
+ test_case_begin (test, "Number of stations associated");
+
+ test_begin (test, "Add 10 STAs")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+
+ memset (&cp, 0, sizeof (cp_t));
+ mac_config_t mac_config;
+ cp.mac_config=&mac_config;
+ cp_sta_mgr_init (&cp);
+
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+
+ test_fail_unless (cp_net_num_sta_associated (&cp, net) == 0);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, MAC_TEI_UNASSOCIATED, 1);
+ slab_release (sta);
+
+ test_fail_unless (cp_net_num_sta_associated (&cp, net) == 0);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ slab_release (sta);
+
+ test_fail_unless (cp_net_num_sta_associated (&cp, net) == 1);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, MAC_TEI_UNASSOCIATED, 1);
+ slab_release (sta);
+
+ test_fail_unless (cp_net_num_sta_associated (&cp, net) == 0);
+
+ sta = cp_sta_mgr_sta_add (&cp, net, 2, 1);
+ slab_release (sta);
+
+ test_fail_unless (cp_net_num_sta_associated (&cp, net) == 1);
+
+ cp_sta_mgr_sta_remove_from_mac (&cp, 1);
+ test_fail_unless (cp_net_num_sta_associated (&cp, net) == 0);
+
+ cp_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_suite_sta_mgr (test_t test)
+{
+ test_suite_begin (test, "sta mgr");
+ test_case__cp_sta_mgr_sta (test);
+ test_case__cp_net_uninit (test);
+ test_case__cp_sta_manager_garbage (test);
+ test_case__cp_net_pco (test);
+ test_case__cp_net_sta_get_first_next (test);
+ test_case__cp_sta_mgr_get_avln (test);
+ test_case__cp_sta_mgr_get_first_next_avln (test);
+ test_case__cp_net_is_empty (test);
+ test_case__cp_sta_mgr_set_our_avln__no_net (test);
+ test_case__cp_sta_mgr_set_our_avln__with_net (test);
+ test_case__cp_sta_mgr_set_our_avln__with_net_to_unassoc (test);
+ test_case__cp_sta_mgr_release_station (test);
+ test_case__cp_sta_mgr_partial_ack (test);
+ test_case__cp_sta_mgr_change_snid (test);
+ test_case_snid_present (test);
+ test_case_slot_usage (test);
+ test_case__cp_net_num_sta_associated (test);
+}
diff --git a/cesar/cp/eoc/sta/mgr/test/src/station_test.c b/cesar/cp/eoc/sta/mgr/test/src/station_test.c
new file mode 100644
index 0000000000..14b983ca50
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/station_test.c
@@ -0,0 +1,428 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/station_test.c
+ * \brief Test the station.
+ * \ingroup cp_sta_mgr
+ *
+ */
+#include "common/std.h"
+#include "cp/sta/mgr/test/test_sta_mgr.h"
+
+#include "cp/sta/mgr/inc/sta.h"
+
+/**
+ * Initialise a station.
+ *
+ */
+void
+test_case_station_init (test_t test)
+{
+ cp_sta_t *sta;
+ cp_sta_private_t station;
+ slab_cache_t sta_slab_cache;
+
+ test_case_begin (test, "Station init");
+ test_begin (test, "verify data")
+ {
+ slab_cache_init (&sta_slab_cache,
+ "Station cache",
+ sizeof (cp_sta_private_t),
+ (slab_object_destructor_t) cp_sta_uninit);
+
+
+ memset (&station, 0, sizeof (cp_sta_private_t));
+ station.association_confirmed = true;
+ station.visible = true;
+ sta = cp_sta_init (&sta_slab_cache);
+
+ test_fail_if (memcmp(sta, &station,
+ sizeof(cp_sta_private_t)) != 0,
+ "Wrong sta is not initialised");
+
+
+ slab_release (sta);
+ }
+ test_end;
+}
+
+/**
+ * Get the TEI of the station.
+ *
+ * \param test the test object.
+ */
+void
+test_case_get_tei (test_t test)
+{
+ cp_sta_private_t station;
+
+ memset (&station, '\0', sizeof (cp_sta_private_t));
+
+ test_case_begin (test, "get station TEI");
+
+ station.tei = 0xA;
+
+ test_begin (test, "Getting TEI")
+ {
+ test_fail_if (cp_sta_get_tei ((cp_sta_t *) &station) != 0xA,
+ "Wrong TEI");
+ }
+ test_end;
+}
+
+/**
+ * Get the Mac address of the station.
+ *
+ * \param test the test object.
+ */
+void
+test_case_get_mac_addr (test_t test)
+{
+ cp_sta_private_t station;
+
+ memset (&station, '\0', sizeof (cp_sta_private_t));
+
+ test_case_begin (test, "get station Mac address");
+
+ station.mac_address = 0x123456789abcull;
+
+ test_begin (test, "Getting Mac address")
+ {
+ test_fail_if (cp_sta_get_mac_address ((cp_sta_t *) &station)
+ != 0x123456789abcull,
+ "Wrong Mac address");
+ }
+ test_end;
+}
+
+/**
+ * Get the peer structure of the station.
+ *
+ * \param test the test object.
+ */
+void
+test_case_get_peer (test_t test)
+{
+ cp_sta_private_t station;
+
+ memset (&station, '\0', sizeof (cp_sta_private_t));
+
+ test_case_begin (test, "get station peer");
+
+ station.tei = 0xA;
+ station.mac_address = 0x123456789abcull;
+
+ test_begin (test, "Getting peer")
+ {
+ cp_mme_peer_t peer;
+ cp_sta_get_peer ((cp_sta_t *) &station, &peer);
+ test_fail_if (!cp_mme_peer_cmp (
+ &peer, &CP_MME_PEER (0x123456789abcull, 0xA)),
+ "Wrong peer");
+ }
+ test_end;
+}
+
+/**
+ * Get the CCo status of the station.
+ *
+ * \param test the test object.
+ */
+void
+test_case_get_cco_status (test_t test)
+{
+ cp_sta_private_t station;
+
+ memset (&station, '\0', sizeof (cp_sta_private_t));
+
+ test_case_begin (test, "get station CCo status");
+
+ test_begin (test, "Getting CCo status")
+ {
+ test_fail_if (cp_sta_get_cco_status ((cp_sta_t *) &station)
+ != false,
+ "Wrong CCo status");
+ }
+ test_end;
+
+ station.is_cco = true;
+
+ test_begin (test, "Getting CCo status true")
+ {
+ test_fail_if (cp_sta_get_cco_status ((cp_sta_t *) &station)
+ != true,
+ "Wrong CCo status");
+ }
+ test_end;
+}
+
+/**
+ * Get the PCo status of the station.
+ *
+ * \param test the test object.
+ */
+void
+test_case_get_pco_status (test_t test)
+{
+ cp_sta_private_t station;
+
+ memset (&station, '\0', sizeof (cp_sta_private_t));
+
+ test_case_begin (test, "get station PCo status");
+
+ test_begin (test, "Getting PCo status")
+ {
+ test_fail_if (cp_sta_get_pco_status ((cp_sta_t *) &station)
+ != false,
+ "Wrong PCo status");
+ }
+ test_end;
+
+ station.pco_glid = 0x80;
+
+ test_begin (test, "Getting PCo status true")
+ {
+ test_fail_if (cp_sta_get_pco_status ((cp_sta_t *) &station)
+ != true,
+ "Wrong PCo status");
+ }
+ test_end;
+}
+
+void
+test_case_authenticated (test_t test)
+{
+ test_case_begin (test, "Authentication");
+
+ test_begin (test, "set & get authentication")
+ {
+ cp_t cp;
+ cp_net_t net;
+ cp_sta_private_t station;
+ cp_sta_t *sta = (cp_sta_t *) &station;
+
+ memset (&station, 0, sizeof (cp_sta_private_t));
+ memset (&cp, 0, sizeof (cp_t));
+
+ /* configure the test. */
+ cp.mac_store = mac_store_init ();
+ cp.sta_mgr.our_avln = &net;
+ station.tei = 0xA;
+ station.net = &net;
+ mac_store_sta_add (cp.mac_store, station.tei);
+
+ cp_sta_set_authenticated (&cp, sta, true);
+ test_fail_if (cp_sta_get_authenticated (&cp, sta) != true);
+
+ cp_sta_set_authenticated (&cp, sta, false);
+ test_fail_if (cp_sta_get_authenticated (&cp, sta) != false);
+
+ dbg_check (mac_store_sta_remove (cp.mac_store, station.tei));
+ mac_store_uninit (cp.mac_store);
+ }
+ test_end;
+
+ test_begin (test, "set authentication TEI = 0")
+ {
+ cp_t cp;
+ cp_net_t net;
+ cp_sta_private_t station;
+ cp_sta_t *sta = (cp_sta_t *) &station;
+
+ memset (&station, 0, sizeof (cp_sta_private_t));
+ memset (&cp, 0, sizeof (cp_t));
+
+ /* configure the test. */
+ cp.mac_store = mac_store_init ();
+ cp.sta_mgr.our_avln = &net;
+ station.tei = 0;
+ station.net = &net;
+
+ cp_sta_set_authenticated (&cp, sta, false);
+ mac_store_uninit (cp.mac_store);
+ }
+ test_end;
+}
+
+void
+test_case_visible_state (test_t test)
+{
+ test_case_begin (test, "Visible state");
+
+ test_begin (test, "station visible state")
+ {
+ cp_t cp;
+ cp_net_t net;
+ cp_sta_private_t sta;
+
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&net, 0, sizeof (cp_net_t));
+ memset (&sta, 0, sizeof (cp_sta_private_t));
+
+ /* configure the stations. */
+ sta.net = &net;
+ sta.tei = 1;
+
+ cp_sta_set_visible_status (&cp, (cp_sta_t *) &sta,
+ CP_STA_VISIBLE_STATE_VISIBLE);
+ test_fail_if (cp_net_get_num_discovered_stas (&cp, &net) != 1);
+
+ cp_sta_set_visible_status (&cp, (cp_sta_t *) &sta,
+ CP_STA_VISIBLE_STATE_HIDDEN);
+ test_fail_if (cp_net_get_num_discovered_stas (&cp, &net) != 0);
+ test_fail_if (cp_sta_get_visible_status ((cp_sta_t *) &sta) !=
+ CP_STA_VISIBLE_STATE_HIDDEN);
+ }
+ test_end;
+
+ test_begin (test, "station visible state in our AVLN")
+ {
+ cp_t cp;
+ cp_net_t net;
+ cp_sta_private_t sta;
+ sta_t *sta_store;
+
+ memset (&cp, 0, sizeof (cp_t));
+ memset (&net, 0, sizeof (cp_net_t));
+ memset (&sta, 0, sizeof (cp_sta_private_t));
+
+ /* configure the stations. */
+ sta.net = &net;
+ sta.tei = 1;
+ cp.sta_mgr.our_avln = &net;
+ cp.mac_store = mac_store_init ();
+
+ mac_store_sta_add (cp.mac_store, sta.tei);
+ sta_store = mac_store_sta_get (cp.mac_store, 1);
+
+ cp_sta_set_assoc_confirmed (&cp, (cp_sta_t*) &sta, false);
+ test_fail_unless (sta_store->multi_unicast_receiver == false);
+
+ cp_sta_set_visible_status (&cp, (cp_sta_t *) &sta,
+ CP_STA_VISIBLE_STATE_VISIBLE);
+ test_fail_if (cp_net_get_num_discovered_stas (&cp, &net) != 1);
+ test_fail_unless (sta_store->multi_unicast_receiver == false);
+
+ cp_sta_set_assoc_confirmed (&cp, (cp_sta_t*) &sta, true);
+ test_fail_if (sta_store->multi_unicast_receiver != true);
+
+ cp_sta_set_visible_status (&cp, (cp_sta_t *) &sta,
+ CP_STA_VISIBLE_STATE_HIDDEN);
+ test_fail_if (cp_net_get_num_discovered_stas (&cp, &net) != 0);
+ test_fail_if (cp_sta_get_visible_status ((cp_sta_t *) &sta) !=
+ CP_STA_VISIBLE_STATE_HIDDEN);
+
+ test_fail_if (sta_store->multi_unicast_receiver != false);
+ blk_release (sta_store);
+
+ dbg_check (mac_store_sta_remove (cp.mac_store, 1));
+ mac_store_uninit (cp.mac_store);
+ }
+ test_end;
+
+}
+
+void
+test_case_pco_glid (test_t test)
+{
+ test_case_begin (test, "PCo GLID");
+
+ test_begin (test, "PCo GLID")
+ {
+ cp_sta_private_t sta;
+
+ memset (&sta, 0, sizeof (cp_sta_private_t));
+
+ cp_sta_set_pco_glid ((cp_sta_t *) &sta, 0x95);
+ test_fail_if (cp_sta_get_pco_glid ((cp_sta_t *) &sta) != 0x95);
+ test_fail_if (cp_sta_get_pco_status ((cp_sta_t *) &sta) != true);
+
+ cp_sta_set_pco_glid ((cp_sta_t *) &sta, 0x0);
+ test_fail_if (cp_sta_get_pco_glid ((cp_sta_t *) &sta) != 0x0);
+ test_fail_if (cp_sta_get_pco_status ((cp_sta_t *) &sta) != false);
+ }
+ test_end;
+}
+
+void
+test_case_multi_association_confirmed (test_t test)
+{
+ test_case_begin (test, "Association confirmed");
+ test_begin (test, "Visible station")
+ {
+ cp_t cp;
+ /* Configure the test. */
+ test_sta_mgr_init (&cp);
+ cp_net_t *net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ cp_sta_t *sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ sta_t *sta_store;
+ cp_sta_mgr_set_our_avln (&cp, net);
+ cp_sta_own_data_set_tei (&cp, 2);
+ cp_sta_own_data_set_cco_status (&cp, true);
+ /* begin the test. */
+ cp_sta_set_visible_status (&cp, sta, CP_STA_VISIBLE_STATE_VISIBLE);
+ cp_sta_set_assoc_confirmed (&cp, sta, true);
+ sta_store = mac_store_sta_get (cp.mac_store, 1);
+ test_fail_unless (cp_sta_get_assoc_confirmed (&cp, sta));
+ test_fail_unless (sta_store->multi_unicast_receiver);
+ /* Change the state. */
+ cp_sta_set_assoc_confirmed (&cp, sta, false);
+ test_fail_unless (!cp_sta_get_assoc_confirmed (&cp, sta));
+ test_fail_unless (!sta_store->multi_unicast_receiver);
+ /* Uninitialise */
+ slab_release (sta);
+ blk_release (sta_store);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "Hidden station")
+ {
+ cp_t cp;
+ cp_net_t *net;
+ cp_sta_t *sta;
+ sta_t *sta_store;
+ /* Configure the test. */
+ test_sta_mgr_init (&cp);
+ net = cp_sta_mgr_add_avln (&cp, 1, 1);
+ sta = cp_sta_mgr_sta_add (&cp, net, 1, 1);
+ cp_sta_mgr_set_our_avln (&cp, net);
+ cp_sta_own_data_set_tei (&cp, 2);
+ /* begin the test. */
+ cp_sta_set_visible_status (&cp, sta, CP_STA_VISIBLE_STATE_HIDDEN);
+ cp_sta_set_assoc_confirmed (&cp, sta, true);
+ sta_store = mac_store_sta_get (cp.mac_store, 1);
+ test_fail_unless (cp_sta_get_assoc_confirmed (&cp, sta));
+ test_fail_unless (!sta_store->multi_unicast_receiver);
+ /* Change the state. */
+ cp_sta_set_assoc_confirmed (&cp, sta, false);
+ test_fail_unless (!cp_sta_get_assoc_confirmed (&cp, sta));
+ test_fail_unless (!sta_store->multi_unicast_receiver);
+ /* Uninitialise */
+ slab_release (sta);
+ blk_release (sta_store);
+ test_sta_mgr_uninit (&cp);
+ }
+ test_end;
+}
+
+void
+test_suite_station (test_t test)
+{
+ test_suite_begin (test, "station");
+ test_case_station_init (test);
+ test_case_get_tei (test);
+ test_case_get_mac_addr (test);
+ test_case_get_peer (test);
+ test_case_get_cco_status (test);
+ test_case_get_pco_status (test);
+ test_case_authenticated (test);
+ test_case_visible_state (test);
+ test_case_pco_glid (test);
+ test_case_multi_association_confirmed (test);
+}
diff --git a/cesar/cp/eoc/sta/mgr/test/src/test_sta_mgr.c b/cesar/cp/eoc/sta/mgr/test/src/test_sta_mgr.c
new file mode 100644
index 0000000000..a5a94c03c4
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/src/test_sta_mgr.c
@@ -0,0 +1,136 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/mgr/test/src/test_sta_mgr.c
+ * \brief Test environment.
+ * \ingroup cp_sta_mgr
+ */
+#include "common/std.h"
+#include "cp/sta/mgr/test/test_sta_mgr.h"
+
+static cl_mactotei_t table[10];
+static uint table_index;
+
+void
+test_sta_mgr_init (cp_t *cp)
+{
+ static mac_config_t mac_config;
+ static cl_t cl;
+ static sar_t sar;
+ memset (&mac_config, 0, sizeof (mac_config));
+ memset (&cl, 0, sizeof (cl_t));
+ memset (&sar, 0, sizeof (sar_t));
+ memset (cp, 0, sizeof (cp_t));
+ cp->mac_config = &mac_config;
+ cp->cl = &cl;
+ cp->sar = &sar;
+ cp->mac_store = sar.mac_store = mac_store_init ();
+ lib_rnd_init (&cp->rnd, 1234);
+ cp_sta_mgr_init (cp);
+}
+
+void
+test_sta_mgr_uninit (cp_t *cp)
+{
+ cp_sta_mgr_uninit (cp);
+ mac_store_uninit (cp->mac_store);
+}
+
+/**
+ * Create a new table to be filled by the CP.
+ *
+ * \return a pointer to the new block to be fill with the mac to tei table
+ * data
+ */
+cl_mactotei_blk_t *
+cl_mactotei_new (void)
+{
+ memset (table, 0, sizeof (table));
+ table_index = 0;
+ return (cl_mactotei_blk_t *) &table;
+}
+
+/**
+ * Add a new tupple of data to the table.
+ *
+ * \param table the table pointer to add a new mac to tei correspondance.
+ * \param mac_addr the mac addr to add
+ * \param tei the tei corresponding to the STA.
+ * \param tag the CP tag provide to indentifier a network.
+ */
+void cl_mactotei_addr_add (cl_mactotei_blk_t *table, mac_t mac_addr,
+ uint tei, uint tag)
+{
+ cl_mactotei_t *curr;
+
+ curr = (cl_mactotei_t*) table;
+ curr[table_index].tag = tag;
+ curr[table_index].tei = tei;
+ curr[table_index].mac = mac_addr;
+ table_index ++;
+}
+
+/**
+ * Request the CL to use the new table and remove the old one.
+ *
+ * \param ctx the CL context
+ * \param table the new table to use.
+ */
+void
+cl_mactotei_use_table (cl_t *ctx, cl_mactotei_blk_t *table)
+{
+ dbg_assert (table);
+ dbg_assert (ctx);
+
+ ctx->mactotei = (cl_mactotei_table_t *) table;
+}
+
+/**
+ * Release the complete table from the memory.
+ *
+ * \param ctx the convergence layer context
+ */
+void cl_mactotei_release_table (cl_t *ctx)
+{
+ dbg_assert (ctx);
+ memset (table, 0, sizeof (table));
+ ctx->mactotei = NULL;
+}
+
+void
+test_suite_sta_mgr (test_t test);
+
+void
+test_suite_net (test_t test);
+
+void
+test_suite_sta_own (test_t test);
+
+void
+test_suite_station (test_t test);
+
+int
+main (int argc, char **argv)
+{
+ test_t test;
+ test_init (test, argc, argv);
+ test_suite_sta_mgr (test);
+ test_suite_net (test);
+ test_suite_sta_own (test);
+ test_suite_station (test);
+
+ test_case_begin (test, "Memory allocation");
+ test_begin (test, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/cesar/cp/eoc/sta/mgr/test/test_sta_mgr.h b/cesar/cp/eoc/sta/mgr/test/test_sta_mgr.h
new file mode 100644
index 0000000000..fa00768521
--- /dev/null
+++ b/cesar/cp/eoc/sta/mgr/test/test_sta_mgr.h
@@ -0,0 +1,54 @@
+#ifndef cp_sta_mgr_test_test_sta_mgr_h
+#define cp_sta_mgr_test_test_sta_mgr_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/sta/mgr/test/test_sta_mgr.h
+ * \brief Test environment.
+ * \ingroup cp_sta_mgr
+ */
+#include "lib/test.h"
+#include "cp/cp.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/core/core.h"
+
+#include "mac/common/ntb.h"
+#include "mac/common/timings.h"
+#include "mac/sar/sar.h"
+#include "cl/cl.h"
+
+/* Override includes. */
+#include "mac/sar/inc/context.h"
+#include "cl/inc/context.h"
+#include "cp/inc/context.h"
+
+#include "cl/cl_mactotei.h"
+
+struct cl_mactotei_t
+{
+ mac_t mac;
+ cp_tei_t tei;
+ uint tag;
+};
+typedef struct cl_mactotei_t cl_mactotei_t;
+
+/**
+ * Initialise all necessary data for the station manager test.
+ * \param cp the control plane override structure.
+ */
+void
+test_sta_mgr_init (cp_t *cp);
+
+/**
+ * Uninitialise the environment of test for station manager.
+ * \param cp the control plane override structure.
+ */
+void
+test_sta_mgr_uninit (cp_t *cp);
+
+#endif /* cp_sta_mgr_test_test_sta_mgr_h */
diff --git a/cesar/cp/fsm/Config b/cesar/cp/fsm/Config
index 23ee136ab4..81631bb2cb 100644
--- a/cesar/cp/fsm/Config
+++ b/cesar/cp/fsm/Config
@@ -1 +1,2 @@
CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp.fsm"
+CONFIG_CP_EOC_CCO_FSM = n
diff --git a/cesar/cp/fsm/src/fsm.c b/cesar/cp/fsm/src/fsm.c
index 8086b0ee27..8622ac123a 100644
--- a/cesar/cp/fsm/src/fsm.c
+++ b/cesar/cp/fsm/src/fsm.c
@@ -18,6 +18,7 @@
#include "inc/tables.h"
#include "cp/sta/core/core.h"
+#include "hal/arch/arch.h"
void
cp_fsm_init (cp_t *ctx)
@@ -200,24 +201,32 @@ cp_fsm_process_urgent (cp_t *ctx)
uint i;
dbg_assert (ctx);
dbg_assert (!ctx->fsm.handling_urgent_event);
+ cp_fsm_event_t *e = NULL;
+ bool signal = false;
+ arch_dsr_lock ();
if (ctx->fsm.urgent_head)
{
/* Extract event from queue. */
- cp_fsm_event_t *e = ctx->fsm.urgent_head;
+ e = ctx->fsm.urgent_head;
ctx->fsm.urgent_head = e->next;
if (!e->next)
dbg_invalid_ptr (ctx->fsm.urgent_tail);
dbg_assert (e->type < CP_FSM_EVENT_TYPE_NB);
dbg_assert (e->handler);
- /* Handle event. */
+ /* Set flag again if there is another event pending. */
+ signal = (ctx->fsm.urgent_head);
+ }
+ arch_dsr_unlock ();
+ /* Handle event. */
+ if (e)
+ {
CP_TRACE (FSM_HANDLE_URGENT_EVENT, e->type);
for (i = 0; i < CP_FSM_INITIAL_NB; i++)
cp_fsm_handled_urgent_event (ctx, e, i);
/* Release event. */
slab_release (e);
}
- /* Set flag again if there is another event pending. */
- if (ctx->fsm.urgent_head)
+ if (signal)
cp_sta_core_signal_fsm_urgent_event (ctx);
}
diff --git a/cesar/cp/fsm/src/fsm/cp_eoc_cco.fsm b/cesar/cp/fsm/src/fsm/cp_eoc_cco.fsm
new file mode 100644
index 0000000000..74981908f8
--- /dev/null
+++ b/cesar/cp/fsm/src/fsm/cp_eoc_cco.fsm
@@ -0,0 +1,211 @@
+Control Plane CCO FSM
+ CCO FSM for control plane
+
+States:
+ STOPPED
+ STARTED
+ POWER_ON
+ CCO
+ BCCO
+ STOPPING
+
+Events:
+ BEACON
+ BEACON_NOT_RECEIVED
+ BEACON_TIMER_EXPIRES
+ BEACON_WITH_SAME_NID
+ HOIP_EXPIRED
+ HANDOVER_DISCOVERED_STA
+ HANDOVER_DISCOVER_PROCESS_DONE
+ nek_timeout
+ cco_change_nek
+ nek_request
+ to_leave
+ cco__snid_conflict
+ to_poweron
+ to_stop
+ rx_beacon
+ no_beacons
+ net_list_empty
+ sta_status_changed
+ stopped
+ first_com_with_assoc_sta
+ leave_remove_delay
+ discover_info_updated
+ whoru_timeout
+ sta_not_polled
+
+ DRV_MAC_STOP
+ MULTI_STA_MME
+
+ DRV_STA_SET_MAC_ADDR_REQ
+ DRV_STA_SET_CCO_PREF_REQ
+ DRV_STA_SET_WAS_CCO_REQ
+ DRV_STA_SET_NPW_REQ
+ DRV_STA_SET_DPW_REQ
+ DRV_STA_SET_SL_REQ
+ DRV_STA_SET_NID_REQ
+ DRV_STA_SET_M_STA_HFID_REQ
+ DRV_STA_SET_U_STA_HFID_REQ
+ DRV_STA_SET_AVLN_HFID_REQ
+ DRV_STA_SET_TONEMASK_REQ
+ DRV_STA_MAC_START_REQ
+ DRV_STA_MAC_STOP_REQ
+ DRV_STA_SC_REQ
+ DRV_STA_SET_KEY_REQ
+ DRV_STA_SET_DAK_REQ
+ DRV_STA_GET_KEY_REQ
+ DRV_STA_STATUS_REQ
+ DRV_STA_SET_CONFIG_REQ
+ DRV_EOC_STA_SET_SLAVE_CONFIG_REQ
+ DRV_EOC_STA_SET_EOC_CONFIG_REQ
+ DRV_MCAST_SET_LIST_REQ
+
+ VS_GET_TONEMAP_REQ
+ VS_GET_SNR_REQ
+ VS_GET_LINK_STATS_REQ
+ VS_GET_SPECTRUM_REQ
+ VS_GET_AMP_MAP_REQ
+ VS_GET_STATS_REQ
+ VS_GET_CE_STATS_REQ
+
+ VS_EOC_GET_TOPO_REQ
+ VS_EOC_CCO_SET_WL_REQ
+ VS_EOC_CCO_GET_WL_REQ
+ VS_EOC_CCO_SET_OUT_LEV_IND
+ VS_EOC_SET_PORTS_REQ
+ VS_EOC_GET_PORTS_REQ
+ VS_EOC_SET_SERVICES_REQ
+ VS_EOC_GET_SERVICES_REQ
+ VS_EOC_GET_INFO_REQ
+ VS_EOC_DIAGNOSTIC_INFO_REQ
+ VS_EOC_GET_REAL_TIME_STATS_REQ
+
+ IMAC_GET_DISCOVER_LIST_REQ
+
+ CC_DISCOVER_LIST_REQ
+ CC_DISCOVER_LIST_CNF
+ CC_WHO_RU_REQ
+ CC_WHO_RU_CNF
+ CC_ASSOC_REQ
+ CC_ASSOC_CNF
+ CC_LEAVE_REQ
+ CC_LEAVE_CNF
+ CC_LEAVE_IND
+ CC_LEAVE_RSP
+ CC_SET_TEI_MAP_REQ
+ CC_SET_TEI_MAP_IND
+ CC_RELAY_REQ
+ CC_RELAY_IND
+ CC_HANDOVER_CNF
+ CC_HANDOVER_REQ
+ CC_HANDOVER_INFO_IND
+ CC_HANDOVER_INFO_RSP
+ CM_UNASSOCIATED_STA_IND
+ CM_SET_KEY_REQ
+ CM_SET_KEY_CNF
+ CM_SET_KEY_REQ_PID1
+ CM_SET_KEY_CNF_PID1
+ CM_SET_KEY_REQ_PID3
+ CM_SET_KEY_CNF_PID3
+ CM_GET_KEY_REQ
+ CM_GET_KEY_CNF
+ CM_GET_KEY_REQ_PID0
+ CM_GET_KEY_CNF_PID0
+ CM_GET_KEY_REQ_PID3
+ CM_GET_KEY_CNF_PID3
+ CM_SC_JOIN_REQ
+ CM_SC_JOIN_CNF
+ CM_CHAN_EST_IND
+ CM_TM_UPDATE_IND
+ CM_AMP_MAP_REQ
+ CM_AMP_MAP_CNF
+ CM_BRG_INFO_REQ
+ CM_BRG_INFO_CNF
+ CM_STA_CAP_REQ
+ CM_STA_CAP_CNF
+ CM_NW_INFO_REQ
+ CM_NW_INFO_CNF
+ CM_NW_STATS_REQ
+ CM_NW_STATS_CNF
+ CM_LINK_STATS_REQ
+ CM_HFID_REQ
+ CM_HFID_CNF
+ CM_MME_ERROR_IND
+
+STOPPED:
+ DRV_STA_SET_MAC_ADDR_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req]
+ DRV_STA_SET_CCO_PREF_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req]
+ DRV_STA_SET_WAS_CCO_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_was_cco_req]
+ DRV_STA_SET_DPW_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_dpw_req]
+ DRV_STA_SET_NPW_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_npw_req]
+ DRV_STA_SET_NID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_nid_req]
+ DRV_STA_SET_M_STA_HFID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req]
+ DRV_STA_SET_U_STA_HFID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req]
+ DRV_STA_SET_AVLN_HFID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req]
+ DRV_STA_SET_SL_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_sl_req]
+ DRV_STA_SET_TONEMASK_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_tonemask_req]
+ DRV_STA_SET_KEY_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_key_req]
+ DRV_STA_SET_DAK_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_dak_req]
+ DRV_STA_MAC_START_REQ -> STARTED [cp_sta_action_drv__stopped__drv_sta_mac_start_req]
+ DRV_STA_SET_CONFIG_REQ -> . [cp_sta_action_drv__drv_sta_set_config_req]
+ DRV_EOC_STA_SET_SLAVE_CONFIG_REQ -> . [cp_sta_action_drv__drv_sta_set_slave_config_req]
+ DRV_EOC_STA_SET_EOC_CONFIG_REQ -> . [cp_sta_action_drv__drv_sta_set_eoc_config_req]
+
+STARTED:
+ to_poweron -> POWER_ON [cp_cco_action_poweron__idle__to_poweron]
+ VS_GET_TONEMAP_REQ -> . [cp_sta_action_vs__started__vs_get_tonemap_req]
+ VS_GET_SNR_REQ -> . [cp_sta_action_vs__started__vs_get_snr_req]
+
+POWER_ON:
+ BEACON_TIMER_EXPIRES -> . [cp_beacon_beacon_not_received]
+ BEACON_NOT_RECEIVED -> CCO [cp_eoc_cco_action_send_central_beacon]
+ rx_beacon -> BCCO [cp_eoc_cco_action__power_on_rx_beacon]
+
+CCO:
+ DRV_STA_MAC_STOP_REQ -> STOPPING [cp_sta_action_drv__started__drv_sta_mac_stop_req]
+ DRV_STA_GET_KEY_REQ -> . [cp_sta_action_drv__drv_sta_get_key_req]
+ VS_EOC_CCO_GET_WL_REQ -> . [cp_eoc_cco_action_vs__stopped__vs_cco_get_wl_req]
+ VS_EOC_CCO_SET_WL_REQ -> . [cp_eoc_cco_action_vs__stopped__vs_cco_set_wl_req]
+ VS_EOC_SET_PORTS_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_ports_req]
+ VS_EOC_GET_PORTS_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_ports_req]
+ VS_EOC_SET_SERVICES_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_set_services_req]
+ VS_EOC_GET_SERVICES_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_services_req]
+ VS_EOC_GET_INFO_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_info_req]
+ VS_EOC_DIAGNOSTIC_INFO_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_diagnostic_info_req]
+ VS_EOC_GET_REAL_TIME_STATS_REQ -> . [cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req]
+ BEACON_TIMER_EXPIRES -> . [cp_eoc_cco_action_send_central_beacon]
+ MULTI_STA_MME -> . [cp_eoc_cco_action_event_dispatch]
+ CM_CHAN_EST_IND -> . [ce_tx_process__cm_chan_est_ind]
+ CM_TM_UPDATE_IND -> . [ce_tx_process__cm_update_tm_ind]
+ VS_EOC_GET_TOPO_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req]
+ first_com_with_assoc_sta -> . [NULL]
+ PREV: cp_sta_action_bridge_first_com
+ CM_BRG_INFO_CNF -> . [cp_sta_action_process_cm_brg_info_cnf]
+ CM_BRG_INFO_REQ -> . [cp_sta_action_process_cm_brg_info_req]
+ VS_GET_TONEMAP_REQ -> . [cp_sta_action_vs__started__vs_get_tonemap_req]
+ VS_GET_SNR_REQ -> . [cp_sta_action_vs__started__vs_get_snr_req]
+ CM_NW_STATS_REQ -> . [cp_sta_action_process_cm_nw_stats_req]
+ CM_LINK_STATS_REQ -> . [cp_sta_action_process_cm_link_stats_req]
+ CM_NW_INFO_REQ -> . [cp_sta_action_process_cm_nw_info_req]
+ CM_SET_KEY_CNF -> . [cp_eoc_cco_action__set_key_cnf]
+ nek_timeout:no -> . [cp_eoc_cco_action_nek_change_timeout]
+ nek_timeout:yes -> .
+ leave_remove_delay -> . [cp_eoc_cco_action__cco__leave_remove_timeout]
+ VS_GET_STATS_REQ -> . [cp_sta_action_vs__started__vs_get_stats_req]
+ CM_STA_CAP_REQ -> . [cp_sta_action_process_cm_sta_cap_req]
+ cco_change_nek -> . [cp_eoc_cco_action_nek_provide]
+ VS_GET_CE_STATS_REQ -> . [cp_sta_action_vs__started__vs_get_ce_stats_req]
+
+BCCO:
+ DRV_STA_MAC_STOP_REQ -> STOPPING [cp_eoc_cco_action__bcco_drv_mac_stop]
+ BEACON_NOT_RECEIVED -> CCO [cp_eoc_cco_action__bcco_no_beacons]
+ VS_EOC_GET_TOPO_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req]
+ VS_GET_TONEMAP_REQ -> . [cp_sta_action_vs__started__vs_get_tonemap_req]
+ VS_GET_SNR_REQ -> . [cp_sta_action_vs__started__vs_get_snr_req]
+
+STOPPING:
+ VS_EOC_GET_TOPO_REQ -> . [cp_eoc_cco_action_vs_eoc__cco__vs_eoc_get_topo_req]
+ to_stop -> . [cp_sta_action_poweron__many__to_idle]
+ stopped -> STOPPED [cp_sta_action_drv__stopping__stopped]
+ send DRV_STA_MAC_STOP.CNF
diff --git a/cesar/cp/fsm/src/fsm/cp_eoc_sta.fsm b/cesar/cp/fsm/src/fsm/cp_eoc_sta.fsm
new file mode 100644
index 0000000000..b4d7bbffca
--- /dev/null
+++ b/cesar/cp/fsm/src/fsm/cp_eoc_sta.fsm
@@ -0,0 +1,248 @@
+Control Plane STA FSM
+ STA FSM for control plane.
+
+States:
+ STOPPED
+ STARTED
+ STOPPING
+ DETECTING_BEACON
+ UNASSOCIATED [enter=cp_sta_action_unassoc__start_retry_timer leave=cp_sta_action_unassoc__stop_retry_timer]
+ ASSOCIATING [enter=cp_sta_action_assoc__start_retry_timer leave=cp_sta_action_assoc__stop_retry_timer]
+ ASSOCIATED [enter=cp_sta_action_assoc__start_retry_timer leave=cp_sta_action_assoc__stop_retry_timer]
+ AUTHENTICATED
+ SLEEP_UNASSOCIATED
+ SLEEP_AUTHENTICATED
+
+Events:
+ BEACON
+ BEACON_NOT_RECEIVED
+ BEACON_TIMER_EXPIRES
+ BEACON_WITH_SAME_NID
+ HOIP_EXPIRED
+ HANDOVER_DISCOVERED_STA
+ HANDOVER_DISCOVER_PROCESS_DONE
+ to_poweron
+ to_stop
+ stopped
+ nd_beacon
+ timeout_associating
+ timeout_unassociating
+ nd_beacon_timeout
+ no_beacons
+ enter_sleep_unassociated
+ retry_unassociated
+ exit_sleep_unassociated
+ sleep_enter_cnf
+ sleep_exit_rsp
+ encrypt_payload_rsp
+ cco_change_nek
+ nek_request
+ to_leave
+ first_com_with_assoc_sta
+ sta_not_polled
+ discover_info_updated
+ whoru_timeout
+ cco__snid_conflict
+
+ DRV_STA_SET_MAC_ADDR_REQ
+ DRV_STA_SET_CCO_PREF_REQ
+ DRV_STA_SET_WAS_CCO_REQ
+ DRV_STA_SET_NPW_REQ
+ DRV_STA_SET_DPW_REQ
+ DRV_STA_SET_SL_REQ
+ DRV_STA_SET_NID_REQ
+ DRV_STA_SET_M_STA_HFID_REQ
+ DRV_STA_SET_U_STA_HFID_REQ
+ DRV_STA_SET_AVLN_HFID_REQ
+ DRV_STA_SET_TONEMASK_REQ
+ DRV_STA_MAC_START_REQ
+ DRV_STA_MAC_STOP_REQ
+ DRV_STA_SC_REQ
+ DRV_STA_SET_KEY_REQ
+ DRV_STA_SET_DAK_REQ
+ DRV_STA_GET_KEY_REQ
+ DRV_STA_STATUS_REQ
+ DRV_STA_SET_CONFIG_REQ
+ DRV_EOC_STA_SET_SLAVE_CONFIG_REQ
+ DRV_EOC_STA_SET_EOC_CONFIG_REQ
+ DRV_MCAST_SET_LIST_REQ
+
+ VS_GET_TONEMAP_REQ
+ VS_GET_SNR_REQ
+ VS_GET_LINK_STATS_REQ
+ VS_GET_SPECTRUM_REQ
+ VS_GET_AMP_MAP_REQ
+ VS_GET_STATS_REQ
+ VS_GET_CE_STATS_REQ
+ VS_EOC_GET_TOPO_REQ
+ VS_EOC_CCO_SET_WL_REQ
+ VS_EOC_CCO_GET_WL_REQ
+ VS_EOC_CCO_SET_OUT_LEV_IND
+ VS_EOC_SET_PORTS_REQ
+ VS_EOC_GET_PORTS_REQ
+ VS_EOC_SET_SERVICES_REQ
+ VS_EOC_GET_SERVICES_REQ
+ VS_EOC_GET_INFO_REQ
+ VS_EOC_DIAGNOSTIC_INFO_REQ
+ VS_EOC_GET_REAL_TIME_STATS_REQ
+ IMAC_GET_DISCOVER_LIST_REQ
+
+ CC_DISCOVER_LIST_REQ
+ CC_DISCOVER_LIST_CNF
+ CC_WHO_RU_REQ
+ CC_WHO_RU_CNF
+ CC_ASSOC_REQ
+ CC_ASSOC_CNF
+ CC_LEAVE_REQ
+ CC_LEAVE_CNF
+ CC_LEAVE_IND
+ CC_LEAVE_RSP
+ CC_SET_TEI_MAP_REQ
+ CC_SET_TEI_MAP_IND
+ CC_RELAY_REQ
+ CC_RELAY_IND
+ CC_HANDOVER_CNF
+ CC_HANDOVER_REQ
+ CC_HANDOVER_INFO_IND
+ CC_HANDOVER_INFO_RSP
+ CM_UNASSOCIATED_STA_IND
+ CM_SET_KEY_REQ
+ CM_SET_KEY_CNF
+ CM_SET_KEY_REQ_PID1
+ CM_SET_KEY_CNF_PID1
+ CM_SET_KEY_REQ_PID3
+ CM_SET_KEY_CNF_PID3
+ CM_GET_KEY_REQ
+ CM_GET_KEY_CNF
+ CM_GET_KEY_REQ_PID0
+ CM_GET_KEY_CNF_PID0
+ CM_GET_KEY_REQ_PID3
+ CM_GET_KEY_CNF_PID3
+ CM_SC_JOIN_REQ
+ CM_SC_JOIN_CNF
+ CM_CHAN_EST_IND
+ CM_TM_UPDATE_IND
+ CM_AMP_MAP_REQ
+ CM_AMP_MAP_CNF
+ CM_BRG_INFO_REQ
+ CM_BRG_INFO_CNF
+ CM_STA_CAP_REQ
+ CM_STA_CAP_CNF
+ CM_NW_INFO_REQ
+ CM_NW_INFO_CNF
+ CM_NW_STATS_REQ
+ CM_NW_STATS_CNF
+ CM_LINK_STATS_REQ
+ CM_HFID_REQ
+ CM_HFID_CNF
+ CM_MME_ERROR_IND
+
+STOPPED:
+ DRV_STA_SET_MAC_ADDR_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_mac_addr_req]
+ DRV_STA_SET_CCO_PREF_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_cco_pref_req]
+ DRV_STA_SET_WAS_CCO_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_was_cco_req]
+ DRV_STA_SET_DPW_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_dpw_req]
+ DRV_STA_SET_NPW_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_npw_req]
+ DRV_STA_SET_NID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_nid_req]
+ DRV_STA_SET_M_STA_HFID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_m_sta_hfid_req]
+ DRV_STA_SET_U_STA_HFID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_u_sta_hfid_req]
+ DRV_STA_SET_AVLN_HFID_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_avln_hfid_req]
+ DRV_STA_SET_SL_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_sl_req]
+ DRV_STA_SET_TONEMASK_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_tonemask_req]
+ DRV_STA_SET_KEY_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_key_req]
+ DRV_STA_SET_DAK_REQ -> . [cp_sta_action_drv__stopped__drv_sta_set_dak_req]
+ DRV_STA_MAC_START_REQ -> STARTED [cp_sta_action_drv__stopped__drv_sta_mac_start_req]
+ DRV_STA_SET_CONFIG_REQ -> . [cp_sta_action_drv__drv_sta_set_config_req]
+ DRV_EOC_STA_SET_SLAVE_CONFIG_REQ -> . [cp_sta_action_drv__drv_sta_set_slave_config_req]
+ DRV_EOC_STA_SET_EOC_CONFIG_REQ -> . [cp_sta_action_drv__drv_sta_set_eoc_config_req]
+
+STARTED:
+ to_poweron -> DETECTING_BEACON [cp_sta_action_poweron__idle__to_poweron]
+ VS_GET_TONEMAP_REQ -> . [cp_sta_action_vs__started__vs_get_tonemap_req]
+ VS_GET_SNR_REQ -> . [cp_sta_action_vs__started__vs_get_snr_req]
+
+DETECTING_BEACON:
+ BEACON -> . [cp_eoc_sta_action_detect__beacon_received]
+ nd_beacon -> ASSOCIATING [cp_eoc_sta_action_assoc__detecting_detected]
+ nd_beacon_timeout -> UNASSOCIATED [cp_eoc_sta_action_assoc__detecting_timeout]
+ no_beacons -> . [cp_eoc_sta_action_sta_clear_status]
+
+UNASSOCIATED:
+ enter_sleep_unassociated -> SLEEP_UNASSOCIATED [cp_eoc_sta_action_sleep__unassociated_enter_sleep]
+ retry_unassociated -> DETECTING_BEACON [NULL]
+ timeout_unassociating -> DETECTING_BEACON [NULL]
+
+ASSOCIATING:
+ timeout_associating: retry -> DETECTING_BEACON [cp_eoc_sta_action_assoc__associating_timeout]
+ timeout_associating: no_retry -> UNASSOCIATED
+ CC_ASSOC_CNF: success -> ASSOCIATED [cp_eoc_sta_action_assoc__associating_cnf]
+ CC_ASSOC_CNF: unsuccess -> UNASSOCIATED
+ CC_ASSOC_CNF: unrelated -> UNASSOCIATED
+ no_beacons -> UNASSOCIATED [cp_eoc_sta_action_assoc__associating_no_beacons]
+
+ASSOCIATED:
+ CM_GET_KEY_CNF: all_keys_granted -> AUTHENTICATED [cp_eoc_sta_action_assoc__associated_key_cnf]
+ CM_GET_KEY_CNF: granted_more_to_grant -> .
+ CM_GET_KEY_CNF: not_granted -> UNASSOCIATED
+ CM_GET_KEY_CNF: unrelated -> UNASSOCIATED
+ encrypt_payload_rsp -> UNASSOCIATED [cp_eoc_sta_action_assoc__associated_encrypt_payload_rsp]
+ no_beacons -> UNASSOCIATED [cp_eoc_sta_action_assoc__associated_no_beacons]
+ timeout_associating -> UNASSOCIATED [cp_eoc_sta_action_assoc__associated_timeout]
+ CC_LEAVE_IND: ok -> DETECTING_BEACON [cp_eoc_sta_action_assoc__associated_leave]
+ send CC_LEAVE.RSP
+ CC_LEAVE_IND: nok -> .
+
+AUTHENTICATED:
+ CM_GET_KEY_CNF -> . [cp_eoc_sta_action_auth__authenticated_key_cnf]
+ sleep_enter_cnf -> SLEEP_AUTHENTICATED [cp_eoc_sta_action_sleep__authenticated_sleep_enter]
+ no_beacons -> DETECTING_BEACON [cp_eoc_sta_action_assoc__authenticated_no_beacons]
+ CC_LEAVE_IND: ok -> DETECTING_BEACON [cp_eoc_sta_action_assoc__authenticated_leave]
+ send CC_LEAVE.RSP
+ CC_LEAVE_IND: nok -> .
+ DRV_STA_MAC_STOP_REQ -> STOPPING [cp_sta_action_drv__started__drv_sta_mac_stop_req]
+ CM_SET_KEY_REQ -> . [cp_eoc_sta_action_auth__authenticated_set_key_req]
+ VS_EOC_CCO_SET_OUT_LEV_IND -> . [cp_eoc_sta_action_auth__authenticated_set_out_lev]
+ CM_STA_CAP_REQ -> . [cp_sta_action_process_cm_sta_cap_req]
+ VS_GET_TONEMAP_REQ -> . [cp_sta_action_vs__started__vs_get_tonemap_req]
+ VS_GET_SNR_REQ -> . [cp_sta_action_vs__started__vs_get_snr_req]
+ sta_not_polled -> DETECTING_BEACON [cp_eoc_sta_action_sta_clear_status]
+ CM_LINK_STATS_REQ -> . [cp_sta_action_process_cm_link_stats_req]
+ CM_NW_INFO_REQ -> . [cp_sta_action_process_cm_nw_info_req]
+ CM_NW_STATS_REQ -> . [cp_sta_action_process_cm_nw_stats_req]
+ VS_GET_STATS_REQ -> . [cp_sta_action_vs__started__vs_get_stats_req]
+ VS_GET_CE_STATS_REQ -> . [cp_sta_action_vs__started__vs_get_ce_stats_req]
+
+DETECTING_BEACON, UNASSOCIATED, ASSOCIATING, ASSOCIATED, AUTHENTICATED, SLEEP_AUTHENTICATED:
+ BEACON_TIMER_EXPIRES -> . [cp_beacon_beacon_not_received]
+ BEACON_NOT_RECEIVED -> . [cp_eoc_sta_action_assoc__beacon_not_received]
+ VS_EOC_GET_INFO_REQ -> . [cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_info_req]
+ VS_EOC_DIAGNOSTIC_INFO_REQ -> . [cp_eoc_sta_action_vs_eoc__sta__vs_eoc_diagnostic_info_req]
+ VS_EOC_GET_REAL_TIME_STATS_REQ -> . [cp_eoc_sta_action_vs_eoc__sta__vs_eoc_get_real_time_stats_req]
+
+ASSOCIATING:
+ BEACON -> . [cp_eoc_sta_action_assoc__beacon_received]
+
+ASSOCIATED, AUTHENTICATED, SLEEP_AUTHENTICATED:
+ BEACON -> . [cp_eoc_sta_action_auth__beacon_received]
+
+ASSOCIATED, AUTHENTICATED:
+ CM_CHAN_EST_IND -> . [ce_tx_process__cm_chan_est_ind]
+ CM_TM_UPDATE_IND -> . [ce_tx_process__cm_update_tm_ind]
+
+AUTHENTICATED:
+ first_com_with_assoc_sta -> . [NULL]
+ cp_sta_action_bridge_first_com
+ CM_BRG_INFO_CNF -> . [cp_sta_action_process_cm_brg_info_cnf]
+ CM_BRG_INFO_REQ -> . [cp_sta_action_process_cm_brg_info_req]
+
+SLEEP_UNASSOCIATED:
+ exit_sleep_unassociated -> UNASSOCIATED [cp_eoc_sta_action_sleep__sleep_unassociated_exit_sleep]
+
+SLEEP_AUTHENTICATED:
+ sleep_exit_rsp -> AUTHENTICATED [cp_eoc_sta_action_sleep__sleep_authenticated_exit]
+ no_beacons -> UNASSOCIATED [cp_eoc_sta_action_assoc__sleep_authenticated_no_beacons]
+
+STOPPING:
+ to_stop -> . [cp_sta_action_poweron__many__to_idle]
+ stopped -> STOPPED [cp_sta_action_drv__stopping__stopped]
+ send DRV_STA_MAC_STOP.CNF
diff --git a/cesar/cp/fsm/src/tables.c b/cesar/cp/fsm/src/tables.c
index e0d749aca9..613b892dc1 100644
--- a/cesar/cp/fsm/src/tables.c
+++ b/cesar/cp/fsm/src/tables.c
@@ -15,11 +15,19 @@
#include "fsm.h"
#include "inc/tables.h"
+#include "config/cp/eoc/cco/fsm.h"
+#if CONFIG_CP_EOC_CCO_FSM
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/sta/action/action.h"
+#else
#include "cp/sta/action/action.h"
-#include "cp/beacon/beacon.h"
#include "cp/cco/action/cco_action.h"
+#endif
+
+#include "cp/beacon/beacon.h"
#include "ce/tx/tx.h"
+
/* CE TX stub. */
void
ce_tx_process__cm_chan_est_ind (cp_t *ctx, cp_mme_rx_t *mme)
diff --git a/cesar/cp/fsm/test/utest/Makefile b/cesar/cp/fsm/test/utest/Makefile
index 5f1381e948..c68a2466f7 100644
--- a/cesar/cp/fsm/test/utest/Makefile
+++ b/cesar/cp/fsm/test/utest/Makefile
@@ -5,6 +5,7 @@ INCLUDES = cp/fsm/test/utest cp/fsm/test/utest/override
HOST_PROGRAMS = test_fsm
test_fsm_SOURCES = test_fsm.c fsm_stub.c actions.c
test_fsm_MODULES = lib lib/scenario cp/fsm cp
+test_fsm_CONFIG_MODULES = cp/sta/mgr mac/common
cp_fsm_MODULE_SOURCES = fsm.c events.c
cp_MODULE_MODULES =
cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
diff --git a/cesar/cp/inc/context.h b/cesar/cp/inc/context.h
index 828bee4b9e..e013fccc78 100644
--- a/cesar/cp/inc/context.h
+++ b/cesar/cp/inc/context.h
@@ -53,6 +53,8 @@
#include "cp/msg/inc/context.h"
#include "cp/fsm/inc/context.h"
#include "ce/tx/inc/tx.h"
+#include "cp/eoc/cco/bw/inc/bw.h"
+#include "config/cp/eoc.h"
enum cp_handover_reason_t
{
@@ -162,6 +164,10 @@ struct cp_t
/** Context of the CE in RX. */
ce_rx_t *ce_rx;
+ /** EoC scheduling context */
+#if CONFIG_CP_EOC_SCHEDULER
+ cp_eoc_cco_bw_sched_t schedule;
+#endif
/** Context of the bsu. */
bsu_t *bsu;
diff --git a/cesar/cp/inc/trace.h b/cesar/cp/inc/trace.h
index 400207100a..733a9dafec 100644
--- a/cesar/cp/inc/trace.h
+++ b/cesar/cp/inc/trace.h
@@ -50,6 +50,10 @@ enum
CP_TRACE_CCO_TEI_EXPIRED,
CP_TRACE_CE_TX_NEW_TONEMAP,
CP_TRACE_CE_TX_NEW_DEFAULT_TMI,
+#if CONFIG_CP_STA_MGR_EOC
+ CP_TRACE_MULTI_STA_FSM_CHANGE_STATE,
+ CP_TRACE_MULTI_STA_ASSOC,
+#endif
CP_TRACE_CE_TX_DEFAULT_TMI_UNAVAILABLE,
CP_TRACE_CE_TX_TMI_AVAILABLE_LIST,
CP_TRACE_CE_TX_TM_EXPIRATION,
diff --git a/cesar/cp/mme.h b/cesar/cp/mme.h
index c8d96e5dca..8c554ff0dc 100644
--- a/cesar/cp/mme.h
+++ b/cesar/cp/mme.h
@@ -89,52 +89,69 @@
#define CM_RSVD_MAX 0x7FFC
/* MMTYPE base values for DRV MME messages. */
-#define DRV_STA_SET_MAC_ADDR 0xB000
-#define DRV_STA_SET_CCO_PREF 0xB004
-#define DRV_STA_SET_WAS_CCO 0xB008
-#define DRV_STA_SET_NPW 0xB00C /* TODO to be removed #465*/
-#define DRV_STA_SET_DPW 0xB010 /* TODO to be removed #465*/
-#define DRV_STA_SET_SL 0xB014
-#define DRV_STA_SET_M_STA_HFID 0xB018
-#define DRV_STA_SET_U_STA_HFID 0xB01C
-#define DRV_STA_SET_AVLN_HFID 0xB020
-#define DRV_STA_SET_TONEMASK 0xB024
-#define DRV_STA_MAC_START 0xB028
-#define DRV_STA_MAC_STOP 0xB02C
-#define DRV_STA_SET_NID 0xB030
-#define DRV_STA_SC 0xB034
-#define DRV_STA_STATUS 0xB03C
-#define DRV_STA_SET_KEY 0xB040
-#define DRV_STA_GET_KEY 0xB044
-#define DRV_STA_SET_DAK 0xB048
-#define DRV_STA_SET_CONFIG 0xB04C
-#define DRV_MCAST_SET_LIST 0xB054
-#define DRV_MIN 0xB000
-#define DRV_MAX 0xBFFF
+#define DRV_STA_SET_MAC_ADDR 0xB000
+#define DRV_STA_SET_CCO_PREF 0xB004
+#define DRV_STA_SET_WAS_CCO 0xB008
+#define DRV_STA_SET_NPW 0xB00C /* TODO to be removed #465*/
+#define DRV_STA_SET_DPW 0xB010 /* TODO to be removed #465*/
+#define DRV_STA_SET_SL 0xB014
+#define DRV_STA_SET_M_STA_HFID 0xB018
+#define DRV_STA_SET_U_STA_HFID 0xB01C
+#define DRV_STA_SET_AVLN_HFID 0xB020
+#define DRV_STA_SET_TONEMASK 0xB024
+#define DRV_STA_MAC_START 0xB028
+#define DRV_STA_MAC_STOP 0xB02C
+#define DRV_STA_SET_NID 0xB030
+#define DRV_STA_SC 0xB034
+#define DRV_STA_STATUS 0xB03C
+#define DRV_STA_SET_KEY 0xB040
+#define DRV_STA_GET_KEY 0xB044
+#define DRV_STA_SET_DAK 0xB048
+#define DRV_STA_SET_CONFIG 0xB04C
+#define DRV_MCAST_SET_LIST 0xB054
+#define DRV_EOC_STA_SET_SLAVE_CONFIG 0xB0A8
+#define DRV_EOC_STA_SET_EOC_CONFIG 0xB0AC
+#define DRV_MIN 0xB000
+#define DRV_MAX 0xBFFF
/* MMTYPE base values for VS MME messages. */
-#define VS_GET_VERSION 0xA000
-#define VS_RESET 0xA008
-#define VS_GET_MFG_INFO 0xA00C
-#define VS_GET_NVRAM 0xA010
-#define VS_GET_LOOPBACK 0xA014
-#define VS_SET_LOOPBACK 0xA018
-#define VS_GET_TONEMASK 0xA01C
-#define VS_GET_ETH_PHY 0xA020
-#define VS_ETH_STATS 0xA024
-#define VS_PLC_STATS 0xA028
-#define VS_SNIFFER 0xA02C
-#define VS_GET_STATUS 0xA030
-#define VS_GET_TONEMAP 0xA034
-#define VS_GET_SNR 0xA038
-#define VS_GET_SPECTRUM 0xA03C
-#define VS_GET_LINK_STATS 0xA040
-#define VS_GET_AMP_MAP 0xA044
-#define VS_GET_STATS 0xA048
-#define VS_GET_CE_STATS 0xA074
-#define IMAC_GET_DISCOVER_LIST 0xA800
-#define VS_MIN 0xA000
-#define VS_MAX (DRV_MIN - 1)
+#define VS_GET_VERSION 0xA000
+#define VS_RESET 0xA008
+#define VS_GET_MFG_INFO 0xA00C
+#define VS_GET_NVRAM 0xA010
+#define VS_GET_LOOPBACK 0xA014
+#define VS_SET_LOOPBACK 0xA018
+#define VS_GET_TONEMASK 0xA01C
+#define VS_GET_ETH_PHY 0xA020
+#define VS_ETH_STATS 0xA024
+#define VS_PLC_STATS 0xA028
+#define VS_SNIFFER 0xA02C
+#define VS_GET_STATUS 0xA030
+#define VS_GET_TONEMAP 0xA034
+#define VS_GET_SNR 0xA038
+#define VS_GET_SPECTRUM 0xA03C
+#define VS_GET_LINK_STATS 0xA040
+#define VS_GET_AMP_MAP 0xA044
+#define VS_GET_STATS 0xA048
+#define VS_GET_CE_STATS 0xA074
+
+#define VS_EOC_GET_TOPO 0xA08C
+#define VS_EOC_CCO_SET_WL 0xA094
+#define VS_EOC_CCO_GET_WL 0xA098
+#define VS_EOC_CCO_SET_OUT_LEV 0xA09C
+#define VS_EOC_SET_SERVICES 0xA0A0
+#define VS_EOC_GET_SERVICES 0xA0A4
+#define VS_EOC_SET_PORTS 0xA0A8
+#define VS_EOC_GET_PORTS 0xA0AC
+#define VS_EOC_GET_LINK_INFO 0xA0C0
+#define VS_EOC_GET_INFO 0xA0C4
+#define VS_EOC_DIAGNOSTIC_INFO 0xA0C8
+#define VS_EOC_GET_REAL_TIME_STATS 0xA0CC
+
+
+#define IMAC_GET_DISCOVER_LIST 0xA800
+#define VS_MIN 0xA000
+#define VS_MAX (DRV_MIN - 1)
/* MMTYPE sub-values for MMEs (REQ, CNF, IND or RSP). */
#define CP_MME_REQ 0x00
@@ -145,178 +162,218 @@
/** MMTYPE constants. */
enum cp_mmtype_t
{
- CC_CCO_APPOINT_REQ = CC_CCO_APPOINT + CP_MME_REQ,
- CC_CCO_APPOINT_CNF = CC_CCO_APPOINT + CP_MME_CNF,
- CC_BACKUP_APPOINT_REQ = CC_BACKUP_APPOINT + CP_MME_REQ,
- CC_BACKUP_APPOINT_CNF = CC_BACKUP_APPOINT + CP_MME_CNF,
- CC_LINK_INFO_REQ = CC_LINK_INFO + CP_MME_REQ,
- CC_LINK_INFO_CNF = CC_LINK_INFO + CP_MME_CNF,
- CC_LINK_INFO_IND = CC_LINK_INFO + CP_MME_IND,
- CC_LINK_INFO_RSP = CC_LINK_INFO + CP_MME_RSP,
- CC_HANDOVER_REQ = CC_HANDOVER + CP_MME_REQ,
- CC_HANDOVER_CNF = CC_HANDOVER + CP_MME_CNF,
- CC_HANDOVER_INFO_IND = CC_HANDOVER_INFO + CP_MME_IND,
- CC_HANDOVER_INFO_RSP = CC_HANDOVER_INFO + CP_MME_RSP,
- CC_DISCOVER_LIST_REQ = CC_DISCOVER_LIST + CP_MME_REQ,
- CC_DISCOVER_LIST_CNF = CC_DISCOVER_LIST + CP_MME_CNF,
- CC_DISCOVER_LIST_IND = CC_DISCOVER_LIST + CP_MME_IND,
- CC_LINK_NEW_REQ = CC_LINK_NEW + CP_MME_REQ,
- CC_LINK_NEW_CNF = CC_LINK_NEW + CP_MME_CNF,
- CC_LINK_MOD_REQ = CC_LINK_MOD + CP_MME_REQ,
- CC_LINK_MOD_CNF = CC_LINK_MOD + CP_MME_CNF,
- CC_LINK_SQZ_REQ = CC_LINK_SQZ + CP_MME_REQ,
- CC_LINK_SQZ_CNF = CC_LINK_SQZ + CP_MME_CNF,
- CC_LINK_REL_REQ = CC_LINK_REL + CP_MME_REQ,
- CC_LINK_REL_IND = CC_LINK_REL + CP_MME_IND,
- CC_DETECT_REPORT_REQ = CC_DETECT_REPORT + CP_MME_REQ,
- CC_DETECT_REPORT_CNF = CC_DETECT_REPORT + CP_MME_CNF,
- CC_WHO_RU_REQ = CC_WHO_RU + CP_MME_REQ,
- CC_WHO_RU_CNF = CC_WHO_RU + CP_MME_CNF,
- CC_ASSOC_REQ = CC_ASSOC + CP_MME_REQ,
- CC_ASSOC_CNF = CC_ASSOC + CP_MME_CNF,
- CC_LEAVE_REQ = CC_LEAVE + CP_MME_REQ,
- CC_LEAVE_CNF = CC_LEAVE + CP_MME_CNF,
- CC_LEAVE_IND = CC_LEAVE + CP_MME_IND,
- CC_LEAVE_RSP = CC_LEAVE + CP_MME_RSP,
- CC_SET_TEI_MAP_REQ = CC_SET_TEI_MAP + CP_MME_REQ,
- CC_SET_TEI_MAP_IND = CC_SET_TEI_MAP + CP_MME_IND,
- CC_RELAY_REQ = CC_RELAY + CP_MME_REQ,
- CC_RELAY_IND = CC_RELAY + CP_MME_IND,
- CC_BEACON_RELIABILITY_REQ = CC_BEACON_RELIABILITY + CP_MME_REQ,
- CC_BEACON_RELIABILITY_CNF = CC_BEACON_RELIABILITY + CP_MME_CNF,
- CC_ALLOC_MOVE_REQ = CC_ALLOC_MOVE + CP_MME_REQ,
- CC_ALLOC_MOVE_CNF = CC_ALLOC_MOVE + CP_MME_CNF,
- CC_ACCESS_NEW_REQ = CC_ACCESS_NEW + CP_MME_REQ,
- CC_ACCESS_NEW_CNF = CC_ACCESS_NEW + CP_MME_CNF,
- CC_ACCESS_NEW_IND = CC_ACCESS_NEW + CP_MME_IND,
- CC_ACCESS_NEW_RSP = CC_ACCESS_NEW + CP_MME_RSP,
- CC_ACCESS_REL_REQ = CC_ACCESS_REL + CP_MME_REQ,
- CC_ACCESS_REL_CNF = CC_ACCESS_REL + CP_MME_CNF,
- CC_ACCESS_REL_IND = CC_ACCESS_REL + CP_MME_IND,
- CC_ACCESS_REL_RSP = CC_ACCESS_REL + CP_MME_RSP,
- CC_DCPPC_IND = CC_DCPPC + CP_MME_IND,
- CC_DCPPC_RSP = CC_DCPPC + CP_MME_RSP,
- CC_HP1_DET_REQ = CC_HP1_DET + CP_MME_REQ,
- CC_HP1_DET_CNF = CC_HP1_DET + CP_MME_CNF,
- CC_BLE_UPDATE_IND = CC_BLE_UPDATE + CP_MME_IND,
-
- CP_PROXY_APPOINT_REQ = CP_PROXY_APPOINT + CP_MME_REQ,
- CP_PROXY_APPOINT_CNF = CP_PROXY_APPOINT + CP_MME_CNF,
- PH_PROXY_APPOINT_IND = PH_PROXY_APPOINT + CP_MME_IND,
- CP_PROXY_WAKE_REQ = CP_PROXY_WAKE + CP_MME_REQ,
-
- NN_INL_REQ = NN_INL + CP_MME_REQ,
- NN_INL_CNF = NN_INL + CP_MME_CNF,
- NN_NEW_NET_REQ = NN_NEW_NET + CP_MME_REQ,
- NN_NEW_NET_CNF = NN_NEW_NET + CP_MME_CNF,
- NN_NEW_NET_IND = NN_NEW_NET + CP_MME_IND,
- NN_ADD_ALLOC_REQ = NN_ADD_ALLOC + CP_MME_REQ,
- NN_ADD_ALLOC_CNF = NN_ADD_ALLOC + CP_MME_CNF,
- NN_ADD_ALLOC_IND = NN_ADD_ALLOC + CP_MME_IND,
- NN_REL_ALLOC_REQ = NN_REL_ALLOC + CP_MME_REQ,
- NN_REL_ALLOC_CNF = NN_REL_ALLOC + CP_MME_CNF,
- NN_REL_NET_IND = NN_REL_NET + CP_MME_IND,
-
- CM_UNASSOCIATED_STA_IND = CM_UNASSOCIATED_STA + CP_MME_IND,
- CM_ENCRYPTED_PAYLOAD_IND = CM_ENCRYPTED_PAYLOAD + CP_MME_IND,
- CM_ENCRYPTED_PAYLOAD_RSP = CM_ENCRYPTED_PAYLOAD + CP_MME_RSP,
- CM_SET_KEY_REQ = CM_SET_KEY + CP_MME_REQ,
- CM_SET_KEY_CNF = CM_SET_KEY + CP_MME_CNF,
- CM_GET_KEY_REQ = CM_GET_KEY + CP_MME_REQ,
- CM_GET_KEY_CNF = CM_GET_KEY + CP_MME_CNF,
- CM_SC_JOIN_REQ = CM_SC_JOIN + CP_MME_REQ,
- CM_SC_JOIN_CNF = CM_SC_JOIN + CP_MME_CNF,
- CM_CHAN_EST_IND = CM_CHAN_EST + CP_MME_IND,
- CM_TM_UPDATE_IND = CM_TM_UPDATE + CP_MME_IND,
- CM_AMP_MAP_REQ = CM_AMP_MAP + CP_MME_REQ,
- CM_AMP_MAP_CNF = CM_AMP_MAP + CP_MME_CNF,
- CM_BRG_INFO_REQ = CM_BRG_INFO + CP_MME_REQ,
- CM_BRG_INFO_CNF = CM_BRG_INFO + CP_MME_CNF,
- CM_CONN_NEW_REQ = CM_CONN_NEW + CP_MME_REQ,
- CM_CONN_NEW_CNF = CM_CONN_NEW + CP_MME_CNF,
- CM_CONN_REL_IND = CM_CONN_REL + CP_MME_IND,
- CM_CONN_REL_RSP = CM_CONN_REL + CP_MME_RSP,
- CM_CONN_MOD_REQ = CM_CONN_MOD + CP_MME_REQ,
- CM_CONN_MOD_CNF = CM_CONN_MOD + CP_MME_CNF,
- CM_CONN_INFO_REQ = CM_CONN_INFO + CP_MME_REQ,
- CM_CONN_INFO_CNF = CM_CONN_INFO + CP_MME_CNF,
- CM_STA_CAP_REQ = CM_STA_CAP + CP_MME_REQ,
- CM_STA_CAP_CNF = CM_STA_CAP + CP_MME_CNF,
- CM_NW_INFO_REQ = CM_NW_INFO + CP_MME_REQ,
- CM_NW_INFO_CNF = CM_NW_INFO + CP_MME_CNF,
- CM_GET_BEACON_REQ = CM_GET_BEACON + CP_MME_REQ,
- CM_GET_BEACON_CNF = CM_GET_BEACON + CP_MME_CNF,
- CM_HFID_REQ = CM_HFID + CP_MME_REQ,
- CM_HFID_CNF = CM_HFID + CP_MME_CNF,
- CM_MME_ERROR_IND = CM_MME_ERROR + CP_MME_IND,
- CM_NW_STATS_REQ = CM_NW_STATS + CP_MME_REQ,
- CM_NW_STATS_CNF = CM_NW_STATS + CP_MME_CNF,
- CM_LINK_STATS_REQ = CM_LINK_STATS + CP_MME_REQ,
- CM_LINK_STATS_CNF = CM_LINK_STATS + CP_MME_CNF,
-
- DRV_STA_SET_MAC_ADDR_REQ = DRV_STA_SET_MAC_ADDR + CP_MME_REQ,
- DRV_STA_SET_MAC_ADDR_CNF = DRV_STA_SET_MAC_ADDR + CP_MME_CNF,
- DRV_STA_SET_CCO_PREF_REQ = DRV_STA_SET_CCO_PREF + CP_MME_REQ,
- DRV_STA_SET_CCO_PREF_CNF = DRV_STA_SET_CCO_PREF + CP_MME_CNF,
- DRV_STA_SET_WAS_CCO_REQ = DRV_STA_SET_WAS_CCO + CP_MME_REQ,
- DRV_STA_SET_WAS_CCO_CNF = DRV_STA_SET_WAS_CCO + CP_MME_CNF,
- DRV_STA_SET_WAS_CCO_IND = DRV_STA_SET_WAS_CCO + CP_MME_IND,
- DRV_STA_SET_WAS_CCO_RSP = DRV_STA_SET_WAS_CCO + CP_MME_RSP,
- DRV_STA_SET_NPW_REQ = DRV_STA_SET_NPW + CP_MME_REQ,
- DRV_STA_SET_NPW_CNF = DRV_STA_SET_NPW + CP_MME_CNF,
- DRV_STA_SET_DPW_REQ = DRV_STA_SET_DPW + CP_MME_REQ,
- DRV_STA_SET_DPW_CNF = DRV_STA_SET_DPW + CP_MME_CNF,
- DRV_STA_SET_SL_REQ = DRV_STA_SET_SL + CP_MME_REQ,
- DRV_STA_SET_SL_CNF = DRV_STA_SET_SL + CP_MME_CNF,
- DRV_STA_SET_M_STA_HFID_REQ = DRV_STA_SET_M_STA_HFID + CP_MME_REQ,
- DRV_STA_SET_M_STA_HFID_CNF = DRV_STA_SET_M_STA_HFID + CP_MME_CNF,
- DRV_STA_SET_U_STA_HFID_REQ = DRV_STA_SET_U_STA_HFID + CP_MME_REQ,
- DRV_STA_SET_U_STA_HFID_CNF = DRV_STA_SET_U_STA_HFID + CP_MME_CNF,
- DRV_STA_SET_U_STA_HFID_IND = DRV_STA_SET_U_STA_HFID + CP_MME_IND,
- DRV_STA_SET_AVLN_HFID_REQ = DRV_STA_SET_AVLN_HFID + CP_MME_REQ,
- DRV_STA_SET_AVLN_HFID_CNF = DRV_STA_SET_AVLN_HFID + CP_MME_CNF,
- DRV_STA_SET_AVLN_HFID_IND = DRV_STA_SET_AVLN_HFID + CP_MME_IND,
- DRV_STA_SET_TONEMASK_REQ = DRV_STA_SET_TONEMASK + CP_MME_REQ,
- DRV_STA_SET_TONEMASK_CNF = DRV_STA_SET_TONEMASK + CP_MME_CNF,
- DRV_STA_MAC_START_REQ = DRV_STA_MAC_START + CP_MME_REQ,
- DRV_STA_MAC_START_CNF = DRV_STA_MAC_START + CP_MME_CNF,
- DRV_STA_MAC_STOP_REQ = DRV_STA_MAC_STOP + CP_MME_REQ,
- DRV_STA_MAC_STOP_CNF = DRV_STA_MAC_STOP + CP_MME_CNF,
- DRV_STA_SET_NID_REQ = DRV_STA_SET_NID + CP_MME_REQ,
- DRV_STA_SET_NID_CNF = DRV_STA_SET_NID + CP_MME_CNF,
- DRV_STA_SC_REQ = DRV_STA_SC + CP_MME_REQ,
- DRV_STA_SC_CNF = DRV_STA_SC + CP_MME_CNF,
- DRV_STA_STATUS_REQ = DRV_STA_STATUS + CP_MME_REQ,
- DRV_STA_STATUS_CNF = DRV_STA_STATUS + CP_MME_CNF,
- DRV_STA_STATUS_IND = DRV_STA_STATUS + CP_MME_IND,
- DRV_STA_SET_KEY_REQ = DRV_STA_SET_KEY + CP_MME_REQ,
- DRV_STA_SET_KEY_CNF = DRV_STA_SET_KEY + CP_MME_CNF,
- DRV_STA_SET_KEY_IND = DRV_STA_SET_KEY + CP_MME_IND,
- DRV_STA_GET_KEY_REQ = DRV_STA_GET_KEY + CP_MME_REQ,
- DRV_STA_GET_KEY_CNF = DRV_STA_GET_KEY + CP_MME_CNF,
- DRV_STA_SET_DAK_REQ = DRV_STA_SET_DAK + CP_MME_REQ,
- DRV_STA_SET_DAK_CNF = DRV_STA_SET_DAK + CP_MME_CNF,
- DRV_STA_SET_CONFIG_REQ = DRV_STA_SET_CONFIG + CP_MME_REQ,
- DRV_STA_SET_CONFIG_CNF = DRV_STA_SET_CONFIG + CP_MME_CNF,
- DRV_MCAST_SET_LIST_REQ = DRV_MCAST_SET_LIST + CP_MME_REQ,
- DRV_MCAST_SET_LIST_CNF = DRV_MCAST_SET_LIST + CP_MME_CNF,
-
- VS_GET_TONEMAP_REQ = VS_GET_TONEMAP + CP_MME_REQ,
- VS_GET_TONEMAP_CNF = VS_GET_TONEMAP + CP_MME_CNF,
- VS_GET_SNR_REQ = VS_GET_SNR + CP_MME_REQ,
- VS_GET_SNR_CNF = VS_GET_SNR + CP_MME_CNF,
- VS_GET_SPECTRUM_REQ = VS_GET_SPECTRUM + CP_MME_REQ,
- VS_GET_SPECTRUM_CNF = VS_GET_SPECTRUM + CP_MME_CNF,
- VS_GET_LINK_STATS_REQ = VS_GET_LINK_STATS + CP_MME_REQ,
- VS_GET_LINK_STATS_CNF = VS_GET_LINK_STATS + CP_MME_CNF,
- VS_GET_AMP_MAP_REQ = VS_GET_AMP_MAP + CP_MME_REQ,
- VS_GET_AMP_MAP_CNF = VS_GET_AMP_MAP + CP_MME_CNF,
- VS_GET_STATS_REQ = VS_GET_STATS + CP_MME_REQ,
- VS_GET_STATS_CNF = VS_GET_STATS + CP_MME_CNF,
- VS_GET_CE_STATS_REQ = VS_GET_CE_STATS + CP_MME_REQ,
- VS_GET_CE_STATS_CNF = VS_GET_CE_STATS + CP_MME_CNF,
- IMAC_GET_DISCOVER_LIST_REQ = IMAC_GET_DISCOVER_LIST + CP_MME_REQ,
- IMAC_GET_DISCOVER_LIST_CNF = IMAC_GET_DISCOVER_LIST + CP_MME_CNF,
+ CC_CCO_APPOINT_REQ = CC_CCO_APPOINT + CP_MME_REQ,
+ CC_CCO_APPOINT_CNF = CC_CCO_APPOINT + CP_MME_CNF,
+ CC_BACKUP_APPOINT_REQ = CC_BACKUP_APPOINT + CP_MME_REQ,
+ CC_BACKUP_APPOINT_CNF = CC_BACKUP_APPOINT + CP_MME_CNF,
+ CC_LINK_INFO_REQ = CC_LINK_INFO + CP_MME_REQ,
+ CC_LINK_INFO_CNF = CC_LINK_INFO + CP_MME_CNF,
+ CC_LINK_INFO_IND = CC_LINK_INFO + CP_MME_IND,
+ CC_LINK_INFO_RSP = CC_LINK_INFO + CP_MME_RSP,
+ CC_HANDOVER_REQ = CC_HANDOVER + CP_MME_REQ,
+ CC_HANDOVER_CNF = CC_HANDOVER + CP_MME_CNF,
+ CC_HANDOVER_INFO_IND = CC_HANDOVER_INFO + CP_MME_IND,
+ CC_HANDOVER_INFO_RSP = CC_HANDOVER_INFO + CP_MME_RSP,
+ CC_DISCOVER_LIST_REQ = CC_DISCOVER_LIST + CP_MME_REQ,
+ CC_DISCOVER_LIST_CNF = CC_DISCOVER_LIST + CP_MME_CNF,
+ CC_DISCOVER_LIST_IND = CC_DISCOVER_LIST + CP_MME_IND,
+ CC_LINK_NEW_REQ = CC_LINK_NEW + CP_MME_REQ,
+ CC_LINK_NEW_CNF = CC_LINK_NEW + CP_MME_CNF,
+ CC_LINK_MOD_REQ = CC_LINK_MOD + CP_MME_REQ,
+ CC_LINK_MOD_CNF = CC_LINK_MOD + CP_MME_CNF,
+ CC_LINK_SQZ_REQ = CC_LINK_SQZ + CP_MME_REQ,
+ CC_LINK_SQZ_CNF = CC_LINK_SQZ + CP_MME_CNF,
+ CC_LINK_REL_REQ = CC_LINK_REL + CP_MME_REQ,
+ CC_LINK_REL_IND = CC_LINK_REL + CP_MME_IND,
+ CC_DETECT_REPORT_REQ = CC_DETECT_REPORT + CP_MME_REQ,
+ CC_DETECT_REPORT_CNF = CC_DETECT_REPORT + CP_MME_CNF,
+ CC_WHO_RU_REQ = CC_WHO_RU + CP_MME_REQ,
+ CC_WHO_RU_CNF = CC_WHO_RU + CP_MME_CNF,
+ CC_ASSOC_REQ = CC_ASSOC + CP_MME_REQ,
+ CC_ASSOC_CNF = CC_ASSOC + CP_MME_CNF,
+ CC_LEAVE_REQ = CC_LEAVE + CP_MME_REQ,
+ CC_LEAVE_CNF = CC_LEAVE + CP_MME_CNF,
+ CC_LEAVE_IND = CC_LEAVE + CP_MME_IND,
+ CC_LEAVE_RSP = CC_LEAVE + CP_MME_RSP,
+ CC_SET_TEI_MAP_REQ = CC_SET_TEI_MAP + CP_MME_REQ,
+ CC_SET_TEI_MAP_IND = CC_SET_TEI_MAP + CP_MME_IND,
+ CC_RELAY_REQ = CC_RELAY + CP_MME_REQ,
+ CC_RELAY_IND = CC_RELAY + CP_MME_IND,
+ CC_BEACON_RELIABILITY_REQ = CC_BEACON_RELIABILITY + CP_MME_REQ,
+ CC_BEACON_RELIABILITY_CNF = CC_BEACON_RELIABILITY + CP_MME_CNF,
+ CC_ALLOC_MOVE_REQ = CC_ALLOC_MOVE + CP_MME_REQ,
+ CC_ALLOC_MOVE_CNF = CC_ALLOC_MOVE + CP_MME_CNF,
+ CC_ACCESS_NEW_REQ = CC_ACCESS_NEW + CP_MME_REQ,
+ CC_ACCESS_NEW_CNF = CC_ACCESS_NEW + CP_MME_CNF,
+ CC_ACCESS_NEW_IND = CC_ACCESS_NEW + CP_MME_IND,
+ CC_ACCESS_NEW_RSP = CC_ACCESS_NEW + CP_MME_RSP,
+ CC_ACCESS_REL_REQ = CC_ACCESS_REL + CP_MME_REQ,
+ CC_ACCESS_REL_CNF = CC_ACCESS_REL + CP_MME_CNF,
+ CC_ACCESS_REL_IND = CC_ACCESS_REL + CP_MME_IND,
+ CC_ACCESS_REL_RSP = CC_ACCESS_REL + CP_MME_RSP,
+ CC_DCPPC_IND = CC_DCPPC + CP_MME_IND,
+ CC_DCPPC_RSP = CC_DCPPC + CP_MME_RSP,
+ CC_HP1_DET_REQ = CC_HP1_DET + CP_MME_REQ,
+ CC_HP1_DET_CNF = CC_HP1_DET + CP_MME_CNF,
+ CC_BLE_UPDATE_IND = CC_BLE_UPDATE + CP_MME_IND,
+
+ CP_PROXY_APPOINT_REQ = CP_PROXY_APPOINT + CP_MME_REQ,
+ CP_PROXY_APPOINT_CNF = CP_PROXY_APPOINT + CP_MME_CNF,
+ PH_PROXY_APPOINT_IND = PH_PROXY_APPOINT + CP_MME_IND,
+ CP_PROXY_WAKE_REQ = CP_PROXY_WAKE + CP_MME_REQ,
+
+ NN_INL_REQ = NN_INL + CP_MME_REQ,
+ NN_INL_CNF = NN_INL + CP_MME_CNF,
+ NN_NEW_NET_REQ = NN_NEW_NET + CP_MME_REQ,
+ NN_NEW_NET_CNF = NN_NEW_NET + CP_MME_CNF,
+ NN_NEW_NET_IND = NN_NEW_NET + CP_MME_IND,
+ NN_ADD_ALLOC_REQ = NN_ADD_ALLOC + CP_MME_REQ,
+ NN_ADD_ALLOC_CNF = NN_ADD_ALLOC + CP_MME_CNF,
+ NN_ADD_ALLOC_IND = NN_ADD_ALLOC + CP_MME_IND,
+ NN_REL_ALLOC_REQ = NN_REL_ALLOC + CP_MME_REQ,
+ NN_REL_ALLOC_CNF = NN_REL_ALLOC + CP_MME_CNF,
+ NN_REL_NET_IND = NN_REL_NET + CP_MME_IND,
+
+ CM_UNASSOCIATED_STA_IND = CM_UNASSOCIATED_STA + CP_MME_IND,
+ CM_ENCRYPTED_PAYLOAD_IND = CM_ENCRYPTED_PAYLOAD + CP_MME_IND,
+ CM_ENCRYPTED_PAYLOAD_RSP = CM_ENCRYPTED_PAYLOAD + CP_MME_RSP,
+ CM_SET_KEY_REQ = CM_SET_KEY + CP_MME_REQ,
+ CM_SET_KEY_CNF = CM_SET_KEY + CP_MME_CNF,
+ CM_GET_KEY_REQ = CM_GET_KEY + CP_MME_REQ,
+ CM_GET_KEY_CNF = CM_GET_KEY + CP_MME_CNF,
+ CM_SC_JOIN_REQ = CM_SC_JOIN + CP_MME_REQ,
+ CM_SC_JOIN_CNF = CM_SC_JOIN + CP_MME_CNF,
+ CM_CHAN_EST_IND = CM_CHAN_EST + CP_MME_IND,
+ CM_TM_UPDATE_IND = CM_TM_UPDATE + CP_MME_IND,
+ CM_AMP_MAP_REQ = CM_AMP_MAP + CP_MME_REQ,
+ CM_AMP_MAP_CNF = CM_AMP_MAP + CP_MME_CNF,
+ CM_BRG_INFO_REQ = CM_BRG_INFO + CP_MME_REQ,
+ CM_BRG_INFO_CNF = CM_BRG_INFO + CP_MME_CNF,
+ CM_CONN_NEW_REQ = CM_CONN_NEW + CP_MME_REQ,
+ CM_CONN_NEW_CNF = CM_CONN_NEW + CP_MME_CNF,
+ CM_CONN_REL_IND = CM_CONN_REL + CP_MME_IND,
+ CM_CONN_REL_RSP = CM_CONN_REL + CP_MME_RSP,
+ CM_CONN_MOD_REQ = CM_CONN_MOD + CP_MME_REQ,
+ CM_CONN_MOD_CNF = CM_CONN_MOD + CP_MME_CNF,
+ CM_CONN_INFO_REQ = CM_CONN_INFO + CP_MME_REQ,
+ CM_CONN_INFO_CNF = CM_CONN_INFO + CP_MME_CNF,
+ CM_STA_CAP_REQ = CM_STA_CAP + CP_MME_REQ,
+ CM_STA_CAP_CNF = CM_STA_CAP + CP_MME_CNF,
+ CM_NW_INFO_REQ = CM_NW_INFO + CP_MME_REQ,
+ CM_NW_INFO_CNF = CM_NW_INFO + CP_MME_CNF,
+ CM_GET_BEACON_REQ = CM_GET_BEACON + CP_MME_REQ,
+ CM_GET_BEACON_CNF = CM_GET_BEACON + CP_MME_CNF,
+ CM_HFID_REQ = CM_HFID + CP_MME_REQ,
+ CM_HFID_CNF = CM_HFID + CP_MME_CNF,
+ CM_MME_ERROR_IND = CM_MME_ERROR + CP_MME_IND,
+ CM_NW_STATS_REQ = CM_NW_STATS + CP_MME_REQ,
+ CM_NW_STATS_CNF = CM_NW_STATS + CP_MME_CNF,
+ CM_LINK_STATS_REQ = CM_LINK_STATS + CP_MME_REQ,
+ CM_LINK_STATS_CNF = CM_LINK_STATS + CP_MME_CNF,
+
+ DRV_STA_SET_MAC_ADDR_REQ = DRV_STA_SET_MAC_ADDR + CP_MME_REQ,
+ DRV_STA_SET_MAC_ADDR_CNF = DRV_STA_SET_MAC_ADDR + CP_MME_CNF,
+ DRV_STA_SET_CCO_PREF_REQ = DRV_STA_SET_CCO_PREF + CP_MME_REQ,
+ DRV_STA_SET_CCO_PREF_CNF = DRV_STA_SET_CCO_PREF + CP_MME_CNF,
+ DRV_STA_SET_WAS_CCO_REQ = DRV_STA_SET_WAS_CCO + CP_MME_REQ,
+ DRV_STA_SET_WAS_CCO_CNF = DRV_STA_SET_WAS_CCO + CP_MME_CNF,
+ DRV_STA_SET_WAS_CCO_IND = DRV_STA_SET_WAS_CCO + CP_MME_IND,
+ DRV_STA_SET_WAS_CCO_RSP = DRV_STA_SET_WAS_CCO + CP_MME_RSP,
+ DRV_STA_SET_NPW_REQ = DRV_STA_SET_NPW + CP_MME_REQ,
+ DRV_STA_SET_NPW_CNF = DRV_STA_SET_NPW + CP_MME_CNF,
+ DRV_STA_SET_DPW_REQ = DRV_STA_SET_DPW + CP_MME_REQ,
+ DRV_STA_SET_DPW_CNF = DRV_STA_SET_DPW + CP_MME_CNF,
+ DRV_STA_SET_SL_REQ = DRV_STA_SET_SL + CP_MME_REQ,
+ DRV_STA_SET_SL_CNF = DRV_STA_SET_SL + CP_MME_CNF,
+ DRV_STA_SET_M_STA_HFID_REQ = DRV_STA_SET_M_STA_HFID + CP_MME_REQ,
+ DRV_STA_SET_M_STA_HFID_CNF = DRV_STA_SET_M_STA_HFID + CP_MME_CNF,
+ DRV_STA_SET_U_STA_HFID_REQ = DRV_STA_SET_U_STA_HFID + CP_MME_REQ,
+ DRV_STA_SET_U_STA_HFID_CNF = DRV_STA_SET_U_STA_HFID + CP_MME_CNF,
+ DRV_STA_SET_U_STA_HFID_IND = DRV_STA_SET_U_STA_HFID + CP_MME_IND,
+ DRV_STA_SET_AVLN_HFID_REQ = DRV_STA_SET_AVLN_HFID + CP_MME_REQ,
+ DRV_STA_SET_AVLN_HFID_CNF = DRV_STA_SET_AVLN_HFID + CP_MME_CNF,
+ DRV_STA_SET_AVLN_HFID_IND = DRV_STA_SET_AVLN_HFID + CP_MME_IND,
+ DRV_STA_SET_TONEMASK_REQ = DRV_STA_SET_TONEMASK + CP_MME_REQ,
+ DRV_STA_SET_TONEMASK_CNF = DRV_STA_SET_TONEMASK + CP_MME_CNF,
+ DRV_STA_MAC_START_REQ = DRV_STA_MAC_START + CP_MME_REQ,
+ DRV_STA_MAC_START_CNF = DRV_STA_MAC_START + CP_MME_CNF,
+ DRV_STA_MAC_STOP_REQ = DRV_STA_MAC_STOP + CP_MME_REQ,
+ DRV_STA_MAC_STOP_CNF = DRV_STA_MAC_STOP + CP_MME_CNF,
+ DRV_STA_SET_NID_REQ = DRV_STA_SET_NID + CP_MME_REQ,
+ DRV_STA_SET_NID_CNF = DRV_STA_SET_NID + CP_MME_CNF,
+ DRV_STA_SC_REQ = DRV_STA_SC + CP_MME_REQ,
+ DRV_STA_SC_CNF = DRV_STA_SC + CP_MME_CNF,
+ DRV_STA_STATUS_REQ = DRV_STA_STATUS + CP_MME_REQ,
+ DRV_STA_STATUS_CNF = DRV_STA_STATUS + CP_MME_CNF,
+ DRV_STA_STATUS_IND = DRV_STA_STATUS + CP_MME_IND,
+ DRV_STA_SET_KEY_REQ = DRV_STA_SET_KEY + CP_MME_REQ,
+ DRV_STA_SET_KEY_CNF = DRV_STA_SET_KEY + CP_MME_CNF,
+ DRV_STA_SET_KEY_IND = DRV_STA_SET_KEY + CP_MME_IND,
+ DRV_STA_GET_KEY_REQ = DRV_STA_GET_KEY + CP_MME_REQ,
+ DRV_STA_GET_KEY_CNF = DRV_STA_GET_KEY + CP_MME_CNF,
+ DRV_STA_SET_DAK_REQ = DRV_STA_SET_DAK + CP_MME_REQ,
+ DRV_STA_SET_DAK_CNF = DRV_STA_SET_DAK + CP_MME_CNF,
+ DRV_STA_SET_CONFIG_REQ = DRV_STA_SET_CONFIG + CP_MME_REQ,
+ DRV_STA_SET_CONFIG_CNF = DRV_STA_SET_CONFIG + CP_MME_CNF,
+ DRV_EOC_STA_SET_SLAVE_CONFIG_REQ = DRV_EOC_STA_SET_SLAVE_CONFIG + CP_MME_REQ,
+ DRV_EOC_STA_SET_SLAVE_CONFIG_CNF = DRV_EOC_STA_SET_SLAVE_CONFIG + CP_MME_CNF,
+ DRV_EOC_STA_SET_EOC_CONFIG_REQ = DRV_EOC_STA_SET_EOC_CONFIG + CP_MME_REQ,
+ DRV_EOC_STA_SET_EOC_CONFIG_CNF = DRV_EOC_STA_SET_EOC_CONFIG + CP_MME_CNF,
+ DRV_MCAST_SET_LIST_REQ = DRV_MCAST_SET_LIST + CP_MME_REQ,
+ DRV_MCAST_SET_LIST_CNF = DRV_MCAST_SET_LIST + CP_MME_CNF,
+
+ VS_GET_TONEMAP_REQ = VS_GET_TONEMAP + CP_MME_REQ,
+ VS_GET_TONEMAP_CNF = VS_GET_TONEMAP + CP_MME_CNF,
+ VS_GET_SNR_REQ = VS_GET_SNR + CP_MME_REQ,
+ VS_GET_SNR_CNF = VS_GET_SNR + CP_MME_CNF,
+ VS_GET_SPECTRUM_REQ = VS_GET_SPECTRUM + CP_MME_REQ,
+ VS_GET_SPECTRUM_CNF = VS_GET_SPECTRUM + CP_MME_CNF,
+ VS_GET_LINK_STATS_REQ = VS_GET_LINK_STATS + CP_MME_REQ,
+ VS_GET_LINK_STATS_CNF = VS_GET_LINK_STATS + CP_MME_CNF,
+ VS_GET_AMP_MAP_REQ = VS_GET_AMP_MAP + CP_MME_REQ,
+ VS_GET_AMP_MAP_CNF = VS_GET_AMP_MAP + CP_MME_CNF,
+ VS_GET_STATS_REQ = VS_GET_STATS + CP_MME_REQ,
+ VS_GET_STATS_CNF = VS_GET_STATS + CP_MME_CNF,
+ VS_GET_CE_STATS_REQ = VS_GET_CE_STATS + CP_MME_REQ,
+ VS_GET_CE_STATS_CNF = VS_GET_CE_STATS + CP_MME_CNF,
+
+ VS_EOC_GET_TOPO_REQ = VS_EOC_GET_TOPO + CP_MME_REQ,
+ VS_EOC_GET_TOPO_CNF = VS_EOC_GET_TOPO + CP_MME_CNF,
+
+ VS_EOC_CCO_GET_WL_REQ = VS_EOC_CCO_GET_WL + CP_MME_REQ,
+ VS_EOC_CCO_GET_WL_CNF = VS_EOC_CCO_GET_WL + CP_MME_CNF,
+
+ VS_EOC_CCO_SET_WL_REQ = VS_EOC_CCO_SET_WL + CP_MME_REQ,
+ VS_EOC_CCO_SET_WL_CNF = VS_EOC_CCO_SET_WL + CP_MME_CNF,
+
+ VS_EOC_CCO_SET_OUT_LEV_IND = VS_EOC_CCO_SET_OUT_LEV + CP_MME_IND,
+
+ VS_EOC_GET_LINK_INFO_REQ = VS_EOC_GET_LINK_INFO + CP_MME_REQ,
+ VS_EOC_GET_LINK_INFO_CNF = VS_EOC_GET_LINK_INFO + CP_MME_CNF,
+
+ VS_EOC_SET_PORTS_REQ = VS_EOC_SET_PORTS + CP_MME_REQ,
+ VS_EOC_SET_PORTS_CNF = VS_EOC_SET_PORTS + CP_MME_CNF,
+
+ VS_EOC_GET_PORTS_REQ = VS_EOC_GET_PORTS + CP_MME_REQ,
+ VS_EOC_GET_PORTS_CNF = VS_EOC_GET_PORTS + CP_MME_CNF,
+
+ VS_EOC_SET_SERVICES_REQ = VS_EOC_SET_SERVICES + CP_MME_REQ,
+ VS_EOC_SET_SERVICES_CNF = VS_EOC_SET_SERVICES + CP_MME_CNF,
+
+ VS_EOC_GET_SERVICES_REQ = VS_EOC_GET_SERVICES + CP_MME_REQ,
+ VS_EOC_GET_SERVICES_CNF = VS_EOC_GET_SERVICES + CP_MME_CNF,
+
+ VS_EOC_GET_INFO_REQ = VS_EOC_GET_INFO + CP_MME_REQ,
+ VS_EOC_GET_INFO_CNF = VS_EOC_GET_INFO + CP_MME_CNF,
+
+ VS_EOC_DIAGNOSTIC_INFO_REQ = VS_EOC_DIAGNOSTIC_INFO + CP_MME_REQ,
+ VS_EOC_DIAGNOSTIC_INFO_CNF = VS_EOC_DIAGNOSTIC_INFO + CP_MME_CNF,
+
+ VS_EOC_GET_REAL_TIME_STATS_REQ = VS_EOC_GET_REAL_TIME_STATS + CP_MME_REQ,
+ VS_EOC_GET_REAL_TIME_STATS_CNF = VS_EOC_GET_REAL_TIME_STATS + CP_MME_CNF,
+
+ IMAC_GET_DISCOVER_LIST_REQ = IMAC_GET_DISCOVER_LIST + CP_MME_REQ,
+ IMAC_GET_DISCOVER_LIST_CNF = IMAC_GET_DISCOVER_LIST + CP_MME_CNF,
};
typedef enum cp_mmtype_t cp_mmtype_t;
diff --git a/cesar/cp/msg/Config b/cesar/cp/msg/Config
new file mode 100644
index 0000000000..45f15cf5d5
--- /dev/null
+++ b/cesar/cp/msg/Config
@@ -0,0 +1,3 @@
+CONFIG_CP_MSG_EOC_VS = n
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = n
+CONFIG_CP_MSG_EOC_DRV_MME = n
diff --git a/cesar/cp/msg/Module b/cesar/cp/msg/Module
index ea3547c7c7..ff6d69c9b8 100644
--- a/cesar/cp/msg/Module
+++ b/cesar/cp/msg/Module
@@ -1 +1,6 @@
SOURCES := msg.c mme.c msg_cc.c msg_cm.c msg_drv.c msg_vs.c
+
+ifeq ($(CONFIG_CP_MSG_EOC_VS),y)
+SOURCES += msg_vs_eoc.c
+endif
+
diff --git a/cesar/cp/msg/inc/cc_assoc.h b/cesar/cp/msg/inc/cc_assoc.h
index f1f3708378..5d5e8a1ae1 100644
--- a/cesar/cp/msg/inc/cc_assoc.h
+++ b/cesar/cp/msg/inc/cc_assoc.h
@@ -28,6 +28,7 @@ enum cp_msg_cc_assoc_cnf_result_t
CP_MSG_CC_ASSOC_CNF_RESULT_FAILURE_TEMPORARY_RESSOURCE_EXHAUSTION,
CP_MSG_CC_ASSOC_CNF_RESULT_FAILURE_PERMANANT_RESSOURCE_EXHAUSTION,
CP_MSG_CC_ASSOC_CNF_RESULT_FAILURE_OTHER_REASON,
+ CP_MSG_CC_ASSOC_CNF_RESULT_SUCCESS_WL_ACCEPT_ALL,
CP_MSG_CC_ASSOC_CNF_RESULT_NB
};
@@ -61,4 +62,6 @@ struct cp_msg_cc_assoc_cnf_t
};
typedef struct cp_msg_cc_assoc_cnf_t cp_msg_cc_assoc_cnf_t;
+#define MASTER_GOLDEN_DPW "SPIDCOM-TEST-MASTER"
+
#endif /* cp_msg_inc_cc_assoc_h */
diff --git a/cesar/cp/msg/inc/msg_drv.h b/cesar/cp/msg/inc/msg_drv.h
index a15a98c6e4..0886f9137b 100644
--- a/cesar/cp/msg/inc/msg_drv.h
+++ b/cesar/cp/msg/inc/msg_drv.h
@@ -16,6 +16,7 @@
#include "cp/msg/inc/drv_sta_set_key.h"
#include "cp/msg/inc/drv_sta_status.h"
#include "cp/msg/inc/drv_sta_get_key.h"
+#include "cp/sta/mgr/sta.h"
#include "common/defs/homeplugAV.h"
#include "common/defs/igmp.h"
@@ -326,6 +327,18 @@ cp_msg_drv_sta_set_avln_hfid_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
const char *avln_hfid);
/**
+ * Send a DRV_STA_STATUS_IND.
+ * \param ctx control plane context
+ * \param peer peer information
+ * \param mmtype MMTYPE to respond to
+ * \param state state of the station (unassociated, associated, authenticated)
+ */
+
+void
+cp_msg_drv_get_status_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype, cp_eoc_sta_state_t state);
+
+/**
* Receive DRV_MCAST_SET_LIST.REQ
* \param ctx control plane context
* \param mme MME to handle.
@@ -341,6 +354,30 @@ cp_msg_drv_mcast_set_list_req_receive (
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]);
+/**
+ * Receives a DRV_STA_SET_EOC.REQ
+ * \param ctx control plane context.
+ * \param mme MME to handle.
+ * \param exp output level exponent
+ * \param value output power value
+ * \return true on success.
+ */
+bool
+cp_msg_drv_sta_set_eoc_req_receive (cp_t *ctx, cp_mme_rx_t *mme, uint *exp,
+ uint *value);
+
+/**
+ * Receives a DRV_STA_SET_SLAVE.REQ
+ * \param ctx control plane context.
+ * \param mme MME to handle.
+ * \param config configuration string.
+ * \return true on success.
+ */
+bool
+cp_msg_drv_sta_set_slave_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ char config[HPAV_MME_PAYLOAD_MAX_SIZE]);
+
+
END_DECLS
#endif /* cp_msg_inc_msg_drv_h */
diff --git a/cesar/cp/msg/inc/msg_vs_eoc.h b/cesar/cp/msg/inc/msg_vs_eoc.h
new file mode 100644
index 0000000000..83aead2e5c
--- /dev/null
+++ b/cesar/cp/msg/inc/msg_vs_eoc.h
@@ -0,0 +1,247 @@
+#ifndef cp_msg_inc_msg_vs_eoc_h
+#define cp_msg_inc_msg_vs_eoc_h
+/* Cesar-EoC project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/inc/msg_vs_eoc.h
+ * \brief VS EoC family MME.
+ * \ingroup cp_msg
+ */
+#include "cp/msg/inc/vs_eoc_get_topo.h"
+#include "cp/eoc/cco/bw/inc/service.h"
+#include "cp/sta/mgr/sta.h"
+#include "cp/eoc/cco/action/vs_eoc.h"
+#include "cp/eoc/sta/action/vs_eoc.h"
+
+/** Result of a VS_EOC_CCO_SET_WL request. */
+enum cp_msg_vs_eoc_cco_set_wl_req_result_t
+{
+ CP_MSG_VS_EOC_CCO_SET_WL_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_CCO_SET_WL_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_CCO_SET_WL_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_cco_set_wl_req_result_t cp_msg_vs_eoc_cco_set_wl_req_result_t;
+
+
+/** Result of a VS_EOC_CCO_GET_WL request. */
+enum cp_msg_vs_eoc_cco_get_wl_req_result_t
+{
+ CP_MSG_VS_EOC_CCO_GET_WL_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_CCO_GET_WL_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_CCO_GET_WL_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_cco_get_wl_req_result_t cp_msg_vs_eoc_cco_get_wl_req_result_t;
+
+/** Result of a VS_EOC_SET_PORTS request */
+
+enum cp_msg_vs_eoc_set_ports_req_result_t
+{
+ CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_SET_PORTS_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_set_ports_req_result_t cp_msg_vs_eoc_set_ports_req_result_t;
+
+/** Result of a VS_EOC_GET_PORTS request */
+
+enum cp_msg_vs_eoc_get_ports_req_result_t
+{
+ CP_MSG_VS_EOC_GET_PORTS_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_GET_PORTS_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_GET_PORTS_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_get_ports_req_result_t cp_msg_vs_eoc_get_ports_req_result_t;
+
+/** Result of a VS_EOC_SET_SERVICES request */
+
+enum cp_msg_vs_eoc_set_services_req_result_t
+{
+ CP_MSG_VS_EOC_SET_SERVICES_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_SET_SERVICES_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_SET_SERVICES_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_set_services_req_result_t cp_msg_vs_eoc_set_services_req_result_t;
+
+/** Result of a VS_EOC_GET_SERVICES request */
+
+enum cp_msg_vs_eoc_get_services_req_result_t
+{
+ CP_MSG_VS_EOC_GET_SERVICES_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_GET_SERVICES_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_GET_SERVICES_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_get_services_req_result_t cp_msg_vs_eoc_get_services_req_result_t;
+
+/** Result of a VS_EOC_GET_INFO_REQ request */
+
+enum cp_msg_vs_eoc_get_info_req_result_t
+{
+ CP_MSG_VS_EOC_GET_INFO_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_GET_INFO_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_GET_INFO_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_get_info_req_result_t cp_msg_vs_eoc_get_info_req_result_t;
+
+/** Result of a VS_EOC_DIAGNOSTIC_INFO_REQ request */
+
+enum cp_msg_vs_eoc_diagnostic_info_req_result_t
+{
+ CP_MSG_VS_EOC_DIAGNOSTIC_INFO_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_DIAGNOSTIC_INFO_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_DIAGNOSTIC_INFO_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_diagnostic_info_req_result_t cp_msg_vs_eoc_diagnostic_info_req_result_t;
+
+/** Result of a VS_EOC_GET_REAL_TIME_STATS_REQ request */
+
+enum cp_msg_vs_eoc_get_real_time_stats_req_result_t
+{
+ CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_FAILURE,
+ CP_MSG_VS_EOC_GET_REAL_TIME_STATS_REQ_RESULT_NB,
+};
+typedef enum cp_msg_vs_eoc_get_real_time_stats_req_result_t cp_msg_vs_eoc_get_real_time_stats_req_result_t;
+
+BEGIN_DECLS
+
+
+
+/**
+ * Receive a VS_EOC_CCO_SET_WL.REQ.
+ * \param ctx control plane context
+ * \param mme MME handle
+ * \param mac received mac address
+ * \return true on success
+ */
+
+
+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, u8 *stas_actions);
+
+void
+cp_msg_vs_eoc_cco_set_wl_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ cp_msg_vs_eoc_cco_set_wl_req_result_t result);
+
+bool
+cp_msg_vs_eoc_cco_get_wl_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *first_wl_index_nb);
+
+void
+cp_msg_vs_eoc_cco_get_wl_cnf_send (cp_t *ctx, uint 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, u8 *stas_actions, u8 first_wl_index_nb);
+
+void
+cp_msg_vs_eoc_cco_set_out_lev_ind_send (cp_t *ctx, cp_mme_peer_t *peer, uint output_level);
+
+bool
+cp_msg_eoc_sta_vs_set_out_lev_ind_receive(cp_t *ctx, cp_mme_rx_t *mme, uint *output_level);
+
+
+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]);
+
+void
+cp_msg_vs_eoc_set_ports_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ cp_msg_vs_eoc_set_ports_req_result_t result);
+
+bool
+cp_msg_vs_eoc_cco_get_ports_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *first_mac_index_nb);
+
+void
+cp_msg_vs_eoc_cco_get_ports_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_msg_vs_eoc_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);
+
+bool
+cp_msg_vs_eoc_set_services_req_receive(cp_t *ctx, cp_mme_rx_t *mme, u8 *command, u8 *services_number, u8 *service_indexes,
+ u8 *classifier_rules, u16 *clssifier_values, u8 *acses, u8 *parameters_numbers,
+ u16 parameters_lists[][SERVICE_PARAMETERS_NB]);
+
+void
+cp_msg_vs_eoc_set_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ cp_msg_vs_eoc_set_services_req_result_t result);
+
+bool
+cp_msg_vs_eoc_cco_get_services_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *first_service_index_nb);
+
+void
+cp_msg_vs_eoc_cco_get_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_msg_vs_eoc_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);
+
+bool
+cp_msg_vs_eoc_cco_get_info_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *internal_eoc_index, u8 *control);
+
+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, u8 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);
+
+bool
+cp_msg_vs_eoc_cco_diagnostic_info_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *internal_eoc_index, u8 *control);
+
+
+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);
+
+
+
+/**
+ * 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);
+
+/**
+ * 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, u8 up_att);
+
+/**
+ * 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);
+
+
+bool
+cp_msg_vs_eoc_cco_get_real_time_stats_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *control);
+
+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_stats_req_result_t status, real_time_stats_t *rt_stats);
+
+
+
+END_DECLS
+
+
+#endif /* cp_msg_inc_msg_vs_eoc_h */
diff --git a/cesar/cp/msg/inc/vs_eoc_get_topo.h b/cesar/cp/msg/inc/vs_eoc_get_topo.h
new file mode 100644
index 0000000000..7052b7cd05
--- /dev/null
+++ b/cesar/cp/msg/inc/vs_eoc_get_topo.h
@@ -0,0 +1,27 @@
+#ifndef cp_msg_inc_vs_eoc_get_topo_h
+#define cp_msg_inc_vs_eoc_get_topo_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/inc/vs_eoc_get_topo.h
+ * \brief VS_EOC_GET_TOPO Structures.
+ * \ingroup cp_msg
+ */
+
+/** VS_EOC_GET_TOPO.CNF result. */
+enum cp_msg_vs_eoc_get_topo_cnf_result_t
+{
+ CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_FAILURE,
+ CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_NB
+};
+
+typedef enum cp_msg_vs_eoc_get_topo_cnf_result_t
+cp_msg_vs_eoc_get_topo_cnf_result_t;
+
+#endif /* cp_msg_inc_vs_eoc_get_topo_h */
diff --git a/cesar/cp/msg/msg.h b/cesar/cp/msg/msg.h
index 0e4c6f0a5a..0d3df6ee21 100644
--- a/cesar/cp/msg/msg.h
+++ b/cesar/cp/msg/msg.h
@@ -29,6 +29,13 @@
#include "cp/msg/inc/msg_drv.h"
#include "cp/msg/inc/msg_vs.h"
+/*#include "config/cp/msg/eoc.h"
+#if CONFIG_CP_MSG_EOC_VS
+#include "cp/msg/inc/msg_vs_eoc.h"
+#endif*/
+/* CONFIG_CP_MSG_EOC_VS */
+
+
enum cp_msg_avln_status_t
{
CP_MSG_AVLN_STATUS_UNASSOC_CCO_0,
diff --git a/cesar/cp/msg/src/msg.c b/cesar/cp/msg/src/msg.c
index 045e905510..bf8e53d4b9 100644
--- a/cesar/cp/msg/src/msg.c
+++ b/cesar/cp/msg/src/msg.c
@@ -36,7 +36,10 @@
#include "cp/msg/inc/allowed_mme.h"
-#include <stdio.h>
+#include "config/cp/msg/eoc/multi/sta/mme.h"
+#include "config/cp/msg/eoc.h"
+
+
#define CP_MSG_CM_ENC_PLAYLOAD_RF_LEN_MAX_SIZE 15
@@ -95,9 +98,13 @@ cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
CP_MSG_MME_ALLOWED_ENTRY (CC_LINK_REL_IND, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
CP_MSG_MME_ALLOWED_ENTRY (CC_DETECT_REPORT_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
CP_MSG_MME_ALLOWED_ENTRY (CC_DETECT_REPORT_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
- CP_MSG_MME_ALLOWED_ENTRY (CC_WHO_RU_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, CC_WHO_RU_REQ),
- CP_MSG_MME_ALLOWED_ENTRY (CC_WHO_RU_CNF, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_WHO_RU_CNF),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_WHO_RU_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, CC_WHO_RU_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (CC_WHO_RU_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_WHO_RU_CNF),
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+ CP_MSG_MME_ALLOWED_ENTRY (CC_ASSOC_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, MULTI_STA_MME),
+#else
CP_MSG_MME_ALLOWED_ENTRY (CC_ASSOC_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_ASSOC_REQ),
+#endif /* CONFIG_CP_MSG_EOC_MULTI_STA_MME */
CP_MSG_MME_ALLOWED_ENTRY (CC_ASSOC_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CC_ASSOC_CNF),
CP_MSG_MME_ALLOWED_ENTRY (CC_LEAVE_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_LEAVE_REQ),
CP_MSG_MME_ALLOWED_ENTRY (CC_LEAVE_CNF, STA_ASSOC, NEK_ENC_NO, FROM_H1_NO, CC_LEAVE_CNF),
@@ -144,7 +151,11 @@ cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
CP_MSG_MME_ALLOWED_ENTRY (CM_ENCRYPTED_PAYLOAD_RSP, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
CP_MSG_MME_ALLOWED_ENTRY (CM_SET_KEY_REQ, STA_ASSOC, NEK_ENC_YES, FROM_H1_YES, CM_SET_KEY_REQ),
CP_MSG_MME_ALLOWED_ENTRY (CM_SET_KEY_CNF, STA_ASSOC, NEK_ENC_YES, FROM_H1_YES, CM_SET_KEY_CNF),
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+ CP_MSG_MME_ALLOWED_ENTRY (CM_GET_KEY_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, MULTI_STA_MME),
+#else
CP_MSG_MME_ALLOWED_ENTRY (CM_GET_KEY_REQ, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, CM_GET_KEY_REQ),
+#endif /* CONFIG_CP_MSG_EOC_MULTI_STA_MME */
CP_MSG_MME_ALLOWED_ENTRY (CM_GET_KEY_CNF, STA_ASSOC, NEK_ENC_NO, FROM_H1_YES, CM_GET_KEY_CNF),
CP_MSG_MME_ALLOWED_ENTRY (CM_SC_JOIN_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_SC_JOIN_REQ),
CP_MSG_MME_ALLOWED_ENTRY (CM_SC_JOIN_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, CM_SC_JOIN_CNF),
@@ -175,7 +186,7 @@ cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
CP_MSG_MME_ALLOWED_ENTRY (CM_NW_STATS_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
CP_MSG_MME_ALLOWED_ENTRY (CM_LINK_STATS_REQ, STA_AUTH, NEK_ENC_YES, FROM_H1_YES, CM_LINK_STATS_REQ),
CP_MSG_MME_ALLOWED_ENTRY (CM_LINK_STATS_CNF, STA_AUTH, NEK_ENC_YES, FROM_H1_NO, NO_EVENT),
- // CP_MSG_MME_ALLOWED_ENTRY (VS_GET_VERSION_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
+// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_VERSION_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
// CP_MSG_MME_ALLOWED_ENTRY (VS_GET_VERSION_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
// CP_MSG_MME_ALLOWED_ENTRY (VS_RESET_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, NO_EVENT),
// CP_MSG_MME_ALLOWED_ENTRY (VS_RESET_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
@@ -211,6 +222,31 @@ cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
CP_MSG_MME_ALLOWED_ENTRY (VS_GET_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
CP_MSG_MME_ALLOWED_ENTRY (VS_GET_CE_STATS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_GET_CE_STATS_REQ),
CP_MSG_MME_ALLOWED_ENTRY (VS_GET_CE_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+#if CONFIG_CP_MSG_EOC_VS
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_TOPO_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_GET_TOPO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_TOPO_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_CCO_SET_WL_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_CCO_SET_WL_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_CCO_SET_WL_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_CCO_GET_WL_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_CCO_GET_WL_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_CCO_GET_WL_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_CCO_SET_OUT_LEV_IND, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, VS_EOC_CCO_SET_OUT_LEV_IND),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_SET_SERVICES_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_SET_SERVICES_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_SET_SERVICES_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_SERVICES_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_GET_SERVICES_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_SERVICES_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_SET_PORTS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_SET_PORTS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_SET_PORTS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_PORTS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_GET_PORTS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_PORTS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_INFO_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_GET_INFO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_INFO_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_DIAGNOSTIC_INFO_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_DIAGNOSTIC_INFO_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_DIAGNOSTIC_INFO_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_REAL_TIME_STATS_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, VS_EOC_GET_REAL_TIME_STATS_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (VS_EOC_GET_REAL_TIME_STATS_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+
+
+#endif /* CONFIG_CP_MSG_EOC_VS */
CP_MSG_MME_ALLOWED_ENTRY (IMAC_GET_DISCOVER_LIST_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, IMAC_GET_DISCOVER_LIST_REQ),
CP_MSG_MME_ALLOWED_ENTRY (IMAC_GET_DISCOVER_LIST_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
@@ -256,6 +292,12 @@ cp_msg_mme_allowed_t cp_msg_mme_allowed[] =
CP_MSG_MME_ALLOWED_ENTRY (DRV_STA_SET_CONFIG_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
CP_MSG_MME_ALLOWED_ENTRY (DRV_MCAST_SET_LIST_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_MCAST_SET_LIST_REQ),
CP_MSG_MME_ALLOWED_ENTRY (DRV_MCAST_SET_LIST_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+#if CONFIG_CP_MSG_EOC_VS
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_EOC_STA_SET_SLAVE_CONFIG_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_EOC_STA_SET_SLAVE_CONFIG_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_EOC_STA_SET_SLAVE_CONFIG_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_EOC_STA_SET_EOC_CONFIG_REQ, STA_UNASSOC, NEK_ENC_NO, FROM_H1_YES, DRV_EOC_STA_SET_EOC_CONFIG_REQ),
+ CP_MSG_MME_ALLOWED_ENTRY (DRV_EOC_STA_SET_EOC_CONFIG_CNF, STA_UNASSOC, NEK_ENC_NO, FROM_H1_NO, NO_EVENT),
+#endif /* CONFIG_CP_MSG_EOC_VS */
};
uint cp_msg_mme_allowed_count = COUNT (cp_msg_mme_allowed);
@@ -347,6 +389,47 @@ cp_msg_peks_key_get (cp_t *ctx, cp_mme_peks_t peks)
dbg_assert_default ();
}
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+/**
+ * Provide the key for the peer using the PEKS to select it.
+ * \param ctx the module context.
+ * \param peer the peer to communicate with.
+ * \param peks the peks to use.
+ * \return the key to encrypt or decrypt.
+ *
+ * If the peks points to an invalid value the function asserts.
+ * PEKS_SPC_NOT_EMBEDDED is considered as a wrong value and causes an assert.
+ */
+static inline cp_key_t
+cp_msg_peer_peks_key_get (cp_t *ctx, cp_mme_peer_t peer, cp_mme_peks_t peks)
+{
+ dbg_assert (ctx);
+ dbg_assert (peks < CP_MME_PEKS_NONE);
+
+ if (peks == CP_MME_PEKS_NMK)
+ return cp_sta_own_data_get_nmk (ctx);
+ else if ((peks >= CP_MME_PEKS_TEK_MIN)
+ && (peks <= CP_MME_PEKS_TEK_MAX))
+ return cp_sta_own_data_get_tek (ctx);
+ else if (peks == CP_MME_PEKS_DAK)
+ {
+ cp_sta_t *dest = cp_sta_mgr_sta_get_from_mac (ctx, peer.mac);
+ if (dest)
+ {
+ slab_release (dest);
+ return dest->multi_sta.dak;
+ }
+ else
+ {
+ cp_key_t zero_key = {{0, 0, 0, 0}};
+ return zero_key;
+ }
+ }
+ else
+ dbg_assert_default ();
+}
+#endif
+
/**
* Initialise the MSG module.
* \param ctx control plane context
@@ -982,8 +1065,11 @@ cp_msg_mme_send (cp_t *ctx, cp_mme_tx_t *mme)
/* Select the key indexed by the PEKS to encrypted the embedded MME. */
if (mme->peks != CP_MME_PEKS_NONE)
{
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+ key = cp_msg_peer_peks_key_get (ctx, mme->peer, mme->peks);
+#else
key = cp_msg_peks_key_get (ctx, mme->peks);
-
+#endif
/* AES encryption. */
enc_length = mme->length
+ mme->rf_len
@@ -1232,7 +1318,11 @@ cp_msg_mme_read_header_enc (cp_t *ctx, cp_mme_rx_t *mme)
/* Select the key to decrypt the embedded MME. */
if (mme->peks != CP_MME_PEKS_NONE)
{
+#if CONFIG_CP_MSG_EOC_MULTI_STA_MME
+ key = cp_msg_peer_peks_key_get (ctx, mme->peer, mme->peks);
+#else
key = cp_msg_peks_key_get (ctx, mme->peks);
+#endif
cp_secu_aes_set_decrypt_key (&aes, key);
cp_secu_aes_cbc_decrypt (ctx, &aes, mme->iv_uuid.key,
(u32 *) (mme->p_mme + payload_offset),
diff --git a/cesar/cp/msg/src/msg_cm.c b/cesar/cp/msg/src/msg_cm.c
index ee17754ede..df29c4a4d7 100644
--- a/cesar/cp/msg/src/msg_cm.c
+++ b/cesar/cp/msg/src/msg_cm.c
@@ -607,10 +607,13 @@ cp_msg_cm_get_key_cnf_receive (cp_t *ctx, cp_mme_rx_t *mme,
/* Check EKS field is correctly set according to KEY_TYPE. */
switch (data->key_type)
{
+ /* In EoC TEK is used for auth confirm (request double key). */
+ /* EOC specific. */
+ case CP_MSG_KEY_TEK:
+ break;
/* DAK, TEK, Nonce are not permitted. */
case CP_MSG_KEY_DAK:
case CP_MSG_KEY_NONCE_ONLY:
- case CP_MSG_KEY_TEK:
return false;
break;
case CP_MSG_KEY_NEK:
diff --git a/cesar/cp/msg/src/msg_drv.c b/cesar/cp/msg/src/msg_drv.c
index 98db473794..c0caacbc63 100644
--- a/cesar/cp/msg/src/msg_drv.c
+++ b/cesar/cp/msg/src/msg_drv.c
@@ -19,6 +19,7 @@
#include "cp/msg/inc/msg_drv.h"
#include "cp/msg/inc/msg.h"
+#include "config/cp/msg/eoc/drv/mme.h"
#include "common/defs/igmp.h"
/**
@@ -288,6 +289,33 @@ cp_msg_drv_sta_set_avln_hfid_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
CP_HFID_SIZE);
}
+// #if CONFIG_CP_MSG_EOC_DRV_MME
+// /**
+// * Receive a DRV_STA_SET_TONEMASK.REQ.
+// * FIXME
+// * \param ctx control plane context
+// * \param mme MME handle
+// * \param tonemask received tonemask
+// * \return true on success
+// */
+// bool
+// cp_msg_drv_sta_set_tonemask_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+// u32 *tonemask)
+// {
+// dbg_assert (ctx);
+// dbg_assert (mme);
+// dbg_assert (tonemask);
+// uint i;
+//
+// if (cp_msg_mme_read_error (ctx, mme))
+// {
+// for(i = 0; i < PHY_TONEMASK_WORDS; i++)
+// tonemask[i] = bitstream_read(&mme->bitstream, 32);
+// return true;
+// }
+// return false;
+// }
+// #else
/**
* Receive a DRV_STA_SET_TONEMASK.REQ.
* \param ctx control plane context
@@ -351,6 +379,7 @@ cp_msg_drv_sta_set_tonemask_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
}
return false;
}
+// #endif
/**
* Receive a DRV_STA_MAC_START.REQ.
@@ -459,6 +488,47 @@ cp_msg_drv_sta_set_config_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
return false;
}
+bool
+cp_msg_drv_sta_set_slave_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ char config[HPAV_MME_PAYLOAD_MAX_SIZE])
+{
+ /* Check parameters. */
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (config);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ /* Read configuration string. */
+ uint config_len =
+ bitstream_read_str (&mme->bitstream, config,
+ HPAV_MME_PAYLOAD_MAX_SIZE);
+ /* Message must be lower than HPAV_MME_PAYLOAD_MAX_SIZE. */
+ if (config_len != HPAV_MME_PAYLOAD_MAX_SIZE)
+ /* No check is done for the last character, bitstream_read_str
+ * will stop when it found it (or when there is no more space). */
+ return true;
+ }
+ return false;
+}
+
+bool
+cp_msg_drv_sta_set_eoc_req_receive (cp_t *ctx, cp_mme_rx_t *mme, uint *exp,
+ uint *value)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *exp = bitstream_read (&mme->bitstream, 8);
+ *value = bitstream_read (&mme->bitstream, 16);
+ *exp = *exp & 0x0f;
+ return true;
+ }
+ return false;
+}
+
void
cp_msg_drv_sta_set_key_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
cp_key_t nmk,
@@ -661,6 +731,39 @@ cp_msg_drv_sta_set_avln_hfid_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
cp_msg_mme_send (ctx, msg);
}
+/**
+ * Send a DRV_STA_STATUS_IND.
+ * \param ctx control plane context
+ * \param peer peer information
+ * \param mmtype MMTYPE to respond to
+ * \param state state of the station (unassociated, associated, authenticated)
+ */
+void
+cp_msg_drv_get_status_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype, cp_eoc_sta_state_t state)
+{
+ cp_mme_tx_t *msg;
+
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+
+ u8 cco = 0;
+ u8 prefered_cco = 0;
+ u8 backup_cco = 0;
+ u8 simple_connect = 0;
+
+ msg = cp_msg_mme_init (ctx, peer, mmtype);
+ dbg_check (msg);
+
+ bitstream_access (&msg->bitstream, &state, 8);
+ bitstream_access (&msg->bitstream, &cco, 8);
+ bitstream_access (&msg->bitstream, &prefered_cco, 8);
+ bitstream_access (&msg->bitstream, &backup_cco, 8);
+ bitstream_access (&msg->bitstream, &simple_connect, 8);
+
+ cp_msg_mme_send (ctx, msg);
+}
+
bool
cp_msg_drv_mcast_set_list_req_receive (
cp_t *ctx, cp_mme_rx_t *mme, uint *nb_groups,
diff --git a/cesar/cp/msg/src/msg_vs_eoc.c b/cesar/cp/msg/src/msg_vs_eoc.c
new file mode 100644
index 0000000000..aeff7517b6
--- /dev/null
+++ b/cesar/cp/msg/src/msg_vs_eoc.c
@@ -0,0 +1,626 @@
+/* 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 "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/msg/inc/msg_vs_eoc.h"
+#include "cp/msg/inc/msg.h"
+
+
+/**
+ * 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 (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,
+ u8 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);
+ bitstream_write (&mme->bitstream, 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, 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_actions);
+
+ uint number_of_stations; /* Number of stations in the current MME */
+ 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(&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, cp_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 (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, 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_actions);
+
+ /* One MME can contain maximum of 43 WL entries*/
+ total_wl_index_nb = numStas;
+
+ if (first_wl_index_nb > total_wl_index_nb)
+ wl_index_nb = 0;
+ else
+ wl_index_nb = ((total_wl_index_nb - first_wl_index_nb) >= 43) ?
+ 43 : total_wl_index_nb - first_wl_index_nb;
+
+ tx = cp_msg_mme_init (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(&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 (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, cp_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 (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_ports_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *first_mac_index_nb)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *first_mac_index_nb = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+
+void
+cp_msg_vs_eoc_cco_get_ports_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_msg_vs_eoc_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)
+{
+ cp_mme_tx_t *tx;
+ u8 i,j;
+ u8 entries_per_mme_nb;
+ u8 total_macs_index_nb;
+ u8 macs_index_nb;
+ dbg_assert (ctx);
+ dbg_assert (stas_macs);
+ dbg_assert(stas_port_ed);
+ dbg_assert(stas_port_service);
+
+ /* One mme can contain 1492 bytes. The first 4 bytes are: result, total_macs_index_nb, first_mac_index_nb
+ and macs_index_nb. There are 1488 bytes remaining. Each entry begins with 6 bytes for a mac address,
+ followed by 2 bytes for each port (one for stas_port_ed and the other one for stas_port_service). */
+
+ entries_per_mme_nb = 1488/(6 + 2 * PORT_NB) - 1;
+ total_macs_index_nb = numStas;
+
+ if (first_mac_index_nb > total_macs_index_nb)
+ macs_index_nb = 0;
+ else
+ macs_index_nb = ((total_macs_index_nb - first_mac_index_nb) >= entries_per_mme_nb) ?
+ entries_per_mme_nb : total_macs_index_nb - first_mac_index_nb;
+
+ tx = cp_msg_mme_init (ctx, peer, VS_EOC_GET_PORTS_CNF);
+ dbg_assert (tx);
+ bitstream_write (&tx->bitstream, result, 8);
+ bitstream_write (&tx->bitstream, total_macs_index_nb, 8);
+ bitstream_write (&tx->bitstream, first_mac_index_nb, 8);
+ bitstream_write (&tx->bitstream, macs_index_nb, 8);
+ for (i = first_mac_index_nb; i < first_mac_index_nb + macs_index_nb; i++)
+ {
+ bitstream_write_large(&tx->bitstream, stas_macs[i], 48);
+ for(j = 0; j < PORT_NB; j++)
+ {
+ bitstream_write(&tx->bitstream, stas_port_ed[i][j], 8);
+ bitstream_write(&tx->bitstream, stas_port_service[i][j], 8);
+ }
+ }
+
+ cp_msg_mme_send (ctx, tx);
+}
+
+
+bool
+cp_msg_vs_eoc_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_set_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ cp_msg_vs_eoc_set_services_req_result_t result)
+{
+ cp_mme_tx_t *msg;
+
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+
+ msg = cp_msg_mme_init (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_services_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *first_service_index_nb)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *first_service_index_nb = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+void
+cp_msg_vs_eoc_cco_get_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_msg_vs_eoc_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)
+{
+ dbg_assert(ctx);
+ dbg_assert(peer);
+ dbg_assert(service_indexes);
+ dbg_assert(classifier_rules);
+ dbg_assert(classifier_values);
+ dbg_assert(acses);
+ dbg_assert(parameters_numbers);
+ dbg_assert(parameters_lists);
+
+ cp_mme_tx_t *tx;
+ u8 i, j;
+ u8 total_services_index_nb;
+ u8 services_index_nb;
+
+ total_services_index_nb = services_number;
+
+ /* One MME can contain maximum of 73 services entries. One mme can contain 1492 bytes. The first 4 bytes are:
+ result, total_services_index_nb, first_service_index_nb and services_index_nb. There are 1488 bytes remaining.
+ Each entry contains 20 bytes. */
+
+ if (first_service_index_nb > total_services_index_nb)
+ services_index_nb = 0;
+ else
+ services_index_nb = ((total_services_index_nb - first_service_index_nb) >= 73) ?
+ 73 : total_services_index_nb - first_service_index_nb;
+
+ tx = cp_msg_mme_init (ctx, peer, VS_EOC_GET_SERVICES_CNF);
+ dbg_assert (tx);
+ bitstream_write (&tx->bitstream, result, 8);
+ bitstream_write (&tx->bitstream, total_services_index_nb, 8);
+ bitstream_write (&tx->bitstream, first_service_index_nb, 8);
+ bitstream_write (&tx->bitstream, services_index_nb, 8);
+
+ for (i = first_service_index_nb; i < first_service_index_nb + services_index_nb; i++)
+ {
+ bitstream_write(&tx->bitstream, service_indexes[i], 8);
+ bitstream_write(&tx->bitstream, classifier_rules[i], 8);
+ bitstream_write(&tx->bitstream, classifier_values[i], 16);
+ bitstream_write(&tx->bitstream, acses[i], 8);
+ bitstream_write(&tx->bitstream, parameters_numbers[i], 8);
+ for(j = 0; j < parameters_numbers[i]; j++)
+ {
+ bitstream_write(&tx->bitstream, parameters_lists[i][j], 16);
+ }
+ }
+
+ cp_msg_mme_send (ctx, tx);
+}
+
+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, u8 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);
+
+ cp_mme_tx_t *tx;
+ tx = cp_msg_mme_init (ctx, peer, VS_EOC_GET_INFO_CNF);
+ dbg_assert (tx);
+
+ bitstream_write (&tx->bitstream, status, 8);
+ bitstream_write (&tx->bitstream, tei, 16);
+ bitstream_write (&tx->bitstream, attenuation, 8);
+ bitstream_write (&tx->bitstream, snr, 8);
+ bitstream_write (&tx->bitstream, phy_uplink_speed, 16);
+ bitstream_write (&tx->bitstream, phy_downlink_speed, 16);
+ bitstream_write (&tx->bitstream, output_power, 8);
+ bitstream_write (&tx->bitstream, tx_success_counter, 32);
+ bitstream_write (&tx->bitstream, tx_crc_error_counter, 32);
+ bitstream_write (&tx->bitstream, tx_other_error_counter, 32);
+ bitstream_write (&tx->bitstream, rx_success_counter, 32);
+ bitstream_write (&tx->bitstream, rx_crc_error_counter, 32);
+ bitstream_write (&tx->bitstream, rx_other_error_counter, 32);
+
+ cp_msg_mme_send (ctx, tx);
+}
+
+
+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);
+
+ cp_mme_tx_t *tx;
+ tx = cp_msg_mme_init (ctx, peer, VS_EOC_DIAGNOSTIC_INFO_CNF);
+ dbg_assert (tx);
+
+ bitstream_write (&tx->bitstream, status, 8);
+ bitstream_write (&tx->bitstream, assoc_stat, 8);
+ bitstream_write_large (&tx->bitstream, nid, 56);
+ bitstream_write (&tx->bitstream, num_slots, 8);
+ bitstream_write_large (&tx->bitstream, he_mac_address, 48);
+ bitstream_write (&tx->bitstream, est_avg_phy_rate, 16);
+ bitstream_write (&tx->bitstream, num_good_assoc_auth, 8);
+ bitstream_write (&tx->bitstream, num_bad_could_not_assoc, 16);
+ bitstream_write (&tx->bitstream, num_bad_assoc_failure, 32);
+ bitstream_write (&tx->bitstream, num_bad_could_not_auth, 32);
+ bitstream_write (&tx->bitstream, num_leave, 32);
+
+ cp_msg_mme_send (ctx, tx);
+}
+
+
+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);
+
+ if (cp_msg_mme_read_error (ctx, mme))
+ {
+ *control = bitstream_read(&mme->bitstream, 8);
+ return true;
+ }
+ return false;
+}
+
+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_stats_req_result_t status, real_time_stats_t *rt_stats)
+{
+ dbg_assert(ctx);
+ dbg_assert(peer);
+
+ cp_mme_tx_t *tx;
+ tx = cp_msg_mme_init (ctx, peer, VS_EOC_GET_REAL_TIME_STATS_CNF);
+ dbg_assert (tx);
+
+ bitstream_write (&tx->bitstream, status, 8);
+ bitstream_write (&tx->bitstream, rt_stats->nb_unicast_packets_rx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_unicast_packets_tx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->total_nb_bytes_rx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->total_nb_bytes_tx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_broadcast_packets_rx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_broadcast_packets_tx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_multicast_packets_rx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_multicast_packets_tx, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_packets_rx_crc, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_packets_rx_short, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_packets_tx_short, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_packets_tx_dropped, 32);
+ bitstream_write (&tx->bitstream, rt_stats->nb_packets_rx_discarded, 32);
+ bitstream_write (&tx->bitstream, rt_stats->avg_pre_fec_bit_error_rate, 32);
+
+ cp_msg_mme_send (ctx, tx);
+}
+
diff --git a/cesar/cp/msg/stub/Module b/cesar/cp/msg/stub/Module
index fbb8b7de5e..6af2144b10 100644
--- a/cesar/cp/msg/stub/Module
+++ b/cesar/cp/msg/stub/Module
@@ -1 +1,5 @@
SOURCES:= mme.c msg.c msg_cc.c msg_cm.c msg_drv.c msg_vs.c
+
+ifeq ($(CONFIG_CP_MSG_EOC_VS),y)
+SOURCES += msg_vs_eoc.c
+endif
diff --git a/cesar/cp/msg/stub/src/msg_cc.c b/cesar/cp/msg/stub/src/msg_cc.c
index 99b8b4d753..cd8baf4a58 100644
--- a/cesar/cp/msg/stub/src/msg_cc.c
+++ b/cesar/cp/msg/stub/src/msg_cc.c
@@ -532,3 +532,9 @@ cp_msg_cc_handover_info_rsp_receive (cp_t *ctx, cp_mme_rx_t *mme)
{
return true;
}
+
+void
+cp_msg_cc_relay_req_send_finalise (cp_t *ctx, cp_mme_tx_t *msg)
+{
+}
+
diff --git a/cesar/cp/msg/stub/src/msg_drv.c b/cesar/cp/msg/stub/src/msg_drv.c
index 7624addd4a..95d070b014 100644
--- a/cesar/cp/msg/stub/src/msg_drv.c
+++ b/cesar/cp/msg/stub/src/msg_drv.c
@@ -197,3 +197,52 @@ cp_msg_drv_sta_set_key_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
cp_security_level_t sl)
{
}
+
+bool
+cp_msg_drv_sta_set_config_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ char config[HPAV_MME_PAYLOAD_MAX_SIZE])
+{
+ /* Check parameters. */
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (config);
+
+ return true;
+}
+
+void
+cp_msg_drv_sta_get_key_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ const cp_msg_drv_sta_get_key_t *data)
+{
+ dbg_assert (ctx);
+ dbg_assert (data);
+}
+
+void
+cp_msg_drv_get_status_ind_send (cp_t *ctx, cp_mme_peer_t *peer,
+ cp_mmtype_t mmtype, cp_eoc_sta_state_t state)
+{
+ dbg_assert (peer);
+ dbg_assert (mmtype);
+}
+
+bool
+cp_msg_drv_sta_get_key_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ return true;
+}
+
+bool
+cp_msg_drv_sta_set_slave_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ char config[HPAV_MME_PAYLOAD_MAX_SIZE])
+{
+ /* Check parameters. */
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (config);
+
+ return true;
+}
diff --git a/cesar/cp/msg/stub/src/msg_vs_eoc.c b/cesar/cp/msg/stub/src/msg_vs_eoc.c
new file mode 100644
index 0000000000..d0696a1741
--- /dev/null
+++ b/cesar/cp/msg/stub/src/msg_vs_eoc.c
@@ -0,0 +1,207 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/msg_vs_eoc.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "cp/cp.h"
+#include "cp/msg/msg.h"
+#include "cp/msg/inc/msg.h"
+#include "cp/msg/inc/vs_eoc_get_topo.h"
+
+bool
+cp_msg_vs_eoc_get_topo_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
+ __attribute__((weak));
+
+bool
+cp_msg_vs_eoc_get_topo_req_receive (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ return true;
+}
+
+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)
+ __attribute__((weak));
+
+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)
+{
+ return NULL;
+}
+
+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,
+ u8 up_att)
+ __attribute__((weak));
+
+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,
+ u8 up_att) {}
+
+void
+cp_msg_vs_eoc_get_topo_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme)
+ __attribute__((weak));
+
+void
+cp_msg_vs_eoc_get_topo_cnf_send_end (cp_t *ctx, cp_mme_tx_t *mme) {}
+
+
+bool
+cp_msg_eoc_sta_vs_set_out_lev_ind_receive(cp_t *ctx, cp_mme_rx_t *mme,
+ uint *output_level) __attribute__((weak));
+
+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);
+
+ return true;
+}
+
+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);
+
+ return true;
+}
+
+void
+cp_msg_vs_eoc_cco_set_out_lev_ind_send(cp_t *ctx, cp_mme_peer_t *peer, uint output_level)
+{
+
+}
+
+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);
+
+ return true;
+}
+
+void
+cp_msg_vs_eoc_set_ports_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ int result)
+{
+
+}
+
+bool
+cp_msg_vs_eoc_cco_get_ports_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
+ u8 *first_mac_index_nb)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ return true;
+}
+
+bool
+cp_msg_vs_eoc_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[][7])
+{
+ return true;
+}
+
+void
+cp_msg_vs_eoc_cco_get_ports_cnf_send (cp_t *ctx, cp_mme_peer_t *peer,
+ int result, uint numStas, mac_t *stas_macs,
+ bool stas_port_ed[][PORT_NB], u8 stas_port_service[][PORT_NB], u8 first_mac_index_nb)
+{
+
+}
+
+void
+cp_msg_vs_eoc_set_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, cp_mmtype_t mmtype,
+ int result)
+{
+
+}
+
+bool
+cp_msg_vs_eoc_cco_get_services_req_receive (cp_t *ctx, cp_mme_rx_t *mme, u8 *first_service_index_nb)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+ return true;
+}
+
+void
+cp_msg_vs_eoc_cco_get_services_cnf_send (cp_t *ctx, cp_mme_peer_t *peer, int result,
+ u8 services_number, u8 *service_indexes, u8 *classifier_rules, u16 *classifier_values,
+ u8 *acses, u8 *parameters_numbers, u16 (*parameters_lists)[7], u8 first_service_index_nb)
+{
+
+}
+
+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);
+
+ return true;
+}
+
+void
+cp_msg_vs_eoc_cco_get_info_cnf_send(cp_t *ctx, cp_mme_peer_t *peer, int status,
+ u16 tei, u8 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)
+{
+
+}
+
+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);
+
+ return true;
+}
+
+void
+cp_msg_vs_eoc_cco_diagnostict_info_cnf_send(cp_t *ctx, cp_mme_peer_t *peer, int 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)
+{
+
+}
+
+bool
+cp_msg_drv_sta_set_eoc_req_receive (cp_t *ctx, cp_mme_rx_t *mme, uint *exp,
+ uint *value)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme);
+
+return true;
+}
diff --git a/cesar/cp/msg/test/Config b/cesar/cp/msg/test/Config
index dbdade324f..cc0ce01fc1 100644
--- a/cesar/cp/msg/test/Config
+++ b/cesar/cp/msg/test/Config
@@ -1 +1,2 @@
CONFIG_DEBUG_FATAL_CATCH=y
+CONFIG_CL_EOC_ROUTE = n
diff --git a/cesar/cp/msg/test/Makefile b/cesar/cp/msg/test/Makefile
index a09ff9db54..db4c26ec12 100644
--- a/cesar/cp/msg/test/Makefile
+++ b/cesar/cp/msg/test/Makefile
@@ -32,6 +32,7 @@ test_drv_msg_SOURCES = msg_drv.c interface_stub.c \
test_drv_msg_MODULES = lib cp/msg cp/secu mac/common cp/sta/mgr cp/fsm/stub \
cp/sta/core/stub cp/cco/action/stub mac/sar/stub \
cl/stub bsu/stub
+test_drv_msg_CONFIG_MODULES = cl
test_cc_discover_list_SOURCES = cc_discover_list.c interface_stub.c misc_stub.c
test_cc_discover_list_MODULES = lib cp/msg cp/secu mac/common cp/sta/mgr \
@@ -42,7 +43,7 @@ relay_SOURCES = relay.c interface_stub.c misc_stub.c
relay_MODULES = lib cp/msg cp/secu mac/common cp/sta/mgr \
cp/fsm/stub cp/sta/core/stub cp/cco/action/stub \
cl/stub bsu/stub mac/sar/stub
-
+
test_vs_msg_SOURCES = msg_vs.c interface_stub.c misc_stub.c
test_vs_msg_MODULES = lib cp/msg cp/secu mac/common cp/sta/mgr \
cp/fsm/stub cp/sta/core/stub cp/cco/action/stub \
diff --git a/cesar/cp/msg/test/src/cc_discover_list.c b/cesar/cp/msg/test/src/cc_discover_list.c
index bc131dc30c..f759ae9047 100644
--- a/cesar/cp/msg/test/src/cc_discover_list.c
+++ b/cesar/cp/msg/test/src/cc_discover_list.c
@@ -223,6 +223,7 @@ test_case__cc_discover_list_cnf_send (test_t test)
test_begin (test, "Complex discover list")
{
+
cp_t cp;
uint nb_sta = 150;
uint nb_net = 2;
@@ -291,8 +292,9 @@ test_case__cc_discover_list_cnf_send (test_t test)
cp_msg_cc_discover_list_cnf_send_end (&cp, mme);
/* Verify. */
- test_fail_if (*(buffer_first + 19) != nb_sta);
- test_fail_if (*(buffer_second + 321) != nb_net);
+ test_fail_if (*(buffer_first + HPAV_MME_HEADER) != nb_sta);
+ test_fail_if (*(buffer_second + 2 * HPAV_MME_HEADER + 12 * nb_sta
+ + 1 - ETH_PACKET_MAX_SIZE) != nb_net);
bitstream_read_init (&bitstream, buffer_first + 20,
ETH_PACKET_MAX_SIZE - 20);
@@ -331,8 +333,10 @@ test_case__cc_discover_list_cnf_send (test_t test)
}
bitstream_finalise (&bitstream);
- bitstream_read_init (&bitstream, buffer_second + 322,
- ETH_PACKET_MAX_SIZE - 322);
+ bitstream_read_init (&bitstream, buffer_second + 2 * HPAV_MME_HEADER
+ + 12 * nb_sta + 2 - ETH_PACKET_MAX_SIZE,
+ 2 * ETH_PACKET_MAX_SIZE - (2 * HPAV_MME_HEADER
+ + 2 + 12 * nb_sta));
for ( i = 0; i < nb_net; i++)
{
memset (&net_read, 0, sizeof (cp_msg_cc_discover_list_net_t));
diff --git a/cesar/cp/msg/test/src/mme_frag.c b/cesar/cp/msg/test/src/mme_frag.c
index 871fd14be8..41ea4d8c72 100644
--- a/cesar/cp/msg/test/src/mme_frag.c
+++ b/cesar/cp/msg/test/src/mme_frag.c
@@ -60,6 +60,7 @@ test_case_msg_cc_set_tei_map_frag (test_t test)
cp_t cp;
mac_config_t mac_config;
cp_mme_rx_t msg_rx;
+ lib_rnd_init (&cp.rnd, 0x12345678);
mac_t mac;
cp_tei_t tei;
@@ -233,8 +234,10 @@ test_case_msg_cc_handover_info_ind (test_t test)
head->length = BLK_SIZE;
head->next->length = BLK_SIZE;
- head->next->next->length = 475;
- head->next->next->next->length = 304;
+ head->next->next->length = (ETH_PACKET_MAX_SIZE
+ - HPAV_MME_HEADER - 2 * BLK_SIZE);
+ head->next->next->next->length = (nb_sta * 9 + 3 + HPAV_MME_HEADER)
+ - ETH_PACKET_MAX_SIZE;
for (current = head, offset = 19, length = ETH_PACKET_MAX_SIZE;
offset < length && current != NULL;
diff --git a/cesar/cp/msg/test_eoc/Config b/cesar/cp/msg/test_eoc/Config
new file mode 100644
index 0000000000..8890069329
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/Config
@@ -0,0 +1,7 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_CL_EOC_ROUTE = y
+
diff --git a/cesar/cp/msg/test_eoc/Makefile b/cesar/cp/msg/test_eoc/Makefile
new file mode 100644
index 0000000000..adb523b526
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/Makefile
@@ -0,0 +1,30 @@
+BASE = ../../..
+
+INCLUDES = cp/msg/test_eoc/overide/ cp/sta/core/stub/
+
+HOST_PROGRAMS = test_vs_eoc_msg test_msg_cc_eoc
+
+test_vs_eoc_msg_SOURCES = msg_vs_eoc.c interface_stub.c
+test_vs_eoc_msg_MODULES = lib cp/msg cp/secu mac/common cp/sta/mgr \
+ cp/fsm/stub cp/sta/core/stub cp/cco/action/stub \
+ cl/stub mac/sar/stub cp/eoc/cco/action/stub cp/eoc/sta/mgr \
+ bsu/stub
+test_vs_eoc_msg_CONFIG_MODULES = cp/eoc/multi_sta_fsm
+
+
+
+
+
+
+
+test_msg_cc_eoc_SOURCES = msg_cc_eoc.c interface_stub.c
+test_msg_cc_eoc_MODULES = lib cp/msg cp/secu mac/common cp/sta/mgr cp/fsm/stub \
+ cp/sta/core/stub cp/cco/action/stub mac/sar/stub \
+ cl/stub cp/eoc/cco/action/stub cp/eoc/sta/mgr cp/cl_interf\
+ interface/stub bsu/stub
+test_msg_cc_eoc_CONFIG_MODULES = cl
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+
+include $(BASE)/common/make/top.mk
+
diff --git a/cesar/cp/msg/test_eoc/doc/Makefile b/cesar/cp/msg/test_eoc/doc/Makefile
new file mode 100644
index 0000000000..50006394a5
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/doc/Makefile
@@ -0,0 +1,20 @@
+PAGES = read-header.txt
+
+ODT=$(PAGES:%.txt=%.odt)
+HTML=$(PAGES:%.txt=%.html)
+
+all: $(ODT) $(HTML)
+
+odt: $(ODT)
+
+html: $(HTML)
+
+%.odt: %.txt
+ rst2odt.py $< $@
+
+%.html: %.txt
+ rst2html $< $@
+
+clean:
+ rm -f $(ODT)
+ rm -f $(HTML)
diff --git a/cesar/cp/msg/test_eoc/doc/read-header.txt b/cesar/cp/msg/test_eoc/doc/read-header.txt
new file mode 100644
index 0000000000..24eb81f982
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/doc/read-header.txt
@@ -0,0 +1,67 @@
+MSG read MME header
+===================
+
+ MME used for the test with :
+
+* a length of 92 bytes.
+* TEI = 1
+
++-------+-------------------+-----------------+
+|Name | Value | length (bytes) |
++-------+-------------------+-----------------+
+|oda | 12:34:56:78:9A:BC | 6 |
++-------+-------------------+-----------------+
+|osa | 34:56:78:9A:BC:DE | 6 |
++-------+-------------------+-----------------+
+|[vlan] | 0x12 | 4 |
++-------+-------------------+-----------------+
+|Mtype | 0x88E1 | 2 |
++-------+-------------------+-----------------+
+|MMV | 0x1 | 1 |
++-------+-------------------+-----------------+
+|MMTYPE | 0x3245 | 2 |
++-------+-------------------+-----------------+
+|FMI | 0x432 | 2 |
++-------+-------------------+-----------------+
+
+Test 1 : Read a MME with a VLAN tag.
+------------------------------------
+
+The result shall be the following one.
+
+The MME rx object returned shall not be NULL and shall contain:
+
+* p_mme = buffer address containing the MME.
+* mmtype = 0x3245
+* length = 92.
+* peer
+
+ * mac = 34:56:78:9A:BC:DE
+ * vlan = 0x12
+ * tei = 1 (provided in argument).
+
+Test 2 : Read a MME without a VLAN tag.
+---------------------------------------
+
+The result shall be the following one.
+
+The MME rx object returned shall not be NULL and shall contain:
+
+* p_mme = buffer address containing the MME.
+* mmtype = 0x3245
+* length = 92.
+* peer
+
+ * mac = 34:56:78:9A:BC:DE
+ * vlan = 0
+ * tei = 1 (provided in argument).
+
+Test 3 : Read a MME with the MMV equal to 0
+-------------------------------------------
+
+The returned value shall be NULL.
+
+Test 4 : Read the MME with MType different of 0x88E1
+----------------------------------------------------
+
+The returned value shall be NULL.
diff --git a/cesar/cp/msg/test_eoc/overide/cp/inc/context.h b/cesar/cp/msg/test_eoc/overide/cp/inc/context.h
new file mode 100644
index 0000000000..d00a34dd38
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/overide/cp/inc/context.h
@@ -0,0 +1,71 @@
+#ifndef overide_cp_inc_context_h
+#define overide_cp_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/cp/inc/context.h
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+
+#define TCK_PER_RTC 250000
+#define BEACON_PERIOD_TCK BSU_ACLF_BP_50HZ_TCK
+
+#include "lib/rnd.h"
+#include "cp/msg/inc/context.h"
+#include "cl/cl.h"
+
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/inc/sta_mgr.h"
+
+#include "cp/fsm/fsm.h"
+
+#include "cp/cl_interf/cl_interf.h"
+#include "cp/cl_interf/inc/context.h"
+
+#include "mac/common/config.h"
+#include "mac/common/store.h"
+
+struct cp_t
+{
+ /** MSG context. */
+ cp_msg_t msg;
+
+ /** Interface context. */
+ interface_t *interface;
+
+ /** Station Manager. */
+ cp_sta_mgr_t sta_mgr;
+
+ /** Convergence layer context. */
+ cl_t *cl;
+
+ /** Random generator. */
+ lib_rnd_t rnd;
+
+ /** Mac config. */
+ mac_config_t *mac_config;
+
+ /** Store. */
+ mac_store_t *mac_store;
+
+ /** SAR context. */
+ sar_t *sar;
+
+ /** BSU context. */
+ bsu_t *bsu;
+
+ /** BSU. */
+ bsu_aclf_t *bsu_aclf;
+
+ cp_cl_interf_t cl_interf;
+};
+
+#endif /* overide_cp_inc_context_h */
diff --git a/cesar/cp/msg/test_eoc/overide/mac/sar/inc/context.h b/cesar/cp/msg/test_eoc/overide/mac/sar/inc/context.h
new file mode 100644
index 0000000000..9e7c6f07ca
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/overide/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) 2008 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/msg/test_eoc/src/interface_stub.c b/cesar/cp/msg/test_eoc/src/interface_stub.c
new file mode 100644
index 0000000000..bff881ea6f
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/src/interface_stub.c
@@ -0,0 +1,27 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/interface_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+#include "cp/cp.h"
+
+/**
+ * Inform the Data plane when the MME as been processed by the CP.
+ * \param ctx the interface context
+ * \param mme_recv the cl data (as a void pointer).
+ */
+void
+interface_mme_recv_done (interface_t *ctx, void *mme_recv)
+{
+}
diff --git a/cesar/cp/msg/test_eoc/src/msg_cc_eoc.c b/cesar/cp/msg/test_eoc/src/msg_cc_eoc.c
new file mode 100644
index 0000000000..8344b3eeae
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/src/msg_cc_eoc.c
@@ -0,0 +1,133 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/test/src/msg_cc.c
+ * \brief Test the MSG_CC Family functions.
+ * \ingroup cp_msg
+ *
+ */
+#include "common/std.h"
+
+#include "common/defs/ethernet.h"
+#include "common/defs/homeplugAV.h"
+
+#include "lib/test.h"
+#include "lib/swap.h"
+#include "lib/bitstream.h"
+
+#include "cp/cp.h"
+#include "cp/msg/msg.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/sta/mgr/sta_own_data.h"
+
+#include "cp/inc/context.h"
+#include "cp/msg/inc/msg.h"
+
+#include "stdio.h"
+
+#include "mac/sar/inc/context.h"
+#include "cl/inc/context.h"
+
+
+
+
+static u8 buffer[256] __attribute__((aligned(256)));
+cp_t cp;
+bitstream_t stream;
+test_t test;
+bool fsm_post;
+
+void
+test_case_msg_dispatch (void)
+{
+ test_case_begin (test, "MSG Dispatch");
+
+ test_begin (test, "MSG dispatch STA does not exists")
+ {
+ cp_mme_rx_t *mme_rx;
+ //uint fmi;
+ cl_t cl;
+ sar_t sar;
+ bitstream_t bitstream;
+ uint req_type = CP_MSG_CC_ASSOC_REQ_TYPE_NEW;
+ u64 nid = 12;
+ uint cco_cap = 2;
+ uint pco_cap = true;
+
+ cp_sta_mgr_init (&cp);
+ cp_msg_init (&cp);
+ cl.mactotei = NULL;
+ sar.mac_store = mac_store_init ();
+ cp.sar = &sar;
+ cp.mac_store = sar.mac_store;
+ cp.cl = &cl;
+
+ mme_rx = cp_msg_mme_rx_init (&cp, buffer, 60, MAC_TEI_UNASSOCIATED, false);
+ mme_rx->peer.mac = 2;
+ mme_rx->peer.vlan_tag = 0;
+ mme_rx->peer.tei = 0;
+ mme_rx->mmtype = CC_ASSOC_REQ;
+
+ // 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_rx->p_mme = buffer;
+ mme_rx->length = 60;
+ bitstream_init (&mme_rx->bitstream, buffer + 19, 60, BITSTREAM_READ);
+
+ /* Test */
+ fsm_post = false;
+ cp_msg_dispatch (&cp, mme_rx);
+ test_fail_if (fsm_post != false);
+
+ cp_msg_uninit (&cp);
+ }
+ test_end;
+
+}
+
+int
+main (void)
+{
+
+ test_init (test, 0, NULL);
+ lib_stats_init ();
+
+ test_case_msg_dispatch ();
+
+ lib_stats_uninit ();
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
+
+u32
+bsu_aclf_beacon_period_tck (bsu_aclf_t *ctx)
+{
+ return BSU_ACLF_BP_50HZ_TCK;
+}
+
+u32
+cyg_current_time (void)
+{
+ /* For tests purpose we can simulate 1000 beacon periods */
+ return (u32)((BSU_ACLF_BP_50HZ_TCK * 1000ull) / TCK_PER_RTC);
+}
+
+
+u32
+cp_sta_core_tck_per_rtc (cp_t *ctx)
+{
+
+ return TCK_PER_RTC;
+}
diff --git a/cesar/cp/msg/test_eoc/src/msg_vs_eoc.c b/cesar/cp/msg/test_eoc/src/msg_vs_eoc.c
new file mode 100644
index 0000000000..a97d213672
--- /dev/null
+++ b/cesar/cp/msg/test_eoc/src/msg_vs_eoc.c
@@ -0,0 +1,316 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/test/src/msg_vs_eoc.c
+ * \brief Test the MSG_VS_EOC Family functions.
+ * \ingroup cp_msg
+ *
+ */
+
+#include "common/std.h"
+
+#include "common/defs/ethernet.h"
+#include "common/defs/homeplugAV.h"
+
+#include "lib/test.h"
+#include "lib/bitstream.h"
+
+#include "cp/cp.h"
+#include "cp/msg/msg.h"
+
+#include "cp/inc/context.h"
+#include "cp/msg/inc/msg.h"
+#include "cp/msg/inc/vs_eoc_get_topo.h"
+
+struct mme_header_t
+{
+ mac_t oda;
+ mac_t osa;
+ uint vlan;
+ uint mtype;
+ uint mmv;
+ cp_mmtype_t mmtype;
+ uint fmi_inf;
+ uint fmi_mi;
+ uint fmi_ssn;
+};
+typedef struct mme_header_t mme_header_t;
+
+static u8 buffer[2048] __attribute__((aligned(2048)));
+cp_t cp;
+
+mac_t own_mac_addr = 0x123456789ABCull;
+test_t test;
+cp_mme_peer_t peer;
+
+static void
+test_write_header (bool vlan_present, mme_header_t *pheader,
+ bitstream_t *pstream)
+{
+ bitstream_init (pstream, buffer, 1518, BITSTREAM_WRITE);
+
+ bitstream_write_large (pstream, pheader->oda, 48);
+ bitstream_write_large (pstream, pheader->osa, 48);
+ bitstream_write (pstream, swap16 (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);
+}
+
+static void
+test_read_header (bool vlan_present, mme_header_t *pheader,
+ mme_header_t *pexpected, bitstream_t *pstream)
+{
+ bitstream_init (pstream, buffer, 1518, 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 = swap16 (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 (pheader->mmtype >= VS_MIN && pheader->mmtype <= VS_MAX)
+ 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_msg_vs_eoc_get_topo (void)
+{
+ test_case_begin (test, "VS_EOC_GET_TOPO");
+
+ test_begin (test, "VS_EOC_GET_TOPO.CNF Send")
+ {
+ uint i;
+ /* Context. */
+ bitstream_t stream;
+ mme_header_t header;
+ mme_header_t expected;
+
+ u64 data;
+ cp_mme_tx_t *tx_mme;
+ cp_msg_vs_eoc_get_topo_cnf_result_t result;
+
+ cp_msg_init (&cp);
+
+ /*********************************/
+ /* Good values. */
+ /*********************************/
+ result = CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS;
+ u8 sta_nb = 10;
+ u8 auth_status = 1;
+ u8 up_att = 0;
+ mac_t mac_addr = 0x112233445566LL;
+
+ /* Call MME. */
+ tx_mme = cp_msg_vs_eoc_get_topo_cnf_send_begin (&cp, &peer, result,
+ sta_nb);
+
+ for (i = 1; i <= sta_nb ; i++)
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (&cp, tx_mme, mac_addr,
+ auth_status, up_att);
+
+ cp_msg_vs_eoc_get_topo_cnf_send_end (&cp, tx_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");
+
+ for(i = 0 ; i < sta_nb ; i++)
+ {
+ bitstream_access (&stream, &data, 48);
+ test_fail_if ((data != mac_addr),
+ "Wrong mac address [%d]",i);
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != auth_status, "Wrong authorization status [%d]",i);
+ bitstream_access (&stream, &data, 8);
+ test_fail_if (data != up_att, "Wrong upstream attenuation [%d]",i);
+ }
+
+ /*********************************/
+ /* Send the request with bad value of result */
+ /*********************************/
+ dbg_fatal_try_begin
+ {
+ result = CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_NB;
+ tx_mme = cp_msg_vs_eoc_get_topo_cnf_send_begin (&cp, &peer, result,
+ sta_nb);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ test_verbose_print (fatal_message);
+ test_fail_unless (true);
+ }
+ dbg_fatal_try_end;
+
+ /*********************************/
+ /* Send the request with bad value of authorization status */
+ /*********************************/
+ dbg_fatal_try_begin
+ {
+ result = CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS;
+ auth_status = 36;
+ tx_mme = cp_msg_vs_eoc_get_topo_cnf_send_begin (&cp, &peer, result,
+ sta_nb);
+ cp_msg_vs_eoc_get_topo_cnf_send_sta (&cp, tx_mme, mac_addr, auth_status, up_att);
+ }
+ dbg_fatal_try_catch (const char *fatal_message)
+ {
+ slab_release(tx_mme);
+ test_verbose_print (fatal_message);
+ test_fail_unless (true);
+ }
+ dbg_fatal_try_end;
+
+ /* End TEST VS_EOC_GET_TOPO.CNF Send */
+ cp_msg_uninit (&cp);
+ }
+ test_end;
+
+ test_begin (test, "VS_EOC_GET_TOPO.REQ Receive")
+ {
+ /* Context. */
+ bitstream_t stream;
+ mme_header_t header;
+ uint fmi;
+
+ cp_mme_rx_t *rx_mme;
+ cp_msg_init (&cp);
+
+ /* Buil 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, 1518, peer.tei, &fmi, false);
+ test_fail_unless (rx_mme != NULL);
+ test_fail_unless (rx_mme->mmtype == VS_EOC_GET_TOPO_REQ);
+
+ slab_release(rx_mme);
+
+ /* End TEST VS_EOC_GET_TOPO.REQ Receive */
+
+ cp_msg_uninit (&cp);
+ }
+ test_end;
+}
+
+int
+main (void)
+{
+ mac_config_t mac_config;
+
+ test_init (test, 0, NULL);
+ cp.mac_config = &mac_config;
+
+ cp_sta_own_data_set_mac_address (&cp, own_mac_addr);
+
+ peer.mac = 0x23456789ABCDull;
+ peer.vlan_tag = 0x0;
+ peer.tei = MAC_TEI_FOREIGN;
+
+ test_case_msg_vs_eoc_get_topo ();
+
+ test_case_begin (test, "Memory allocation");
+ test_begin (test, "memory leaks")
+ {
+ test_fail_if (blk_check_memory () != true, "Memory leaks");
+ }
+ test_end;
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+
+ return 0;
+}
+
+u8 *
+cp_cl_interf_get_buffer_tx (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ return buffer;
+}
+
+void
+cp_cl_interf_add_buffer_tx (cp_t *ctx, u8 * 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;
+}
+
+u32
+bsu_aclf_beacon_period_tck (bsu_aclf_t *ctx)
+{
+ return BSU_ACLF_BP_50HZ_TCK;
+}
+
+u32
+cyg_current_time (void)
+{
+ /* For tests purpose we can simulate 1000 beacon periods */
+ return (u32)((BSU_ACLF_BP_50HZ_TCK * 1000ull) / TCK_PER_RTC);
+}
+
+
+u32
+cp_sta_core_tck_per_rtc (cp_t *ctx)
+{
+
+ return TCK_PER_RTC;
+}
diff --git a/cesar/cp/pwl/Config b/cesar/cp/pwl/Config
new file mode 100644
index 0000000000..0f265107b9
--- /dev/null
+++ b/cesar/cp/pwl/Config
@@ -0,0 +1 @@
+CONFIG_CP_PWL_EOC=n
diff --git a/cesar/cp/pwl/pwl.h b/cesar/cp/pwl/pwl.h
new file mode 100644
index 0000000000..ae99719ac5
--- /dev/null
+++ b/cesar/cp/pwl/pwl.h
@@ -0,0 +1,181 @@
+#ifndef cp_pwl_h
+#define cp_pwl_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/pwl/pwl.h
+ * \brief The powerline state.
+ * \ingroup cp_pwl
+ *
+ */
+#include "cp/cp.h"
+
+#define CP_PWL_BTO_NB 4
+#define CP_PWL_BP_AVLN_NB CP_PWL_BTO_NB
+#define CP_PWL_TIMER_OFFSET_CCO 500000
+#define CP_PWL_TIMER_OFFSET_STA 1750000
+
+/** Frequency possibility. */
+enum cp_pwl_frequency_t
+{
+ CP_PWL_FREQ_50,
+ CP_PWL_FREQ_60
+};
+typedef enum cp_pwl_frequency_t cp_pwl_frequency_t;
+
+/** Conversion of the frequency to ticks. */
+enum cp_pwl_bp_t
+{
+ CP_PWL_BP_50 = 1000000,
+ CP_PWL_BP_60 = 833333,
+ CP_PWL_BP_EOC = 2500000,
+};
+typedef enum cp_pwl_bp_t cp_pwl_bp_t;
+
+/** Zero cross values. */
+enum cp_pwl_zc_t
+{
+ CP_PWL_ZC_50 = (CP_PWL_BP_50 / 4),
+ CP_PWL_ZC_60 = (CP_PWL_BP_60 / 4)
+};
+typedef enum cp_pwl_zc_t cp_pwl_zc_t;
+
+/** Forward declaration. */
+typedef struct cp_pwl_t cp_pwl_t;
+
+BEGIN_DECLS
+
+/**
+ * Initialise the pwl module.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_pwl_init (cp_t *ctx);
+
+/**
+ * Uninitialise the PWL module.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_pwl_uninit (cp_t *ctx);
+
+/**
+ * Compute the frequency of the power line using the pratic register.
+ * \param ctx the module context.
+ *
+ * It shall read the pratic register twice with a gap of 20 ms. This
+ * function shall update the data in the object. If the medium is a coaxial
+ * cable, the 50Hz will be chosen
+ *
+ * \warn Only call this function in a Thread.
+ */
+void
+cp_pwl_acl_frequency_detection (cp_t *ctx);
+
+/**
+ * Compute the beacon period start time from the data contained in the beacon.
+ * \param ctx the module context.
+ * \param bts the beacon time stamp.
+ * \param bto the four btos present in the beacon.
+ * \param bpsto the beacon period start time offset.
+ */
+void
+cp_pwl__sta__compute_beacon_period_start_time_ntb (cp_t *ctx, const u32 bts,
+ const s16 bto[CP_PWL_BTO_NB],
+ const u32 bpsto);
+
+/**
+ * Compute the beacon period start time from the data contained in the beacon.
+ * \param ctx the module context.
+ */
+void
+cp_pwl__tracker__compute_beacon_period_start_time_ntb (cp_t *ctx);
+
+/**
+ * Get the three values of the beacon period start time.
+ * \param ctx the module context.
+ * \param pos the current, the future, or the next one.
+ * \return An array of CP_PWL_BP_AVLN_NB elements.
+ *
+ * The current one, the two next ones
+ */
+u32
+cp_pwl_get_beacon_period_start_ntb (cp_t *ctx, uint pos);
+
+/**
+ * Get the three values of the beacon period start time.
+ * \param ctx the module context.
+ * \param pos the current, the future, or the next one.
+ * \return An array of CP_PWL_BP_AVLN_NB elements.
+ *
+ * The current one, the two next ones
+ */
+u32
+cp_pwl_get_beacon_period_start_date (cp_t *ctx, uint pos);
+
+/**
+ * Get the estimated value of the beacon period in NTB ticks.
+ * \param ctx the module context.
+ * \return the beacon period int NTB ticks estimated.
+ */
+u32
+cp_pwl_get_beacon_period_ntb (cp_t *ctx);
+
+/**
+ * Get the four BTOs estimated.
+ * \param ctx the module context.
+ * \return The array of four BTO estimated by the CCo.
+ */
+const s16 *
+cp_pwl_get_bto (cp_t *ctx);
+
+/**
+ * Provide the next date to awake.
+ * \param ctx the module context.
+ * \param cco If the station is acting as CCo or not (useful when the
+ * station is Ucco.)
+ * \return Return the next date to program the timer.
+ *
+ * If the station is CCo, it will return a date before the beacon period
+ * end. It the station is CCo it will return a date a quarter after the
+ * beacon period start
+ */
+u32
+cp_pwl_get_next_timer_date (cp_t *ctx, bool cco);
+
+/**
+ * Verify the current ntb date it in the new beacon period or not.
+ * \param ctx the module context.
+ *
+ * Example current ntb_date is 1 200 435 ticks, and the current beacon period
+ * start date is 1 000 000 and the next beacon period start date is 2 000 000,
+ * this function shall return false, because it is still the current beacon
+ * period and not a new one.
+ *
+ * The beacon period start date are accurate when the station receives the
+ * AVLN central beacon or when it is CCo and it generate the central beacon.
+ */
+bool
+cp_pwl_is_new_beacon_period (cp_t *ctx);
+
+/**
+ * Reinit fields needed for fresh start.
+ * \param ctx the module context.
+ *
+ * After MAC_STOP.REQ and MAC_START.REQ time in tracker is stale.
+ * Reinit fields to accept fresh values on first call to functions to
+ * sync local time related to beacon.
+ */
+void
+cp_pwl_reset (cp_t *ctx);
+
+END_DECLS
+
+#endif /* cp_pwl_h */
diff --git a/cesar/cp/pwl/src/pwl.c b/cesar/cp/pwl/src/pwl.c
new file mode 100644
index 0000000000..cd20d259ec
--- /dev/null
+++ b/cesar/cp/pwl/src/pwl.c
@@ -0,0 +1,377 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/pwl/src/pwl.c
+ * \brief Power Line module.
+ * \ingroup cp_pwl
+ *
+ * The Power line module is responsible to keep the station synchronized with
+ * the AC Line Power Line.
+ */
+#include "common/std.h"
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+
+/* Timings, for the macro MAC_MS_TO_TCK*/
+#include "mac/common/timings.h"
+#include "mac/common/ntb.h"
+
+#include "cp/cp.h"
+
+#include "cp/pwl/pwl.h"
+#include "cp/pwl/inc/pwl.h"
+
+#include "cp/inc/context.h"
+#include "cp/inc/trace.h"
+#include "string.h"
+
+#include "config.h"
+
+/**
+ * Initialise the pwl module.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_pwl_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ memset (&ctx->pwl, 0, sizeof (cp_pwl_t));
+
+ if (CONFIG_CP_PWL_EOC)
+ ctx->pwl.cable = true;
+}
+
+/**
+ * Reset some fields in pwl structure.
+ * After MAC_STOP.REQ and MAC_START.REQ
+ * reinitialize fields to set start position.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_pwl_reset (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ if (CONFIG_CP_PWL_EOC)
+ ctx->pwl.cable = true;
+ ctx->pwl.tracking = false;
+}
+
+/**
+ * Uninitialise the PWL module.
+ * \param ctx the module context.
+ *
+ */
+void
+cp_pwl_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+/**
+ * Compute the frequency of the power line using the pratic register.
+ * \param ctx the module context.
+ *
+ * It shall read the pratic register twice with a gap of 20 ms. This
+ * function shall update the data in the object. If the medium is a coaxial
+ * cable, the 50Hz will be chosen
+ *
+ * \warn Only call this function in a Thread.
+ */
+void
+cp_pwl_acl_frequency_detection (cp_t *ctx)
+{
+ uint bp_width_ntb;
+
+ dbg_assert (ctx);
+ dbg_assert (ctx->phy);
+
+ if (!CONFIG_CP_PWL_EOC)
+ {
+ ctx->pwl.date_ntb[1] =
+ phy_clock_get_zero_cross_captured_date(ctx->phy);
+
+ cyg_thread_delay (2);
+ ctx->pwl.date_ntb[0] =
+ phy_clock_get_zero_cross_captured_date(ctx->phy);
+
+ // compute the becon period.
+ bp_width_ntb = (ctx->pwl.date_ntb[0] - ctx->pwl.date_ntb[1] + 5000)
+ % CP_PWL_ZC_50;
+
+ if (bp_width_ntb > 6000)
+ {
+ *((cp_pwl_frequency_t*) &ctx->pwl.frequency) = CP_PWL_FREQ_60;
+ *((cp_pwl_bp_t*) &ctx->pwl.bp_ntb) = CP_PWL_BP_60;
+ *((uint*) &ctx->pwl.zc_ntb) = CP_PWL_ZC_60;
+ }
+ else
+ {
+ *((cp_pwl_frequency_t*) &ctx->pwl.frequency) = CP_PWL_FREQ_50;
+ *((cp_pwl_bp_t*) &ctx->pwl.bp_ntb) = CP_PWL_BP_50;
+ *((uint*) &ctx->pwl.zc_ntb) = CP_PWL_ZC_50;
+ }
+
+ ctx->pwl.cable = (ctx->pwl.date_ntb[0] == ctx->pwl.date_ntb[1]);
+ }
+ else
+ {
+ *((cp_pwl_bp_t*) &ctx->pwl.bp_ntb) = CP_PWL_BP_EOC;
+ }
+
+
+ ctx->pwl.per_ntb = ctx->pwl.bp_ntb;
+ *((uint*) &ctx->pwl.discover_period_max_bp) =
+ MAC_MS_TO_TCK (MAC_SEC_TO_MS(CP_DISCOVER_PERIOD_MAX_S))
+ / ctx->pwl.bp_ntb;
+
+
+ CP_TRACE (PWL_FREQ, phy_date (), ctx->pwl.cable, ctx->pwl.zc_ntb,
+ ctx->pwl.bp_ntb);
+}
+
+/**
+ * Compute the beacon period start time from the data contained in the beacon.
+ * \param ctx the module context.
+ * \param bts the beacon time stamp.
+ * \param bto the four btos present in the beacon.
+ * \param bpsto the beacon period start time offset.
+ */
+void
+cp_pwl__sta__compute_beacon_period_start_time_ntb (cp_t *ctx, const u32 bts,
+ const s16 bto[4],
+ const u32 bpsto)
+{
+ uint i;
+ dbg_assert (ctx);
+
+ ctx->pwl.tracking = false;
+
+ /* Update the bto to the next one. */
+ ctx->pwl.bto[0] = bto[1];
+ ctx->pwl.bto[1] = bto[2];
+ ctx->pwl.bto[2] = bto[3];
+ ctx->pwl.bto[3] = bto[3];
+
+ ctx->pwl.bp_avln_ntb[0] = bts - bpsto;
+ for (i = 1; i < CP_PWL_BP_AVLN_NB; i++)
+ {
+ ctx->pwl.bp_avln_ntb[i] = ctx->pwl.bp_avln_ntb[i-1] + ctx->pwl.bto[i]
+ + ctx->pwl.bp_ntb;
+ }
+
+ ctx->pwl.per_ntb = ctx->pwl.bp_avln_ntb[1] - ctx->pwl.bp_avln_ntb[0];
+
+ CP_TRACE_VERBOSE (PWL_STA_COMP_BPS, phy_date (), ctx->pwl.per_ntb,
+ ctx->pwl.bp_avln_ntb[0], ctx->pwl.bp_avln_ntb[1],
+ ctx->pwl.bp_avln_ntb[2], ctx->pwl.bp_avln_ntb[3]);
+ CP_TRACE_VERBOSE (PWL_STA_COMP_BPS_DATA, bts, bto[0], bto[1], bto[2],
+ bto[3], bpsto);
+}
+
+static inline void
+cp_pwl__tracker__compute_period (cp_t *ctx)
+{
+ uint diff_ntb;
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_config);
+
+ ctx->pwl.date_ntb[1] = ctx->pwl.date_ntb[0];
+ ctx->pwl.date_ntb[0] =
+ phy_clock_get_zero_cross_captured_date (ctx->phy)
+ + ctx->mac_config->ntb_offset_tck;
+
+ diff_ntb = (ctx->pwl.date_ntb[0] - ctx->pwl.date_ntb[1])
+ % (ctx->pwl.bp_ntb + 10000);
+
+ if (diff_ntb <= 3 * ctx->pwl.zc_ntb)
+ {
+ float div;
+
+ div = ((float)diff_ntb / (float)ctx->pwl.zc_ntb);
+ diff_ntb = (4 - div) * ctx->pwl.zc_ntb + diff_ntb;
+ }
+
+ /* Using a Wp value with k = 4. */
+ ctx->pwl.per_ntb += 0.0625 * ((s32) diff_ntb
+ - (s32)ctx->pwl.per_ntb);
+}
+
+void
+cp_pwl__tracker__compute_beacon_period_start_time_ntb (cp_t *ctx)
+{
+ uint i;
+ dbg_assert (ctx);
+ dbg_assert (ctx->pwl.bp_ntb);
+
+ while (lesseq_mod2p32 (ctx->pwl.bp_avln_ntb[1], mac_ntb())
+ || (ctx->pwl.bp_avln_ntb[0] == ctx->pwl.bp_avln_ntb[1]))
+ {
+ if (!ctx->pwl.cable)
+ {
+ cp_pwl__tracker__compute_period (ctx);
+
+ if (ctx->pwl.tracking)
+ {
+ /* Update the beacon period start time. */
+ for (i = 0; i < CP_PWL_BP_AVLN_NB - 1; i++)
+ ctx->pwl.bp_avln_ntb[i] = ctx->pwl.bp_avln_ntb[i+1];
+
+ ctx->pwl.bp_avln_ntb[CP_PWL_BP_AVLN_NB - 1] +=
+ ctx->pwl.per_ntb;
+
+ /* Compute BTO's */
+ for (i = 0; i < CP_PWL_BTO_NB - 1; i++)
+ ctx->pwl.bto[i] = ctx->pwl.bto[i+1];
+
+ ctx->pwl.bto[CP_PWL_BTO_NB-1] =
+ ctx->pwl.bp_avln_ntb[CP_PWL_BP_AVLN_NB - 1]
+ - ctx->pwl.bp_avln_ntb[CP_PWL_BP_AVLN_NB - 2]
+ - ctx->pwl.bp_ntb;
+ }
+ else
+ {
+ s16 bto;
+ uint now = mac_ntb();
+
+ if (lesseq_mod2p32 (ctx->pwl.bp_avln_ntb[2], now))
+ ctx->pwl.bp_avln_ntb[0] = now;
+ else
+ ctx->pwl.bp_avln_ntb[0] = ctx->pwl.bp_avln_ntb[1];
+
+ /* Update the beacon period start time. */
+ for (i = 1; i < CP_PWL_BP_AVLN_NB; i++)
+ ctx->pwl.bp_avln_ntb[i] = ctx->pwl.bp_avln_ntb[i-1] +
+ ctx->pwl.per_ntb;
+
+
+ /* Compute BTO's */
+ bto = ctx->pwl.bp_avln_ntb[CP_PWL_BP_AVLN_NB - 1]
+ - ctx->pwl.bp_avln_ntb[CP_PWL_BP_AVLN_NB - 2]
+ - ctx->pwl.bp_ntb;
+
+ for (i = 0; i < CP_PWL_BTO_NB; i++)
+ ctx->pwl.bto[i] = bto;
+ }
+ }
+ else /* Cable mode. */
+ {
+ uint i;
+ for (i = 0; i < CP_PWL_BTO_NB; i++)
+ ctx->pwl.bto[i] = 0;
+
+ if (ctx->pwl.tracking)
+ {
+ ctx->pwl.bp_avln_ntb[0] += ctx->pwl.bp_ntb;
+ }
+ else
+ {
+ ctx->pwl.bp_avln_ntb[0] = mac_ntb();
+ }
+
+ for (i = 1; i < CP_PWL_BP_AVLN_NB; i++)
+ ctx->pwl.bp_avln_ntb[i] = ctx->pwl.bp_avln_ntb[i-1] +
+ ctx->pwl.bp_ntb;
+ }
+ CP_TRACE_VERBOSE (PWL_CCO_COMP_BPS, phy_date (), ctx->pwl.per_ntb,
+ ctx->pwl.bp_avln_ntb[0], ctx->pwl.bp_avln_ntb[1],
+ ctx->pwl.bp_avln_ntb[2], ctx->pwl.bp_avln_ntb[3]);
+ }
+
+ ctx->pwl.tracking = true;
+}
+
+
+/**
+ * Get the three values of the beacon period start time.
+ * \param ctx the module context.
+ * \return An array of CP_PWL_BP_AVLN_NB elements.
+ *
+ * The current one, the two next ones
+ */
+u32
+cp_pwl_get_beacon_period_start_ntb (cp_t *ctx, uint pos)
+{
+ dbg_assert (ctx);
+ dbg_assert (pos < CP_PWL_BP_AVLN_NB);
+
+ return ctx->pwl.bp_avln_ntb[pos];
+}
+
+u32
+cp_pwl_get_beacon_period_start_date (cp_t *ctx, uint pos)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_config);
+ dbg_assert (pos < CP_PWL_BP_AVLN_NB);
+
+ return (u32) (ctx->pwl.bp_avln_ntb[pos] -
+ ctx->mac_config->ntb_offset_tck);
+}
+
+/**
+ * Get the estimated value of the beacon period in NTB ticks.
+ * \param ctx the module context.
+ * \return the beacon period int NTB ticks estimated.
+ */
+u32
+cp_pwl_get_beacon_period_ntb (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->pwl.per_ntb;
+}
+
+/**
+ * Get the four BTOs estimated.
+ * \param ctx the module context.
+ * \return The array of four BTO estimated by the CCo.
+ */
+const s16 *
+cp_pwl_get_bto (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return ctx->pwl.bto;
+}
+
+/**
+ * Provide the next date to awake.
+ * \param ctx the module context.
+ * \param cco If the station is acting as CCo or not (useful when the
+ * station is Ucco.)
+ * \return Return the next date to program the timer.
+ *
+ * If the station is CCo, it will return a date before the beacon period
+ * end. It the station is CCo it will return a date a quarter after the
+ * beacon period start
+ */
+u32
+cp_pwl_get_next_timer_date (cp_t *ctx, bool cco)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_config);
+
+ if (cco)
+ return ctx->pwl.bp_avln_ntb[2]
+ - CP_PWL_TIMER_OFFSET_CCO * ((CONFIG_CP_PWL_EOC) ? 3 : 1)
+ - ctx->mac_config->ntb_offset_tck;
+ else
+ return ctx->pwl.bp_avln_ntb[1] + CP_PWL_TIMER_OFFSET_STA -
+ ctx->mac_config->ntb_offset_tck;
+}
+
+bool
+cp_pwl_is_new_beacon_period (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ return less_mod2p32 (ctx->pwl.bp_avln_ntb[1], mac_ntb());
+}
diff --git a/cesar/cp/src/cp.c b/cesar/cp/src/cp.c
index 7cdf39b7c9..3396c61d94 100644
--- a/cesar/cp/src/cp.c
+++ b/cesar/cp/src/cp.c
@@ -12,11 +12,12 @@
*
*/
#include "common/std.h"
-
#include "cp/cp.h"
-
#include "cp/inc/context.h"
-
+#include "config/cp/eoc.h"
+#if CONFIG_CP_EOC_SCHEDULER
+#include "cp/eoc/cco/bw/bw.h"
+#endif
/** Static data. */
static cp_t cp_global;
@@ -102,6 +103,9 @@ cp_init (bsu_t *bsu, bsu_aclf_t* aclf, mac_config_t * mac_config,
/* Init CE in TX. */
ce_tx_init (&cp_global);
+#if CONFIG_CP_EOC_SCHEDULER && CONFIG_CP_STA_MGR_EOC
+ cp_eoc_cco_bw_sched_init (&cp_global);
+#endif
return &cp_global;
}
@@ -121,6 +125,9 @@ cp_uninit (cp_t *ctx)
cp_cl_interf_uninit (ctx);
cp_msg_uninit (ctx);
cp_trace_uninit (ctx);
+#if CONFIG_CP_EOC_SCHEDULER && CONFIG_CP_STA_MGR_EOC
+ cp_eoc_cco_bw_sched_uninit (ctx);
+#endif
}
/**
diff --git a/cesar/cp/src/trace.c b/cesar/cp/src/trace.c
index 2b67f9bce3..94b0d26ddc 100644
--- a/cesar/cp/src/trace.c
+++ b/cesar/cp/src/trace.c
@@ -44,6 +44,9 @@ const char *cp_trace_ce_tx_mme_error_code_table[] =
"UNKNOWN",
};
+#if CONFIG_CP_STA_MGR_EOC
+#include "cp/eoc/multi_sta_fsm/inc/tables.h"
+#endif /* CONFIG_CP_STA_MGR_EOC */
/**
* Table to associate an MME dispatch error code and its string translation.
*/
@@ -59,7 +62,6 @@ const char *cp_trace_rx_mme_error_code_table[] =
"UNKNOWN"
};
-
/**
* Format a FSM state.
* \see trace_format_t.
@@ -135,14 +137,59 @@ cp_trace_format_mmtype (char *text, uint text_size, int data)
}
}
+#if CONFIG_CP_STA_MGR_EOC
+/**
+ * Format a MULTI_STA_FSM state.
+ * \see trace_format_t.
+ */
+static int
+cp_trace_format_multi_sta_fsm_state (char *text, uint text_size, int data)
+{
+ const char *state_name;
+ if (data < 0 || data >= CP_FSM_STATE_NB)
+ state_name = "UNKNOWN";
+ else
+ state_name = cp_eoc_multi_sta_fsm_state_names_table[data];
+ uint state_name_len = strlen (state_name);
+ if (state_name_len > text_size)
+ return -1;
+ else
+ {
+ memcpy (text, state_name, state_name_len);
+ return state_name_len;
+ }
+}
+/**
+ * Format a MULTI_STA_FSM event.
+ * \see trace_format_t.
+ */
+static int
+cp_trace_format_multi_sta_fsm_event (char *text, uint text_size, int data)
+{
+ const char *event_name;
+ if (data < 0 || data >= CP_FSM_EVENT_TYPE_NB)
+ event_name = "UNKNOWN";
+ else
+ event_name = cp_eoc_multi_sta_fsm_event_names_table[data];
+ uint event_name_len = strlen (event_name);
+ if (event_name_len > text_size)
+ return -1;
+ else
+ {
+ memcpy (text, event_name, event_name_len);
+ return event_name_len;
+ }
+}
+#endif /* CONFIG_CP_STA_MGR_EOC */
+
/**
* Copy an error into trace buffer.
* \param error_name the error to trace.
* \return error_name length on success, -1 otherwise.
*/
static int
-cp_trace_format_copy_error (char *text, uint text_size,
- const char *error_name)
+ cp_trace_format_copy_error (char *text, uint text_size,
+ const char *error_name)
{
/* Copy if we can. */
uint error_name_len = strlen (error_name);
@@ -276,6 +323,12 @@ cp_trace_init (cp_t *ctx)
"new tone map received: tmi %d", TIMESTAMP),
TRACE_EVENT (CP_TRACE_CE_TX_NEW_DEFAULT_TMI, "[ce_tx] tei %d: "
"default tmi changed: %d -> %d", TIMESTAMP),
+#if CONFIG_CP_STA_MGR_EOC
+ TRACE_EVENT (CP_TRACE_MULTI_STA_FSM_CHANGE_STATE,
+ "multi_sta_fsm %T => %T"),
+ TRACE_EVENT (CP_TRACE_MULTI_STA_ASSOC,
+ "[CCO_EOC] Assoc, Mac addr : %m, tei : %x"),
+#endif /* CONFIG_CP_STA_MGR_EOC */
TRACE_EVENT (CP_TRACE_CE_TX_DEFAULT_TMI_UNAVAILABLE, "[ce_tx] tei "
"%d: default tmi unavailable: %d", TIMESTAMP),
TRACE_EVENT (CP_TRACE_CE_TX_TMI_AVAILABLE_LIST, "[ce_tx] tei %d: "
@@ -300,6 +353,12 @@ cp_trace_init (cp_t *ctx)
cp_trace_format_fsm_event);
trace_namespace_register_format (&namespace, 'M',
cp_trace_format_mmtype);
+#if CONFIG_CP_STA_MGR_EOC
+ trace_namespace_register_format (&namespace, 'T',
+ cp_trace_format_multi_sta_fsm_state);
+ trace_namespace_register_format (&namespace, 'V',
+ cp_trace_format_multi_sta_fsm_event);
+#endif /* CONFIG_CP_STA_MGR_EOC */
trace_namespace_register_format (&namespace, 'Z',
cp_trace_format_ce_mme_error);
trace_namespace_register_format (&namespace, 'T',
@@ -317,4 +376,3 @@ cp_trace_uninit (cp_t *ctx)
trace_buffer_remove (&ctx->trace_verbose);
trace_buffer_remove (&ctx->trace);
}
-
diff --git a/cesar/cp/sta/action/Config b/cesar/cp/sta/action/Config
index 343ccd99b6..ec2625bda7 100644
--- a/cesar/cp/sta/action/Config
+++ b/cesar/cp/sta/action/Config
@@ -1 +1,2 @@
+CONFIG_CP_STA_ACTION_MISC_EOC = n
CONFIG_DATA_RATE=n
diff --git a/cesar/cp/sta/action/inc/context.h b/cesar/cp/sta/action/inc/context.h
index fb65f0d47e..5a42362775 100644
--- a/cesar/cp/sta/action/inc/context.h
+++ b/cesar/cp/sta/action/inc/context.h
@@ -34,6 +34,12 @@ struct cp_sta_action_assoc_t
cp_sta_core_timed_event_def_t lease_timer;
/** Number of lost central beacons since the last beacon reception. */
uint beacon_loss;
+ /** Number of succ received central beacons. */
+ uint beacon_succ;
+ /** Init count for randomization of first REQ . */
+ uint init_count;
+ /** Consecutive assoc requests. */
+ uint assoc_req_retry_nb;
};
diff --git a/cesar/cp/sta/action/src/bridge.c b/cesar/cp/sta/action/src/bridge.c
index 2d27454ee3..5122f83d35 100644
--- a/cesar/cp/sta/action/src/bridge.c
+++ b/cesar/cp/sta/action/src/bridge.c
@@ -25,6 +25,7 @@
#include "cl/bridge_table.h" // bridge_table_*
#include "lib/utils.h" // less_mod2p32
#include "cp/sta/action/bridge.h"
+#include "config/cl/eoc.h"
/**
* Send a CM_BRG_INFO.CNF with the local bridge table of the CL.
@@ -197,8 +198,10 @@ cp_sta_action_update_bridge_table (cp_t *ctx)
* authenticated. */
if (cp_sta_own_data_get_authenticated_status (ctx))
{
+#if !CONFIG_CL_EOC_ROUTE
cp_mme_peer_t peer = CP_MME_PEER_ALL_STA;
cp_sta_action_send_cm_brg_info_cnf (ctx, &peer);
+#endif
/* Reset cycle counter since last emission. */
ctx->sta_action.bridge.cycle_count_since_last_emission = 0;
/* Reset flag for new table to send. */
diff --git a/cesar/cp/sta/action/src/misc.c b/cesar/cp/sta/action/src/misc.c
index 5e83dd48af..1ea0d5aec5 100644
--- a/cesar/cp/sta/action/src/misc.c
+++ b/cesar/cp/sta/action/src/misc.c
@@ -25,6 +25,7 @@
#include "common/defs/spidcom.h"
#include "mac/common/timings.h"
+#include "config/cp/sta/action/misc/eoc.h"
#include "cp/fsm/fsm.h"
#include "cp/cco/action/cco_action.h"
@@ -434,7 +435,11 @@ cp_sta_action_process_cm_nw_stats_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
cp_sta_t* sta_list = NULL;
uint NumSTAs = 0;
+#if (!CONFIG_CP_STA_ACTION_MISC_EOC)
if (cp_msg_cm_nw_stats_req_receive (ctx, rx_mme))
+#else
+ if (true)
+#endif
{
/* Make sure we have an avln */
if (MAC_TEI_IS_STA (cp_sta_own_data_get_tei (ctx)))
@@ -769,6 +774,7 @@ cp_sta_action_get_average_ble (cp_t *ctx, cp_tei_t tei, bool tx,
return average_ble;
}
+#if (!CONFIG_CP_STA_ACTION_MISC_EOC)
void
cp_sta_action_process_cc_discover_list_req (cp_t *ctx, cp_mme_rx_t *rx_mme)
{
@@ -913,3 +919,4 @@ cp_sta_action_poweron__cco__join_timeout_sc_failed (
cp_fsm_branch_ (ctx, branch_sta);
}
}
+#endif /* CONFIG_CP_STA_ACTION_MISC_EOC */
diff --git a/cesar/cp/sta/action/test/utest/Makefile b/cesar/cp/sta/action/test/utest/Makefile
index b9d087f885..ee9451ee05 100644
--- a/cesar/cp/sta/action/test/utest/Makefile
+++ b/cesar/cp/sta/action/test/utest/Makefile
@@ -17,5 +17,7 @@ cp_fsm_MODULE_SOURCES = tables.c
# For bridging MME tests.
cl_stub_MODULE_SOURCES = cl.c cl_mactotei.c brg_rx.c
cl_MODULE_SOURCES = bridge_table.c data_rate.c
+cl_MODULES_CONFIG = cp/msg
+cp_msg_stub_MODULE_SOURCES = mme.c msg.c msg_cc.c msg_cm.c msg_vs.c
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/sta/action/test/utest/src/sc.c b/cesar/cp/sta/action/test/utest/src/sc.c
index 32a6350a99..c68d229614 100644
--- a/cesar/cp/sta/action/test/utest/src/sc.c
+++ b/cesar/cp/sta/action/test/utest/src/sc.c
@@ -247,6 +247,31 @@ sc_basic_test_cases (test_t t)
scenario_run (t, sc_main_timeout, &globals);
} test_end;
+ /* Timeout of the whole SC procedure in SC_ADD. */
+ test_begin (t, "timeout of SC procedure (in SC_ADD)")
+ {
+ /* No answer, main timeout of SC join procedure occurs. */
+ scenario_entry_t sc_main_timeout[] = {
+ /* First, execute transition. */
+ SCENARIO_ACTION (sc_add__sc_timeout),
+ /* Tell CP FSM we failed. */
+ SCENARIO_EVENT (cp_fsm_event_bare_new,
+ .type = CP_FSM_EVENT_TYPE_sc_failed),
+ /* Second, leave the SC_IDLE. */
+ SCENARIO_ACTION (sc__sc_join__leave),
+ /* Stop SC join timer. */
+ SCENARIO_EVENT (cp_sta_core_stop_timed_or_cyclic_event),
+ /* Last, enter SC_IDLE. */
+ SCENARIO_ACTION (sc__sc_idle__enter),
+ /* Stop timer. */
+ SCENARIO_EVENT (cp_sta_core_stop_timed_or_cyclic_event),
+ /* Check SC status has been updated. */
+ SCENARIO_ACTION (sc__check_sc_status, .sc_status = false),
+ SCENARIO_END
+ };
+ scenario_run (t, sc_main_timeout, &globals);
+ } test_end;
+
/* Test SC join procedure with a STA replying with an SC_JOIN.CNF. */
test_begin (t, "SC_JOIN.CNF received from unassociated STA, decoding"
" failed")
diff --git a/cesar/cp/sta/core/core.h b/cesar/cp/sta/core/core.h
index 6778c540d3..2410b31a12 100644
--- a/cesar/cp/sta/core/core.h
+++ b/cesar/cp/sta/core/core.h
@@ -160,6 +160,16 @@ cp_sta_core_get_date_ms (cp_t *ctx);
void
cp_sta_core_checkpoint (cp_t *ctx);
+/**
+ * refresh watch dog.
+ * \param user_data CP context
+ *
+ * Update tracking variable and resfresh watch dog. reset if gc is not
+ * called for about 25 sec.
+ */
+void
+cp_sta_core_refresh_watch_dog (void * user_data);
+
END_DECLS
/**
diff --git a/cesar/cp/sta/core/inc/core.h b/cesar/cp/sta/core/inc/core.h
index 8a8f70dec9..834eb74c40 100644
--- a/cesar/cp/sta/core/inc/core.h
+++ b/cesar/cp/sta/core/inc/core.h
@@ -81,6 +81,10 @@ struct cp_sta_core_t
/* Ticks per RTC. */
u32 tck_per_rtc;
+ /** Last GC update */
+ u32 gc_update_date_ms;
+ /** Tracking watch dog variable */
+ u32 watch_dog_refresh_count;
};
/** Definition for sta core array of (event , action function). */
diff --git a/cesar/cp/sta/core/src/core.c b/cesar/cp/sta/core/src/core.c
index ab33992817..93c098c09b 100644
--- a/cesar/cp/sta/core/src/core.c
+++ b/cesar/cp/sta/core/src/core.c
@@ -55,6 +55,10 @@
#include "ce/rx/cp/cp.h"
#include "cp/sta/core/inc/core.h"
+#include "hal/arch/arch.h"
+
+#define CP_STA_CORE_GARBAGE_COLLECTOR_TIMEOUT_MS 1000
+#define CP_STA_CORE_WATCH_DOG_REFRESH_COUNT_MAX 100*10
/** array of cp sta core events/actions. */
static const cp_sta_core_event_action_t cp_sta_core_event_action[] =
@@ -121,7 +125,7 @@ cp_sta_core_init(cp_t *ctx)
ce_rx_cp_set_cp_signal_work_callback (ctx->ce_rx,
cp_sta_core_signal_ce_rx_work_event,
ctx);
-
+ ctx->sta_core.gc_update_date_ms = cp_sta_core_get_date_ms (ctx);
#ifndef STA_CORE_UNIT_TEST
// create and launch the CP sta core thread
cyg_thread_create (
@@ -537,8 +541,11 @@ void
cp_sta_core_garbage_collector(cp_t *cp_ctx)
{
dbg_assert (cp_ctx);
- /* Reset watchdog. */
- hal_watchdog_reset ();
+ /* reset tracking variable */
+ arch_dsr_lock ();
+ cp_ctx->sta_core.watch_dog_refresh_count = 0;
+ arch_dsr_unlock ();
+ cp_ctx->sta_core.gc_update_date_ms = cp_sta_core_get_date_ms (cp_ctx);
/* Call garbage functions. */
cp_sta_action_garbage (cp_ctx);
if (cp_sta_own_data_get_cco_status (cp_ctx))
@@ -560,6 +567,16 @@ cp_sta_core_quit_wait_event_loop(cp_t *cp_ctx)
cp_ctx->sta_core.terminate_flag = true;
}
+void
+cp_sta_core_refresh_watch_dog (void * user_data)
+{
+ cp_t *cp_ctx = (cp_t *) user_data;
+ dbg_assert (cp_ctx);
+ dbg_assert (cp_ctx->sta_core.watch_dog_refresh_count++
+ < CP_STA_CORE_WATCH_DOG_REFRESH_COUNT_MAX);
+ hal_watchdog_reset ();
+}
+
/**
* station core main wait event loop.
*
@@ -598,8 +615,25 @@ cp_sta_core_wait_event_loop(cp_t *ctx)
{
// wait for a cp sta core event
flag_value = cyg_flag_wait (&ctx->sta_core.wait_event_core_flag, flag_mask, CYG_FLAG_WAITMODE_OR | CYG_FLAG_WAITMODE_CLR );
+ i = 0;
+ /* check GC urgent event */
+ if (flag_value & CP_STA_CORE_EVENT_FLAG_GARBAGE
+ && ctx->sta_core.gc_update_date_ms
+ + CP_STA_CORE_GARBAGE_COLLECTOR_TIMEOUT_MS
+ < cp_sta_core_get_date_ms (ctx))
+ {
+ uint j;
+ /* find position of GC event */
+ for (j = 0; j < COUNT (cp_sta_core_event_action); j++)
+ if (cp_sta_core_event_action[j].event_flag ==
+ CP_STA_CORE_EVENT_FLAG_GARBAGE)
+ {
+ i = j;
+ break;
+ }
+ }
// process the event(s) in respect of event category priority order
- for (i = 0; i < COUNT (cp_sta_core_event_action); i++)
+ for (; i < COUNT (cp_sta_core_event_action); i++)
{
if (flag_value & cp_sta_core_event_action[i].event_flag)
{
diff --git a/cesar/cp/sta/core/test/Makefile.mk b/cesar/cp/sta/core/test/Makefile.mk
index 379a472919..f20a8d9d17 100644
--- a/cesar/cp/sta/core/test/Makefile.mk
+++ b/cesar/cp/sta/core/test/Makefile.mk
@@ -12,19 +12,23 @@ core_events_SOURCES = core_events.c cp_cl_interf_stub.c action_stub.c \
core_events_MODULES = lib cp/sta/core cp/fsm/stub cp/cco/action/stub \
ce/rx/cp/stub \
$(SPARC_MODULES)
+core_events_MODULES_CONFIG = mac/common cp/sta/mgr
core_SOURCES = core.c cp_cl_interf_stub.c action_stub.c\
sta_mgr_stub.c pwl_stub.c beacon_stub.c
core_MODULES = lib cp/sta/core cp/fsm/stub cp/cco/action/stub \
ce/rx/cp/stub \
$(SPARC_MODULES)
+core_CONFIG_MODULES = mac/common cp/sta/mgr
core_thread_SOURCES = core_thread.c
core_thread_MODULES = lib cp/sta/core cp/fsm/stub ce/rx/cp/stub \
$(SPARC_MODULES)
+core_thread_CONFIG_MODULES = mac/common cp/sta/mgr
core_timer_SOURCES = core_timer.c
core_timer_MODULES = lib cp/sta/core cp/fsm/stub ce/rx/cp/stub \
$(SPARC_MODULES)
+core_timer_CONFIG_MODULES = mac/common cp/sta/mgr
include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/sta/mgr/Config b/cesar/cp/sta/mgr/Config
new file mode 100644
index 0000000000..1cb6a28525
--- /dev/null
+++ b/cesar/cp/sta/mgr/Config
@@ -0,0 +1,3 @@
+CONFIG_CP_STA_MGR_EOC = n
+CONFIG_GPIO_LED_IS_CCO = n
+CONFIG_GPIO_LED_IS_CCO_GPIO = 0
diff --git a/cesar/cp/sta/mgr/inc/sta_mgr.h b/cesar/cp/sta/mgr/inc/sta_mgr.h
index 7ea53f9a82..eb2ed14e7a 100644
--- a/cesar/cp/sta/mgr/inc/sta_mgr.h
+++ b/cesar/cp/sta/mgr/inc/sta_mgr.h
@@ -18,6 +18,7 @@
#include "cp/sta/mgr/inc/net.h"
#define CP_STA_MGR_STATION_RELEASE_MS 5000
+#define OUTPUT_LEVEL_ALL 80
struct cp_sta_mgr_t
{
diff --git a/cesar/cp/sta/mgr/inc/sta_own_data.h b/cesar/cp/sta/mgr/inc/sta_own_data.h
index 308c7672c8..bd5ef73ae7 100644
--- a/cesar/cp/sta/mgr/inc/sta_own_data.h
+++ b/cesar/cp/sta/mgr/inc/sta_own_data.h
@@ -98,9 +98,55 @@ struct cp_sta_own_data_private_t
cp_key_t dak;
/**
+ * The station's original DAK.
+ */
+ cp_key_t original_dak;
+
+ /**
+ * The station's output level.
+ */
+ uint output_level;
+
+ /**
+ * The station's number of successful associations and authentications. In CCo case, it is
+ * the number of successful associations and authentications for all the slaves in the network.
+ */
+ uint num_good_assoc_auth;
+
+ /**
+ * The station's number of association requests with no response. In CCo case, it is
+ * the number of associations requests with no response for all the slaves in the network (zero).
+ */
+ uint num_bad_could_not_assoc;
+
+ /**
+ * The station's number of refused association requests. In CCo case, it is
+ * the number of refused associations requests for all the slaves in the network.
+ */
+ uint num_bad_assoc_failure;
+
+ /**
+ * The station's number of authentication requests with no response. In CCo case, it is
+ * the number of authentication requests with no response for all the slaves in the network (zero).
+ */
+ uint num_bad_could_not_auth;
+
+ /**
+ * The station's number of being disconnected by master. In CCo case, it is the number of CC_LEAVE
+ * requests sent to all the slaves in the network.
+ */
+ uint num_leave;
+
+ /**
* Simple connect procedure status.
*/
bool sc;
+
+
+ /**
+ * State of the station (unassociated, associated, authenticated).
+ */
+ cp_eoc_sta_state_t state;
};
#endif /* cp_sta_data_inc_sta_own_data_h */
diff --git a/cesar/cp/sta/mgr/src/sta.c b/cesar/cp/sta/mgr/src/sta.c
index 7c4af11886..bfdafbc6cd 100644
--- a/cesar/cp/sta/mgr/src/sta.c
+++ b/cesar/cp/sta/mgr/src/sta.c
@@ -22,6 +22,8 @@
#include "cp/inc/context.h"
#include "cp/cp.h"
+#include "config/cp/sta/mgr/eoc.h"
+
cp_sta_t *
cp_sta_init (slab_cache_t *cache)
{
@@ -36,6 +38,15 @@ cp_sta_init (slab_cache_t *cache)
sta->association_confirmed = true;
sta->visible = CP_STA_VISIBLE_STATE_VISIBLE;
+#if CONFIG_CP_STA_MGR_EOC
+ /* Station authorization is initially set to false. It can be changed by adding the station
+ into the White List and setting the authorization to true. */
+ ((cp_sta_t *) sta)->multi_sta.allowed = false;
+ ((cp_sta_t *) sta)->multi_sta.ports.port[0].enabled = true;
+ ((cp_sta_t *) sta)->authenticated_to_unassociated = false;
+ ((cp_sta_t *) sta)->sta_in_wl = false;
+#endif /* CONFIG_CP_STA_MGR_EOC */
+
return (cp_sta_t *) sta;
}
diff --git a/cesar/cp/sta/mgr/src/sta_own_data.c b/cesar/cp/sta/mgr/src/sta_own_data.c
index bca8688a1f..f6f0b25437 100644
--- a/cesar/cp/sta/mgr/src/sta_own_data.c
+++ b/cesar/cp/sta/mgr/src/sta_own_data.c
@@ -28,6 +28,8 @@
#include "cp/inc/context.h"
#include "cp/sta/mgr/inc/sta_own_data.h"
+#include "config/av/only/mode.h"
+
/**
* Initialise the station own data to default values.
* \param ctx the module context.
@@ -41,6 +43,7 @@ cp_sta_own_data_init (cp_t *ctx)
/* Store the hybrid mode. */
ctx->sta_mgr.sta_own_data.public.hybrid_mode =
MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE;
+
/* Get an snid. */
ctx->sta_mgr.sta_own_data.snid =
lib_rnd_uniform (&ctx->rnd, HPAV_SNID_NB);
diff --git a/cesar/cp/sta/mgr/sta.h b/cesar/cp/sta/mgr/sta.h
index 648db088ea..80ae3ff1e7 100644
--- a/cesar/cp/sta/mgr/sta.h
+++ b/cesar/cp/sta/mgr/sta.h
@@ -20,6 +20,13 @@
#include "cp/mme.h"
#include "mac/common/store.h"
+#include "config/cp/sta/mgr/eoc.h"
+#if CONFIG_CP_STA_MGR_EOC
+#include "cp/eoc/multi_sta_fsm/inc/context.h"
+#endif /* CONFIG_CP_STA_MGR_EOC */
+
+#define PORT_NB 5
+
/** Enum */
enum cp_sta_visible_status_t
{
@@ -29,6 +36,15 @@ enum cp_sta_visible_status_t
};
typedef enum cp_sta_visible_status_t cp_sta_visible_status_t;
+/** Enum */
+enum cp_eoc_sta_state_t
+{
+ CP_EOC_STA_STATE_UNASSOCIATED,
+ CP_EOC_STA_STATE_ASSOCIATED,
+ CP_EOC_STA_STATE_AUTHENTICATED,
+};
+typedef enum cp_eoc_sta_state_t cp_eoc_sta_state_t;
+
/** Reassembly context block. */
struct cp_sta_reassembly_ctx_blk_t
{
@@ -57,6 +73,46 @@ struct cp_sta_reassembly_ctx_t
};
typedef struct cp_sta_reassembly_ctx_t cp_sta_reassembly_ctx_t;
+#if CONFIG_CP_STA_MGR_EOC
+
+/**
+ * Control plane EoC port structure
+ */
+struct cp_eoc_port_t
+{
+ bool enabled;
+ u8 index_of_service;
+};
+typedef struct cp_eoc_port_t cp_eoc_port_t;
+
+/**
+ * Control plane EoC ports structure
+ */
+struct cp_eoc_ports_t
+{
+ cp_eoc_port_t port[PORT_NB];
+};
+typedef struct cp_eoc_ports_t cp_eoc_ports_t;
+
+/**
+ * Control plane multi station structure
+ */
+struct cp_multi_sta_t
+{
+ bool allowed;
+ u8 output_level;
+ u32 start_time;
+ u32 end_time;
+ cp_key_t dak;
+ u8 action;
+ bool to_leave;
+ cp_eoc_ports_t ports;
+ /* TBD */
+};
+typedef struct cp_multi_sta_t cp_multi_sta_t;
+
+#endif /* CONFIG_CP_STA_MGR_EOC */
+
/**
* Control plane station.
*/
@@ -75,6 +131,11 @@ struct cp_sta_t
u32 expired_date_ms;
/**
+ * Date of association.
+ */
+ uint associated_date_ms;
+
+ /**
* The Reassembly context for the cl_interf.
*/
cp_sta_reassembly_ctx_t reassembly_ctx;
@@ -135,6 +196,14 @@ struct cp_sta_t
/** Heap CCo selection node. */
heap_node_t cco_selection_node;
+ bool authenticated_to_unassociated;
+ bool sta_in_wl;
+
+#if CONFIG_CP_STA_MGR_EOC
+ /** Multi STA FSM */
+ cp_eoc_multi_sta_fsm_t fsm;
+ cp_multi_sta_t multi_sta;
+#endif /* CONFIG_CP_STA_MGR_EOC */
};
typedef struct cp_sta_t cp_sta_t;
diff --git a/cesar/cp/sta/mgr/sta_mgr.h b/cesar/cp/sta/mgr/sta_mgr.h
index d624630c9d..7a4c6f7f81 100644
--- a/cesar/cp/sta/mgr/sta_mgr.h
+++ b/cesar/cp/sta/mgr/sta_mgr.h
@@ -16,6 +16,7 @@
*/
#include "cp/sta/mgr/net.h"
#include "cp/sta/mgr/sta_own_data.h"
+#include "cp/sta/mgr/inc/sta.h"
/* Forward declaration. */
typedef struct cp_sta_mgr_t cp_sta_mgr_t;
@@ -226,6 +227,29 @@ cp_sta_t *
cp_sta_mgr_sta_get_assoc (cp_t *ctx, cp_net_t *net, cp_tei_t tei);
/**
+ * Get the station identified by its mac address.
+ * \param ctx the module context.
+ * \param net the network context.
+ * \param mac The station's mac address.
+ * \return A reference on the station.
+ *
+ * returns NULL if the station does not exists. It only returns a new
+ * reference on the station (one reference is still kept by the network),
+ * when the user does not use it any more, it must release it.
+ */
+cp_sta_t *
+cp_sta_mgr_sta_get_unassoc (cp_t *ctx, cp_net_t *net, mac_t mac);
+
+void
+cp_eoc_sta_mgr_get_wl (cp_t *ctx, 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, u8 *stas_actions);
+
+void
+cp_eoc_sta_mgr_get_ports (cp_t *ctx, uint *numStas, mac_t *stas_macs, bool stas_port_ed[][PORT_NB],
+ u8 stas_port_service[][PORT_NB]);
+
+/**
* Get the associated station identified by its Mac address.
* \param ctx the module context.
* \param mac_address The station's mac_address.
diff --git a/cesar/cp/sta/mgr/sta_own_data.h b/cesar/cp/sta/mgr/sta_own_data.h
index 871e6853d5..46a6a3f365 100644
--- a/cesar/cp/sta/mgr/sta_own_data.h
+++ b/cesar/cp/sta/mgr/sta_own_data.h
@@ -391,6 +391,22 @@ cp_key_t
cp_sta_own_data_get_dak (cp_t *ctx);
/**
+ * Set the original DAK in the station.
+ * \param ctx the control plane context.
+ * \param dak the DAK of the station.
+ */
+void
+cp_sta_own_data_set_original_dak (cp_t *ctx, cp_key_t dak);
+
+/**
+ * Get the original DAK of the station.
+ * \param ctx the control plane context.
+ * \return the DAK of the station.
+ */
+cp_key_t
+cp_sta_own_data_get_original_dak (cp_t *ctx);
+
+/**
* Set the Simple connect station's status.
* \param ctx the control plane context.
* \param status true if currently in SC, false otherwise.
diff --git a/cesar/cp/sta/mgr/test/src/sta_mgr.c b/cesar/cp/sta/mgr/test/src/sta_mgr.c
index 3f49c6246c..73bbf7f97b 100644
--- a/cesar/cp/sta/mgr/test/src/sta_mgr.c
+++ b/cesar/cp/sta/mgr/test/src/sta_mgr.c
@@ -1306,6 +1306,7 @@ test_case__cp_sta_mgr_partial_ack (test_t test)
{
uint i;
bool teis[3] = {false, false, false};
+
cp_sta_t *sta = cp_sta_mgr_sta_add (&cp, net, 2, 2);
for (i = 0; i < 20; i++)
{
diff --git a/cesar/ecos/packages/hal/common/current/cdl/interrupts.cdl b/cesar/ecos/packages/hal/common/current/cdl/interrupts.cdl
index 411ee163dd..2d2705af8b 100644
--- a/cesar/ecos/packages/hal/common/current/cdl/interrupts.cdl
+++ b/cesar/ecos/packages/hal/common/current/cdl/interrupts.cdl
@@ -75,7 +75,7 @@ cdl_option CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK {
cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
display "Interrupt stack size"
flavor data
- default_value { CYGPKG_KERNEL ? 6144 : 32768 }
+ default_value { CYGPKG_KERNEL ? 5800 : 32768 }
legal_values 128 to 1048576
description "
This configuration option specifies the stack size in bytes
diff --git a/cesar/ecos/packages/kernel/current/src/common/thread.cxx b/cesar/ecos/packages/kernel/current/src/common/thread.cxx
index 7888c66307..962a912ce6 100644
--- a/cesar/ecos/packages/kernel/current/src/common/thread.cxx
+++ b/cesar/ecos/packages/kernel/current/src/common/thread.cxx
@@ -90,13 +90,13 @@ Cyg_HardwareThread::thread_entry( Cyg_Thread *thread )
Cyg_Scheduler::scheduler.set_current_thread(thread); // restore current thread pointer
CYG_INSTRUMENT_THREAD(ENTER,thread,0);
-
+
#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
// Reset the timeslice counter so that this thread gets a full
- // quantum.
+ // quantum.
Cyg_Scheduler::reset_timeslice_count();
#endif
-
+
// Zero the lock
HAL_REORDER_BARRIER (); // Prevent the compiler from moving
Cyg_Scheduler::zero_sched_lock(); // the assignment into the code above.
@@ -165,7 +165,7 @@ Cyg_Thread::remove_from_list( void )
}
prev = prev->list_next;
} while ( prev != thread_list );
-
+
Cyg_Scheduler::unlock();
}
@@ -200,7 +200,7 @@ Cyg_Thread::Cyg_Thread(
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(CREATE,this,0);
-
+
// Start the thread in suspended state.
state = SUSPENDED;
suspend_count = 1;
@@ -229,10 +229,10 @@ Cyg_Thread::Cyg_Thread(
#ifdef CYGVAR_KERNEL_THREADS_LIST
// Add thread to housekeeping list
add_to_list();
-#endif
-
+#endif
+
Cyg_Scheduler::scheduler.register_thread(this);
-
+
init_context(this);
CYG_REPORT_RETURN();
@@ -269,14 +269,14 @@ Cyg_Thread::reinitialize()
#else
char * name_arg = NULL;
#endif
-
+
new(this) Cyg_Thread( pri,
entry_point, entry_data,
name_arg,
get_stack_base(), get_stack_size() );
// the constructor re-registers the thread with the scheduler.
- CYG_ASSERTCLASS( this, "Thread corrupted by reinitialize");
+ CYG_ASSERTCLASS( this, "Thread corrupted by reinitialize");
CYG_REPORT_RETURN();
}
@@ -293,11 +293,11 @@ Cyg_Thread::~Cyg_Thread()
#ifdef CYGVAR_KERNEL_THREADS_LIST
// Remove thread from housekeeping list.
remove_from_list();
-#endif
-
+#endif
+
// Zero the unique_id to render this thread inconsistent.
unique_id = 0;
-
+
CYG_REPORT_RETURN();
}
@@ -313,7 +313,7 @@ Cyg_Thread::check_this( cyg_assert_class_zeal zeal) const
// check that we have a non-NULL pointer first
if( this == NULL ) return false;
-
+
switch( zeal )
{
case cyg_system_test:
@@ -353,9 +353,9 @@ Cyg_Thread::sleep()
Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
CYG_ASSERTCLASS( current, "Bad current thread" );
-
+
CYG_INSTRUMENT_THREAD(SLEEP,current,0);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
@@ -381,7 +381,7 @@ Cyg_Thread::wake()
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
@@ -398,7 +398,7 @@ Cyg_Thread::wake()
Cyg_Scheduler::scheduler.add_thread(this);
}
-
+
// Unlock the scheduler and maybe switch threads
Cyg_Scheduler::unlock();
@@ -418,9 +418,9 @@ Cyg_Thread::counted_sleep()
Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
CYG_ASSERTCLASS( current, "Bad current thread" );
-
+
CYG_INSTRUMENT_THREAD(SLEEP,current,0);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
@@ -439,10 +439,10 @@ Cyg_Thread::counted_sleep()
// and deal with anything we must do when we return
switch( current->wake_reason ) {
case DESTRUCT:
- case EXIT:
+ case EXIT:
current->exit();
break;
-
+
default:
break;
}
@@ -464,9 +464,9 @@ Cyg_Thread::counted_sleep( cyg_tick_count delay )
Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
CYG_ASSERTCLASS( current, "Bad current thread" );
-
+
CYG_INSTRUMENT_THREAD(SLEEP,current,0);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
@@ -478,7 +478,7 @@ Cyg_Thread::counted_sleep( cyg_tick_count delay )
// If the timeout is in the past, the wake reason will have been
// set to something other than NONE already.
-
+
if( current->get_wake_reason() == Cyg_Thread::NONE )
{
set_sleep_reason( Cyg_Thread::TIMEOUT );
@@ -486,7 +486,7 @@ Cyg_Thread::counted_sleep( cyg_tick_count delay )
current->state |= COUNTSLEEP; // Set the state
Cyg_Scheduler::reschedule();
-
+
// clear the timer; if it actually fired, no worries.
clear_timer();
}
@@ -501,10 +501,10 @@ Cyg_Thread::counted_sleep( cyg_tick_count delay )
// and deal with anything we must do when we return
switch( current->wake_reason ) {
case DESTRUCT:
- case EXIT:
+ case EXIT:
current->exit();
break;
-
+
default:
break;
}
@@ -522,7 +522,7 @@ Cyg_Thread::counted_wake()
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
@@ -553,7 +553,7 @@ Cyg_Thread::cancel_counted_wake()
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
@@ -577,12 +577,12 @@ Cyg_Thread::suspend()
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(SUSPEND,this,Cyg_Scheduler::current_thread);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
suspend_count++;
-
+
#ifdef CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT
CYG_ASSERT( CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT > suspend_count,
"suspend_count overflow" );
@@ -594,7 +594,7 @@ Cyg_Thread::suspend()
// Set the state
state |= SUSPENDED;
-
+
// Unlock the scheduler and maybe switch threads
Cyg_Scheduler::unlock();
@@ -611,19 +611,19 @@ Cyg_Thread::resume()
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
// If we are about to zero the count, clear the state bit and
// reschedule the thread if possible.
-
+
if( suspend_count == 1 )
{
suspend_count = 0;
CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
-
+
// Set the state
state &= ~SUSPENDED;
@@ -651,18 +651,18 @@ Cyg_Thread::force_resume()
CYG_REPORT_FUNCTION();
CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
// If we are about to zero the count, clear the state bit and
// reschedule the thread if possible.
-
+
if ( 0 < suspend_count ) {
suspend_count = 0;
CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
-
+
// Set the state
state &= ~SUSPENDED;
@@ -697,14 +697,14 @@ Cyg_Thread::release()
case NONE:
// The thread is not sleeping for any reason, do nothing.
// drop through...
-
+
case DESTRUCT:
case BREAK:
case EXIT:
case DONE:
// Do nothing in any of these cases. They are here to
// keep the compiler happy.
-
+
Cyg_Scheduler::unlock();
CYG_REPORT_RETURN();
return;
@@ -713,11 +713,11 @@ Cyg_Thread::release()
// The thread was waiting for some sync object to do
// something.
// drop through...
-
+
case TIMEOUT:
// The thread was waiting on a sync object with a timeout.
// drop through...
-
+
case DELAY:
// The thread was simply delaying, unless it has been
// woken up for some other reason, wake it now.
@@ -727,7 +727,7 @@ Cyg_Thread::release()
}
wake();
-
+
// Allow preemption
Cyg_Scheduler::unlock();
@@ -748,7 +748,7 @@ void
Cyg_Thread::exit()
{
CYG_REPORT_FUNCTION();
-
+
// The thread should never return from this function.
Cyg_Thread *self = Cyg_Thread::self();
@@ -760,7 +760,7 @@ Cyg_Thread::exit()
destructor_fn fn = self->destructors[i].fn;
CYG_ADDRWORD data = self->destructors[i].data;
fn(data);
- }
+ }
}
#endif
#ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT
@@ -823,14 +823,14 @@ Cyg_Thread::kill()
if( state == RUNNING ) Cyg_Scheduler::scheduler.rem_thread(this);
state = EXITED;
break;
-
+
case DESTRUCT:
case BREAK:
case EXIT:
case DONE:
// Do nothing in any of these cases. They are here to
// keep the compiler happy.
-
+
Cyg_Scheduler::unlock();
CYG_REPORT_RETURN();
return;
@@ -839,11 +839,11 @@ Cyg_Thread::kill()
// The thread was waiting for some sync object to do
// something.
// drop through...
-
+
case TIMEOUT:
// The thread was waiting on a sync object with a timeout.
// drop through...
-
+
case DELAY:
// The thread was simply delaying, unless it has been
// woken up for some other reason, wake it now.
@@ -871,14 +871,14 @@ Cyg_Thread::set_priority( cyg_priority new_priority )
// CYG_ASSERT( new_priority >= CYG_THREAD_MAX_PRIORITY, "Priority out of range");
// CYG_ASSERT( new_priority <= CYG_THREAD_MIN_PRIORITY, "Priority out of range");
-
+
CYG_INSTRUMENT_THREAD(PRIORITY,this,new_priority);
-
+
// Prevent preemption
Cyg_Scheduler::lock();
Cyg_ThreadQueue *queue = NULL;
-
+
// If running, remove from run qs
if( state == RUNNING )
Cyg_Scheduler::scheduler.rem_thread(this);
@@ -888,20 +888,20 @@ Cyg_Thread::set_priority( cyg_priority new_priority )
queue = get_current_queue();
// if indeed we are on a queue
if ( NULL != queue ) {
- CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");
+ CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");
remove();
}
}
Cyg_Scheduler::scheduler.deregister_thread(this);
-
+
#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
// Check that there are no other threads at this priority.
// If so, leave is as it is.
CYG_ASSERT( Cyg_Scheduler::scheduler.unique(new_priority), "Priority not unique");
-
+
if( Cyg_Scheduler::scheduler.unique(new_priority) )
priority = new_priority;
@@ -914,24 +914,24 @@ Cyg_Thread::set_priority( cyg_priority new_priority )
// better than the current inherited one, then use that
// immediately. We remain in inherited state to avoid problems
// with multiple mutex inheritances.
-
+
if( priority_inherited )
{
original_priority = new_priority;
if( priority > new_priority ) priority = new_priority;
}
else priority = new_priority;
-
-#else
+
+#else
priority = new_priority;
#endif
-
+
#endif // CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
Cyg_Scheduler::scheduler.register_thread(this);
-
+
// Return thread to scheduler if runnable
if( state == RUNNING )
Cyg_Scheduler::scheduler.add_thread(this);
@@ -954,11 +954,11 @@ Cyg_Thread::set_priority( cyg_priority new_priority )
// If it is not the current thread then we need to see whether
// it is more worthy of execution than any current thread and
// rescheduled if necessary.
-
+
if( this == Cyg_Scheduler::get_current_thread() )
Cyg_Scheduler::set_need_reschedule();
else Cyg_Scheduler::set_need_reschedule(this);
-
+
// Unlock the scheduler and maybe switch threads
Cyg_Scheduler::unlock();
CYG_REPORT_RETURN();
@@ -981,7 +981,7 @@ Cyg_Thread::delay( cyg_tick_count delay)
// Prevent preemption
Cyg_Scheduler::lock();
-
+
sleep();
set_timer( Cyg_Clock::real_time_clock->current_value()+delay, DELAY );
@@ -996,10 +996,10 @@ Cyg_Thread::delay( cyg_tick_count delay)
// and deal with anything else we must do when we return
switch( wake_reason ) {
case DESTRUCT:
- case EXIT:
+ case EXIT:
exit();
break;
-
+
default:
break;
}
@@ -1026,7 +1026,7 @@ Cyg_Thread::deliver_exception(
exception_control.deliver_exception( exception_number, exception_info );
}
-#ifdef CYGIMP_EXCEPTION_ASYNC
+#ifdef CYGIMP_EXCEPTION_ASYNC
else
{
// Delivering to another thread, probably as a result of one thread
@@ -1041,9 +1041,9 @@ Cyg_Thread::deliver_exception(
// end of unlock_inner(). However this would add extra code to the scheduler,
// and require a way of storing pending exceptions. So for now this option is
// disabled and not yet implemented, it may never be.
-
+
}
-#endif
+#endif
}
#endif
@@ -1068,13 +1068,13 @@ Cyg_Thread::new_data_index()
if (0 == thread_data_map)
return -1;
-
+
// find ls set bit
HAL_LSBIT_INDEX( index, thread_data_map );
// clear the bit
thread_data_map &= ~(1<<index);
-
+
Cyg_Scheduler::unlock();
return index;
@@ -1085,8 +1085,8 @@ void Cyg_Thread::free_data_index( Cyg_Thread::cyg_data_index index )
Cyg_Scheduler::lock();
thread_data_map |= (1<<index);
-
- Cyg_Scheduler::unlock();
+
+ Cyg_Scheduler::unlock();
}
@@ -1123,7 +1123,7 @@ void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size )
// i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1);
cyg_ucount32 i;
cyg_uint32 sig = (cyg_uint32)this;
-
+
for ( i = 0;
i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
i++ ) {
@@ -1137,11 +1137,11 @@ void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size )
stack_limit += CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
Cyg_Scheduler::unlock();
-
+
return ret;
}
#endif
-
+
// =========================================================================
// Cyg_ThreadTimer member functions
@@ -1161,15 +1161,15 @@ Cyg_ThreadTimer::alarm(
Cyg_ThreadTimer *self = (Cyg_ThreadTimer *)data;
Cyg_Thread *thread = self->thread;
-
+
CYG_INSTRUMENT_THREAD(ALARM, 0, 0);
-
+
Cyg_Scheduler::lock();
Cyg_Thread::cyg_reason sleep_reason = thread->get_sleep_reason();
-
+
switch( sleep_reason ) {
-
+
case Cyg_Thread::DESTRUCT:
case Cyg_Thread::BREAK:
case Cyg_Thread::EXIT:
@@ -1225,6 +1225,9 @@ Cyg_ThreadTimer::alarm(
# endif // CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE
#endif // CYGNUM_HAL_STACK_SIZE_MINIMUM
+# undef CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE
+# define CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE 150000
+
static char idle_thread_stack[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE];
// Loop counter for debugging/housekeeping
@@ -1247,7 +1250,7 @@ idle_thread_main( CYG_ADDRESS data )
#if 0
// For testing, it is useful to be able to fake
// clock interrupts in the idle thread.
-
+
Cyg_Clock::real_time_clock->tick();
#endif
#ifdef CYGIMP_IDLE_THREAD_YIELD
@@ -1266,7 +1269,7 @@ class Cyg_IdleThread : public Cyg_Thread
{
public:
Cyg_IdleThread();
-
+
};
// -------------------------------------------------------------------------
@@ -1289,7 +1292,7 @@ Cyg_IdleThread::Cyg_IdleThread()
// Call into scheduler to set up this thread as the default
// current thread for its CPU.
-
+
Cyg_Scheduler::scheduler.set_idle_thread( this, this-&idle_thread[0] );
CYG_REPORT_RETURN();
diff --git a/cesar/hal/leon/watchdog.h b/cesar/hal/leon/watchdog.h
index 5c8ec347de..65e01343b5 100644
--- a/cesar/hal/leon/watchdog.h
+++ b/cesar/hal/leon/watchdog.h
@@ -19,8 +19,8 @@
/** Watchdog counter register. */
#define LEON_WATCHDOG_COUNTER (* (volatile u32 *) (LEON_WATCHDOG_BASE + 0x00))
-/** Watchdog counter reset value, about 2 sec. */
-#define LEON_WATCHDOG_RESET_VALUE (2 * 1024 * 1024)
+/** Watchdog counter reset value, about 10 sec. */
+#define LEON_WATCHDOG_RESET_VALUE (10 * 1024 * 1024)
extern inline void
leon_watchdog_reset (void)
diff --git a/cesar/hal/phy/Module b/cesar/hal/phy/Module
index f408a8bf65..20e833f76f 100644
--- a/cesar/hal/phy/Module
+++ b/cesar/hal/phy/Module
@@ -17,6 +17,8 @@ CLEAN_FILES += $(hal_phy_resys_prog_h) $(hal_phy_resys_prog_patch_h) \
$(hal_phy_resys_offsettable_h) \
$(hal_phy_resys_labels_h) $(hal_phy_params_h)
+$(call src2obj,hal/phy/src/resys.c,target): $(hal_phy_resys_prog_h) \
+$(hal_phy_resys_prog_patch_h) $(hal_phy_resys_offsettable_h)
COMPILE_DEPS += $(hal_phy_resys_labels_h) $(hal_phy_params_h)
hal_phy_resys_prog_di_hex = $(OBJ_DIR)/resys_mem_di.hex
diff --git a/cesar/hal/phy/defs.h b/cesar/hal/phy/defs.h
index d0eac35d11..d85f9ff571 100644
--- a/cesar/hal/phy/defs.h
+++ b/cesar/hal/phy/defs.h
@@ -23,7 +23,7 @@
#endif
/** Number of OFDM carrier, defined by the hardware. */
-#define PHY_CARRIER_NB 1155
+#define PHY_CARRIER_NB 1408
/** Number of first OFDM carrier, defined by the hardware. */
#define PHY_CARRIER_OFFSET 74
@@ -41,6 +41,9 @@
/** Number of first OFDM carrier for HP10, defined by the hardware. */
#define PHY_HP10_CARRIER_OFFSET 10
+/** Last OFDM carrier number in EoC configuration. */
+#define PHY_LAST_EOC_CARRIER_NB 1439
+
/** Number of words needed to define a tonemask. */
#define PHY_TONEMASK_WORDS ((PHY_CARRIER_NB + 32 - 1) / 32)
diff --git a/cesar/hal/phy/inc/phy_params.txt b/cesar/hal/phy/inc/phy_params.txt
index 81b7e02324..821355100d 100644
--- a/cesar/hal/phy/inc/phy_params.txt
+++ b/cesar/hal/phy/inc/phy_params.txt
@@ -1,7 +1,7 @@
resys_prog = http://gevrey:8080/svn/spidcom_digital_svn/branches/MARIA_RC_17/modules/resys/tb/prog_resys_tr_internal_fc10_attempt@10348
resys_offsettable = http://gevrey:8080/svn/spidcom_digital_svn/branches/MARIA_RC_17/modules/resys/tb/resys_offsettable.txt@10348
tx_scale_adapt = 0x10000
-tx_scale_adapt_blk_exp = 8
+tx_scale_adapt_blk_exp = 7
rx_fec_param__me10doi_max_it = 9
rx_fec_param__tcc_half_it_fc = 10
rx_fec_param__tcc_half_it_data_last_pb = 15
diff --git a/cesar/hal/phy/inc/regs.h b/cesar/hal/phy/inc/regs.h
index fb38df84ae..9b7160bd53 100644
--- a/cesar/hal/phy/inc/regs.h
+++ b/cesar/hal/phy/inc/regs.h
@@ -122,6 +122,10 @@ typedef u32 uint32_t;
| BF_MASK (PHY_DSPSS_TX_PARAM__USE_SHAKER) \
)
+/* TX_SCALE */
+#define PHY_DSPSS_TX_SCALE_ADAPT__GAIN 17, 0
+#define PHY_DSPSS_TX_SCALE_ADAPT_BLK_EXP__STEP 2, 0
+
/* TX_FC_10 */
#define PHY_DSPSS_TX_FC_10__FC 24, 0
#define PHY_DSPSS_TX_FC_10__CRC 31, 31
@@ -320,12 +324,6 @@ typedef u32 uint32_t;
#define PHY_DSPSS_SPOC_DEBUG_MODE__M_MATRIX_WITHOUT_PHASE 3, 3
#define PHY_DSPSS_SPOC_DEBUG_MODE__BYPASS 4, 4
-/* WIENER_PHASE_CORRECTION */
-#define PHY_DSPSS_WIENER_PHASE_CORRECTION__IND_MAX_IFFT_ON_CHEPRE 8, 0
-#define PHY_DSPSS_WIENER_PHASE_CORRECTION__SOFT_PHASE 17, 9
-#define PHY_DSPSS_WIENER_PHASE_CORRECTION__SOFT_PHASE_EN 18, 18
-#define PHY_DSPSS_WIENER_PHASE_CORRECTION__PHASE_CORRECTION_EN 19, 19
-
/* WIENER_CHANNEL_MAX_DETECTION_PARAM */
#define PHY_DSPSS_WIENER_CHANNEL_MAX_DETECTION_PARAM__FREQ_HOLE_WIDTH 7, 0
#define PHY_DSPSS_WIENER_CHANNEL_MAX_DETECTION_PARAM__SOFT_ADDR 16, 8
diff --git a/cesar/hal/phy/maximus/dur/test/Config b/cesar/hal/phy/maximus/dur/test/Config
new file mode 100644
index 0000000000..dd537c7602
--- /dev/null
+++ b/cesar/hal/phy/maximus/dur/test/Config
@@ -0,0 +1 @@
+CONFIG_ATU_FACTOR = 1
diff --git a/cesar/hal/phy/maximus/dur/test/Makefile b/cesar/hal/phy/maximus/dur/test/Makefile
index 1f78d505f5..c5b005b827 100644
--- a/cesar/hal/phy/maximus/dur/test/Makefile
+++ b/cesar/hal/phy/maximus/dur/test/Makefile
@@ -3,5 +3,6 @@ BASE = ../../../../..
HOST_PROGRAMS = test_dur
test_dur_SOURCES = test_dur.c
test_dur_MODULES = lib hal/phy/maximus/dur
+test_dur_CONFIG_MODULES = mac/common
include $(BASE)/common/make/top.mk
diff --git a/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h b/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h
index aacd155746..b299959c26 100644
--- a/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h
+++ b/cesar/hal/phy/maximus/inc/maximus_phy_ctx.h
@@ -128,6 +128,8 @@ struct maximus_phy_rx_param_t
* in order to start chandata transfer.
* If equals 0, it's a data frame transmission. */
u32 end_date;
+ /* Analog gain applied to rx signal*/
+ u32 agc_gain;
};
typedef struct maximus_phy_rx_param_t maximus_phy_rx_param_t;
diff --git a/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c b/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c
index f9d6b3fcb8..cafe769610 100644
--- a/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c
+++ b/cesar/hal/phy/maximus/src/maximus_phy_ctrl.c
@@ -1199,6 +1199,9 @@ maximus_phy_recv_noise (phy_t *ctx, sci_msg_t *msg)
max_size[PHY_CHANDATA_TYPE_NRJ - 1] = PHY_CARRIER_NB*sizeof(phy_noise_energy_t); // in octets
max_size[PHY_CHANDATA_TYPE_NRJ_SYMBOL - 1] = MAC_MAX_SYMB_PER_MPDU*sizeof(phy_noise_energy_t); // in octets
+ /* pb_crc_error information has to be kept from last received MPDU processing */
+ u8 pb_crc_error = ctx->pbdma.status_word.pb_crc_error;
+
/* For a chandata transfer, all data are received into one SCI message. */
u8 frequency_noise[PHY_CARRIER_NB*sizeof(phy_noise_energy_t)];
u8 time_noise[MAC_MAX_SYMB_PER_MPDU*sizeof(phy_noise_energy_t)];
@@ -1243,6 +1246,7 @@ maximus_phy_recv_noise (phy_t *ctx, sci_msg_t *msg)
// for pb dma callback
memset(&ctx->pbdma.status_word, '\0', sizeof(phy_pbdma_status_t));
+ ctx->pbdma.status_word.pb_crc_error = pb_crc_error; /* saved from last MPDU reception */
// set current chandata
current_chandata = ctx->pbdma.first_chandata;
@@ -2614,6 +2618,15 @@ phy_tx_cancel (phy_t *ctx)
maximus_phy_next_tx_frame_cancel(ctx);
}
+void
+phy_tx_scale_adapt_set (phy_t *ctx, u16 value)
+{
+}
+
+void
+phy_tx_scale_adapt_exp_set (phy_t *ctx, u8 exp)
+{
+}
/**
* set errno to:
@@ -2992,6 +3005,25 @@ phy_rx_fc10 (phy_t *ctx)
return fc_10;
}
+u32
+phy_rx_agc_gain (phy_t *ctx)
+{
+ u32 agc_gain = 0;
+
+ dbg_assert_ptr(ctx);
+ if (NULL == ctx)
+ {
+ errno = EINVAL;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_PHY,
+ "%s: errno = %d", __FUNCTION__, errno);
+ }
+ else
+ {
+ agc_gain = ctx->control.rx_param.agc_gain;
+ }
+
+ return agc_gain;
+}
u32
phy_rx_sysdate (phy_t *ctx)
diff --git a/cesar/hal/phy/phy.h b/cesar/hal/phy/phy.h
index 66f1a3156b..198ab48c72 100644
--- a/cesar/hal/phy/phy.h
+++ b/cesar/hal/phy/phy.h
@@ -376,6 +376,29 @@ phy_extra_timer_cancel (phy_t *ctx);
void
phy_zero_cross_init (phy_t *ctx, phy_zero_cross_cb_t zero_cross_cb);
+/**
+ * Read agc gain value from reguster
+ * \param ctx phy context
+ */
+u32
+phy_rx_agc_gain (phy_t *ctx);
+
+/**
+ * Set exponent for output level
+ * \param ctx phy context
+ * \param exp exponent
+ */
+void
+phy_tx_scale_adapt_exp_set (phy_t *ctx, u8 exp);
+
+/**
+ * Set value for output level
+ * \param ctx phy context
+ * \param value value
+ */
+void
+phy_tx_scale_adapt_set (phy_t *ctx, u16 value);
+
END_DECLS
#endif /* hal_phy_phy_h */
diff --git a/cesar/hal/phy/spoc/Module b/cesar/hal/phy/spoc/Module
index 75a0c66074..0a7f2b4b11 100644
--- a/cesar/hal/phy/spoc/Module
+++ b/cesar/hal/phy/spoc/Module
@@ -1 +1 @@
-SOURCES := spoc.c spoc_regs.c utils.c
+SOURCES := spoc.c spoc_regs.c
diff --git a/cesar/hal/phy/spoc/inc/utils.h b/cesar/hal/phy/spoc/inc/utils.h
deleted file mode 100644
index de9de6103a..0000000000
--- a/cesar/hal/phy/spoc/inc/utils.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef inc_utils_h
-#define inc_utils_h
-/* Cesar project {{{
- *
- * Copyright (C) 2010 Spidcom
- *
- * <<<Licence>>>
- *
- * }}} */
-/**
- * \file hal/phy/spoc/inc/utils.h
- * \brief SPOC utilities.
- * \ingroup hal_phy
- */
-
-BEGIN_DECLS
-
-/**
- * Find first and last unmasked carriers.
- * \param tonemask tonemask data
- * \param first_unmasked will receive first unmasked carrier
- * \param last_unmasked will receive last unmasked carrier
- */
-void
-phy_spoc_analyse_tonemask (const u32 *tonemask, uint *first_unmasked,
- uint *last_unmasked);
-
-END_DECLS
-
-#endif /* inc_utils_h */
diff --git a/cesar/hal/phy/spoc/spoc.h b/cesar/hal/phy/spoc/spoc.h
index 7288d09852..5cc7e19ce1 100644
--- a/cesar/hal/phy/spoc/spoc.h
+++ b/cesar/hal/phy/spoc/spoc.h
@@ -86,11 +86,9 @@ phy_spoc_compute_all (s32 rho_q30, phy_spoc_coeff_t *coeff);
* Initialise SPOC initial state.
* \param ctx phy context
* \param rho_q30 initial frequency error, Q30 format
- * \param tonemask tonemask data
- * \param carrier_nb number of active carriers in the given tone mask
*/
void
-phy_spoc_init (phy_t *ctx, s32 rho_q30, const u32 *tonemask, uint carrier_nb);
+phy_spoc_init (phy_t *ctx, s32 rho_q30);
/**
* Set SPOC coefficients for TX.
diff --git a/cesar/hal/phy/spoc/src/spoc.c b/cesar/hal/phy/spoc/src/spoc.c
index b04a0f06cb..9e37f3489a 100644
--- a/cesar/hal/phy/spoc/src/spoc.c
+++ b/cesar/hal/phy/spoc/src/spoc.c
@@ -131,6 +131,9 @@ phy_spoc_compute_m_matrix (s32 rho_q30, s32 *reg_alpha, s32 *reg_beta)
void
phy_spoc_compute_all (s32 rho_q30, phy_spoc_coeff_t *coeff)
{
+ if (!(rho_q30 >= -PHY_SPOC_RHO_MAX_Q30
+ && rho_q30 <= PHY_SPOC_RHO_MAX_Q30))
+ return;
dbg_assert (rho_q30 >= -PHY_SPOC_RHO_MAX_Q30
&& rho_q30 <= PHY_SPOC_RHO_MAX_Q30);
dbg_assert_ptr (coeff);
diff --git a/cesar/hal/phy/spoc/src/spoc_regs.c b/cesar/hal/phy/spoc/src/spoc_regs.c
index 6b79046823..4e56762ecd 100644
--- a/cesar/hal/phy/spoc/src/spoc_regs.c
+++ b/cesar/hal/phy/spoc/src/spoc_regs.c
@@ -17,21 +17,18 @@
#include "hal/phy/inc/regs.h"
#include "hal/phy/spoc/inc/defs.h"
-#include "hal/phy/spoc/inc/utils.h"
#include "hal_phy_params.h"
/**
* Set SPOC coefficients for Wiener.
* \param ctx phy context
- * \param tonemask tonemask data
- * \param carrier_nb number of active carriers in the given tone mask
*/
static void
-phy_spoc_wiener_set (phy_t *ctx, const u32 *tonemask, uint carrier_nb);
+phy_spoc_wiener_set (phy_t *ctx);
void
-phy_spoc_init (phy_t *ctx, s32 rho_q30, const u32 *tonemask, uint carrier_nb)
+phy_spoc_init (phy_t *ctx, s32 rho_q30)
{
/* Compute coefficients for 0 frequency error. */
phy_spoc_coeff_t coeff;
@@ -41,7 +38,7 @@ phy_spoc_init (phy_t *ctx, s32 rho_q30, const u32 *tonemask, uint carrier_nb)
/* Set coefficients. */
phy_spoc_tx_set (ctx, &coeff);
phy_spoc_rx_set (ctx, &coeff);
- phy_spoc_wiener_set (ctx, tonemask, carrier_nb);
+ phy_spoc_wiener_set (ctx);
/* No bypass. */
PHY_DSPSS_SPOC_DEBUG_MODE = 0;
/* Channel maximum erasing. */
@@ -126,13 +123,10 @@ phy_spoc_rx_set (phy_t *ctx, phy_spoc_coeff_t *coeff)
}
static void
-phy_spoc_wiener_set (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
+phy_spoc_wiener_set (phy_t *ctx)
{
uint i;
dbg_assert (ctx);
- /* Analyse tonemask. */
- uint first_unmasked, last_unmasked;
- phy_spoc_analyse_tonemask (tonemask, &first_unmasked, &last_unmasked);
/* Fill registers. */
static const int wiener_real[] = PHY_PARAM_WIENER_REAL;
static const int wiener_imag[] = PHY_PARAM_WIENER_IMAG;
@@ -141,10 +135,8 @@ phy_spoc_wiener_set (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
PHY_DSPSS_SPOC_CP_PREBEGIN_n_WIENER_REAL_n[i] = wiener_real[i];
PHY_DSPSS_SPOC_CP_PREEND_n_WIENER_IMAG_n[i] = wiener_imag[i];
}
- PHY_DSPSS_SPOC_RHO_WIENER_USED_CARRIER = /* See DSPSS spec. */
- last_unmasked - first_unmasked + 21;
- PHY_DSPSS_SPOC_M_CENTRAL_WIENER_FIRST_CARRIER = /* Idem. */
- PHY_CARRIER_OFFSET + first_unmasked - 9;
+ PHY_DSPSS_SPOC_RHO_WIENER_USED_CARRIER = PHY_CARRIER_NB;
+ PHY_DSPSS_SPOC_M_CENTRAL_WIENER_FIRST_CARRIER = PHY_CARRIER_OFFSET;
PHY_DSPSS_SPOC_FILTER_SHIFT =
BF_FILL (PHY_DSPSS_SPOC_FILTER_SHIFT,
PHY_PARAM_WIENER_SPOC_FILTER_SHIFT);
@@ -155,9 +147,5 @@ phy_spoc_wiener_set (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
dbg_assert (PHY_DSPSS_SPOC_SET_REQUEST
== PHY_DSPSS_SPOC_SET_REQUEST__NONE);
PHY_DSPSS_SPOC_SET_REQUEST = PHY_DSPSS_SPOC_SET_REQUEST__WIENER;
- /* Enable wiener. */
- PHY_DSPSS_WIENER_PHASE_CORRECTION =
- BF_FILL (PHY_DSPSS_WIENER_PHASE_CORRECTION,
- (PHASE_CORRECTION_EN, 1));
}
diff --git a/cesar/hal/phy/spoc/test/Makefile b/cesar/hal/phy/spoc/test/Makefile
index ab95f242ad..120bdf2ddd 100644
--- a/cesar/hal/phy/spoc/test/Makefile
+++ b/cesar/hal/phy/spoc/test/Makefile
@@ -3,16 +3,18 @@ BASE = ../../../..
ECOS = y
TARGET = sparc
-HOST_PROGRAMS = test_spoc
-TARGET_PROGRAMS = test_spoc_target
+HOST_PROGRAMS = spoc_host_check_coeff
+TARGET_PROGRAMS = spoc_target_check_coeff
-test_spoc_SOURCES = test_spoc.c spoc_coeff_check.c
-test_spoc_MODULES = lib hal/phy/spoc mac/common
+spoc_host_check_coeff_SOURCES = spoc_coeff_check.c
+spoc_host_check_coeff_MODULES = lib hal/phy/spoc
+spoc_host_check_coeff_CONFIG_MODULES = mac/common
-test_spoc_target_SOURCES = test_spoc.c spoc_coeff_check.c
-test_spoc_target_MODULES = lib hal/arch hal/phy hal/phy/spoc mac/common
+spoc_target_check_coeff_SOURCES = spoc_coeff_check.c
+spoc_target_check_coeff_MODULES = lib hal/arch hal/phy hal/phy/spoc
+spoc_target_check_coeff_CONFIG_MODULES = mac/common
-hal_phy_spoc_MODULE_SOURCES = spoc.c utils.c
+hal_phy_spoc_MODULE_SOURCES = spoc.c
coeff_h = obj/inc/coeff.h
CLEAN_FILES += $(coeff_h)
diff --git a/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c b/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c
index 00c96e8d28..21deb2019b 100644
--- a/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c
+++ b/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c
@@ -117,3 +117,16 @@ test_spoc_coeff (test_t test)
}
}
+int
+main (int argc, char **argv)
+{
+ test_t test;
+
+ test_init (test, argc, argv);
+
+ test_spoc_coeff (test);
+
+ test_result (test);
+ return (test_nb_failed (test) == 0 ? 0 : 1);
+}
+
diff --git a/cesar/hal/phy/spoc/test/src/test_spoc.c b/cesar/hal/phy/spoc/test/src/test_spoc.c
deleted file mode 100644
index 0b6c45f4c8..0000000000
--- a/cesar/hal/phy/spoc/test/src/test_spoc.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Cesar project {{{
- *
- * Copyright (C) 2010 Spidcom
- *
- * <<<Licence>>>
- *
- * }}} */
-/**
- * \file src/test_spoc.c
- * \brief SPOC module check.
- * \ingroup test
- */
-#include "common/std.h"
-#include "lib/test.h"
-#include "hal/phy/spoc/inc/utils.h"
-#include "mac/common/tonemask.h"
-
-#include <string.h>
-#include <stdio.h>
-
-void
-test_spoc_coeff (test_t test);
-
-static void
-test_spoc_analyse_tonemask (test_t t)
-{
- volatile uint i, j;
- tonemask_info_t ti;
- uint carrier_nb;
- uint first_unmasked, last_unmasked;
- test_case_begin (t, "analyse_tonemask");
- test_begin (t, "default")
- {
- carrier_nb = tonemask_default (ti.tonemask);
- dbg_assert (carrier_nb == 917);
- phy_spoc_analyse_tonemask (ti.tonemask, &first_unmasked,
- &last_unmasked);
- test_fail_unless (first_unmasked == 86 - PHY_CARRIER_OFFSET);
- test_fail_unless (last_unmasked == 1143 - PHY_CARRIER_OFFSET);
- } test_end;
- test_begin (t, "full")
- {
- memset (ti.tonemask, 0, sizeof ti.tonemask);
- carrier_nb = PHY_CARRIER_NB;
- phy_spoc_analyse_tonemask (ti.tonemask, &first_unmasked,
- &last_unmasked);
- test_fail_unless (first_unmasked == 0);
- test_fail_unless (last_unmasked == PHY_CARRIER_NB - 1);
- } test_end;
- for (i = 0; i < 32; i++)
- for (j = 0; j < 32; j++)
- {
- char test_name[32];
- snprintf (test_name, sizeof test_name, "begin %d end %d", i, j);
- test_begin (t, test_name)
- {
- uint last_unmasked_expect;
- memset (ti.tonemask, 0, sizeof ti.tonemask);
- ti.tonemask[0] = ~(1u << i);
- if (PHY_CARRIER_NB % 32 == 0 || j < PHY_CARRIER_NB % 32)
- {
- last_unmasked_expect = (PHY_TONEMASK_WORDS - 1) * 32 + j;
- ti.tonemask[PHY_TONEMASK_WORDS - 1] = ~(1u << j);
- }
- else
- {
- last_unmasked_expect = (PHY_TONEMASK_WORDS - 2) * 32 + j;
- ti.tonemask[PHY_TONEMASK_WORDS - 2] = ~(1u << j);
- ti.tonemask[PHY_TONEMASK_WORDS - 1] = ~0u;
- }
- carrier_nb = 42; /* Not really used. */
- phy_spoc_analyse_tonemask (ti.tonemask, &first_unmasked,
- &last_unmasked);
- test_fail_unless (first_unmasked == i);
- test_fail_unless (last_unmasked == last_unmasked_expect);
- } test_end;
- }
-}
-
-int
-main (int argc, char **argv)
-{
- test_t t;
- test_init (t, argc, argv);
- test_spoc_coeff (t);
- test_suite_begin (t, "utils");
- test_spoc_analyse_tonemask (t);
- test_result (t);
- return test_nb_failed (t) == 0 ? 0 : 1;
-}
-
diff --git a/cesar/hal/phy/src/phy.c b/cesar/hal/phy/src/phy.c
index c02b2249cf..254bb07664 100644
--- a/cesar/hal/phy/src/phy.c
+++ b/cesar/hal/phy/src/phy.c
@@ -29,6 +29,7 @@
#include "config/phy/trace/more.h"
#include "config/phy/cap.h"
+#include "config/phy/cap/mask.h"
#include "lib/stats.h"
#include "lib/fixed.h"
@@ -474,6 +475,14 @@ phy_init_tunable_param (phy_t *ctx)
&ctx->cap_mask,
LIB_STATS_ACCESS_WRITE_ONLY,
LIB_STATS_DEBUG);
+ lib_stats_set_stat_value_notype ("DELTA_RES_COEF_INTERNAL",
+ &phy_tunable.delta_res_coef_internal,
+ LIB_STATS_ACCESS_WRITE_ONLY,
+ LIB_STATS_DEBUG);
+ lib_stats_set_stat_value_notype ("DELTA_RES_COEF_EXTERNAL",
+ &phy_tunable.delta_res_coef_external,
+ LIB_STATS_ACCESS_WRITE_ONLY,
+ LIB_STATS_DEBUG);
#endif
ctx->cap_mask = CONFIG_PHY_CAP_MASK_DEFAULT;
}
@@ -746,7 +755,7 @@ phy_set_robo_param (phy_t *ctx, u32 *tonemask, uint carrier_nb)
}
static void
-phy_set_tunable_param (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
+phy_set_tunable_param (phy_t *ctx)
{
uint i;
for (i = 0; i < COUNT (phy_tunable.mafadese_coef_filter_band0); i++)
@@ -755,8 +764,7 @@ phy_set_tunable_param (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
for (i = 0; i < COUNT (phy_tunable.mafadese_coef_filter_band1); i++)
PHY_DSPSS_MAFADESE_COEF_FILTER_BAND_1_n[i] =
phy_tunable.mafadese_coef_filter_band1[i];
- phy_spoc_init (ctx, phy_tunable.spoc_rho_initial_q30, tonemask,
- carrier_nb);
+ phy_spoc_init (ctx, phy_tunable.spoc_rho_initial_q30);
PHY_DSPSS_CHANNEL_ESTIM_COEF =
PHY_PARAMS (PHY_DSPSS, CHANNEL_ESTIM_COEF, COEF_PREAMBLE)
| BF_FILL (
@@ -848,7 +856,7 @@ phy_set_tonemask (phy_t *ctx, u32 *tonemask, uint carrier_nb)
PHY_DSPSS_HP10_FC_MASK_1 = 0x000E0000;
PHY_DSPSS_HP10_FC_MASK_2 = 0xFFF00060;
/* Set tunable parameters. */
- phy_set_tunable_param (ctx, tonemask, carrier_nb);
+ phy_set_tunable_param (ctx);
/* Set ROBO parameters. */
phy_set_robo_param (ctx, tonemask, carrier_nb);
/* Create preamble and PRS. */
diff --git a/cesar/hal/phy/src/rx.c b/cesar/hal/phy/src/rx.c
index ebd45f2546..0ecf6a5cfe 100644
--- a/cesar/hal/phy/src/rx.c
+++ b/cesar/hal/phy/src/rx.c
@@ -204,7 +204,7 @@ phy_rx_prepare_sound (phy_t *ctx, uint nb_pb, u32 mod_fecrate_pb_size,
symbol_nb);
}
-u32 ARCH_ILRAM
+u32 /*ARCH_ILRAM*/
phy_rx_fc10 (phy_t *ctx)
{
dbg_claim (ctx);
@@ -228,3 +228,10 @@ phy_rx_sysdate (phy_t *ctx)
PHY_DSPSS_RESYS_DETECT_OFFSET);
}
+u32 ARCH_ILRAM
+phy_rx_agc_gain (phy_t *ctx)
+{
+ dbg_claim (ctx);
+ return BF_GET (PHY_DSPSS_MAGIC_PARAM_4__LAST_AGC_GAIN_VALUE,
+ PHY_DSPSS_MAGIC_PARAM_4);
+}
diff --git a/cesar/hal/phy/src/tx.c b/cesar/hal/phy/src/tx.c
index f137ed58b3..27f9ec3444 100644
--- a/cesar/hal/phy/src/tx.c
+++ b/cesar/hal/phy/src/tx.c
@@ -17,7 +17,7 @@
#include "hal/leon/itc2.h"
#include "hal/arch/arch.h"
-void ARCH_ILRAM
+void /*ARCH_ILRAM*/
phy_tx_fc10 (phy_t *ctx, u32 date, u32 fc_10)
{
dbg_claim (ctx);
@@ -215,3 +215,19 @@ phy_tx_cancel (phy_t *ctx)
PHY_PRATIC_TIMER_6_CTRL = 0;
}
+void
+phy_tx_scale_adapt_exp_set (phy_t *ctx, u8 exp)
+{
+ dbg_claim (ctx);
+ PHY_DSPSS_TX_SCALE_ADAPT_BLK_EXP = BF_SET (PHY_DSPSS_TX_SCALE_ADAPT_BLK_EXP,
+ PHY_DSPSS_TX_SCALE_ADAPT_BLK_EXP__STEP,
+ exp);
+}
+
+void
+phy_tx_scale_adapt_set (phy_t *ctx, u16 value)
+{
+ dbg_claim (ctx);
+ PHY_DSPSS_TX_SCALE_ADAPT = BF_SET (PHY_DSPSS_TX_SCALE_ADAPT,
+ PHY_DSPSS_TX_SCALE_ADAPT__GAIN, value);
+}
diff --git a/cesar/hal/phy/test/bridgedma/Makefile.mk b/cesar/hal/phy/test/bridgedma/Makefile.mk
index e20fe69dec..c53d12e2eb 100644
--- a/cesar/hal/phy/test/bridgedma/Makefile.mk
+++ b/cesar/hal/phy/test/bridgedma/Makefile.mk
@@ -6,5 +6,6 @@ TARGET_PROGRAMS = bridgedma
bridgedma_SOURCES = bridgedma.c common.c bridgedma_tx.c bridgedma_rx.c \
bridgedma_tx_rx.c
bridgedma_MODULES = lib hal/arch $(TEST_MODULES)
+bridgedma_CONFIG_MODULES = mac/common
include $(BASE)/common/make/top.mk
diff --git a/cesar/hle/src/hle.c b/cesar/hle/src/hle.c
index c324365518..60080f0acd 100644
--- a/cesar/hle/src/hle.c
+++ b/cesar/hle/src/hle.c
@@ -81,7 +81,6 @@ static inline void
hle_data_send (hle_t *ctx, u8 *buffer, uint length, uint tag,
u32 arrival_time_ntb)
{
- dbg_assert (ctx);
dbg_assert (buffer);
dbg_assert (length <= ETH_PACKET_MAX_SIZE);
@@ -135,9 +134,10 @@ hle_data_recv (hle_t *ctx, u8 *buffer, uint length)
static inline void
hle_data_buffer_add (hle_t *ctx, u8 *buffer)
{
- dbg_assert (ctx);
- dbg_assert (buffer);
- dbg_assert (ctx->cl);
+ dbg_claim (ctx);
+ dbg_claim (buffer);
+ dbg_claim (ctx->cl);
+
/* Tracing data. */
HLE_TRACE (DATA_BUFFER_ADD, phy_date (), buffer);
cl_data_buffer_add (ctx->cl, buffer);
diff --git a/cesar/interface/sniffer/test/Makefile b/cesar/interface/sniffer/test/Makefile
index fa382ea15e..bc8515c575 100644
--- a/cesar/interface/sniffer/test/Makefile
+++ b/cesar/interface/sniffer/test/Makefile
@@ -3,5 +3,6 @@ BASE = ../../..
HOST_PROGRAMS = test-sniffer
test-sniffer_SOURCES = test-sniffer.c
test-sniffer_MODULES = lib interface/sniffer bsu/beacon
+test-sniffer_CONFIG_MODULES = mac/common bsu
include $(BASE)/common/make/top.mk
diff --git a/cesar/interface/test/sparc-Makefile b/cesar/interface/test/sparc-Makefile
index 5cd45a282a..c27ebf329f 100644
--- a/cesar/interface/test/sparc-Makefile
+++ b/cesar/interface/test/sparc-Makefile
@@ -9,6 +9,7 @@ TARGET_PROGRAMS = test-interface
test-interface_SOURCES = sar_stub.c test-interface.c
test-interface_MODULES = lib interface host \
cl/stub hal bsu/beacon
+test-interface_CONFIG_MODULES = mac/common bsu
VARIANT = sparc
diff --git a/cesar/interface/test/synth-Makefile b/cesar/interface/test/synth-Makefile
index 652c36ded8..a7a2615832 100644
--- a/cesar/interface/test/synth-Makefile
+++ b/cesar/interface/test/synth-Makefile
@@ -8,6 +8,7 @@ TARGET_PROGRAMS = test-interface
test-interface_SOURCES = sar_stub.c test-interface.c
test-interface_MODULES = lib interface host \
cl/stub bsu/beacon
+test-interface_CONFIG_MODULES = mac/common bsu
VARIANT = synth
diff --git a/cesar/lib/Config b/cesar/lib/Config
index bb13fd5ab8..cb6dd037a9 100644
--- a/cesar/lib/Config
+++ b/cesar/lib/Config
@@ -18,6 +18,7 @@ CONFIG_STATS = y
CONFIG_STATS_ON_FATAL = n
CONFIG_RESTRACK = n
CONFIG_RESTRACK_KEEP = n
+CONFIG_MAC_PBPROC_EOC_FC = n
CONFIG_GPIO_FATAL = n
CONFIG_GPIO_FATAL_GPIO = 0
CONFIG_GPIO_FATAL_BLINK = n
diff --git a/cesar/lib/blk.h b/cesar/lib/blk.h
index 44277badca..44f3c2ebf5 100644
--- a/cesar/lib/blk.h
+++ b/cesar/lib/blk.h
@@ -235,6 +235,14 @@ blk_print_memory (void);
uint
blk_slack (void);
+/**
+ * Get value of free blocks.
+ * \return value of free blocks.
+ *
+ */
+uint
+blk_free_nb (void);
+
END_DECLS
#endif /* lib_blk_h */
diff --git a/cesar/lib/src/blk.c b/cesar/lib/src/blk.c
index 445339eb12..ec3487ad4e 100644
--- a/cesar/lib/src/blk.c
+++ b/cesar/lib/src/blk.c
@@ -407,3 +407,9 @@ blk_slack (void)
else
return 0;
}
+
+uint
+blk_free_nb (void)
+{
+ return blk_global.free_nb;
+}
diff --git a/cesar/lib/test/trace/Makefile b/cesar/lib/test/trace/Makefile
index 7e08ff8563..5a392df01e 100644
--- a/cesar/lib/test/trace/Makefile
+++ b/cesar/lib/test/trace/Makefile
@@ -10,5 +10,6 @@ ECOS = y
TARGET_PROGRAMS = trace_perf
trace_perf_SOURCES = trace_perf.c
trace_perf_MODULES = lib hal/phy hal/arch
+trace_perf_CONFIG_MODULES = mac/common
include $(BASE)/common/make/top.mk
diff --git a/cesar/lib/utils.h b/cesar/lib/utils.h
index fc1e689a75..c3229f27ce 100644
--- a/cesar/lib/utils.h
+++ b/cesar/lib/utils.h
@@ -73,6 +73,14 @@ lesseq_mod2p16 (u16 a, u16 b)
#define MIN(a, b) ({ typeof (a) _a = (a); typeof (b) _b = (b); \
_a < _b ? _a : _b; })
+/** Return distance between \p a to \p b modulo 2^16. This only works iff
+ * \p a and \p b are distant no more than 2^15. */
+extern inline u16
+distance_mod2p16 (u16 a, u16 b)
+{
+ return ABS(((s16) (a - b)));
+}
+
/**
* Return the upper rounded integer value of a divided by b (a/b).
* \param a the numerator
diff --git a/cesar/mac/ca/ca.h b/cesar/mac/ca/ca.h
index 4cc03ba5f5..15ef859487 100644
--- a/cesar/mac/ca/ca.h
+++ b/cesar/mac/ca/ca.h
@@ -109,6 +109,23 @@ struct ca_schedule_t
};
typedef struct ca_schedule_t ca_schedule_t;
+/** Copy of scheduler allocation from EoC bandwidth scheduler */
+struct ca_eoc_sched_record_t
+{
+ /** Destionation tei */
+ u8 tei;
+ /** Link ID to find mfs for sending */
+ u8 lid;
+ /** Duration of CCo frame*/
+ uint cco_tx_duration;
+ /** Duration of station frame*/
+ uint sta_tx_duration;
+ /** Number of polls per beacon period */
+ u8 poll;
+};
+
+typedef struct ca_eoc_sched_record_t ca_eoc_sched_record_t;
+
/** Channel Access parameters for next ACCESS event.
* This structure is read by PB Processing to prepare its new MPDU. */
struct ca_access_param_t
@@ -121,6 +138,14 @@ struct ca_access_param_t
u32 cw_start_date;
/** Available time (valid if not AIFS). */
uint duration_tck;
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ /** Available time for reverse transmission. */
+ uint reverse_duration_tck;
+ /* Tei and lid choosen by EoC scheduling */
+ u8 tei;
+ u8 lid;
+#endif
+ /** Is there a PRP? */
/** True for AIFS (allocation change, always valid). */
bool aifs;
/** Is there a PRP (valid if not unusable)? */
@@ -157,6 +182,27 @@ struct ca_alloc_param_t
};
typedef struct ca_alloc_param_t ca_alloc_param_t;
+/** Maximum number of records for one TDMA interval in Beacon Period */
+#define CA_EOC_SCHED_NB 70
+
+/** Channel Access scheduler for TDMA interval in Beacon Period*/
+struct ca_eoc_sched_t
+{
+ /** Currently active schedule records */
+ u8 toggle;
+ /** Local scheduling time */
+ u32 offset[2];
+ u32 offset0[2];
+ /** number of valid records */
+ uint record_nb[2];
+ /** current record */
+ uint record_curr[2];
+ /** array of records */
+ ca_eoc_sched_record_t * sched_record[2];
+};
+
+typedef struct ca_eoc_sched_t ca_eoc_sched_t;
+
BEGIN_DECLS
/**
@@ -235,6 +281,24 @@ void
ca_access_vcs_restart_eifs (ca_t *ctx, u32 start_date);
/**
+ * Reprogram access structure.
+ * \param ctx ca context
+ * \param date expiration date
+ * \param duration_tck grant duration
+ * \param lid lid to find proper mfs
+ * \param tei TEI fo find proper mfs
+ *
+ * Reprograme ca->access structure. This is done when you send RSOF instead
+ * of SOF. Use this artificial feeding of CA to bypass schedule structures in
+ * CA. After this FSM could behave as usual.
+ */
+#if CONFIG_MAC_COMMON_EOC_SCHED
+void
+ca_access_reprogram (ca_t *ctx, u32 date, uint duration_tck,
+ uint lid, uint tei);
+#endif
+/**
+ * Update next ACCESS information for the given grant.
* Program hardware ACCESS timer.
* \param ctx ca context
* \param date expiration date
diff --git a/cesar/mac/ca/inc/alloc.h b/cesar/mac/ca/inc/alloc.h
index 59e8d89000..f56e16daa2 100644
--- a/cesar/mac/ca/inc/alloc.h
+++ b/cesar/mac/ca/inc/alloc.h
@@ -22,6 +22,9 @@
#define CA_ALLOC_IS_USABLE(lid) ((lid) != MAC_LID_SPC_HOLE \
&& (lid) != MAC_LID_CFPI)
+#if CONFIG_MAC_PBPROC_EOC_FC
+#define CA_ALLOC_IS_HYBRID(coex, lid) 0
+#else
/** Should transmissions in the specified allocation use hybrid frame
* controls according to the specified coexistence mode. */
#define CA_ALLOC_IS_HYBRID(coex, lid) \
@@ -30,7 +33,7 @@
|| ((lid) == MAC_LID_SHARED_CSMA \
&& (coex) == MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE) \
|| MAC_LID_IS_BEACON (lid))
-
+#endif
/**
* Find the beacon period index corresponding to the given date.
* \param ctx ca context
@@ -65,4 +68,8 @@ ca_alloc_find (const ca_schedule_t *sched, uint offset_tck);
void
ca_alloc_prepare (ca_t *ctx);
+/* minimal anticip of ca_access_aifs function execution offset */
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ #define CA_ACCESS_AIFS_ANTICIP_TCK MAC_US_TO_TCK (10)
+#endif
#endif /* mac_ca_inc_alloc_h */
diff --git a/cesar/mac/ca/inc/context.h b/cesar/mac/ca/inc/context.h
index 58d8b0d2f4..a0451bcabb 100644
--- a/cesar/mac/ca/inc/context.h
+++ b/cesar/mac/ca/inc/context.h
@@ -21,6 +21,8 @@
#include "hal/arch/arch.h"
+#include "config/mac/common.h"
+
/** Channel Access state. */
enum ca_state_t
{
@@ -86,6 +88,10 @@ struct ca_t
list_t prio[MAC_CAP_NB];
/** List of MFS held until the next beacon period. */
list_t held;
+ /** EoC TDMA scheduling table*/
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ ca_eoc_sched_t ca_eoc_sched;
+#endif /* CONFIG_MAC_COMMON_EOC_SCHED */
};
/* Forward declaration in mac/ca/ca.h. */
diff --git a/cesar/mac/ca/src/access.c b/cesar/mac/ca/src/access.c
index 2e70bc7ce6..08bac46357 100644
--- a/cesar/mac/ca/src/access.c
+++ b/cesar/mac/ca/src/access.c
@@ -11,9 +11,9 @@
* \ingroup mac_ca
*/
#include "common/std.h"
+#include "mac/ca/ca.h"
#include "mac/common/timings.h"
-#include "mac/ca/ca.h"
#include "hal/phy/phy.h"
@@ -24,6 +24,14 @@
/** Anticipation delay for an access update. */
#define CA_ACCESS_UPDATE_ANTICIP_TCK MAC_US_TO_TCK (200)
+#if CONFIG_MAC_COMMON_EOC_SCHED
+#define TDMA_EOC_EMPTY_SOF_TCK (MAC_PREAMBLE_TCK + 2 * MAC_FC_AV_TCK\
+ + MAC_AIFS_TCK + MAC_CIFS_TCK)
+#define TDMA_EOC_EMPTY_POLL_TCK 2*TDMA_EOC_EMPTY_SOF_TCK
+#define TDMA_EOC_TX_OFFSET_TCK MAC_US_TO_TCK (40)
+#define TDMA_EOC_IFS_TCK MAC_US_TO_TCK (120)
+#endif
+
/** Minimum access duration. */
#define CA_ACCESS_MIN_TCK MAC_US_TO_TCK (150)
@@ -83,6 +91,92 @@ ca_access_hold (ca_t *ctx)
static mfs_tx_t *
ca_access_choose_mfs_tx (ca_t *ctx, uint glid);
+#if CONFIG_MAC_COMMON_EOC_SCHED
+
+#define SCHED_RECC_INCC(toggle, rec_nb)\
+ if (ctx->ca_eoc_sched.record_curr[toggle] >= rec_nb - 1)\
+ ctx->ca_eoc_sched.record_curr[toggle] = 0;\
+ else\
+ ctx->ca_eoc_sched.record_curr[toggle]++;
+
+#define SCHED_RECC_GET(toggle)\
+ ctx->ca_eoc_sched.sched_record[toggle] +\
+ ctx->ca_eoc_sched.record_curr[toggle];
+
+#define SCHED_STA_GET(sched)\
+ (sched->tei != MAC_TEI_BCAST) ?\
+ mac_store_sta_get_noref (ctx->store, sched->tei) : NULL;
+
+#define SCHED_MFS_GET(sched)\
+ mac_store_mfs_get_sta_tx (ctx->store, sched->lid, sched->tei);
+
+#define MANDATORY_POLLS_MAX 0x21ul
+#endif
+
+/** Go through scheduling records and give right one for next poll
+ * \param ctx ca_context
+ */
+#if CONFIG_MAC_COMMON_EOC_SCHED
+static inline ca_eoc_sched_record_t * ARCH_ILRAM
+ca_access_get_next_sched (ca_t *ctx)
+{
+ ca_eoc_sched_record_t *sched = NULL, *sched_fit = NULL;
+ uint toggle = ctx->ca_eoc_sched.toggle, i, current = 0;
+ uint rec_nb = ctx->ca_eoc_sched.record_nb[toggle];
+ u32 now = phy_date (), offset = 0;
+ sta_t *sta = NULL;
+ mfs_tx_t *mfs = NULL;
+
+ /* Mandatory polls */
+ for (i = 0; i < MIN(rec_nb, MANDATORY_POLLS_MAX); i++)
+ {
+ SCHED_RECC_INCC (toggle, rec_nb)
+ sched = SCHED_RECC_GET (toggle)
+
+ if (sched->poll)
+ {
+ sched->poll--;
+ return sched;
+ }
+
+ sta = SCHED_STA_GET (sched)
+ mfs = SCHED_MFS_GET (sched)
+ if ((mfs && mfs->seg_nb) || (sta && sta->ppb))
+ return sched;
+
+ if (sta && lesseq_mod2p32(sta->poll_time,
+ now + ctx->ca_eoc_sched.offset[toggle]))
+ return sched;
+
+ if (sta)
+ {
+ if (!sched_fit || lesseq_mod2p32(sta->poll_time, now + offset))
+ {
+ sched_fit = sched;
+ current = ctx->ca_eoc_sched.record_curr[toggle];
+ offset = sta->poll_time - now;
+ }
+ }
+ }
+ if (sched_fit)
+ {
+ if (!ctx->ca_eoc_sched.offset0[toggle])
+ ctx->ca_eoc_sched.offset0[toggle] = offset;
+ else
+ {
+ ctx->ca_eoc_sched.offset[toggle] =
+ (offset < ctx->ca_eoc_sched.offset0[toggle]) ?
+ offset : ctx->ca_eoc_sched.offset0[toggle];
+ ctx->ca_eoc_sched.offset0[toggle] = 0;
+ ctx->ca_eoc_sched.record_curr[toggle] = current;
+ }
+ return sched_fit;
+ }
+ /* if no slaves authenticated, return bcast */
+ return ctx->ca_eoc_sched.sched_record[toggle];
+}
+#endif
+
/**
* Compute access parameters.
* \param ctx ca context
@@ -103,6 +197,123 @@ ca_access_compute (ca_t *ctx, u32 end_date, bool eifs)
glid = ctx->current_allocation_param.glid;
/* Test for allocation overflow or unusable allocation. */
access_date = end_date;
+
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ // Note : The third EoC allocation use LID_CFPI
+ if (glid == MAC_LID_CFPI)
+ {
+ /* set parameters first, avoid multiple settings */
+ ctx->access.unusable = false;
+ ctx->access.param.prp = false;
+ ctx->access.param.cfp = true;
+
+ if (less_mod2p32 (access_date + CA_ACCESS_MIN_TCK, allocation_end_date))
+ {
+ /* CCo will create access, else program to next part of Beacon */
+ u32 last_allocation_date = allocation_end_date
+ - TDMA_EOC_EMPTY_SOF_TCK
+ - TDMA_EOC_IFS_TCK;
+
+ if (MAC_TEI_IS_EOC_CCO(ctx->config->tei))
+ {
+ /* If only update access timer and mfs OK skip mfs find */
+ if (eifs)
+ {
+ ctx->access.param.access_date = access_date;
+ /* Normaly, ca_access_done haven't been done */
+ mfs = ctx->access.mfs;
+ }
+ else
+ {
+ /* Calculate access.param and create entry, advance sch */
+ /* TODO: when to advance sched, only when act expires */
+ /* read current allocation */
+ uint num_retries = 0, last_sof;
+ uint duration_tck = 0;
+ uint reverse_duration_tck = 0;
+ uint lid = 0, tei = MAC_TEI_UNASSOCIATED;
+ uint toggle = ctx->ca_eoc_sched.toggle;
+
+ /* find appropriate allocation in schedule */
+ while (num_retries < ctx->ca_eoc_sched.record_nb[toggle]
+ && !mfs)
+ {
+ num_retries++;
+ last_sof = 0;
+ /* advance to next allocation */
+ const ca_eoc_sched_record_t * alloc_rec =
+ ca_access_get_next_sched (ctx);
+ dbg_claim_ptr (alloc_rec);
+ tei = alloc_rec->tei;
+ lid = alloc_rec->lid;
+ duration_tck = alloc_rec->cco_tx_duration;
+ reverse_duration_tck = alloc_rec->sta_tx_duration;
+ uint max_end_date = access_date
+ + duration_tck
+ + reverse_duration_tck
+ + TDMA_EOC_IFS_TCK;
+
+ /* duration outside the region, reform durations */
+ if (less_mod2p32 (max_end_date, allocation_end_date
+ - TDMA_EOC_EMPTY_POLL_TCK))
+ {
+ } /* reduce current exchange */
+ else if (less_mod2p32 (access_date,
+ allocation_end_date
+ - 3*TDMA_EOC_EMPTY_POLL_TCK))
+ {
+ uint duration = allocation_end_date
+ - access_date
+ - TDMA_EOC_IFS_TCK
+ - TDMA_EOC_EMPTY_POLL_TCK;
+ if (reverse_duration_tck)
+ {
+ duration_tck =
+ reverse_duration_tck = duration / 2;
+ }
+ else
+ duration_tck = duration;
+ } /* send empty SOF */
+ else if (lesseq_mod2p32 (access_date,
+ last_allocation_date))
+ {
+ duration_tck = 0;
+ reverse_duration_tck = 0;
+ last_sof = 1;
+ if (ctx->ca_eoc_sched.record_curr[toggle])
+ ctx->ca_eoc_sched.record_curr[toggle]--;
+ }
+ else
+ break;
+
+ /* set access_date only in mfs is choosen */
+ mfs = mac_store_mfs_get_sta_tx (ctx->store, lid, tei);
+ /* set access_date only in mfs is choosen */
+ if (mfs && last_sof)
+ access_date = last_allocation_date;
+ }
+ /* end while */
+
+ /* Prepare normal TDMA allocations parameters */
+ access_date = access_date + TDMA_EOC_TX_OFFSET_TCK;
+
+ /* Set access parameters. */
+ ctx->access.param.access_date = access_date;
+ ctx->access.param.duration_tck = duration_tck;
+ ctx->access.param.reverse_duration_tck =
+ reverse_duration_tck;
+ ctx->access.param.lid = lid;
+ ctx->access.param.tei = tei;
+ }
+ }
+
+ /* Reactivate RX or start PRP. */
+ if (!eifs)
+ phy_rx_activate (ctx->phy, false, end_date, true);
+ }
+ }
+ else
+#endif
if (!less_mod2p32 (access_date + CA_ACCESS_MIN_TCK, allocation_end_date)
|| !CA_ALLOC_IS_USABLE (glid))
{
@@ -136,10 +347,12 @@ ca_access_compute (ca_t *ctx, u32 end_date, bool eifs)
ca_backoff_new (ctx, cap);
access_date += ctx->backoff.bc * MAC_SLOT_TCK;
}
+
/* Set access parameters. */
ctx->access.param.access_date = access_date;
ctx->access.param.duration_tck =
allocation_end_date - access_date;
+
/* Reactivate RX or start PRP. */
if (!eifs)
{
@@ -149,6 +362,7 @@ ca_access_compute (ca_t *ctx, u32 end_date, bool eifs)
phy_rx_activate (ctx->phy, false, end_date, true);
}
}
+
/* Program access timer, and trace result. */
if (!ctx->access.unusable
&& mfs
@@ -194,6 +408,27 @@ ca_access_vcs_restart_eifs (ca_t *ctx, u32 start_date)
ca_access_compute (ctx, start_date + eifs_tck, true);
}
+#if CONFIG_MAC_COMMON_EOC_SCHED
+/* This function is called only in slave config */
+void
+ca_access_reprogram (ca_t *ctx, u32 date, uint duration_tck,
+ uint lid, uint tei)
+{
+ ctx->access.param.lid = lid;
+ ctx->access.param.tei = tei;
+ ctx->access.unusable = false;
+ ctx->access.param.aifs = false;
+ ctx->access.param.access_date = date;
+ ctx->access.param.duration_tck = duration_tck;
+ ctx->access.param.reverse_duration_tck = 0;
+ ctx->access.param.prp = false;
+ ctx->access.param.cfp = true;
+
+ ca_access_program (ctx, date);
+
+}
+#endif
+
/**
* Update current access after a MFS or schedule change.
* \param ctx ca context
@@ -206,12 +441,19 @@ ca_access_compute_update (ca_t *ctx, u32 update_date)
bool aifs = true;
u32 access_date = ctx->access.param.access_date;
u32 allocation_end_date = ctx->current_allocation_param.end_date;
+ uint glid = ctx->current_allocation_param.glid;
+
+ if (!CA_ALLOC_IS_USABLE(glid))
+ return;
/* Test whether an access is possible. */
if (!ctx->access.unusable)
{
/* Is there MFS to send? */
uint glid = ctx->current_allocation_param.glid;
- mfs_tx_t *mfs = ca_access_choose_mfs_tx (ctx, glid);
+ mfs_tx_t *mfs;
+
+ mfs = ca_access_choose_mfs_tx (ctx, glid);
+
if (mfs)
{
/* Should access be postponed? */
@@ -301,7 +543,7 @@ ca_access_aifs (ca_t *ctx)
uint alloc_i = ctx->current_allocation_index;
u32 access_date;
/* Last allocation? */
- if (alloc_i + 1 == sched->allocations_nb)
+ if (alloc_i + 1 >= sched->allocations_nb)
{
bp++;
dbg_assert (bp != ctx->beacon_periods + ctx->beacon_periods_nb);
@@ -312,6 +554,16 @@ ca_access_aifs (ca_t *ctx)
}
else
{
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ if (alloc_i == 0)
+ {
+ ctx->ca_eoc_sched.toggle = 1 - ctx->ca_eoc_sched.toggle;
+ /* set start position of current record */
+ if (ctx->ca_eoc_sched.record_nb[ctx->ca_eoc_sched.toggle])
+ ctx->ca_eoc_sched.record_curr[ctx->ca_eoc_sched.toggle] =
+ ctx->ca_eoc_sched.record_curr[1 - ctx->ca_eoc_sched.toggle];
+ }
+#endif
access_date = bp->start_date
+ sched->allocations[alloc_i].end_offset_tck;
alloc_i++;
@@ -346,11 +598,26 @@ ca_access_get_param (ca_t *ctx)
mfs_tx_t * ARCH_ILRAM
ca_access_get_mfs (ca_t *ctx)
{
+ mfs_tx_t *mfs = NULL;
dbg_claim (ctx);
dbg_claim (!ctx->access.mfs);
- /* Get an MFS for this access. */
uint glid = ctx->current_allocation_param.glid;
- mfs_tx_t *mfs = ca_access_choose_mfs_tx (ctx, glid);
+ /* Get an MFS for this access. */
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ if (glid == MAC_LID_CFPI)
+ {
+ uint tei = ctx->access.param.tei;
+ uint lid = ctx->access.param.lid;
+ mfs = mac_store_mfs_get_sta_tx (ctx->store, lid, tei);
+ }
+ else
+ {
+ mfs = ca_access_choose_mfs_tx (ctx, glid);
+ ctx->access.param.lid = mfs->common.lid;
+ }
+#else
+ mfs = ca_access_choose_mfs_tx (ctx, glid);
+#endif
/* Keep MFS pointer. */
ctx->access.mfs = mfs;
/* Return this MFS. */
@@ -391,11 +658,10 @@ ca_access_update (ca_t *ctx)
static mfs_tx_t * ARCH_ILRAM
ca_access_choose_mfs_tx (ca_t *ctx, uint glid)
{
- mfs_tx_t *mfs;
+ mfs_tx_t *mfs = NULL;
dbg_claim (ctx);
dbg_claim (glid >= MAC_GLID_MIN);
- /* If GLID, this is a CFP allocation, else choose the MFS with the greater
- * priority. */
+
if (!CA_ALLOC_IS_CSMA (glid))
{
dbg_claim (glid <= MAC_GLID_MAX
@@ -404,7 +670,8 @@ ca_access_choose_mfs_tx (ca_t *ctx, uint glid)
dbg_assert (!mfs || mfs->ca_state == CA_MFS_STATE_UNKNOWN
|| mfs->ca_state == CA_MFS_STATE_CFP_QUEUED
|| mfs->ca_state == CA_MFS_STATE_HELD
- || mfs->ca_state == CA_MFS_STATE_REMOVED);
+ || mfs->ca_state == CA_MFS_STATE_REMOVED
+ || CONFIG_MAC_COMMON_EOC_SCHED);
/* Reference is borrowed from the store. */
if (mfs)
blk_release (mfs);
@@ -429,4 +696,3 @@ ca_access_choose_mfs_tx (ca_t *ctx, uint glid)
return NULL;
}
}
-
diff --git a/cesar/mac/ca/src/alloc.c b/cesar/mac/ca/src/alloc.c
index 9c10a403c5..704bc24356 100644
--- a/cesar/mac/ca/src/alloc.c
+++ b/cesar/mac/ca/src/alloc.c
@@ -176,15 +176,16 @@ ca_alloc_update_beacon_periods (ca_t *ctx,
ca_beacon_period_t *bp = ctx->beacon_periods;
ca_schedule_t *sched = &ctx->schedules[bp->schedule_index];
uint alloc_i = ca_alloc_find (sched, now + MAC_AIFS_TCK
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ - CA_ACCESS_AIFS_ANTICIP_TCK
+#endif
- bp->start_date);
ctx->current_beacon_period = bp;
ctx->current_allocation_index = alloc_i;
ca_alloc_prepare (ctx);
- arch_isr_unlock (flags);
/* Update schedule. */
ca_access_update (ctx);
}
- else
- arch_isr_unlock (flags);
+ arch_isr_unlock (flags);
}
diff --git a/cesar/mac/ca/src/ca.c b/cesar/mac/ca/src/ca.c
index b0e30b29c3..076790b7c1 100644
--- a/cesar/mac/ca/src/ca.c
+++ b/cesar/mac/ca/src/ca.c
@@ -18,7 +18,10 @@
#include "hal/phy/phy.h"
+#include "config/mac/common.h"
+
ca_t ARCH_DLRAM_BSS ca_global;
+static ca_eoc_sched_record_t ca_eoc_shed[2][CA_EOC_SCHED_NB];
ca_t *
ca_init (phy_t *phy, mac_config_t *config, mac_store_t *store,
@@ -51,6 +54,13 @@ ca_init (phy_t *phy, mac_config_t *config, mac_store_t *store,
list_init (&ctx->prio[cap]);
list_init (&ctx->held);
CA_TRACE (INIT);
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ ctx->ca_eoc_sched.sched_record[0] = &ca_eoc_shed[0][0];
+ ctx->ca_eoc_sched.sched_record[1] = &ca_eoc_shed[1][0];
+ ctx->ca_eoc_sched.record_nb[0] = ctx->ca_eoc_sched.record_curr[0] = 0;
+ ctx->ca_eoc_sched.record_nb[1] = ctx->ca_eoc_sched.record_curr[1] = 0;
+ ctx->ca_eoc_sched.toggle = 0;
+#endif /* CONFIG_MAC_COMMON_EOC_SCHED */
return ctx;
}
@@ -109,6 +119,12 @@ ca_mfs_update_common (ca_t *ctx, mfs_tx_t *mfs, bool locked)
dbg_assert_ptr (mfs);
dbg_assert (mfs->ca_state != CA_MFS_STATE_REMOVED);
CA_TRACE (MFS_UPDATE, mfs);
+
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ /* dont update mfs for TDMA, scheduler will take care about them */
+ if (mfs->cfp && !mfs->beacon)
+ return;
+#endif
/* Lock. */
uint flags = 0;
if (!locked) flags = arch_isr_lock ();
diff --git a/cesar/mac/ca/test/ca/src/phy_stub.c b/cesar/mac/ca/test/ca/src/phy_stub.c
index fe279800b0..ed0d0e4cfb 100644
--- a/cesar/mac/ca/test/ca/src/phy_stub.c
+++ b/cesar/mac/ca/test/ca/src/phy_stub.c
@@ -49,6 +49,7 @@ phy_access_backoff_update (phy_t *ctx, uint cap)
void
phy_access_timer_program (phy_t *ctx, u32 date)
{
+ dbg_assert (lesseq_mod2p32(ctx->date, date));
dbg_assert (ctx);
}
diff --git a/cesar/mac/ca/test/ca_eoc/Config b/cesar/mac/ca/test/ca_eoc/Config
new file mode 100644
index 0000000000..8160a8dda3
--- /dev/null
+++ b/cesar/mac/ca/test/ca_eoc/Config
@@ -0,0 +1,6 @@
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_TRACE = y
+CONFIG_RESTRACK = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_MFS = y
diff --git a/cesar/mac/ca/test/ca_eoc/Makefile b/cesar/mac/ca/test/ca_eoc/Makefile
new file mode 100644
index 0000000000..e246399098
--- /dev/null
+++ b/cesar/mac/ca/test/ca_eoc/Makefile
@@ -0,0 +1,8 @@
+BASE = ../../../..
+
+HOST_PROGRAMS = test_ca
+test_ca_SOURCES = test_ca.c ../../ca/src/test_backoff.c test_alloc.c test_access.c \
+ ../../ca/src/phy_stub.c
+test_ca_MODULES = lib mac/ca mac/common
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/ca/test/ca_eoc/inc/phy_stub.h b/cesar/mac/ca/test/ca_eoc/inc/phy_stub.h
new file mode 100644
index 0000000000..b1a4746d35
--- /dev/null
+++ b/cesar/mac/ca/test/ca_eoc/inc/phy_stub.h
@@ -0,0 +1,23 @@
+#ifndef inc_phy_stub_h
+#define inc_phy_stub_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/phy_stub.h
+ * \brief HAL Phy stub.
+ * \ingroup test
+ */
+
+/** Stub phy structure. */
+struct phy_t
+{
+ u32 date;
+};
+/* Forward declaration in hal/phy/forward.h. */
+
+#endif /* inc_phy_stub_h */
diff --git a/cesar/mac/ca/test/ca_eoc/src/test_access.c b/cesar/mac/ca/test/ca_eoc/src/test_access.c
new file mode 100644
index 0000000000..c0245785b5
--- /dev/null
+++ b/cesar/mac/ca/test/ca_eoc/src/test_access.c
@@ -0,0 +1,551 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_access.c
+ * \brief Test access code.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "mac/ca/inc/context.h"
+#include "mac/ca/inc/alloc.h"
+#include "mac/common/timings.h"
+
+#include "hal/phy/phy.h"
+#include "inc/phy_stub.h"
+
+#include "lib/test.h"
+
+#include <string.h>
+
+#define NB_ITER 100000
+#define NB_PEER 5
+#define NB_GLID 20
+#define RANDOM_START 0
+
+#define PEER_MIN 10
+#define MAX_SYMB 3
+
+void
+access_random_prepare_tdma_alloc(lib_rnd_t *rnd,
+ ca_eoc_sched_t * alloc,
+ uint max_length_tck,
+ uint nb)
+{
+ uint j;
+ for(j = 0; j < 2; j++)
+ {
+ alloc->record_nb[j] = 1 + lib_rnd_uniform (rnd, nb);
+ alloc->record_curr[j] = 0;
+ uint i;
+ uint fixed_clk = MAC_RIFS_DEFAULT_TCK
+ + MAC_PREAMBLE_TCK + 2 * MAC_FC_AV_TCK;
+ for (i=0; i < alloc->record_nb[j]; i++)
+ {
+ alloc->sched_record[j][i].tei = lib_rnd_uniform (rnd, NB_PEER)
+ + PEER_MIN;
+ alloc->sched_record[j][i].lid = lib_rnd_uniform (rnd, MAC_PLID_NB)
+ + MAC_LLID_MIN;
+ alloc->sched_record[j][i].cco_tx_duration = fixed_clk
+ + MAC_PAYLOAD_TCK (1+lib_rnd_uniform (rnd, MAX_SYMB),
+ MAC_DX417_TCK);
+ alloc->sched_record[j][i].sta_tx_duration = fixed_clk
+ + MAC_PAYLOAD_TCK (1+lib_rnd_uniform (rnd, MAX_SYMB),
+ MAC_DX417_TCK);
+ }
+ }
+ alloc->toggle = 0;
+}
+
+void
+access_random_schedule_tdma (lib_rnd_t *rnd,
+ ca_schedule_t *sched,
+ uint length_tck)
+{
+ uint i;
+ const uint mini_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_AIFS_TCK;
+ const uint nb = 3;
+ /* Coexistence mode and encryption. */
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = 5;
+ sched->nek_switch = 0;
+ /* Random allocations. */
+ uint zoffset_tck = 0;
+ sched->allocations_nb = nb;
+ for (i = 0; i < nb - 1; i++)
+ {
+ sched->allocations[i].end_offset_tck =
+ lib_rnd_uniform (rnd, length_tck - zoffset_tck
+ - (nb - i) * mini_tck) + zoffset_tck + mini_tck;
+ zoffset_tck = sched->allocations[i].end_offset_tck;
+ }
+ sched->allocations[nb - 1].end_offset_tck = length_tck;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[1].glid = MAC_LID_LOCAL_CSMA;
+ sched->allocations[2].glid = MAC_LID_CFPI;
+}
+
+void
+access_random_schedule (lib_rnd_t *rnd, ca_schedule_t *sched, uint length_tck)
+{
+ uint i;
+ const uint nb = lib_rnd_uniform (rnd, 10/*CA_SCHEDULE_SIZE*/ - 3) + 3;
+ /* Coexistence mode and encryption. */
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = 5;
+ sched->nek_switch = 0;
+ /* Random allocations. */
+ uint zoffset_tck = 0;
+ uint avr_alloc_tck = length_tck/nb;
+ uint low_alloc_tck = avr_alloc_tck - (avr_alloc_tck>>2); /* 3/4 */
+ uint dif_alloc_tck = (avr_alloc_tck>>2); /* 1/4 */
+ sched->allocations_nb = nb;
+ for (i = 0; i < nb - 1; i++)
+ {
+ sched->allocations[i].end_offset_tck =
+ lib_rnd_uniform (rnd, dif_alloc_tck)
+ + zoffset_tck + low_alloc_tck;
+ zoffset_tck = sched->allocations[i].end_offset_tck;
+ }
+ sched->allocations[nb - 1].end_offset_tck = length_tck;
+ /* Random GLID. */
+ static const struct
+ {
+ u8 glid_min;
+ u8 glid_max;
+ uint prob;
+ } glid_prob[] = {
+ { MAC_LID_SPC_HOLE, MAC_LID_SPC_HOLE, 8 },
+ { MAC_GLID_MIN, MAC_GLID_MAX, 8 + 8 },
+ { MAC_LID_CFPI, MAC_LID_CFPI, 8 + 8 + 1 },
+ { MAC_LID_SHARED_CSMA, MAC_LID_SHARED_CSMA, 8 + 8 + 1 + 2 + 8 },
+ { MAC_LID_LOCAL_CSMA, MAC_LID_LOCAL_CSMA, 8 + 8 + 1 + 2 + 8 + 8 },
+ };
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ for (i = 1; i < nb; i++)
+ {
+ uint r = lib_rnd_uniform (rnd, glid_prob[COUNT (glid_prob) - 1].prob);
+ uint j;
+ DICHOTOMY_SEARCH (0, COUNT (glid_prob), j, r < glid_prob[j].prob);
+ dbg_assert (j < COUNT (glid_prob));
+ sched->allocations[i].glid = glid_prob[j].glid_min
+ + lib_rnd_uniform (rnd, glid_prob[j].glid_max
+ - glid_prob[j].glid_min + 1);
+ }
+}
+
+/**
+ * Get allocation end date without AIFS.
+ * \param ca CA context
+ * \param date date in allocation
+ * \return allocation end date
+ */
+static uint
+access_allocation_end_date (ca_t *ca, uint date)
+{
+ dbg_assert (ca);
+ ca_beacon_period_t *bp = ca_alloc_find_beacon_period (ca, date);
+ dbg_assert (bp);
+ ca_schedule_t *sched = &ca->schedules[bp->schedule_index];
+ uint alloc_i = ca_alloc_find (sched, date - bp->start_date);
+ dbg_assert (alloc_i < sched->allocations_nb);
+ ca_allocation_t *alloc = &sched->allocations[alloc_i];
+ return bp->start_date + alloc->end_offset_tck;
+}
+
+/**
+ * Compute AIFS at given date.
+ * \param ca CA context
+ * \param date current date
+ * \return AIFS in tck
+ */
+static uint
+access_aifs_tck (ca_t *ca, uint date)
+{
+ dbg_assert (ca);
+ ca_beacon_period_t *bp = ca_alloc_find_beacon_period (ca, date);
+ dbg_assert (bp);
+ ca_schedule_t *sched = &ca->schedules[bp->schedule_index];
+ uint alloc_i = ca_alloc_find (sched, date - bp->start_date);
+ dbg_assert (alloc_i < sched->allocations_nb);
+ ca_allocation_t *alloc = &sched->allocations[alloc_i];
+ uint aifs_tck = MAC_LID_IS_BEACON (alloc->glid)
+ ? MAC_B2BIFS_TCK : MAC_AIFS_TCK;
+ if (alloc_i == sched->allocations_nb - 1
+ && MAC_LID_IS_BEACON (ca->schedules[bp[1].schedule_index]
+ .allocations[0].glid)
+ && MAC_B2BIFS_TCK > MAC_AIFS_TCK)
+ aifs_tck = MAC_B2BIFS_TCK;
+ return aifs_tck;
+}
+
+void
+access_check_vcs_restart (test_t t, ca_t *ca, u32 date, uint duration_tck,
+ bool eifs, const ca_alloc_param_t *ap)
+{
+ test_within (t);
+ dbg_assert (ca);
+ ca_beacon_period_t *bp = ca_alloc_find_beacon_period (ca, date);
+ dbg_assert (bp);
+ ca_schedule_t *sched = &ca->schedules[bp->schedule_index];
+ dbg_assert (sched->coexistence_mode < MAC_COEXISTENCE_NB);
+ dbg_assert (sched->snid < 16);
+ dbg_assert (sched->nek_switch < 2);
+ dbg_assert (sched->allocations_nb);
+ uint alloc_i = ca_alloc_find (sched, date - bp->start_date);
+ dbg_assert (alloc_i < sched->allocations_nb);
+ ca_allocation_t *alloc = &sched->allocations[alloc_i];
+ ca_access_param_t *a = &ca->access.param;
+ uint aifs_tck = access_aifs_tck (ca, date);
+ uint alloc_end_date = bp->start_date + alloc->end_offset_tck - aifs_tck;
+ if (ap)
+ {
+ /* Check current allocation parameters. */
+ test_fail_unless (ap->coexistence_mode == sched->coexistence_mode);
+ test_fail_unless (ap->snid == sched->snid);
+ test_fail_unless (ap->nek_switch == sched->nek_switch);
+ test_fail_unless (ap->end_date == alloc_end_date);
+ }
+ if (!ca->access.unusable)
+ {
+ /* Usable, the access should be prepared. */
+ test_fail_unless (lesseq_mod2p32 (date, a->access_date));
+ /* TDMA check elements */
+ if (alloc->glid == MAC_LID_CFPI)
+ {
+ uint sched_i;
+ sched_i = ca->ca_eoc_sched.record_curr[ca->ca_eoc_sched.toggle];
+ const ca_eoc_sched_record_t * alloc_rec =
+ &ca->ca_eoc_sched.sched_record[ca->ca_eoc_sched.toggle][sched_i];
+ uint lid = alloc_rec->lid;
+ uint tei = alloc_rec->tei;
+ uint duration_tck = alloc_rec->cco_tx_duration;
+ uint reverse_duration_tck = alloc_rec->sta_tx_duration;
+ /* select end of period */
+ if (a->duration_tck != a->reverse_duration_tck)
+ {
+ test_fail_unless (a->duration_tck == duration_tck);
+ test_fail_unless (a->reverse_duration_tck
+ == reverse_duration_tck);
+ }
+ test_fail_unless (a->tei == tei);
+ test_fail_unless (a->lid == lid);
+ test_fail_unless (a->cfp == true);
+ test_fail_unless (a->prp == false);
+ }
+ else
+ {
+ /* MFS scheduled. */
+ uint slot = CA_ALLOC_IS_CSMA (alloc->glid)
+ ? (eifs ? 0 : 2) + ca->backoff.bc
+ : 0;
+ bool prp = CA_ALLOC_IS_CSMA (alloc->glid) && !eifs;
+ test_fail_unless (a->access_date == date + duration_tck
+ + slot * MAC_SLOT_TCK);
+ test_fail_unless (a->cw_start_date == date + duration_tck
+ + (prp ? 2 * MAC_SLOT_TCK : 0));
+ test_fail_unless (a->aifs
+ || (a->duration_tck == alloc_end_date
+ - a->access_date));
+ test_fail_unless (a->prp == prp);
+ test_fail_unless (a->cfp == !CA_ALLOC_IS_CSMA (alloc->glid));
+ }
+ }
+ if (!a->aifs)
+ {
+ /* ACCESS scheduled. */
+ test_fail_unless (lesseq_mod2p32 (a->access_date, alloc_end_date));
+ test_fail_unless (ca->access.timer_date == a->access_date
+ - ca->anticipation_tck);
+ }
+ else
+ {
+ /* AIFS scheduled. */
+ if (alloc->glid != MAC_LID_CFPI)
+ test_fail_unless (ca->access.timer_date == alloc_end_date);
+ else
+ test_fail_unless (lesseq_mod2p32 (ca->access.timer_date, alloc_end_date));
+ }
+}
+
+void
+access_check_vcs_restart_eifs (test_t t, ca_t *ca, u32 date,
+ const ca_alloc_param_t *ap)
+{
+ const ca_alloc_param_t *cap = &ca->current_allocation_param;
+ uint eifs_tck = ((cap->coexistence_mode
+ == MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE)
+ || !cap->hybrid) ? MAC_EIFS_AV_TCK : MAC_EIFS_10_TCK;
+ access_check_vcs_restart (t, ca, date, eifs_tck, true, ap);
+}
+
+void
+access_check_defer (test_t t, ca_t *ca)
+{
+ test_within (t);
+ dbg_assert (ca);
+ test_fail_unless (ca->access.param.aifs);
+ test_fail_unless (ca->access.timer_date !=
+ ca->current_allocation_param.end_date
+ - access_aifs_tck (ca, ca->access.timer_date));
+}
+
+void
+access_check_aifs (test_t t, ca_t *ca, u32 date,
+ const ca_alloc_param_t *ap)
+{
+ dbg_assert_ptr (ap);
+ access_check_vcs_restart (t, ca, access_allocation_end_date (ca, date), 0,
+ false, ap);
+}
+
+void
+access_basic_test_case (test_t t)
+{
+ uint i, j;
+ lib_rnd_t rnd[1];
+ phy_t *phy;
+ mac_config_t config;
+ mac_store_t *store;
+ ca_t *ca;
+ test_case_begin (t, "basic");
+ /* Initialise. */
+ lib_rnd_init (rnd, 1234);
+ phy = phy_init (NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+#if RANDOM_START
+ phy->date = lib_rnd32 (rnd);
+#else
+ phy->date = MAC_MS_TO_TCK (500 / 50);
+#endif
+ mac_config_init (&config);
+ config.tei = 1;
+ store = mac_store_init ();
+ ca = ca_init (phy, &config, store, 0);
+ /* Characteristics for null slots are determined as-is:
+ * - for index < NB_GLID: i = index
+ * - lid = i != 0 ? i + MAC_GLID_MIN : MAC_LID_SPC_CENTRAL
+ * - cap = i % 4
+ * - tei = i % NB_PEER + PEER_MIN
+ * - bcast = false
+ * - cfp = true
+ * - for index >= NB_GLID: i = index - NB_GLID
+ * - lid = i % MAC_PLID_NB + MAC_PLID_MIN
+ * - cap = lid - MAC_PLID_MIN
+ * - tei = i >= MAC_PLID_NB * NB_PEER
+ * ? MAC_TEI_BCAST
+ * : i / MAC_PLID_NB + PEER_MIN
+ * - bcast = i >= MAC_PLID_NB * NB_PEER
+ * - cfp = false
+ */
+ mfs_tx_t *mfses[NB_GLID + MAC_PLID_NB * (1 + NB_PEER)];
+ uint mfses_used = 0;
+ memset (mfses, 0, sizeof (mfses));
+ /* Now the big test.
+ * Create random schedules and random MFS for the STA with TEI = [2,3]. */
+ test_begin (t, "random test")
+ {
+ const int beacon_period_length_tck = MAC_MS_TO_TCK (1000 / 10);
+ ca_beacon_period_t bps[2];
+ /* Initialise first beacon period. */
+ access_random_schedule (rnd, ca_alloc_get_schedule (ca, 3),
+ beacon_period_length_tck);
+ bps[1].start_date = phy->date - beacon_period_length_tck / 2;
+ bps[1].schedule_index = 3;
+ /* Update allocations for TDMA period */
+ access_random_prepare_tdma_alloc(rnd, &ca->ca_eoc_sched, 1000, 20);
+ for (i = 0; i < NB_ITER; i++)
+ {
+ /* Make new schedule. */
+ access_random_schedule (rnd, ca_alloc_get_schedule (ca, i % 4),
+ beacon_period_length_tck);
+ /* Make new beacon period. */
+ bps[0] = bps[1];
+ bps[1].start_date = bps[0].start_date + beacon_period_length_tck;
+ bps[1].schedule_index = i % 4;
+ /* Update beacon period. */
+ phy->date += CA_ACCESS_AIFS_ANTICIP_TCK;
+ ca_alloc_update_beacon_periods (ca, bps, COUNT (bps));
+ phy->date -= CA_ACCESS_AIFS_ANTICIP_TCK;
+ /* First schedule. */
+ if (i == 0)
+ {
+ const ca_alloc_param_t *ap =
+ ca_access_activate (ca, phy->date);
+ access_check_vcs_restart_eifs (t, ca, phy->date, ap);
+ }
+ while (less_mod2p32 (phy->date, bps[1].start_date))
+ {
+ if (phy->date == ca->access.timer_date
+ || lib_rnd_flip_coin (rnd, LIB_RND_RATIO (0.5)))
+ {
+ /* Next ACCESS. */
+ phy->date = ca->access.timer_date;
+ if (!ca->access.param.aifs)
+ {
+ mfs_tx_t *mfs = ca_access_get_mfs (ca);
+ int seg_sent;
+ uint fl_tck;
+ if (mfs)
+ {
+ /* Timings are completely approximated. */
+ seg_sent = mfs->seg_nb
+ ? lib_rnd_uniform (rnd, mfs->seg_nb) + 1 : 0;
+ fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_DX567_TCK * seg_sent;
+ }
+ if (!mfs
+ || mfs->seg_nb == 0
+ || fl_tck > ca->access.param.duration_tck)
+ {
+ ca_access_done (ca);
+ ca_access_defer (ca, phy->date);
+ access_check_defer (t, ca);
+ }
+ else
+ {
+ ca_access_vcs_restart_eifs (ca, phy->date);
+ access_check_vcs_restart_eifs (t, ca, phy->date,
+ NULL);
+ if (seg_sent)
+ {
+ mfs->seg_nb -= seg_sent;
+ ca_access_done (ca);
+ ca_access_vcs_restart (ca,
+ phy->date + fl_tck);
+ access_check_vcs_restart (t, ca, phy->date,
+ fl_tck, false,
+ NULL);
+ }
+ else
+ ca_access_done (ca);
+ }
+ }
+ else
+ {
+ const ca_alloc_param_t *ap = ca_access_aifs (ca);
+ access_check_aifs (t, ca, phy->date, ap);
+ }
+ }
+ else
+ {
+ /* Random event. */
+ dbg_assert (less_mod2p32 (phy->date,
+ ca->access.timer_date));
+ u32 next_date = phy->date + lib_rnd_uniform (
+ rnd, ca->access.timer_date - phy->date);
+ /* TODO: For the moment, avoid bad cases where date is in
+ * AIFS. */
+ u32 danger_date = bps[1].start_date + MAC_US_TO_TCK (100);
+ if (!less_mod2p32 (next_date, danger_date))
+ next_date = danger_date;
+ phy->date = next_date;
+ if (mfses_used == 0
+ || lib_rnd_flip_coin (rnd, LIB_RND_RATIO (0.2)))
+ {
+ j = lib_rnd_uniform (rnd, COUNT (mfses));
+ if (!mfses[j])
+ {
+ /* Create a new MFS. */
+ uint lid, cap, tei;
+ bool bcast, cfp;
+ if (j < NB_GLID)
+ {
+ lid = j != 0 ? j + MAC_GLID_MIN
+ : MAC_LID_SPC_CENTRAL;
+ cap = j % 4;
+ tei = j % NB_PEER + PEER_MIN;
+ bcast = false;
+ cfp = true;
+ }
+ else
+ {
+ uint sj = j - NB_GLID;
+ cap = sj % MAC_PLID_NB;
+ bcast = sj >= MAC_PLID_NB * NB_PEER;
+ lid = cap +
+ (bcast ? MAC_PLID_MIN : MAC_LLID_MIN);
+ tei = bcast ? MAC_TEI_BCAST
+ : sj / MAC_PLID_NB + PEER_MIN;
+ cfp = true;
+ }
+ bool added;
+ mfs_tx_t *mfs = mac_store_mfs_add_tx
+ (store, bcast, false, lid, tei, &added);
+ mfs->cfp = cfp;
+ dbg_assert (added);
+ mfs->seg_nb = lib_rnd_uniform (rnd, 100);
+ mfses[j] = mfs;
+ mfses_used++;
+ ca_mfs_add (ca, mfs);
+ }
+ else
+ {
+ /* Remove an MFS. */
+ mfs_tx_t *mfs = mfses[j];
+ ca_mfs_remove (ca, mfs);
+ mfs->seg_nb = 0;
+ mac_store_mfs_remove (store,
+ PARENT_OF (mfs_t, tx, mfs));
+ blk_release (mfs);
+ mfses[j] = NULL;
+ mfses_used--;
+ }
+ }
+ else
+ {
+ /* Modify an MFS. */
+ do {
+ j = lib_rnd_uniform (rnd, COUNT (mfses));
+ } while (!mfses[j]);
+ mfs_tx_t *mfs = mfses[j];
+ if (mfs->ca_state != CA_MFS_STATE_HELD)
+ {
+ if (lib_rnd_flip_coin (rnd, LIB_RND_RATIO (0.05)))
+ {
+ ca_mfs_hold (ca, mfs);
+ }
+ else
+ {
+ mfs->seg_nb = lib_rnd_uniform (rnd, 100);
+ ca_mfs_update (ca, mfs);
+ }
+ }
+ }
+ }
+ }
+ }
+ ca_access_deactivate (ca);
+ } test_end;
+ /* Uninitialise. */
+ for (i = 0; i < COUNT (mfses); i++)
+ {
+ mfs_tx_t *mfs = mfses[i];
+ if (mfs)
+ {
+ ca_mfs_remove (ca, mfs);
+ mac_store_mfs_remove (store, PARENT_OF (mfs_t, tx, mfs));
+ blk_release (mfs);
+ }
+ }
+ for (i = 0; i < NB_PEER; i++)
+ {
+ bool ok = mac_store_sta_remove (store, PEER_MIN + i);
+ dbg_assert (ok);
+ }
+ ca_uninit (ca);
+ phy_uninit (phy);
+ mac_store_uninit (store);
+}
+
+void
+access_test_suite (test_t t)
+{
+ test_suite_begin (t, "access");
+ access_basic_test_case (t);
+}
+
diff --git a/cesar/mac/ca/test/ca_eoc/src/test_alloc.c b/cesar/mac/ca/test/ca_eoc/src/test_alloc.c
new file mode 100644
index 0000000000..91aaa6f61c
--- /dev/null
+++ b/cesar/mac/ca/test/ca_eoc/src/test_alloc.c
@@ -0,0 +1,444 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_alloc.c
+ * \brief Test allocations code.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "mac/ca/inc/context.h"
+#include "mac/ca/inc/access.h"
+#include "mac/ca/inc/alloc.h"
+#include "mac/common/timings.h"
+
+#include "hal/phy/phy.h"
+#include "inc/phy_stub.h"
+
+#include "lib/test.h"
+
+#define NB_ITER 100000
+
+void
+alloc_basic_test_case (test_t t)
+{
+ uint i, j;
+ lib_rnd_t rnd[1];
+ phy_t *phy;
+ mac_config_t config;
+ mac_store_t *store;
+ ca_t *ca;
+ test_case_begin (t, "basic");
+ /* Initialise. */
+ phy = phy_init (NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ mac_config_init (&config);
+ config.tei = 1;
+ store = mac_store_init ();
+ ca = ca_init (phy, &config, store, 0);
+ lib_rnd_init (rnd, 1234);
+/*
+ test_begin (t, "is hybrid")
+ {
+ struct
+ {
+ u8 lid;
+ mac_coexistence_mode_t coex;
+ bool expect;
+ } is_hybrid_tab[] = {
+ { 0x80, MAC_COEXISTENCE_AV_ONLY_MODE, false },
+ { 0x8a, MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE, false },
+ { 0xa2, MAC_COEXISTENCE_FULL_HYBRID_MODE, true },
+ { 0xcd, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_AV_ONLY_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_FULL_HYBRID_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, true },
+ { MAC_LID_SHARED_CSMA, MAC_COEXISTENCE_AV_ONLY_MODE, false },
+ { MAC_LID_SHARED_CSMA, MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE, true },
+ { MAC_LID_SHARED_CSMA, MAC_COEXISTENCE_FULL_HYBRID_MODE, true },
+ { MAC_LID_SHARED_CSMA, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, true },
+ { MAC_LID_LOCAL_CSMA, MAC_COEXISTENCE_AV_ONLY_MODE, false },
+ { MAC_LID_LOCAL_CSMA, MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE, false },
+ { MAC_LID_LOCAL_CSMA, MAC_COEXISTENCE_FULL_HYBRID_MODE, true },
+ { MAC_LID_LOCAL_CSMA, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_AV_ONLY_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_FULL_HYBRID_MODE, true },
+ { MAC_LID_DISCOVER, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, true },
+ { MAC_LID_SPC_CENTRAL, MAC_COEXISTENCE_AV_ONLY_MODE, true },
+ { MAC_LID_SPC_CENTRAL, MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE, true },
+ { MAC_LID_SPC_CENTRAL, MAC_COEXISTENCE_FULL_HYBRID_MODE, true },
+ { MAC_LID_SPC_CENTRAL, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, true },
+ // { MAC_LID_CFPI, ? },
+ };
+ for (i = 0; i < COUNT (is_hybrid_tab); i++)
+ {
+ test_fail_unless (
+ CA_ALLOC_IS_HYBRID (is_hybrid_tab[i].coex,
+ is_hybrid_tab[i].lid) ==
+ is_hybrid_tab[i].expect, "is hybrid mismatch i=%d", i);
+ }
+ } test_end;
+*/
+ test_begin (t, "beacon periods")
+ {
+ const int beacon_period_length = MAC_MS_TO_TCK (1000 / 50);
+ ca_beacon_period_t periods[CA_BEACON_PERIOD_NB];
+ uint periods_nb = 0;
+ uint periods_nb_new;
+ uint used;
+ /* Create schedule to satisfy asserts. */
+ for (i = 0; i < CA_SCHEDULE_NB; i++)
+ {
+ ca_schedule_t *sched = ca_alloc_get_schedule (ca, i);
+ sched->coexistence_mode = MAC_COEXISTENCE_AV_ONLY_MODE;
+ sched->snid = 5;
+ sched->nek_switch = 0;
+ sched->allocations_nb = 1;
+ sched->allocations[0].end_offset_tck = beacon_period_length;
+ sched->allocations[0].glid = MAC_LID_SPC_HOLE;
+ }
+ /* Create beacon periods. */
+ for (i = 0; i < NB_ITER; i++)
+ {
+ phy->date = i * beacon_period_length + beacon_period_length / 3;
+ periods_nb_new =
+ lib_rnd_uniform (rnd, CA_BEACON_PERIOD_NB - 2) + 1;
+ for (j = 0; j < periods_nb_new; j++)
+ {
+ /* Change older periods, set new periods. */
+ if (j + 1 >= periods_nb
+ || lib_rnd_flip_coin (rnd, LIB_RND_RATIO (0.3)))
+ {
+ periods[j].start_date = (i + j) * beacon_period_length
+ + lib_rnd_uniform (rnd, beacon_period_length / 100)
+ - beacon_period_length / 200;
+ periods[j].schedule_index =
+ lib_rnd_uniform (rnd, CA_SCHEDULE_NB);
+ }
+ else
+ {
+ periods[j] = periods[j + 1];
+ }
+ }
+ periods_nb = periods_nb_new;
+ /* Update CA periods. */
+ ca_alloc_update_beacon_periods (ca, periods, periods_nb);
+ /* Check the update. */
+ test_fail_unless (periods_nb == ca->beacon_periods_nb);
+ for (j = 0; j < periods_nb; j++)
+ {
+ test_fail_unless ((ca->beacon_periods[j].start_date
+ == periods[j].start_date)
+ && (ca->beacon_periods[j].schedule_index
+ == periods[j].schedule_index));
+ }
+ /* Test get_schedule. */
+ used = 0;
+ for (j = 0; j < periods_nb; j++)
+ {
+ dbg_assert (periods[j].schedule_index < CA_SCHEDULE_NB);
+ used |= 1 << periods[j].schedule_index;
+ }
+ for (j = 0; used; j++, used >>= 1)
+ {
+ bool caught = false;
+ dbg_fatal_try_begin
+ {
+ ca_alloc_get_schedule (ca, j);
+ }
+ dbg_fatal_try_catch_void ()
+ {
+ caught = true;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (((used & 1) && caught)
+ || (!(used & 1) && !caught));
+ }
+ /* Test find_beacon_period. */
+ for (j = 0; j < periods_nb; j++)
+ {
+ test_fail_unless (ca_alloc_find_beacon_period (
+ ca, periods[j].start_date) == &ca->beacon_periods[j]);
+ test_fail_unless (ca_alloc_find_beacon_period (
+ ca, periods[j].start_date + beacon_period_length / 3)
+ == &ca->beacon_periods[j]);
+ }
+ }
+ } test_end;
+ test_begin (t, "alloc find")
+ {
+ ca_schedule_t schedule;
+ uint end;
+ for (i = 0; i < NB_ITER / CA_SCHEDULE_SIZE; i++)
+ {
+ schedule.coexistence_mode = MAC_COEXISTENCE_AV_ONLY_MODE;
+ schedule.snid = 5;
+ schedule.nek_switch = 0;
+ schedule.allocations_nb = lib_rnd_uniform (rnd, CA_SCHEDULE_SIZE);
+ end = 0;
+ for (j = 0; j < schedule.allocations_nb; j++)
+ {
+ end = end + 2 + lib_rnd_uniform (
+ rnd, (1 << 24)
+ - (schedule.allocations_nb - j) * 2
+ - end - 2);
+ schedule.allocations[j].end_offset_tck = end;
+ schedule.allocations[j].glid = 0;
+ }
+ end = 0;
+ for (j = 0; j < schedule.allocations_nb; j++)
+ {
+ test_fail_unless (ca_alloc_find (&schedule, end) == j);
+ test_fail_unless (ca_alloc_find (&schedule, end + 1) == j);
+ end = schedule.allocations[j].end_offset_tck;
+ test_fail_unless (ca_alloc_find (&schedule, end) == j + 1);
+ test_fail_unless (ca_alloc_find (&schedule, end + 1)
+ == j + 1);
+ }
+ }
+ } test_end;
+ /* Uninitialise. */
+ ca_uninit (ca);
+ phy_uninit (phy);
+ mac_store_uninit (store);
+}
+
+/**
+ * Helper function to prepare schedules.
+ * \param ca CA context
+ *
+ * Schedules is described with variable arguments:
+ *
+ * arguments: beacon_period* 0
+ * beacon_period: allocations_nb start_date coexistence_mode snid nek_switch
+ * allocations+
+ * allocations: end_offset_tck glid
+ */
+static void
+alloc_prepare_schedules (ca_t *ca, ...)
+{
+ ca_beacon_period_t periods[CA_BEACON_PERIOD_NB];
+ ca_schedule_t *sched = NULL;
+ uint allocs_nb = 0;
+ uint period_index = 0;
+ uint alloc_index = 0;
+ va_list ap;
+ va_start (ap, ca);
+ do
+ {
+ /* Fetch next allocation number for next beacon period. */
+ if (alloc_index == 0)
+ allocs_nb = va_arg (ap, uint);
+ if (allocs_nb)
+ {
+ /* If first allocation initialise schedule. */
+ if (alloc_index == 0)
+ {
+ periods[period_index].start_date = va_arg (ap, u32);
+ periods[period_index].schedule_index = period_index;
+ sched = ca_alloc_get_schedule (ca, period_index);
+ sched->coexistence_mode = va_arg (ap, uint);
+ sched->snid = va_arg (ap, uint);
+ sched->nek_switch = va_arg (ap, uint);
+ sched->allocations_nb = 0;
+ }
+ /* Set allocation from parameters. */
+ sched->allocations[alloc_index].end_offset_tck =
+ va_arg (ap, uint);
+ sched->allocations[alloc_index].glid = va_arg (ap, uint);
+ sched->allocations_nb++;
+ alloc_index++;
+ /* Next beacon period? */
+ if (alloc_index == allocs_nb)
+ {
+ period_index++;
+ alloc_index = 0;
+ }
+ }
+ } while (allocs_nb);
+ va_end (ap);
+ /* Program CA. */
+ ca_alloc_update_beacon_periods (ca, periods, period_index);
+}
+
+static void
+alloc_prepare_test_case (test_t t)
+{
+ phy_t *phy;
+ mac_config_t config;
+ mac_store_t *store;
+ ca_t *ca;
+ test_case_begin (t, "prepare");
+ /* Initialise. */
+ phy = phy_init (NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ mac_config_init (&config);
+ config.tei = 1;
+ store = mac_store_init ();
+ test_begin (t, "no shrink")
+ {
+ ca = ca_init (phy, &config, store, 0);
+ alloc_prepare_schedules (
+ ca,
+ 1, 0, MAC_COEXISTENCE_AV_ONLY_MODE, 1, 0,
+ 1000000, MAC_GLID_MIN + 10,
+ 1, 1000000, MAC_COEXISTENCE_AV_ONLY_MODE, 1, 0,
+ 1000000, MAC_GLID_MIN + 11,
+ 0);
+ ca_access_activate (ca, 0);
+ ca_alloc_param_t *ap = &ca->current_allocation_param;
+ test_fail_unless (ap->coexistence_mode
+ == MAC_COEXISTENCE_AV_ONLY_MODE);
+ test_fail_unless (ap->snid == 1);
+ test_fail_unless (!ap->hybrid);
+ test_fail_unless (!ap->merge);
+ test_fail_unless (ap->nek_switch == 0);
+ test_fail_unless (ap->end_date == 1000000 - MAC_AIFS_TCK);
+ test_fail_unless (ap->aifs_date == 1000000);
+ test_fail_unless (ap->beacon_period_start_date == 0);
+ test_fail_unless (ap->glid == MAC_GLID_MIN + 10);
+ ca_access_deactivate (ca);
+ ca_uninit (ca);
+ } test_end;
+ test_begin (t, "shrink")
+ {
+ ca = ca_init (phy, &config, store, 0);
+ alloc_prepare_schedules (
+ ca,
+ 1, 0, MAC_COEXISTENCE_AV_ONLY_MODE, 1, 0,
+ 1000000, MAC_GLID_MIN + 10,
+ 1, 900000, MAC_COEXISTENCE_AV_ONLY_MODE, 1, 0,
+ 1000000, MAC_GLID_MIN + 11,
+ 0);
+ ca_access_activate (ca, 0);
+ ca_alloc_param_t *ap = &ca->current_allocation_param;
+ test_fail_unless (ap->coexistence_mode
+ == MAC_COEXISTENCE_AV_ONLY_MODE);
+ test_fail_unless (ap->snid == 1);
+ test_fail_unless (!ap->hybrid);
+ test_fail_unless (!ap->merge);
+ test_fail_unless (ap->nek_switch == 0);
+ test_fail_unless (ap->end_date == 900000 - MAC_AIFS_TCK);
+ test_fail_unless (ap->aifs_date == 900000);
+ test_fail_unless (ap->beacon_period_start_date == 0);
+ test_fail_unless (ap->glid == MAC_GLID_MIN + 10);
+ ca_access_deactivate (ca);
+ ca_uninit (ca);
+ } test_end;
+ test_begin (t, "shrink beacon")
+ {
+ ca = ca_init (phy, &config, store, 0);
+ alloc_prepare_schedules (
+ ca,
+ 1, 0, MAC_COEXISTENCE_AV_ONLY_MODE, 1, 0,
+ 1000000, MAC_GLID_MIN + 10,
+ 1, 900000, MAC_COEXISTENCE_AV_ONLY_MODE, 1, 0,
+ 1000000, MAC_LID_SPC_CENTRAL,
+ 0);
+ ca_access_activate (ca, 0);
+ ca_alloc_param_t *ap = &ca->current_allocation_param;
+ test_fail_unless (ap->coexistence_mode
+ == MAC_COEXISTENCE_AV_ONLY_MODE);
+ test_fail_unless (ap->snid == 1);
+ test_fail_unless (!ap->hybrid);
+ test_fail_unless (!ap->merge);
+ test_fail_unless (ap->nek_switch == 0);
+ test_fail_unless (ap->end_date == 900000 - MAC_B2BIFS_TCK);
+ test_fail_unless (ap->aifs_date == 900000);
+ test_fail_unless (ap->beacon_period_start_date == 0);
+ test_fail_unless (ap->glid == MAC_GLID_MIN + 10);
+ ca_access_deactivate (ca);
+ ca_uninit (ca);
+ } test_end;
+ test_begin (t, "merge")
+ {
+ ca = ca_init (phy, &config, store, 0);
+ alloc_prepare_schedules (
+ ca,
+ 1, 0, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, 1, 0,
+ 1000000, MAC_LID_SHARED_CSMA,
+ 1, 1000000, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, 1, 0,
+ 1000000, MAC_LID_SHARED_CSMA,
+ 0);
+ ca_access_activate (ca, 0);
+ ca_alloc_param_t *ap = &ca->current_allocation_param;
+ test_fail_unless (ap->coexistence_mode
+ == MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE);
+ test_fail_unless (ap->snid == 1);
+ test_fail_unless (ap->merge);
+ test_fail_unless (ap->nek_switch == 0);
+ test_fail_unless (ap->end_date == 1000000 - MAC_AIFS_TCK
+ + CA_ACCESS_MERGE_MARGIN_TCK);
+ test_fail_unless (ap->aifs_date == 1000000);
+ test_fail_unless (ap->beacon_period_start_date == 0);
+ test_fail_unless (ap->glid == MAC_LID_SHARED_CSMA);
+ ca_access_deactivate (ca);
+ ca_uninit (ca);
+ } test_end;
+ test_begin (t, "no merge, not last")
+ {
+ ca = ca_init (phy, &config, store, 0);
+ alloc_prepare_schedules (
+ ca,
+ 2, 0, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, 1, 0,
+ 500000, MAC_LID_SHARED_CSMA,
+ 1000000, MAC_LID_SHARED_CSMA,
+ 1, 1000000, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, 1, 0,
+ 1000000, MAC_LID_SHARED_CSMA,
+ 0);
+ ca_access_activate (ca, 0);
+ ca_alloc_param_t *ap = &ca->current_allocation_param;
+ test_fail_unless (ap->coexistence_mode
+ == MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE);
+ test_fail_unless (ap->snid == 1);
+ test_fail_unless (!ap->merge);
+ test_fail_unless (ap->nek_switch == 0);
+ test_fail_unless (ap->end_date == 500000 - MAC_AIFS_TCK);
+ test_fail_unless (ap->aifs_date == 500000);
+ test_fail_unless (ap->beacon_period_start_date == 0);
+ test_fail_unless (ap->glid == MAC_LID_SHARED_CSMA);
+ ca_access_deactivate (ca);
+ ca_uninit (ca);
+ } test_end;
+ test_begin (t, "no merge, not csma")
+ {
+ ca = ca_init (phy, &config, store, 0);
+ alloc_prepare_schedules (
+ ca,
+ 1, 0, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, 1, 0,
+ 1000000, MAC_LID_SHARED_CSMA,
+ 1, 1000000, MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE, 1, 0,
+ 1000000, MAC_LID_SPC_PROXY,
+ 0);
+ ca_access_activate (ca, 0);
+ ca_alloc_param_t *ap = &ca->current_allocation_param;
+ test_fail_unless (ap->coexistence_mode
+ == MAC_COEXISTENCE_HYBRID_DELIMITERS_MODE);
+ test_fail_unless (ap->snid == 1);
+ test_fail_unless (!ap->merge);
+ test_fail_unless (ap->nek_switch == 0);
+ test_fail_unless (ap->end_date == 1000000 - MAC_AIFS_TCK);
+ test_fail_unless (ap->aifs_date == 1000000);
+ test_fail_unless (ap->beacon_period_start_date == 0);
+ test_fail_unless (ap->glid == MAC_LID_SHARED_CSMA);
+ ca_access_deactivate (ca);
+ ca_uninit (ca);
+ } test_end;
+ /* Uninitialise. */
+ phy_uninit (phy);
+ mac_store_uninit (store);
+}
+
+void
+alloc_test_suite (test_t t)
+{
+ test_suite_begin (t, "alloc");
+ alloc_basic_test_case (t);
+ alloc_prepare_test_case (t);
+}
+
diff --git a/cesar/mac/ca/test/ca_eoc/src/test_ca.c b/cesar/mac/ca/test/ca_eoc/src/test_ca.c
new file mode 100644
index 0000000000..ec9b6724ba
--- /dev/null
+++ b/cesar/mac/ca/test/ca_eoc/src/test_ca.c
@@ -0,0 +1,39 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_ca.c
+ * \brief Test Channel Access.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "lib/trace.h"
+
+void
+backoff_test_suite (test_t t);
+
+void
+alloc_test_suite (test_t t);
+
+void
+access_test_suite (test_t t);
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ trace_init ();
+ test_init (t, argc, argv);
+ backoff_test_suite (t);
+ alloc_test_suite (t);
+ access_test_suite (t);
+ trace_uninit ();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/mac/common/Config b/cesar/mac/common/Config
new file mode 100644
index 0000000000..b50aeca749
--- /dev/null
+++ b/cesar/mac/common/Config
@@ -0,0 +1,5 @@
+CONFIG_ATU_FACTOR = 1
+CONFIG_AV_ONLY_MODE = n
+CONFIG_MAC_COMMON_EOC_MFS = n
+CONFIG_MAC_COMMON_EOC_SCHED = n
+CONFIG_MAC_COMMON_EOC_TONEMASK = n
diff --git a/cesar/mac/common/defs.h b/cesar/mac/common/defs.h
index eb6c79b9a7..c81d01ef56 100644
--- a/cesar/mac/common/defs.h
+++ b/cesar/mac/common/defs.h
@@ -25,6 +25,8 @@
/** Maximum number of physical PHY blocks per MPDU. */
#define MAC_MAX_PB_PER_MPDU 236
+#include "config/mac/pbproc/eoc.h"
+
/** Number of channel access priority. */
#define MAC_CAP_NB 4
@@ -79,29 +81,53 @@ enum mac_lid_t
/** Test if a LID is a beacon LID (vendor specific LID).
* \warning This is a macro, the argument may be evaluated several time. */
-#define MAC_LID_IS_BEACON(lid) ((lid) >= MAC_LID_BEACON_MIN \
- && (lid) <= MAC_LID_BEACON_MAX)
+#if CONFIG_MAC_PBPROC_EOC_FC
+#define MAC_LID_IS_BEACON(lid) ((lid) == MAC_LID_SPC_CENTRAL)
+#else
+#define MAC_LID_IS_BEACON(lid)\
+ ((lid) >= MAC_LID_BEACON_MIN && (lid) <= MAC_LID_BEACON_MAX)
+#endif
/** Terminal Equipment Identifier. */
enum mac_tei_t
{
MAC_TEI_UNASSOCIATED = 0,
- MAC_TEI_STA_MIN = 1,
- MAC_TEI_STA_MAX = 0xfe,
- MAC_TEI_STA_NB = MAC_TEI_STA_MAX - MAC_TEI_STA_MIN + 1,
MAC_TEI_BCAST = 0xff,
/** Used to request unicast transmission to all stations in the AVLN. */
MAC_TEI_MULTI_UNICAST = 0x100,
/** Used for peers not present on the medium (HLE driver or other bridged
* address). */
MAC_TEI_FOREIGN = 0x200,
+ MAC_TEI_STA_MIN = 1,
+#if CONFIG_MAC_PBPROC_EOC_FC
+ MAC_TEI_CCO_MIN = 1,
+ MAC_TEI_CCO_MAX = 2,
+ MAC_TEI_CCO_DEF = MAC_TEI_CCO_MIN,
+ MAC_TEI_STA_MIN_EOC = MAC_TEI_CCO_MAX + 1,
+ MAC_TEI_STA_NB = 128,
+ MAC_TEI_STA_MAX = 0xfe,
+ MAC_TEI_MCAST_MAX = MAC_TEI_BCAST - 1,
+ MAC_TEI_MCAST_NB = 5,
+ MAC_TEI_MCAST_MIN = MAC_TEI_MCAST_MAX - MAC_TEI_MCAST_NB + 1,
+#else
+ MAC_TEI_STA_MAX = 0xfe,
+ MAC_TEI_STA_NB = MAC_TEI_STA_MAX - MAC_TEI_STA_MIN + 1,
+#endif
};
/** Test if a TEI is between STA_MIN and STA_MAX.
* \warning This is a macro, the argument may be evaluated several time. */
+#if CONFIG_MAC_PBPROC_EOC_FC
+#define MAC_TEI_IS_EOC_CCO(tei) \
+ ((tei) >= MAC_TEI_CCO_MIN && (tei) <= MAC_TEI_CCO_MAX)
+#define MAC_TEI_IS_EOC_STA(tei) \
+ ((tei) >= MAC_TEI_STA_MIN_EOC && (tei) <= MAC_TEI_STA_MAX)
+#define MAC_TEI_IS_STA(tei) \
+ ((tei) >= MAC_TEI_CCO_MIN && (tei) <= MAC_TEI_MCAST_MAX)
+#else
#define MAC_TEI_IS_STA(tei) \
((tei) >= MAC_TEI_STA_MIN && (tei) <= MAC_TEI_STA_MAX)
-
+#endif
/** Coexistence modes.
* \warning Full Hybrid mode is also used in CSMA-Only with HomePlug 1.0
* compatible frame length. This maps directly to beacon HM field. */
@@ -119,9 +145,14 @@ typedef enum mac_coexistence_mode_t mac_coexistence_mode_t;
enum mac_eks_t
{
MAC_EKS_MIN = 0,
+#if CONFIG_MAC_PBPROC_EOC_FC
+ MAC_EKS_CLEAR = 0x3,
+ MAC_EKS_MAX = 2,
+#else
+ MAC_EKS_CLEAR = 0xf,
MAC_EKS_MAX = 7,
+#endif
MAC_EKS_NB = MAC_EKS_MAX - MAC_EKS_MIN + 1,
- MAC_EKS_CLEAR = 0xf,
};
typedef enum mac_eks_t mac_eks_t;
diff --git a/cesar/mac/common/mfs.h b/cesar/mac/common/mfs.h
index cb401df18c..d97f2109da 100644
--- a/cesar/mac/common/mfs.h
+++ b/cesar/mac/common/mfs.h
@@ -18,6 +18,8 @@
#include "lib/list.h"
#include "mac/common/link_stats.h"
+#include "config/mac/common.h"
+
/** Default encoded RX window size for data (corresponding to 16). */
#define MFS_RX_WINDOW_SIZE_DATA_DEFAULT_ENCODED 0x2
/** Delay during the one the MFS is still active. */
@@ -25,9 +27,14 @@
/** Release timeout. */
#define MFS_RELEASE_DELAY_MS 1000
/** Delay TX PBs have to pass through MAC layer. */
-#define MFS_PB_TX_DELAY_MS 100
+#define MFS_PB_TX_DELAY_MS 500
/** Delay RX PBs have to pass through MAC layer. */
-#define MFS_PB_RX_DELAY_MS 100
+#define MFS_PB_RX_DELAY_MS 500
+
+/** Limit on number of segment numbers per one TX MFS. */
+#if CONFIG_MAC_COMMON_EOC_MFS
+#define MFS_TX_MAX_SEG_NB 1200
+#endif
/** MFS FSM commands. WARNING: should match AV spec. */
enum mfs_fsm_cmd_t
@@ -193,6 +200,10 @@ struct mfs_tx_t
bool beacon;
/** link stats */
link_stats_tx_t stats;
+#if CONFIG_MAC_COMMON_EOC_MFS
+ /** Count number of consecutive frames without reply*/
+ u8 no_reply_count;
+#endif
};
typedef struct mfs_tx_t mfs_tx_t;
@@ -290,6 +301,8 @@ mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei);
void
mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei);
+#define MFS_WINDOW_TOLERANCE 8
+
END_DECLS
#endif /* mac_common_mfs_h */
diff --git a/cesar/mac/common/src/mfs.c b/cesar/mac/common/src/mfs.c
index 5dacab71ad..a16a10994c 100644
--- a/cesar/mac/common/src/mfs.c
+++ b/cesar/mac/common/src/mfs.c
@@ -23,7 +23,8 @@
#define MFS_WINDOW_SIZE_DATA_RX MFS_WINDOW_SIZE_256
/** Default TX MFS DATA window size (actual value is fixed by the receiver). */
-#define MFS_DEFAULT_WINDOW_SIZE_DATA_TX MFS_WINDOW_SIZE_16
+#define MFS_DEFAULT_WINDOW_SIZE_DATA_TX CONFIG_MAC_COMMON_EOC_MFS ? \
+ MFS_WINDOW_SIZE_256 : MFS_WINDOW_SIZE_16
/** Window size values table (values of the RxWSz field of the FCs in which
* it is included). */
@@ -45,6 +46,12 @@ mfs_common_init (mfs_common_t *mfs_common, bool tx, bool bcast, bool mme, uint
list_init_node (&mfs_common->store_unassociated_link);
/* mfs_common->expiration_ntb */
if (tx)
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (mfs_common->mme)
+ mfs_common->expiration_delay_tck =
+ MAC_MS_TO_TCK (MFS_PB_TX_DELAY_MS << 1);
+ else
+#endif
mfs_common->expiration_delay_tck =
MAC_MS_TO_TCK (MFS_PB_TX_DELAY_MS);
else
@@ -88,6 +95,10 @@ mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
|| (!bcast && mme && tei == MAC_TEI_UNASSOCIATED));
mfs_common_init (&mfs->common, true, bcast, mme, lid, tei);
mfs->cfp = false;
+ if (CONFIG_MAC_COMMON_EOC_MFS && (tei != MAC_TEI_UNASSOCIATED))
+ {
+ mfs->cfp = true;
+ }
mfs->burst_count = 0;
list_init_node (&mfs->ca_link);
mfs->ca_state = CA_MFS_STATE_UNKNOWN;
@@ -106,17 +117,22 @@ mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
mfs->last_seg_offset = 0;
mfs->next_ssn = 0;
mfs->beacon = false;
+#if CONFIG_MAC_COMMON_EOC_MFS
+ mfs->no_reply_count = 0;
+ mfs->cap = 0;
+#endif
link_stats_tx_reset (&mfs->stats);
}
void
-mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid,
- uint tei)
+mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
{
dbg_assert (mfs);
mfs_tx_init (mfs, bcast, mme, lid, tei);
mfs->common.unassociated = true;
mfs->fsm_state = MFS_FSM_CMD_NOP;
+ if (CONFIG_MAC_COMMON_EOC_MFS)
+ mfs->cfp = false;
}
diff --git a/cesar/mac/common/src/sta.c b/cesar/mac/common/src/sta.c
index 817a45edfb..971d385ca2 100644
--- a/cesar/mac/common/src/sta.c
+++ b/cesar/mac/common/src/sta.c
@@ -33,6 +33,12 @@ sta_init (sta_t *sta, uint tei)
ce_rx_bitloading_init (&sta->ce_rx_bt);
sta->tx_data_rate.data_rate = CL_DATA_RATE_REQ_INIT;
sta->rx_data_rate.data_rate = CL_DATA_RATE_REQ_INIT;
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ /** Should STA be regularly polled */
+ sta->tdma_poll = true;
+ sta->poll_off = 0;
+ sta->upstream_att = 0;
+#endif
sta->intervals = NULL;
}
diff --git a/cesar/mac/common/src/store.c b/cesar/mac/common/src/store.c
index f74cfaef83..a02def04d6 100644
--- a/cesar/mac/common/src/store.c
+++ b/cesar/mac/common/src/store.c
@@ -10,6 +10,7 @@
* \brief MFS and STA store, store pointers to MFS and STA information.
* \ingroup mac_common
*/
+#include "config.h"
#include "common/std.h"
#include "mac/common/store.h"
@@ -17,6 +18,8 @@
#include "mac/common/defs.h"
#include "lib/blk.h"
+#include "config/mac/common.h"
+
/** Define index into MFS tables tables. */
enum mac_store_kind_t
{
@@ -43,6 +46,10 @@ struct mac_store_sta_t
/** LLID MFS for RX from this STA. Only allocated when really needed, the
* first four pointers are not used. */
mfs_t **rx_llid;
+#if CONFIG_MAC_COMMON_EOC_MFS
+ /** LLID MFS for tx to this station in EoC mode */
+ mfs_t **tx_llid;
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
};
typedef struct mac_store_sta_t mac_store_sta_t;
@@ -124,6 +131,9 @@ mac_store_mfs_slot_get (mac_store_t *ctx, bool tx, bool bcast, bool mme,
|| MAC_LID_IS_BEACON (lid)) && tei == 0)
|| (bcast && tx && tei == MAC_TEI_BCAST)
|| (!(bcast && tx) && MAC_TEI_IS_STA (tei)));
+ dbg_blame (!CONFIG_MAC_COMMON_EOC_MFS
+ || !bcast || MAC_LID_IS_PLID (lid)
+ || MAC_LID_IS_BEACON (lid) || (mme && (lid == MAC_LID_NONE)));
if (!mme && (lid >= MAC_GLID_MIN))
{
/* GLID table contains TX and RX MFS, check it is the requested
@@ -136,7 +146,7 @@ mac_store_mfs_slot_get (mac_store_t *ctx, bool tx, bool bcast, bool mme,
else
return &ctx->lglid[lid];
}
- else if (!mme && (tx && lid >= MAC_LLID_MIN))
+ else if (!mme && (tx && lid >= MAC_LLID_MIN) && !CONFIG_MAC_COMMON_EOC_MFS)
return &ctx->lglid[lid];
else if (tx && bcast && !mme && MAC_LID_IS_PLID (lid))
return &ctx->bcast_tx_plid[lid];
@@ -154,20 +164,40 @@ mac_store_mfs_slot_get (mac_store_t *ctx, bool tx, bool bcast, bool mme,
{
if (!mme && lid >= MAC_LLID_MIN)
{
- dbg_blame (!tx && lid <= MAC_LLID_MAX);
- if (!sta->rx_llid)
+ dbg_blame ((!tx || CONFIG_MAC_COMMON_EOC_MFS) && lid <= MAC_LLID_MAX);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (tx)
{
- if (add)
+ if (!sta->tx_llid)
{
- /* Allocate a new table. */
- sta->rx_llid = blk_alloc_zero_ (_fl);
- return &sta->rx_llid[lid];
+ if (add)
+ {
+ sta->tx_llid = blk_alloc_zero_ (_fl);
+ return &sta->tx_llid[lid];
+ }
+ else
+ return NULL;
}
else
- return NULL;
+ return &sta->tx_llid[lid];
}
else
- return &sta->rx_llid[lid];
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
+ {
+ if (!sta->rx_llid)
+ {
+ if (add)
+ {
+ /* Allocate a new table. */
+ sta->rx_llid = blk_alloc_zero_ (_fl);
+ return &sta->rx_llid[lid];
+ }
+ else
+ return NULL;
+ }
+ else
+ return &sta->rx_llid[lid];
+ }
}
else
{
@@ -185,6 +215,61 @@ mac_store_mfs_slot_get (mac_store_t *ctx, bool tx, bool bcast, bool mme,
}
}
+#if CONFIG_MAC_COMMON_EOC_MFS
+mfs_tx_t * ARCH_ILRAM
+mac_store_mfs_get_sta_tx_data_ (mac_store_t *ctx, uint lid, uint tei __FL)
+{
+ dbg_claim (ctx);
+ mfs_tx_t *mfs = NULL;
+ mac_store_sta_t *sta = ctx->sta[tei];
+ if (sta && sta->sta.tdma_poll)
+ {
+ dbg_claim (lid >= MAC_LLID_MIN);
+ dbg_claim (lid <= MAC_LLID_MAX);
+ mfs = (mfs_tx_t *)sta->tx_llid[lid];
+ }
+ return mfs;
+}
+
+mfs_tx_t * ARCH_ILRAM
+mac_store_mfs_get_sta_tx_ (mac_store_t *ctx, uint lid, uint tei __FL)
+{
+ mfs_tx_t *mfs = NULL;
+ dbg_claim (ctx);
+ mfs_tx_t * mfs1 = (mfs_tx_t *)(ctx->bcast_tx_mme);
+ /* bcast mme has highest priority */
+ if (mfs1 && mfs1->seg_nb > 0)
+ return mfs1;
+ switch(tei)
+ {
+ case MAC_TEI_BCAST:
+ mfs = (mfs_tx_t *)(ctx->bcast_tx_plid[lid]);
+ if (mfs && mfs->seg_nb <= 0)
+ mfs = NULL;
+ break;
+ default:
+ {
+ mac_store_sta_t *sta = ctx->sta[tei];
+ if (sta && sta->sta.tdma_poll)
+ {
+ mfs_tx_t * mfs1 = (mfs_tx_t *)sta->mme[MAC_STORE_KIND_TX];
+ if (!mfs1 || mfs1->seg_nb <= 0)
+ {
+ dbg_claim (MAC_LID_IS_LLID (lid));
+ mfs = (mfs_tx_t *)sta->tx_llid[lid];
+ if (!mfs)
+ mfs = mfs1;
+ }
+ else
+ mfs = mfs1;
+ }
+ break;
+ }
+ }
+ return mfs;
+}
+#endif
+
mfs_t *
mac_store_mfs_get_ (mac_store_t *ctx, bool tx, bool bcast, bool mme, uint lid,
uint tei __FL)
@@ -435,30 +520,52 @@ mac_store_mfs_travel_by_tei (mac_store_t *ctx, uint tei,
mac_store_mfs_travel_mfs_and_unlock (ctx, sta->rx_llid[i],
travel, user);
}
+
+#if CONFIG_MAC_COMMON_EOC_MFS
+ for (i = MAC_LLID_MIN; i <= MAC_LLID_MAX; i++)
+ {
+ arch_dsr_lock ();
+ /* Do this test at each loop step as the scheduler is unlocked
+ * between each step. */
+ if (!sta->tx_llid)
+ {
+ arch_dsr_unlock ();
+ break;
+ }
+ mac_store_mfs_travel_mfs_and_unlock (ctx, sta->tx_llid[i],
+ travel, user);
+ }
+#endif
blk_release (sta);
}
}
-sta_t *
+sta_t * ARCH_ILRAM
mac_store_sta_get_ (mac_store_t *ctx, uint tei __FL)
{
- dbg_assert (ctx);
+ dbg_claim (ctx);
dbg_blame (MAC_TEI_IS_STA (tei));
arch_dsr_lock ();
mac_store_sta_t *sta = ctx->sta[tei];
+ sta_t * sta_sta = NULL;
if (sta)
{
blk_addref_ (sta __fl);
- arch_dsr_unlock ();
- return &sta->sta;
- }
- else
- {
- arch_dsr_unlock ();
- return NULL;
+ sta_sta = &sta->sta;
}
+ arch_dsr_unlock ();
+ return sta_sta;
}
+#if CONFIG_MAC_COMMON_EOC_MFS
+sta_t * ARCH_ILRAM
+mac_store_sta_get_noref_ (mac_store_t *ctx, uint tei __FL)
+{
+ mac_store_sta_t *sta = ctx->sta[tei];
+ return sta ? &sta->sta : NULL;
+}
+#endif
+
void
mac_store_sta_add_ (mac_store_t *ctx, uint tei __FL)
{
@@ -484,6 +591,15 @@ mac_store_sta_add_ (mac_store_t *ctx, uint tei __FL)
sta->mme[i] = NULL;
}
sta->rx_llid = NULL;
+#if CONFIG_MAC_COMMON_EOC_MFS
+ sta->tx_llid = NULL;
+ /* add here to prevent additional checks */
+ sta->tx_llid = blk_alloc_zero_ (_fl);
+ sta->rx_llid = blk_alloc_zero_ (_fl);
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ sta->sta.tdma_poll = true;
+#endif
/* Done, ready to be used (order is important). */
arch_reorder_barrier ();
ctx->sta[tei] = sta;
@@ -519,6 +635,14 @@ mac_store_sta_remove_ (mac_store_t *ctx, uint tei __FL)
if (sta->rx_llid[i])
ok = false;
}
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (ok && sta->tx_llid)
+ {
+ for (i = 0; ok && i < MAC_LLID_MAX; i++)
+ if (sta->tx_llid[i])
+ ok = false;
+ }
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
if (ok)
{
/* Can no longer be accessed by interrupts, order is important. */
@@ -529,6 +653,10 @@ mac_store_sta_remove_ (mac_store_t *ctx, uint tei __FL)
* store and it does not care about rx_llid. */
if (sta->rx_llid)
blk_release_ (sta->rx_llid __fl);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (sta->tx_llid)
+ blk_release_ (sta->tx_llid __fl);
+#endif /* CONFIG_MAC_COMMON_EOC_MFS */
/* Release the STA information. */
blk_release_ (sta __fl);
}
diff --git a/cesar/mac/common/src/tonemap.c b/cesar/mac/common/src/tonemap.c
index 0cde1fdbd3..c6e9afa19b 100644
--- a/cesar/mac/common/src/tonemap.c
+++ b/cesar/mac/common/src/tonemap.c
@@ -61,7 +61,6 @@ tonemaps_init (tonemaps_t *tms)
/* Check parameter. */
dbg_assert (tms);
- tms->sound_frame_counter = TONEMAP_SOUND_FRAME_COUNTER;
u8 i;
for (i = 0; i < TONEMAP_INDEX_NB; i++)
tms->tm[i] = NULL;
@@ -458,6 +457,8 @@ tonemaps_alloc ()
tonemaps_t *tms = (tonemaps_t *) blk_alloc_zero ();
/* Set default values. */
tms->default_tmi = TONEMAP_INDEX_INITIAL_START;
+ /* This need to be done only when allocating tonemaps (see #1595). */
+ tms->sound_frame_counter = TONEMAP_SOUND_FRAME_COUNTER;
tonemaps_init (tms);
return tms;
}
diff --git a/cesar/mac/common/src/tonemask.c b/cesar/mac/common/src/tonemask.c
index 0a47a6979b..4652148eb3 100644
--- a/cesar/mac/common/src/tonemask.c
+++ b/cesar/mac/common/src/tonemask.c
@@ -11,9 +11,11 @@
* \ingroup mac_common
*/
#include "common/std.h"
+#include <stdio.h>
#include "tonemask.h"
#include "timings.h"
+#include "config/mac/common/eoc/tonemask.h"
uint
tonemask_carrier_nb (const u32 *tonemask)
@@ -98,6 +100,7 @@ tonemask_update (tonemask_info_t *ti)
uint
tonemask_default (u32 *tonemask)
{
+#if (!CONFIG_MAC_COMMON_EOC_TONEMASK)
/** HomePlug AV default tone mask carriers. */
static const uint carriers[] =
{
@@ -125,11 +128,26 @@ tonemask_default (u32 *tonemask)
};
/** HomePlug AV default tone mask carriers number. */
static const uint carriers_nb = 917;
+#else
+ /** EoC default tone mask carriers. */
+ static const uint carriers[] =
+ {
+ /* 0-73 are OFF */
+ PHY_LAST_EOC_CARRIER_NB, /* 74-1439 are ON */
+ 1535, /* 1440-1535 are OFF */
+ };
+ /** EoC default tone mask carriers number. */
+ static const uint carriers_nb = PHY_LAST_EOC_CARRIER_NB-PHY_CARRIER_OFFSET+1;
+#endif
uint i, j;
uint dtc_idx = 0;
dbg_assert (carriers[0] > PHY_CARRIER_OFFSET);
uint dtc_stop = carriers[dtc_idx] - PHY_CARRIER_OFFSET;
+#if (!CONFIG_MAC_COMMON_EOC_TONEMASK)
bool dtc_on = false;
+#else
+ bool dtc_on = true;
+#endif
dbg_assert_ptr (tonemask);
/* Slow loop, but only done at boot time. */
for (i = 0; i < PHY_TONEMASK_WORDS; i++)
diff --git a/cesar/mac/common/sta.h b/cesar/mac/common/sta.h
index 37134f65c5..fff549f973 100644
--- a/cesar/mac/common/sta.h
+++ b/cesar/mac/common/sta.h
@@ -19,6 +19,8 @@
#include "ce/rx/bitloading/bitloading.h"
#include "ce/rx/bitloading/intervals.h"
+#include "config/mac/common.h"
+
/** Station information. Must be < BLK_SIZE. */
struct sta_t
{
@@ -42,6 +44,20 @@ struct sta_t
cl_data_rate_t tx_data_rate;
/** Data rate for receive from this station to the local one. */
cl_data_rate_t rx_data_rate;
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ /** Should STA be regularly polled. */
+ bool tdma_poll;
+ /** Next time station should be polled. */
+ u32 poll_time;
+ /** Number of concesutive polls with no data exchange. */
+ u8 empty_poll;
+ /** STA is not replying. */
+ u8 poll_off;
+ /** Number of pending PB's for this sta */
+ uint ppb;
+ /** Upstream attenuation. */
+ uint upstream_att;
+#endif
};
typedef struct sta_t sta_t;
diff --git a/cesar/mac/common/store.h b/cesar/mac/common/store.h
index 446795d544..184922b5e5 100644
--- a/cesar/mac/common/store.h
+++ b/cesar/mac/common/store.h
@@ -339,6 +339,63 @@ mac_store_get_free_tx_llid (mac_store_t *ctx);
int
mac_store_get_free_tei (mac_store_t *ctx);
+#if CONFIG_MAC_COMMON_EOC_MFS
+/**
+ * Return a MFS (data + bcast).
+ * \param ctx store context
+ * \param lid Link identifier
+ * \param tei tei of station polled
+ * \return a MFS or NULL
+ * \context CA (DSR)
+ *
+ * This call is useful for the CA.
+ *
+ * Return MFS for given tei,lid pair. Reduced number of parameters.
+ * If bcast mme could be sent it has priority.
+ */
+mfs_tx_t *
+mac_store_mfs_get_sta_tx_ (mac_store_t *ctx, uint lid, uint tei __FL);
+#define mac_store_mfs_get_sta_tx(args...)\
+mac_store_mfs_get_sta_tx_ (args __fL)
+
+/**
+ * Return a MFS (data only).
+ * \param ctx store context
+ * \param lid Link identifier
+ * \param tei tei of station polled
+ * \return a MFS or NULL
+ * \context CA (DSR)
+ *
+ * This call is useful for the CA.
+ *
+ * Return MFS for given tei,lid pair. Reduced number of parameters.
+ * This call is bound to data TX MFS-s only.
+ */
+mfs_tx_t *
+mac_store_mfs_get_sta_tx_data_ (mac_store_t *ctx, uint lid, uint tei __FL);
+#define mac_store_mfs_get_sta_tx_data(args...)\
+ mac_store_mfs_get_sta_tx_data_ (args __fL)
+
+/**
+ * Return a pointer to station.
+ * \param ctx store context
+ * \param tei station identifier
+ * \return a sta_t * or NULL
+ * \context CA/PBProc/SAR (DSR)
+ *
+ * This call is useful for the CA/PBProc/SAR.
+ *
+ * Return sta for given tei .
+ * Call is without additional reference call. Time is saved.
+ * Be carefull. Call only in protected section of code.
+ * CAUTION: Not thread safe.
+ */
+sta_t *
+mac_store_sta_get_noref_ (mac_store_t *ctx, uint tei __FL);
+#define mac_store_sta_get_noref(args...)\
+ mac_store_sta_get_noref_ (args __fL)
+#endif
+
END_DECLS
#endif /* mac_common_store_h */
diff --git a/cesar/mac/common/test/store/Config b/cesar/mac/common/test/store/Config
index ad48be57b6..3d154e4594 100644
--- a/cesar/mac/common/test/store/Config
+++ b/cesar/mac/common/test/store/Config
@@ -1 +1,4 @@
CONFIG_BLK_NB = 16384
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_SCHED = y \ No newline at end of file
diff --git a/cesar/mac/common/test/store/override/mac/common/mfs.h b/cesar/mac/common/test/store/override/mac/common/mfs.h
index 576f9d6e0c..7ad47012a8 100644
--- a/cesar/mac/common/test/store/override/mac/common/mfs.h
+++ b/cesar/mac/common/test/store/override/mac/common/mfs.h
@@ -37,6 +37,7 @@ typedef struct mfs_rx_t mfs_rx_t;
struct mfs_tx_t
{
mfs_common_t common;
+ int seg_nb;
};
typedef struct mfs_tx_t mfs_tx_t;
diff --git a/cesar/mac/common/test/store/override/mac/common/sta.h b/cesar/mac/common/test/store/override/mac/common/sta.h
index 90fd84983e..56592c3967 100644
--- a/cesar/mac/common/test/store/override/mac/common/sta.h
+++ b/cesar/mac/common/test/store/override/mac/common/sta.h
@@ -17,6 +17,7 @@
struct sta_t
{
uint tei;
+ uint tdma_poll;
u8 *dyn;
};
typedef struct sta_t sta_t;
diff --git a/cesar/mac/common/test/store/src/test_store.c b/cesar/mac/common/test/store/src/test_store.c
index e375710a39..20b19280a6 100644
--- a/cesar/mac/common/test/store/src/test_store.c
+++ b/cesar/mac/common/test/store/src/test_store.c
@@ -10,6 +10,7 @@
* \brief Test MAC store.
* \ingroup test
*/
+#include "config.h"
#include "common/std.h"
#include "mac/common/store.h"
#include "mac/common/mfs.h"
@@ -80,14 +81,15 @@ add_rnd_mfs (test_store_t *ctx, test_t t)
tx = lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.5));
bcast = lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.2));
mme = lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.1));
- lid = mme ? MAC_LID_NONE : lib_rnd_uniform (ctx->rnd, MAC_LID_NB + 2);
+ lid = mme ? MAC_LID_NONE : lib_rnd_uniform (ctx->rnd,
+ bcast ? MAC_PLID_NB : MAC_LID_NB + 2);
unassoc = lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.005));
- if (lid >= MAC_LID_NB && !unassoc)
+ if (!mme && lid >= MAC_LID_NB && !unassoc)
{
tx = true;
bcast = true;
- mme = false;
- lid = lid == MAC_LID_NB ? MAC_LID_DISCOVER : MAC_LID_SPC_CENTRAL;
+ lid = lid == MAC_LID_NB && !CONFIG_MAC_COMMON_EOC_MFS
+ ? MAC_LID_DISCOVER : MAC_LID_SPC_CENTRAL;
}
lid_alias = MAC_LID_IS_GLID (lid) && !unassoc
? lib_rnd_uniform (ctx->rnd, MAC_LLID_NB) + MAC_LLID_MIN
@@ -100,9 +102,9 @@ add_rnd_mfs (test_store_t *ctx, test_t t)
&& *used_mfs (ctx, tx, bcast, mme, lid_alias, tei)));
uint addlid = lid_alias == MAC_LID_NONE ? lid : lid_alias;
/* The STA will be automatically added if needed. */
+ /* CAUSION: In EoC LLID needs station! */
if (MAC_TEI_IS_STA (tei) && !ctx->used_tei[tei]
- && !(unassoc || (tx && bcast) || (tx && MAC_LID_IS_LLID (addlid))
- || MAC_LID_IS_GLID (addlid)))
+ && !(unassoc || (tx && bcast) || MAC_LID_IS_GLID (addlid)))
{
ctx->used_tei[tei] = true;
ctx->used_tei_nb++;
@@ -118,6 +120,7 @@ add_rnd_mfs (test_store_t *ctx, test_t t)
&added);
test_fail_unless (added);
test_fail_unless (m);
+ ((mfs_tx_t *)m)->seg_nb = lib_rnd_uniform (ctx->rnd, 10);
blk_release (m);
m = mac_store_mfs_add (ctx->store, tx, bcast, mme, addlid, tei,
&added);
@@ -167,6 +170,74 @@ add_rnd_mfs (test_store_t *ctx, test_t t)
}
void
+check_random_mfs (test_store_t *ctx, test_t t)
+{
+ test_within (t);
+ uint lid, tei, bcast;
+ bcast = lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.05));
+ if (bcast)
+ {
+ lid = lib_rnd_uniform (ctx->rnd, MAC_PLID_NB) + MAC_PLID_MIN;
+ tei = MAC_TEI_BCAST;
+ }
+ else
+ {
+ int try_nb = 0;
+ bool ok = false;
+ while ((try_nb++ < 5) && ctx->used_mfs_nb)
+ {
+ int pos = lib_rnd_uniform (ctx->rnd, ctx->used_mfs_nb);
+ mfs_t * m2 = ctx->used_mfs [pos];
+ /* find the mfs */
+ if (m2 && !m2->common.bcast
+ && (m2->common.mme || MAC_LID_IS_LLID (m2->common.lid))
+ && !m2->common.unassociated)
+ {
+ tei = m2->common.tei;
+ lid = m2->common.mme ? MAC_LLID_MIN : m2->common.lid;
+ ok = true;
+ break;
+ }
+ }
+ if (!ok)
+ return;
+ }
+ /* retrieve mfs-s */
+ mfs_tx_t *m_bcast = (mfs_tx_t *)mac_store_mfs_get (ctx->store, true, true, true,
+ MAC_LID_NONE, MAC_TEI_BCAST);
+ mfs_tx_t *m_mme = (mfs_tx_t *)mac_store_mfs_get (ctx->store, true, bcast, true,
+ MAC_LID_NONE, tei);
+ mfs_tx_t *m = mac_store_mfs_get_sta_tx (ctx->store, lid, tei);
+ /* check order */
+ if (m_bcast && m_bcast->seg_nb)
+ test_fail_unless (m_bcast == m);
+ else if (m_mme && m_mme->seg_nb)
+ test_fail_unless (m_mme == m);
+ if (tei == MAC_TEI_BCAST)
+ {
+ /* if broadcast mfs is polled it must contain segments */
+ if (m)
+ {
+ test_fail_unless (m->common.bcast);
+ test_fail_unless (m->seg_nb);
+ }
+ else
+ {
+ mfs_tx_t *m_b = (mfs_tx_t *)mac_store_mfs_get (ctx->store, true,
+ true, false, lid, tei);
+ test_fail_unless (!m_b || m_b->seg_nb == 0);
+ if (m_b)
+ blk_release (m_b);
+ }
+ }
+ if (m_bcast) blk_release (m_bcast);
+ if (m_mme) blk_release (m_mme);
+ /* erase segments */
+ if (m)
+ m->seg_nb = 0;
+}
+
+void
remove_mfs (test_store_t *ctx, test_t t, int mfs_index)
{
test_within (t);
@@ -337,9 +408,13 @@ store_basic_test_case (test_t t)
}
}
}
+ /* check retrieve of mfs related to tei (MAC_LLID) */
+ check_random_mfs (ctx, t);
+ /* LLID is always related to station in EoC
uint free_llid = mac_store_get_free_tx_llid (ctx->store);
test_fail_unless (ctx->used_mfs_set[true][false][false]
[free_llid][0] == false);
+ */
uint free_tei = mac_store_get_free_tei (ctx->store);
test_fail_unless (ctx->used_tei[free_tei] == false);
}
diff --git a/cesar/mac/common/test/tonemap/Config b/cesar/mac/common/test/tonemap/Config
new file mode 100644
index 0000000000..59b91c0839
--- /dev/null
+++ b/cesar/mac/common/test/tonemap/Config
@@ -0,0 +1 @@
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
diff --git a/cesar/mac/common/test/tonemap/src/test_tonemap.c b/cesar/mac/common/test/tonemap/src/test_tonemap.c
index b85652fba9..7cfd2d2a6a 100644
--- a/cesar/mac/common/test/tonemap/src/test_tonemap.c
+++ b/cesar/mac/common/test/tonemap/src/test_tonemap.c
@@ -19,6 +19,7 @@
#include "mac/common/tonemask.h"
#include "mac/common/timings.h"
#include "ce/common/mod.h"
+#include "config/mac/common/eoc/tonemask.h"
void
tonemap_access_test (test_t t)
@@ -392,9 +393,14 @@ tonemap_tonemask_test_case (test_t t)
test_begin (t, "default")
{
carrier_nb = tonemask_default (ti.tonemask);
+#if (!CONFIG_MAC_COMMON_EOC_TONEMASK)
test_fail_unless (carrier_nb == 917);
+#else
+ test_fail_unless (carrier_nb == 1366);
+#endif
#define __(n) \
((ti.tonemask[((n) - 74) / 32] >> ((((n) - 74) % 32) / 8 * 8)) & 0xff)
+#if (!CONFIG_MAC_COMMON_EOC_TONEMASK)
test_fail_unless (__ (74) == 0xff); /* 74 */
test_fail_unless (__ (85) == 0x0f); /* 85 */
test_fail_unless (__ (419) == 0x03); /* 419 */
@@ -403,6 +409,16 @@ tonemap_tonemask_test_case (test_t t)
test_fail_unless (__ (1143) == 0xc0); /* 1143 */
test_fail_unless (__ (1144) == 0xc0); /* 1144 */
test_fail_unless (__ (1229) == 0xff); /* 1229 */
+#else
+ test_fail_unless (__ (74) == 0x00); /* 74 */
+ test_fail_unless (__ (85) == 0x00); /* 85 */
+ test_fail_unless (__ (419) == 0x00); /* 419 */
+ test_fail_unless (__ (569) == 0x00); /* 569 */
+ test_fail_unless (__ (856) == 0x00); /* 856 */
+ test_fail_unless (__ (1143) == 0x00); /* 1143 */
+ test_fail_unless (__ (1144) == 0x00); /* 1144 */
+ test_fail_unless (__ (1450) == 0xff); /* 1229 */
+#endif
#undef __
} test_end;
test_begin (t, "carrier nb")
diff --git a/cesar/mac/common/timings.h b/cesar/mac/common/timings.h
index 09b9efb447..6517609719 100644
--- a/cesar/mac/common/timings.h
+++ b/cesar/mac/common/timings.h
@@ -13,6 +13,8 @@
* \ingroup mac_common
*/
+#include "config/atu/factor.h"
+
/** Number of ticks per microsecond. */
#define MAC_TCK_PER_US 25
@@ -32,9 +34,9 @@
#define MAC_TCK_TO_US(tck) ((tck) / MAC_TCK_PER_US)
/** Convert ticks to allocation time unit.
* \warning returned value rounded up. */
-#define MAC_TCK_TO_ATU(tck) CEIL_DIV ((tck), 256)
+#define MAC_TCK_TO_ATU(tck) CEIL_DIV ((tck), (256 * CONFIG_ATU_FACTOR))
/** Convert allocation time unit to ticks. */
-#define MAC_ATU_TO_TCK(atu) ((atu) * 256)
+#define MAC_ATU_TO_TCK(atu) ((atu) * 256 * CONFIG_ATU_FACTOR)
/** Convert frame length unit to ticks. */
#define MAC_FL_TO_TCK(fl) ((fl) * MAC_TCK_PER_FL)
/** Convert ticks to frame length unit, round up. */
diff --git a/cesar/mac/common/tonemap.h b/cesar/mac/common/tonemap.h
index 270f7096e4..df6ac7226f 100644
--- a/cesar/mac/common/tonemap.h
+++ b/cesar/mac/common/tonemap.h
@@ -77,7 +77,7 @@ typedef enum tonemap_sound_reason_code_t tonemap_sound_reason_code_t;
#define TONEMAP_BITS_PER_SYMBOL_MAX (10 * PHY_CARRIER_NB)
/** Tonemaps life duration since last refresh before it becomes stale */
-#define TONEMAPS_LIFE_DURATION_S 30
+#define TONEMAPS_LIFE_DURATION_S 3600
/**
* Position of the header of the tone map in the allocated data.
@@ -91,7 +91,7 @@ typedef enum tonemap_sound_reason_code_t tonemap_sound_reason_code_t;
* Number of frames sound to receive before the PBProc send a sound complete
* flag to the peer.
*/
-#define TONEMAP_SOUND_FRAME_COUNTER 22
+#define TONEMAP_SOUND_FRAME_COUNTER 4
/**
* Tone map in use flag.
@@ -133,7 +133,7 @@ struct tonemap_intervals_t
* This change is handle by the mac_interval_commit_changes function which
* will update the version while swapping intervals list.
*/
- uint version;
+ u8 version;
/**
* Count of intervals.
* 0 is a valid number (0 intervals).
diff --git a/cesar/mac/pbproc/Config b/cesar/mac/pbproc/Config
index 6d8e591baa..a288c83896 100644
--- a/cesar/mac/pbproc/Config
+++ b/cesar/mac/pbproc/Config
@@ -2,3 +2,6 @@ CONFIG_GPIO_LED_TRAFFIC = n
CONFIG_GPIO_LED_TRAFFIC_GPIO = 2
CONFIG_GPIO_LED_PBPROC_ALIVE = n
CONFIG_GPIO_LED_PBPROC_ALIVE_GPIO = 3
+CONFIG_GPIO_LED_PBPROC_WORKING = n
+CONFIG_GPIO_LED_PBPROC_WORKING_GPIO = 0
+CONFIG_MAC_PBPROC_EOC_EXHAUST_THRESHOLD = 300 \ No newline at end of file
diff --git a/cesar/mac/pbproc/inc/context.h b/cesar/mac/pbproc/inc/context.h
index c83cd6ce06..d1538f09b7 100644
--- a/cesar/mac/pbproc/inc/context.h
+++ b/cesar/mac/pbproc/inc/context.h
@@ -39,10 +39,10 @@
/** Number of PB before frame end for first step of SACKD computation (there
* can be only one PB in the last symbol, and at most three PB in the symbol
* before. */
-#define PBPROC_SACKD_ANTICIP_PB_NB 4
+#define PBPROC_SACKD_ANTICIP_PB_NB 8
/** Maximum number of channel data retrieved after a frame reception. */
-#define PBPROC_CHANDATA_NB 11
+#define PBPROC_CHANDATA_NB 15
/** Delay to keep detection valid for HP 1.0 and 1.1. */
#define PBPROC_HP_DETECT_DELAY_TCK MAC_MS_TO_TCK (2000)
@@ -98,6 +98,16 @@ struct pbproc_recv_mpdu_t
bool drop;
/** SACK data. */
pbproc_sackd_t sackd;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /** Bidirectional flag */
+ bool bbf;
+ /** Use infrastructure for ACK but not send */
+ bool send_sack;
+ /** Use reduced ifs. Only RSOF-SOF transition */
+ bool reduced_ifs;
+ /** Duration of RSOF frame */
+ u32 mrtfl;
+#endif
};
typedef struct pbproc_recv_mpdu_t pbproc_recv_mpdu_t;
@@ -220,6 +230,8 @@ struct pbproc_stat_t
uint rx_fc_unknown;
/** RX: FC CRC error. */
uint rx_crc_error;
+ /** RX: Frame length is bad. */
+ uint rx_len_err;
/** TX: invalid (nothing to send). */
uint tx_invalid;
/** TX: late. */
@@ -311,6 +323,10 @@ struct pbproc_t
phy_chandata_conf_t chandata_conf[PBPROC_CHANDATA_NB];
/** Number of channel data blocks to retrieve after reception. */
uint chandata_nb;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /** True if station is polled from CCO in current beacon period */
+ bool polled;
+#endif
/** Whether channel data should be collected for data MPDU. */
bool chandata_data;
};
diff --git a/cesar/mac/pbproc/inc/fc.h b/cesar/mac/pbproc/inc/fc.h
index 56885997e4..4ef6e0ad3e 100644
--- a/cesar/mac/pbproc/inc/fc.h
+++ b/cesar/mac/pbproc/inc/fc.h
@@ -15,6 +15,8 @@
* Be careful to bit order.
*/
+#include "config/mac/pbproc/eoc.h"
+
/** Delimiter type. */
enum pbproc_fc_dt_t
{
@@ -105,6 +107,7 @@ typedef struct pbproc_fc_beacon_t pbproc_fc_beacon_t;
#define PBPROC_FC_BEACON_W3__BTO3_MSB8 7, 0
#define PBPROC_FC_BEACON_W3__FCCS_AV 31, 8
+#if !CONFIG_MAC_PBPROC_EOC_FC
/** Start Of Frame frame control. */
struct pbproc_fc_sof_t
{
@@ -177,6 +180,91 @@ struct pbproc_fc_sof_t
/** FCCS. */
uint fccs_av:24;)
};
+#else
+/** Start Of Frame EoC */
+struct pbproc_fc_sof_t
+{
+ BITFIELDS_WORD(
+ /** Delimiter type. */
+ pbproc_fc_dt_t dt_av:3;,
+ /** Access field. */
+ bool access:1;,
+ /** Short network identifier. */
+ uint snid:4;,
+ /** Destination terminal equipment identifier. */
+ uint dtei:8;,
+ /** Link identifier. */
+ uint lid:4;,
+ /** Encryption key select. */
+ uint eks:2;,
+ /** terminal equipment identifier
+ direction 0 C->S, 1 S->C. */
+ bool direction:1;,
+ /** PB size, true for 136. */
+ bool pbsz:1;,
+ /** Number of symbols. */
+ uint num_sym:2;,
+ /** Tone map index. */
+ uint tmi_av:5;,
+ /** Multicast flag. */
+ bool mcf:1;)
+ BITFIELDS_WORD(
+ /** Frame length. */
+ uint fl_av:12;,
+ /** MPDU count. */
+ uint mpdu_cnt:2;,
+ /** Burst count. */
+ uint burst_cnt:2;,
+ /** Max reverse transmission frame length. */
+ uint mrtfl:12;,
+ /** Multi-network broadcast flag. */
+ bool mnbf:1;,
+ /** Bidirectional burst flag. */
+ bool bbf:1;,
+ uint sackt0:2;)
+ uint sacki0;
+ BITFIELDS_WORD(
+ uint sacki1:8;,
+ /** FCCS. */
+ uint fccs_av:24;)
+};
+
+/** EOC SACK Size. */
+enum pbproc_fc_sacki_eoc_size_t
+{
+ PBPROC_FC_SACKI_EOC_SOF_SIZE = 40, /* two fields: 32+8 */
+ PBPROC_FC_SACKI_EOC_RSOF_SIZE = 57,/* three fields: 32+25 */
+ PBPROC_FC_SACKI_EOC_SOUND_SIZE = 53, /* two fields: 32+21 */
+ PBPROC_FC_SACKI_EOC_SOF_LEFT = PBPROC_FC_SACKI_EOC_SOF_SIZE - 32,
+ PBPROC_FC_SACKI_EOC_RSOF_LEFT = PBPROC_FC_SACKI_EOC_RSOF_SIZE - 32,
+ PBPROC_FC_SACKI_EOC_SOUND_LEFT = PBPROC_FC_SACKI_EOC_SOUND_SIZE - 32,
+};
+
+#define PBPROC_FC_EOC_SOF_W0__DT_AV 2, 0
+#define PBPROC_FC_EOC_SOF_W0__ACCESS 3, 3
+#define PBPROC_FC_EOC_SOF_W0__SNID 7, 4
+#define PBPROC_FC_EOC_SOF_W0__DTEI 15, 8
+#define PBPROC_FC_EOC_SOF_W0__LID 19, 16
+#define PBPROC_FC_EOC_SOF_W0__EKS 21, 20
+#define PBPROC_FC_EOC_SOF_W0__DIRECTION 22, 22
+#define PBPROC_FC_EOC_SOF_W0__PBSZ 23, 23
+#define PBPROC_FC_EOC_SOF_W0__NUM_SYM 25, 24
+#define PBPROC_FC_EOC_SOF_W0__TMI_AV 30, 26
+#define PBPROC_FC_EOC_SOF_W0__MCF 31, 31
+
+#define PBPROC_FC_EOC_SOF_W1__FL_AV 11, 0
+#define PBPROC_FC_EOC_SOF_W1__MPDU_CNT 13, 12
+#define PBPROC_FC_EOC_SOF_W1__BURST_CNT 15, 14
+#define PBPROC_FC_EOC_SOF_W1__MRTFL 27, 16
+#define PBPROC_FC_EOC_SOF_W1__MNBF 28, 28
+#define PBPROC_FC_EOC_SOF_W1__BBF 29, 29
+#define PBPROC_FC_EOC_SOF_W1__SACKT0 31, 30
+
+#define PBPROC_FC_EOC_SOF_W2__SACKI0 31, 0
+
+#define PBPROC_FC_EOC_SOF_W3__SACKI1 7, 0
+
+#endif
typedef struct pbproc_fc_sof_t pbproc_fc_sof_t;
#define PBPROC_FC_SOF_W0__DT_AV 2, 0
@@ -379,6 +467,7 @@ typedef struct pbproc_fc_rts_cts_t pbproc_fc_rts_cts_t;
#define PBPROC_FC_RTS_CTS_W3__RESERVED2 7, 0
#define PBPROC_FC_RTS_CTS_W3__FCCS_AV 31, 8
+#if !CONFIG_MAC_PBPROC_EOC_FC
/** Sound frame control. */
struct pbproc_fc_sound_t
{
@@ -427,6 +516,71 @@ struct pbproc_fc_sound_t
/** FCCS. */
uint fccs_av:24;)
};
+#else
+/** Sound frame control. EOC */
+struct pbproc_fc_sound_t
+{
+ BITFIELDS_WORD(
+ /** Delimiter type. */
+ pbproc_fc_dt_t dt_av:3;,
+ /** Access field. */
+ bool access:1;,
+ /** Short network identifier. */
+ uint snid:4;,
+ /** Destination terminal equipment identifier. */
+ uint dtei:8;,
+ /** Frame length. */
+ uint fl_av:12;,
+ /** Link identifier. */
+ uint lid:4;)
+ BITFIELDS_WORD(
+ /** Type of compression */
+ uint sackt0:2;,
+ /** Direction identifier. */
+ uint direction:1;,
+ /** PB size, true for 136. */
+ bool pbsz:1;,
+ /** Sound ACK flag. */
+ bool saf:1;,
+ /** Sound complete flag. */
+ bool scf:1;,
+ /** Max tone map requested. */
+ uint req_tm:3;,
+ /** MPDU count. */
+ uint mpdu_cnt:2;,
+ /** sacki 0 */
+ uint sacki0:21;)
+ /** sacki 1 */
+ uint sacki1;
+ BITFIELDS_WORD(
+ uint src:8;,
+ /** FCCS. */
+ uint fccs_av:24;)
+};
+
+#define PBPROC_FC_EOC_SOUND_W0__DT_AV 2, 0
+#define PBPROC_FC_EOC_SOUND_W0__ACCESS 3, 3
+#define PBPROC_FC_EOC_SOUND_W0__SNID 7, 4
+#define PBPROC_FC_EOC_SOUND_W0__DTEI 15, 8
+#define PBPROC_FC_EOC_SOUND_W0__FL_AV 27, 16
+#define PBPROC_FC_EOC_SOUND_W0__LID 31, 28
+
+#define PBPROC_FC_EOC_SOUND_W1__SACKT0 1, 0
+#define PBPROC_FC_EOC_SOUND_W1__DIRECTION 2, 2
+#define PBPROC_FC_EOC_SOUND_W1__PBSZ 3, 3
+#define PBPROC_FC_EOC_SOUND_W1__SAF 4, 4
+#define PBPROC_FC_EOC_SOUND_W1__SCF 5, 5
+#define PBPROC_FC_EOC_SOUND_W1__REQ_TM 8, 6
+#define PBPROC_FC_EOC_SOUND_W1__MPDU_CNT 10, 9
+#define PBPROC_FC_EOC_SOUND_W1__SACKI0 31, 11
+
+#define PBPROC_FC_EOC_SOUND_W2__SACKI1 31, 0
+
+#define PBPROC_FC_EOC_SOUND_W3__SRC 7, 0
+#define PBPROC_FC_EOC_SOUND_W3__FCCS_AV 31, 8
+
+
+#endif
typedef struct pbproc_fc_sound_t pbproc_fc_sound_t;
#define PBPROC_FC_SOUND_W0__DT_AV 2, 0
@@ -453,6 +607,7 @@ typedef struct pbproc_fc_sound_t pbproc_fc_sound_t;
#define PBPROC_FC_SOUND_W3__RESERVED2 7, 0
#define PBPROC_FC_SOUND_W3__FCCS_AV 31, 8
+#if !CONFIG_MAC_PBPROC_EOC_FC
/** Reverse SOF frame control. */
struct pbproc_fc_rsof_t
{
@@ -507,6 +662,64 @@ struct pbproc_fc_rsof_t
/** FCCS. */
uint fccs_av:24;)
};
+#else
+/** Reverse SOF frame control EoC. */
+struct pbproc_fc_rsof_t
+{
+ BITFIELDS_WORD(
+ /** Delimiter type. */
+ pbproc_fc_dt_t dt_av:3;,
+ /** Access field. */
+ bool access:1;,
+ /** Short network identifier. */
+ uint snid:4;,
+ /** Destination terminal equipment identifier. */
+ uint dtei:8;,
+ /** SACK type */
+ uint sackt0:2;,
+ /** Reverse SOF frame length. */
+ uint rsof_fl_av:12;,
+ /** Number of symbols. */
+ uint num_sym:2;)
+ /** ACK part 1 */
+ uint sacki0;
+ BITFIELDS_WORD(
+ /** ACK part 2 */
+ uint sacki1:25;,
+ /** Tone map index. */
+ uint tmi_av:5;,
+ /** Beacon detect flag. */
+ bool bdf:1;,
+ /** PB size, true for 136. */
+ bool pbsz:1;
+ )
+ BITFIELDS_WORD(
+ /** Number of pending PBs. */
+ uint ppb:8;,
+ /** FCCS. */
+ uint fccs_av:24;)
+};
+
+#define PBPROC_FC_EOC_RSOF_W0__DT_AV 2, 0
+#define PBPROC_FC_EOC_RSOF_W0__ACCESS 3, 3
+#define PBPROC_FC_EOC_RSOF_W0__SNID 7, 4
+#define PBPROC_FC_EOC_RSOF_W0__DTEI 15, 8
+#define PBPROC_FC_EOC_RSOF_W0__SACKT0 17, 16
+#define PBPROC_FC_EOC_RSOF_W0__RSOF_FL_AV 29, 18
+#define PBPROC_FC_EOC_RSOF_W0__NUM_SYM 31, 30
+
+#define PBPROC_FC_EOC_RSOF_W1__SACKI0 31, 0
+
+#define PBPROC_FC_EOC_RSOF_W2__SACKI1 24, 0
+#define PBPROC_FC_EOC_RSOF_W2__TMI_AV 29, 25
+#define PBPROC_FC_EOC_RSOF_W2__BDF 30, 30
+#define PBPROC_FC_EOC_RSOF_W2__PBSZ 31, 31
+
+#define PBPROC_FC_EOC_RSOF_W3__PPB 7, 0
+#define PBPROC_FC_EOC_RSOF_W3__FCCS_AV 31, 8
+
+#endif
+
typedef struct pbproc_fc_rsof_t pbproc_fc_rsof_t;
#define PBPROC_FC_RSOF_W0__DT_AV 2, 0
diff --git a/cesar/mac/pbproc/inc/fsm_rx_data.h b/cesar/mac/pbproc/inc/fsm_rx_data.h
index 6e9eddf707..ca8ceb4346 100644
--- a/cesar/mac/pbproc/inc/fsm_rx_data.h
+++ b/cesar/mac/pbproc/inc/fsm_rx_data.h
@@ -26,10 +26,10 @@ pbproc_frda_init (pbproc_t *ctx);
* Handle a RX data, called from handle_fc.
* \param ctx pbproc context
* \param rx_date start of preamble date
- * \param sof SOF frame control
+ * \param fc_av frame control
*/
void
-pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof);
+pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av);
/**
* RX DATA WACK =PBDMA=>.
diff --git a/cesar/mac/pbproc/inc/prep_mpdu.h b/cesar/mac/pbproc/inc/prep_mpdu.h
index 038d1c6ba6..36c6024f94 100644
--- a/cesar/mac/pbproc/inc/prep_mpdu.h
+++ b/cesar/mac/pbproc/inc/prep_mpdu.h
@@ -89,6 +89,8 @@ struct pbproc_prep_mpdu_t
uint ifs_tck;
/** Frame length with preamble (including IFS). */
uint flp_tck;
+ /** Reverse frame length with preamble (including IFS). */
+ uint rev_flp_tck;
/** Used main MFS. */
mfs_tx_t *main_mfs;
/** Number of reserved main MFS segment from MFS still to be queued. */
@@ -101,6 +103,10 @@ struct pbproc_prep_mpdu_t
bool bypass_aes;
/** AES network encryption key. */
u32 *nek;
+ /** Network encryption key select, info from RX SOF */
+ u8 eks;
+ /** bidirection transmission, info from RX SOF */
+ bool bbf;
/** Data kept for each individual MPDU. */
pbproc_prep_mpdu_single_t mpdu[PBPROC_PREP_MPDU_NB_MAX];
/** Pointer to current MPDU data, should be synchronised with
@@ -249,6 +255,34 @@ pbproc_prep_mpdu_handle_sack (pbproc_t *ctx, const pbproc_fc_t *fc);
void
pbproc_prep_mpdu_commit_burst (pbproc_t *ctx);
+
+#if CONFIG_MAC_PBPROC_EOC_FC
+/**
+ * Reassembly SACKI fields from frame control
+ * \param fc_av FC generic pointer (SOF, RSOF, SOUND)
+ * \param st[4] type of sacki
+ * \param sacki_dec SACKI dec
+ */
+void
+pbproc_prep_mpdu_reassembly_ack (const pbproc_fc_t * fc_av,
+ uint st[4], pbproc_sacki_dec_t * sacki_dec);
+/**
+ * Decision for ACK in SOF/RSOF/SOUND.
+ * \param ctx pbproc context
+ * \param rx_date reception date
+ * \param fc_av FC generic pointer (SOF, RSOF, SOUND)
+ */
+void
+pbproc_prep_mpdu_pg_ack (pbproc_t *ctx, u32 rx_date,
+ const pbproc_fc_t *fc_av);
+/**
+ * Track access timeout for prep mpdu/sound.
+ * \param ctx pbproc context
+ */
+void
+pbproc_prep_mpdu_access_track (pbproc_t *ctx);
+#endif
+
/**
* Acknowledge or cancel a SOUND frame.
* \param ctx pbproc context
diff --git a/cesar/mac/pbproc/inc/trace.h b/cesar/mac/pbproc/inc/trace.h
index 9c518a0ba9..a868f397f2 100644
--- a/cesar/mac/pbproc/inc/trace.h
+++ b/cesar/mac/pbproc/inc/trace.h
@@ -41,11 +41,16 @@ enum
PBPROC_TRACE_FTOP_PRP_LOST,
PBPROC_TRACE_FTOP_TX_INVALID,
PBPROC_TRACE_FTOP_TX,
+ PBPROC_TRACE_FHFC_BEACON,
+ PBPROC_TRACE_FHFC_SOF,
+ PBPROC_TRACE_FHFC_RSOF,
+ PBPROC_TRACE_FHFC_SOUND,
PBPROC_TRACE_FRDA_SACK_UNIFORM,
PBPROC_TRACE_FRDA_SACK_MIXED,
PBPROC_TRACE_FRDA_SACK_MIXED_COMPRESSED,
PBPROC_TRACE_FTDA_TX_BURST,
PBPROC_TRACE_PREP_MPDU_COMMIT,
+ PBPROC_TRACE_SOUND_FRAME_COUNTER,
};
BEGIN_DECLS
diff --git a/cesar/mac/pbproc/pbproc.h b/cesar/mac/pbproc/pbproc.h
index 0cf54548a4..9491be10e6 100644
--- a/cesar/mac/pbproc/pbproc.h
+++ b/cesar/mac/pbproc/pbproc.h
@@ -78,6 +78,10 @@ struct pbproc_rx_params_t
u8 sound_req_tm;
/** For sound frames: whether we responded with the sound complete flag. */
bool sound_complete;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /** Attenuation measured for last frame. */
+ u32 agc_gain;
+#endif
};
typedef struct pbproc_rx_params_t pbproc_rx_params_t;
@@ -375,6 +379,17 @@ pbproc_mfs_expire (pbproc_t *ctx, mfs_tx_t *mfs, u32 expiration_ntb,
void
pbproc_mfs_remove_all (mfs_tx_t *mfs);
+/**
+ * Adjust PBProc parameters according to number of carriers
+ * \param ctx PBProc context
+ * \param adjust use 2 symbols in control and extend EIFS time period
+ *
+ */
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+pbproc_parameters_adjust (pbproc_t *ctx, bool adjust);
+#endif
+
END_DECLS
#endif /* mac_pbproc_pbproc_h */
diff --git a/cesar/mac/pbproc/src/fsm.c b/cesar/mac/pbproc/src/fsm.c
index 68457a09ef..929ca31570 100644
--- a/cesar/mac/pbproc/src/fsm.c
+++ b/cesar/mac/pbproc/src/fsm.c
@@ -12,6 +12,8 @@
*/
#include "common/std.h"
+#include "hal/gpio/gpio.h"
+
#include "mac/pbproc/pbproc.h"
#include "mac/pbproc/inc/fsm.h"
@@ -78,8 +80,10 @@ pbproc_fsm_handle_rx_fc_event (pbproc_t *ctx, u32 rx_date, const u32 *fc_av)
PBPROC_TRACE (FSM_RX_FC, phy_date (), rx_date,
fc_av ? fc_av[0] : (u32) -1, fc_av ? fc_av[1] : (u32) -1,
fc_av ? fc_av[2] : (u32) -1, fc_av ? fc_av[3] : (u32) -1);
+ GPIO_SET (LED_PBPROC_WORKING, 1);
ctx->fsm.states[ctx->fsm.current_state].
rx_fc_cb (ctx, rx_date, (const pbproc_fc_t *) fc_av);
+ GPIO_SET (LED_PBPROC_WORKING, 0);
if (ctx->fsm.schedule_deferred)
{
ctx->fsm.schedule_deferred = false;
@@ -95,7 +99,9 @@ pbproc_fsm_handle_access_event (pbproc_t *ctx)
dbg_claim (ctx);
dbg_claim (ctx->fsm.current_state < PBPROC_FSM_STATE_NB);
PBPROC_TRACE (FSM_ACCESS, phy_date ());
+ GPIO_SET (LED_PBPROC_WORKING, 1);
ctx->fsm.states[ctx->fsm.current_state].access_cb (ctx);
+ GPIO_SET (LED_PBPROC_WORKING, 0);
if (ctx->fsm.schedule_deferred)
{
ctx->fsm.schedule_deferred = false;
@@ -111,7 +117,9 @@ pbproc_fsm_handle_access_conf_event (pbproc_t *ctx)
dbg_claim (ctx);
dbg_claim (ctx->fsm.current_state < PBPROC_FSM_STATE_NB);
PBPROC_TRACE (FSM_ACCESS_CONF, phy_date ());
+ GPIO_SET (LED_PBPROC_WORKING, 1);
ctx->fsm.states[ctx->fsm.current_state].access_conf_cb (ctx);
+ GPIO_SET (LED_PBPROC_WORKING, 0);
if (ctx->fsm.schedule_deferred)
{
ctx->fsm.schedule_deferred = false;
@@ -128,7 +136,9 @@ pbproc_fsm_handle_pbdma_event (pbproc_t *ctx, u32 status_word)
dbg_claim (ctx->fsm.current_state < PBPROC_FSM_STATE_NB);
PBPROC_TRACE (FSM_PBDMA, phy_date (), status_word);
ctx->pbdma_status = PHY_PBDMA_STATUS (status_word);
+ GPIO_SET (LED_PBPROC_WORKING, 1);
ctx->fsm.states[ctx->fsm.current_state].pbdma_cb (ctx);
+ GPIO_SET (LED_PBPROC_WORKING, 0);
if (ctx->fsm.schedule_deferred)
{
ctx->fsm.schedule_deferred = false;
diff --git a/cesar/mac/pbproc/src/fsm_handle_fc.c b/cesar/mac/pbproc/src/fsm_handle_fc.c
index a6fd63d8cc..5ad5e7496c 100644
--- a/cesar/mac/pbproc/src/fsm_handle_fc.c
+++ b/cesar/mac/pbproc/src/fsm_handle_fc.c
@@ -33,13 +33,13 @@ pbproc_fhfc_beacon (pbproc_t *ctx, u32 rx_date,
const pbproc_fc_beacon_t *beacon);
/**
- * Handle SOF FC.
+ * Handle SOF/RSOF FC.
* \param ctx pbproc context
* \param rx_date start of preamble date
- * \param sof SOF FC
+ * \param fc_av generic FC
*/
static void
-pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof);
+pbproc_fhfc_sof_rsof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t * fc_av);
/**
* Handle RTS/CTS.
@@ -86,7 +86,6 @@ pbproc_fhfc_bad (pbproc_t *ctx, u32 rx_date);
*/
static bool
pbproc_fhfc_fc10 (pbproc_t *ctx, u32 rx_date, u32 fc10);
-
void
pbproc_fhfc_init (pbproc_t *ctx)
{
@@ -108,7 +107,8 @@ pbproc_fhfc_handle_fc (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
if (!fc_av)
{
/* Handle HP 1.0 detection. */
- bool crc_error = pbproc_fhfc_fc10 (ctx, rx_date,
+ bool crc_error = CONFIG_MAC_PBPROC_EOC_FC
+ || pbproc_fhfc_fc10 (ctx, rx_date,
phy_rx_fc10 (ctx->phy));
if (crc_error)
{
@@ -126,7 +126,8 @@ pbproc_fhfc_handle_fc (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
pbproc_fhfc_beacon (ctx, rx_date, &fc_av->beacon);
break;
case PBPROC_FC_DT_SOF:
- pbproc_fhfc_sof (ctx, rx_date, &fc_av->sof);
+ case PBPROC_FC_DT_RSOF:
+ pbproc_fhfc_sof_rsof (ctx, rx_date, fc_av);
break;
case PBPROC_FC_DT_SACK:
pbproc_fhfc_ignore (ctx, rx_date, ctx->times.pre_fcs_tck
@@ -144,6 +145,11 @@ pbproc_fhfc_handle_fc (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
pbproc_fhfc_bad (ctx, rx_date);
}
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* maybe ack for us in frame control: Immediate action
+ * before FC handle to take care for short SOF, RSOF frames */
+ pbproc_prep_mpdu_pg_ack(ctx, rx_date, fc_av);
+#endif
}
static void ARCH_ILRAM
@@ -154,18 +160,52 @@ pbproc_fhfc_beacon (pbproc_t *ctx, u32 rx_date,
}
static void ARCH_ILRAM
-pbproc_fhfc_sof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
+pbproc_fhfc_sof_rsof (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t * fc_av)
{
- if (sof->access == false
- && ((ctx->config->tei && sof->snid == ctx->alloc.snid) || sof->mnbf)
- && (sof->dtei == ctx->config->tei || sof->mcf))
+ bool accept_frame = false;
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF)
+ {
+ PBPROC_TRACE (FHFC_RSOF, fc_av->rsof.dtei, ctx->prep_mpdu.lid);
+ }
+ else if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)
{
- pbproc_frda__handle (ctx, rx_date, sof);
+ PBPROC_TRACE (FHFC_SOF, fc_av->sof.dtei, fc_av->sof.lid);
+ }
+ /* Accept RSOF */
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF
+ && fc_av->rsof.access == false
+ && (fc_av->rsof.snid == ctx->alloc.snid)
+ && ctx->prep_mpdu.valid
+ && ctx->prep_mpdu.bbf)
+ accept_frame = true;
+ /* Accept SOF */
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF
+ && fc_av->sof.access == false
+#if CONFIG_MAC_PBPROC_EOC_FC
+ && ((fc_av->sof.snid == ctx->alloc.snid) || fc_av->sof.mnbf)
+ && ((fc_av->sof.dtei && fc_av->sof.dtei == ctx->config->tei)
+ || fc_av->sof.mcf
+ || (fc_av->sof.direction
+ && MAC_TEI_IS_EOC_CCO(ctx->config->tei))))
+#else
+ && ((ctx->config->tei && fc_av->sof.snid == ctx->alloc.snid)
+ || fc_av->sof.mnbf)
+ && (fc_av->sof.dtei == ctx->config->tei || fc_av->sof.mcf))
+#endif
+ accept_frame = true;
+
+ /* What is the decision? */
+ if (accept_frame)
+ {
+ pbproc_frda__handle (ctx, rx_date, fc_av); /* Handle SOF/RSOF FC */
}
else
{
- /* Not for us, count the expected following SACK. */
- pbproc_fhfc_ignore (ctx, rx_date, MAC_FL_TO_TCK (sof->fl_av)
+ /* Not for us */
+ pbproc_fhfc_ignore (ctx, rx_date,
+ MAC_FL_TO_TCK ((fc_av->generic.dt_av == PBPROC_FC_DT_SOF)?
+ fc_av->sof.fl_av:
+ fc_av->rsof.rsof_fl_av)
+ 2 * ctx->times.pre_fcs_tck
+ MAC_CIFS_TCK);
}
@@ -233,7 +273,12 @@ pbproc_fhfc_sound (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sound_t *sound)
{
if (sound->access == false
&& sound->snid == ctx->alloc.snid
+#if CONFIG_MAC_PBPROC_EOC_FC
+ && ((sound->dtei == ctx->config->tei && !sound->direction)
+ || (MAC_TEI_IS_EOC_CCO(ctx->config->tei) && sound->direction))
+#else
&& sound->dtei == ctx->config->tei
+#endif
&& !sound->saf)
{
pbproc_frso__handle (ctx, rx_date, sound);
@@ -269,7 +314,13 @@ pbproc_fhfc_bad (pbproc_t *ctx, u32 rx_date)
{
dbg_claim (ctx);
phy_rx_prepare_short (ctx->phy);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* We call this function only to have a EoC reschedule.
+ * As scheduling is done in ca_access_compute. */
+ ca_access_vcs_restart (ctx->ca, rx_date + ctx->times.max_fl_tck);
+#else
ca_access_vcs_restart_eifs (ctx->ca, rx_date);
+#endif
phy_rx_activate (ctx->phy, false, rx_date + ctx->times.pre_fcs_tck
+ PHY_RX_ACTIVATE_DELAY_AFTER_SHORT_TCK, true);
pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
@@ -345,4 +396,3 @@ pbproc_fhfc_fc10 (pbproc_t *ctx, u32 rx_date, u32 fc10)
crc_error = true;
return crc_error;
}
-
diff --git a/cesar/mac/pbproc/src/fsm_rx_beacon.c b/cesar/mac/pbproc/src/fsm_rx_beacon.c
index 2b1fde55c1..d85c694234 100644
--- a/cesar/mac/pbproc/src/fsm_rx_beacon.c
+++ b/cesar/mac/pbproc/src/fsm_rx_beacon.c
@@ -46,9 +46,13 @@ pbproc_frbe__handle (pbproc_t *ctx, u32 rx_date,
+ MAC_B2BIFS_TCK;
ctx->recv_mpdu.ack_date = rx_date + flp_tck;
/* Ignore frames ending after the allocation, handle pool exhaustion. */
+#if !CONFIG_MAC_PBPROC_EOC_FC
if ((!ctx->alloc.merge
&& less_mod2p32 (ctx->alloc.end_date, ctx->recv_mpdu.ack_date))
|| ctx->rx_pool_size < 1)
+#else
+ if (ctx->rx_pool_size < 1)
+#endif
{
/* Ignore. */
if (ctx->rx_pool_size < 1)
diff --git a/cesar/mac/pbproc/src/fsm_rx_data.c b/cesar/mac/pbproc/src/fsm_rx_data.c
index 9fb87b0131..da32a9cd3b 100644
--- a/cesar/mac/pbproc/src/fsm_rx_data.c
+++ b/cesar/mac/pbproc/src/fsm_rx_data.c
@@ -22,6 +22,14 @@
#include "hal/phy/pbdma.h"
+/** constants for IFS-s */
+#if CONFIG_MAC_PBPROC_EOC_FC
+/** IFS from SOF-RSOF. */
+#define MAC_CF_SOF_RSOF_IFS_TCK MAC_US_TO_TCK (100)
+/** IFS from RSOF-SOF. Also in CA + 40 uS is added to access time. */
+#define MAC_CF_RSOF_SOF_IFS_TCK MAC_US_TO_TCK (60)
+#endif
+
/**
* Restart VCS for next MPDU.
* \param ctx pbproc context
@@ -46,10 +54,10 @@ pbproc_frda_send_sack (pbproc_t *ctx);
/**
* Initialise SACKD, reset if not part of last burst.
* \param ctx pbproc context
- * \param sof received MPDU SOF
+ * \param fc received MPDU fc
*/
static void
-pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof);
+pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_t *fc_av);
/**
* Give up reception and eventually prepare a SACK to signal the problem.
@@ -62,7 +70,7 @@ pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof);
* Go to next FSM state.
*/
static void
-pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof,
+pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av,
bool wack, uint sacki_uniform);
/**
@@ -71,7 +79,6 @@ pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof,
*/
static void
pbproc_frda_commit (pbproc_t *ctx);
-
void
pbproc_frda_init (pbproc_t *ctx)
{
@@ -88,41 +95,131 @@ pbproc_frda_init (pbproc_t *ctx)
pbproc_frda__rx_burst__access;
}
+#define PB_EOC_SKIP_LEVEL1 1
+#define PB_EOC_SKIP_LEVEL2 3
+#define PB_EOC_SKIP_LEVEL3 5
+
+#if CONFIG_MAC_COMMON_EOC_SCHED
+static inline void
+pbproc_next_poll_update (pbproc_t *ctx, u32 rx_date)
+{
+ sta_t *sta = NULL;
+ /* examine only unicast frames */
+ sta = mac_store_sta_get_noref (ctx->store, ctx->prep_mpdu.dtei);
+ /* check last poll */
+ if (sta)
+ {
+ u8 empty;
+ if (!ctx->recv_mpdu.pb_nb && !ctx->prep_mpdu.burst_seg_nb)
+ sta->empty_poll++;
+ else
+ sta->empty_poll = 0;
+ sta->poll_time = rx_date;
+ sta->ppb = ctx->recv_mpdu.rx_params.pending_seg_nb;
+ empty = sta->empty_poll;
+ if (empty > PB_EOC_SKIP_LEVEL3)
+ sta->empty_poll = PB_EOC_SKIP_LEVEL3 + 1;
+ /* Update poll_time */
+ if (empty > PB_EOC_SKIP_LEVEL3)
+ sta->poll_time += MAC_MS_TO_TCK (200);
+ else if (empty > PB_EOC_SKIP_LEVEL2)
+ sta->poll_time += MAC_MS_TO_TCK (150);
+ else if (empty > PB_EOC_SKIP_LEVEL1)
+ sta->poll_time += MAC_MS_TO_TCK (100);
+ }
+}
+#endif
+
void ARCH_ILRAM
-pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
+pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
{
- bool wack, unassociated;
- phy_pb_size_t pb_size;
dbg_claim (ctx);
- dbg_claim (sof);
+ dbg_claim (fc_av);
+ const bool is_sof = (fc_av->generic.dt_av == PBPROC_FC_DT_SOF);
+ bool wack, unassociated, mcf;
+ phy_pb_size_t pb_size;
+ uint tei, eks, fl_av, num_sym;
+ const pbproc_fc_sof_t *sof = &fc_av->sof;
/* TODO features. */
- dbg_claim (sof->bbf == false);
- dbg_claim (sof->dcppcf == false);
- dbg_claim (sof->rsr == false);
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ if (is_sof)
+ {
+ dbg_claim (sof->bbf == false);
+ dbg_claim (sof->dcppcf == false);
+ dbg_claim (sof->rsr == false);
+ }
/* Update stats. */
ctx->stats.rx_data++;
/* Unassociated? */
- unassociated = sof->stei == 0 || sof->mnbf;
+ unassociated = is_sof && (sof->stei == 0 || sof->mnbf);
/* With ACK? */
wack = sof->snid == ctx->alloc.snid && sof->dtei == ctx->config->tei;
- /* Burst? */
- ctx->recv_mpdu.mpdu_cnt = sof->mpdu_cnt;
- /* PB Size. */
pb_size = sof->pbsz ? PHY_PB_SIZE_136 : PHY_PB_SIZE_520;
+#else
+ /* Update stats. */
+ ctx->stats.rx_data++;
+ if (is_sof)
+ {
+ /* Unassociated? */
+ unassociated = sof->dtei == 0 || sof->mnbf;
+ wack = sof->snid == ctx->alloc.snid
+ && ((sof->dtei == ctx->config->tei && !sof->direction)
+ || (MAC_TEI_IS_EOC_CCO(ctx->config->tei)
+ && sof->direction
+ && (sof->dtei != MAC_TEI_BCAST)));
+ pb_size = sof->pbsz ? PHY_PB_SIZE_136 : PHY_PB_SIZE_520;
+ }
+ /* Unassociated? Not true if RSOF in EOC */
+ else
+ {
+ unassociated = false;
+ wack = true; /* After RSOF no wack but use infrastructure of acked */
+ pb_size = PHY_PB_SIZE_520;
+ }
+#endif
+ if (is_sof)
+ {
+ mcf = sof->mcf;
+ fl_av = sof->fl_av;
+ eks = sof->eks;
+ num_sym = sof->num_sym;
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ tei = sof->stei;
+#else
+ if (sof->direction == 1)
+ tei = sof->dtei;
+ else /* TODO current CCO, maybe function needed */
+ tei = MAC_TEI_CCO_DEF;
+#endif
+ }
+ else
+ {
+ mcf = false;
+ fl_av = ((pbproc_fc_rsof_t *)fc_av)->rsof_fl_av;
+ eks = ctx->prep_mpdu.eks;
+ tei = ((pbproc_fc_rsof_t *)fc_av)->dtei;
+ num_sym = ((pbproc_fc_rsof_t *)fc_av)->num_sym;
+ }
+ /* Burst? */
+ ctx->recv_mpdu.mpdu_cnt = (is_sof) ? sof->mpdu_cnt : 0;
+ uint fl_tck = MAC_FL_TO_TCK (fl_av);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ ctx->recv_mpdu.reduced_ifs = false;
+#endif
/* Ignore frames ending after the allocation. */
- uint fl_tck = MAC_FL_TO_TCK (sof->fl_av);
if (!ctx->alloc.merge
&& less_mod2p32 (ctx->alloc.end_date,
rx_date + 2 * ctx->times.pre_fcs_tck + fl_tck
+ MAC_CIFS_TCK))
{
ctx->stats.rx_out_of_alloc++;
- pbproc_frda_error (ctx, rx_date, sof, false,
+ pbproc_frda_error (ctx, rx_date, fc_av, false,
PBPROC_FC_SACKI_UNIFORM_ALL_ERROR);
return;
}
/* Get tonemap. */
- uint tmi = sof->tmi_av;
+ uint tmi = (is_sof)?sof->tmi_av:
+ ((pbproc_fc_rsof_t *)fc_av)->tmi_av;
tonemap_t *tm;
uint rifs_tck;
if (tmi < PHY_MOD_ROBO_NB)
@@ -130,9 +227,9 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
tm = &ctx->config->tonemask_info.tonemap_robo[tmi];
rifs_tck = MAC_RIFS_DEFAULT_TCK;
}
- else if (sof->mcf || unassociated)
+ else if (mcf || unassociated)
{
- pbproc_frda_error (ctx, rx_date, sof, wack,
+ pbproc_frda_error (ctx, rx_date, fc_av, wack,
PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO);
return;
}
@@ -140,7 +237,7 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
{
dbg_claim (wack);
dbg_claim (tmi < TONEMAP_INDEX_NB);
- sta_t *sta = mac_store_sta_get (ctx->store, sof->stei);
+ sta_t *sta = mac_store_sta_get (ctx->store, tei);
if (sta)
{
tm = sta->rx_tonemaps->tm[tmi];
@@ -148,14 +245,14 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
rifs_tck = MAC_RIFS_SPC_ANY_TCK;
if (!tm)
{
- pbproc_frda_error (ctx, rx_date, sof, true,
+ pbproc_frda_error (ctx, rx_date, fc_av, true,
PBPROC_FC_SACKI_UNIFORM_TMI_RESTART);
return;
}
}
else
{
- pbproc_frda_error (ctx, rx_date, sof, true,
+ pbproc_frda_error (ctx, rx_date, fc_av, true,
PBPROC_FC_SACKI_UNIFORM_TMI_RESTART);
return;
}
@@ -165,31 +262,33 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
rifs_tck = MAC_BIFS_TCK;
/* Compute symbol and PB number. */
uint symb_nb;
- if (sof->num_sym <= 2)
- symb_nb = sof->num_sym;
+ if (num_sym <= 2)
+ symb_nb = num_sym;
else
- symb_nb = ((fl_tck - rifs_tck - 2 * MAC_DX567_TCK)
- / ctx->symbol_tck[tm->gil] + 2);
+ symb_nb = (fl_tck > rifs_tck + 2 * MAC_DX567_TCK)?
+ ((fl_tck - rifs_tck - 2 * MAC_DX567_TCK)
+ / ctx->symbol_tck[tm->gil] + 2):0;
uint bits_per_pb = tm->bits_per_pb[pb_size];
/* To take into account that there is only one segment in the last
* symbol, here is the trick: */
uint pb_nb;
- if (bits_per_pb >= tm->bits_per_symbol)
- pb_nb = symb_nb * tm->bits_per_symbol / bits_per_pb;
- else
- pb_nb = ((symb_nb - 1) * tm->bits_per_symbol + bits_per_pb)
- / bits_per_pb;
- /* Stop if no PB. */
+ pb_nb = ((symb_nb - 1) * tm->bits_per_symbol
+ + MIN (bits_per_pb, tm->bits_per_symbol)) / bits_per_pb;
+ /* Fix number of symbol. */
+ uint real_symb_nb = (pb_nb * bits_per_pb + tm->bits_per_symbol - 1)
+ / tm->bits_per_symbol;
+ /* No data */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ if (symb_nb > 0 && pb_nb == 0)
+#else
if (!pb_nb)
+#endif
{
ctx->stats.rx_data_empty++;
- pbproc_frda_error (ctx, rx_date, sof, wack,
+ pbproc_frda_error (ctx, rx_date, fc_av, wack,
PBPROC_FC_SACKI_UNIFORM_ALL_ERROR);
return;
}
- /* Fix number of symbol. */
- uint real_symb_nb = (pb_nb * bits_per_pb + tm->bits_per_symbol - 1)
- / tm->bits_per_symbol;
if (real_symb_nb != symb_nb)
{
symb_nb = real_symb_nb;
@@ -201,11 +300,11 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
bool nek_ok = false;
do
{
- if (sof->eks < MAC_EKS_NB)
+ if (eks < MAC_EKS_NB)
{
if (unassociated)
break;
- sta_t *sta = mac_store_sta_get (ctx->store, sof->stei);
+ sta_t *sta = mac_store_sta_get (ctx->store, tei);
mac_nek_t (*nek)[2];
if (sta)
{
@@ -216,24 +315,24 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
}
else
nek = &ctx->config->nek;
- if ((*nek)[0].eks == sof->eks)
+ if ((*nek)[0].eks == eks)
key = (*nek)[0].nek_dec;
- else if ((*nek)[1].eks == sof->eks)
+ else if ((*nek)[1].eks == eks)
key = (*nek)[1].nek_dec;
else
break;
bypass_aes = false;
nek_ok = true;
}
- else if (sof->eks == MAC_EKS_CLEAR)
+ else if (eks == MAC_EKS_CLEAR)
{
nek_ok = true;
}
} while (0);
/* Acknowledge multicast frame even if it can not be decrypted. */
- if (!nek_ok && !(wack && sof->mcf))
+ if (!nek_ok && !(wack && mcf))
{
- pbproc_frda_error (ctx, rx_date, sof, wack,
+ pbproc_frda_error (ctx, rx_date, fc_av, wack,
PBPROC_FC_SACKI_UNIFORM_NEK_ERROR);
return;
}
@@ -241,18 +340,20 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
if (ctx->rx_pool_size < 1 + ctx->chandata_nb + pb_nb)
{
ctx->stats.rx_pool_shortage++;
- pbproc_frda_error (ctx, rx_date, sof, wack,
+ pbproc_frda_error (ctx, rx_date, fc_av, wack,
PBPROC_FC_SACKI_UNIFORM_ALL_ERROR);
return;
}
/* First thing to do: unblock the hardware. */
if (tmi >= PHY_MOD_ROBO_NB)
phy_set_tonemap (ctx->phy, tm->tmdma_desc_head);
- phy_rx_prepare (ctx->phy, pb_nb, tm->phy_combo_params[pb_size],
+ if (pb_nb)
+ phy_rx_prepare (ctx->phy, pb_nb, tm->phy_combo_params[pb_size],
tm->gil, symb_nb, tm->tcc_halfit);
/* Save received MPDU parameters. */
ctx->recv_mpdu.rx_params.preamble_ntb = rx_date
+ ctx->config->ntb_offset_tck;
+#if !CONFIG_MAC_PBPROC_EOC_FC
ctx->recv_mpdu.rx_params.beacon_period_start_ntb =
ctx->alloc.beacon_period_start_date + ctx->config->ntb_offset_tck;
ctx->recv_mpdu.rx_params.fl_tck = fl_tck;
@@ -274,15 +375,73 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
ctx->recv_mpdu.rx_params.hp11df = sof->hp11df;
ctx->recv_mpdu.rx_params.mfs_cmd_data = sof->mfs_cmd_data;
ctx->recv_mpdu.rx_params.mfs_cmd_mme = sof->mfs_cmd_mgmt;
+#else
+ ctx->recv_mpdu.rx_params.beacon_period_start_ntb =
+ ctx->alloc.beacon_period_start_date + ctx->config->ntb_offset_tck;
+ ctx->recv_mpdu.rx_params.fl_tck = fl_tck;
+ ctx->recv_mpdu.rx_params.mpdu_cnt = 0;
+ ctx->recv_mpdu.rx_params.bdf = 0;
+ ctx->recv_mpdu.rx_params.hp10df = false;
+ ctx->recv_mpdu.rx_params.hp11df = false;
+ ctx->recv_mpdu.rx_params.mfs_cmd_data = MFS_FSM_CMD_NOP;
+ ctx->recv_mpdu.rx_params.mfs_cmd_mme = MFS_FSM_CMD_NOP;
+ ctx->recv_mpdu.rx_params.sound = false;
+ ctx->recv_mpdu.rx_params.ble = 0;
+ ctx->recv_mpdu.rx_params.pb_size = pb_size;
+ ctx->recv_mpdu.rx_params.tei = tei;
+ ctx->recv_mpdu.rx_params.cfp = ctx->access.cfp;
+ ctx->recv_mpdu.rx_params.agc_gain = phy_rx_agc_gain (ctx->phy);
+ if (is_sof)
+ {
+ dbg_assert(sof->lid != MAC_LID_NONE);
+ ctx->recv_mpdu.rx_params.lid = sof->lid;
+ ctx->recv_mpdu.rx_params.snid = sof->snid;
+ ctx->recv_mpdu.rx_params.bcast = sof->mcf;
+ ctx->recv_mpdu.rx_params.multi_net_bcast = sof->mnbf;
+ ctx->recv_mpdu.rx_params.eks = sof->eks;
+ ctx->recv_mpdu.rx_params.pending_seg_nb = 0;
+ ctx->recv_mpdu.rx_params.tmi_av = sof->tmi_av;
+ /* Store bbf and mrtlf for RSOF */
+ ctx->recv_mpdu.bbf = (sof->mrtfl > 0);
+ ctx->recv_mpdu.mrtfl = MAC_FL_TO_TCK(((u32)sof->mrtfl));
+ /* TODO no sack in TDMA, care about partial ACK mcast */
+ ctx->recv_mpdu.send_sack = wack && (!ctx->access.cfp
+ || !ctx->recv_mpdu.bbf);
+ }
+ else
+ {
+ dbg_assert(ctx->prep_mpdu.valid);
+ dbg_assert(ctx->prep_mpdu.lid != MAC_LID_NONE);
+ const pbproc_fc_rsof_t *rsof = &fc_av->rsof;
+ ctx->recv_mpdu.rx_params.lid = ctx->prep_mpdu.lid != MAC_LID_NONE ?
+ ctx->prep_mpdu.lid : MAC_LLID_MIN;
+ ctx->recv_mpdu.rx_params.eks = ctx->prep_mpdu.eks;
+ ctx->recv_mpdu.rx_params.snid = rsof->snid;
+ ctx->recv_mpdu.rx_params.bcast = false; /* No bcast while RSOF */
+ ctx->recv_mpdu.rx_params.multi_net_bcast = false; /* Same as bcast */
+ ctx->recv_mpdu.rx_params.pending_seg_nb = rsof->ppb;
+ ctx->recv_mpdu.rx_params.tmi_av = rsof->tmi_av;
+ ctx->recv_mpdu.bbf = false;
+ ctx->recv_mpdu.mrtfl = 0;
+ ctx->recv_mpdu.send_sack = false; /* In next SOF */
+ ctx->recv_mpdu.reduced_ifs = true;
+ }
+#endif
ctx->recv_mpdu.pb_nb = pb_nb;
ctx->recv_mpdu.ack_date = rx_date + ctx->times.pre_fcs_tck + fl_tck;
ctx->recv_mpdu.drop = !nek_ok;
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ if (MAC_TEI_IS_EOC_CCO (ctx->config->tei))
+ pbproc_next_poll_update (ctx, rx_date);
+ else if (ctx->config->tei == sof->dtei)
+ ctx->polled = true;
+#endif
/* Keep a block to store received MPDU parameters. */
pb_t *pool = ctx->rx_pool_head;
ctx->recv_mpdu.rx_desc = (pbproc_rx_desc_t *) pool;
pool = pool->next;
/* Prepare channel data blocks and give them to PB DMA. */
- if (ctx->chandata_data && ctx->chandata_nb && nek_ok && !unassociated)
+ if (ctx->chandata_data && ctx->chandata_nb && nek_ok && !unassociated && pb_nb)
{
uint i;
/* Take from RX pool. */
@@ -311,7 +470,8 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
else
pb_it = pb_nb;
ctx->recv_mpdu.pb_head = pool;
- phy_pbdma_start (ctx->phy, bypass_aes, key, pb_nb, pb_it, &pool->phy_pb,
+ if (pb_nb)
+ phy_pbdma_start (ctx->phy, bypass_aes, key, pb_nb, pb_it, &pool->phy_pb,
&ctx->recv_mpdu.chandata_head->phy_pb.chandata, true);
/* Program VCS. */
pbproc_frda_vcs_restart (ctx);
@@ -319,21 +479,36 @@ pbproc_frda__handle (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof)
if (wack)
{
/* Initialise SACKD. */
- pbproc_frda_sackd_init (ctx, sof);
+ pbproc_frda_sackd_init (ctx, fc_av);
/* Wait. */
pbproc_fsm_change_state (ctx, sack_last_pb
? PBPROC_FSM_STATE_RX_DATA_WACK
: PBPROC_FSM_STATE_RX_DATA_WACK_LAST_PB);
+ if (!pb_nb)
+ {
+ phy_rx_prepare_short (ctx->phy);
+ u32 status_word = 0;
+ ctx->pbdma_status = PHY_PBDMA_STATUS (status_word);
+ pbproc_frda__rx_data_wack_last_pb__pbdma(ctx); /* simulation */
+ }
ctx->stats.rx_data_wack++;
}
else
{
/* Wait end of frame. */
pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_RX_DATA_WOACK);
+
+ if (!pb_nb)
+ {
+ phy_rx_prepare_short (ctx->phy);
+ pbproc_frda__rx_data_woack__pbdma(ctx); /* simulation */
+ }
ctx->stats.rx_data_woack++;
}
+#if !CONFIG_MAC_PBPROC_EOC_FC
/* Signal received traffic. */
GPIO_SET (LED_TRAFFIC, 1);
+#endif
}
void ARCH_ILRAM
@@ -359,12 +534,30 @@ pbproc_frda__rx_data_wack_last_pb__pbdma (pbproc_t *ctx)
{
dbg_claim (ctx);
/* Prepare FC 1.0 in advance. */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ if (ctx->recv_mpdu.send_sack && ctx->recv_mpdu.mpdu_cnt == 0)
+#else
if (ctx->recv_mpdu.mpdu_cnt == 0)
+#endif
pbproc_frda_send_sack_anticip (ctx);
/* Prepare SACKD. */
ctx->recv_mpdu.sackd.any_pb_crc_error =
ctx->recv_mpdu.sackd.any_pb_crc_error
|| ctx->pbdma_status.pb_crc_error;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ if (ctx->recv_mpdu.pb_nb
+ && (ctx->rx_pool_size < CONFIG_MAC_PBPROC_EOC_EXHAUST_THRESHOLD
+ || !blk_slack()))
+ {
+ /* Number of PB's for reception is about to be exhausted,
+ reject all PB-s. */
+ ctx->recv_mpdu.drop = true;
+ ctx->recv_mpdu.sackd.valid = false;
+ ctx->stats.rx_pool_shortage++;
+ PBPROC_TRACE (FRDA_SACK_UNIFORM, PBPROC_FC_SACKI_UNIFORM_ALL_ERROR);
+ }
+ else
+#endif
if (!ctx->recv_mpdu.sackd.any_pb_crc_error)
{
/* All OK, use uniform encoding. */
@@ -401,9 +594,26 @@ pbproc_frda__rx_data_wack_last_pb__pbdma (pbproc_t *ctx)
PBPROC_TRACE (FRDA_SACK_MIXED);
}
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* Check if this is for reverse transmission
+ * else do ordinary sack confirmation, only STA context could use */
+ /* TODO this could be used in both releases, check */
+ if (ctx->recv_mpdu.bbf)
+ {
+ u32 access_date = ctx->recv_mpdu.ack_date + MAC_CF_SOF_RSOF_IFS_TCK;
+ ca_access_reprogram (ctx->ca, access_date, ctx->recv_mpdu.mrtfl,
+ ctx->recv_mpdu.rx_params.lid,
+ ctx->recv_mpdu.rx_params.tei);
+ }
+#endif
+
/* TODO: Handle bidir. */
/* Send SACK if not a burst MPDU. */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ if (ctx->recv_mpdu.send_sack && ctx->recv_mpdu.mpdu_cnt == 0)
+#else
if (ctx->recv_mpdu.mpdu_cnt == 0)
+#endif
pbproc_frda_send_sack (ctx);
/* Unchain and give received frame to upper layer. */
pbproc_frda_commit (ctx);
@@ -429,6 +639,11 @@ static void ARCH_ILRAM
pbproc_frda_commit (pbproc_t *ctx)
{
dbg_claim (ctx);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* early return from empty message */
+ if (ctx->recv_mpdu.pb_nb == 0)
+ return;
+#endif
if (!ctx->recv_mpdu.drop)
{
pbproc_rx_desc_t *rx = ctx->recv_mpdu.rx_desc;
@@ -454,7 +669,11 @@ pbproc_frda_commit (pbproc_t *ctx)
dbg_invalid_ptr (ctx->recv_mpdu.chandata_head);
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+#else
void ARCH_ILRAM
+#endif
pbproc_frda__rx_burst__rx_fc (pbproc_t *ctx, u32 rx_date,
const pbproc_fc_t *fc_av)
{
@@ -463,7 +682,11 @@ pbproc_frda__rx_burst__rx_fc (pbproc_t *ctx, u32 rx_date,
pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+#else
void ARCH_ILRAM
+#endif
pbproc_frda__rx_burst__access (pbproc_t *ctx)
{
dbg_claim (ctx);
@@ -474,19 +697,28 @@ pbproc_frda__rx_burst__access (pbproc_t *ctx)
}
static void ARCH_ILRAM
-pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof)
+pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_t *fc_av)
{
dbg_claim (ctx);
- dbg_claim (sof);
+ dbg_claim (fc_av);
/* Clear current SACKD if this frame is not part of the previous burst. */
bool reinit = false;
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ uint sack_size = PBPROC_FC_SACK_SACKI_BITS;
+#else
+ uint sack_size = PBPROC_FC_SACKI_EOC_RSOF_SIZE; /* pg-SOF/RSOF/SOUND size */
+#endif
+ pbproc_fc_sof_t *sof = (pbproc_fc_sof_t *)&fc_av->sof;
pbproc_sackd_t *sackd = &ctx->recv_mpdu.sackd;
+ /* no burst, always reset sackd fields */
+ #if !CONFIG_MAC_PBPROC_EOC_FC
if (!sackd->valid
|| sackd->tei != sof->stei
|| sackd->lid != sof->lid
|| sackd->bcast != sof->mcf
|| sackd->burst_cnt != sof->burst_cnt
|| sackd->last_mpdu_cnt <= sof->mpdu_cnt)
+ #endif
{
sackd->sackt[0] = PBPROC_FC_SACKT_NOT_RECEIVED;
sackd->sackt[1] = PBPROC_FC_SACKT_NOT_RECEIVED;
@@ -496,37 +728,64 @@ pbproc_frda_sackd_init (pbproc_t *ctx, const pbproc_fc_sof_t *sof)
}
/* Record SACKD parameters. */
sackd->valid = true;
- sackd->tei = sof->stei;
- sackd->lid = sof->lid;
- sackd->bcast = sof->mcf;
- sackd->cfp = sof->cfs;
- sackd->burst_cnt = sof->burst_cnt;
- sackd->last_mpdu_cnt = sof->mpdu_cnt;
+ if (fc_av->generic.dt_av == PBPROC_FC_DT_SOF)
+ {
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ sackd->tei = sof->stei;
+ sackd->cfp = sof->cfs;
+ sackd->burst_cnt = sof->burst_cnt;
+ sackd->last_mpdu_cnt = sof->mpdu_cnt;
+#else
+ sackd->tei = sof->direction?sof->dtei:MAC_TEI_CCO_DEF;
+ sackd->cfp = ctx->access.cfp;
+ sackd->burst_cnt = 0;
+ sackd->last_mpdu_cnt = 0;
+#endif
+ sackd->lid = sof->lid;
+ sackd->bcast = sof->mcf;
+ /* Reply will be RSOF? */
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ sack_size = PBPROC_FC_SACK_SACKI_BITS
+ - (MAC_LID_IS_PLID (sof->lid) ? 4 : 0);
+#endif
+ }
+ else if (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF)
+ {
+ sackd->tei = fc_av->rsof.dtei;
+ sackd->cfp = true; /* TODO check from other place, mpdu */
+ sackd->lid = ctx->prep_mpdu.lid;
+ sackd->bcast = false;
+ sackd->burst_cnt = 0;
+ sackd->last_mpdu_cnt = 0;
+ }
/* Initialise SACKD preparation. */
sackd->any_pb_crc_error = false;
- pbproc_sacki_enc_init (&sackd->sacki_enc,
- PBPROC_FC_SACK_SACKI_BITS
- - (MAC_LID_IS_PLID (sof->lid) ? 4 : 0),
- reinit);
+ pbproc_sacki_enc_init (&sackd->sacki_enc, sack_size, reinit);
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+static void
+#else
static void ARCH_ILRAM
-pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_sof_t *sof,
+#endif
+pbproc_frda_error (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av,
bool wack, uint sacki_uniform)
{
dbg_claim (ctx);
- dbg_claim (sof);
+ dbg_claim (fc_av);
dbg_claim (sacki_uniform < PBPROC_FC_SACKI_UNIFORM_NB);
/* First thing to do: unblock the hardware. */
phy_rx_prepare_short (ctx->phy);
/* ACK date. */
ctx->recv_mpdu.ack_date = rx_date + ctx->times.pre_fcs_tck
- + MAC_FL_TO_TCK (sof->fl_av);
+ + ((fc_av->generic.dt_av == PBPROC_FC_DT_SOF) ?
+ MAC_FL_TO_TCK (fc_av->sof.fl_av) :
+ MAC_FL_TO_TCK (fc_av->rsof.rsof_fl_av));
/* With acknowledge? */
if (wack)
{
/* Prepare SACKD. */
- pbproc_frda_sackd_init (ctx, sof);
+ pbproc_frda_sackd_init (ctx, fc_av);
ctx->recv_mpdu.sackd.sackt[ctx->recv_mpdu.mpdu_cnt] =
PBPROC_FC_SACKT_UNIFORM;
pbproc_sacki_enc_copy (&ctx->recv_mpdu.sackd.sacki_enc,
@@ -624,8 +883,16 @@ pbproc_frda_vcs_restart (pbproc_t *ctx)
if (ctx->recv_mpdu.mpdu_cnt == 0)
{
/* Prepare for next MPDU. */
- ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date
- + ctx->times.pre_fcs_tck + MAC_CIFS_TCK);
+ /* if there is no SACK in tdma use shorter time */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date +
+ ((ctx->recv_mpdu.reduced_ifs) ?
+ MAC_CF_RSOF_SOF_IFS_TCK :
+ ctx->times.pre_fcs_tck + MAC_CIFS_TCK));
+#else
+ ca_access_vcs_restart (ctx->ca, ctx->recv_mpdu.ack_date +
+ ctx->times.pre_fcs_tck + MAC_CIFS_TCK);
+#endif
}
else
{
diff --git a/cesar/mac/pbproc/src/fsm_rx_sound.c b/cesar/mac/pbproc/src/fsm_rx_sound.c
index 7f2cc83846..abd7e3bce9 100644
--- a/cesar/mac/pbproc/src/fsm_rx_sound.c
+++ b/cesar/mac/pbproc/src/fsm_rx_sound.c
@@ -39,6 +39,24 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
{
dbg_claim (ctx);
dbg_claim (sound);
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ uint tei = sound->stei;
+#else
+ uint tei = sound->direction ? sound->dtei : MAC_TEI_CCO_DEF;
+ if (MAC_TEI_IS_EOC_STA (ctx->config->tei))
+ ctx->polled = true;
+#if CONFIG_MAC_COMMON_EOC_SCHED
+ else /* cco */
+ {
+ sta_t *sta = mac_store_sta_get_noref (ctx->store, ctx->prep_mpdu.dtei);
+ if (sta)
+ {
+ sta->empty_poll = 0;
+ sta->poll_time = phy_date ();
+ }
+ }
+#endif
+#endif
/* Update stats. */
ctx->stats.rx_sound++;
/* Get tonemap. */
@@ -85,17 +103,21 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
phy_rx_prepare_sound (ctx->phy, 1, tm->phy_combo_params[pb_size],
tm->gil, symb_nb);
/* Is sound completed? */
- sta_t *sta = mac_store_sta_get (ctx->store, sound->stei);
+ sta_t *sta = mac_store_sta_get (ctx->store, tei);
+ uint sound_frame_counter = 0xFF;
if (sta)
{
if (sta->rx_tonemaps->sound_frame_counter)
sta->rx_tonemaps->sound_frame_counter--;
sound_complete = sta->rx_tonemaps->sound_frame_counter == 0;
+ sound_frame_counter = sta->rx_tonemaps->sound_frame_counter;
blk_release (sta);
}
/* Update stats. */
if (sound_complete)
ctx->stats.rx_sound_complete++;
+ PBPROC_TRACE (SOUND_FRAME_COUNTER, tei, sound_frame_counter,
+ sound_complete);
}
else
{
@@ -110,20 +132,26 @@ pbproc_frso__handle (pbproc_t *ctx, u32 rx_date,
ctx->recv_mpdu.rx_params.beacon_period_start_ntb =
ctx->alloc.beacon_period_start_date + ctx->config->ntb_offset_tck;
ctx->recv_mpdu.rx_params.fl_tck = fl_tck;
- ctx->recv_mpdu.rx_params.tei = sound->stei;
ctx->recv_mpdu.rx_params.lid = sound->lid;
ctx->recv_mpdu.rx_params.snid = sound->snid;
ctx->recv_mpdu.rx_params.bcast = false;
- ctx->recv_mpdu.rx_params.cfp = sound->cfs;
ctx->recv_mpdu.rx_params.multi_net_bcast = false;
ctx->recv_mpdu.rx_params.sound = true;
ctx->recv_mpdu.rx_params.eks = MAC_EKS_CLEAR;
- ctx->recv_mpdu.rx_params.pending_seg_nb = sound->ppb;
ctx->recv_mpdu.rx_params.ble = 0;
ctx->recv_mpdu.rx_params.pb_size = pb_size;
ctx->recv_mpdu.rx_params.tmi_av = mod;
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ ctx->recv_mpdu.rx_params.tei = sound->stei;
ctx->recv_mpdu.rx_params.mpdu_cnt = sound->mpdu_cnt;
ctx->recv_mpdu.rx_params.bdf = sound->bdf;
+ ctx->recv_mpdu.rx_params.cfp = sound->cfs;
+#else
+ ctx->recv_mpdu.rx_params.pending_seg_nb = 0;
+ ctx->recv_mpdu.rx_params.bdf = true;
+ ctx->recv_mpdu.rx_params.cfp = true;
+ ctx->recv_mpdu.rx_params.tei = tei;
+#endif
ctx->recv_mpdu.rx_params.hp10df = false;
ctx->recv_mpdu.rx_params.hp11df = false;
ctx->recv_mpdu.rx_params.mfs_cmd_data = MFS_FSM_CMD_NOP;
@@ -182,6 +210,7 @@ pbproc_frso__rx_sound__pbdma (pbproc_t *ctx)
phy_tx_fc10 (ctx->phy, ctx->recv_mpdu.ack_date, 0);
/* Prepare SOUND acknowledgment. */
pbproc_fc_t fc;
+#if !CONFIG_MAC_PBPROC_EOC_FC
fc.words[0] = BF_FILL (
PBPROC_FC_SOUND_W0,
(DT_AV, PBPROC_FC_DT_SOUND),
@@ -209,6 +238,31 @@ pbproc_frso__rx_sound__pbdma (pbproc_t *ctx)
fc.words[3] = BF_FILL (
PBPROC_FC_SOUND_W3,
(RESERVED2, 0));
+#else
+ fc.words[0] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W0,
+ (DT_AV, PBPROC_FC_DT_SOUND),
+ (ACCESS, false),
+ (SNID, ctx->alloc.snid),
+ (DTEI, MAC_TEI_IS_EOC_CCO(ctx->config->tei)
+ ? ctx->recv_mpdu.rx_params.tei : ctx->config->tei),
+ (FL_AV, 0),
+ (LID, ctx->recv_mpdu.rx_params.lid));
+ fc.words[1] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W1,
+ (SACKT0, PBPROC_FC_SACKT_UNIFORM),
+ (DIRECTION, !MAC_TEI_IS_EOC_CCO(ctx->config->tei)),
+ (PBSZ, false),
+ (SAF, true),
+ (SCF, ctx->recv_mpdu.rx_params.sound_complete),
+ (REQ_TM, 0),
+ (MPDU_CNT, 0),
+ (SACKI0, PBPROC_FC_SACKI_UNIFORM_NOT_AVAILABLE));
+ fc.words[2] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W2,
+ (SACKI1, 0));
+ fc.words[3] = 0;
+#endif
/* Send it. */
phy_tx_param_short (ctx->phy,
PHY_FC_MODE (hybrid, ctx->config->fc_symbols_nb));
@@ -218,16 +272,16 @@ pbproc_frso__rx_sound__pbdma (pbproc_t *ctx)
/* Received frame is given to upper layer in DSR. */
if (ctx->recv_mpdu.chandata_nb)
{
- pbproc_rx_desc_t *rx = ctx->recv_mpdu.rx_desc;
- rx->rx->params = ctx->recv_mpdu.rx_params;
- rx->rx->mfs = NULL;
- rx->rx->mfs_mme = NULL;
- rx->rx->pb_first = NULL;
- rx->rx->pb_last = NULL;
- rx->rx->pb_nb = 0;
- rx->rx->chandata_first = ctx->recv_mpdu.chandata_head;
- rx->rx->chandata_nb = ctx->recv_mpdu.chandata_nb;
- slist_push_back (ctx->commit.rx_, rx);
+ pbproc_rx_t *rx = ctx->recv_mpdu.rx_desc->rx;
+ rx->params = ctx->recv_mpdu.rx_params;
+ rx->mfs = NULL;
+ rx->mfs_mme = NULL;
+ rx->pb_first = NULL;
+ rx->pb_last = NULL;
+ rx->pb_nb = 0;
+ rx->chandata_first = ctx->recv_mpdu.chandata_head;
+ rx->chandata_nb = ctx->recv_mpdu.chandata_nb;
+ slist_push_back (ctx->commit.rx_, ctx->recv_mpdu.rx_desc);
pbproc_fsm_schedule_deferred (ctx);
dbg_invalid_ptr (ctx->recv_mpdu.chandata_head);
}
@@ -235,7 +289,11 @@ pbproc_frso__rx_sound__pbdma (pbproc_t *ctx)
pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+static void
+#else
static void ARCH_ILRAM_PRIO (2)
+#endif
pbproc_frso_vcs_restart (pbproc_t *ctx)
{
dbg_claim (ctx);
diff --git a/cesar/mac/pbproc/src/fsm_top.c b/cesar/mac/pbproc/src/fsm_top.c
index 582d630528..c940cd803a 100644
--- a/cesar/mac/pbproc/src/fsm_top.c
+++ b/cesar/mac/pbproc/src/fsm_top.c
@@ -75,6 +75,7 @@ pbproc_ftop_aifs (pbproc_t *ctx)
&& lesseq_mod2p32 (ctx->detect.beacon_detect_expiration_date,
now))
ctx->detect.beacon_detected = false;
+#if !CONFIG_MAC_PBPROC_EOC_FC
if (ctx->detect.hp10_detected
&& lesseq_mod2p32 (ctx->detect.hp10_detect_date
+ PBPROC_HP_DETECT_DELAY_TCK, now))
@@ -83,6 +84,7 @@ pbproc_ftop_aifs (pbproc_t *ctx)
&& lesseq_mod2p32 (ctx->detect.hp11_detect_date
+ PBPROC_HP_DETECT_DELAY_TCK, now))
ctx->detect.hp11_detected = false;
+#endif
}
void ARCH_ILRAM
@@ -164,6 +166,10 @@ pbproc_ftop__idle__access (pbproc_t *ctx)
if (!ctx->prep_mpdu.valid)
{
PBPROC_TRACE (FTOP_TX_INVALID);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ ca_backoff_deferred (ctx->ca,
+ ctx->access.duration_tck / MAC_SLOT_TCK);
+#endif
ca_access_done (ctx->ca);
ca_access_defer (ctx->ca, ctx->access.access_date);
ctx->stats.tx_invalid++;
diff --git a/cesar/mac/pbproc/src/fsm_tx_data.c b/cesar/mac/pbproc/src/fsm_tx_data.c
index 7b1e6e717a..bffd9c89d0 100644
--- a/cesar/mac/pbproc/src/fsm_tx_data.c
+++ b/cesar/mac/pbproc/src/fsm_tx_data.c
@@ -49,14 +49,23 @@ pbproc_ftda__handle (pbproc_t *ctx)
dbg_claim (ctx);
if (PHY_FC_MODE_IS_HYBRID (ctx->prep_mpdu.fc_mode))
phy_tx_fc10 (ctx->phy, ctx->prep_mpdu.tx_date, ctx->prep_mpdu.fc10);
- phy_pbdma_start (ctx->phy, ctx->prep_mpdu.bypass_aes, ctx->prep_mpdu.nek,
- mpdu->pb_nb_total,
- ctx->prep_mpdu.wack ? 0 : mpdu->pb_nb_total,
- &mpdu->main_head->phy_pb, NULL, false);
- if (mpdu->tmi >= PHY_MOD_ROBO_NB)
- phy_set_tonemap (ctx->phy, ctx->prep_mpdu.tonemap);
- phy_tx_param (ctx->phy, ctx->prep_mpdu.fc_mode,
- ctx->prep_mpdu.phy_combo_params, ctx->prep_mpdu.gil);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ if (mpdu->pb_nb_total)
+#endif
+ {
+ phy_pbdma_start (ctx->phy, ctx->prep_mpdu.bypass_aes,
+ ctx->prep_mpdu.nek, mpdu->pb_nb_total,
+ ctx->prep_mpdu.wack ? 0 : mpdu->pb_nb_total,
+ &mpdu->main_head->phy_pb, NULL, false);
+ if (mpdu->tmi >= PHY_MOD_ROBO_NB)
+ phy_set_tonemap (ctx->phy, ctx->prep_mpdu.tonemap);
+ phy_tx_param (ctx->phy, ctx->prep_mpdu.fc_mode,
+ ctx->prep_mpdu.phy_combo_params, ctx->prep_mpdu.gil);
+ }
+#if CONFIG_MAC_PBPROC_EOC_FC
+ else
+ phy_tx_param_short (ctx->phy, ctx->prep_mpdu.fc_mode);
+#endif
bool prp = ctx->access.prp && !ctx->prep_mpdu.rts_cts;
phy_tx_frame (ctx->phy, ctx->prep_mpdu.tx_date, true, prp,
ctx->prep_mpdu.fc_av.words);
@@ -74,19 +83,33 @@ pbproc_ftda__tx_wait_access_conf__rx_fc (pbproc_t *ctx, u32 rx_date,
dbg_claim (ctx);
/* Update backoff. */
pbproc_backoff_lost (ctx);
+ ctx->stats.tx_data_cancel++;
/* Handle FC. */
pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
+#if !CONFIG_MAC_PBPROC_EOC_FC
/* Now, we have time, cancel transmission. */
pbproc_prep_mpdu_cancel_burst (ctx);
- ctx->stats.tx_data_cancel++;
+#endif
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+#else
void ARCH_ILRAM
+#endif
pbproc_ftda__tx_wait_access_conf__access (pbproc_t *ctx)
{
dbg_claim (ctx);
pbproc_prep_mpdu_cancel_burst (ctx);
+
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* prepare next schedule, start access timer */
+ ca_access_vcs_restart (ctx->ca, phy_date ()
+ + ctx->times.pre_fcs_tck + MAC_CIFS_TCK);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+#else
pbproc_ftop__idle__access (ctx);
+#endif
ctx->stats.prp_lost++;
ctx->stats.tx_data_cancel++;
}
@@ -131,6 +154,7 @@ pbproc_ftda__tx_wait_access_conf__access_conf (pbproc_t *ctx)
}
else
{
+ ctx->prep_mpdu.main_mfs->stats.num_bursts++;
if (ctx->prep_mpdu.wack)
{
/* With ACK. */
@@ -153,17 +177,28 @@ pbproc_ftda__tx_wait_access_conf__access_conf (pbproc_t *ctx)
ctx->stats.tx_data_beacon++;
else
ctx->stats.tx_data_woack++;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* If Short SOF is sent goto tx end, but tx_end is here */
+ if (stats_num_pbs == 0)
+ pbproc_ftda__tx_wait_tx_end__pbdma(ctx);
+#endif
}
- ctx->prep_mpdu.main_mfs->stats.num_bursts++;
}
+
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* in EoC it is possible to prematurely ack prep_mpdu, short msgs */
+ if (ctx->prep_mpdu.valid)
+#endif
/* Update link stats. */
- ctx->prep_mpdu.main_mfs->stats.num_mpdus++;
- ctx->prep_mpdu.main_mfs->stats.num_pbs += stats_num_pbs;
- /* If there is a pending SPOC update and enough time, program it. */
- if (ctx->prep_mpdu.ifs_tck >= PHY_PREPARE_DELAY_TCK)
- pbproc_spoc_schedule_update (ctx, ctx->prep_mpdu.tx_date
- + ctx->prep_mpdu.flp_tck
- - ctx->prep_mpdu.ifs_tck);
+ {
+ ctx->prep_mpdu.main_mfs->stats.num_mpdus++;
+ ctx->prep_mpdu.main_mfs->stats.num_pbs += stats_num_pbs;
+ /* If there is a pending SPOC update and enough time, program it. */
+ if (ctx->prep_mpdu.ifs_tck >= PHY_PREPARE_DELAY_TCK)
+ pbproc_spoc_schedule_update (ctx, ctx->prep_mpdu.tx_date
+ + ctx->prep_mpdu.flp_tck
+ - ctx->prep_mpdu.ifs_tck);
+ }
}
void ARCH_ILRAM
@@ -195,6 +230,9 @@ pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
else
{
//handle_access ();
+ ca_access_vcs_restart (ctx->ca, rx_date + ctx->times.pre_fcs_tck
+ + MAC_CIFS_TCK);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
}
ctx->stats.tx_data_wack_ack++;
}
@@ -209,20 +247,35 @@ pbproc_ftda__tx_wait_sackd__rx_fc (pbproc_t *ctx, u32 rx_date,
}
else
#endif
+#if !CONFIG_MAC_PBPROC_EOC_FC
{
pbproc_prep_mpdu_cancel_burst (ctx);
ctx->stats.tx_data_wack_noack++;
}
+#endif
pbproc_fhfc_handle_fc (ctx, rx_date, fc_av);
}
}
-
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+#else
void ARCH_ILRAM
+#endif
pbproc_ftda__tx_wait_sackd__access (pbproc_t *ctx)
{
dbg_claim (ctx);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ pbproc_prep_mpdu_access_track (ctx);
+#endif
pbproc_prep_mpdu_cancel_burst (ctx);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* prepare next schedule, start access timer */
+ ca_access_vcs_restart (ctx->ca, phy_date ()
+ + ctx->times.pre_fcs_tck + MAC_CIFS_TCK);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+#else
pbproc_ftop__idle__access (ctx);
+#endif
ctx->stats.tx_data_wack_noack++;
}
@@ -239,7 +292,11 @@ pbproc_ftda__tx_wait_tx_end__pbdma (pbproc_t *ctx)
pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+#else
void ARCH_ILRAM
+#endif
pbproc_ftda__tx_burst__access_conf (pbproc_t *ctx)
{
dbg_claim (ctx);
diff --git a/cesar/mac/pbproc/src/fsm_tx_sound.c b/cesar/mac/pbproc/src/fsm_tx_sound.c
index 4308b71749..98b05b6679 100644
--- a/cesar/mac/pbproc/src/fsm_tx_sound.c
+++ b/cesar/mac/pbproc/src/fsm_tx_sound.c
@@ -62,8 +62,13 @@ pbproc_ftso__tx_sound_wait_ack__rx_fc (pbproc_t *ctx, u32 rx_date,
&& fc_av->generic.access == false
&& fc_av->generic.snid == ctx->alloc.snid
&& fc_av->sound.saf == true
+#if !CONFIG_MAC_PBPROC_EOC_FC
&& fc_av->sound.stei == prep->dtei
&& fc_av->sound.dtei == prep->stei
+#else
+ && ((fc_av->sound.dtei == prep->dtei && fc_av->sound.direction)
+ || (fc_av->sound.dtei == prep->stei && !fc_av->sound.direction))
+#endif
&& less_mod2p32 (rx_date, prep->tx_date + prep->flp_tck
+ MAC_TOLERANCE_TCK))
{
@@ -81,6 +86,12 @@ pbproc_ftso__tx_sound_wait_ack__rx_fc (pbproc_t *ctx, u32 rx_date,
else
{
//handle_access ();
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* prepare next schedule, start access timer */
+ ca_access_vcs_restart (ctx->ca, rx_date + ctx->times.pre_fcs_tck
+ + MAC_CIFS_TCK);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+#endif
}
/* Update stats. */
ctx->stats.tx_sound_ack++;
@@ -98,16 +109,30 @@ pbproc_ftso__tx_sound_wait_ack__rx_fc (pbproc_t *ctx, u32 rx_date,
}
}
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+#else
void ARCH_ILRAM_PRIO (2)
+#endif
pbproc_ftso__tx_sound_wait_ack__access (pbproc_t *ctx)
{
dbg_claim (ctx);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ pbproc_prep_mpdu_access_track (ctx);
+#endif
/* Cancel transmission. */
pbproc_prep_mpdu_sound_ack (ctx, false);
/* Update backoff. */
pbproc_backoff_lost (ctx);
/* Handle ACCESS. */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* prepare next schedule, start access timer */
+ ca_access_vcs_restart (ctx->ca, phy_date () + ctx->times.pre_fcs_tck
+ + MAC_CIFS_TCK);
+ pbproc_fsm_change_state (ctx, PBPROC_FSM_STATE_IDLE);
+#else
pbproc_ftop__idle__access (ctx);
+#endif
/* Update stats. */
ctx->stats.tx_sound_noack++;
}
diff --git a/cesar/mac/pbproc/src/pbproc.c b/cesar/mac/pbproc/src/pbproc.c
index 188be35426..2778ef1a1b 100644
--- a/cesar/mac/pbproc/src/pbproc.c
+++ b/cesar/mac/pbproc/src/pbproc.c
@@ -46,6 +46,14 @@ static bool
pbproc_spoc_update_cb (void *user);
/**
+ * Update SPOC, triggered by extra interrupt.
+ * \param user user data, pbproc context
+ * \return true to request a DSR
+ */
+static bool
+pbproc_spoc_update_cb (void *user);
+
+/**
* Deferred handler, commit beacons and MPDU to upper layers.
* \param ctx pbproc context
*/
@@ -53,8 +61,9 @@ static void ARCH_ILRAM
pbproc_deferred (pbproc_t *ctx)
{
uint flags;
- u32 budget_date, current_date;
dbg_claim (ctx);
+ u32 budget_date, current_date;
+
if (!slist_empty (ctx->commit.release_))
{
/* Extract to be released PB. */
@@ -69,7 +78,7 @@ pbproc_deferred (pbproc_t *ctx)
current_date = phy_date ();
budget_date = current_date + PBPROC_BUDGET_RX_BEACON_TCK;
while (!slist_empty (ctx->commit.rx_beacon_)
- && less_mod2p32 (current_date, budget_date))
+ && less_mod2p32 (current_date, budget_date))
{
/* Extract beacon. */
flags = arch_isr_lock ();
@@ -81,12 +90,11 @@ pbproc_deferred (pbproc_t *ctx)
PBPROC_TRACE (RX_BEACON_CB);
dbg_claim (ctx->rx_beacon_cb);
ctx->rx_beacon_cb (ctx->user_data, rx_beacon, params);
- /* Watch watch. */
current_date = phy_date ();
}
budget_date = current_date + PBPROC_BUDGET_RX_TCK;
while (!slist_empty (ctx->commit.rx_)
- && less_mod2p32 (current_date, budget_date))
+ && less_mod2p32 (current_date, budget_date))
{
/* Extract MPDU. */
flags = arch_isr_lock ();
@@ -96,11 +104,11 @@ pbproc_deferred (pbproc_t *ctx)
PBPROC_TRACE (RX_CB, rx_desc->rx->pb_nb);
dbg_claim (ctx->rx_cb);
ctx->rx_cb (ctx->user_data, rx_desc);
- /* Watch watch. */
current_date = phy_date ();
}
- if (!slist_empty (ctx->commit.rx_beacon_)
- || !slist_empty (ctx->commit.rx_))
+
+ if (!slist_empty (ctx->commit.rx_)
+ || !slist_empty (ctx->commit.rx_beacon_))
phy_deferred_schedule (ctx->phy);
}
@@ -173,6 +181,7 @@ pbproc_stats_init (pbproc_t *ctx)
PBPROC_STAT (rx_nfu);
PBPROC_STAT (rx_fc_unknown);
PBPROC_STAT (rx_crc_error);
+ PBPROC_STAT (rx_len_err);
PBPROC_STAT (tx_invalid);
PBPROC_STAT (tx_late);
PBPROC_STAT (tx_data);
@@ -254,6 +263,8 @@ pbproc_init (mac_config_t *config, mac_store_t *store)
/* Setup live indicator. */
GPIO_SETUP (LED_PBPROC_ALIVE, GPIO_DIRECTION_OUT);
GPIO_SET (LED_PBPROC_ALIVE, 1);
+ GPIO_SETUP (LED_PBPROC_WORKING, GPIO_DIRECTION_OUT);
+ GPIO_SET (LED_PBPROC_WORKING, 0);
/* All done! */
PBPROC_TRACE (INIT);
return ctx;
@@ -466,4 +477,16 @@ pbproc_backoff_lost (pbproc_t *ctx)
ctx->stats.prp_lost++;
}
}
-
+#if CONFIG_MAC_PBPROC_EOC_FC
+void
+pbproc_parameters_adjust (pbproc_t *ctx, bool adjust)
+{
+ dbg_assert (ctx);
+ /* adjust only non-hybrid time */
+ if (adjust)
+ {
+ ctx->times_array[0].max_fl_tck =
+ ctx->times_array[2].max_fl_tck = MAC_MS_TO_TCK (4);
+ }
+}
+#endif
diff --git a/cesar/mac/pbproc/src/prep_mpdu.c b/cesar/mac/pbproc/src/prep_mpdu.c
index 411ba4707d..52a149b38b 100644
--- a/cesar/mac/pbproc/src/prep_mpdu.c
+++ b/cesar/mac/pbproc/src/prep_mpdu.c
@@ -20,11 +20,15 @@
#include "inc/sacki_dec.h"
#include "inc/mfs.h"
+#include "hal/gpio/gpio.h"
#include <string.h>
/** Number of prepared PB before ACCESS_CONF. */
-#define PBPROC_PB_START_NB 4
+#define PBPROC_PB_START_NB (CONFIG_MAC_PBPROC_EOC_FC ? 16 : 4)
+
+/** Maximum number of transmissions toward STA which does not reply*/
+#define PBPROC_TX_ATTEMPTS_NB 5
/**
* Commit MPDU.
@@ -51,8 +55,10 @@ pbproc_prep_mpdu_commit (pbproc_t *ctx, uint mpdu_count,
* Commit FSM changes.
* \param ctx pbproc context
*/
+#if !CONFIG_MAC_PBPROC_EOC_FC
static void
pbproc_prep_mpdu_commit_fsm (pbproc_t *ctx);
+#endif
/**
* Prepare a SOUND MPDU.
@@ -67,9 +73,10 @@ pbproc_prep_mpdu_sound (pbproc_t *ctx, mfs_tx_t *mfs, uint fl_tck);
* Prepare a SHORT MPDU for burst interruption.
* \param ctx pbproc context
*/
+#if !CONFIG_MAC_PBPROC_EOC_FC
static void
pbproc_prep_mpdu_short (pbproc_t *ctx);
-
+#endif
void
pbproc_prep_mpdu_init (pbproc_t *ctx)
{
@@ -85,7 +92,29 @@ pbproc_prep_mpdu_init (pbproc_t *ctx)
slist_init (prep->main_commit_return_);
}
+/* mfs window_size calculation on tx_side
+ * WARNING: mfs size is already checked against <=0 value.
+ * return value: distance between start PB and end PB in mfs.
+ */
+static inline u16
+pbproc_get_segments_nb (mfs_tx_t *mfs)
+{
+ int distance = mfs->window_size
+ - distance_mod2p16 (mfs->next_ssn, mfs->head->header.ssn)
+ + mfs->seg_nb;
+ dbg_assert (distance < mfs->window_size + MFS_WINDOW_TOLERANCE);
+ /* send at least one segment to other side */
+ if (distance <= 0)
+ return 1;
+ else
+ return (u16)distance;
+}
+
+#if (CONFIG_MAC_PBPROC_EOC_FC)
+void /*ARCH_ILRAM: TODO ugly */
+#else
void ARCH_ILRAM_PRIO (1)
+#endif
pbproc_prep_beacon (pbproc_t *ctx, mfs_tx_t *mfs)
{
ca_access_param_t *access;
@@ -108,10 +137,14 @@ pbproc_prep_beacon (pbproc_t *ctx, mfs_tx_t *mfs)
prep->wack = false;
prep->unassociated = false;
prep->rts_cts = false;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ prep->fc_mode = PHY_FC_MODE (false, ctx->config->fc_symbols_nb);
+#else
+ prep->fc_mode = PHY_FC_MODE (true, ctx->config->fc_symbols_nb);
+#endif
prep->burst_mpdu_nb = 1;
prep->mpdu_count = 0;
prep->current = &prep->mpdu[0];
- prep->fc_mode = PHY_FC_MODE (true, ctx->config->fc_symbols_nb);
prep->sound_reason_code = TONEMAP_SRC_NULL;
prep->bypass_aes = true;
/* Modulation. */
@@ -127,8 +160,12 @@ pbproc_prep_beacon (pbproc_t *ctx, mfs_tx_t *mfs)
+ tm->bits_per_symbol - 1) / tm->bits_per_symbol;
u32 data_tck = MAC_PAYLOAD_TCK (symb_nb, ctx->symbol_tck[tm->gil]);
prep->ifs_tck = MAC_B2BIFS_TCK;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ uint pre_fcs_tck = ctx->times.pre_fcs_tck;
+#else
uint pre_fcs_tck = ctx->times_array[PBPROC_TIMES_ARRAY_INDEX
- (true, MAC_COEXISTENCE_FULL_HYBRID_MODE)].pre_fcs_tck;
+ (true, MAC_COEXISTENCE_FULL_HYBRID_MODE)].pre_fcs_tck;
+#endif
prep->flp_tck = pre_fcs_tck + data_tck + MAC_B2BIFS_TCK;
/* Does it fit? */
if (prep->flp_tck > access->duration_tck)
@@ -187,7 +224,11 @@ pbproc_prep_beacon (pbproc_t *ctx, mfs_tx_t *mfs)
prep->valid = true;
}
+#if (CONFIG_TRACE && CONFIG_MAC_PBPROC_EOC_FC)
+void
+#else
void ARCH_ILRAM
+#endif
pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
{
ca_access_param_t *access;
@@ -210,6 +251,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
access_duration_tck = access->duration_tck;
/* If prepared frame is valid, this is a bursts continuation. */
uint ack_dtei;
+ bool rsof_fc = false, authenticated = false, mcf = false, mnbf = false;
if (!prep->valid)
{
/* Fill easy fields. Work around Intellon behaviour: they do not
@@ -217,14 +259,21 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
prep->dtei = mfs->common.tei;
prep->unassociated = mfs->common.unassociated;
ack_dtei = mfs->common.bcast && !prep->unassociated
- ? ctx->config->partial_ack_tei_default : prep->dtei;
+ ? ctx->config->partial_ack_tei_default : prep->dtei;
+ #if CONFIG_MAC_PBPROC_EOC_FC
+ dbg_claim (access->lid != MAC_LID_NONE || mfs->common.bcast
+ || !access->cfp || ctx->recv_mpdu.bbf);
+ prep->lid = access->lid;
+ #else
prep->lid = mfs->common.lid != MAC_LID_NONE ? mfs->common.lid
- : MAC_LID_NO_DATA;
+ : MAC_LID_NO_DATA;
+ #endif
prep->wack = MAC_TEI_IS_STA (ack_dtei);
prep->fc_mode = PHY_FC_MODE (ctx->alloc.hybrid,
ctx->config->fc_symbols_nb);
prep->stei = (!mfs->common.bcast && prep->unassociated)
- ? 0 : ctx->config->tei;
+ ? MAC_TEI_UNASSOCIATED : ctx->config->tei;
+ prep->rev_flp_tck = 0;
/* Should we use RTS CTS?
* TODO: real test is more complex. */
prep->rts_cts = mfs->common.bcast && ctx->config->rts_broadcast;
@@ -241,6 +290,33 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
{
prep->tx_date = access->access_date;
}
+ #if CONFIG_MAC_PBPROC_EOC_FC
+ rsof_fc = access->cfp && ctx->recv_mpdu.bbf;
+ authenticated = true;
+ mcf = mfs->common.bcast;
+ mnbf = mfs->common.bcast && (mfs->common.mme || prep->unassociated);
+ if (access->duration_tck == 0
+ && access->reverse_duration_tck == 0
+ && MAC_TEI_IS_EOC_CCO(prep->stei))
+ {
+ prep->wack &= !access->cfp;
+ /* prepare last SOF according to rules */
+ if (access->cfp)
+ {
+ prep->dtei = MAC_TEI_BCAST;
+ mcf = mnbf = false;
+ }
+ }
+ /* dont create rsof while in unassoc state.
+ * avoid conflicts with station removal */
+ if (rsof_fc && ctx->config->tei == MAC_TEI_UNASSOCIATED)
+ {
+ /* set fields used in EoC for SACK + bidirectional */
+ ctx->recv_mpdu.bbf = 0;
+ ctx->recv_mpdu.sackd.valid = false;
+ return;
+ }
+ #endif
}
else
{
@@ -268,9 +344,16 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
/* Find tonemap. */
if (MAC_TEI_IS_STA (prep->dtei))
{
+#if CONFIG_MAC_PBPROC_EOC_FC
+ sta_t *sta = mac_store_sta_get_noref (ctx->store, prep->dtei);
+#else
sta_t *sta = mac_store_sta_get (ctx->store, prep->dtei);
+#endif
if (sta)
{
+#if CONFIG_MAC_PBPROC_EOC_FC
+ authenticated = sta->authenticated;
+#endif
tonemaps_t *tms = sta->tx_tonemaps;
uint default_tmi = tms->default_tmi;
if (default_tmi == TONEMAP_INDEX_INITIAL_START)
@@ -279,7 +362,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
sound_reason_code = TONEMAP_SRC_ERROR;
else if (default_tmi == TONEMAP_INDEX_INITIAL_SOUND_COMPLETE)
/* ROBO */;
- else
+ else if (mfs->seg_nb > 0)
{
uint offset_atu = MAC_TCK_TO_ATU (
prep->tx_date + times->pre_fcs_tck
@@ -326,12 +409,21 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
tm = &ctx->config->tonemask_info.tonemap_robo[tmi];
}
}
+#if !CONFIG_MAC_PBPROC_EOC_FC
blk_release (sta);
+#endif
}
}
/* No sound unless a CE is running and data is transfered. */
if (!ctx->chandata_nb || mfs->common.mme)
sound_reason_code = TONEMAP_SRC_NULL;
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* No sound outside TDMA region in EoC, or frame too short, TODO define */
+ if (!access->cfp || access_duration_tck < MAC_MS_TO_TCK(1)
+ || !authenticated || !ctx->config->authenticated
+ || mfs->common.mme)
+ sound_reason_code = TONEMAP_SRC_NULL;
+#endif
/* Prepare parameters. */
phy_gil_t previous_gil = prep->gil;
prep->phy_combo_params = tm->phy_combo_params[PHY_PB_SIZE_520];
@@ -359,6 +451,14 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
}
else
{
+ /* Early return if no segments (can be -1 if tail is currently
+ * extracted). */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ if (mfs->seg_nb > 0)
+ max_seg_nb = MIN (mfs->seg_nb, pbproc_get_segments_nb (mfs));
+ else
+ max_seg_nb = 0;
+#else
if (mfs->ca_state == CA_MFS_STATE_REMOVED)
max_seg_nb = 0;
else if (mfs->fsm_state == MFS_FSM_CMD_RE_SYNC
@@ -367,7 +467,10 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
else
max_seg_nb = MIN (mfs->seg_nb, (int) (mfs->window_size
- mfs->holes_seg_nb - prep->burst_seg_nb));
+#endif
}
+
+#if !CONFIG_MAC_PBPROC_EOC_FC
/* Early return if no segments. */
if (!max_seg_nb)
{
@@ -375,6 +478,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
pbproc_prep_mpdu_short (ctx);
return;
}
+#endif
bits_per_pb = tm->bits_per_pb[PHY_PB_SIZE_520];
/* Do not put more than one segment in the last symbol. Add one symbol if
* this arise. */
@@ -442,6 +546,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
uint data_tck, rifs_tck;
uint symb_nb = ((max_seg_nb + seg_nb_pending) * bits_per_pb
+ tm->bits_per_symbol - 1) / tm->bits_per_symbol;
+ uint symb_nb_orig = symb_nb; /* prevent send empty sound frame */
if (symb_nb > 2)
{
data_tck = MAC_PAYLOAD_TCK (symb_nb, ctx->symbol_tck[tm->gil]);
@@ -461,6 +566,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
{
data_tck = 0;
rifs_tck = MAC_RIFS_DEFAULT_TCK;
+ symb_nb = 3; /* Fake for reception, no data in frame */
}
/* Bursts heuristic. */
if (!prep->valid)
@@ -469,6 +575,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
&& symb_nb >= 2
&& tmi >= PHY_MOD_ROBO_NB
&& old_max_seg_nb > max_seg_nb + 1
+ && !CONFIG_MAC_PBPROC_EOC_FC
&& data_tck + 25 * 2000 < access_duration_tck)
{
dbg_claim (sound_reason_code == TONEMAP_SRC_NULL);
@@ -495,6 +602,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
mpdu->tmi = tmi;
prep->ifs_tck = rifs_tck;
prep->flp_tck = times->pre_fcs_tck + data_tck + rifs_tck;
+#if !CONFIG_MAC_PBPROC_EOC_FC
/* Early return if no symbol. */
if (max_seg_nb == 0)
{
@@ -502,6 +610,20 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
pbproc_prep_mpdu_short (ctx);
return;
}
+#else
+ /* Early return if no symbol only in CSMA region or bcast mfs,
+ * else wait for RSOF */
+ if (max_seg_nb == 0 && !access->cfp)
+ return;
+ /* Again calculate minimal time and decide not to send frame
+ * skip empty SOF where access_duration_tck = 0 TODO */
+ uint sack_tck = !mfs->common.bcast || !access->cfp ? times->sack_tck : 0;
+ if(access_duration_tck && (MAC_DX567_TCK >= tm_data_max_tck
+ || (times->pre_fcs_tck + MAC_DX567_TCK + rifs_av_one_sym_tck
+ + sack_tck > access_duration_tck)))
+ return;
+#endif
+#if !CONFIG_MAC_PBPROC_EOC_FC
/* Prepare RTS FC. */
if (prep->rts_cts)
{
@@ -537,8 +659,9 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
/* Invalid FC 1.0, HP 1.0 stations will defer (20 symbols and ROBO). */
prep->rts_fc10 = 0x200000;
}
- /* Stop here for SOUND. */
- if (sound_reason_code != TONEMAP_SRC_NULL)
+#endif
+ /* Stop here for SOUND, must have enough time (one symbol al least ) */
+ if ((sound_reason_code != TONEMAP_SRC_NULL) && symb_nb_orig)
{
pbproc_prep_mpdu_sound (ctx, mfs, data_tck + rifs_tck);
return;
@@ -549,7 +672,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
{
/* No encryption. */
}
- else if (mfs->common.bcast)
+ else if (mfs->common.bcast && !mfs->common.mme)
{
if (ctx->config->authenticated)
{
@@ -563,7 +686,11 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
}
else if (MAC_TEI_IS_STA (prep->dtei))
{
+#if CONFIG_MAC_PBPROC_EOC_FC
+ sta_t *sta = mac_store_sta_get_noref (ctx->store, prep->dtei);
+#else
sta_t *sta = mac_store_sta_get (ctx->store, prep->dtei);
+#endif
if (sta)
{
if (sta->authenticated)
@@ -577,14 +704,31 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
prep->nek = nek->nek_enc;
}
}
+#if !CONFIG_MAC_PBPROC_EOC_FC
blk_release (sta);
+#endif
+ }
+ }
+#if CONFIG_MAC_PBPROC_EOC_FC
+ /* for rsof keep received key type */
+ if (rsof_fc)
+ {
+ eks = ctx->recv_mpdu.rx_params.eks;
+ if (eks != MAC_EKS_CLEAR)
+ {
+ mac_nek_t *nek =&ctx->config->nek[eks];
+ dbg_assert(eks == nek->eks);
+ prep->nek = nek->nek_enc;
}
}
+#endif
prep->bypass_aes = eks == MAC_EKS_CLEAR;
+ prep->eks = eks; /* Easy life */
// TODO: dbg_assert (mfs->common.mme || !prep->bypass_aes);
/* Data FC. */
prep->main_mfs_cmd = mfs->fsm_state;
prep->main_mfs_rsp = MFS_FSM_RSP_NB;
+#if !CONFIG_MAC_PBPROC_EOC_FC
if (1 /* TODO */)
{
mfs_fsm_cmd_t mfs_cmd_mgmt, mfs_cmd_data;
@@ -638,6 +782,91 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
(MFS_RSP_DATA, MFS_FSM_RSP_ACK), /* TODO */
(BM_SACKI, 0xf)); /* TODO */
}
+#else
+ uint sackt0=PBPROC_FC_SACKT_UNIFORM, sacki0, sacki1=0;
+ if (ctx->recv_mpdu.sackd.valid)
+ {
+ sackt0 = ctx->recv_mpdu.sackd.sackt[0];
+ sacki0 = ctx->recv_mpdu.sackd.sacki_enc.si[0];
+ sacki1 = ctx->recv_mpdu.sackd.sacki_enc.si[1]
+ & BITS_ONES (rsof_fc ? PBPROC_FC_SACKI_EOC_RSOF_LEFT :
+ PBPROC_FC_SACKI_EOC_SOF_LEFT);
+ }
+ else
+ /* Could be also ALL_ERROR */
+ sacki0 = PBPROC_FC_SACKI_UNIFORM_NOT_AVAILABLE;
+
+ /* decision what to choose SOF or RSOF depend on position,
+ * SOF = cco or BCAST/MCAST, RSOF = sta only
+ * prepare RSOF/SOF by EOC specification */
+ if (rsof_fc)
+ {
+ dbg_assert(MAC_TEI_IS_EOC_STA(ctx->config->tei));
+ prep->fc_av.words[0] = BF_FILL (
+ PBPROC_FC_EOC_RSOF_W0,
+ (DT_AV, PBPROC_FC_DT_RSOF),
+ (ACCESS, false),
+ (SNID, ctx->alloc.snid),
+ (DTEI, ctx->config->tei),
+ (RSOF_FL_AV, MAC_TCK_TO_FL (data_tck + rifs_tck)),
+ (NUM_SYM, symb_nb < 3 ? symb_nb : 3),
+ (SACKT0, sackt0));
+ prep->fc_av.words[1] = BF_FILL (
+ PBPROC_FC_EOC_RSOF_W1,
+ (SACKI0, sacki0));
+ prep->fc_av.words[2] = BF_FILL (
+ PBPROC_FC_EOC_RSOF_W2,
+ (SACKI1, sacki1),
+ (TMI_AV, tmi),
+ (BDF, true), /*TODO: status to be added */
+ (PBSZ, false));
+ prep->fc_av.words[3] = BF_FILL (
+ PBPROC_FC_EOC_RSOF_W3,
+ (PPB, pbproc_fc_pbb (mfs->seg_nb - max_seg_nb)));
+ }
+ else
+ {
+ prep->bbf = !mfs->common.bcast
+ && MAC_TEI_IS_EOC_CCO (prep->stei)
+ && access->cfp
+ && access->reverse_duration_tck
+ && MAC_TEI_IS_EOC_STA (ack_dtei);
+ prep->rev_flp_tck = (prep->bbf) ? access->reverse_duration_tck : 0;
+ bool direction = !MAC_TEI_IS_EOC_CCO (ctx->config->tei);
+
+ prep->fc_av.words[0] = BF_FILL (
+ PBPROC_FC_EOC_SOF_W0,
+ (DT_AV, PBPROC_FC_DT_SOF),
+ (ACCESS, false),
+ (SNID, ctx->alloc.snid),
+ (DTEI, direction ? prep->stei : ack_dtei),
+ (LID, access->lid & 0xF),
+ (EKS, eks),
+ (DIRECTION, direction),
+ (PBSZ, false),
+ (NUM_SYM, symb_nb < 3 ? symb_nb : 3),
+ (TMI_AV, tmi),
+ (MCF, mcf));
+ prep->fc_av.words[1] = BF_FILL (
+ PBPROC_FC_EOC_SOF_W1,
+ (FL_AV, MAC_TCK_TO_FL (data_tck + rifs_tck)),
+ (MPDU_CNT, 0),
+ (BURST_CNT, 0),
+ (MRTFL, MAC_TCK_TO_FL(prep->rev_flp_tck)),
+ (MNBF, mnbf),
+ (BBF, prep->bbf),
+ (SACKT0, sackt0));
+ prep->fc_av.words[2] = BF_FILL (
+ PBPROC_FC_EOC_SOF_W2,
+ (SACKI0, sacki0));
+ prep->fc_av.words[3] = BF_FILL (
+ PBPROC_FC_EOC_SOF_W3,
+ (SACKI1, sacki1));
+ }
+ /* Reset dangerous fields */
+ ctx->recv_mpdu.bbf = 0;
+ ctx->recv_mpdu.sackd.valid = false;
+#endif
/* Invalid FC 1.0, HP 1.0 stations will defer (20 symbols and ROBO). */
prep->fc10 = 0x200000;
/* Prepare PB. */
@@ -648,7 +877,7 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
seg_nb_reserved = max_seg_nb - seg_nb;
/* Get head and tail. */
pb_t *seg;
- seg = mfs->head;
+ seg = seg_nb ? mfs->head : 0;
mpdu->main_head = seg;
for (i = 1; i < seg_nb; i++, seg = seg->next)
{
@@ -656,18 +885,20 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
}
mpdu->main_tail = seg;
/* Set Oldest Pending Segment Flag. */
- if (!prep->valid)
+ if (mpdu->main_head && !prep->valid)
mpdu->main_head->header.opsf = true;
/* Change MFS. */
mfs->seg_nb -= max_seg_nb;
- slist_slice (mfs->, seg, bare);
+ if (max_seg_nb)
+ slist_slice (mfs->, seg, bare);
mpdu->main_seg_nb = seg_nb;
prep->burst_seg_nb += seg_nb;
prep->main_seg_nb_reserved = seg_nb_reserved;
/* Prepare PB chain, simple one. */
mpdu->pb_nb_total = max_seg_nb + seg_nb_pending;
/* Loop over the last PB, PBDMA null PB is not working. */
- mpdu->main_tail->next = mpdu->main_tail;
+ if (mpdu->main_tail)
+ mpdu->main_tail->next = mpdu->main_tail;
/* Ok, ready to go! */
if (!prep->valid)
{
@@ -675,6 +906,14 @@ pbproc_prep_mpdu (pbproc_t *ctx, mfs_tx_t *mfs)
blk_addref (mfs);
prep->valid = true;
}
+ #if CONFIG_MAC_PBPROC_EOC_FC
+ {
+ if (mpdu->main_seg_nb)
+ GPIO_SET (LED_TRAFFIC, 1);
+ else
+ GPIO_SET (LED_TRAFFIC, 0);
+ }
+ #endif
}
static void __attribute__ ((noinline))
@@ -709,9 +948,22 @@ pbproc_prep_mpdu_chain (pbproc_t *ctx)
pbproc_prep_mpdu_single_t *mpdu = prep->current;
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
+#if !CONFIG_MAC_PBPROC_EOC_FC
dbg_claim_ptr (mpdu->main_head);
dbg_claim_ptr (mpdu->main_tail);
dbg_claim (mpdu->main_seg_nb);
+#else
+ if (mpdu->main_seg_nb)
+ {
+ dbg_claim_ptr (mpdu->main_head);
+ dbg_claim_ptr (mpdu->main_tail);
+ }
+ else
+ {
+ dbg_claim (!mpdu->main_head);
+ dbg_claim (!mpdu->main_tail);
+ }
+#endif
/* Already chained? */
if (prep->main_seg_nb_reserved != 0)
{
@@ -759,7 +1011,6 @@ pbproc_prep_mpdu_chain (pbproc_t *ctx)
pbproc_handle_expiration (ctx);
}
}
-
void ARCH_ILRAM
pbproc_prep_mpdu_cancel_burst (pbproc_t *ctx)
{
@@ -785,15 +1036,27 @@ pbproc_prep_mpdu_cancel (pbproc_t *ctx, uint mpdu_count)
pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
+#if !CONFIG_MAC_PBPROC_EOC_FC
dbg_claim_ptr (mpdu->main_head);
dbg_claim_ptr (mpdu->main_tail);
- dbg_claim (mpdu->main_seg_nb);
+ dbg_claim (mpdu->main_seg_nb); /* possible on EoC */
+#else
+ if (mpdu->main_seg_nb)
+ {
+ dbg_claim_ptr (mpdu->main_head);
+ dbg_claim_ptr (mpdu->main_tail);
+ }
+ else
+ {
+ dbg_claim (!mpdu->main_head);
+ dbg_claim (!mpdu->main_tail);
+ }
+#endif
/* Commit. */
pbproc_prep_mpdu_commit (ctx, mpdu_count, NULL, NULL,
mpdu->main_head, mpdu->main_tail,
mpdu->main_seg_nb);
}
-
void ARCH_ILRAM
pbproc_prep_mpdu_ack_all_burst (pbproc_t *ctx)
{
@@ -819,11 +1082,30 @@ pbproc_prep_mpdu_ack_all (pbproc_t *ctx, uint mpdu_count)
pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
+#if !CONFIG_MAC_PBPROC_EOC_FC
dbg_claim_ptr (mpdu->main_head);
dbg_claim_ptr (mpdu->main_tail);
dbg_claim (mpdu->main_seg_nb);
dbg_claim (prep->main_seg_nb_reserved == 0);
dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
+#else
+ if (mpdu->main_seg_nb)
+ {
+ dbg_claim_ptr (mpdu->main_head);
+ dbg_claim_ptr (mpdu->main_tail);
+ }
+ else
+ {
+ dbg_claim (!mpdu->main_head);
+ dbg_claim (!mpdu->main_tail);
+ }
+ dbg_claim (prep->main_seg_nb_reserved == 0);
+ dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
+#endif
+#if CONFIG_MAC_COMMON_EOC_MFS
+ if (prep->wack)
+ prep->main_mfs->no_reply_count = 0;
+#endif
/* Commit. */
pbproc_prep_mpdu_commit (ctx, mpdu_count,
mpdu->main_head, mpdu->main_tail,
@@ -842,11 +1124,29 @@ pbproc_prep_mpdu_ack_bitmap (pbproc_t *ctx, uint mpdu_count,
pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
+#if !CONFIG_MAC_PBPROC_EOC_FC
dbg_claim_ptr (mpdu->main_head);
dbg_claim_ptr (mpdu->main_tail);
dbg_claim (mpdu->main_seg_nb);
dbg_claim (prep->main_seg_nb_reserved == 0);
dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
+#else
+ if (mpdu->main_seg_nb)
+ {
+ dbg_claim_ptr (mpdu->main_head);
+ dbg_claim_ptr (mpdu->main_tail);
+ }
+ else
+ {
+ dbg_claim (!mpdu->main_head);
+ dbg_claim (!mpdu->main_tail);
+ }
+#endif
+ dbg_claim (prep->main_seg_nb_reserved == 0);
+ dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
+#if CONFIG_MAC_COMMON_EOC_MFS
+ prep->main_mfs->no_reply_count = 0;
+#endif
/* Read bitmap and collect acknowledged PB. */
uint bmpw = 0;
u32 bmp0 = 0;
@@ -969,11 +1269,30 @@ pbproc_prep_mpdu_ack_encoded (pbproc_t *ctx, uint mpdu_count,
pbproc_prep_mpdu_single_t *mpdu = &prep->mpdu[mpdu_count];
dbg_claim (prep->valid);
dbg_claim_ptr (prep->main_mfs);
+#if !CONFIG_MAC_PBPROC_EOC_FC
+
dbg_claim_ptr (mpdu->main_head);
dbg_claim_ptr (mpdu->main_tail);
dbg_claim (mpdu->main_seg_nb);
dbg_claim (prep->main_seg_nb_reserved == 0);
dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
+#else
+ if (mpdu->main_seg_nb)
+ {
+ dbg_claim_ptr (mpdu->main_head);
+ dbg_claim_ptr (mpdu->main_tail);
+ }
+ else
+ {
+ dbg_claim (!mpdu->main_head);
+ dbg_claim (!mpdu->main_tail);
+ }
+ dbg_claim (prep->main_seg_nb_reserved == 0);
+ dbg_claim (mpdu->pb_nb_total >= mpdu->main_seg_nb);
+#endif
+#if CONFIG_MAC_COMMON_EOC_MFS
+ prep->main_mfs->no_reply_count = 0;
+#endif
/* Uncompress. */
pbproc_prep_mpdu_ack_encoded_t enc =
{
@@ -1097,7 +1416,7 @@ pbproc_prep_mpdu_ack (pbproc_t *ctx, const uint sackt[],
pbproc_prep_mpdu_commit_burst (ctx);
}
-void ARCH_ILRAM
+void /*ARCH_ILRAM*/
pbproc_prep_mpdu_handle_sack (pbproc_t *ctx, const pbproc_fc_t *fc)
{
dbg_claim (ctx);
@@ -1148,6 +1467,7 @@ pbproc_prep_mpdu_commit (pbproc_t *ctx, uint mpdu_count,
dbg_claim (prep->valid);
mfs_tx_t *mfs = prep->main_mfs;
/* Release acknowledged PB in DSR. */
+
if (release_head)
{
slist_push_back_range (ctx->commit.release_,
@@ -1237,7 +1557,105 @@ pbproc_prep_mpdu_commit_fsm (pbproc_t *ctx)
}
}
-void ARCH_ILRAM
+#if CONFIG_MAC_PBPROC_EOC_FC
+static inline void
+pbproc_prep_mpdu_reassembly_ack_ (const pbproc_fc_t * fc_av,
+ uint st[4], pbproc_sacki_dec_t * sacki_dec)
+{
+ uint sackt0 = PBPROC_FC_SACKT_NOT_RECEIVED, si[3] = {0, 0, 0}, sil = 0;
+ /* Compute bitmap and size */
+ switch(fc_av->generic.dt_av)
+ {
+ case PBPROC_FC_DT_SOF:
+ sackt0 = fc_av->sof.sackt0;
+ si[0] = fc_av->sof.sacki0;
+ si[1] = fc_av->sof.sacki1;
+ sil = PBPROC_FC_SACKI_EOC_SOF_SIZE;
+ break;
+ case PBPROC_FC_DT_RSOF:
+ sackt0 = fc_av->rsof.sackt0;
+ si[0] = fc_av->rsof.sacki0;
+ si[1] = fc_av->rsof.sacki1;
+ sil = PBPROC_FC_SACKI_EOC_RSOF_SIZE;
+ break;
+ case PBPROC_FC_DT_SOUND:
+ sackt0 = fc_av->sound.sackt0;
+ si[0] = fc_av->sound.sacki0
+ | (fc_av->sound.sacki1 << PBPROC_FC_SACKI_EOC_SOUND_LEFT);
+ si[1] = fc_av->sound.sacki1 >> (32 - PBPROC_FC_SACKI_EOC_SOUND_LEFT);
+ sil = PBPROC_FC_SACKI_EOC_SOUND_SIZE;
+ break;
+ default:
+ /* TODO Error handling */
+ break;
+ }
+ pbproc_sacki_dec_init (sacki_dec, si[0], si[1], si[2], sil);
+ st[0] = sackt0;
+ st[1] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ st[2] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ st[3] = PBPROC_FC_SACKT_NOT_RECEIVED;
+}
+
+void
+pbproc_prep_mpdu_reassembly_ack (const pbproc_fc_t * fc_av,
+ uint st[4], pbproc_sacki_dec_t * sacki_dec)
+{
+ pbproc_prep_mpdu_reassembly_ack_ (fc_av, st, sacki_dec);
+}
+/* Handling of SACK field in SOF/RSOF */
+void
+pbproc_prep_mpdu_pg_ack (pbproc_t *ctx, u32 rx_date, const pbproc_fc_t *fc_av)
+{
+ dbg_claim (ctx);
+ /* Place for EOC SACKD encapsulated in next frame
+ * if CCO and RSOF it is our SACKD else if SOF and STA
+ * and valid mpdu that it is our SACKD */
+ if (!(fc_av
+ && fc_av->generic.access == false
+ && fc_av->generic.snid == ctx->alloc.snid
+ && ctx->prep_mpdu.valid
+ && less_mod2p32 (rx_date, ctx->prep_mpdu.tx_date /* TODO chk timeval*/
+ + ctx->prep_mpdu.flp_tck
+ + MAC_FL_TO_TCK (MAC_MAX_FL_MAX_FL))
+ && ((fc_av->generic.dt_av == PBPROC_FC_DT_SOF
+ && MAC_TEI_IS_EOC_STA(ctx->config->tei))
+ || (fc_av->generic.dt_av == PBPROC_FC_DT_SOUND)
+ || (fc_av->generic.dt_av == PBPROC_FC_DT_SACK)
+ || (fc_av->generic.dt_av == PBPROC_FC_DT_RSOF
+ && MAC_TEI_IS_EOC_CCO(ctx->config->tei)))))
+ { /* Time expired, noise on line */
+ if (ctx->prep_mpdu.valid)
+ {
+ pbproc_prep_mpdu_cancel_burst (ctx);
+ ctx->stats.tx_data_cancel++;
+ }
+ return;
+ }
+ pbproc_sacki_dec_t sacki_dec;
+ uint st[4];
+ pbproc_prep_mpdu_reassembly_ack_ (fc_av, st, &sacki_dec);
+ pbproc_prep_mpdu_ack (ctx, st, &sacki_dec);
+}
+
+void
+pbproc_prep_mpdu_access_track (pbproc_t *ctx)
+{
+ dbg_claim (ctx);
+ pbproc_prep_mpdu_t * mpdu = &ctx->prep_mpdu;
+ if (mpdu->valid && !mpdu->main_mfs->common.bcast)
+ {
+ mfs_tx_t * mfs = mpdu->main_mfs;
+ if (++mfs->no_reply_count > PBPROC_TX_ATTEMPTS_NB)
+ {
+ sta_t *sta = mac_store_sta_get_noref (ctx->store, mfs->common.tei);
+ if (sta)
+ sta->poll_off |= 1;
+ }
+ }
+}
+#endif
+
+void /*ARCH_ILRAM*/
pbproc_prep_mpdu_commit_burst (pbproc_t *ctx)
{
dbg_claim (ctx);
@@ -1312,8 +1730,10 @@ pbproc_prep_mpdu_commit_burst (pbproc_t *ctx)
else
mfs->holes_seg_nb = 0;
}
+#if !CONFIG_MAC_PBPROC_EOC_FC
/* Commit FSM change. */
pbproc_prep_mpdu_commit_fsm (ctx);
+#endif
/* Inform CA. */
ca_access_done (ctx->ca);
/* No longer valid. */
@@ -1324,6 +1744,7 @@ pbproc_prep_mpdu_commit_burst (pbproc_t *ctx)
prep->valid = false;
}
+#if !CONFIG_MAC_PBPROC_EOC_FC
static void
pbproc_prep_mpdu_short (pbproc_t *ctx)
{
@@ -1381,7 +1802,7 @@ pbproc_prep_mpdu_short (pbproc_t *ctx)
/* Invalid FC 1.0, HP 1.0 stations will defer (20 symbols and ROBO). */
prep->fc10 = 0x200000;
}
-
+#endif
static void
pbproc_prep_mpdu_sound (pbproc_t *ctx, mfs_tx_t *mfs, uint fl_tck)
{
@@ -1393,6 +1814,7 @@ pbproc_prep_mpdu_sound (pbproc_t *ctx, mfs_tx_t *mfs, uint fl_tck)
/* No encryption. */
prep->bypass_aes = true;
/* SOUND FC. */
+#if !CONFIG_MAC_PBPROC_EOC_FC
prep->fc_av.words[0] = BF_FILL (
PBPROC_FC_SOUND_W0,
(DT_AV, PBPROC_FC_DT_SOUND),
@@ -1420,12 +1842,54 @@ pbproc_prep_mpdu_sound (pbproc_t *ctx, mfs_tx_t *mfs, uint fl_tck)
prep->fc_av.words[3] = BF_FILL (
PBPROC_FC_SOUND_W3,
(RESERVED2, 0));
+#else
+ uint sackt0 = PBPROC_FC_SACKT_UNIFORM;
+ uint sacki0 = PBPROC_FC_SACKI_UNIFORM_NOT_AVAILABLE, sacki1 = 0;
+
+ /* Inject sacki data */
+ if (ctx->recv_mpdu.sackd.valid)
+ {
+ sackt0 = ctx->recv_mpdu.sackd.sackt[0];
+ sacki0 = ctx->recv_mpdu.sackd.sacki_enc.si[0]
+ & BITS_ONES (PBPROC_FC_SACKI_EOC_SOUND_LEFT);
+ sacki1 = (ctx->recv_mpdu.sackd.sacki_enc.si[0] >> PBPROC_FC_SACKI_EOC_SOUND_LEFT)
+ | (ctx->recv_mpdu.sackd.sacki_enc.si[1] << (32 - PBPROC_FC_SACKI_EOC_SOUND_LEFT));
+ }
+
+ prep->fc_av.words[0] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W0,
+ (DT_AV, PBPROC_FC_DT_SOUND),
+ (ACCESS, false),
+ (SNID, ctx->alloc.snid),
+ (DTEI, (MAC_TEI_IS_EOC_STA(ctx->config->tei))
+ ? prep->stei : prep->dtei),
+ (FL_AV, MAC_TCK_TO_FL (fl_tck)),
+ (LID, prep->lid));
+ prep->fc_av.words[1] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W1,
+ (SACKT0, sackt0),
+ (DIRECTION, MAC_TEI_IS_EOC_STA(ctx->config->tei)),
+ (PBSZ, false), /* TODO */
+ (SAF, false),
+ (SCF, false),
+ (REQ_TM, TONEMAP_MAX),
+ (MPDU_CNT, 0), /* TODO */
+ (SACKI0, sacki0));
+ prep->fc_av.words[2] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W2,
+ (SACKI1, sacki1));
+ prep->fc_av.words[3] = BF_FILL (
+ PBPROC_FC_EOC_SOUND_W3,
+ (SRC, prep->sound_reason_code));
+#endif
/* Invalid FC 1.0, HP 1.0 stations will defer (20 symbols and ROBO). */
prep->fc10 = 0x200000;
/* Ok, ready to go! */
prep->main_mfs = mfs;
blk_addref (mfs);
prep->valid = true;
+ /* reset sackd */
+ ctx->recv_mpdu.sackd.valid = false;
}
void
@@ -1481,4 +1945,3 @@ pbproc_prep_mpdu_sound_ack (pbproc_t *ctx, bool scf)
prep->main_mfs = NULL;
prep->valid = false;
}
-
diff --git a/cesar/mac/pbproc/src/trace.c b/cesar/mac/pbproc/src/trace.c
index 21a1e5edb4..7ff65ef026 100644
--- a/cesar/mac/pbproc/src/trace.c
+++ b/cesar/mac/pbproc/src/trace.c
@@ -26,11 +26,15 @@ static int
pbproc_trace_format_fc (char *text, uint text_size, const int *data,
uint size)
{
+#if !CONFIG_MAC_PBPROC_EOC_FC
static const char *mfs_cmd_str[] = { "INIT", "IN_SYNC", "RE_SYNC",
"RELEASE", "NOP", "RES=5", "RES=6", "RES=7" };
+ char mrtfl[sizeof ("bbf mrtfl=0xn ")];
+#else
+ char mrtfl[sizeof ("bbf mrtfl=0xnnn ")];
+#endif
static const char *mfs_rsp_str[] = { "ACK", "NACK", "FAIL", "HOLD" };
static const char *sackt[] = { "m", "mc", "nr", "u" };
- char mrtfl[sizeof ("bbf mrtfl=0xn ")];
char mpdu_cnt[sizeof ("mpdu_cnt=n ")];
char burst_cnt[sizeof ("burst_cnt=n ")];
dbg_assert (size == 4);
@@ -61,6 +65,25 @@ pbproc_trace_format_fc (char *text, uint text_size, const int *data,
dbg_check (snprintf (burst_cnt, sizeof (burst_cnt),
"burst_cnt=%d ", fc->sof.burst_cnt)
< (int) sizeof (burst_cnt));
+#if CONFIG_MAC_PBPROC_EOC_FC
+ r = snprintf (text, text_size,
+ "SOF snid=%s%d dir=%s dtei=0x%02x lid=0x%02x"
+ " %s%seks=%d"
+ " %snum_sym=%d tmi=%d fl_av=%d "
+ "%s%s%s"
+ "sackt0=0x%x sacki0=0x%x, sacki1=0x%x",
+ FC_ACCESS_SNID (fc),
+ fc->sof.direction ? "STA->CCO" : "CCO->STA",
+ fc->sof.dtei, fc->sof.lid,
+ fc->sof.mcf ? "mcf " : "",
+ fc->sof.mnbf ? "mnbf " : "", fc->sof.eks,
+ fc->sof.pbsz ? "pb136 " : "", fc->sof.num_sym,
+ fc->sof.tmi_av, fc->sof.fl_av,
+ fc->sof.mpdu_cnt ? mpdu_cnt : "",
+ fc->sof.burst_cnt ? burst_cnt : "",
+ fc->sof.bbf ? mrtfl : "",
+ fc->sof.sackt0, fc->sof.sacki0, fc->sof.sacki1);
+#else
r = snprintf (text, text_size,
"SOF snid=%s%d stei=0x%02x dtei=0x%02x lid=0x%02x"
" %s%s%s%s%s%seks=%d ppb=0x%02x ble=0x%02x"
@@ -88,6 +111,7 @@ pbproc_trace_format_fc (char *text, uint text_size, const int *data,
mfs_rsp_str[fc->sof.mfs_rsp_mgmt],
mfs_rsp_str[fc->sof.mfs_rsp_data],
fc->sof.bm_sacki);
+#endif
break;
case PBPROC_FC_DT_SACK:
r = snprintf (text, text_size,
@@ -127,6 +151,25 @@ pbproc_trace_format_fc (char *text, uint text_size, const int *data,
dbg_check (snprintf (mpdu_cnt, sizeof (mpdu_cnt), "mpdu_cnt=%d ",
fc->sound.mpdu_cnt)
< (int) sizeof (mpdu_cnt));
+#if CONFIG_MAC_PBPROC_EOC_FC
+ r = snprintf (text, text_size,
+ "SOUND snid=%s%d dir=%s dtei=0x%02x lid=0x%02x"
+ " %s%s%sreq_tm=%d fl_av=%d %s"
+ "src=0x%02x"
+ " sackt0=0x%x sacki0=0x%x, sacki1=0x%x",
+ FC_ACCESS_SNID (fc),
+ fc->sof.direction ? "STA->CCO" : "CCO->STA",
+ fc->sound.dtei,
+ fc->sound.lid,
+ fc->sound.pbsz ? "pb136 " : "",
+ fc->sound.saf ? "saf " : "",
+ fc->sound.scf ? "scf " : "",
+ fc->sound.req_tm, fc->sound.fl_av,
+ fc->sound.mpdu_cnt ? mpdu_cnt : "",
+ fc->sound.src,
+ fc->sound.sackt0, fc->sound.sacki0,
+ fc->sound.sacki1);
+#else
r = snprintf (text, text_size,
"SOUND snid=%s%d stei=0x%02x dtei=0x%02x lid=0x%02x"
" %s%s%s%s%sreq_tm=%d fl_av=%d %sppb=0x%02x"
@@ -141,8 +184,22 @@ pbproc_trace_format_fc (char *text, uint text_size, const int *data,
fc->sound.req_tm, fc->sound.fl_av,
fc->sound.mpdu_cnt ? mpdu_cnt : "", fc->sound.ppb,
fc->sound.src);
+#endif
break;
case PBPROC_FC_DT_RSOF:
+#if CONFIG_MAC_PBPROC_EOC_FC
+ r = snprintf (text, text_size,
+ "RSOF snid=%s%d dtei=0x%02x"
+ " %s%sppb=0x%x"
+ " fl_av=%d tmi=%d num_sym=%d"
+ " sackt0=0x%x sacki0=0x%x sacki1=0x%x",
+ FC_ACCESS_SNID (fc), fc->rsof.dtei,
+ fc->rsof.bdf ? "bdf " : "",
+ fc->rsof.pbsz ? "pb136 " : "", fc->rsof.ppb,
+ fc->rsof.rsof_fl_av, fc->rsof.tmi_av,
+ fc->rsof.num_sym,
+ fc->rsof.sackt0, fc->rsof.sacki0, fc->rsof.sacki1);
+#else
r = snprintf (text, text_size,
"RSOF snid=%s%d dtei=0x%02x"
" %s%s%s%smfs=m%s,%s,%s,m%s sackt=%s,%s,%s,%s"
@@ -165,6 +222,7 @@ pbproc_trace_format_fc (char *text, uint text_size, const int *data,
: fc->rsof.rsof_fl_av * 2 - 0x200, fc->rsof.tmi_av,
fc->rsof.pbsz ? "pb136 " : "",
fc->rsof.num_sym);
+#endif
break;
default:
r = snprintf (text, text_size, "UNKNOWN dt=%d snid=%s%d",
@@ -282,6 +340,10 @@ pbproc_trace_init (pbproc_t *ctx)
TRACE_EVENT (PBPROC_TRACE_FTOP_TX, "ftop tx mfs=%x dtei=%d lid=%d "
"tx_date=%x flp_tck=%d pb_nb=%d"),
TRACE_EVENT (PBPROC_TRACE_FTOP_TX_INVALID, "ftop tx invalid"),
+ TRACE_EVENT (PBPROC_TRACE_FHFC_BEACON, "fhfc beacon"),
+ TRACE_EVENT (PBPROC_TRACE_FHFC_SOF, "fhfc sof dtei=%d lid=%d"),
+ TRACE_EVENT (PBPROC_TRACE_FHFC_RSOF, "fhfc rsof dtei=%d lid=%d"),
+ TRACE_EVENT (PBPROC_TRACE_FHFC_SOUND, "fhfc sound saf=%b dtei=%d lid=%d"),
TRACE_EVENT (PBPROC_TRACE_FRDA_SACK_UNIFORM,
"frda sack uniform sacki=%d"),
TRACE_EVENT (PBPROC_TRACE_FRDA_SACK_MIXED,
@@ -291,6 +353,8 @@ pbproc_trace_init (pbproc_t *ctx)
TRACE_EVENT (PBPROC_TRACE_FTDA_TX_BURST, "ftda tx burst tx_date=%x "
"flp_tck=%d pb_nb=%d"),
TRACE_EVENT (PBPROC_TRACE_PREP_MPDU_COMMIT, "commit return_nb=%d"),
+ TRACE_EVENT (PBPROC_TRACE_SOUND_FRAME_COUNTER, "tei=%x, "
+ "sound_frame_counter=%x, sound_complete=%x"),
};
dbg_assert (ctx);
trace_namespace_init (&namespace, event_ids, COUNT (event_ids));
@@ -300,7 +364,7 @@ pbproc_trace_init (pbproc_t *ctx)
pbproc_trace_format_state);
trace_namespace_register_format (&namespace, 'P',
pbproc_trace_format_pbdma_status);
- trace_buffer_add (&ctx->trace, "pbproc", 8, 4, true, &namespace);
+ trace_buffer_add (&ctx->trace, "pbproc", 8, 256, true, &namespace);
}
void
diff --git a/cesar/mac/pbproc/test/fsm/Makefile b/cesar/mac/pbproc/test/fsm/Makefile
index ee1f48266a..232d57ced5 100644
--- a/cesar/mac/pbproc/test/fsm/Makefile
+++ b/cesar/mac/pbproc/test/fsm/Makefile
@@ -4,5 +4,6 @@ HOST_PROGRAMS = test_fsm
test_fsm_SOURCES = test_fsm.c
test_fsm_MODULES = lib mac/pbproc
mac_pbproc_MODULE_SOURCES = fsm.c
+test_fsm_CONFIG_MODULES = mac/common
include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/pbproc/test/int/maximus-Config b/cesar/mac/pbproc/test/int/maximus-Config
index 7072fca3f1..2f66a11eb2 100644
--- a/cesar/mac/pbproc/test/int/maximus-Config
+++ b/cesar/mac/pbproc/test/int/maximus-Config
@@ -1,2 +1,5 @@
CONFIG_TRACE = y
CONFIG_STATS = n
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_COMMON_EOC_MFS = y
diff --git a/cesar/mac/pbproc/test/int/maximus-Makefile b/cesar/mac/pbproc/test/int/maximus-Makefile
index 9b5189aaa6..f368e526d4 100644
--- a/cesar/mac/pbproc/test/int/maximus-Makefile
+++ b/cesar/mac/pbproc/test/int/maximus-Makefile
@@ -7,6 +7,7 @@ test_pbproc_SOURCES = test_pbproc.c get_seg.c add_seg.c prepare_beacon.c
test_pbproc_MODULES = lib hal host \
mac/pbproc mac/ca mac/common \
mac/ca/test/fcall mac/common/test/fcall
+test_pbproc_CONFIG_MODULES = cp/sta/mgr
VARIANT = maximus
include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/pbproc/test/int/sparc-Config b/cesar/mac/pbproc/test/int/sparc-Config
index c9c832ab38..34df90d773 100644
--- a/cesar/mac/pbproc/test/int/sparc-Config
+++ b/cesar/mac/pbproc/test/int/sparc-Config
@@ -2,4 +2,7 @@ CONFIG_TRACE = y
CONFIG_DEBUG_CLAIM = n
CONFIG_STATS = n
CONFIG_INTERFACE_SNIFFER = n
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_MFS = y
CONFIG_ARCH_ILRAM_PRIO = 0
diff --git a/cesar/mac/pbproc/test/int/sparc-Makefile b/cesar/mac/pbproc/test/int/sparc-Makefile
index 6152f8e490..dd373a0848 100644
--- a/cesar/mac/pbproc/test/int/sparc-Makefile
+++ b/cesar/mac/pbproc/test/int/sparc-Makefile
@@ -12,6 +12,7 @@ test_pbproc_SOURCES = test_pbproc.c get_seg.c add_seg.c prepare_beacon.c \
test_pbproc_MODULES = lib hal hle interface host \
mac/pbproc mac/ca mac/common \
mac/ca/test/fcall mac/common/test/fcall
+test_pbproc_CONFIG_MODULES = cp/sta/mgr
VARIANT = sparc
include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/pbproc/test/int/src/test_pbproc.c b/cesar/mac/pbproc/test/int/src/test_pbproc.c
index 546d7f6aa7..fabfc4c70f 100644
--- a/cesar/mac/pbproc/test/int/src/test_pbproc.c
+++ b/cesar/mac/pbproc/test/int/src/test_pbproc.c
@@ -479,3 +479,12 @@ cyg_user_start (void)
test_pbproc_init (&test_pbproc_global, fcall);
}
+void
+phy_freq_error_set (phy_t *ctx, bool sync, s32 rho_q30) __attribute__ ((weak));
+
+void
+phy_freq_error_set (phy_t *ctx, bool sync, s32 rho_q30)
+{
+ dbg_assert_ptr (ctx);
+ /* Ignored. */
+}
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/Config b/cesar/mac/pbproc/test/pbproc_eoc/Config
new file mode 100644
index 0000000000..a6f5398549
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/Config
@@ -0,0 +1,6 @@
+CONFIG_TRACE = y
+CONFIG_STATS = n
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_EXHAUST_THRESHOLD = 1 \ No newline at end of file
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/Makefile b/cesar/mac/pbproc/test/pbproc_eoc/Makefile
new file mode 100644
index 0000000000..1815b9fd84
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/Makefile
@@ -0,0 +1,13 @@
+BASE = ../../../..
+
+INCLUDES = mac/pbproc/test/pbproc/override mac/pbproc/test/pbproc_eoc
+
+HOST_PROGRAMS = test_pbproc
+test_pbproc_SOURCES = test_pbproc.c prep_mpdu.c tx_data.c tx_sound.c \
+ rx_data.c rx_sound.c \
+ scenario_defs.c ca.c phy.c hal.c utils.c
+test_pbproc_MODULES = lib lib/scenario mac/pbproc mac/common hal/watchdog
+test_pbproc_MODULES_CONFIG = cp/sta/mgr cl
+hal_watchdog_MODULE_SOURCES =
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/inc/scenario_defs.h b/cesar/mac/pbproc/test/pbproc_eoc/inc/scenario_defs.h
new file mode 100644
index 0000000000..d4ad6325f2
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/inc/scenario_defs.h
@@ -0,0 +1,346 @@
+#ifndef inc_scenario_defs_h
+#define inc_scenario_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/scenario_defs.h
+ * \brief Scenario entries definition.
+ * \ingroup test
+ */
+
+#include "inc/test_pbproc.h"
+
+/* Scenario globals. */
+#define SCENARIO_DEFS_GLOBALS \
+ test_pbproc_t *tp;
+
+/* Scenario actions. */
+#define SCENARIO_DEFS_ACTIONS \
+ phy_rx_fc, \
+ phy_access, \
+ phy_access_conf, \
+ phy_pbdma, \
+ phy_deferred, \
+ phy_extra_timer, \
+ pbproc_activate
+
+typedef struct
+{
+ u32 rx_date;
+ u32 rx_sysdate;
+ u32 *fc_av;
+ bool prp_won;
+ uint slot_count;
+ u32 fc10;
+} scenario_action_phy_rx_fc_t;
+
+void
+scenario_action_phy_rx_fc_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+typedef struct
+{
+ mfs_tx_t *mfs;
+ ca_access_param_t *access_param;
+ bool prp_won;
+ uint slot_count;
+ uint delay_tck;
+} scenario_action_phy_access_t;
+
+void
+scenario_action_phy_access_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+typedef scenario_empty_t scenario_action_phy_access_conf_t;
+
+void
+scenario_action_phy_access_conf_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+typedef struct
+{
+ bool pb_null;
+ bool pb_crc_error;
+ bool pb_it;
+ bool end_rx_pb;
+ bool end_tx_pb;
+ bool end_chandata;
+ uint null_pb_index;
+ u32 *crc_bitmap;
+ uint crc_bitmap_bits;
+} scenario_action_phy_pbdma_t;
+
+void
+scenario_action_phy_pbdma_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+typedef scenario_empty_t scenario_action_phy_deferred_t;
+
+void
+scenario_action_phy_deferred_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+typedef scenario_empty_t scenario_action_phy_extra_timer_t;
+
+void
+scenario_action_phy_extra_timer_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+typedef struct
+{
+ bool flag;
+} scenario_action_pbproc_activate_t;
+
+void
+scenario_action_pbproc_activate_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+/* Scenario events. */
+#define SCENARIO_DEFS_EVENTS \
+ phy_prepare, \
+ phy_deferred_schedule, \
+ phy_set_tonemap, \
+ phy_freq_error_set, \
+ phy_tx_fc10, \
+ phy_tx_param, \
+ phy_tx_param_short, \
+ phy_tx_param_sound, \
+ phy_tx_frame, \
+ phy_tx_prepare, \
+ phy_tx_cancel, \
+ phy_rx_param, \
+ phy_rx_activate, \
+ phy_rx_prepare, \
+ phy_rx_prepare_short, \
+ phy_rx_prepare_sound, \
+ phy_access_timer_cancel, \
+ phy_extra_timer_program, \
+ phy_pbdma_start, \
+ phy_pbdma_update, \
+ phy_pbdma_start_chandata, \
+ phy_spoc_tx_set, \
+ phy_spoc_rx_set, \
+ ca_access_activate, \
+ ca_access_deactivate, \
+ ca_access_hold, \
+ ca_access_vcs_restart, \
+ ca_access_vcs_restart_eifs, \
+ ca_access_program, \
+ ca_access_reprogram, \
+ ca_access_defer, \
+ ca_access_aifs, \
+ ca_access_get_mfs, \
+ ca_access_done, \
+ ca_backoff_deferred, \
+ ca_backoff_success, \
+ ca_backoff_cancel, \
+ pbproc_rx_cb, \
+ pbproc_rx_beacon_cb
+
+typedef struct
+{
+ phy_prepare_type_t type;
+ bool wait;
+} scenario_event_phy_prepare_t;
+
+typedef scenario_empty_t scenario_event_phy_deferred_schedule_t;
+
+typedef scenario_empty_t scenario_event_phy_set_tonemap_t;
+
+typedef struct
+{
+ bool sync;
+ s32 rho_q30;
+} scenario_event_phy_freq_error_set_t;
+
+typedef struct
+{
+ u32 date;
+ u32 fc10;
+} scenario_event_phy_tx_fc10_t;
+
+typedef struct
+{
+ phy_fc_mode_t fc_mode;
+ phy_mod_t mod;
+ phy_fecrate_t fecrate;
+ phy_pb_size_t pb_size;
+ phy_gil_t gil;
+} scenario_event_phy_tx_param_t;
+
+typedef struct
+{
+ phy_fc_mode_t fc_mode;
+} scenario_event_phy_tx_param_short_t;
+
+typedef struct
+{
+ phy_fc_mode_t fc_mode;
+ uint nb_pb;
+ phy_mod_t mod;
+ phy_fecrate_t fecrate;
+ phy_pb_size_t pb_size;
+ phy_gil_t gil;
+} scenario_event_phy_tx_param_sound_t;
+
+typedef struct
+{
+ u32 date;
+ bool want_conf;
+ bool stop_tx_on_prp_lost;
+} scenario_event_phy_tx_frame_t;
+
+typedef scenario_empty_t scenario_event_phy_tx_prepare_t;
+
+typedef scenario_empty_t scenario_event_phy_tx_cancel_t;
+
+typedef struct
+{
+ phy_fc_mode_t fc_mode;
+} scenario_event_phy_rx_param_t;
+
+typedef struct
+{
+ bool now;
+ u32 date;
+ bool pre_detection;
+} scenario_event_phy_rx_activate_t;
+
+typedef struct
+{
+ uint nb_pb;
+ phy_mod_t mod;
+ phy_fecrate_t fecrate;
+ phy_pb_size_t pb_size;
+ phy_gil_t gil;
+ uint symbol_nb;
+ uint tcc_halfit;
+} scenario_event_phy_rx_prepare_t;
+
+typedef scenario_empty_t scenario_event_phy_rx_prepare_short_t;
+
+typedef struct
+{
+ uint nb_pb;
+ phy_mod_t mod;
+ phy_fecrate_t fecrate;
+ phy_pb_size_t pb_size;
+ phy_gil_t gil;
+ uint symbol_nb;
+} scenario_event_phy_rx_prepare_sound_t;
+
+typedef scenario_empty_t scenario_event_phy_access_timer_cancel_t;
+
+typedef struct
+{
+ u32 date;
+} scenario_event_phy_extra_timer_program_t;
+
+typedef struct
+{
+ bool bypass_aes;
+ uint nb_total;
+ uint nb_pb_it;
+ bool chandata;
+ bool now;
+} scenario_event_phy_pbdma_start_t;
+
+typedef struct
+{
+ uint nb_pb_it;
+} scenario_event_phy_pbdma_update_t;
+
+typedef scenario_empty_t scenario_event_phy_pbdma_start_chandata_t;
+
+typedef scenario_empty_t scenario_event_phy_spoc_tx_set_t;
+
+typedef scenario_empty_t scenario_event_phy_spoc_rx_set_t;
+
+typedef struct
+{
+ u32 date;
+ mac_coexistence_mode_t coexistence_mode;
+ u8 snid;
+ bool hybrid;
+ bool merge;
+ uint nek_switch;
+} scenario_event_ca_access_activate_t;
+
+typedef scenario_empty_t scenario_event_ca_access_deactivate_t;
+
+typedef scenario_empty_t scenario_event_ca_access_hold_t;
+
+typedef struct
+{
+ u32 end_date;
+} scenario_event_ca_access_vcs_restart_t;
+
+typedef struct
+{
+ u32 start_date;
+} scenario_event_ca_access_vcs_restart_eifs_t;
+
+typedef struct
+{
+ u32 date;
+} scenario_event_ca_access_program_t;
+
+typedef struct
+{
+ u32 date;
+ uint duration_tck;
+ uint lid;
+ uint tei;
+} scenario_event_ca_access_reprogram_t;
+
+typedef struct
+{
+ u32 date;
+} scenario_event_ca_access_defer_t;
+
+typedef struct
+{
+ mac_coexistence_mode_t coexistence_mode;
+ u8 snid;
+ bool hybrid;
+ bool merge;
+ uint nek_switch;
+} scenario_event_ca_access_aifs_t;
+
+typedef scenario_empty_t scenario_event_ca_access_get_mfs_t;
+
+typedef scenario_empty_t scenario_event_ca_access_done_t;
+
+typedef struct
+{
+ uint slot_count;
+} scenario_event_ca_backoff_deferred_t;
+
+typedef scenario_empty_t scenario_event_ca_backoff_success_t;
+
+typedef scenario_empty_t scenario_event_ca_backoff_cancel_t;
+
+typedef struct
+{
+ uint pb_nb;
+ uint chandata_nb;
+ u32 beacon_period_start_date;
+ uint fl_tck;
+ uint pb_size;
+ uint mpdu_cnt;
+ mfs_fsm_cmd_t mfs_cmd_data;
+ mfs_fsm_cmd_t mfs_cmd_mme;
+ uint duration_tck;
+} scenario_event_pbproc_rx_cb_t;
+
+typedef struct
+{
+ uint duration_tck;
+} scenario_event_pbproc_rx_beacon_cb_t;
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/inc/test_pbproc.h b/cesar/mac/pbproc/test/pbproc_eoc/inc/test_pbproc.h
new file mode 100644
index 0000000000..ee8ebafc1a
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/inc/test_pbproc.h
@@ -0,0 +1,93 @@
+#ifndef inc_test_pbproc_h
+#define inc_test_pbproc_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/test_pbproc.h
+ * \brief PBProc test.
+ * \ingroup test
+ */
+#include "lib/test.h"
+#include "lib/rnd.h"
+#include "mac/common/config.h"
+#include "mac/common/ntb.h"
+#include "mac/common/store.h"
+#include "mac/ca/ca.h"
+#include "mac/pbproc/pbproc.h"
+#include "mac/pbproc/inc/context.h"
+
+/** Default NTB offset value. */
+#define TEST_PBPROC_NTB_OFFSET_TCK 0x12345
+
+/** Date offset for expiration tests. */
+#define TEST_PBPROC_EXPIRATION_DATE_OFFSET 1000000000
+
+/** Test pbproc context. */
+struct test_pbproc_t
+{
+ /** Random context. */
+ lib_rnd_t rnd[1];
+ /** Mac configuration. */
+ mac_config_t config;
+ /** Short network identifier. */
+ u8 snid;
+ /** Mac MFS and STA store. */
+ mac_store_t *store;
+ /** PB Processing context. */
+ pbproc_t *pbproc;
+ /** Channel Access context. */
+ ca_t *ca;
+ /** Recorded stats before test. */
+ pbproc_stat_t recorded_stats;
+};
+typedef struct test_pbproc_t test_pbproc_t;
+
+BEGIN_DECLS
+
+void
+test_pbproc_init (test_pbproc_t *ctx);
+
+/**
+ * Setup allocation in PBProc.
+ * \param ctx test context
+ * \param hybrid whether to use hybrid mode
+ * \param beacon_period_start_date start date of the beacon period
+ *
+ * This is to be done by PBProc on activate or AIFS, but this is a shortcut
+ * for tests.
+ */
+void
+test_pbproc_alloc (test_pbproc_t *ctx, bool hybrid,
+ u32 beacon_period_start_date);
+
+/**
+ * Check stats have been incremented.
+ * \param t test context
+ * \param ctx test pbproc context
+ * \param stats expected stats increment
+ */
+void
+test_pbproc_check_stats_ (test_t t, test_pbproc_t *ctx,
+ const pbproc_stat_t *stats);
+
+#define test_pbproc_check_stats(t, ctx, params...) \
+ test_pbproc_check_stats_ ((t), (ctx), & (pbproc_stat_t) { params })
+
+/**
+ * Reset stats.
+ * \param ctx test pbproc context
+ */
+void
+test_pbproc_check_stats_reset (test_pbproc_t *ctx);
+
+void
+test_pbproc_uninit (test_pbproc_t *ctx);
+
+END_DECLS
+
+#endif /* inc_test_pbproc_h */
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/inc/utils.h b/cesar/mac/pbproc/test/pbproc_eoc/inc/utils.h
new file mode 100644
index 0000000000..ef21f39f16
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/inc/utils.h
@@ -0,0 +1,81 @@
+#ifndef inc_utils_h
+#define inc_utils_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/utils.h
+ * \brief Utilities.
+ * \ingroup test
+ */
+#include "mac/common/mfs.h"
+#include "mac/common/tonemap.h"
+#include "inc/test_pbproc.h"
+
+/** Step between created PBs' expiration date. Needed, because of the hysteresis
+ * offset used in the expiration process, to have some control on the number of
+ * expired PBs. */
+#define UTILS_MFS_EXPIRATION_NTB_STEP PBPROC_EXPIRATION_HYSTERESIS_OFFSET
+
+/** Define interval properties. */
+struct utils_interval_t
+{
+ /** Interval end offset, 0 to stop. */
+ uint end_offset_tck;
+ /** TMI for this interval. */
+ u8 tmi;
+ /** Number of bits in this tonemap if it has to be created, else 0. */
+ uint tm_mod;
+};
+typedef struct utils_interval_t utils_interval_t;
+
+BEGIN_DECLS
+
+mfs_tx_t *
+utils_mfs_tx_prepare (bool bcast, bool mme, uint lid, uint tei, int seg_nb);
+
+mfs_tx_t *
+utils_mfs_tx_holes_prepare (bool bcast, bool mme, uint lid, uint tei,
+ int seg_nb, u64 holes_bmp);
+
+void
+utils_mfs_tx_cleanup (mfs_tx_t *mfs);
+
+tonemap_t *
+utils_sta_prepare_default_tonemap (test_pbproc_t *tp, bool tx, uint tei,
+ uint tmi, uint tm_mod, uint tm_max_fl_tck,
+ uint *dx);
+
+/**
+ * Prepare tonemaps intervals.
+ * \param tp test context
+ * \param tei STA TEI
+ * \param intervals list of intervals to prepare
+ * \param default_tmi new default TMI
+ * \return intervals version
+ *
+ * utils_sta_prepare_default_tonemap should have been called before.
+ */
+uint
+utils_sta_prepare_intervals (test_pbproc_t *tp, uint tei,
+ utils_interval_t *intervals, uint default_tmi);
+
+void
+utils_prepare_encryption (test_pbproc_t *tp, bool encrypted, bool sta_auth,
+ uint tei, uint nek_switch);
+
+void
+utils_delete_mfs_saved(void);
+
+mfs_tx_t *
+utils_mfs_tx_prepare_save (bool bcast, bool mme, uint lid, uint tei,
+ uint seg_nb);
+
+
+END_DECLS
+
+#endif /* inc_utils_h */
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/ca.c b/cesar/mac/pbproc/test/pbproc_eoc/src/ca.c
new file mode 100644
index 0000000000..e5fce901a2
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/ca.c
@@ -0,0 +1,169 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/ca.c
+ * \brief Override CA functions.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "mac/ca/ca.h"
+
+#include "mac/ca/inc/context.h"
+
+#include "lib/scenario/scenario.h"
+#include "inc/utils.h"
+
+ca_t *
+ca_init (phy_t *phy, mac_config_t *config, mac_store_t *store,
+ uint anticipation_tck)
+{
+ static ca_t ca_ctx;
+ ca_t *ctx = &ca_ctx;
+ ctx->mfs = NULL;
+ dbg_assert (anticipation_tck);
+ return ctx;
+}
+
+void
+ca_uninit (ca_t *ctx)
+{
+}
+
+void
+ca_mfs_hold_locked (ca_t *ctx, mfs_tx_t *mfs)
+{
+ dbg_assert (mfs);
+ mfs->ca_state = CA_MFS_STATE_HELD;
+}
+
+const ca_alloc_param_t *
+ca_access_activate (ca_t *ctx, u32 date)
+{
+ scenario_event (ca_access_activate, params);
+ test_fail_unless (date == params->date);
+ ctx->current_allocation_param.coexistence_mode = params->coexistence_mode;
+ ctx->current_allocation_param.snid = params->snid;
+ ctx->current_allocation_param.hybrid = params->hybrid;
+ ctx->current_allocation_param.merge = params->merge;
+ ctx->current_allocation_param.nek_switch = params->nek_switch;
+ ctx->current_allocation_param.end_date = 0x80000000;
+ ctx->current_allocation_param.aifs_date = 0x80000000;
+ return &ctx->current_allocation_param;
+}
+
+void
+ca_access_deactivate (ca_t *ctx)
+{
+ scenario_event (ca_access_deactivate);
+}
+
+void
+ca_access_hold (ca_t *ctx)
+{
+ scenario_event (ca_access_hold);
+}
+
+void
+ca_access_vcs_restart (ca_t *ctx, u32 end_date)
+{
+ scenario_event (ca_access_vcs_restart, params);
+ test_fail_unless (end_date == params->end_date);
+}
+
+void
+ca_access_vcs_restart_eifs (ca_t *ctx, u32 start_date)
+{
+ scenario_event (ca_access_vcs_restart_eifs, params);
+ test_fail_unless (start_date == params->start_date);
+}
+
+void
+ca_access_program (ca_t *ctx, u32 date)
+{
+ scenario_event (ca_access_program, params);
+ test_fail_unless (date == params->date);
+}
+void
+ca_access_reprogram (ca_t *ctx, u32 date, uint duration_tck,
+ uint lid, uint tei)
+{
+ scenario_event (ca_access_reprogram, params);
+ test_fail_unless (date == params->date);
+ test_fail_unless (duration_tck == params->duration_tck);
+ test_fail_unless (lid == params->lid);
+ test_fail_unless (tei == params->tei);
+ ctx->access_param.access_date = date;
+ ctx->access_param.duration_tck = duration_tck;
+ ctx->access_param.reverse_duration_tck = 0;
+ ctx->access_param.prp = false;
+ ctx->access_param.cfp = true;
+ ctx->access_param.lid = lid;
+}
+
+void
+ca_access_defer (ca_t *ctx, u32 date)
+{
+ scenario_event (ca_access_defer, params);
+ test_fail_unless (date == params->date);
+}
+
+const ca_alloc_param_t *
+ca_access_aifs (ca_t *ctx)
+{
+ scenario_event (ca_access_aifs, params);
+ ctx->current_allocation_param.coexistence_mode = params->coexistence_mode;
+ ctx->current_allocation_param.snid = params->snid;
+ ctx->current_allocation_param.hybrid = params->hybrid;
+ ctx->current_allocation_param.merge = params->merge;
+ ctx->current_allocation_param.nek_switch = params->nek_switch;
+ ctx->current_allocation_param.end_date = 0x80000000;
+ ctx->current_allocation_param.aifs_date = 0x80000000;
+ return &ctx->current_allocation_param;
+}
+
+const ca_access_param_t *
+ca_access_get_param (ca_t *ctx)
+{
+ return &ctx->access_param;
+}
+
+mfs_tx_t *
+ca_access_get_mfs (ca_t *ctx)
+{
+ scenario_event (ca_access_get_mfs);
+ return ctx->mfs;
+}
+
+void
+ca_access_done (ca_t *ctx)
+{
+ if (scenario.current)
+ {
+ scenario_event (ca_access_done);
+ }
+}
+
+void
+ca_backoff_deferred (ca_t *ctx, int slot_counter)
+{
+ scenario_event (ca_backoff_deferred, params);
+ test_fail_unless (slot_counter == (int) params->slot_count);
+}
+
+void
+ca_backoff_success (ca_t *ctx)
+{
+ scenario_event (ca_backoff_success);
+}
+
+void
+ca_backoff_cancel (ca_t *ctx)
+{
+ scenario_event (ca_backoff_cancel);
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/hal.c b/cesar/mac/pbproc/test/pbproc_eoc/src/hal.c
new file mode 100644
index 0000000000..0c727a126c
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/hal.c
@@ -0,0 +1,27 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/hal.c
+ * \brief HAL stub.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "hal/watchdog/watchdog.h"
+
+void
+hal_watchdog_activate (uint event, bool active)
+{
+ dbg_claim (event == HAL_WATCHDOG_EVENT_PBPROC);
+}
+
+void
+hal_watchdog_trigger (uint event)
+{
+ dbg_claim (event == HAL_WATCHDOG_EVENT_PBPROC);
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/phy.c b/cesar/mac/pbproc/test/pbproc_eoc/src/phy.c
new file mode 100644
index 0000000000..aa7f3aa01f
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/phy.c
@@ -0,0 +1,363 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/phy.c
+ * \brief Override HAL Phy functions.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "hal/phy/phy.h"
+#include "hal/phy/pbdma.h"
+
+#include "hal/phy/inc/context.h"
+
+#include "lib/scenario/scenario.h"
+
+static phy_t phy_global;
+
+phy_t *
+phy_init (void *user_data, phy_rx_fc_cb_t rx_fc_cb, phy_access_cb_t access_cb,
+ phy_access_conf_cb_t access_conf_cb, phy_pbdma_cb_t pbdma_cb,
+ phy_tx_false_alarm_cb_t tx_false_alarm_cb,
+ phy_deferred_cb_t deferred_cb)
+{
+ phy_t *ctx = &phy_global;
+ ctx->current_date = 0;
+ ctx->user_data = user_data;
+ ctx->rx_fc_cb = rx_fc_cb;
+ ctx->access_cb = access_cb;
+ ctx->access_conf_cb = access_conf_cb;
+ ctx->pbdma_cb = pbdma_cb;
+ ctx->tx_false_alarm_cb = tx_false_alarm_cb;
+ ctx->deferred_cb = deferred_cb;
+ ctx->prp_won = false;
+ ctx->slot_count = 0;
+ ctx->pbdma_nb_total = 0;
+ ctx->pbdma_first_pb = NULL;
+ uint i;
+ for (i = 0; i < COUNT (ctx->tx_fc); i++)
+ ctx->tx_fc[i] = 0;
+ for (i = 0; i < COUNT (ctx->crc_bitmap); i++)
+ ctx->crc_bitmap[i] = 0;
+ return ctx;
+}
+
+void
+phy_uninit (phy_t *ctx)
+{
+}
+
+void
+phy_prepare (phy_t *ctx, phy_prepare_type_t type, bool wait)
+{
+ scenario_event (phy_prepare, params);
+ dbg_assert (ctx);
+ test_fail_unless (type == params->type);
+ test_fail_unless (wait == params->wait);
+}
+
+void
+phy_deferred_schedule (phy_t *ctx)
+{
+ scenario_event (phy_deferred_schedule);
+ dbg_assert (ctx);
+ ctx->dsr_scheduled = true;
+}
+
+u32
+phy_date (void)
+{
+ return phy_global.current_date;
+}
+
+void
+phy_set_tonemask (phy_t *ctx, u32 *tonemask, uint carrier_nb)
+{
+}
+
+void
+phy_set_tonemap (phy_t *ctx, blk_t *tonemap)
+{
+ scenario_event (phy_set_tonemap);
+ /* Test tonemap? */
+}
+
+void
+phy_tx_fc10 (phy_t *ctx, u32 date, u32 fc_10)
+{
+ scenario_event (phy_tx_fc10, params);
+ test_fail_unless (date == params->date);
+ test_fail_unless (fc_10 == params->fc10);
+}
+
+void
+phy_tx_param (phy_t *ctx, phy_fc_mode_t fc_mode, u32 mod_fecrate_pb_size,
+ phy_gil_t gil)
+{
+ phy_mod_t mod = BF_GET (PHY_COMBO_PARAMS__MOD, mod_fecrate_pb_size);
+ phy_fecrate_t fecrate = BF_GET (PHY_COMBO_PARAMS__FECRATE,
+ mod_fecrate_pb_size);
+ phy_pb_size_t pb_size = BF_GET (PHY_COMBO_PARAMS__PB_SIZE,
+ mod_fecrate_pb_size);
+ scenario_event (phy_tx_param, params);
+ test_fail_unless (fc_mode == params->fc_mode);
+ test_fail_unless (mod == params->mod);
+ test_fail_unless (fecrate == params->fecrate);
+ test_fail_unless (pb_size == params->pb_size);
+ test_fail_unless (gil == params->gil);
+}
+
+void
+phy_tx_param_short (phy_t *ctx, phy_fc_mode_t fc_mode)
+{
+ scenario_event (phy_tx_param_short, params);
+ test_fail_unless (fc_mode == params->fc_mode);
+}
+
+void
+phy_tx_param_sound (phy_t *ctx, phy_fc_mode_t fc_mode, uint nb_pb,
+ u32 mod_fecrate_pb_size, phy_gil_t gil)
+{
+ phy_mod_t mod = BF_GET (PHY_COMBO_PARAMS__MOD, mod_fecrate_pb_size);
+ phy_fecrate_t fecrate = BF_GET (PHY_COMBO_PARAMS__FECRATE,
+ mod_fecrate_pb_size);
+ phy_pb_size_t pb_size = BF_GET (PHY_COMBO_PARAMS__PB_SIZE,
+ mod_fecrate_pb_size);
+ scenario_event (phy_tx_param_sound, params);
+ test_fail_unless (fc_mode == params->fc_mode);
+ test_fail_unless (nb_pb == params->nb_pb);
+ test_fail_unless (mod == params->mod);
+ test_fail_unless (fecrate == params->fecrate);
+ test_fail_unless (pb_size == params->pb_size);
+ test_fail_unless (gil == params->gil);
+}
+
+void
+phy_tx_frame (phy_t *ctx, u32 date, bool want_conf, bool stop_tx_on_prp_lost,
+ const u32 fc_av[4])
+{
+ scenario_event (phy_tx_frame, params);
+ test_fail_unless (date == params->date);
+ test_fail_unless (want_conf == params->want_conf);
+ test_fail_unless (stop_tx_on_prp_lost == params->stop_tx_on_prp_lost);
+ ctx->tx_fc[0] = fc_av[0];
+ ctx->tx_fc[1] = fc_av[1];
+ ctx->tx_fc[2] = fc_av[2];
+ ctx->tx_fc[3] = fc_av[3];
+}
+
+void
+phy_tx_prepare (phy_t *ctx)
+{
+ scenario_event (phy_tx_prepare);
+}
+
+void
+phy_tx_cancel (phy_t *ctx)
+{
+ scenario_event (phy_tx_cancel);
+}
+
+void
+phy_rx_param (phy_t *ctx, phy_fc_mode_t fc_mode)
+{
+ scenario_event (phy_rx_param, params);
+ test_fail_unless (fc_mode == params->fc_mode);
+}
+
+void
+phy_rx_activate (phy_t *ctx, bool now, u32 date, bool pre_detection)
+{
+ scenario_event (phy_rx_activate, params);
+ test_fail_unless (now == params->now);
+ test_fail_unless (date == params->date);
+ test_fail_unless (pre_detection == params->pre_detection);
+}
+
+void
+phy_rx_prepare (phy_t *ctx, uint nb_pb, u32 mod_fecrate_pb_size,
+ phy_gil_t gil, uint symbol_nb, uint tcc_halfit)
+{
+ phy_mod_t mod = BF_GET (PHY_COMBO_PARAMS__MOD, mod_fecrate_pb_size);
+ phy_fecrate_t fecrate = BF_GET (PHY_COMBO_PARAMS__FECRATE,
+ mod_fecrate_pb_size);
+ phy_pb_size_t pb_size = BF_GET (PHY_COMBO_PARAMS__PB_SIZE,
+ mod_fecrate_pb_size);
+ scenario_event (phy_rx_prepare, params);
+ test_fail_unless (nb_pb == params->nb_pb);
+ test_fail_unless (mod == params->mod);
+ test_fail_unless (fecrate == params->fecrate);
+ test_fail_unless (pb_size == params->pb_size);
+ test_fail_unless (gil == params->gil);
+ test_fail_unless (symbol_nb == params->symbol_nb);
+ test_fail_unless (tcc_halfit == params->tcc_halfit);
+}
+
+void
+phy_rx_prepare_short (phy_t *ctx)
+{
+ scenario_event (phy_rx_prepare_short);
+}
+
+void
+phy_rx_prepare_sound (phy_t *ctx, uint nb_pb, u32 mod_fecrate_pb_size,
+ phy_gil_t gil, uint symbol_nb)
+{
+ phy_mod_t mod = BF_GET (PHY_COMBO_PARAMS__MOD, mod_fecrate_pb_size);
+ phy_fecrate_t fecrate = BF_GET (PHY_COMBO_PARAMS__FECRATE,
+ mod_fecrate_pb_size);
+ phy_pb_size_t pb_size = BF_GET (PHY_COMBO_PARAMS__PB_SIZE,
+ mod_fecrate_pb_size);
+ scenario_event (phy_rx_prepare_sound, params);
+ test_fail_unless (nb_pb == params->nb_pb);
+ test_fail_unless (mod == params->mod);
+ test_fail_unless (fecrate == params->fecrate);
+ test_fail_unless (pb_size == params->pb_size);
+ test_fail_unless (gil == params->gil);
+ test_fail_unless (symbol_nb == params->symbol_nb);
+}
+
+void
+phy_freq_error_set (phy_t *ctx, bool sync, s32 rho_q30)
+{
+ scenario_event (phy_freq_error_set, params);
+ test_fail_unless (sync == params->sync);
+ test_fail_unless (rho_q30 == params->rho_q30);
+}
+
+u32
+phy_rx_fc10 (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->fc10;
+}
+
+u32
+phy_rx_sysdate (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->rx_sysdate;
+}
+
+void
+phy_access_timer_cancel (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ scenario_event (phy_access_timer_cancel);
+}
+
+void
+phy_extra_timer_init (phy_t *ctx, void *extra_timer_user_data,
+ phy_extra_timer_cb_t extra_timer_cb)
+{
+ dbg_assert (ctx);
+ dbg_assert (extra_timer_user_data == ctx->user_data);
+ ctx->extra_timer_cb = extra_timer_cb;
+}
+
+void
+phy_extra_timer_program (phy_t *ctx, u32 date)
+{
+ dbg_assert (ctx);
+ scenario_event (phy_extra_timer_program, params);
+ test_fail_unless (date == params->date);
+}
+
+void
+phy_access_timer_program (phy_t *ctx, u32 date)
+{
+ dbg_assert (ctx);
+}
+
+uint
+phy_access_backoff_slot_count (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->slot_count;
+}
+
+bool
+phy_access_backoff_prp_won (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ return ctx->prp_won;
+}
+
+void
+phy_pbdma_start (phy_t *ctx, bool bypass_aes, const u32 nek[4], uint nb_total,
+ uint nb_pb_it, phy_pb_t *first_pb,
+ phy_chandata_t *first_chandata, bool now)
+{
+ scenario_event (phy_pbdma_start, params);
+ test_fail_unless (bypass_aes == params->bypass_aes);
+ test_fail_unless (nb_total == params->nb_total);
+ test_fail_unless (nb_pb_it == params->nb_pb_it);
+ test_fail_unless ((first_chandata ? true : false) == params->chandata);
+ test_fail_unless (now == params->now);
+ ctx->pbdma_nb_total = nb_total;
+ ctx->pbdma_first_pb = first_pb;
+}
+
+void
+phy_pbdma_update (phy_t *ctx, uint nb_pb_it)
+{
+ scenario_event (phy_pbdma_update, params);
+ test_fail_unless (nb_pb_it == params->nb_pb_it);
+}
+
+phy_pb_t *
+phy_pbdma_get_tail (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ uint i;
+ phy_pb_t *pb;
+ for (i = 1, pb = ctx->pbdma_first_pb;
+ i < ctx->pbdma_nb_total;
+ i++, pb = PARENT_OF (phy_pb_t, blk, pb->blk.next))
+ ;
+ return pb;
+}
+
+volatile const u32 *
+phy_pbdma_get_crc_bitmap (phy_t *ctx)
+{
+ return ctx->crc_bitmap;
+}
+
+void
+phy_pbdma_start_chandata (phy_t *ctx, phy_chandata_t *first_chandata)
+{
+ scenario_event (phy_pbdma_start_chandata);
+}
+
+void
+phy_spoc_tx_set (phy_t *ctx, phy_spoc_coeff_t *coeff)
+{
+ scenario_event (phy_spoc_tx_set);
+ dbg_assert (ctx);
+ dbg_assert (coeff);
+ dbg_assert (coeff->part2);
+}
+
+void
+phy_spoc_rx_set (phy_t *ctx, phy_spoc_coeff_t *coeff)
+{
+ scenario_event (phy_spoc_rx_set);
+ dbg_assert (ctx);
+ dbg_assert (coeff);
+ dbg_assert (coeff->part2);
+}
+
+u32
+phy_rx_agc_gain (phy_t *ctx)
+{
+ dbg_assert (ctx);
+ return 0;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/prep_mpdu.c b/cesar/mac/pbproc/test/pbproc_eoc/src/prep_mpdu.c
new file mode 100644
index 0000000000..69235e473f
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/prep_mpdu.c
@@ -0,0 +1,1847 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/prep_mpdu.c
+ * \brief PBProc prep_mpdu test.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "inc/test_pbproc.h"
+#include "inc/utils.h"
+
+#include "mac/common/timings.h"
+
+#include "hal/phy/inc/context.h"
+
+/* Maximum number of bits usable in a CRC bitmap. */
+#define PREP_MPDU_TEST_CRC_BITMAP_SIZE 72u
+
+/** Test parameters. */
+struct prep_mpdu_test_t
+{
+ /** Multicast. */
+ bool bcast;
+ /** MME. */
+ bool mme;
+ /** Partial acknowledgement. */
+ bool partial_ack;
+ /** Number of MFS segments. */
+ int mfs_seg_nb;
+ /** Duration of the access, measured as a number of symbol. */
+ uint duration_symb_nb;
+ /** Expected number of symbols. */
+ uint symb_nb;
+ /** Expected total number of segments for the main MFS. */
+ uint main_seg_nb_total;
+ /** Expected pending segments. */
+ uint seg_nb_pending;
+ /** Expected MPDU count (non zero for bursts). */
+ uint mpdu_count;
+ /** If set, CRC checking is done. */
+ bool crc;
+ /** If set (and crc not set), acknowledge all, else cancel
+ * transmission. */
+ bool all_ok;
+ /** If not zero and crc not set, uniform SACK information. */
+ uint sacki;
+ /** Updated default TMI after SACKI handling. */
+ uint tmi_sacki;
+ /** Indicate PBs with bad CRC. */
+ u32 crc_error[3];
+ /** Encoded SACK information, or 0 for bitmap. */
+ u64 encoded_sack;
+ /** Length of encoded SACK (to be eaten). */
+ uint encoded_sack_length;
+ /** Tonemap index. */
+ uint tmi;
+ /** Tonemap updated during transmission (by CE). */
+ uint tmi_update;
+ /** Tonemap number of bits per carrier. */
+ uint tm_mod;
+ /** Maximum frame length limited by the tonemap. */
+ uint tm_max_fl_tck;
+ /** Table of intervals. */
+ utils_interval_t *intervals;
+ /** Used interval. */
+ uint interval;
+ /** Updated interval TMI after SACKI handling. */
+ uint interval_tmi_sacki;
+ /** If not 0, override sound_reason_code. */
+ tonemap_sound_reason_code_t sound_reason_code;
+ /** Wether encryption is done. */
+ bool encrypted;
+ /** True for unassociated TX (unassociated unicast or multi network
+ * broadcast). */
+ bool unassociated;
+ /** Remove the MFS during preparation:
+ * - 1: before first call (obsolete).
+ * - 2: before chaining remaining segments.
+ * - 3: before acknowledge or cancel. */
+ uint remove;
+ /** True to simulate that ACCESS_CONF event has never been received. */
+ bool no_access_conf;
+ /** Sound completed flag. */
+ bool scf;
+ /** Beacon detected. */
+ bool beacon_detected;
+ /** HP 1.0 detected. */
+ bool hp10_detected;
+ /** HP 1.1 detected. */
+ bool hp11_detected;
+ /** Current date for expiration tests. */
+ uint expiration_date;
+ /** Receiver window size. */
+ uint window_size;
+ /** Bitmap used to create holes in the generated MFS. */
+ u64 mfs_holes_bitmap;
+ /* If set, MFS FSM state test is done. */
+ bool mfs_fsm_state_test;
+ /* Expected MFS FSM state after SACK reception. */
+ mfs_fsm_cmd_t expected_mfs_fsm_state;
+ /* for RSOF */
+ bool bbf;
+ /* Piggy back sacki */
+ bool pg_sacki;
+};
+
+#define prep_mpdu_test(t, tp, date, params...) \
+ prep_mpdu_test_f ((t), (tp), (date), \
+ &(struct prep_mpdu_test_t) { params })
+
+void
+prep_mpdu_test_f (test_t t, test_pbproc_t *tp, u32 date,
+ const struct prep_mpdu_test_t *params)
+{
+ uint i;
+ tp->pbproc->config->tei = params->bbf ? 31 : 1;
+ const uint stei = (!params->bcast && params->unassociated
+ ? 0 : tp->config.tei);
+ const uint dtei = (params->bcast ? MAC_TEI_BCAST : params->bbf ? 1 : 31);
+ const uint ack_dtei = params->partial_ack ? 3 : dtei;
+ const uint lid = params->mme ? MAC_LID_NONE : MAC_LID_MIN;
+ const uint fclid = lid;
+ pb_t *seg;
+ test_within (t);
+ uint nack_count;
+ if (!params->crc)
+ nack_count = params->all_ok ? 0 : params->main_seg_nb_total;
+ else
+ {
+ nack_count = 0;
+ for (i = 0; i < COUNT (params->crc_error); i++)
+ {
+ u32 x = params->crc_error[i];
+ nack_count += BITS_ONES_COUNT (x);
+ }
+ nack_count = MIN (params->main_seg_nb_total, nack_count);
+ }
+ uint seg_nb_pending = params->seg_nb_pending;
+ tp->config.partial_ack_tei_default =
+ params->partial_ack || params->unassociated ? 3 : MAC_TEI_BCAST;
+ /* Ask for channel data to enable sound transmission. */
+ u32 chandata_conf[1] = { 0 };
+ pbproc_set_chandata_conf (
+ tp->pbproc, (phy_chandata_conf_t *) chandata_conf, 1, false);
+ /* Prepare tone map. */
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint dx = MAC_DX417_TCK;
+ bool sta_created = false;
+ if (params->tmi != PHY_MOD_ROBO
+ || (params->encrypted && !params->bcast)
+ || params->intervals)
+ {
+ tm = utils_sta_prepare_default_tonemap (tp, true, dtei, params->tmi,
+ params->tm_mod,
+ params->tm_max_fl_tck, &dx);
+ sta_created = true;
+ }
+ uint interval = TONEMAP_INTERVAL_NB;
+ uint intervals_version;
+ if (params->intervals)
+ {
+ intervals_version = utils_sta_prepare_intervals (
+ tp, dtei, params->intervals, PHY_MOD_ROBO);
+ interval = params->interval;
+ }
+ tonemap_sound_reason_code_t sound_reason_code =
+ params->sound_reason_code ? params->sound_reason_code :
+ params->mme ? TONEMAP_SRC_NULL :
+ params->tmi == TONEMAP_INDEX_INITIAL_START ? TONEMAP_SRC_INITIAL :
+ params->tmi == TONEMAP_INDEX_INITIAL_ERROR ? TONEMAP_SRC_ERROR :
+ TONEMAP_SRC_NULL;
+ uint tmi = params->tmi < TONEMAP_INDEX_NB && !sound_reason_code
+ ? params->tmi : PHY_MOD_ROBO;
+ phy_mod_t mod = tmi < PHY_MOD_ROBO_NB ? tmi : PHY_MOD_TM;
+ uint rifs_tck = params->symb_nb == 0 || tmi < PHY_MOD_ROBO_NB
+ ? MAC_RIFS_DEFAULT_TCK : MAC_RIFS_SPC_ANY_TCK;
+ uint eff_rifs_tck = params->mpdu_count ? MAC_BIFS_TCK : rifs_tck;
+ /* Create an MFS. */
+ mfs_tx_t *mfs = utils_mfs_tx_holes_prepare (params->bcast, params->mme, lid,
+ dtei, params->mfs_seg_nb, params->mfs_holes_bitmap);
+ mfs->last_seg_offset = 1;
+ if (params->unassociated)
+ mfs->common.unassociated = true;
+ pb_t *seg_first = mfs->head;
+ /* Setup receiver window size */
+ if (params->window_size)
+ mfs->window_size = mfs_window_size[params->window_size];
+ /* Encrypted? */
+ utils_prepare_encryption (tp, params->encrypted, !params->bcast, dtei, 0);
+ /* Setup an access. */
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 25;
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t *access = &tp->pbproc->access;
+ access->lid = lid;
+ access->access_date = date;
+ access->reverse_duration_tck = 0;
+ access->duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (params->duration_symb_nb, MAC_DX417_TCK)
+ + rifs_tck + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK;
+ bool cfp = (tmi != PHY_MOD_ROBO && params->tm_max_fl_tck) || params->bbf;
+ /* in Eoc sounds in TDMA period */
+ if (sound_reason_code != TONEMAP_SRC_NULL)
+ {
+ /* sound frame in authenticated state cco & sta */
+ cfp = true;
+ tp->config.authenticated = true;
+ sta_t * sta = mac_store_sta_get(tp->store, dtei);
+ if (sta)
+ { /* need authenticated sta to send sound frames */
+ sta->authenticated = true;
+ blk_release (sta);
+ }
+ }
+ access->prp = false;
+ access->cfp = cfp;
+ tp->pbproc->detect.beacon_detected = params->beacon_detected;
+ tp->pbproc->detect.hp10_detected = params->hp10_detected;
+ tp->pbproc->detect.hp11_detected = params->hp11_detected;
+ /* Set the current date for expiration tests. */
+ if (params->expiration_date)
+ tp->pbproc->phy->current_date = params->expiration_date
+ + TEST_PBPROC_EXPIRATION_DATE_OFFSET;
+ else
+ tp->pbproc->phy->current_date = 0;
+ if (params->remove == 1)
+ mfs->ca_state = CA_MFS_STATE_REMOVED;
+ if (params->bbf)
+ {
+ tp->pbproc->recv_mpdu.bbf = true;
+ tp->pbproc->recv_mpdu.rx_params.eks =
+ tp->pbproc->config->nek[tp->pbproc->alloc.nek_switch].eks;
+ }
+ if (params->pg_sacki)
+ {
+ pbproc_sackd_t *sackd = &tp->pbproc->recv_mpdu.sackd;
+ sackd->valid = true;
+ sackd->sackt[0] = PBPROC_FC_SACKT_MIXED;
+ sackd->sackt[1] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ sackd->sackt[2] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ sackd->sackt[3] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ sackd->any_pb_crc_error = true;
+ pbproc_sacki_enc_init (&sackd->sacki_enc, 64, true);
+ pbproc_sacki_enc_copy (&sackd->sacki_enc, params->crc_error, 64);
+ }
+ /* Prepare MPDU. */
+ pbproc_prep_mpdu (tp->pbproc, params->remove != 1 ? mfs : NULL);
+ /* Check result. */
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ if (params->remove != 1)
+ {
+ test_fail_unless (prep->stei == stei);
+ test_fail_unless (prep->dtei == dtei);
+ test_fail_unless (prep->lid == fclid);
+ test_fail_unless (prep->wack
+ == (!params->bcast || params->partial_ack));
+ test_fail_unless (prep->lid == access->lid);
+ test_fail_unless (prep->unassociated == params->unassociated);
+ test_fail_unless (!prep->rts_cts);
+ test_fail_unless (prep->burst_mpdu_nb == params->mpdu_count + 1);
+ test_fail_unless (prep->mpdu_count == params->mpdu_count);
+ test_fail_unless (prep->current == &prep->mpdu[prep->mpdu_count]);
+ test_fail_unless (prep->tx_date == date);
+ }
+ if (sound_reason_code != TONEMAP_SRC_NULL)
+ {
+ test_fail_unless (prep->valid);
+ test_fail_unless (prep->main_mfs == mfs);
+ test_fail_unless (prep->fc_mode == PHY_FC_MODE_AV_1);
+ test_fail_unless (prep->current->tmi == tmi);
+ test_fail_unless (prep->phy_combo_params == PHY_COMBO_PARAMS (
+ mod, tm->fecrate, PHY_PB_SIZE_520));
+ test_fail_unless (prep->gil == tm->gil);
+ test_fail_unless (prep->tonemap == tm->tmdma_desc_head);
+ test_fail_unless (prep->current->interval == interval);
+ test_fail_unless (interval == TONEMAP_INTERVAL_NB
+ || (prep->current->intervals_version
+ == intervals_version));
+ test_fail_unless (prep->sound_reason_code == sound_reason_code);
+ test_fail_unless (prep->current->pb_nb_total == 0);
+ test_fail_unless (prep->current->main_seg_nb == 0);
+ test_fail_unless (prep->main_seg_nb_reserved == 0);
+ test_fail_unless (prep->ifs_tck == eff_rifs_tck);
+ test_fail_unless (prep->flp_tck == MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (params->symb_nb, dx)
+ + eff_rifs_tck);
+ test_fail_unless (prep->bypass_aes);
+ /* Check FC. */
+ pbproc_fc_sound_t fc = prep->fc_av.sound;
+ test_fail_unless (fc.dt_av = PBPROC_FC_DT_SOUND
+ && !fc.access
+ && fc.snid == tp->snid);
+ test_fail_unless (fc.dtei == fc.direction ? dtei : stei);
+ test_fail_unless (fc.lid == access->lid);
+ test_fail_unless (!fc.pbsz);
+ test_fail_unless (!fc.saf);
+ test_fail_unless (!fc.scf);
+ test_fail_unless (fc.req_tm == TONEMAP_MAX);
+ test_fail_unless (fc.fl_av ==
+ MAC_TCK_TO_FL (MAC_PAYLOAD_TCK (params->symb_nb, dx)
+ + eff_rifs_tck));
+ test_fail_unless (fc.mpdu_cnt == params->mpdu_count);
+ test_fail_unless (fc.src == sound_reason_code);
+ test_fail_unless (prep->fc10 == 0x200000);
+ /* Acknowledge preparation. */
+ pbproc_prep_mpdu_sound_ack (tp->pbproc, params->scf);
+ test_fail_unless (!prep->valid);
+ test_fail_unless (!prep->main_mfs);
+ sta_t *sta = mac_store_sta_get (tp->store, dtei);
+ dbg_assert (sta);
+ tonemaps_t *tms = sta->tx_tonemaps;
+ if (!params->scf)
+ {
+ test_fail_unless (tms->default_tmi == params->tmi);
+ }
+ else
+ {
+ if (sound_reason_code == TONEMAP_SRC_INITIAL
+ || sound_reason_code == TONEMAP_SRC_ERROR)
+ {
+ test_fail_unless (tms->default_tmi
+ == TONEMAP_INDEX_INITIAL_SOUND_COMPLETE);
+ }
+ else
+ {
+ test_fail_unless (tms->default_tmi == params->tmi);
+ }
+ if (sound_reason_code == TONEMAP_SRC_INTERVAL_UNAVAILABLE
+ || sound_reason_code == TONEMAP_SRC_INTERVAL_UNUSABLE)
+ {
+ test_fail_unless (
+ tms->intervals->interval[params->interval].tmi
+ == TONEMAP_INDEX_INTERVAL_SOUND_COMPLETE);
+ }
+ }
+ blk_release (sta);
+ }
+ else if (params->main_seg_nb_total == 0)
+ {
+ test_fail_unless (!prep->valid);
+ test_fail_unless (prep->main_mfs == NULL);
+ test_fail_unless (prep->current->main_seg_nb == 0);
+ test_fail_unless (prep->main_seg_nb_reserved == 0);
+ test_fail_unless (prep->current->pb_nb_total == 0);
+ }
+ else
+ {
+ test_fail_unless (prep->valid);
+ test_fail_unless (prep->main_mfs == mfs);
+ test_fail_unless (prep->main_mfs_cmd
+ == (params->bcast ? MFS_FSM_CMD_NOP
+ : MFS_FSM_CMD_INIT));
+ test_fail_unless (prep->main_mfs_rsp == MFS_FSM_RSP_NB);
+ test_fail_unless (prep->fc_mode == PHY_FC_MODE_AV_1);
+ test_fail_unless (prep->current->tmi == tmi);
+ test_fail_unless (prep->phy_combo_params == PHY_COMBO_PARAMS (
+ mod, tm->fecrate, PHY_PB_SIZE_520));
+ test_fail_unless (prep->gil == tm->gil);
+ test_fail_unless (prep->tonemap == tm->tmdma_desc_head);
+ test_fail_unless (prep->current->interval == interval);
+ test_fail_unless (interval == TONEMAP_INTERVAL_NB
+ || (prep->current->intervals_version
+ == intervals_version));
+ test_fail_unless (prep->sound_reason_code == sound_reason_code);
+ test_fail_unless (prep->current->main_head == seg_first);
+ uint main_seg_nb = MIN (params->main_seg_nb_total, 16u);
+ uint main_seg_nb_reserved = params->main_seg_nb_total - main_seg_nb;
+ test_fail_unless (prep->current->main_seg_nb == main_seg_nb);
+ for (seg = seg_first, i = 1; i < main_seg_nb; seg = seg->next, i++)
+ test_fail_unless (seg->header.opsf == (i == 1));
+ test_fail_unless (seg->next == seg);
+ test_fail_unless (seg->header.opsf == (i == 1));
+ test_fail_unless (prep->current->main_tail == seg);
+ test_fail_unless (prep->main_seg_nb_reserved == main_seg_nb_reserved);
+ test_fail_unless (prep->current->pb_nb_total
+ == params->main_seg_nb_total + seg_nb_pending);
+ test_fail_unless (prep->ifs_tck == eff_rifs_tck);
+ test_fail_unless (prep->flp_tck == MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (params->symb_nb, dx)
+ + eff_rifs_tck);
+ if (params->encrypted)
+ {
+ test_fail_if (prep->bypass_aes);
+ test_fail_unless (prep->nek == tp->config.nek[0].nek_enc);
+ }
+ else
+ test_fail_unless (prep->bypass_aes);
+ /* Check FC. */
+ if (prep->fc_av.generic.dt_av == PBPROC_FC_DT_SOF)
+ {
+ pbproc_fc_sof_t fc = prep->fc_av.sof;
+ test_fail_unless (fc.dt_av = PBPROC_FC_DT_SOF
+ && !fc.access
+ && fc.snid == tp->snid);
+ test_fail_unless (fc.dtei == ack_dtei);
+ test_fail_unless (fc.lid == (access->lid & 0x0F));
+ test_fail_unless (fc.eks == (params->encrypted ? 0 : 0x3));
+ test_fail_unless (!fc.pbsz);
+ test_fail_unless (fc.num_sym == MIN (params->symb_nb, 3u));
+ test_fail_unless (fc.tmi_av == tmi);
+ test_fail_unless (fc.fl_av ==
+ MAC_TCK_TO_FL (MAC_PAYLOAD_TCK (params->symb_nb, dx)
+ + eff_rifs_tck));
+ test_fail_unless (fc.mpdu_cnt == params->mpdu_count);
+ test_fail_unless (fc.burst_cnt == 0);
+ test_fail_unless (!fc.bbf);
+ test_fail_unless (fc.mrtfl == 0);
+ test_fail_unless (fc.mcf == params->bcast);
+ test_fail_unless (fc.mnbf == (params->bcast && params->unassociated));
+ test_fail_unless (prep->fc10 == 0x200000);
+ }
+ else if (prep->fc_av.generic.dt_av == PBPROC_FC_DT_RSOF)
+ {
+ pbproc_fc_rsof_t fc = prep->fc_av.rsof;
+ test_fail_unless (fc.dt_av = PBPROC_FC_DT_RSOF
+ && !fc.access
+ && fc.snid == tp->snid);
+ test_fail_unless (fc.dtei == stei);
+ test_fail_unless (fc.num_sym == MIN (params->symb_nb, 3u));
+ test_fail_unless (fc.tmi_av == tmi);
+ test_fail_unless (fc.rsof_fl_av ==
+ MAC_TCK_TO_FL (MAC_PAYLOAD_TCK (params->symb_nb, dx)
+ + eff_rifs_tck));
+ test_fail_unless (fc.bdf);
+ test_fail_unless (!fc.pbsz);
+ test_fail_unless (prep->fc10 == 0x200000);
+ }
+ /* Chain remaining segments. */
+ if (params->remove == 2 || params->no_access_conf)
+ seg_nb_pending += params->main_seg_nb_total - main_seg_nb;
+ else
+ main_seg_nb = params->main_seg_nb_total;
+ if (params->remove == 2)
+ mfs->ca_state = CA_MFS_STATE_REMOVED;
+ if (!params->no_access_conf)
+ pbproc_prep_mpdu_chain (tp->pbproc);
+ /* Check result. */
+ test_fail_unless (prep->valid);
+ test_fail_unless (prep->main_mfs == mfs);
+ test_fail_unless (prep->current->main_head == seg_first);
+ test_fail_unless (prep->current->main_seg_nb == main_seg_nb);
+ test_fail_unless (prep->main_seg_nb_reserved ==
+ (params->no_access_conf ? main_seg_nb_reserved : 0));
+ test_fail_unless (prep->current->pb_nb_total == main_seg_nb
+ + seg_nb_pending);
+ for (seg = seg_first, i = 1; i < main_seg_nb; seg = seg->next, i++)
+ test_fail_unless (seg->header.opsf == (i == 1));
+ test_fail_unless (seg->next == seg);
+ test_fail_unless (seg->header.opsf == (i == 1));
+ test_fail_unless (prep->current->main_tail == seg);
+ test_fail_unless (mfs->last_seg_offset ==
+ (main_seg_nb == (uint) params->mfs_seg_nb ? 0 : 1));
+ /* Cancel or acknowledge preparation. */
+ if (params->remove == 3)
+ mfs->ca_state = CA_MFS_STATE_REMOVED;
+ uint acked = params->main_seg_nb_total;
+ if (!params->remove)
+ acked -= nack_count;
+ uint mfs_seg_nb_after = params->mfs_seg_nb - acked;
+ /* Expired PBs */
+ if (!params->no_access_conf)
+ {
+ if (params->expiration_date
+ >= params->main_seg_nb_total * UTILS_MFS_EXPIRATION_NTB_STEP)
+ mfs_seg_nb_after -= (params->main_seg_nb_total - acked);
+ if ((uint) params->mfs_seg_nb > params->main_seg_nb_total)
+ {
+ uint expected_expired_nb = params->expiration_date
+ > params->main_seg_nb_total * UTILS_MFS_EXPIRATION_NTB_STEP
+ + PBPROC_EXPIRATION_HYSTERESIS_OFFSET
+ ? params->expiration_date / UTILS_MFS_EXPIRATION_NTB_STEP
+ - params->main_seg_nb_total : 0;
+ uint mfs_remaining_seg_nb = params->mfs_seg_nb
+ - params->main_seg_nb_total;
+ if (expected_expired_nb > mfs_remaining_seg_nb)
+ expected_expired_nb = mfs_remaining_seg_nb;
+ if (expected_expired_nb > PBPROC_CURRENT_TX_MFS_EXPIRE_BUDGET)
+ expected_expired_nb = PBPROC_CURRENT_TX_MFS_EXPIRE_BUDGET;
+ mfs_seg_nb_after -= expected_expired_nb;
+ }
+ }
+ else
+ {
+ if (params->expiration_date
+ >= main_seg_nb * UTILS_MFS_EXPIRATION_NTB_STEP)
+ mfs_seg_nb_after -= main_seg_nb;
+ }
+ if (!params->crc)
+ {
+ if (params->sacki)
+ {
+ if (params->tmi != PHY_MOD_ROBO || params->intervals)
+ {
+ sta_t *sta = mac_store_sta_get (tp->store, dtei);
+ dbg_assert (sta);
+ tonemaps_t *tms = sta->tx_tonemaps;
+ if (params->tmi_update)
+ tms->default_tmi = params->tmi_update;
+ pbproc_prep_mpdu_ack_uniform (
+ tp->pbproc, prep->mpdu_count, params->sacki);
+ test_fail_unless (
+ tms->default_tmi == params->tmi_sacki);
+ if (params->intervals)
+ test_fail_unless (
+ tms->intervals->interval[params->interval].tmi
+ == params->interval_tmi_sacki);
+ blk_release (sta);
+ }
+ else
+ pbproc_prep_mpdu_ack_uniform (
+ tp->pbproc, prep->mpdu_count, params->sacki);
+ }
+ else if (!params->all_ok)
+ pbproc_prep_mpdu_cancel (tp->pbproc, prep->mpdu_count);
+ else
+ pbproc_prep_mpdu_ack_all (tp->pbproc, prep->mpdu_count);
+ }
+ else
+ {
+ if (!params->encoded_sack)
+ {
+ pbproc_sacki_dec_t sacki_dec;
+ pbproc_sacki_dec_init (&sacki_dec, params->crc_error[0],
+ params->crc_error[1],
+ params->crc_error[2] & 0xff,
+ PREP_MPDU_TEST_CRC_BITMAP_SIZE);
+ pbproc_prep_mpdu_ack_bitmap (tp->pbproc, prep->mpdu_count,
+ &sacki_dec);
+ uint eaten = MIN (main_seg_nb + seg_nb_pending,
+ PREP_MPDU_TEST_CRC_BITMAP_SIZE);
+ test_fail_unless (sacki_dec.sil
+ == PREP_MPDU_TEST_CRC_BITMAP_SIZE - eaten);
+ }
+ else
+ {
+ pbproc_sacki_dec_t sacki_dec;
+ pbproc_sacki_dec_init (
+ &sacki_dec, params->encoded_sack & 0xffffffff,
+ (params->encoded_sack >> 32) & 0xffffffff, 0, 64);
+ pbproc_prep_mpdu_ack_encoded (tp->pbproc, prep->mpdu_count,
+ &sacki_dec);
+ test_fail_unless (sacki_dec.sil
+ == 64 - params->encoded_sack_length);
+ }
+ }
+ /* Set MFS_RSP and MFS_CMD to allow test of MFS fsm state in case of
+ * expiration. */
+ mfs->fsm_state = MFS_FSM_CMD_IN_SYNC;
+ tp->pbproc->prep_mpdu.main_mfs_cmd = MFS_FSM_CMD_IN_SYNC;
+ tp->pbproc->prep_mpdu.main_mfs_rsp = MFS_FSM_RSP_ACK;
+ pbproc_prep_mpdu_commit_burst (tp->pbproc);
+ u16 expected_holes_nb = 0;
+ if (mfs->ca_state != CA_MFS_STATE_REMOVED && mfs->seg_nb)
+ {
+ pb_t *mfs_seg;
+ for (mfs_seg = mfs->head; mfs_seg != mfs->tail; mfs_seg = mfs_seg->next)
+ expected_holes_nb += (mfs_seg->next->header.ssn - mfs_seg->header.ssn - 1);
+ expected_holes_nb += (mfs->next_ssn - mfs->tail->header.ssn - 1);
+ }
+ /* Test update of number of holes in the MFS. */
+ test_fail_unless (mfs->holes_seg_nb == expected_holes_nb);
+ /* Test update of MFS FSM state in case of expiration. */
+ if (params->mfs_fsm_state_test)
+ test_fail_unless (mfs->fsm_state == params->expected_mfs_fsm_state);
+ /* Call DSR if requested. */
+ if (tp->pbproc->fsm.schedule_deferred)
+ pbproc_fsm_handle_deferred (tp->pbproc);
+ /* Check result. */
+ test_fail_unless (mfs->seg_nb == (int) mfs_seg_nb_after);
+ if (!params->mfs_holes_bitmap && !params->expiration_date)
+ {
+ seg = mfs->head;
+ for (i = 0; i < (uint) params->mfs_seg_nb; i++)
+ {
+ bool bad_crc = !params->crc ? !params->all_ok
+ : (params->crc_error[i / 32] & (1u << (i % 32))) != 0;
+ if (i >= main_seg_nb || (!params->remove && bad_crc))
+ {
+ test_fail_unless (seg->header.ssn == i
+ && seg->header.mfbo == 0
+ && seg->header.vpbf == true
+ && seg->header.mmqf == params->mme
+ && seg->header.mfbf == false
+ && seg->header.opsf == (i == 0)
+ && seg->header.rsvd == 0);
+ seg = seg->next;
+ }
+ }
+ }
+ }
+ /* Information stored in frame control */
+ if (params->pg_sacki)
+ {
+ pbproc_sacki_dec_t sacki_dec;
+ uint st[4];
+ pbproc_prep_mpdu_reassembly_ack (&prep->fc_av, st, &sacki_dec);
+ test_fail_unless (st[0] == PBPROC_FC_SACKT_MIXED);
+ test_fail_unless (params->crc_error[0] == sacki_dec.si[0]);
+ test_fail_unless ((params->crc_error[1] & BITS_ONES (sacki_dec.sil - 32))
+ == (sacki_dec.si[1] & BITS_ONES (sacki_dec.sil - 32)));
+ test_fail_unless (params->crc_error[2] == 0);
+ test_fail_unless (sacki_dec.si[2] == 0);
+ /* check size of sound frame sacki info */
+ uint sil;
+ if (prep->fc_av.generic.dt_av == PBPROC_FC_DT_SOUND)
+ sil = PBPROC_FC_SACKI_EOC_SOUND_SIZE;
+ else if (prep->fc_av.generic.dt_av == PBPROC_FC_DT_SOF)
+ sil = PBPROC_FC_SACKI_EOC_SOF_SIZE;
+ else if (prep->fc_av.generic.dt_av == PBPROC_FC_DT_RSOF)
+ sil = PBPROC_FC_SACKI_EOC_RSOF_SIZE;
+ test_fail_unless (sacki_dec.sil == sil);
+ }
+ /* Cleanup. */
+ utils_mfs_tx_cleanup (mfs);
+ if (sta_created)
+ dbg_check (mac_store_sta_remove (tp->store, dtei));
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0, false);
+ tp->pbproc->detect.beacon_detected = false;
+ tp->pbproc->detect.hp10_detected = false;
+ tp->pbproc->detect.hp11_detected = false;
+ tp->config.authenticated = false;
+ tp->config.partial_ack_tei_default = false;
+}
+
+void
+prep_mpdu_basic_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "basic");
+ test_pbproc_init (&tp);
+ test_begin (t, "robo unicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1);
+ } test_end;
+ test_begin (t, "rsof robo unicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1, .bbf = true);
+ } test_end;
+ test_begin (t, "robo unicast mme limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mme = true, .mfs_seg_nb = 30,
+ .duration_symb_nb = 25, .symb_nb = 19,
+ .main_seg_nb_total = 1);
+ } test_end;
+ test_begin (t, "robo unicast data limit dur max")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 38, .main_seg_nb_total = 2);
+ } test_end;
+ test_begin (t, "robo unicast data limit seg")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19, .main_seg_nb_total = 1);
+ } test_end;
+ test_begin (t, "robo unicast data limit no seg")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 0, .duration_symb_nb = 95,
+ .main_seg_nb_total = 0);
+ } test_end;
+ test_begin (t, "robo unicast data limit dur zero")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 16,
+ .symb_nb = 0, .main_seg_nb_total = 0);
+ } test_end;
+ test_begin (t, "robo multicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .bcast = true);
+ } test_end;
+ test_begin (t, "robo multicast data limit dur partial ack")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .bcast = true, .partial_ack = true);
+ } test_end;
+ test_begin (t, "robo multicast data limit dur max")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .bcast = true);
+ } test_end;
+ test_begin (t, "robo unassociated unicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .unassociated = true);
+ } test_end;
+ test_begin (t, "robo unassociated multicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .bcast = true, .unassociated = true);
+ } test_end;
+ test_begin (t, "hs-robo unicast data limit seg")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 95,
+ .symb_nb = 30, .main_seg_nb_total = 3,
+ .tmi = PHY_MOD_HS_ROBO);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 16,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "tm unicast data limit seg with null")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 13, .duration_symb_nb = 8,
+ .symb_nb = 8, .main_seg_nb_total = 12,
+ .seg_nb_pending = 0,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur bis")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 13, .duration_symb_nb = 8,
+ .symb_nb = 8, .main_seg_nb_total = 12,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ /* Bursting is not supported yet */
+ /*
+ test_begin (t, "tm unicast data limit dur tm")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 60, .duration_symb_nb = 91,
+ .symb_nb = 30, .main_seg_nb_total = 49,
+ .tmi = 5, .tm_mod = 10,
+ .tm_max_fl_tck = MAC_PAYLOAD_TCK (30, MAC_DX417_TCK)
+ + MAC_RIFS_SPC_ANY_TCK,
+ .mpdu_count = 1);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur max")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 100, .duration_symb_nb = 100,
+ .symb_nb = 50, .main_seg_nb_total = 83,
+ .tmi = 5, .tm_mod = 10,
+ .mpdu_count = 1);
+ } test_end;
+ */
+ test_begin (t, "tm unicast data limit dur zero")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 0,
+ .symb_nb = 0, .main_seg_nb_total = 0,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur one")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 1,
+ .symb_nb = 1, .main_seg_nb_total = 1,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur two")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 2,
+ .symb_nb = 2, .main_seg_nb_total = 2,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "robo unicast data limit dur encrypted")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .encrypted = true);
+ } test_end;
+ test_begin (t, "robo multicast data limit dur encrypted")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .bcast = true, .encrypted = true);
+ } test_end;
+ test_begin (t, "hs-robo unicast data limit dur remove 2")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .remove = 2, .tmi = PHY_MOD_HS_ROBO);
+ } test_end;
+ test_begin (t, "hs-robo unicast data limit dur remove 3")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .remove = 3, .tmi = PHY_MOD_HS_ROBO);
+ } test_end;
+ test_begin (t, "no sound for mme")
+ {
+ prep_mpdu_test (t, &tp, 0, .mme = true, .mfs_seg_nb = 30,
+ .duration_symb_nb = 25, .symb_nb = 19,
+ .main_seg_nb_total = 1,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ } test_end;
+ test_begin (t, "sound initial")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .tmi = TONEMAP_INDEX_INITIAL_START, .scf = true);
+ } test_end;
+ test_begin (t, "sound error")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .tmi = TONEMAP_INDEX_INITIAL_ERROR);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .tmi = TONEMAP_INDEX_INITIAL_ERROR, .scf = true);
+ } test_end;
+ test_begin (t, "sound complete")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .tmi = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE);
+ } test_end;
+ test_begin (t, "sound tmi")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 19, .tmi = 6, .sound_reason_code = 6);
+ } test_end;
+ test_begin (t, "beacon detection")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .beacon_detected = true);
+ } test_end;
+ test_begin (t, "hp detection")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .hp10_detected = true);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .hp11_detected = true);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .hp10_detected = true, .hp11_detected = true);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_ack_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "ack");
+ test_pbproc_init (&tp);
+ test_begin (t, "acked all")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .all_ok = true, .tmi = PHY_MOD_HS_ROBO);
+ } test_end;
+ test_begin (t, "acked bitmap")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc = true, .crc_error = { 0 },
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc = true, .crc_error = { 0x15 },
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 41, .duration_symb_nb = 30,
+ .symb_nb = 25, .main_seg_nb_total = 41,
+ .crc = true, .crc_error = { 0x0fa5c03a, 0x15 },
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked bitmap overflow")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 81, .duration_symb_nb = 55,
+ .symb_nb = 49, .main_seg_nb_total = 81,
+ .crc = true,
+ .crc_error = { 0xaa55aa55, 0x5a5a5a5a, 0x1ff5a },
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked bitmap with null")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 13, .duration_symb_nb = 9,
+ .symb_nb = 9, .main_seg_nb_total = 13,
+ .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x1a5a },
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc = true, .crc_error = { 0x15 },
+ .encoded_sack = 0x6f,
+ .encoded_sack_length = 9,
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 41, .duration_symb_nb = 30,
+ .symb_nb = 25, .main_seg_nb_total = 41,
+ .crc = true, .crc_error = { 0x0fa5c03a, 0x15 },
+ .encoded_sack = 0x066bffc9fd3f9ull,
+ .encoded_sack_length = 49,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap overflow")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 32, .duration_symb_nb = 30,
+ .symb_nb = 20, .main_seg_nb_total = 32,
+ .crc = true, .crc_error = { 0xf9ffffff },
+ .encoded_sack = 0xbfffffffffffffffull,
+ .encoded_sack_length = 64,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap with null extra symbol")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 3,
+ .symb_nb = 3, .main_seg_nb_total = 3,
+ .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x4 },
+ .encoded_sack = 0x5, .encoded_sack_length = 4,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap with null same symbol")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 3,
+ .symb_nb = 3, .main_seg_nb_total = 3,
+ .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x0 },
+ .encoded_sack = 0x0, .encoded_sack_length = 1,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap with null extra symbol bad")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 3,
+ .symb_nb = 3, .main_seg_nb_total = 3,
+ .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x4 },
+ .encoded_sack = 0x1d, .encoded_sack_length = 6,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap with null same symbol bad")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 3,
+ .symb_nb = 3, .main_seg_nb_total = 3,
+ .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x0 },
+ .encoded_sack = 0x7, .encoded_sack_length = 4,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked encoded bitmap with null overflow")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 29,
+ .symb_nb = 19, .main_seg_nb_total = 30,
+ .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x39ffffff },
+ .encoded_sack = 0xbfffffffffffffffull,
+ .encoded_sack_length = 64,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked uniform basic")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .all_ok = true,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_ALL_OK);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .all_ok = false,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_NOT_AVAILABLE);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .all_ok = false,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_NEK_ERROR);
+ } test_end;
+ test_begin (t, "acked uniform tmi error no sta")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .tmi = PHY_MOD_ROBO,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .tmi = PHY_MOD_ROBO,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_RESTART);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 38, .main_seg_nb_total = 2,
+ .tmi = PHY_MOD_ROBO,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_RESTART);
+ } test_end;
+ test_begin (t, "acked uniform tmi error robo")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 95,
+ .symb_nb = 30, .main_seg_nb_total = 3,
+ .tmi = PHY_MOD_HS_ROBO,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO,
+ .tmi_sacki = PHY_MOD_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 95,
+ .symb_nb = 30, .main_seg_nb_total = 3,
+ .tmi = PHY_MOD_HS_ROBO,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 95,
+ .symb_nb = 30, .main_seg_nb_total = 3,
+ .tmi = PHY_MOD_HS_ROBO,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_START);
+ } test_end;
+ test_begin (t, "acked uniform tmi error tm")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO,
+ .tmi_sacki = PHY_MOD_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_START);
+ } test_end;
+ test_begin (t, "acked uniform tmi error ce update")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6,
+ .tmi_update = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6,
+ .tmi_update = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6,
+ .tmi_update = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_SOUND_COMPLETE);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_intervals_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "intervals");
+ test_pbproc_init (&tp);
+ utils_interval_t intervals[] =
+ {
+ { 100000, TONEMAP_INDEX_INTERVAL_UNAVAILABLE, 0 },
+ { 200000, TONEMAP_INDEX_INTERVAL_UNUSABLE, 0 },
+ { 300000, 6, 0 },
+ { 400000, TONEMAP_INDEX_INTERVAL_SOUND_COMPLETE, 0 },
+ { 0, 0, 0 }
+ };
+ test_begin (t, "interval tmi")
+ {
+ prep_mpdu_test (t, &tp, 210000,
+ .mfs_seg_nb = 14, .duration_symb_nb = 9,
+ .symb_nb = 9, .main_seg_nb_total = 14,
+ .tmi = 6, .tm_mod = 10,
+ .intervals = intervals, .interval = 2);
+ } test_end;
+ test_begin (t, "no interval default tmi")
+ {
+ prep_mpdu_test (t, &tp, 910000,
+ .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .intervals = intervals,
+ .interval = TONEMAP_INTERVAL_NB);
+ } test_end;
+ test_begin (t, "unavailable interval")
+ {
+ prep_mpdu_test (t, &tp, 10000,
+ .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .intervals = intervals, .interval = 0,
+ .sound_reason_code = TONEMAP_SRC_INTERVAL_UNAVAILABLE);
+ prep_mpdu_test (t, &tp, 10000,
+ .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .intervals = intervals, .interval = 0,
+ .sound_reason_code = TONEMAP_SRC_INTERVAL_UNAVAILABLE,
+ .scf = true);
+ } test_end;
+ test_begin (t, "unusable interval")
+ {
+ prep_mpdu_test (t, &tp, 110000,
+ .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .intervals = intervals, .interval = 1,
+ .sound_reason_code = TONEMAP_SRC_INTERVAL_UNUSABLE);
+ prep_mpdu_test (t, &tp, 110000,
+ .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .intervals = intervals, .interval = 1,
+ .sound_reason_code = TONEMAP_SRC_INTERVAL_UNUSABLE,
+ .scf = true);
+ } test_end;
+ test_begin (t, "sound complete interval")
+ {
+ prep_mpdu_test (t, &tp, 310000,
+ .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .intervals = intervals, .interval = 3);
+ } test_end;
+ test_begin (t, "acked uniform tmi error")
+ {
+ prep_mpdu_test (t, &tp, 210000,
+ .mfs_seg_nb = 14, .duration_symb_nb = 9,
+ .symb_nb = 9, .main_seg_nb_total = 14,
+ .tmi = 6, .tm_mod = 10,
+ .intervals = intervals, .interval = 2,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO,
+ .tmi_sacki = PHY_MOD_ROBO, .interval_tmi_sacki =
+ TONEMAP_INDEX_INTERVAL_UNAVAILABLE);
+ prep_mpdu_test (t, &tp, 210000,
+ .mfs_seg_nb = 14, .duration_symb_nb = 9,
+ .symb_nb = 9, .main_seg_nb_total = 14,
+ .tmi = 6, .tm_mod = 10,
+ .intervals = intervals, .interval = 2,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_RESTART,
+ .tmi_sacki = PHY_MOD_ROBO, .interval_tmi_sacki =
+ TONEMAP_INDEX_INTERVAL_UNAVAILABLE);
+ } test_end;
+ test_begin (t, "acked uniform tmi error restart")
+ {
+ prep_mpdu_test (t, &tp, 210000,
+ .mfs_seg_nb = 14, .duration_symb_nb = 9,
+ .symb_nb = 9, .main_seg_nb_total = 14,
+ .tmi = 6, .tm_mod = 10,
+ .intervals = intervals, .interval = 2,
+ .sacki = PBPROC_FC_SACKI_UNIFORM_TMI_RESTART,
+ .tmi_sacki = TONEMAP_INDEX_INITIAL_START,
+ .interval_tmi_sacki = 6);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_expiration_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "expiration");
+ test_pbproc_init (&tp);
+ test_begin (t, "expiration on sack return")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .duration_symb_nb = 50,
+ .symb_nb = 25, .main_seg_nb_total = 40, .seg_nb_pending = 1,
+ .expiration_date = 20 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .duration_symb_nb = 50,
+ .symb_nb = 25, .main_seg_nb_total = 40, .seg_nb_pending = 1,
+ .expiration_date = 50 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .duration_symb_nb = 50,
+ .symb_nb = 25, .main_seg_nb_total = 40, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x0fa5c03a, 0x15 },
+ .expiration_date = 50 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "expiration on chaining")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 200, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 83, .seg_nb_pending = 0,
+ .expiration_date = 80 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 200, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 83, .seg_nb_pending = 0,
+ .expiration_date = 150 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 200, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 83, .seg_nb_pending = 0,
+ .expiration_date = 250 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 200, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 83, .seg_nb_pending = 0,
+ .crc = true, .crc_error = { 0x0fa5c03a, 0x15, 0x7ff00 },
+ .expiration_date = 150 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "expiration with cancel")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .duration_symb_nb = 50,
+ .symb_nb = 25, .main_seg_nb_total = 40, .seg_nb_pending = 1,
+ .expiration_date = 3 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .no_access_conf = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .duration_symb_nb = 50,
+ .symb_nb = 25, .main_seg_nb_total = 40, .seg_nb_pending = 1,
+ .expiration_date = 50 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .no_access_conf = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .duration_symb_nb = 50,
+ .symb_nb = 25, .main_seg_nb_total = 40, .seg_nb_pending = 1,
+ .expiration_date = 200 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .no_access_conf = true, .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_window_size_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "window size");
+ test_pbproc_init (&tp);
+ test_begin (t, "no holes no ack")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .mfs_holes_bitmap = 0,
+ .window_size = MFS_WINDOW_SIZE_32, .duration_symb_nb = 50,
+ .symb_nb = 20, .main_seg_nb_total = 32, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 20, .mfs_holes_bitmap = 0,
+ .window_size = MFS_WINDOW_SIZE_32, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "holes no ack")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x55,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 21, .seg_nb_pending = 0,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 16, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 10, .main_seg_nb_total = 16, .seg_nb_pending = 0,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "holes ack all")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .all_ok = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x000100AA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 12, .main_seg_nb_total = 19, .seg_nb_pending = 0,
+ .all_ok = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x100000AA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 12, .main_seg_nb_total = 19, .seg_nb_pending = 0,
+ .all_ok = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x200000AA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 12, .main_seg_nb_total = 19, .seg_nb_pending = 0,
+ .all_ok = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x300000AA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 12, .main_seg_nb_total = 18, .seg_nb_pending = 1,
+ .all_ok = true, .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "holes ack bitmap")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x00021084 },
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x100000AA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 12, .main_seg_nb_total = 19, .seg_nb_pending = 0,
+ .crc = true, .crc_error = { 0x00021084 },
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x000C4261 },
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x000C4000 },
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "expiration")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0x200000AA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 12, .main_seg_nb_total = 19, .seg_nb_pending = 0,
+ .expiration_date = 22 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .all_ok = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x00021084 },
+ .expiration_date = 15 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x00021084 },
+ .expiration_date = 22 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .tmi = 5, .tm_mod = 10);
+ /* No fsm state testing */
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x00021084 },
+ .expiration_date = 50 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .expected_mfs_fsm_state = MFS_FSM_CMD_RE_SYNC,
+ .mfs_fsm_state_test = false, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 200, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .crc = true, .crc_error = { 0x00021084 },
+ .expiration_date = 100 * UTILS_MFS_EXPIRATION_NTB_STEP,
+ .expected_mfs_fsm_state = MFS_FSM_CMD_RE_SYNC,
+ .mfs_fsm_state_test = false, .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "no access conf")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 40, .mfs_holes_bitmap = 0,
+ .window_size = MFS_WINDOW_SIZE_32, .duration_symb_nb = 50,
+ .symb_nb = 20, .main_seg_nb_total = 32, .seg_nb_pending = 0,
+ .no_access_conf = true, .tmi = 5, .tm_mod = 10);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .mfs_holes_bitmap = 0xAA,
+ .window_size = MFS_WINDOW_SIZE_24, .duration_symb_nb = 50,
+ .symb_nb = 13, .main_seg_nb_total = 20, .seg_nb_pending = 1,
+ .no_access_conf = true, .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_beacon_test (test_t t, test_pbproc_t *tp, u32 date, bool prepared,
+ uint duration_symb_nb, uint symb_nb)
+{
+ test_within (t);
+ dbg_assert (tp);
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ const u32 beacon_period_start_date = date / beacon_tck * beacon_tck;
+ /* Create a beacon MFS. */
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (true, false, MAC_LID_SPC_CENTRAL,
+ MAC_TEI_BCAST, 0);
+ mfs->cfp = true;
+ mfs->beacon = true;
+ pb_t *seg = NULL;
+ pbproc_tx_beacon_params_t params =
+ { { 0x0123, 0x4242, 0xabab, 0x5555 }, NULL };
+ if (prepared)
+ {
+ pb_beacon_t *pb = PARENT_OF (pb_beacon_t, blk, blk_alloc_desc ());
+ seg = (pb_t *) pb;
+ params.bpsto = pb->data + 123;
+ pbproc_mfs_beacon_prepare (tp->pbproc, mfs, pb, &params);
+ }
+ /* Setup an access. */
+ test_pbproc_alloc (tp, false, beacon_period_start_date);
+ ca_access_param_t *access = &tp->pbproc->access;
+ access->lid = mfs->common.lid;
+ access->access_date = date;
+ access->duration_tck = MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_PAYLOAD_TCK (duration_symb_nb, MAC_DX567_TCK)
+ + MAC_B2BIFS_TCK;
+ access->prp = false;
+ access->cfp = true;
+ /* Prepare beacon. */
+ pbproc_prep_beacon (tp->pbproc, mfs);
+ /* Check result. */
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ test_fail_unless (prep->stei == 0);
+ test_fail_unless (prep->dtei == MAC_TEI_BCAST);
+ test_fail_unless (prep->lid == MAC_LID_NONE);
+ test_fail_unless (!prep->wack);
+ test_fail_unless (!prep->unassociated);
+ test_fail_unless (!prep->rts_cts);
+ test_fail_unless (prep->burst_mpdu_nb == 1);
+ test_fail_unless (prep->mpdu_count == 0);
+ test_fail_unless (prep->current == &prep->mpdu[0]);
+ if (symb_nb)
+ {
+ test_fail_unless (prep->valid);
+ test_fail_unless (prep->main_mfs == mfs);
+ test_fail_unless (prep->tx_date == date);
+ test_fail_unless (prep->fc_mode == PHY_FC_MODE_AV_1);
+ test_fail_unless (prep->sound_reason_code == TONEMAP_SRC_NULL);
+ test_fail_unless (prep->mpdu[0].tmi == PHY_MOD_MINI_ROBO);
+ test_fail_unless (prep->phy_combo_params == PHY_COMBO_PARAMS (
+ PHY_MOD_MINI_ROBO, PHY_FEC_RATE_1_2, PHY_PB_SIZE_136));
+ test_fail_unless (prep->gil == PHY_GIL_567);
+ test_fail_unless (prep->tonemap == NULL);
+ test_fail_unless (prep->ifs_tck == MAC_B2BIFS_TCK);
+ test_fail_unless (prep->flp_tck == MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX567_TCK)
+ + MAC_B2BIFS_TCK);
+ test_fail_unless (prep->mpdu[0].main_head == seg);
+ test_fail_unless (prep->mpdu[0].main_tail == seg);
+ test_fail_unless (prep->mpdu[0].main_seg_nb == 1);
+ test_fail_unless (prep->main_seg_nb_reserved == 0);
+ test_fail_unless (prep->main_mfs_cmd == MFS_FSM_CMD_NOP);
+ test_fail_unless (prep->main_mfs_rsp == MFS_FSM_RSP_NB);
+ test_fail_unless (prep->mpdu[0].pb_nb_total == 1);
+ test_fail_unless (prep->bypass_aes);
+ /* Check FC. */
+ pbproc_fc_beacon_t *fc = &prep->fc_av.beacon;
+ test_fail_unless (fc->dt_av == PBPROC_FC_DT_BEACON);
+ test_fail_unless (fc->access == false
+ && fc->snid == tp->snid);
+ uint bts = fc->bts_msb8 << 24 | fc->bts_lsb24;
+ uint bto[4] = {
+ fc->bto0,
+ fc->bto1_msb8 << 8 | fc->bto1_lsb8,
+ fc->bto2,
+ fc->bto3_msb8 << 8 | fc->bto3_lsb8
+ };
+ test_fail_unless (bts == date + tp->config.ntb_offset_tck);
+ test_fail_unless (bto[0] == params.bto[0]);
+ test_fail_unless (bto[1] == params.bto[1]);
+ test_fail_unless (bto[2] == params.bto[2]);
+ test_fail_unless (bto[3] == params.bto[3]);
+ test_fail_unless (prep->fc10 == 0x2f00);
+ /* Check payload (BPSTO). */
+ uint bpsto = params.bpsto[0]
+ | params.bpsto[1] << 8
+ | params.bpsto[2] << 16;
+ test_fail_unless (bpsto == date - beacon_period_start_date);
+ /* Cancel preparation. */
+ pbproc_prep_mpdu_cancel_burst (tp->pbproc);
+ /* Check result. */
+ test_fail_unless (mfs->seg_nb == 1);
+ test_fail_unless (mfs->head == seg);
+ test_fail_unless (mfs->tail == seg);
+ test_fail_unless (!mfs->holes_seg_nb);
+ }
+ else
+ {
+ test_fail_unless (!prep->valid);
+ test_fail_unless (prep->main_mfs == NULL);
+ test_fail_unless (prep->mpdu[0].main_seg_nb == 0);
+ test_fail_unless (prep->main_seg_nb_reserved == 0);
+ test_fail_unless (prep->mpdu[0].pb_nb_total == 0);
+ /* Check MFS. */
+ if (prepared)
+ {
+ test_fail_unless (mfs->seg_nb == 1);
+ test_fail_unless (mfs->head == seg);
+ test_fail_unless (mfs->tail == seg);
+ }
+ else
+ {
+ test_fail_unless (mfs->seg_nb == 0);
+ test_fail_unless (mfs->head == NULL);
+ }
+ }
+ /* Cleanup. */
+ utils_mfs_tx_cleanup (mfs);
+}
+
+void
+prep_mpdu_beacon_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "beacon");
+ test_pbproc_init (&tp);
+ test_begin (t, "valid")
+ {
+ prep_beacon_test (t, &tp, 123456, true, 6, 6);
+ } test_end;
+ test_begin (t, "unvalid")
+ {
+ prep_beacon_test (t, &tp, 54321, true, 5, 0);
+ } test_end;
+ test_begin (t, "no seg")
+ {
+ prep_beacon_test (t, &tp, 54321, false, 6, 0);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_fsm_test (test_t t, test_pbproc_t *tp, mfs_fsm_cmd_t cmd,
+ mfs_fsm_rsp_t rsp, bool release, bool empty,
+ bool opsf, mfs_fsm_cmd_t expect_cmd, bool expect_hold)
+{
+ test_within (t);
+ /* Create an MFS. */
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, 2, 2, empty ? 0 : 1);
+ if (!empty && opsf)
+ mfs->head->header.opsf = true;
+ mfs->fsm_state = release ? MFS_FSM_CMD_RELEASE : cmd;
+ /* Prepare MPDU. */
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ prep->valid = true;
+ prep->main_mfs = mfs;
+ blk_addref (mfs);
+ pb_t *pb = PARENT_OF (pb_t, blk, blk_alloc_desc ());
+ prep->burst_mpdu_nb = 1;
+ prep->mpdu[0].main_head = prep->mpdu[0].main_tail = pb;
+ prep->mpdu[0].main_seg_nb = 1;
+ prep->main_seg_nb_reserved = 0;
+ prep->mpdu[0].pb_nb_total = 1;
+ prep->main_mfs_cmd = cmd;
+ /* Test. */
+ prep->main_mfs_rsp = rsp;
+ pbproc_prep_mpdu_ack_all_burst (tp->pbproc);
+ /* Call DSR if requested. */
+ if (tp->pbproc->fsm.schedule_deferred)
+ pbproc_fsm_handle_deferred (tp->pbproc);
+ /* Check result. */
+ test_fail_unless (mfs->fsm_state == expect_cmd);
+ test_fail_unless (
+ (expect_hold && mfs->ca_state == CA_MFS_STATE_HELD)
+ || (!expect_hold && mfs->ca_state == CA_MFS_STATE_UNKNOWN));
+ /* Cleanup. */
+ utils_mfs_tx_cleanup (mfs);
+ prep->main_mfs = NULL;
+ prep->valid = false;
+}
+
+void
+prep_mpdu_fsm_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "fsm");
+ test_pbproc_init (&tp);
+ test_begin (t, "unicast init ack")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_ACK,
+ false, true, false, MFS_FSM_CMD_IN_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_ACK,
+ false, false, false, MFS_FSM_CMD_IN_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_ACK,
+ false, false, true, MFS_FSM_CMD_IN_SYNC, false);
+ } test_end;
+ test_begin (t, "unicast init nack (invalid)")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_NACK,
+ false, true, false, MFS_FSM_CMD_INIT, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_NACK,
+ false, false, false, MFS_FSM_CMD_INIT, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_NACK,
+ false, false, true, MFS_FSM_CMD_INIT, false);
+ } test_end;
+ test_begin (t, "unicast in_sync ack")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_ACK,
+ false, true, false, MFS_FSM_CMD_IN_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_ACK,
+ false, false, false, MFS_FSM_CMD_IN_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_ACK,
+ false, false, true, MFS_FSM_CMD_IN_SYNC, false);
+ } test_end;
+ test_begin (t, "unicast in_sync nack")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_NACK,
+ false, true, false, MFS_FSM_CMD_RE_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_NACK,
+ false, false, false, MFS_FSM_CMD_RE_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_NACK,
+ false, false, true, MFS_FSM_CMD_RE_SYNC, false);
+ } test_end;
+ test_begin (t, "unicast re_sync ack")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_ACK,
+ false, true, false, MFS_FSM_CMD_IN_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_ACK,
+ false, false, false, MFS_FSM_CMD_IN_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_ACK,
+ false, false, true, MFS_FSM_CMD_RE_SYNC, false);
+ } test_end;
+ test_begin (t, "unicast re_sync nack")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_NACK,
+ false, true, false, MFS_FSM_CMD_RE_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_NACK,
+ false, false, false, MFS_FSM_CMD_RE_SYNC, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_NACK,
+ false, false, true, MFS_FSM_CMD_RE_SYNC, false);
+ } test_end;
+ test_begin (t, "multicast ack")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_ACK,
+ false, true, false, MFS_FSM_CMD_NOP, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_ACK,
+ false, false, false, MFS_FSM_CMD_NOP, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_ACK,
+ false, false, true, MFS_FSM_CMD_NOP, false);
+ } test_end;
+ test_begin (t, "multicast nack (invalid)")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_NACK,
+ false, true, false, MFS_FSM_CMD_NOP, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_NACK,
+ false, false, false, MFS_FSM_CMD_NOP, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_NACK,
+ false, false, true, MFS_FSM_CMD_NOP, false);
+ } test_end;
+ test_begin (t, "hold")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_HOLD,
+ false, true, false, MFS_FSM_CMD_INIT, true);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_HOLD,
+ false, true, false, MFS_FSM_CMD_IN_SYNC, true);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_HOLD,
+ false, true, false, MFS_FSM_CMD_RE_SYNC, true);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_HOLD,
+ false, true, false, MFS_FSM_CMD_NOP, false);
+ } test_end;
+ test_begin (t, "released")
+ {
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_ACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_ACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_ACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_ACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_INIT, MFS_FSM_RSP_NACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_IN_SYNC, MFS_FSM_RSP_NACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_RE_SYNC, MFS_FSM_RSP_NACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ prep_mpdu_fsm_test (t, &tp, MFS_FSM_CMD_NOP, MFS_FSM_RSP_NACK,
+ true, true, false, MFS_FSM_CMD_RELEASE, false);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_basic_rsof_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "basic rsof");
+ test_pbproc_init (&tp);
+ test_begin (t, "robo unicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1, .bbf = true);
+ } test_end;
+ test_begin (t, "robo unicast mme limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mme = true, .mfs_seg_nb = 30,
+ .duration_symb_nb = 25, .symb_nb = 19,
+ .main_seg_nb_total = 1, .bbf = true);
+ } test_end;
+ test_begin (t, "robo unicast data limit dur max")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 95,
+ .symb_nb = 38, .main_seg_nb_total = 2, .bbf = true);
+ } test_end;
+ test_begin (t, "robo unicast data limit seg")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 1, .duration_symb_nb = 95,
+ .symb_nb = 19, .main_seg_nb_total = 1, .bbf = true);
+ } test_end;
+ test_begin (t, "hs-robo unicast data limit seg")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 3, .duration_symb_nb = 95,
+ .symb_nb = 30, .main_seg_nb_total = 3,
+ .tmi = PHY_MOD_HS_ROBO, .bbf = true);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 10,
+ .tmi = 5, .tm_mod = 6, .bbf = true);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 10,
+ .symb_nb = 10, .main_seg_nb_total = 16,
+ .tmi = 5, .tm_mod = 10, .bbf = true);
+ } test_end;
+ test_begin (t, "tm unicast data limit seg with null")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 13, .duration_symb_nb = 8,
+ .symb_nb = 8, .main_seg_nb_total = 12,
+ .seg_nb_pending = 0,
+ .tmi = 5, .tm_mod = 10, .bbf = true);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur bis")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 13, .duration_symb_nb = 8,
+ .symb_nb = 8, .main_seg_nb_total = 12,
+ .tmi = 5, .tm_mod = 10, .bbf = true);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur one")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 1,
+ .symb_nb = 1, .main_seg_nb_total = 1,
+ .tmi = 5, .tm_mod = 10, .bbf = true);
+ } test_end;
+ test_begin (t, "tm unicast data limit dur two")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 2,
+ .symb_nb = 2, .main_seg_nb_total = 2,
+ .tmi = 5, .tm_mod = 10, .bbf = true);
+ } test_end;
+ test_begin (t, "robo unicast data limit dur encrypted")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 25,
+ .symb_nb = 19, .main_seg_nb_total = 1,
+ .encrypted = true, .bbf = true);
+ } test_end;
+ test_begin (t, "hs-robo unicast data limit dur remove 2")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .remove = 2, .tmi = PHY_MOD_HS_ROBO, .bbf = true);
+ } test_end;
+ test_begin (t, "hs-robo unicast data limit dur remove 3")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .remove = 3, .tmi = PHY_MOD_HS_ROBO, .bbf = true);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_pg_ack_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "pg_ack");
+ test_pbproc_init (&tp);
+ test_begin (t, "acked bitmap")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc_error = { 0 },
+ .pg_sacki = true,
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc_error = { 0x15 },
+ .pg_sacki = true,
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 41, .duration_symb_nb = 30,
+ .symb_nb = 25, .main_seg_nb_total = 41,
+ .crc_error = { 0x0fa5c03a, 0x15 },
+ .pg_sacki = true,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked bitmap overflow")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 81, .duration_symb_nb = 55,
+ .symb_nb = 49, .main_seg_nb_total = 81,
+ .crc_error = { 0xaa55aa55, 0x5a5a5a5a },
+ .pg_sacki = true,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked bitmap rsof")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc_error = { 0 },
+ .pg_sacki = true, .bbf = true,
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 30, .duration_symb_nb = 50,
+ .symb_nb = 50, .main_seg_nb_total = 5,
+ .crc_error = { 0x15 },
+ .pg_sacki = true, .bbf = true,
+ .tmi = PHY_MOD_HS_ROBO);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 41, .duration_symb_nb = 30,
+ .symb_nb = 25, .main_seg_nb_total = 41,
+ .crc_error = { 0x0fa5c03a, 0x15 },
+ .pg_sacki = true, .bbf = true,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked bitmap overflow rsof")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 81, .duration_symb_nb = 55,
+ .symb_nb = 49, .main_seg_nb_total = 81,
+ .crc_error = { 0xaa55aa55, 0x5a5a5a5a },
+ .pg_sacki = true, .bbf = true,
+ .tmi = 5, .tm_mod = 10);
+ } test_end;
+ test_begin (t, "acked bitmap sound")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0 },
+ .pg_sacki = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0x15 },
+ .pg_sacki = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0x0fa5c03a, 0x15 },
+ .pg_sacki = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ /* Other direction .bbf = true */
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0 },
+ .pg_sacki = true, .bbf = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0x15 },
+ .pg_sacki = true, .bbf = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0x0fa5c03a, 0x15 },
+ .pg_sacki = true, .bbf = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ } test_end;
+ test_begin (t, "acked bitmap overflow sound")
+ {
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0xaa55aa55, 0x5a5a5a5a },
+ .pg_sacki = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ prep_mpdu_test (t, &tp, 0, .mfs_seg_nb = 5, .duration_symb_nb = 95,
+ .symb_nb = 19,
+ .crc_error = { 0xaa55aa55, 0x5a5a5a5a },
+ .pg_sacki = true, .bbf = true,
+ .tmi = TONEMAP_INDEX_INITIAL_START);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+prep_mpdu_test_suite (test_t t)
+{
+ test_suite_begin (t, "prepare mpdu");
+ prep_mpdu_basic_test_case (t);
+ prep_mpdu_basic_rsof_test_case (t);
+ prep_mpdu_ack_test_case (t);
+ prep_mpdu_pg_ack_test_case (t);
+ prep_mpdu_intervals_test_case (t);
+ prep_mpdu_expiration_test_case (t);
+ prep_mpdu_window_size_test_case (t);
+ prep_mpdu_beacon_test_case (t);
+/* prep_mpdu_fsm_test_case (t);*/
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/rx_data.c b/cesar/mac/pbproc/test/pbproc_eoc/src/rx_data.c
new file mode 100644
index 0000000000..190447f5e0
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/rx_data.c
@@ -0,0 +1,1782 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/rx_data.c
+ * \brief RX Data automaton test.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+#include "inc/utils.h"
+
+#include "inc/test_pbproc.h"
+
+#include "mac/common/timings.h"
+#include "hal/phy/inc/context.h"
+
+#include <stdarg.h>
+
+/** RX data burst test MPDU description. */
+struct rx_data_burst_mpdu_t
+{
+ /** Number of symbols. */
+ uint symb_nb;
+ /** Real number of symbols, or 0 if not different. */
+ uint real_symb_nb;
+ /** Number of PB. */
+ uint pb_nb;
+ /** PB Size: false for 520 octets, true for 136 octets. **/
+ bool pb_size_136;
+ /** Tonemap index. */
+ uint tmi;
+ /** Tonemap uniform modulation, or 0 to reuse previous one. */
+ uint tm_mod;
+ /** Payload is encrypted. */
+ bool encrypted;
+ /** NEK switch value (0-1) or STA own NEK (2). */
+ uint nek_switch;
+ /** Use an unknown NEK. */
+ bool bad_nek;
+ /** MPDU count (for bursts). */
+ uint mpdu_cnt;
+ /** Array of CRC error bits. */
+ u32 *crc_error;
+ /** Number of symbols for reverse transmission (RSOF). */
+ uint rev_symb_nb;
+ /** Number of PB for RSOF. */
+ uint rev_pb_nb;
+ /** Reception of rsof */
+ bool rsof;
+ /** bbf - prepare for RSOF */
+ bool bbf;
+ /** time allocated for reverse transmission */
+ uint mrtfl;
+};
+typedef struct rx_data_burst_mpdu_t rx_data_burst_mpdu_t;
+
+/** RX data burst test description. */
+struct rx_data_burst_desc_t
+{
+ /** Wether PRP was won before this reception. */
+ bool prp_won;
+ /** Transmission from an unassociated STA. */
+ bool unassociated;
+ /** Transmission from a STA known to be authenticated. */
+ bool authenticated;
+ /** Link ID. */
+ uint lid;
+ /** Acknowledgment expected. */
+ bool wack;
+ /** Multicast. */
+ bool bcast;
+ /** Multi-network broadcast. */
+ bool multi_net_bcast;
+ /** Window size. */
+ uint window_size_encoded;
+ /** Number of PB in the PB pool. */
+ uint pool_pb_nb;
+ /** Number of channel data. */
+ uint chandata_nb;
+ /** Table of individual MPDU. */
+ rx_data_burst_mpdu_t *mpdu;
+ /** Number of MPDU. */
+ uint mpdu_nb;
+};
+typedef struct rx_data_burst_desc_t rx_data_burst_desc_t;
+
+/** RX data burst test context. */
+struct rx_data_burst_t
+{
+ /** Source TEI. */
+ uint stei;
+ /** Whether the STA was added to MAC store. */
+ bool sta_added;
+ /** Link ID. */
+ uint lid;
+ /** Encoded window size. */
+ u8 window_size_encoded;
+ /** SACKT. */
+ uint sackt[4];
+ /** SACKI encoder. */
+ pbproc_sacki_enc_t sacki_enc;
+ /** Set to false after first MPDU. */
+ bool first;
+ /** Number of block left in pool. */
+ uint pool_size;
+};
+typedef struct rx_data_burst_t rx_data_burst_t;
+
+/** Build a call to rx_data_burst_test_f, see usage below. */
+#define rx_data_burst_test(t, tp, params...) \
+ rx_data_burst_test_f ((t), (tp), \
+ &(rx_data_burst_desc_t) { params })
+#define _one_MPDU_(mpdu...) { mpdu }
+#define _one_MPDU(mpdu) _one_MPDU_ mpdu
+#define MPDU(_mpdu...) \
+ .mpdu = (rx_data_burst_mpdu_t[]) { \
+ PREPROC_FOR_EACH_COMMA (_one_MPDU, _mpdu) }, \
+ .mpdu_nb = PREPROC_NARG (_mpdu)
+
+void
+rx_data_burst_test_mpdu (test_t t, test_pbproc_t *tp,
+ rx_data_burst_desc_t *burst, rx_data_burst_mpdu_t *m,
+ rx_data_burst_t *ctx)
+{
+ test_within (t);
+ dbg_assert (!burst->multi_net_bcast || burst->unassociated);
+ dbg_assert (!burst->multi_net_bcast || burst->bcast);
+ dbg_assert (!burst->authenticated || m->encrypted);
+ u32 date = 123456;
+ tp->config.tei = m->rsof ? 1 : 5; /* TODO put in different place */
+ /* Prepare tone map. */
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint dx = MAC_DX417_TCK;
+ if (m->tmi != PHY_MOD_ROBO || m->encrypted)
+ {
+ tm = utils_sta_prepare_default_tonemap (tp, false, ctx->stei, m->tmi,
+ m->tm_mod, 0, &dx);
+ ctx->sta_added = true;
+ }
+ uint rifs_tck = m->symb_nb == 0 || m->tmi < PHY_MOD_ROBO_NB
+ ? MAC_RIFS_DEFAULT_TCK : MAC_RIFS_SPC_ANY_TCK;
+ if (m->mpdu_cnt)
+ rifs_tck = MAC_BIFS_TCK;
+ /* Encrypted? */
+ utils_prepare_encryption (tp, m->encrypted, burst->authenticated,
+ ctx->stei, m->nek_switch);
+ /* Prepare FC. */
+ const uint fl_tck = MAC_PAYLOAD_TCK (m->symb_nb, dx)
+ + rifs_tck;
+ pbproc_fc_sof_t sof_fc = {
+ .dt_av = PBPROC_FC_DT_SOF,
+ .access = false,
+ .snid = tp->snid + (burst->multi_net_bcast ? 1 : 0),
+ .direction = 0,
+ .dtei = burst->wack ? tp->config.tei : 0xff,
+ .lid = burst->lid,
+ .eks = m->bad_nek ? 1 : (m->encrypted ? 0 : 0x3),
+ .pbsz = m->pb_size_136,
+ .num_sym = MIN (m->symb_nb, 3u),
+ .tmi_av = m->tmi,
+ .fl_av = MAC_TCK_TO_FL (fl_tck),
+ .mpdu_cnt = m->mpdu_cnt,
+ .burst_cnt = 0,
+ .bbf = m->bbf,
+ .mrtfl = MAC_TCK_TO_FL (m->mrtfl),
+ .mcf = burst->bcast,
+ .mnbf = burst->multi_net_bcast,
+ .fccs_av = 0,
+ };
+ pbproc_fc_rsof_t rsof_fc = {
+ .dt_av = PBPROC_FC_DT_RSOF,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = 25,
+ .pbsz = m->pb_size_136,
+ .bdf = true,
+ .num_sym = MIN (m->symb_nb, 3u),
+ .tmi_av = m->tmi,
+ .rsof_fl_av = MAC_TCK_TO_FL (fl_tck),
+ .fccs_av = 0,
+ };
+ const uint rx_fl_tck = MAC_FL_TO_TCK (MAC_TCK_TO_FL (fl_tck));
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + rx_fl_tck;
+ /* Scenario. */
+ const phy_pb_size_t pb_size = m->pb_size_136 ? PHY_PB_SIZE_136 : PHY_PB_SIZE_520;
+ bool drop = m->symb_nb == 0
+ || (burst->bcast && burst->wack && m->bad_nek);
+ uint chandata_nb = burst->chandata_nb && !drop && !burst->unassociated
+ ? burst->chandata_nb : 0;
+ uint nb_pb_it = burst->wack
+ && m->pb_nb > PBPROC_SACKD_ANTICIP_PB_THRESHOLD
+ ? m->pb_nb - PBPROC_SACKD_ANTICIP_PB_NB : m->pb_nb;
+ bool pb_crc_error_first, pb_crc_error_last;
+ pb_crc_error_first = pb_crc_error_last = false;
+ mfs_tx_t *mfs = NULL;
+ if (m->crc_error)
+ {
+ /* Read CRC bitmap to compute CRC status returned by hardware. */
+ u32 *p = m->crc_error;
+ u32 b = 1;
+ uint i;
+ bool *pb_crc_error = &pb_crc_error_first;
+ /* If no intermediary interrupt, go direct to last one. */
+ if (nb_pb_it == m->pb_nb)
+ pb_crc_error = &pb_crc_error_last;
+ /* Read all bits. */
+ for (i = 0; i < m->pb_nb; i++)
+ {
+ /* Second part? */
+ if (i == nb_pb_it)
+ pb_crc_error = &pb_crc_error_last;
+ /* bad CRC? */
+ if (*p & b)
+ *pb_crc_error = true;
+ /* Next bit. */
+ b <<= 1;
+ if (!b)
+ {
+ p++;
+ b = 1;
+ }
+ }
+ }
+ /* Prepare reception */
+ if (m->rsof)
+ {
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ prep->valid = true;
+ prep->bbf = true;
+ prep->lid = burst->lid;
+ prep->eks = 0;
+ prep->tx_date = date;
+ prep->flp_tck = 0;
+ /* prepare false mpdu */
+ prep->main_commit_return_head = 0;
+ prep->main_commit_return_seg_nb = 0;
+ prep->burst_head_ssn = prep->burst_seg_nb =
+ prep->expired_segments_nb = 0;
+ bool added;
+ prep->main_mfs = mfs = mac_store_mfs_add_tx (tp->store, burst->bcast, false,
+ burst->lid, ctx->stei, &added);
+ blk_addref (mfs);
+ test_fail_unless (prep->main_mfs);
+ }
+ else
+ {
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ prep->valid = false;
+ prep->bbf = false;
+ prep->lid = 0;
+ prep->eks = MAC_EKS_CLEAR;
+ }
+ scenario_entry_t entries_long[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date,
+ .prp_won = burst->prp_won,
+ .slot_count = 2,
+ .fc_av = m->rsof
+ ? PARENT_OF (pbproc_fc_t, rsof, &rsof_fc)->words
+ : PARENT_OF (pbproc_fc_t, sof, &sof_fc)->words),
+ SCENARIO_EVENT_COND (ctx->first && burst->prp_won,
+ ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT_COND (ctx->first && !burst->prp_won,
+ ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT_COND (m->tmi >= PHY_MOD_ROBO_NB, phy_set_tonemap),
+ SCENARIO_EVENT (phy_rx_prepare, .nb_pb = m->pb_nb,
+ .mod = m->tmi < PHY_MOD_ROBO_NB ? m->tmi : PHY_MOD_TM,
+ .fecrate = tm->fecrate, .pb_size = pb_size,
+ .gil = tm->gil, .symbol_nb = m->real_symb_nb
+ ? m->real_symb_nb : m->symb_nb,
+ .tcc_halfit = tm->tcc_halfit),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = !m->encrypted || drop,
+ .nb_total = m->pb_nb,
+ .nb_pb_it = m->pb_nb == nb_pb_it && chandata_nb ? 0
+ : nb_pb_it, .chandata = chandata_nb ? true : false,
+ .now = true),
+ SCENARIO_EVENT_COND (m->mpdu_cnt == 0, ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck
+ + (m->rsof ? MAC_US_TO_TCK (60)
+ : MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK)),
+ SCENARIO_EVENT_COND (m->rsof, ca_access_done),
+ SCENARIO_EVENT_COND (m->mpdu_cnt != 0, ca_access_vcs_restart_eifs,
+ .start_date = date + pre_fc_fl_tck),
+ SCENARIO_EVENT_COND (m->mpdu_cnt != 0, phy_rx_activate,
+ .now = false, .date = date + pre_fc_fl_tck
+ + PHY_RX_ACTIVATE_DELAY_AFTER_BURST_TCK,
+ .pre_detection = true),
+ SCENARIO_ACTION_COND (m->pb_nb != nb_pb_it, phy_pbdma, .pb_it = true,
+ .pb_crc_error = pb_crc_error_first,
+ .crc_bitmap = m->crc_error,
+ .crc_bitmap_bits = nb_pb_it),
+ SCENARIO_EVENT_COND (m->pb_nb != nb_pb_it, phy_pbdma_update,
+ .nb_pb_it = chandata_nb ? 0 : m->pb_nb),
+ SCENARIO_ACTION (phy_pbdma, .pb_it = true, .end_rx_pb = true,
+ .pb_crc_error = pb_crc_error_last,
+ .crc_bitmap = m->crc_error,
+ .crc_bitmap_bits = m->pb_nb),
+ SCENARIO_EVENT_COND (burst->wack && m->mpdu_cnt == 0 && !m->bbf && !m->rsof,
+ phy_tx_param_short,
+ .fc_mode = PHY_FC_MODE_AV_1),
+ SCENARIO_EVENT_COND (burst->wack && m->mpdu_cnt == 0 && !m->bbf && !m->rsof,
+ phy_tx_frame,
+ .date = date + pre_fc_fl_tck,
+ .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT_COND (m->bbf && !m->rsof,
+ ca_access_reprogram,
+ .date = date + pre_fc_fl_tck + MAC_US_TO_TCK (100),
+ .duration_tck = m->mrtfl,
+ .lid = burst->lid, .tei = 1),
+ SCENARIO_EVENT_COND (!drop, pbproc_rx_cb, .pb_nb = m->pb_nb,
+ .chandata_nb = chandata_nb,
+ .fl_tck = rx_fl_tck,
+ .pb_size = pb_size,
+ .mpdu_cnt = m->mpdu_cnt,
+ .mfs_cmd_data = !burst->bcast ? MFS_FSM_CMD_INIT
+ : MFS_FSM_CMD_NOP,
+ .mfs_cmd_mme = MFS_FSM_CMD_NOP),
+ SCENARIO_END
+ };
+ scenario_entry_t entries_short[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date,
+ .prp_won = burst->prp_won,
+ .slot_count = 2,
+ .fc_av = PARENT_OF (pbproc_fc_t, sof,
+ &sof_fc)->words),
+ SCENARIO_EVENT_COND (ctx->first && burst->prp_won,
+ ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT_COND (ctx->first && !burst->prp_won,
+ ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT_COND (burst->wack && m->mpdu_cnt == 0,
+ phy_tx_param_short,
+ .fc_mode = PHY_FC_MODE_AV_1),
+ SCENARIO_EVENT_COND (burst->wack && m->mpdu_cnt == 0,
+ phy_tx_frame,
+ .date = date + pre_fc_fl_tck,
+ .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT_COND (m->mpdu_cnt == 0, ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_CIFS_TCK),
+ SCENARIO_EVENT_COND (m->mpdu_cnt != 0, ca_access_vcs_restart_eifs,
+ .start_date = date + pre_fc_fl_tck),
+ SCENARIO_EVENT_COND (m->mpdu_cnt != 0, phy_rx_activate,
+ .now = false, .date = date + pre_fc_fl_tck
+ + PHY_RX_ACTIVATE_DELAY_AFTER_BURST_TCK,
+ .pre_detection = true),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ /* Run scenario. */
+ scenario_run (t, m->symb_nb ? entries_long : entries_short, &globals);
+ /* Check pool. */
+ test_fail_unless (tp->pbproc->rx_pool_size == ctx->pool_size
+ - (!drop ? 1 + m->pb_nb + chandata_nb : 0));
+ ctx->pool_size = tp->pbproc->rx_pool_size;
+ /* Build SACK to check. */
+ if (burst->wack)
+ {
+ dbg_assert (m->mpdu_cnt < COUNT (ctx->sackt));
+ if (m->symb_nb == 0)
+ {
+ ctx->sackt[m->mpdu_cnt] = PBPROC_FC_SACKT_UNIFORM;
+ uint sacki_uniform = PBPROC_FC_SACKI_UNIFORM_ALL_ERROR;
+ pbproc_sacki_enc_copy (&ctx->sacki_enc, &sacki_uniform,
+ PBPROC_FC_SACKI_UNIFORM_SIZE);
+ }
+ else if (!pb_crc_error_first && !pb_crc_error_last)
+ {
+ ctx->sackt[m->mpdu_cnt] = PBPROC_FC_SACKT_UNIFORM;
+ uint sacki_uniform = PBPROC_FC_SACKI_UNIFORM_ALL_OK;
+ pbproc_sacki_enc_copy (&ctx->sacki_enc, &sacki_uniform,
+ PBPROC_FC_SACKI_UNIFORM_SIZE);
+ }
+ else
+ {
+ ctx->sackt[m->mpdu_cnt] = PBPROC_FC_SACKT_MIXED;
+ /* Do not check SACKI, it was checked in its own test. */
+ uint sacki = 0xdead;
+ pbproc_sacki_enc_copy (&ctx->sacki_enc, &sacki, 16);
+ }
+ }
+ /* Check SACK. */
+ if (burst->wack && m->mpdu_cnt == 0 && !m->bbf && !m->rsof)
+ {
+ pbproc_fc_sack_t sack = PARENT_OF (pbproc_fc_t, words,
+ tp->pbproc->phy->tx_fc)->sack;
+ test_fail_unless (sack.dt_av == PBPROC_FC_DT_SACK);
+ test_fail_unless (sack.access == false);
+ test_fail_unless (sack.snid == tp->snid);
+ test_fail_unless (sack.dtei == ctx->stei);
+ test_fail_unless (sack.cfs == true);
+ test_fail_unless (sack.bdf == false);
+ test_fail_unless (sack.svn == 0);
+ test_fail_unless (sack.rrtf == 0);
+ test_fail_unless (sack.mfs_rsp_data == MFS_FSM_RSP_ACK);
+ test_fail_unless (sack.mfs_rsp_mgmt == MFS_FSM_RSP_ACK);
+ uint sackt[COUNT (ctx->sackt)] = {
+ sack.sackt0, sack.sackt1, sack.sackt2, sack.sackt3
+ };
+ bool mixed = false;
+ uint i;
+ for (i = 0; i < COUNT (ctx->sackt); i++)
+ {
+ if (ctx->sackt[i] == PBPROC_FC_SACKT_MIXED)
+ {
+ test_fail_unless (
+ sackt[i] == PBPROC_FC_SACKT_MIXED
+ || sackt[i] == PBPROC_FC_SACKT_MIXED_COMPRESSED);
+ mixed = true;
+ }
+ else
+ test_fail_unless (sackt[i] == ctx->sackt[i]);
+ }
+ if (!mixed)
+ {
+ test_fail_unless (sack.sacki[0] == ctx->sacki_enc.si[0]);
+ test_fail_unless (sack.sacki[1] == ctx->sacki_enc.si[1]);
+ if (MAC_LID_IS_PLID (burst->lid))
+ test_fail_unless ((sack.sacki_last & 0xf)
+ == ctx->sacki_enc.si[2]);
+ else
+ test_fail_unless (sack.sacki_last == ctx->sacki_enc.si[2]);
+ }
+ if (MAC_LID_IS_PLID (burst->lid))
+ test_fail_unless (sack.sacki_last >> 4
+ == ctx->window_size_encoded);
+ }
+ /* Check SACK. */
+ if (burst->wack && m->mpdu_cnt == 0 && m->bbf)
+ {
+ pbproc_sackd_t *sackd = &tp->pbproc->recv_mpdu.sackd;
+ test_fail_if (MAC_LID_IS_PLID (sackd->lid));
+ test_fail_unless (sackd->tei == MAC_TEI_CCO_DEF);
+ test_fail_unless (sackd->sacki_enc.sil + sackd->sacki_enc.sis
+ == PBPROC_FC_SACKI_EOC_RSOF_SIZE);
+ test_fail_unless (tp->pbproc->recv_mpdu.bbf);
+ test_fail_unless (tp->pbproc->recv_mpdu.mrtfl == m->mrtfl);
+ }
+ /* Release allocated mfs for false prepared mpdu */
+ if (m->rsof)
+ {
+ if (mfs)
+ {
+ mac_store_mfs_remove (tp->store, PARENT_OF (mfs_t, tx, mfs));
+ blk_release (mfs);
+ }
+ }
+ ctx->first = false;
+}
+
+void
+rx_data_burst_test_f (test_t t, test_pbproc_t *tp,
+ rx_data_burst_desc_t *burst)
+{
+ test_within (t);
+ uint i, mpdu_i;
+ rx_data_burst_t ctx;
+ ctx.stei = 1; /* 1 default CCO, even in not assoc state stei = 1 */
+ ctx.lid = 1;
+ ctx.sta_added = false;
+ ctx.sackt[0] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ ctx.sackt[1] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ ctx.sackt[2] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ ctx.sackt[3] = PBPROC_FC_SACKT_NOT_RECEIVED;
+ ctx.first = true;
+ pbproc_sacki_enc_init (&ctx.sacki_enc, PBPROC_FC_SACK_SACKI_BITS - 4,
+ true);
+ /* Prepare channel data configuration. */
+ u32 chandata_conf[burst->chandata_nb];
+ if (burst->chandata_nb)
+ {
+ for (i = 0; i < burst->chandata_nb; i++)
+ chandata_conf[i] = i;
+ pbproc_set_chandata_conf (tp->pbproc,
+ (phy_chandata_conf_t *) chandata_conf,
+ burst->chandata_nb, true);
+ }
+ /* Allocate PB pool. */
+ blk_t *first, *last;
+ ctx.pool_size = burst->mpdu_nb + burst->pool_pb_nb;
+ first = blk_alloc_desc_range (ctx.pool_size, &last);
+ pbproc_rx_segment_refill (tp->pbproc, PARENT_OF (pb_t, blk, first),
+ PARENT_OF (pb_t, blk, last), ctx.pool_size);
+ /* Create an MFS if window_size is not default. */
+ mfs_rx_t *mfs = NULL;
+ if (burst->window_size_encoded)
+ {
+ bool added;
+ mfs = mac_store_mfs_add_rx (tp->store, burst->bcast, false,
+ burst->lid, ctx.stei, &added);
+ dbg_assert (added);
+ mfs->window_size_encoded = burst->window_size_encoded;
+ mfs->window_size = mfs_window_size[burst->window_size_encoded];
+ ctx.window_size_encoded = mfs->window_size_encoded;
+ }
+ else
+ ctx.window_size_encoded = MFS_RX_WINDOW_SIZE_DATA_DEFAULT_ENCODED;
+ /* Reset stats. */
+ test_pbproc_check_stats_reset (tp);
+ uint bad_symb_nb = 0, null_symb_nb = 0;
+ /* Receive every MPDU. */
+ test_pbproc_alloc (tp, false, 0);
+ for (mpdu_i = 0; mpdu_i < burst->mpdu_nb; mpdu_i++)
+ {
+ rx_data_burst_mpdu_t *m = &burst->mpdu[mpdu_i];
+ /* Run scenario. */
+ rx_data_burst_test_mpdu (t, tp, burst, m, &ctx);
+ if (m->real_symb_nb)
+ bad_symb_nb++;
+ if (m->symb_nb == 0)
+ null_symb_nb++;
+ }
+ /* Check stats. */
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = burst->prp_won ? 0 : 1,
+ .cw_lost = burst->prp_won ? 1 : 0,
+ .rx_handle_fc = burst->mpdu_nb,
+ .rx_data = burst->mpdu_nb,
+ .rx_data_wack = burst->wack ? burst->mpdu_nb - null_symb_nb : 0,
+ .rx_data_woack = !burst->wack ? burst->mpdu_nb - null_symb_nb : 0,
+ .rx_data_error = null_symb_nb,
+ .rx_data_empty = null_symb_nb,
+ .rx_data_bad_symb_nb = bad_symb_nb);
+ /* Check return to IDLE state. */
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ /* Cleanup. */
+ if (tp->pbproc->rx_pool_size)
+ {
+ blk_release_desc_range (&tp->pbproc->rx_pool_head->blk,
+ &tp->pbproc->rx_pool_tail->blk);
+ slist_init (tp->pbproc->rx_pool_, paste_size);
+ }
+ if (ctx.sta_added)
+ dbg_check (mac_store_sta_remove (tp->store, ctx.stei));
+ tp->config.authenticated = false;
+ if (mfs)
+ {
+ mac_store_mfs_remove (tp->store, PARENT_OF (mfs_t, rx, mfs));
+ blk_release (mfs);
+ }
+ if (burst->chandata_nb)
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0, false);
+}
+
+void
+rx_beacon_test (test_t t, test_pbproc_t *tp, u32 date, uint symb_nb)
+{
+ test_within (t);
+ pbproc_fc_beacon_t beacon_fc = {
+ .dt_av = PBPROC_FC_DT_BEACON,
+ .access = false,
+ .snid = tp->snid,
+ .bts_lsb24 = 0x345678,
+ .bts_msb8 = 0x12,
+ .bto0 = 0x0123,
+ .bto1_lsb8 = 0x34,
+ .bto1_msb8 = 0x12,
+ .bto2 = 0x2345,
+ .bto3_lsb8 = 0x56,
+ .bto3_msb8 = 0x34,
+ .fccs_av = 0,
+ };
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_HYBRID_TCK + MAC_FC_10_TCK
+ + MAC_FC_AV_TCK + MAC_PAYLOAD_TCK (symb_nb, MAC_DX567_TCK)
+ + MAC_B2BIFS_TCK;
+ test_pbproc_check_stats_reset (tp);
+ test_pbproc_alloc (tp, true, 0);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .rx_sysdate = date / 2,
+ .prp_won = false,
+ .fc_av = PARENT_OF (pbproc_fc_t, beacon,
+ &beacon_fc)->words),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare, .nb_pb = 1,
+ .mod = PHY_MOD_MINI_ROBO,
+ .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_136, .gil = PHY_GIL_567,
+ .symbol_nb = symb_nb, .tcc_halfit = 1),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true,
+ .nb_total = 1, .nb_pb_it = 1, .chandata = false,
+ .now = true),
+ SCENARIO_ACTION (phy_pbdma, .pb_it = true, .end_rx_pb = true),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck),
+ SCENARIO_EVENT (pbproc_rx_beacon_cb, .duration_tck = 0),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ blk_t *pb;
+ pb = blk_alloc_desc ();
+ uint old_pool_size = tp->pbproc->rx_pool_size;
+ pbproc_rx_segment_refill (tp->pbproc, PB_FROM_BLK (pb), PB_FROM_BLK (pb),
+ 1);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (t, tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_beacon = 1);
+ test_fail_unless (tp->pbproc->rx_pool_size == old_pool_size);
+ test_fail_unless (old_pool_size != 0 || tp->pbproc->rx_pool_head == NULL);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+rx_data_basic_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "basic");
+ test_pbproc_init (&tp);
+ test_begin (t, "robo unicast reverse")
+ {
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ .lid = 4,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .bbf = true,
+ .mrtfl = MAC_FL_TO_TCK (MAC_TCK_TO_FL (50000)))));
+ } test_end;
+ test_begin (t, "robo unicast encrypted rsof")
+ {
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .encrypted = true, .nek_switch = 0,
+ .rsof = true)));
+ } test_end;
+ test_begin (t, "robo unicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = true, .pool_pb_nb = 7, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo window size")
+ {
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ .lid = 1,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ .lid = 5,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ .lid = 1, .window_size_encoded = MFS_WINDOW_SIZE_160,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ .lid = 5, .window_size_encoded = MFS_WINDOW_SIZE_160,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo unicast chandata")
+ {
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 16, .wack = true,
+ .chandata_nb = 11,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = true, .pool_pb_nb = 18, .wack = true,
+ .chandata_nb = 11,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo multicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .bcast = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo multicast partial ack")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true, .bcast = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo unicast unassociated")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true, .unassociated = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ /* No chandata in unassoc state in EoC
+ test_begin (t, "robo unicast unassociated chandata")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 16, .wack = true, .unassociated = true,
+ .chandata_nb = 11,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ */
+ test_begin (t, "robo multicast unassociated")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .bcast = true, .unassociated = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo multi network multicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .bcast = true, .unassociated = true,
+ .multi_net_bcast = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "hs-robo unicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 50, .pb_nb = 5, .tmi = PHY_MOD_HS_ROBO)));
+ } test_end;
+ test_begin (t, "mini robo unicast PB136")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 1, .wack = true,
+ MPDU ((.symb_nb = 6, .pb_nb = 1, .pb_size_136 = true,
+ .tmi = PHY_MOD_MINI_ROBO)));
+ } test_end;
+ test_begin (t, "tm unicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 6, .wack = true,
+ MPDU ((.symb_nb = 4, .pb_nb = 6, .tmi = 5, .tm_mod = 10)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 1, .wack = true,
+ MPDU ((.symb_nb = 1, .pb_nb = 1, .tmi = 5, .tm_mod = 10)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 2, .wack = true,
+ MPDU ((.symb_nb = 2, .pb_nb = 2, .tmi = 5, .tm_mod = 10)));
+ } test_end;
+ test_begin (t, "tm unicast PB136")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 1, .wack = true,
+ MPDU ((.symb_nb = 2, .pb_nb = 1, .pb_size_136 = true,
+ .tmi = 5, .tm_mod = 1)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 1, .wack = true,
+ MPDU ((.symb_nb = 1, .pb_nb = 1, .pb_size_136 = true,
+ .tmi = 5, .tm_mod = 10)));
+ } test_end;
+ test_begin (t, "tm unicast large")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 41, .wack = true,
+ MPDU ((.symb_nb = 25, .pb_nb = 41, .tmi = 5, .tm_mod = 10)));
+ } test_end;
+ test_begin (t, "tm unicast large chandata")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 46, .wack = true, .chandata_nb = 5,
+ MPDU ((.symb_nb = 25, .pb_nb = 41, .tmi = 5, .tm_mod = 10)));
+ } test_end;
+ test_begin (t, "robo unicast encrypted sta unknown")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .encrypted = true, .nek_switch = 0)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .encrypted = true, .nek_switch = 0)));
+ } test_end;
+ test_begin (t, "robo unicast encrypted sta known")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true, .authenticated = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .encrypted = true, .nek_switch = 0)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true, .authenticated = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .encrypted = true, .nek_switch = 0)));
+ } test_end;
+ test_begin (t, "robo unicast encrypted subavln")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true, .authenticated = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .encrypted = true, .nek_switch = 0)));
+ } test_end;
+ test_begin (t, "robo unicast crc error none")
+ {
+ u32 crc_error[8] = { 0x00, };
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .crc_error = crc_error)));
+ } test_end;
+ test_begin (t, "robo unicast crc error one")
+ {
+ u32 crc_error[8] = { 0x01, };
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .crc_error = crc_error)));
+ } test_end;
+ test_begin (t, "robo unicast crc error many")
+ {
+ u32 crc_error[8] = { 0x1d, };
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .crc_error = crc_error)));
+ } test_end;
+ test_begin (t, "tm unicast large crc error few")
+ {
+ u32 crc_error[8] = { 0x10000001, 0x010 };
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 41, .wack = true,
+ MPDU ((.symb_nb = 25, .pb_nb = 41, .tmi = 5, .tm_mod = 10,
+ .crc_error = crc_error)));
+ } test_end;
+ test_begin (t, "tm unicast large crc error many")
+ {
+ u32 crc_error[8] = { 0xffefdff7, 0x1fb };
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 41, .wack = true,
+ MPDU ((.symb_nb = 25, .pb_nb = 41, .tmi = 5, .tm_mod = 10,
+ .crc_error = crc_error)));
+ } test_end;
+ test_begin (t, "robo multicast partial ack unauthenticated encrypted")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true, .bcast = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .bad_nek = true)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 16, .wack = true, .bcast = true,
+ .chandata_nb = 11,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .bad_nek = true)));
+ } test_end;
+ test_begin (t, "beacon")
+ {
+ rx_beacon_test (t, &tp, 123654, 6);
+ blk_t *pb;
+ pb = blk_alloc_desc ();
+ pbproc_rx_segment_refill (tp.pbproc, PB_FROM_BLK (pb),
+ PB_FROM_BLK (pb), 1);
+ rx_beacon_test (t, &tp, 123654, 6);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+rx_data_burst_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "burst");
+ test_pbproc_init (&tp);
+ test_begin (t, "robo unicast burst 2")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 10, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "robo unicast burst 3")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 15, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 2),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "robo unicast burst 4")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 20, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 3),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 2),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "robo unicast chandata")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 4 * 16, .wack = true, .chandata_nb = 11,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 3),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 2),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "robo multicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 4 * 5, .bcast = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 3),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 2),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "tm unicast")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 50, .wack = true,
+ MPDU ((.symb_nb = 4, .pb_nb = 6, .tmi = 5, .tm_mod = 10,
+ .mpdu_cnt = 3),
+ (.symb_nb = 1, .pb_nb = 1, .tmi = 5,
+ .mpdu_cnt = 2),
+ (.symb_nb = 2, .pb_nb = 2, .tmi = 5,
+ .mpdu_cnt = 1),
+ (.symb_nb = 25, .pb_nb = 41, .tmi = 5,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "robo/tm unicast crc error")
+ {
+ u32 crc_error[][8] = {
+ { 0x00, },
+ { 0x01, },
+ { 0x1d, },
+ { 0x10000001, 0x010 },
+ };
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 56, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 3),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 2, .crc_error = crc_error[1]),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1, .crc_error = crc_error[2]),
+ (.symb_nb = 25, .pb_nb = 41, .tmi = 5, .tm_mod = 10,
+ .mpdu_cnt = 0, .crc_error = crc_error[3])));
+ } test_end;
+ test_begin (t, "robo unicast hole")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 20, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 3),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "robo multicast partial ack unauthenticated encrypted"
+ " hole")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 15, .wack = true, .bcast = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 2),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1, .bad_nek = true),
+ (.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 0)));
+ } test_end;
+ test_begin (t, "burst interruption")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 10, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO,
+ .mpdu_cnt = 1),
+ (.symb_nb = 0, .pb_nb = 0, .mpdu_cnt = 0)));
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+enum rx_data_nfu_t
+{
+ NFU_SACK,
+ NFU_SOF_ACCESS,
+ NFU_SOF_SNID,
+ NFU_SOF_TEI,
+ NFU_SOF_UNASSOC_SNID,
+ NFU_OUT_OF_ALLOC,
+ NFU_POOL_SHORTAGE,
+};
+typedef enum rx_data_nfu_t rx_data_nfu_t;
+
+void
+rx_data_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_data_nfu_t nfu)
+{
+ test_within (t);
+ u32 restart_date;
+ uint length_tck;
+ pbproc_fc_t fc;
+ const uint sof_fl_tck = MAC_PAYLOAD_TCK (45, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK;
+ pbproc_fc_sof_t sof_fc = {
+ .dt_av = PBPROC_FC_DT_SOF,
+ .access = nfu == NFU_SOF_ACCESS,
+ .snid = nfu != NFU_SOF_SNID ? tp->snid : tp->snid + 1,
+ .direction = 0,
+ .dtei = nfu != NFU_SOF_TEI ? tp->config.tei : tp->config.tei + 8,
+ .lid = 1,
+ .eks = 0x2,
+ .pbsz = false,
+ .num_sym = MIN (45u, 3u),
+ .tmi_av = PHY_MOD_ROBO,
+ .fl_av = MAC_TCK_TO_FL (sof_fl_tck),
+ .mpdu_cnt = 0,
+ .burst_cnt = 0,
+ .bbf = false,
+ .mrtfl = 0,
+ .mcf = false,
+ .mnbf = false,
+ .fccs_av = 0,
+ };
+ pbproc_fc_sack_t sack_fc = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = 1/*tp->config.tei*/,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = 0,
+ .fccs_av = 0,
+ };
+ if (nfu == NFU_SACK)
+ {
+ fc.sack = sack_fc;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ }
+ else
+ {
+ fc.sof = sof_fc;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_FL_TO_TCK (MAC_TCK_TO_FL (sof_fl_tck))
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ }
+ if (nfu == NFU_OUT_OF_ALLOC)
+ {
+ date += 0x80000000;
+ restart_date = date + length_tck - MAC_PREAMBLE_TCK - MAC_FC_AV_TCK -
+ MAC_CIFS_TCK;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ }
+ else
+ {
+ restart_date = date;
+ }
+ uint our_tei_saved = tp->config.tei;
+ if (nfu == NFU_SOF_UNASSOC_SNID)
+ tp->config.tei = 0;
+ test_pbproc_check_stats_reset (tp);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .slot_count = 2, .fc_av = fc.words),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = restart_date + length_tck),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_nfu = nfu == NFU_OUT_OF_ALLOC ? 0 : 1,
+ .rx_data = nfu == NFU_OUT_OF_ALLOC ? 1 : 0,
+ .rx_data_error = nfu == NFU_OUT_OF_ALLOC ? 1 : 0,
+ .rx_out_of_alloc = nfu == NFU_OUT_OF_ALLOC ? 1 : 0);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ tp->config.tei = our_tei_saved;
+}
+
+/**
+ * Test beacon to be ignored.
+ * \param t test context
+ * \param tp test_pbproc context
+ * \param nfu NFU kind
+ */
+static void
+rx_beacon_nfu_test (test_t t, test_pbproc_t *tp, rx_data_nfu_t nfu)
+{
+ test_within (t);
+ /* Prepare FC. */
+ pbproc_fc_beacon_t beacon_fc = {
+ .dt_av = PBPROC_FC_DT_BEACON,
+ .access = false,
+ .snid = tp->snid,
+ .bts_lsb24 = 0x345678,
+ .bts_msb8 = 0x12,
+ .bto0 = 0x0123,
+ .bto1_lsb8 = 0x34,
+ .bto1_msb8 = 0x12,
+ .bto2 = 0x2345,
+ .bto3_lsb8 = 0x56,
+ .bto3_msb8 = 0x34,
+ .fccs_av = 0,
+ };
+ u32 date = 12345;
+ if (nfu == NFU_OUT_OF_ALLOC)
+ /* Date to overshoot allocation. */
+ date = 0x80000000 - MAC_PREAMBLE_HYBRID_TCK / 2;
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_HYBRID_TCK + MAC_FC_10_TCK
+ + MAC_FC_AV_TCK + MAC_PAYLOAD_TCK (6, MAC_DX567_TCK)
+ + MAC_B2BIFS_TCK;
+ if (nfu != NFU_POOL_SHORTAGE)
+ tp->pbproc->rx_pool_size = 1;
+ /* Use another state to test return to IDLE. */
+ tp->pbproc->fsm.current_state = PBPROC_FSM_STATE_RX_BURST;
+ /* Reset stats. */
+ test_pbproc_check_stats_reset (tp);
+ /* Scenario. */
+ test_pbproc_alloc (tp, true, 0);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .fc_av = PARENT_OF (pbproc_fc_t, beacon,
+ &beacon_fc)->words),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ scenario_run (t, entries, &globals);
+ /* Check stats. */
+ test_pbproc_check_stats (
+ t, tp,
+ .rx_handle_fc = 1,
+ .rx_beacon = 1,
+ .rx_out_of_alloc = nfu == NFU_OUT_OF_ALLOC ? 1 : 0,
+ .rx_pool_shortage = nfu == NFU_POOL_SHORTAGE ? 1 : 0);
+ /* Check PBProc state. */
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ test_fail_unless (tp->pbproc->rx_pool_size == (nfu != NFU_POOL_SHORTAGE
+ ? 1 : 0));
+ tp->pbproc->rx_pool_size = 0;
+}
+
+enum rx_data_sack_error_t
+{
+ SACK_ERROR_TM_TMI_UNAVAILABLE,
+ SACK_ERROR_TM_STA_UNAVAILABLE,
+ SACK_ERROR_TM_UNASSOCIATED,
+ SACK_ERROR_TM_BCAST,
+ SACK_ERROR_ENC_STA_NO_NEK,
+ SACK_ERROR_ENC_NO_EKS,
+ SACK_ERROR_ENC_UNASSOCIATED,
+ SACK_ERROR_POOL_SHORTAGE,
+ SACK_ERROR_EMPTY,
+ WOACK_ERROR_TM,
+ WOACK_ERROR_ENC,
+};
+typedef enum rx_data_sack_error_t rx_data_sack_error_t;
+
+void
+rx_data_sack_error_test (test_t t, test_pbproc_t *tp,
+ rx_data_sack_error_t sack_error, ...)
+{
+ uint date = 123456;
+ test_within (t);
+ uint sack_uniform[] = {
+ PBPROC_FC_SACKI_UNIFORM_TMI_RESTART,
+ PBPROC_FC_SACKI_UNIFORM_TMI_RESTART,
+ PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO,
+ PBPROC_FC_SACKI_UNIFORM_TMI_DEFAULT_ROBO,
+ PBPROC_FC_SACKI_UNIFORM_NEK_ERROR,
+ PBPROC_FC_SACKI_UNIFORM_NEK_ERROR,
+ PBPROC_FC_SACKI_UNIFORM_NEK_ERROR,
+ PBPROC_FC_SACKI_UNIFORM_ALL_ERROR,
+ PBPROC_FC_SACKI_UNIFORM_ALL_ERROR,
+ };
+ uint symb_nb;
+ if (sack_error == SACK_ERROR_EMPTY)
+ {
+ va_list ap;
+ va_start (ap, sack_error);
+ symb_nb = va_arg (ap, uint);
+ va_end (ap);
+ }
+ else
+ symb_nb = 38;
+ const uint fl_tck = MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK;
+ bool sta = false;
+ if (sack_error == SACK_ERROR_TM_TMI_UNAVAILABLE
+ || sack_error == SACK_ERROR_ENC_STA_NO_NEK)
+ {
+ mac_store_sta_add (tp->store, 5);
+ sta = true;
+ }
+ uint tmi, eks;
+ if (sack_error == SACK_ERROR_TM_TMI_UNAVAILABLE
+ || sack_error == SACK_ERROR_TM_STA_UNAVAILABLE
+ || sack_error == SACK_ERROR_TM_UNASSOCIATED
+ || sack_error == SACK_ERROR_TM_BCAST
+ || sack_error == WOACK_ERROR_TM)
+ {
+ tmi = 5;
+ eks = 0xf;
+ }
+ else if (sack_error == SACK_ERROR_POOL_SHORTAGE)
+ {
+ tmi = PHY_MOD_ROBO;
+ eks = 0xf;
+ }
+ else
+ {
+ tmi = PHY_MOD_ROBO;
+ eks = 2;
+ }
+ bool wack = !(sack_error == WOACK_ERROR_TM
+ || sack_error == WOACK_ERROR_ENC);
+ bool unassociated = sack_error == SACK_ERROR_TM_UNASSOCIATED
+ || sack_error == SACK_ERROR_ENC_UNASSOCIATED;
+ tp->config.tei = (wack)?1:5;
+ pbproc_fc_sof_t fc = {
+ .dt_av = PBPROC_FC_DT_SOF,
+ .access = false,
+ .snid = tp->snid,
+ .direction = wack,
+ .dtei = wack ? (unassociated ? 0 : 5) : 0xff,
+ .lid = 1,
+ .eks = eks,
+ .pbsz = false,
+ .num_sym = MIN (symb_nb, 3u),
+ .tmi_av = tmi,
+ .fl_av = MAC_TCK_TO_FL (fl_tck),
+ .mpdu_cnt = 0,
+ .burst_cnt = 0,
+ .bbf = false,
+ .mrtfl = 0,
+ .mcf = !wack || sack_error == SACK_ERROR_TM_BCAST,
+ .mnbf = false,
+ .fccs_av = 0,
+ };
+ uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_FL_TO_TCK (MAC_TCK_TO_FL (fl_tck));
+ test_pbproc_check_stats_reset (tp);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .slot_count = 2,
+ .fc_av = PARENT_OF (pbproc_fc_t, sof, &fc)->words),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT_COND (wack, phy_tx_param_short,
+ .fc_mode = PHY_FC_MODE_AV_1),
+ SCENARIO_EVENT_COND (wack, phy_tx_frame, .date = date + pre_fc_fl_tck,
+ .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ scenario_run (t, entries, &globals);
+ /* Check stats. */
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_data = 1,
+ .rx_data_error = 1,
+ .rx_data_empty = sack_error == SACK_ERROR_EMPTY ? 1 : 0,
+ .rx_pool_shortage = sack_error == SACK_ERROR_POOL_SHORTAGE ? 1 : 0);
+ /* Check SACK. */
+ if (wack)
+ {
+ pbproc_fc_sack_t sack = PARENT_OF (pbproc_fc_t, words,
+ tp->pbproc->phy->tx_fc)->sack;
+ test_fail_unless (sack.dt_av == PBPROC_FC_DT_SACK);
+ test_fail_unless (sack.access == false);
+ test_fail_unless (sack.snid == tp->snid);
+ test_fail_unless (sack.dtei == (unassociated ? 0 : 5));
+ test_fail_unless (sack.cfs == tp->pbproc->access.cfp);
+ test_fail_unless (sack.bdf == false);
+ test_fail_unless (sack.svn == 0);
+ test_fail_unless (sack.rrtf == 0);
+ test_fail_unless (sack.mfs_rsp_data == MFS_FSM_RSP_ACK);
+ test_fail_unless (sack.mfs_rsp_mgmt == MFS_FSM_RSP_ACK);
+ test_fail_unless (sack.sackt3 == PBPROC_FC_SACKT_NOT_RECEIVED);
+ test_fail_unless (sack.sackt2 == PBPROC_FC_SACKT_NOT_RECEIVED);
+ test_fail_unless (sack.sackt1 == PBPROC_FC_SACKT_NOT_RECEIVED);
+ test_fail_unless (sack.sackt0 == PBPROC_FC_SACKT_UNIFORM);
+ test_fail_unless (sack.sacki[0] == sack_uniform[sack_error]);
+ test_fail_unless (sack.sacki[1] == 0);
+ test_fail_unless (sack.sacki_last
+ == MFS_RX_WINDOW_SIZE_DATA_DEFAULT_ENCODED << 4);
+ }
+ /* Cleanup. */
+ if (sta)
+ dbg_check (mac_store_sta_remove (tp->store, 5));
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+rx_data_fc10 (test_t t, test_pbproc_t *tp, u32 fc10, bool crc_error,
+ uint length, bool hp10_detected, bool hp11_detected)
+{
+ test_within (t);
+ uint date = 12345678;
+ test_pbproc_check_stats_reset (tp);
+ bool hp10_was_detected = tp->pbproc->detect.hp10_detected;
+ bool hp11_was_detected = tp->pbproc->detect.hp11_detected;
+ tp->pbproc->detect.hp10_detect_date = 0x12345678;
+ tp->pbproc->detect.hp11_detect_date = 0x01234567;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .fc_av = NULL, .fc10 = fc10),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT_COND (length, ca_access_vcs_restart,
+ .end_date = date + length
+ + MAC_HP10_PREAMBLE_DELTA_TCK),
+ SCENARIO_EVENT_COND (!length, ca_access_vcs_restart_eifs,
+ .start_date = date),
+ SCENARIO_EVENT_COND (!length, phy_rx_activate, .now = false,
+ .date = date + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + PHY_RX_ACTIVATE_DELAY_AFTER_SHORT_TCK,
+ .pre_detection = true),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_nfu = crc_error ? 0 : 1,
+ .rx_crc_error = crc_error ? 1 : 0,
+ );
+ test_fail_unless (!hp10_detected
+ || tp->pbproc->detect.hp10_detect_date == date);
+ test_fail_unless (tp->pbproc->detect.hp10_detected == (hp10_detected ||
+ hp10_was_detected));
+ test_fail_unless (!hp11_detected
+ || tp->pbproc->detect.hp11_detect_date == date);
+ test_fail_unless (tp->pbproc->detect.hp11_detected == (hp11_detected ||
+ hp11_was_detected));
+ tp->pbproc->detect.hp10_detected = false;
+ tp->pbproc->detect.hp11_detected = false;
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+rx_data_errors_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "errors");
+ test_pbproc_init (&tp);
+ tp.config.tei = 1; /* Test STA->CCO direction */
+ test_begin (t, "crc error")
+ {
+ uint date = 12345678;
+ test_pbproc_check_stats_reset (&tp);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date,
+ .rx_sysdate = date * 21 / 20,
+ .prp_won = false, .fc_av = NULL),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart, .
+ end_date = date + MAC_FL_TO_TCK (MAC_MAX_FL_MIN_FL)),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + PHY_RX_ACTIVATE_DELAY_AFTER_SHORT_TCK,
+ .pre_detection = true),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = &tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (
+ t, &tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_crc_error = 1,
+ );
+ test_fail_unless (tp.pbproc->fsm.current_state
+ == PBPROC_FSM_STATE_IDLE);
+ } test_end;
+ /* SOF with response: wait for EOF.
+ * SOF without response: wait for EOF unless hp1x is detected yet, in this
+ * case use frame length to resynchronise. */
+ /*
+ test_begin (t, "fc10 sof")
+ {
+ rx_data_fc10 (t, &tp, 0x0000a0ab, true, 0, false, false);
+ rx_data_fc10 (t, &tp, 0x0020a0ab, true, 0, false, false);
+ } test_end;
+ test_begin (t, "fc10 sof, hp1x detected")
+ {
+ tp.pbproc->detect.hp10_detected = true;
+ rx_data_fc10 (t, &tp, 0x0000a0ab, false, MAC_HP10_DELIMITER_TCK
+ + (20 + 5 * 20) * MAC_HP10_SYMBOL_TCK + MAC_HP10_EFG_TCK
+ + MAC_HP10_DELIMITER_TCK + MAC_HP10_CIFS_TCK, false,
+ false);
+ tp.pbproc->detect.hp10_detected = true;
+ rx_data_fc10 (t, &tp, 0x0020a0ab, true, 0, false, false);
+ tp.pbproc->detect.hp11_detected = true;
+ rx_data_fc10 (t, &tp, 0x0000a0ab, false, MAC_HP10_DELIMITER_TCK
+ + (20 + 5 * 20) * MAC_HP10_SYMBOL_TCK + MAC_HP10_EFG_TCK
+ + MAC_HP10_DELIMITER_TCK + MAC_HP10_CIFS_TCK, false,
+ false);
+ tp.pbproc->detect.hp11_detected = true;
+ rx_data_fc10 (t, &tp, 0x0020a0ab, true, 0, false, false);
+ } test_end;
+ */
+ /* EOF with response, detect and synchronise. */
+ /*
+ test_begin (t, "fc10 hp10 eof with response")
+ {
+ rx_data_fc10 (t, &tp, 0x006000ab, false, MAC_HP10_DELIMITER_TCK
+ + MAC_HP10_RIFS_TCK + MAC_HP10_DELIMITER_TCK
+ + MAC_HP10_CIFS_TCK, true, false);
+ } test_end;
+ test_begin (t, "fc10 hp11 eof with response")
+ {
+ rx_data_fc10 (t, &tp, 0x006001ab, false, MAC_HP10_DELIMITER_TCK
+ + MAC_HP10_RIFS_TCK + MAC_HP10_DELIMITER_TCK
+ + MAC_HP10_CIFS_TCK, false, true);
+ rx_data_fc10 (t, &tp, 0x006011ab, false, MAC_HP10_DELIMITER_TCK
+ + MAC_HP10_RIFS_TCK + MAC_HP10_DELIMITER_TCK
+ + MAC_HP10_CIFS_TCK, false, true);
+ } test_end;
+ */
+ /* EOF without response, detect and EIFS (too late to synchronise). */
+ /*
+ test_begin (t, "fc10 hp10 eof without response")
+ {
+ rx_data_fc10 (t, &tp, 0x004800ab, false, 0, true, false);
+ } test_end;
+ test_begin (t, "fc10 hp11 eof without response")
+ {
+ rx_data_fc10 (t, &tp, 0x005811ab, false, 0, false, true);
+ } test_end;
+ */
+ /* Other FC10. */
+ /*
+ test_begin (t, "fc10 none")
+ {
+ rx_data_fc10 (t, &tp, 0x004400ab, true, 0, false, false);
+ rx_data_fc10 (t, &tp, 0x004401ab, true, 0, false, false);
+ rx_data_fc10 (t, &tp, 0x002000ab, true, 0, false, false);
+ rx_data_fc10 (t, &tp, 0, true, 0, false, false);
+ } test_end;
+ */
+ test_begin (t, "unknown fc")
+ {
+ uint date = 654879;
+ pbproc_fc_generic_t fc = {
+ .dt_av = 0x7,
+ .access = false,
+ .snid = tp.snid,
+ };
+ test_pbproc_check_stats_reset (&tp);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date,
+ .rx_sysdate = date * 21 / 20,
+ .prp_won = false,
+ .fc_av = PARENT_OF (pbproc_fc_t, generic,
+ &fc)->words),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart, .
+ end_date = date + MAC_FL_TO_TCK (MAC_MAX_FL_MIN_FL)),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + PHY_RX_ACTIVATE_DELAY_AFTER_SHORT_TCK,
+ .pre_detection = true),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = &tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (
+ t, &tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_fc_unknown = 1,
+ );
+ test_fail_unless (tp.pbproc->fsm.current_state
+ == PBPROC_FSM_STATE_IDLE);
+ } test_end;
+ test_begin (t, "nfu sack")
+ {
+ rx_data_nfu_test (t, &tp, 123546, NFU_SACK);
+ } test_end;
+ test_begin (t, "nfu sof")
+ {
+ rx_data_nfu_test (t, &tp, 12354, NFU_SOF_ACCESS);
+ rx_data_nfu_test (t, &tp, 1235, NFU_SOF_SNID);
+ rx_data_nfu_test (t, &tp, 123, NFU_SOF_TEI);
+ } test_end;
+ test_begin (t, "nfu sof unassoc")
+ {
+ rx_data_nfu_test (t, &tp, 123, NFU_SOF_UNASSOC_SNID);
+ } test_end;
+ test_begin (t, "nfu out of alloc")
+ {
+ rx_data_nfu_test (t, &tp, 12354, NFU_OUT_OF_ALLOC);
+ } test_end;
+ test_begin (t, "sack error invalid tm")
+ {
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_TM_TMI_UNAVAILABLE);
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_TM_STA_UNAVAILABLE);
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_TM_UNASSOCIATED);
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_TM_BCAST);
+ } test_end;
+ test_begin (t, "sack error encryption")
+ {
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_ENC_STA_NO_NEK);
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_ENC_NO_EKS);
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_ENC_UNASSOCIATED);
+ } test_end;
+ test_begin (t, "pool shortage")
+ {
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_POOL_SHORTAGE);
+ } test_end;
+ test_begin (t, "woack error invalid tm")
+ {
+ rx_data_sack_error_test (t, &tp, WOACK_ERROR_TM);
+ } test_end;
+ test_begin (t, "woack error encryption")
+ {
+ rx_data_sack_error_test (t, &tp, WOACK_ERROR_ENC);
+ } test_end;
+ /*
+ test_begin (t, "beacon nfu out of alloc")
+ {
+ rx_beacon_nfu_test (t, &tp, NFU_OUT_OF_ALLOC);
+ } test_end;
+ */
+ test_begin (t, "beacon nfu pool shortage")
+ {
+ rx_beacon_nfu_test (t, &tp, NFU_POOL_SHORTAGE);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+rx_data_fl_av_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "fl_av");
+ test_pbproc_init (&tp);
+ test_begin (t, "robo classic")
+ {
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 19, .pb_nb = 1, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 38, .pb_nb = 2, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 57, .pb_nb = 3, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 76, .pb_nb = 4, .tmi = PHY_MOD_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 95, .pb_nb = 5, .tmi = PHY_MOD_ROBO)));
+ } test_end;
+ test_begin (t, "robo weird")
+ {
+ uint symb_nb;
+ for (symb_nb = 20; symb_nb < 110; symb_nb++)
+ {
+ if (symb_nb % 19 == 0)
+ continue;
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = symb_nb, .real_symb_nb = symb_nb / 19 * 19,
+ .pb_nb = symb_nb / 19, .tmi = PHY_MOD_ROBO)));
+ }
+ } test_end;
+ test_begin (t, "robo weird no seg")
+ {
+ uint symb_nb;
+ for (symb_nb = 1; symb_nb < 19; symb_nb++)
+ rx_data_sack_error_test (t, &tp, SACK_ERROR_EMPTY, symb_nb);
+ } test_end;
+ test_begin (t, "hs-robo classic")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 10, .pb_nb = 1, .tmi = PHY_MOD_HS_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 20, .pb_nb = 2, .tmi = PHY_MOD_HS_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 30, .pb_nb = 3, .tmi = PHY_MOD_HS_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 40, .pb_nb = 4, .tmi = PHY_MOD_HS_ROBO)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 50, .pb_nb = 5, .tmi = PHY_MOD_HS_ROBO)));
+ } test_end;
+ test_begin (t, "hs-robo weird")
+ {
+ uint symb_nb;
+ for (symb_nb = 11; symb_nb < 59; symb_nb++)
+ {
+ if (symb_nb % 10 == 0)
+ continue;
+ rx_data_burst_test (
+ t, &tp, .prp_won = false, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = symb_nb, .real_symb_nb = symb_nb / 10 * 10,
+ .pb_nb = symb_nb / 10, .tmi = PHY_MOD_HS_ROBO)));
+ }
+ } test_end;
+ test_begin (t, "tm classic")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 2, .pb_nb = 1, .tmi = 5, .tm_mod = 4)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 3, .pb_nb = 2, .tmi = 5, .tm_mod = 4)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 5, .pb_nb = 3, .tmi = 5, .tm_mod = 4)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 6, .pb_nb = 4, .tmi = 5, .tm_mod = 4)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 8, .pb_nb = 5, .tmi = 5, .tm_mod = 4)));
+ } test_end;
+ test_begin (t, "tm weird")
+ {
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 4, .real_symb_nb = 3, .pb_nb = 2,
+ .tmi = 5, .tm_mod = 4)));
+ rx_data_burst_test (
+ t, &tp, .pool_pb_nb = 5, .wack = true,
+ MPDU ((.symb_nb = 7, .real_symb_nb = 6, .pb_nb = 4,
+ .tmi = 5, .tm_mod = 4)));
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+rx_data_budget_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "budget");
+ test_pbproc_init (&tp);
+ test_begin (t, "overflow")
+ {
+ int i;
+ /* Fill RX queue. */
+ for (i = 0; i < 3; i++)
+ {
+ pb_beacon_t *pbb = PARENT_OF (pb_beacon_t, blk,
+ blk_alloc_desc ());
+ slist_push_back (tp.pbproc->commit.rx_beacon_, pbb);
+ }
+ for (i = 0; i < 3; i++)
+ {
+ pbproc_rx_desc_t *rx = PARENT_OF (pbproc_rx_desc_t, blk,
+ blk_alloc_desc ());
+ rx->rx->pb_nb = 0;
+ rx->rx->pb_first = rx->rx->pb_last = NULL;
+ rx->rx->chandata_nb = 0;
+ rx->rx->chandata_first = NULL;
+ rx->rx->params.beacon_period_start_ntb = tp.config.ntb_offset_tck;
+ rx->rx->params.fl_tck = 0;
+ rx->rx->params.pb_size = 0;
+ rx->rx->params.mpdu_cnt = 0;
+ rx->rx->params.mfs_cmd_data = 0;
+ rx->rx->params.mfs_cmd_mme = 0;
+ slist_push_back (tp.pbproc->commit.rx_, rx);
+ }
+ /* Trigger a deferred callback. */
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_deferred),
+ SCENARIO_EVENT (pbproc_rx_beacon_cb,
+ .duration_tck = MAC_MS_TO_TCK (2)),
+ SCENARIO_EVENT (pbproc_rx_beacon_cb,
+ .duration_tck = MAC_MS_TO_TCK (2)),
+ SCENARIO_EVENT (pbproc_rx_cb, .pb_nb = 0, .chandata_nb = 0,
+ .fl_tck = 0, .pb_size = 0, .mpdu_cnt = 0,
+ .mfs_cmd_data = 0, .mfs_cmd_mme = 0,
+ .duration_tck = MAC_MS_TO_TCK (7)),
+ SCENARIO_EVENT (pbproc_rx_cb, .pb_nb = 0, .chandata_nb = 0,
+ .fl_tck = 0, .pb_size = 0, .mpdu_cnt = 0,
+ .mfs_cmd_data = 0, .mfs_cmd_mme = 0,
+ .duration_tck = MAC_MS_TO_TCK (7)),
+ SCENARIO_EVENT (phy_deferred_schedule),
+ SCENARIO_EVENT (pbproc_rx_beacon_cb,
+ .duration_tck = MAC_MS_TO_TCK (2)),
+ SCENARIO_EVENT (pbproc_rx_cb, .pb_nb = 0, .chandata_nb = 0,
+ .fl_tck = 0, .pb_size = 0, .mpdu_cnt = 0,
+ .mfs_cmd_data = 0, .mfs_cmd_mme = 0,
+ .duration_tck = MAC_MS_TO_TCK (7)),
+ SCENARIO_END
+ };
+
+ scenario_globals_t globals = {
+ .tp = &tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (tp.pbproc->fsm.current_state
+ == PBPROC_FSM_STATE_IDLE);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+rx_data_test_suite (test_t t)
+{
+ test_suite_begin (t, "rx data");
+ rx_data_basic_test_case (t);
+ /* rx_data_burst_test_case (t); */
+ rx_data_errors_test_case (t);
+ rx_data_fl_av_test_case (t);
+ rx_data_budget_test_case (t);
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c b/cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c
new file mode 100644
index 0000000000..a8220b17d8
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c
@@ -0,0 +1,331 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/rx_sound.c
+ * \brief RX SOUND automaton test
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+#include "inc/utils.h"
+
+#include "inc/test_pbproc.h"
+
+#include "mac/common/timings.h"
+#include "hal/phy/inc/context.h"
+
+void
+rx_sound_test (test_t t, test_pbproc_t *tp, u32 date, uint chandata_nb,
+ uint pool_pb_nb, uint tmi, uint burst, bool scf)
+{
+ uint i;
+ test_within (t);
+ const uint lid = 1;
+ /* Prepare tone map. */
+ dbg_assert (tmi == PHY_MOD_ROBO || tmi == PHY_MOD_MINI_ROBO);
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[tmi];
+ dbg_assert (tm->gil == PHY_GIL_417 || tm->gil == PHY_GIL_567);
+ uint dx = tm->gil == PHY_GIL_417 ? MAC_DX417_TCK : MAC_DX567_TCK;
+ uint rifs_tck = burst ? MAC_BIFS_TCK : MAC_RIFS_DEFAULT_TCK;
+ phy_pb_size_t pb_size = tmi == PHY_MOD_ROBO ? PHY_PB_SIZE_520
+ : PHY_PB_SIZE_136;
+ /* Prepare channel data configuration. */
+ u32 chandata_conf[chandata_nb];
+ bool chandata = false;
+ if (chandata_nb)
+ {
+ for (i = 0; i < chandata_nb; i++)
+ chandata_conf[i] = i;
+ pbproc_set_chandata_conf (tp->pbproc,
+ (phy_chandata_conf_t *) chandata_conf,
+ chandata_nb, false);
+ if (pool_pb_nb >= chandata_nb)
+ chandata = true;
+ }
+ /* Compute frame size. */
+ uint symb_nb = (1 * tm->bits_per_pb[pb_size] + tm->bits_per_symbol - 1)
+ / tm->bits_per_symbol;
+ /* Prepare FC. */
+ const uint fl_tck = MAC_PAYLOAD_TCK (symb_nb, dx)
+ + rifs_tck;
+ pbproc_fc_sound_t sound_fc = {
+ .dt_av = PBPROC_FC_DT_SOUND,
+ .access = false,
+ .snid = tp->snid,
+ .direction = 1,
+ .dtei = 5,
+ .lid = lid,
+ .pbsz = pb_size == PHY_PB_SIZE_136,
+ .saf = false,
+ .scf = false,
+ .req_tm = 7,
+ .fl_av = MAC_TCK_TO_FL (fl_tck),
+ .mpdu_cnt = burst,
+ .src = TONEMAP_SRC_INITIAL,
+ .fccs_av = 0,
+ };
+ const uint rx_fl_tck = MAC_FL_TO_TCK (MAC_TCK_TO_FL (fl_tck));
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + rx_fl_tck;
+ /* Reset stats. */
+ test_pbproc_check_stats_reset (tp);
+ /* Scenario. */
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .slot_count = 2,
+ .fc_av = PARENT_OF (pbproc_fc_t, sound,
+ &sound_fc)->words),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT_COND (chandata, phy_rx_prepare_sound, .nb_pb = 1,
+ .mod = tmi, .fecrate = tm->fecrate,
+ .pb_size = pb_size, .gil = tm->gil,
+ .symbol_nb = symb_nb),
+ SCENARIO_EVENT_COND (chandata, phy_pbdma_start_chandata),
+ SCENARIO_EVENT_COND (!chandata, phy_rx_prepare_short),
+ SCENARIO_EVENT_COND (!burst, ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_CIFS_TCK),
+ SCENARIO_EVENT_COND (burst, ca_access_vcs_restart_eifs,
+ .start_date = date + pre_fc_fl_tck),
+ SCENARIO_EVENT_COND (burst, phy_rx_activate, .now = false,
+ .date = date + pre_fc_fl_tck
+ + PHY_RX_ACTIVATE_DELAY_AFTER_BURST_TCK,
+ .pre_detection = true),
+ SCENARIO_ACTION_COND (chandata, phy_pbdma, .end_chandata = true),
+ SCENARIO_EVENT_COND (!burst, phy_tx_param_short,
+ .fc_mode = PHY_FC_MODE_AV_1),
+ SCENARIO_EVENT_COND (!burst, phy_tx_frame,
+ .date = date + pre_fc_fl_tck, .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT_COND (chandata, pbproc_rx_cb, .pb_nb = 0,
+ .chandata_nb = chandata ? chandata_nb : 0,
+ .fl_tck = rx_fl_tck,
+ .pb_size = pb_size,
+ .mpdu_cnt = burst,
+ .mfs_cmd_data = MFS_FSM_CMD_NOP,
+ .mfs_cmd_mme = MFS_FSM_CMD_NOP),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ /* Allocate PB pool. */
+ blk_t *first, *last;
+ first = blk_alloc_desc_range (1 + pool_pb_nb, &last);
+ pbproc_rx_segment_refill (tp->pbproc, PARENT_OF (pb_t, blk, first),
+ PARENT_OF (pb_t, blk, last), 1 + pool_pb_nb);
+ /* Run scenario. */
+ scenario_run (t, entries, &globals);
+ /* Check pool. */
+ test_fail_unless (tp->pbproc->rx_pool_size == 1 + pool_pb_nb
+ - (chandata ? 1 + chandata_nb : 0));
+ /* Check SOUND ACK. */
+ if (!burst)
+ {
+ pbproc_fc_sound_t ack = PARENT_OF (pbproc_fc_t, words,
+ tp->pbproc->phy->tx_fc)->sound;
+ test_fail_unless (ack.dt_av == PBPROC_FC_DT_SOUND);
+ test_fail_unless (ack.access == false);
+ test_fail_unless (ack.snid == tp->snid);
+ test_fail_unless (ack.dtei == sound_fc.dtei);
+ test_fail_unless (ack.direction == 0);
+ test_fail_unless (ack.lid == lid);
+ test_fail_unless (ack.pbsz == false);
+ test_fail_unless (ack.saf == true);
+ test_fail_unless (ack.scf == scf);
+ test_fail_unless (ack.req_tm == 0);
+ test_fail_unless (ack.fl_av == 0);
+ test_fail_unless (ack.mpdu_cnt == 0);
+ test_fail_unless (ack.src == 0);
+ }
+ /* Check stats. */
+ test_pbproc_check_stats (t, tp,
+ .prp_lost = 1,
+ .rx_handle_fc = 1,
+ .rx_sound = 1,
+ .rx_sound_complete = scf && chandata ? 1 : 0,
+ .rx_sound_drop = chandata ? 0 : 1);
+ /* Check return to IDLE state. */
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ /* Cleanup. */
+ if (tp->pbproc->rx_pool_size)
+ {
+ blk_release_desc_range (&tp->pbproc->rx_pool_head->blk,
+ &tp->pbproc->rx_pool_tail->blk);
+ slist_init (tp->pbproc->rx_pool_, paste_size);
+ }
+ if (chandata_nb)
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0, false);
+}
+
+void
+rx_sound_basic_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "basic");
+ test_pbproc_init (&tp);
+ test_begin (t, "robo")
+ {
+ rx_sound_test (t, &tp, 123456, 11, 11, PHY_MOD_ROBO, 0, true);
+ rx_sound_test (t, &tp, 123456, 11, 12, PHY_MOD_ROBO, 0, true);
+ } test_end;
+ test_begin (t, "mini-robo")
+ {
+ rx_sound_test (t, &tp, 1234567, 6, 6, PHY_MOD_MINI_ROBO, 0, true);
+ rx_sound_test (t, &tp, 1234567, 6, 7, PHY_MOD_MINI_ROBO, 0, true);
+ } test_end;
+ test_begin (t, "sound complete")
+ {
+ uint i;
+ utils_sta_prepare_default_tonemap (&tp, false, 5, PHY_MOD_ROBO, 0, 0,
+ NULL);
+ for (i = 0; i < TONEMAP_SOUND_FRAME_COUNTER - 1; i++)
+ rx_sound_test (t, &tp, 123456, 11, 11, PHY_MOD_ROBO, 0, false);
+ rx_sound_test (t, &tp, 123456, 11, 11, PHY_MOD_ROBO, 0, true);
+ rx_sound_test (t, &tp, 123456, 11, 11, PHY_MOD_ROBO, 0, true);
+ dbg_check (mac_store_sta_remove (tp.store, 5));
+ } test_end;
+ /*
+ test_begin (t, "burst")
+ {
+ rx_sound_test (t, &tp, 123456, 11, 11, PHY_MOD_ROBO, 1, true);
+ rx_sound_test (t, &tp, 123456, 11, 11, PHY_MOD_MINI_ROBO, 1, true);
+ } test_end;
+ */
+ test_begin (t, "no chandata")
+ {
+ rx_sound_test (t, &tp, 123456, 0, 1, PHY_MOD_ROBO, 0, true);
+ rx_sound_test (t, &tp, 123456, 0, 1, PHY_MOD_MINI_ROBO, 0, true);
+ } test_end;
+ test_begin (t, "woack no chandata")
+ {
+ rx_sound_test (t, &tp, 123456, 0, 1, PHY_MOD_ROBO, 1, true);
+ rx_sound_test (t, &tp, 123456, 0, 1, PHY_MOD_MINI_ROBO, 1, true);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+enum rx_sound_nfu_t
+{
+ NFU_OUT_OF_ALLOC,
+ NFU_POOL_SHORTAGE,
+};
+typedef enum rx_sound_nfu_t rx_sound_nfu_t;
+
+void
+rx_sound_nfu_test (test_t t, test_pbproc_t *tp, u32 date, rx_sound_nfu_t nfu)
+{
+ test_within (t);
+ u32 restart_date;
+ uint length_tck;
+ /* Use another state to test return to IDLE. */
+ tp->pbproc->fsm.current_state = PBPROC_FSM_STATE_RX_BURST;
+ /* Prepare channel data configuration. */
+ const uint chandata_nb = 3;
+ u32 chandata_conf[chandata_nb];
+ uint i;
+ for (i = 0; i < chandata_nb; i++)
+ chandata_conf[i] = i;
+ pbproc_set_chandata_conf (tp->pbproc,
+ (phy_chandata_conf_t *) chandata_conf,
+ chandata_nb, false);
+ /* Compute frame size. */
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint symb_nb = (1 * tm->bits_per_pb[PHY_PB_SIZE_520]
+ + tm->bits_per_symbol - 1) / tm->bits_per_symbol;
+ const uint fl_tck = MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK;
+ /* Prepare FC. */
+ pbproc_fc_sound_t sound_fc = {
+ .dt_av = PBPROC_FC_DT_SOUND,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = tp->config.tei,
+ .lid = 1,
+ .pbsz = false,
+ .saf = false,
+ .scf = false,
+ .req_tm = 7,
+ .fl_av = MAC_TCK_TO_FL (fl_tck),
+ .mpdu_cnt = 0,
+ .src = TONEMAP_SRC_INITIAL,
+ .fccs_av = 0,
+ };
+ if (nfu == NFU_OUT_OF_ALLOC)
+ date += 0x80000000;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_FL_TO_TCK (MAC_TCK_TO_FL (fl_tck))
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ restart_date = date + length_tck - MAC_PREAMBLE_TCK - MAC_FC_AV_TCK
+ - MAC_CIFS_TCK;
+ length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ tp->pbproc->rx_pool_size = nfu != NFU_POOL_SHORTAGE ? 4 : 3;
+ test_pbproc_check_stats_reset (tp);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date, .prp_won = false,
+ .slot_count = 2,
+ .fc_av = PARENT_OF (pbproc_fc_t, sound,
+ &sound_fc)->words),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = restart_date + length_tck),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = 0,
+ .rx_handle_fc = 1,
+ .rx_sound = 1,
+ .rx_out_of_alloc = nfu == NFU_OUT_OF_ALLOC ? 1 : 0,
+ .rx_pool_shortage = nfu == NFU_POOL_SHORTAGE ? 1 : 0);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ test_fail_unless (tp->pbproc->rx_pool_size == (nfu != NFU_POOL_SHORTAGE
+ ? 4 : 3));
+ tp->pbproc->rx_pool_size = 0;
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0, false);
+}
+
+void
+rx_sound_error_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "error");
+ test_pbproc_init (&tp);
+ test_begin (t, "nfu out of alloc")
+ {
+ rx_sound_nfu_test (t, &tp, 123456, NFU_OUT_OF_ALLOC);
+ } test_end;
+ test_begin (t, "nfu pool shortage")
+ {
+ rx_sound_nfu_test (t, &tp, 123456, NFU_POOL_SHORTAGE);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+rx_sound_test_suite (test_t t)
+{
+ test_suite_begin (t, "rx sound");
+ rx_sound_basic_test_case (t);
+ rx_sound_error_test_case (t);
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/scenario_defs.c b/cesar/mac/pbproc/test/pbproc_eoc/src/scenario_defs.c
new file mode 100644
index 0000000000..a024f336ed
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/scenario_defs.c
@@ -0,0 +1,166 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/scenario_defs.c
+ * \brief Scenario actions.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+#include "hal/phy/inc/context.h"
+#include "mac/ca/inc/context.h"
+
+void
+scenario_action_phy_rx_fc_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ scenario_action_phy_rx_fc_t *p = &params->action_phy_rx_fc;
+ ca_t *ca = globals->tp->ca;
+ phy_t *phy = globals->tp->pbproc->phy;
+ phy->rx_sysdate = p->rx_sysdate;
+ phy->prp_won = p->prp_won;
+ if (!p->prp_won)
+ ca->access_param.prp = true;
+ phy->slot_count = p->slot_count;
+ phy->fc10 = p->fc10 ? p->fc10 : (u32) -1;
+ /* Call callbacks. */
+ if (phy->rx_fc_cb (phy->user_data, p->rx_date, p->fc_av))
+ phy->deferred_cb (phy->user_data);
+ while (phy->dsr_scheduled)
+ {
+ phy->dsr_scheduled = false;
+ phy->deferred_cb (phy->user_data);
+ }
+}
+
+void
+scenario_action_phy_access_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ scenario_action_phy_access_t *p = &params->action_phy_access;
+ ca_t *ca = globals->tp->ca;
+ phy_t *phy = globals->tp->pbproc->phy;
+ /* Prepare parameters. */
+ ca->mfs = p->mfs;
+ if (p->access_param)
+ {
+ ca->access_param = *p->access_param;
+ phy->current_date = ca->access_param.access_date - PBPROC_ANTICIP_TCK
+ + p->delay_tck;
+ }
+ phy->prp_won = p->prp_won;
+ phy->slot_count = p->slot_count;
+ /* Call callbacks. */
+ if (phy->access_cb (phy->user_data))
+ phy->deferred_cb (phy->user_data);
+ while (phy->dsr_scheduled)
+ {
+ phy->dsr_scheduled = false;
+ phy->deferred_cb (phy->user_data);
+ }
+}
+
+void
+scenario_action_phy_access_conf_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ phy_t *phy = globals->tp->pbproc->phy;
+ /* Call callbacks. */
+ if (phy->access_conf_cb (phy->user_data))
+ phy->deferred_cb (phy->user_data);
+ while (phy->dsr_scheduled)
+ {
+ phy->dsr_scheduled = false;
+ phy->deferred_cb (phy->user_data);
+ }
+}
+
+void
+scenario_action_phy_pbdma_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ scenario_action_phy_pbdma_t *p = &params->action_phy_pbdma;
+ phy_t *phy = globals->tp->pbproc->phy;
+ /* Prepare parameters. */
+ phy_pbdma_status_t status;
+ *(u32 *) &status = 0;
+ status.pb_null = p->pb_null;
+ status.pb_crc_error = p->pb_crc_error;
+ status.pb_it = p->pb_it;
+ status.end_rx_pb = p->end_rx_pb;
+ status.end_tx_pb = p->end_tx_pb;
+ status.end_chandata = p->end_chandata;
+ status.null_pb_index = p->null_pb_index;
+ uint i;
+ if (p->crc_bitmap)
+ {
+ dbg_assert (p->crc_bitmap_bits < 256);
+ for (i = 0; i < p->crc_bitmap_bits / 32; i++)
+ phy->crc_bitmap[i] = p->crc_bitmap[i];
+ if (p->crc_bitmap_bits % 32 != 0)
+ {
+ phy->crc_bitmap[i] =
+ p->crc_bitmap[i] & BITS_ONES (p->crc_bitmap_bits % 32);
+ i++;
+ }
+ for (; i < COUNT (phy->crc_bitmap); i++)
+ phy->crc_bitmap[i] = 0;
+ }
+ else
+ for (i = 0; i < COUNT (phy->crc_bitmap); i++)
+ phy->crc_bitmap[i] = 0;
+ /* Call callbacks. */
+ if (phy->pbdma_cb (phy->user_data, *(u32 *) &status))
+ phy->deferred_cb (phy->user_data);
+ while (phy->dsr_scheduled)
+ {
+ phy->dsr_scheduled = false;
+ phy->deferred_cb (phy->user_data);
+ }
+}
+
+void
+scenario_action_phy_deferred_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ phy_t *phy = globals->tp->pbproc->phy;
+ /* Call callbacks. */
+ phy->deferred_cb (phy->user_data);
+ while (phy->dsr_scheduled)
+ {
+ phy->dsr_scheduled = false;
+ phy->deferred_cb (phy->user_data);
+ }
+}
+
+void
+scenario_action_phy_extra_timer_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ phy_t *phy = globals->tp->pbproc->phy;
+ /* Call callbacks. */
+ if (phy->extra_timer_cb (phy->user_data))
+ phy->deferred_cb (phy->user_data);
+ while (phy->dsr_scheduled)
+ {
+ phy->dsr_scheduled = false;
+ phy->deferred_cb (phy->user_data);
+ }
+}
+
+void
+scenario_action_pbproc_activate_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ scenario_action_pbproc_activate_t *p = &params->action_pbproc_activate;
+ pbproc_t *pbproc = globals->tp->pbproc;
+ /* Call function. */
+ pbproc_activate (pbproc, p->flag);
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/test_pbproc.c b/cesar/mac/pbproc/test/pbproc_eoc/src/test_pbproc.c
new file mode 100644
index 0000000000..082bcfdd74
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/test_pbproc.c
@@ -0,0 +1,512 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_pbproc.c
+ * \brief PBProc test.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/trace.h"
+
+#include "inc/test_pbproc.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "hal/phy/inc/context.h"
+
+#include <string.h>
+
+void
+prep_mpdu_test_suite (test_t t);
+
+void
+tx_data_test_suite (test_t t);
+
+void
+tx_sound_test_suite (test_t t);
+
+void
+rx_data_test_suite (test_t t);
+
+void
+rx_sound_test_suite (test_t t);
+
+void
+rx_rts_cts_test_suite (test_t t);
+
+void
+test_pbproc_rx_cb (void *user, pbproc_rx_desc_t *rx_desc)
+{
+ dbg_assert_ptr (user);
+ test_pbproc_t *ctx = user;
+ dbg_assert_ptr (rx_desc);
+ pbproc_rx_t *rx = rx_desc->rx;
+ if (rx->pb_nb)
+ {
+ dbg_assert_ptr (rx->pb_first);
+ dbg_assert_ptr (rx->pb_last);
+ }
+ else
+ dbg_assert (rx->pb_first == NULL && rx->pb_last == NULL);
+ if (rx->chandata_nb)
+ dbg_assert_ptr (rx->chandata_first);
+ else
+ dbg_assert (rx->chandata_first == NULL);
+ scenario_event (pbproc_rx_cb, params, globals);
+ test_fail_unless (rx->pb_nb == params->pb_nb);
+ if (rx->pb_nb)
+ blk_release_desc_range (&rx->pb_first->blk, &rx->pb_last->blk);
+ test_fail_unless (rx->chandata_nb == params->chandata_nb);
+ if (rx->chandata_nb)
+ blk_release_desc_range_nb (&rx->chandata_first->blk, rx->chandata_nb);
+ /* TODO: more verifications. */
+ test_fail_unless (rx->params.beacon_period_start_ntb
+ == params->beacon_period_start_date
+ + ctx->config.ntb_offset_tck);
+ test_fail_unless (rx->params.fl_tck == params->fl_tck);
+ test_fail_unless (rx->params.pb_size == params->pb_size);
+ test_fail_unless (rx->params.mpdu_cnt == params->mpdu_cnt);
+ /*test_fail_unless (rx->params.mfs_cmd_data == params->mfs_cmd_data);*/
+ test_fail_unless (rx->params.mfs_cmd_mme == params->mfs_cmd_mme);
+ /* This took time. */
+ globals->tp->pbproc->phy->current_date += params->duration_tck;
+ /* Done. */
+ blk_release_desc (&rx_desc->blk);
+}
+
+void
+test_pbproc_rx_beacon_cb (void *user, pb_beacon_t *pb,
+ pbproc_rx_beacon_params_t *params)
+{
+ dbg_assert_ptr (user);
+ dbg_assert_ptr (pb);
+ dbg_assert (params == (void *) (pb->data + MAC_PB136_BYTES));
+ scenario_event (pbproc_rx_beacon_cb, event_params, globals);
+ /* TODO: more verifications. */
+ /* This took time. */
+ globals->tp->pbproc->phy->current_date += event_params->duration_tck;
+ /* Done. */
+ blk_release_desc (&pb->blk);
+}
+
+void
+test_pbproc_init (test_pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ lib_rnd_init (ctx->rnd, 1234);
+ mac_config_init (&ctx->config);
+ mac_ntb_init (&ctx->config);
+ ctx->config.ntb_offset_tck = TEST_PBPROC_NTB_OFFSET_TCK;
+ ctx->config.tei = 1;
+ ctx->snid = 1;
+ ctx->config.seed = 42;
+ ctx->store = mac_store_init ();
+ ctx->pbproc = pbproc_init (&ctx->config, ctx->store);
+ pbproc_init_cb (ctx->pbproc, ctx, test_pbproc_rx_cb,
+ test_pbproc_rx_beacon_cb);
+ pbproc_get_phy (ctx->pbproc);
+ ctx->ca = pbproc_get_ca (ctx->pbproc);
+ ctx->pbproc->activated = true;
+ test_pbproc_alloc (ctx, false, 0);
+ test_pbproc_check_stats_reset (ctx);
+}
+
+void
+test_pbproc_alloc (test_pbproc_t *ctx, bool hybrid,
+ u32 beacon_period_start_date)
+{
+ dbg_assert (ctx);
+ ctx->pbproc->alloc.coexistence_mode = hybrid
+ ? MAC_COEXISTENCE_FULL_HYBRID_MODE : MAC_COEXISTENCE_AV_ONLY_MODE;
+ ctx->pbproc->alloc.hybrid = hybrid;
+ ctx->pbproc->alloc.merge = false;
+ ctx->pbproc->times = ctx->pbproc->times_array[PBPROC_TIMES_ARRAY_INDEX (
+ hybrid, ctx->pbproc->alloc.coexistence_mode)];
+ ctx->pbproc->alloc.end_date = 0x80000000;
+ ctx->pbproc->alloc.aifs_date = 0x80000000;
+ ctx->pbproc->alloc.beacon_period_start_date = beacon_period_start_date;
+}
+
+void
+test_pbproc_check_stats_ (test_t t, test_pbproc_t *ctx,
+ const pbproc_stat_t *stats)
+{
+ test_within (t);
+ dbg_assert (ctx);
+ dbg_assert (stats);
+#define TEST_PBPROC_CHECK_STAT(stat) \
+ test_fail_unless (ctx->pbproc->stats.stat == ctx->recorded_stats.stat \
+ + stats->stat, #stat ": %d", \
+ ctx->pbproc->stats.stat - ctx->recorded_stats.stat)
+ TEST_PBPROC_CHECK_STAT(rts_fail);
+ TEST_PBPROC_CHECK_STAT(prp_lost);
+ TEST_PBPROC_CHECK_STAT(cw_lost);
+ TEST_PBPROC_CHECK_STAT(aifs);
+ TEST_PBPROC_CHECK_STAT(rx_out_of_alloc);
+ TEST_PBPROC_CHECK_STAT(rx_pool_shortage);
+ TEST_PBPROC_CHECK_STAT(rx_handle_fc);
+ TEST_PBPROC_CHECK_STAT(rx_beacon);
+ TEST_PBPROC_CHECK_STAT(rx_data);
+ TEST_PBPROC_CHECK_STAT(rx_data_wack);
+ TEST_PBPROC_CHECK_STAT(rx_data_woack);
+ TEST_PBPROC_CHECK_STAT(rx_data_burst_stop);
+ TEST_PBPROC_CHECK_STAT(rx_data_error);
+ TEST_PBPROC_CHECK_STAT(rx_data_empty);
+ TEST_PBPROC_CHECK_STAT(rx_data_bad_symb_nb);
+ TEST_PBPROC_CHECK_STAT(rx_sound);
+ TEST_PBPROC_CHECK_STAT(rx_sound_complete);
+ TEST_PBPROC_CHECK_STAT(rx_sound_drop);
+ TEST_PBPROC_CHECK_STAT(rx_nfu);
+ TEST_PBPROC_CHECK_STAT(rx_fc_unknown);
+ TEST_PBPROC_CHECK_STAT(rx_crc_error);
+ TEST_PBPROC_CHECK_STAT(tx_invalid);
+ TEST_PBPROC_CHECK_STAT(tx_late);
+ TEST_PBPROC_CHECK_STAT(tx_data);
+ TEST_PBPROC_CHECK_STAT(tx_data_cancel);
+ TEST_PBPROC_CHECK_STAT(tx_data_burst);
+ TEST_PBPROC_CHECK_STAT(tx_data_burst_interrupted);
+ TEST_PBPROC_CHECK_STAT(tx_data_wack);
+ TEST_PBPROC_CHECK_STAT(tx_data_woack);
+ TEST_PBPROC_CHECK_STAT(tx_data_beacon);
+ TEST_PBPROC_CHECK_STAT(tx_data_wack_ack);
+ TEST_PBPROC_CHECK_STAT(tx_data_wack_noack);
+ TEST_PBPROC_CHECK_STAT(tx_sound);
+ TEST_PBPROC_CHECK_STAT(tx_sound_ack);
+ TEST_PBPROC_CHECK_STAT(tx_sound_noack);
+}
+
+void
+test_pbproc_check_stats_reset (test_pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->recorded_stats = ctx->pbproc->stats;
+}
+
+void
+test_pbproc_uninit (test_pbproc_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->ca = NULL;
+ pbproc_uninit (ctx->pbproc);
+ ctx->pbproc = NULL;
+ mac_store_uninit (ctx->store);
+ ctx->store = NULL;
+}
+
+void
+test_pbproc_init_suite (test_t t)
+{
+ test_suite_begin (t, "init");
+ test_case_begin (t, "basic");
+ test_pbproc_t ctx;
+ test_begin (t, "init uninit")
+ {
+ test_pbproc_init (&ctx);
+ test_pbproc_uninit (&ctx);
+ test_pbproc_init (&ctx);
+ test_pbproc_uninit (&ctx);
+ } test_end;
+ test_begin (t, "rx segment refill")
+ {
+ test_pbproc_init (&ctx);
+ blk_t *first, *last;
+ first = blk_alloc_desc_range (10, &last);
+ pbproc_rx_segment_refill (ctx.pbproc, PB_FROM_BLK (first),
+ PB_FROM_BLK (last), 10);
+ first = blk_alloc_desc_range (10, &last);
+ pbproc_rx_segment_refill (ctx.pbproc, PB_FROM_BLK (first),
+ PB_FROM_BLK (last), 10);
+ test_pbproc_uninit (&ctx);
+ } test_end;
+ test_begin (t, "activate deactivate")
+ {
+ test_pbproc_init (&ctx);
+ ctx.pbproc->activated = false;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (pbproc_activate, .flag = true),
+ SCENARIO_EVENT (ca_access_activate, .date = 0,
+ .coexistence_mode = MAC_COEXISTENCE_AV_ONLY_MODE,
+ .snid = ctx.snid, .hybrid = false, .merge = false,
+ .nek_switch = 0),
+ SCENARIO_EVENT (phy_rx_param, .fc_mode = PHY_FC_MODE (false, 1)),
+ SCENARIO_EVENT (phy_rx_activate, .now = true,
+ .pre_detection = true),
+ SCENARIO_ACTION (pbproc_activate, .flag = false),
+ SCENARIO_EVENT (phy_rx_activate, .now = true,
+ .pre_detection = false),
+ SCENARIO_EVENT (ca_access_deactivate),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = &ctx,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (memcmp (&ctx.pbproc->times,
+ &ctx.pbproc->times_array[false],
+ sizeof (pbproc_times_t)) == 0);
+ test_pbproc_uninit (&ctx);
+ } test_end;
+ test_begin (t, "activate hybrid")
+ {
+ test_pbproc_init (&ctx);
+ ctx.pbproc->activated = false;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (pbproc_activate, .flag = true),
+ SCENARIO_EVENT (ca_access_activate, .date = 0,
+ .coexistence_mode =
+ MAC_COEXISTENCE_FULL_HYBRID_MODE,
+ .snid = ctx.snid, .hybrid = true, .merge = false,
+ .nek_switch = 0),
+ SCENARIO_EVENT (phy_rx_param, .fc_mode = PHY_FC_MODE (true, 1)),
+ SCENARIO_EVENT (phy_rx_activate, .now = true,
+ .pre_detection = true),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = &ctx,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (memcmp (&ctx.pbproc->times,
+ &ctx.pbproc->times_array[true],
+ sizeof (pbproc_times_t)) == 0);
+ test_pbproc_uninit (&ctx);
+ } test_end;
+ test_begin (t, "aifs")
+ {
+ test_pbproc_init (&ctx);
+ ca_access_param_t access_param = {
+ .access_date = 0, .cw_start_date = 0, .aifs = true,
+ };
+ ctx.pbproc->detect.hp10_detected = true;
+ ctx.pbproc->detect.hp10_detect_date =
+ phy_date () - MAC_MS_TO_TCK (1900);
+ ctx.pbproc->detect.hp11_detected = true;
+ ctx.pbproc->detect.hp11_detect_date =
+ phy_date () - MAC_MS_TO_TCK (2900);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = NULL,
+ .access_param = &access_param,
+ .prp_won = true, .slot_count = 64),
+ SCENARIO_EVENT (phy_rx_activate, .now = true,
+ .pre_detection = false),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (ca_access_aifs,
+ .coexistence_mode = MAC_COEXISTENCE_AV_ONLY_MODE,
+ .snid = ctx.snid, .merge = false,
+ .hybrid = false, .nek_switch = 0),
+ SCENARIO_EVENT (phy_rx_param, .fc_mode = PHY_FC_MODE (false, 1)),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = &ctx,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (ctx.pbproc->fsm.current_state
+ == PBPROC_FSM_STATE_IDLE);
+ test_fail_unless (memcmp (&ctx.pbproc->times,
+ &ctx.pbproc->times_array[false],
+ sizeof (pbproc_times_t)) == 0);
+ test_fail_unless (ctx.pbproc->detect.hp10_detected == true);
+ test_fail_unless (ctx.pbproc->detect.hp11_detected == true);
+ ctx.pbproc->detect.hp10_detected = false;
+ ctx.pbproc->detect.hp11_detected = false;
+ test_pbproc_check_stats (t, &ctx, .aifs = 1);
+ test_pbproc_uninit (&ctx);
+ } test_end;
+ test_begin (t, "aifs merged")
+ {
+ test_pbproc_init (&ctx);
+ ctx.pbproc->alloc.merge = true;
+ ca_access_param_t access_param = {
+ .access_date = 0, .cw_start_date = 0, .aifs = true,
+ };
+ ctx.pbproc->detect.hp10_detected = true;
+ ctx.pbproc->detect.hp10_detect_date =
+ phy_date () - MAC_MS_TO_TCK (1900);
+ ctx.pbproc->detect.hp11_detected = true;
+ ctx.pbproc->detect.hp11_detect_date =
+ phy_date () - MAC_MS_TO_TCK (2900);
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = NULL,
+ .access_param = &access_param,
+ .prp_won = true, .slot_count = 64),
+ SCENARIO_EVENT (ca_access_aifs,
+ .coexistence_mode =
+ MAC_COEXISTENCE_FULL_HYBRID_MODE,
+ .snid = ctx.snid, .hybrid = true, .merge = false,
+ .nek_switch = 0),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = &ctx,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (ctx.pbproc->fsm.current_state
+ == PBPROC_FSM_STATE_IDLE);
+ test_fail_unless (ctx.pbproc->detect.hp10_detected == true);
+ test_fail_unless (ctx.pbproc->detect.hp11_detected == true);
+ ctx.pbproc->detect.hp10_detected = false;
+ ctx.pbproc->detect.hp11_detected = false;
+ test_pbproc_check_stats (t, &ctx, .aifs = 1);
+ test_pbproc_uninit (&ctx);
+ } test_end;
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
+struct test_pbproc_trace_dump_t
+{
+ char text[2048];
+ uint size;
+};
+typedef struct test_pbproc_trace_dump_t test_pbproc_trace_dump_t;
+
+static int
+test_pbproc_trace_dump_callback (void *user, const char *text,
+ uint text_size)
+{
+ test_pbproc_trace_dump_t *ctx = user;
+ dbg_assert (ctx);
+ if (text_size + ctx->size >= COUNT (ctx->text))
+ return 0;
+ memcpy (ctx->text, text, text_size);
+ ctx->size += text_size;
+ ctx->text[ctx->size] = '\0';
+ return text_size;
+}
+
+void
+test_pbproc_trace_suite (test_t t)
+{
+ test_suite_begin (t, "trace");
+ test_case_begin (t, "fc");
+ test_pbproc_t tp;
+ test_pbproc_init (&tp);
+ pbproc_t *ctx = tp.pbproc;
+ test_begin (t, "rx fc")
+ {
+ char ref[2048], *refp = ref;
+ const char *s;
+ s = "---trace-begin[pbproc]---\n"
+ "[.] init\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ s = "[0x00000000] fsm RX FC pre_date=0x00000000"
+ " BEACON snid=A1 bts=0x12345678 bto=42330,42331,42332,42333\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 0, 0,
+ 0x34567818, 0x5ba55a12, 0x5da55ca5, 0xdeaddea5);
+ s = "[0x00000001] fsm RX FC pre_date=0x00000001"
+ " SOF snid=2 dir=CCO->STA dtei=0x12 lid=0x04 mnbf eks=3"
+ " num_sym=2 tmi=21 fl_av=2213 mpdu_cnt=3 burst_cnt=1"
+ " bbf mrtfl=0xbab sackt0=0x2 sacki0=0x21472d05, sacki1=0x54\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 1, 1,
+ 0x56341221, 0xbbab78a5, 0x21472d05, 0xdeadde54);
+ s = "[0x00000002] fsm RX FC pre_date=0x00000002"
+ " SOF snid=A13 dir=STA->CCO dtei=0xed lid=0x0b mcf eks=0"
+ " pb136 num_sym=1 tmi=10 fl_av=1882 burst_cnt=2"
+ " sackt0=0x1 sacki0=0x72b882fa, sacki1=0xab\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 2, 2,
+ 0xa9cbedd9, 0x4454875a, 0x72b882fa, 0xdeaddeab);
+ s = "[0x00000003] fsm RX FC pre_date=0x00000003"
+ " SACK snid=3 dtei=0x12 cfs svn=1 mfs=ACK,mNACK sackt=m,mc,nr,u"
+ " sacki=0x01234567,0x89abcdef,0x01\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 3, 3,
+ 0xe4451232, 0x01234567, 0x89abcdef, 0xdeadde01);
+ s = "[0x00000004] fsm RX FC pre_date=0x00000004"
+ " SACK snid=A12 dtei=0xed bdf rrtf mfs=HOLD,mFAIL sackt=u,nr,mc,m"
+ " sacki=0xfedcba98,0x76543210,0xfe\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 4, 4,
+ 0x1bbaedca, 0xfedcba98, 0x76543210, 0xdeaddefe);
+ s = "[0x00000005] fsm RX FC pre_date=0x00000005"
+ " CTS snid=4 stei=0x23 dtei=0x45 lid=0x67 mcf cfs hp10df igf"
+ " dur=11111\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 5, 5,
+ 0x67452343, 0x002b67a5, 0x00000000, 0xdeadde00);
+ s = "[0x00000006] fsm RX FC pre_date=0x00000006"
+ " RTS snid=A11 stei=0xdc dtei=0xba lid=0x98 mnbf bdf hp11df"
+ " dur=5272\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 6, 6,
+ 0x98badcbb, 0x0014985a, 0x00000000, 0xdeadde00);
+ s = "[0x00000007] fsm RX FC pre_date=0x00000007"
+ " SOUND snid=5 dir=STA->CCO dtei=0x34 lid=0x07 saf scf req_tm=6"
+ " fl_av=2134 mpdu_cnt=2 src=0x00 sackt0=0x1"
+ " sacki0=0x1341a0, sacki1=0xbc\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 7, 7,
+ 0x78563454, 0x9a0d05b5, 0x000000bc, 0xdeadde00);
+ s = "[0x00000008] fsm RX FC pre_date=0x00000008"
+ " SOUND snid=A10 dir=CCO->STA dtei=0xcb lid=0x08 pb136 req_tm=1"
+ " fl_av=1961 mpdu_cnt=1 src=0x00 sackt0=0x2"
+ " sacki0=0xca65f, sacki1=0x43\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 8, 8,
+ 0x87a9cbac, 0x6532fa4a, 0x00000043, 0xdeadde00);
+ s = "[0x00000009] fsm RX FC pre_date=0x00000009"
+ " RSOF snid=6 dtei=0x12 bdf pb136 ppb=0x20 fl_av=2321 tmi=13"
+ " num_sym=3 sackt0=0x1 sacki0=0x1234567 sacki1=0x18089ab\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 9, 9,
+ 0xe4451265, 0x01234567, 0xdb8089ab, 0xdeadde20);
+ s = "[0x0000000a] fsm RX FC pre_date=0x0000000a"
+ " RSOF snid=A9 dtei=0xed ppb=0x73 fl_av=1774 tmi=18"
+ " num_sym=0 sackt0=0x2 sacki0=0xfedcba98 sacki1=0x7f7654\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ PBPROC_TRACE (FSM_RX_FC, 10, 10,
+ 0x1bbaed9d, 0xfedcba98, 0x247f7654, 0xdeadde73);
+ s = "---trace-end---\n";
+ dbg_assert (refp + strlen (s) < ref + sizeof (ref));
+ strcpy (refp, s); refp += strlen (s);
+ test_pbproc_trace_dump_t dump;
+ dump.size = 0;
+ trace_buffer_dump (&ctx->trace, test_pbproc_trace_dump_callback,
+ &dump);
+ test_fail_unless (strcmp (dump.text, ref) == 0);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ trace_init ();
+ test_init (t, argc, argv);
+ test_pbproc_init_suite (t);
+ prep_mpdu_test_suite (t);
+ tx_data_test_suite (t);
+ tx_sound_test_suite (t);
+ rx_data_test_suite (t);
+ rx_sound_test_suite (t);
+ test_pbproc_trace_suite (t);
+ trace_uninit ();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/tx_data.c b/cesar/mac/pbproc/test/pbproc_eoc/src/tx_data.c
new file mode 100644
index 0000000000..075d4d24c7
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/tx_data.c
@@ -0,0 +1,1155 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/tx_data.c
+ * \brief TX Data automaton test.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "inc/test_pbproc.h"
+#include "inc/utils.h"
+
+#include "mac/common/timings.h"
+
+void
+tx_data_test (test_t t, test_pbproc_t *tp, u32 date, uint mfs_seg_nb,
+ uint duration_tck, uint symb_nb, uint data_seg_nb_total,
+ bool unassociated, uint tmi, phy_prepare_type_t spoc_update_step,
+ bool rsof
+ )
+{
+ test_within (t);
+ tp->config.tei = rsof ? 6 : 1;
+ const uint lid = rsof ? 4 : 1;;
+ const uint stei = unassociated ? 0 : tp->config.tei;
+ const uint dtei = rsof ? 1 : 2;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint dx = MAC_DX417_TCK;
+ if (tmi != PHY_MOD_ROBO)
+ tm = utils_sta_prepare_default_tonemap (tp, true, dtei, tmi, 10, 0,
+ &dx);
+ uint rifs_tck = tmi < PHY_MOD_ROBO_NB ? MAC_RIFS_DEFAULT_TCK
+ : MAC_RIFS_SPC_ANY_TCK;
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, lid, dtei,
+ mfs_seg_nb);
+ mfs->common.unassociated = unassociated;
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = duration_tck,
+ .prp = true,
+ .cfp = rsof,
+ };
+ pbproc_fc_sack_t sack_fc = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = stei,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = 0,
+ .fccs_av = 0,
+ };
+ tp->pbproc->recv_mpdu.bbf = rsof;
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + rifs_tck;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT_COND (!data_seg_nb_total, phy_tx_param_short,
+ .fc_mode = PHY_FC_MODE_AV_1),
+ SCENARIO_EVENT_COND (data_seg_nb_total, phy_pbdma_start, .bypass_aes = true,
+ .nb_total = data_seg_nb_total,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT_COND (data_seg_nb_total, phy_tx_param,
+ .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = tmi < PHY_MOD_ROBO_NB ? tmi : PHY_MOD_TM,
+ .fecrate = tm->fecrate, .pb_size = PHY_PB_SIZE_520,
+ .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs,
+ .start_date = date + pre_fc_fl_tck),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_EVENT_COND (spoc_update_step < PHY_PREPARE_TYPE_NB,
+ phy_extra_timer_program,
+ .date = date + pre_fc_fl_tck - rifs_tck),
+ SCENARIO_ACTION_COND (spoc_update_step < PHY_PREPARE_TYPE_NB,
+ phy_extra_timer),
+ SCENARIO_EVENT_COND (spoc_update_step == PHY_PREPARE_TYPE_PREAMBLE,
+ phy_spoc_tx_set),
+ SCENARIO_EVENT_COND (spoc_update_step < PHY_PREPARE_TYPE_NB,
+ phy_prepare, .type = spoc_update_step,
+ .wait = false),
+ SCENARIO_EVENT_COND (spoc_update_step == PHY_PREPARE_TYPE_PREAMBLE,
+ phy_spoc_rx_set),
+ SCENARIO_EVENT_COND (spoc_update_step == PHY_PREPARE_TYPE_PREAMBLE,
+ phy_freq_error_set, .sync = true, .rho_q30 = 42),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date + pre_fc_fl_tck,
+ .fc_av = (u32 *) &sack_fc),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT_COND (!access.cfp, ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_wack = 1,
+ .tx_data_wack_ack = 1);
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_INIT);
+ test_fail_unless (mfs->stats.num_mpdus == 1);
+ test_fail_unless (mfs->stats.num_bursts == 1);
+ test_fail_unless (mfs->stats.num_pbs == data_seg_nb_total);
+ test_fail_unless (mfs->stats.num_segs_suc == data_seg_nb_total);
+ utils_mfs_tx_cleanup (mfs);
+ if (tmi != PHY_MOD_ROBO)
+ dbg_check (mac_store_sta_remove (tp->store, dtei));
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_woack_test (test_t t, test_pbproc_t *tp, u32 date, uint mfs_seg_nb,
+ uint duration_tck, uint symb_nb, uint data_seg_nb_total)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint dtei = 0xff;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (true, false, lid, dtei, mfs_seg_nb);
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = duration_tck,
+ .prp = true,
+ .cfp = false,
+ };
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true,
+ .nb_total = data_seg_nb_total,
+ .nb_pb_it = data_seg_nb_total,
+ .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_ROBO, .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_ACTION (phy_pbdma, .pb_it = true, .end_tx_pb = true),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_woack = 1);
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_NOP);
+ test_fail_unless (mfs->stats.num_mpdus == 1);
+ test_fail_unless (mfs->stats.num_bursts == 1);
+ test_fail_unless (mfs->stats.num_pbs == data_seg_nb_total);
+ test_fail_unless (mfs->stats.num_segs_suc == data_seg_nb_total);
+ utils_mfs_tx_cleanup (mfs);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_rx_window_change_test (test_t t, test_pbproc_t *tp)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint stei = tp->config.tei;
+ const uint dtei = 2;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ tonemap_t *tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint dx = MAC_DX417_TCK;
+ tm = utils_sta_prepare_default_tonemap (tp, true, dtei, 5, 10, 0,
+ &dx);
+ uint rifs_tck = MAC_RIFS_SPC_ANY_TCK;
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, lid, dtei,
+ 100);
+ mfs->common.unassociated = false;
+ test_pbproc_alloc (tp, false, 100000 / beacon_tck * beacon_tck);
+ /* First transmission with default RX window size. */
+ ca_access_param_t access_1 = {
+ .access_date = 100000,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (25, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ .prp = true,
+ .cfp = false,
+ };
+ pbproc_fc_sack_t sack_fc_1 = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = stei,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = MFS_WINDOW_SIZE_256 << 4,
+ .fccs_av = 0,
+ };
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (25, MAC_DX417_TCK) + rifs_tck;
+ scenario_entry_t entries_1[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access_1,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true,
+ .nb_total = 41,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_set_tonemap),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_TM, .fecrate = tm->fecrate,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = 100000, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = 100000),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs,
+ .start_date = 100000 + pre_fc_fl_tck),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = 100000 + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = 100000 + pre_fc_fl_tck,
+ .fc_av = (u32 *) &sack_fc_1),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = 100000 + pre_fc_fl_tck + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries_1, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_wack = 1,
+ .tx_data_wack_ack = 1);
+ /* No fsm command in EoC */
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_INIT);
+ test_fail_unless (mfs->stats.num_mpdus == 1);
+ test_fail_unless (mfs->stats.num_bursts == 1);
+ test_fail_unless (mfs->stats.num_pbs == 41);
+ test_fail_unless (mfs->stats.num_segs_suc == 41);
+ /* Second transmission: RX window will change. */
+ ca_access_param_t access_2 = {
+ .access_date = 300000,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (25, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ .prp = true,
+ .cfp = false,
+ };
+ pbproc_fc_sack_t sack_fc_2 = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = stei,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_NACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = MFS_WINDOW_SIZE_24 << 4,
+ .fccs_av = 0,
+ };
+ scenario_entry_t entries_2[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access_2,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true,
+ .nb_total = 41,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_set_tonemap),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_TM, .fecrate = tm->fecrate,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = 300000, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = 300000),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs,
+ .start_date = 300000 + pre_fc_fl_tck),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = 300000 + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = 300000 + pre_fc_fl_tck,
+ .fc_av = (u32 *) &sack_fc_2),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = 300000 + pre_fc_fl_tck + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries_2, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_wack = 1,
+ .tx_data_wack_ack = 1);
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_INIT);
+ test_fail_unless (mfs->stats.num_mpdus == 2);
+ test_fail_unless (mfs->stats.num_bursts == 2);
+ test_fail_unless (mfs->stats.num_pbs == 82);
+ test_fail_unless (mfs->stats.num_segs_suc == 41);
+#if !CONFIG_MAC_PBPROC_EOC_FC
+ /* Third transmission: check that we only send 1 PB and that we switch to
+ * IN_SYNC after ACK. */
+ ca_access_param_t access_3 = {
+ .access_date = 500000,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (25, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ .prp = true,
+ .cfp = false,
+ };
+ pbproc_fc_sack_t sack_fc_3 = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = stei,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = MFS_WINDOW_SIZE_24 << 4,
+ .fccs_av = 0,
+ };
+ const uint pre_fc_fl_tck_2 = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (1, MAC_DX417_TCK) + rifs_tck;
+ scenario_entry_t entries_3[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access_3,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true,
+ .nb_total = 1,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_set_tonemap),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_TM, .fecrate = tm->fecrate,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = 500000, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = 500000),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs,
+ .start_date = 500000 + pre_fc_fl_tck_2),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = 500000 + pre_fc_fl_tck_2,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = 500000 + pre_fc_fl_tck_2,
+ .fc_av = (u32 *) &sack_fc_3),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = 500000 + pre_fc_fl_tck_2 + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries_3, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_wack = 1,
+ .tx_data_wack_ack = 1);
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_INIT);
+ test_fail_unless (mfs->stats.num_mpdus == 3);
+ test_fail_unless (mfs->stats.num_bursts == 3);
+ test_fail_unless (mfs->stats.num_pbs == 83);
+ test_fail_unless (mfs->stats.num_segs_suc == 42);
+#endif
+ /* End of the test. */
+ utils_mfs_tx_cleanup (mfs);
+ dbg_check (mac_store_sta_remove (tp->store, dtei));
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_burst_test (test_t t, test_pbproc_t *tp, u32 date, uint mfs_seg_nb,
+ uint duration_tck,
+ uint symb_nb_1, uint data_seg_nb_total_1,
+ uint symb_nb_0, uint data_seg_nb_total_0,
+ uint tmi_1, uint tmi_0, utils_interval_t *intervals,
+ bool remove, bool different_gil)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint stei = tp->config.tei;
+ const uint dtei = 2;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ tonemap_t *tm_1 = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ tonemap_t *tm_0 = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ uint dx_1 = MAC_DX417_TCK, dx_0 = MAC_DX417_TCK;
+ /* Prepare tone maps. */
+ if (tmi_1 != PHY_MOD_ROBO || intervals)
+ tm_1 = utils_sta_prepare_default_tonemap (tp, true, dtei, tmi_1, 10,
+ 0, &dx_1);
+ if (tmi_0 == tmi_1)
+ tm_0 = tm_1;
+ else if (tmi_0 != PHY_MOD_ROBO)
+ {
+ tm_0 = utils_sta_prepare_default_tonemap (tp, true, dtei, tmi_0, 10,
+ 0, &dx_0);
+ if (different_gil)
+ {
+ tm_0->gil = PHY_GIL_567;
+ dx_0 = MAC_DX567_TCK;
+ }
+ }
+ if (intervals)
+ utils_sta_prepare_intervals (tp, dtei, intervals, PHY_MOD_ROBO);
+ /* Ask for channel data to enable sound transmission. */
+ u32 chandata_conf[1] = { 0 };
+ pbproc_set_chandata_conf (
+ tp->pbproc, (phy_chandata_conf_t *) chandata_conf, 1, false);
+ /* Prepare ACCESS, data and acknowledge. */
+ uint rifs_tck = tmi_0 < PHY_MOD_ROBO_NB || symb_nb_0 == 0
+ ? MAC_RIFS_DEFAULT_TCK : MAC_RIFS_SPC_ANY_TCK;
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, lid, dtei,
+ mfs_seg_nb);
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = duration_tck,
+ .prp = true,
+ .cfp = false,
+ };
+ pbproc_fc_sack_t sack_fc = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = stei,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = PBPROC_FC_SACKT_UNIFORM,
+ .sackt0 = PBPROC_FC_SACKT_UNIFORM,
+ .sacki = { 0x11, 0 },
+ .sacki_last = 0,
+ .fccs_av = 0,
+ };
+ const uint pre_fc_fl_1_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb_1, dx_1) + MAC_BIFS_TCK;
+ const uint pre_fc_fl_0_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb_0, dx_0) + rifs_tck;
+ /* Scenario. */
+ scenario_entry_t entries[] = {
+ /* First MPDU. */
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true,
+ .nb_total = data_seg_nb_total_1,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT_COND (tmi_1 >= PHY_MOD_ROBO_NB, phy_set_tonemap),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = tmi_1 < PHY_MOD_ROBO_NB ? tmi_1 : PHY_MOD_TM,
+ .fecrate = tm_1->fecrate, .pb_size = PHY_PB_SIZE_520,
+ .gil = tm_1->gil),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_END
+ };
+ scenario_entry_t entries2[] = {
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ /* Second MPDU. */
+ SCENARIO_EVENT (phy_access_timer_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT_COND (symb_nb_0, phy_tx_param,
+ .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = tmi_0 < PHY_MOD_ROBO_NB ? tmi_0
+ : PHY_MOD_TM, .fecrate = tm_0->fecrate,
+ .pb_size = PHY_PB_SIZE_520, .gil = tm_0->gil),
+ SCENARIO_EVENT_COND (!symb_nb_0, phy_tx_param_short, .fc_mode =
+ PHY_FC_MODE_AV_1),
+ SCENARIO_EVENT (phy_tx_frame, .date = date + pre_fc_fl_1_tck,
+ .want_conf = true, .stop_tx_on_prp_lost = false),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_access_timer_cancel),
+ SCENARIO_EVENT_COND (symb_nb_0, phy_pbdma_start, .bypass_aes = true,
+ .nb_total = data_seg_nb_total_0, .nb_pb_it = 0,
+ .chandata = false, .now = false),
+ SCENARIO_EVENT_COND (symb_nb_0 && tmi_0 >= PHY_MOD_ROBO_NB,
+ phy_set_tonemap),
+ SCENARIO_EVENT_COND (symb_nb_0, phy_tx_prepare),
+ /* End of burst. */
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs,
+ .start_date = date + pre_fc_fl_1_tck
+ + pre_fc_fl_0_tck),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + pre_fc_fl_1_tck + pre_fc_fl_0_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date + pre_fc_fl_1_tck
+ + pre_fc_fl_0_tck, .fc_av = (u32 *) &sack_fc),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_1_tck + pre_fc_fl_0_tck
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ uint num_segs_suc;
+ if (remove)
+ {
+ mfs->ca_state = CA_MFS_STATE_REMOVED;
+ num_segs_suc = MIN (4u, data_seg_nb_total_1);
+ }
+ else
+ num_segs_suc = data_seg_nb_total_1 + data_seg_nb_total_0;
+ scenario_run (t, entries2, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_burst = 1,
+ .tx_data_burst_interrupted = symb_nb_0 ? 0 : 1,
+ .tx_data_wack = 1, .tx_data_wack_ack = 1);
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_IN_SYNC);
+ test_fail_unless (mfs->stats.num_mpdus == 2);
+ test_fail_unless (mfs->stats.num_bursts == 1);
+ test_fail_unless (mfs->stats.num_pbs == data_seg_nb_total_1
+ + data_seg_nb_total_0);
+ test_fail_unless (mfs->stats.num_segs_suc == num_segs_suc);
+ /* Cleanup. */
+ utils_mfs_tx_cleanup (mfs);
+ if (tmi_1 != PHY_MOD_ROBO || tmi_0 != PHY_MOD_ROBO || intervals)
+ dbg_check (mac_store_sta_remove (tp->store, dtei));
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_noseg_test (test_t t, test_pbproc_t *tp, u32 date, uint duration_tck,
+ bool prp_won, bool got_mfs, bool late)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint dtei = 2;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ mfs_tx_t *mfs = got_mfs
+ ? utils_mfs_tx_prepare (false, false, lid, dtei, late ? 1 : 0)
+ : NULL;
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = duration_tck,
+ .prp = true,
+ .cfp = false,
+ };
+ scenario_entry_t *entries;
+ scenario_entry_t entries_prp_won[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 0,
+ .delay_tck = late ? PBPROC_ANTICIP_TCK : 0),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT_COND (late, ca_access_done),
+ SCENARIO_EVENT (ca_backoff_deferred,
+ .slot_count = access.duration_tck / MAC_SLOT_TCK),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_access_defer, .date = date),
+ SCENARIO_END
+ };
+ scenario_entry_t entries_prp_lost[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = false, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_backoff_cancel),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs,
+ .start_date = phy_date ()),
+ SCENARIO_END
+ };
+ entries = prp_won ? entries_prp_won : entries_prp_lost;
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (t, tp,
+ .prp_lost = prp_won ? 0 : 1,
+ .tx_invalid = (late || prp_won) ? 1 : 0,
+ .tx_late = late ? 1 : 0);
+ if (mfs)
+ {
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_INIT);
+ test_fail_unless (mfs->stats.num_mpdus == 0);
+ test_fail_unless (mfs->stats.num_bursts == 0);
+ test_fail_unless (mfs->stats.num_pbs == 0);
+ test_fail_unless (mfs->stats.num_segs_suc == 0);
+ utils_mfs_tx_cleanup (mfs);
+ }
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_beacon_test (test_t t, test_pbproc_t *tp, u32 date, uint duration_tck,
+ uint symb_nb)
+{
+ test_within (t);
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (true, false, MAC_LID_SPC_CENTRAL,
+ MAC_TEI_BCAST, 0);
+ mfs->cfp = true;
+ mfs->beacon = true;
+ pb_beacon_t *pb = PARENT_OF (pb_beacon_t, blk, blk_alloc_desc ());
+ pbproc_tx_beacon_params_t params = {
+ { 0x0123, 0x4242, 0xabab, 0x5555 }, pb->data + 123
+ };
+ pbproc_mfs_beacon_prepare (tp->pbproc, mfs, pb, &params);
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = duration_tck,
+ .prp = false,
+ .cfp = true,
+ };
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_PAYLOAD_TCK (symb_nb, MAC_DX567_TCK)
+ + MAC_B2BIFS_TCK;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 0),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true, .nb_total = 1,
+ .nb_pb_it = 1, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_MINI_ROBO, .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_136, .gil = PHY_GIL_567),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = true,
+ .stop_tx_on_prp_lost = false),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_ACTION (phy_access_conf),
+ SCENARIO_EVENT (phy_tx_prepare),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_ACTION (phy_pbdma, .pb_it = true, .end_tx_pb = true),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (t, tp, .tx_data = 1, .tx_data_beacon = 1);
+ test_fail_unless (mfs->stats.num_mpdus == 1);
+ test_fail_unless (mfs->stats.num_bursts == 1);
+ test_fail_unless (mfs->stats.num_pbs == 1);
+ test_fail_unless (mfs->stats.num_segs_suc == 1);
+ utils_mfs_tx_cleanup (mfs);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_basic_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "basic");
+ test_pbproc_init (&tp);
+ test_begin (t, "unicast")
+ {
+ tx_data_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 5, false, PHY_MOD_HS_ROBO, PHY_PREPARE_TYPE_NB, false);
+ tx_data_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 38, 2, true, PHY_MOD_ROBO, PHY_PREPARE_TYPE_NB, false);
+ tx_data_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 5, false, PHY_MOD_HS_ROBO, PHY_PREPARE_TYPE_NB, true);
+ tx_data_test (t, &tp, 5462132, 0,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (30, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 0, 0, false, PHY_MOD_ROBO, PHY_PREPARE_TYPE_NB, true);
+ } test_end;
+ test_begin (t, "no seg prp won")
+ {
+ tx_data_noseg_test (t, &tp, 5462132,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK, true, true, false);
+ } test_end;
+ test_begin (t, "no seg prp lost")
+ {
+ tx_data_noseg_test (t, &tp, 5462132,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK, false, true, false);
+ } test_end;
+ test_begin (t, "no mfs prp won")
+ {
+ tx_data_noseg_test (t, &tp, 5462132,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK, true, false, false);
+ } test_end;
+ test_begin (t, "no mfs prp lost")
+ {
+ tx_data_noseg_test (t, &tp, 5462132,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK, false, false, false);
+ } test_end;
+ test_begin (t, "multicast")
+ {
+ tx_data_woack_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 38, 2);
+ } test_end;
+ test_begin (t, "beacon")
+ {
+ tx_data_beacon_test (t, &tp, 123, MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (6, MAC_DX567_TCK)
+ + MAC_B2BIFS_TCK, 6);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_data_rx_window_change_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "rx window size");
+ test_pbproc_init (&tp);
+ test_begin (t, "change")
+ {
+ tx_data_rx_window_change_test (t, &tp);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_data_bursts_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "bursts");
+ test_pbproc_init (&tp);
+ utils_interval_t intervals[] =
+ {
+ { 100000, 5, 0 },
+ { 200000, 6, 0 },
+ { 300000, TONEMAP_INDEX_INTERVAL_UNUSABLE, 0 },
+ { 0, 0, 0 }
+ };
+ test_begin (t, "max fl")
+ {
+ tx_data_burst_test (t, &tp, 5162132, 83 + 26,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 83, 16, 26,
+ 6, 6, NULL, false, false);
+ } test_end;
+ test_begin (t, "interval max fl, seg limit")
+ {
+ tx_data_burst_test (t, &tp,
+ 100000 - (MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_BIFS_TCK),
+ 83 + 26,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 83, 16, 26,
+ 5, 6, intervals, false, false);
+ } test_end;
+ test_begin (t, "interval max fl, interrupt on sound")
+ {
+ tx_data_burst_test (t, &tp,
+ 200000 - (MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_BIFS_TCK),
+ 90,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 83, 0, 0,
+ 6, 0, intervals, false, false);
+ } test_end;
+ test_begin (t, "interval max fl, interrupt on no pb")
+ {
+ tx_data_burst_test (t, &tp, 5162132, 100,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 83, 0, 0,
+ 6, 0, NULL, true, false);
+ } test_end;
+ test_begin (t, "interval max fl, interrupt on different GIL")
+ {
+ tx_data_burst_test (t, &tp,
+ 100000 - (MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_BIFS_TCK),
+ 100,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 83, 0, 0,
+ 5, 6, intervals, false, true);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_data_spoc_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "spoc");
+ test_pbproc_init (&tp);
+ phy_spoc_coeff_t *coeff = blk_alloc ();
+ coeff->part2 = blk_alloc ();
+ coeff->rho_q30 = 42;
+ pbproc_spoc_coeff_set (tp.pbproc, true, coeff);
+ test_begin (t, "preamble")
+ {
+ tx_data_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 5, false, PHY_MOD_HS_ROBO,
+ PHY_PREPARE_TYPE_PREAMBLE, false);
+ test_fail_unless (tp.pbproc->spoc_update.step
+ == PHY_PREPARE_TYPE_PRS);
+ test_fail_unless (tp.pbproc->spoc_update.coeff == NULL);
+ } test_end;
+ test_begin (t, "prs")
+ {
+ tx_data_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 5, false, PHY_MOD_HS_ROBO,
+ PHY_PREPARE_TYPE_PRS, false);
+ test_fail_unless (tp.pbproc->spoc_update.step
+ == PHY_PREPARE_TYPE_NB);
+ } test_end;
+ test_begin (t, "done")
+ {
+ tx_data_test (t, &tp, 5462132, 30,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (50, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK,
+ 50, 5, false, PHY_MOD_HS_ROBO,
+ PHY_PREPARE_TYPE_NB, false);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_data_cancel_test (test_t t, test_pbproc_t *tp, bool prp_won, bool rx_fc)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint dtei = 2;
+ const uint date = 123456;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, lid, dtei, 1);
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (19, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK +
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK,
+ .prp = true,
+ .cfp = false,
+ };
+ const uint date2 = 123456 + MAC_EIFS_AV_TCK;
+ const uint date3 = date2 + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK
+ - PBPROC_ANTICIP_TCK;
+ ca_access_param_t access2 = {
+ .access_date = date2,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (19, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK +
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK,
+ .prp = false,
+ .cfp = false,
+ };
+ ca_access_param_t access3 = {
+ .access_date = date3,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (19, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK +
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK,
+ .prp = false,
+ .cfp = false,
+ };
+ pbproc_fc_sack_t sack_fc = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = tp->config.tei + 8,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = 0,
+ .fccs_av = 0,
+ };
+ uint sack_length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK;
+ scenario_entry_t sack_entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 6),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true, .nb_total = 1,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_ROBO, .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date - MAC_SLOT_TCK,
+ .prp_won = prp_won, .slot_count = 5,
+ .fc_av = PARENT_OF (pbproc_fc_t, sack,
+ &sack_fc)->words),
+ SCENARIO_EVENT_COND (prp_won, ca_backoff_deferred, .slot_count = 3),
+ SCENARIO_EVENT_COND (!prp_won, ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date - MAC_SLOT_TCK + sack_length_tck),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_END
+ };
+ scenario_entry_t access_entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 6),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true, .nb_total = 1,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_ROBO, .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = true,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access2,
+ .prp_won = prp_won, .slot_count = 600),
+ SCENARIO_EVENT (ca_access_done),
+ /* vcs_restart */
+ SCENARIO_EVENT (ca_access_vcs_restart, .end_date = date3),
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access3,
+ .prp_won = prp_won, .slot_count = 600),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_pbdma_start, .bypass_aes = true, .nb_total = 1,
+ .nb_pb_it = 0, .chandata = false, .now = false),
+ SCENARIO_EVENT (phy_tx_param, .fc_mode = PHY_FC_MODE_AV_1,
+ .mod = PHY_MOD_ROBO, .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date3, .want_conf = true,
+ .stop_tx_on_prp_lost = false),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date3),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date3 - MAC_SLOT_TCK,
+ .prp_won = prp_won, .slot_count = 5,
+ .fc_av = PARENT_OF (pbproc_fc_t, sack,
+ &sack_fc)->words),
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 3),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date3 - MAC_SLOT_TCK + sack_length_tck),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_END
+ };
+ scenario_entry_t *entries = rx_fc ? sack_entries : access_entries;
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = prp_won ? 0 : 1,
+ .cw_lost = prp_won || !rx_fc ? 1 : 0,
+ .rx_handle_fc = 1,
+ .rx_nfu = 1,
+ .tx_data = rx_fc ? 1 : 2,
+ .tx_data_cancel = rx_fc ? 1 : 2,
+ );
+ test_fail_unless (mfs->fsm_state == MFS_FSM_CMD_INIT);
+ test_fail_unless (mfs->stats.num_mpdus == 0);
+ test_fail_unless (mfs->stats.num_bursts == 0);
+ test_fail_unless (mfs->stats.num_pbs == 0);
+ test_fail_unless (mfs->stats.num_segs_suc == 0);
+ utils_mfs_tx_cleanup (mfs);
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+}
+
+void
+tx_data_error_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "error");
+ test_pbproc_init (&tp);
+ test_begin (t, "cw lost")
+ {
+ tx_data_cancel_test (t, &tp, true, true);
+ } test_end;
+ test_begin (t, "prp lost after access")
+ {
+ tx_data_cancel_test (t, &tp, false, true);
+ } test_end;
+ test_begin (t, "prp lost after access and no frame")
+ {
+ tx_data_cancel_test (t, &tp, false, false);
+ } test_end;
+ test_begin (t, "tx late")
+ {
+ tx_data_noseg_test (t, &tp, 5462132,
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (95, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK, true, true, true);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_data_test_suite (test_t t)
+{
+ test_suite_begin (t, "tx data");
+ tx_data_basic_test_case (t);
+ tx_data_rx_window_change_test_case (t);
+ /* bursts are not supported now */
+ /* tx_data_bursts_test_case (t); */
+ tx_data_spoc_test_case (t);
+ tx_data_error_test_case (t);
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/tx_sound.c b/cesar/mac/pbproc/test/pbproc_eoc/src/tx_sound.c
new file mode 100644
index 0000000000..9fce858f86
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/tx_sound.c
@@ -0,0 +1,364 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/tx_sound.c
+ * \brief TX SOUND automaton test
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "inc/test_pbproc.h"
+#include "inc/utils.h"
+
+#include "mac/common/timings.h"
+
+void
+tx_sound_test (test_t t, test_pbproc_t *tp)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint dtei = 5;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ const u32 date = 12345;
+ const uint symb_nb = 19;
+ const uint duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK)
+ + MAC_RIFS_DEFAULT_TCK + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK;
+ u32 chandata_conf[1] = { 0 };
+ pbproc_set_chandata_conf (
+ tp->pbproc, (phy_chandata_conf_t *) chandata_conf, 1, false);
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, lid, dtei, 1);
+ utils_sta_prepare_default_tonemap (tp, true, dtei,
+ TONEMAP_INDEX_INITIAL_START, 0, 0,
+ NULL);
+ /* need authenticated sta to send sound frames */
+ sta_t * sta = mac_store_sta_get(tp->store, dtei);
+ if (sta)
+ {
+ sta->authenticated = true;
+ tp->pbproc->config->authenticated = true;
+ blk_release (sta);
+ }
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = duration_tck,
+ .prp = true,
+ .cfp = true,
+ };
+ pbproc_fc_sound_t sound_ack_fc = {
+ .dt_av = PBPROC_FC_DT_SOUND,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = dtei,
+ .direction = 1,
+ .lid = lid,
+ .pbsz = false,
+ .saf = true,
+ .scf = true,
+ .req_tm = 0,
+ .fl_av = 0,
+ .mpdu_cnt = 0,
+ .src = 0,
+ .fccs_av = 0,
+ };
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 2),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_tx_param_sound, .fc_mode = PHY_FC_MODE_AV_1,
+ .nb_pb = 1, .mod = PHY_MOD_ROBO,
+ .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date + pre_fc_fl_tck,
+ .fc_av = (u32 *) &sound_ack_fc),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT_COND (!access.cfp, ca_backoff_success),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date + pre_fc_fl_tck + MAC_PREAMBLE_TCK
+ + MAC_FC_AV_TCK + MAC_CIFS_TCK),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ test_pbproc_check_stats (t, tp, .tx_sound = 1, .tx_sound_ack = 1);
+ test_fail_unless (mfs->stats.num_mpdus == 0);
+ test_fail_unless (mfs->stats.num_bursts == 0);
+ test_fail_unless (mfs->stats.num_pbs == 0);
+ test_fail_unless (mfs->stats.num_segs_suc == 0);
+ utils_mfs_tx_cleanup (mfs);
+ dbg_check (mac_store_sta_remove (tp->store, dtei));
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0, false);
+}
+
+void
+tx_sound_basic_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "basic");
+ test_pbproc_init (&tp);
+ test_begin (t, "basic")
+ {
+ tx_sound_test (t, &tp);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_sound_cancel_test (test_t t, test_pbproc_t *tp, bool prp_won, bool rx_fc,
+ bool late)
+{
+ test_within (t);
+ const uint lid = 1;
+ const uint dtei = 2;
+ const uint date = 123456;
+ const uint beacon_tck = MAC_MS_TO_TCK (1000) / 50;
+ const uint symb_nb = 19;
+ u32 chandata_conf[1] = { 0 };
+ pbproc_set_chandata_conf (
+ tp->pbproc, (phy_chandata_conf_t *) chandata_conf, 1, false);
+ mfs_tx_t *mfs = utils_mfs_tx_prepare (false, false, lid, dtei, 1);
+ utils_sta_prepare_default_tonemap (tp, true, dtei,
+ TONEMAP_INDEX_INITIAL_START, 0, 0,
+ NULL);
+ test_pbproc_alloc (tp, false, date / beacon_tck * beacon_tck);
+ /* need authenticated sta to send sound frames */
+ sta_t * sta = mac_store_sta_get(tp->store, dtei);
+ if (sta)
+ {
+ sta->authenticated = true;
+ tp->pbproc->config->authenticated = true;
+ blk_release (sta);
+ }
+ ca_access_param_t access = {
+ .access_date = date,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK,
+ .prp = true,
+ .cfp = true,
+ };
+ const uint date2 = 123456 + MAC_EIFS_AV_TCK;
+ const uint date3 = date2 + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK + MAC_CIFS_TCK
+ - PBPROC_ANTICIP_TCK;
+ ca_access_param_t access2 = {
+ .access_date = date2,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK
+ + MAC_PREAMBLE_TCK + MAC_FC_AV_TCK,
+ .prp = false,
+ .cfp = true,
+ };
+ ca_access_param_t access3 = {
+ .access_date = date3,
+ .duration_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK +
+ MAC_PREAMBLE_TCK + MAC_FC_AV_TCK,
+ .prp = false,
+ .cfp = true,
+ };
+ pbproc_fc_sack_t sack_fc = {
+ .dt_av = PBPROC_FC_DT_SACK,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = tp->config.tei + 8,
+ .cfs = false,
+ .bdf = true,
+ .svn = 0,
+ .rrtf = false,
+ .mfs_rsp_data = MFS_FSM_RSP_ACK,
+ .mfs_rsp_mgmt = MFS_FSM_RSP_ACK,
+ .sackt3 = 0,
+ .sackt2 = 0,
+ .sackt1 = 0,
+ .sackt0 = 0,
+ .sacki = { 0, 0 },
+ .sacki_last = 0,
+ .fccs_av = 0,
+ };
+ const uint pre_fc_fl_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_PAYLOAD_TCK (symb_nb, MAC_DX417_TCK) + MAC_RIFS_DEFAULT_TCK;
+ const uint sack_length_tck = MAC_PREAMBLE_TCK + MAC_FC_AV_TCK
+ + MAC_CIFS_TCK;
+ scenario_entry_t sack_entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 6),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_tx_param_sound, .fc_mode = PHY_FC_MODE_AV_1,
+ .nb_pb = 1, .mod = PHY_MOD_ROBO,
+ .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date - MAC_SLOT_TCK,
+ .prp_won = prp_won, .slot_count = 5,
+ .fc_av = PARENT_OF (pbproc_fc_t, sack,
+ &sack_fc)->words),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT_COND (prp_won, ca_backoff_deferred, .slot_count = 3),
+ SCENARIO_EVENT_COND (!prp_won, ca_backoff_cancel),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date - MAC_SLOT_TCK + sack_length_tck),
+ SCENARIO_END
+ };
+ scenario_entry_t access_entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 6),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_tx_param_sound, .fc_mode = PHY_FC_MODE_AV_1,
+ .nb_pb = 1, .mod = PHY_MOD_ROBO,
+ .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date, .want_conf = false,
+ .stop_tx_on_prp_lost = true),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access2,
+ .prp_won = prp_won, .slot_count = 600),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT_COND (prp_won, ca_backoff_deferred, .slot_count = 598),
+ SCENARIO_EVENT_COND (!prp_won, ca_backoff_cancel),
+ SCENARIO_EVENT (ca_access_vcs_restart, .end_date = date3),
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access3,
+ .prp_won = prp_won, .slot_count = 600),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (phy_tx_param_sound, .fc_mode = PHY_FC_MODE_AV_1,
+ .nb_pb = 1, .mod = PHY_MOD_ROBO,
+ .fecrate = PHY_FEC_RATE_1_2,
+ .pb_size = PHY_PB_SIZE_520, .gil = PHY_GIL_417),
+ SCENARIO_EVENT (phy_tx_frame, .date = date3, .want_conf = false,
+ .stop_tx_on_prp_lost = false),
+ SCENARIO_EVENT (ca_access_vcs_restart_eifs, .start_date = date3),
+ SCENARIO_EVENT (phy_rx_activate, .now = false,
+ .date = date3 + pre_fc_fl_tck,
+ .pre_detection = true),
+ SCENARIO_ACTION (phy_rx_fc, .rx_date = date3 - MAC_SLOT_TCK,
+ .prp_won = prp_won, .slot_count = 5,
+ .fc_av = PARENT_OF (pbproc_fc_t, sack,
+ &sack_fc)->words),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_deferred, .slot_count = 3),
+ SCENARIO_EVENT (phy_tx_cancel),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (phy_rx_prepare_short),
+ SCENARIO_EVENT (ca_access_vcs_restart,
+ .end_date = date3 - MAC_SLOT_TCK + sack_length_tck),
+ SCENARIO_END
+ };
+ scenario_entry_t late_entries[] = {
+ SCENARIO_ACTION (phy_access, .mfs = mfs, .access_param = &access,
+ .prp_won = true, .slot_count = 6,
+ .delay_tck = late ? PBPROC_ANTICIP_TCK : 0),
+ SCENARIO_EVENT (ca_access_hold),
+ SCENARIO_EVENT (ca_access_get_mfs),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_backoff_deferred,
+ .slot_count = access.duration_tck / MAC_SLOT_TCK),
+ SCENARIO_EVENT (ca_access_done),
+ SCENARIO_EVENT (ca_access_defer, .date = date),
+ SCENARIO_END
+ };
+ scenario_entry_t *entries =
+ late ? late_entries : (rx_fc ? sack_entries : access_entries);
+ scenario_globals_t globals = {
+ .tp = tp,
+ };
+ test_pbproc_check_stats_reset (tp);
+ scenario_run (t, entries, &globals);
+ if (!late)
+ test_pbproc_check_stats (
+ t, tp,
+ .prp_lost = prp_won ? 0 : 1,
+ .cw_lost = rx_fc ? (prp_won ? 1 : 0) : (prp_won ? 2 : 1),
+ .rx_handle_fc = 1,
+ .rx_nfu = 1,
+ .tx_sound = rx_fc ? 1 : 2,
+ .tx_sound_noack = rx_fc ? 1 : 2,
+ );
+ else
+ test_pbproc_check_stats (t, tp, .tx_invalid = 1, .tx_late = 1);
+ test_fail_unless (mfs->stats.num_mpdus == 0);
+ test_fail_unless (mfs->stats.num_bursts == 0);
+ test_fail_unless (mfs->stats.num_pbs == 0);
+ test_fail_unless (mfs->stats.num_segs_suc == 0);
+ utils_mfs_tx_cleanup (mfs);
+ dbg_check (mac_store_sta_remove (tp->store, dtei));
+ test_fail_unless (tp->pbproc->fsm.current_state == PBPROC_FSM_STATE_IDLE);
+ pbproc_set_chandata_conf (tp->pbproc, NULL, 0, false);
+}
+
+void
+tx_sound_error_test_case (test_t t)
+{
+ test_pbproc_t tp;
+ test_case_begin (t, "error");
+ test_pbproc_init (&tp);
+ test_begin (t, "no ack")
+ {
+ tx_sound_cancel_test (t, &tp, true, false, false);
+ } test_end;
+ test_begin (t, "cw lost")
+ {
+ tx_sound_cancel_test (t, &tp, true, true, false);
+ } test_end;
+ test_begin (t, "prp lost")
+ {
+ tx_sound_cancel_test (t, &tp, false, true, false);
+ } test_end;
+ test_begin (t, "prp lost and no frame")
+ {
+ tx_sound_cancel_test (t, &tp, false, false, false);
+ } test_end;
+ test_begin (t, "tx late")
+ {
+ tx_sound_cancel_test (t, &tp, true, false, true);
+ } test_end;
+ test_pbproc_uninit (&tp);
+}
+
+void
+tx_sound_test_suite (test_t t)
+{
+ test_suite_begin (t, "tx sound");
+ tx_sound_basic_test_case (t);
+ tx_sound_error_test_case (t);
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
diff --git a/cesar/mac/pbproc/test/pbproc_eoc/src/utils.c b/cesar/mac/pbproc/test/pbproc_eoc/src/utils.c
new file mode 100644
index 0000000000..e8bd3907af
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/utils.c
@@ -0,0 +1,253 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/utils.c
+ * \brief Utilities.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "inc/utils.h"
+
+#include "lib/blk.h"
+#include "lib/slist.h"
+#include "mac/common/timings.h"
+#include "mac/common/interval.h"
+#include "mac/pbproc/pbproc.h"
+#include "mac/pbproc/inc/mfs.h"
+
+mfs_tx_t *
+utils_mfs_tx_prepare (bool bcast, bool mme, uint lid, uint tei, int seg_nb)
+{
+ /* Create a MFS without holes. */
+ return utils_mfs_tx_holes_prepare(bcast, mme, lid, tei, seg_nb, 0);
+}
+
+mfs_tx_t *
+utils_mfs_tx_holes_prepare (bool bcast, bool mme, uint lid, uint tei,
+ int seg_nb, u64 holes_bmp)
+{
+ /* Create an MFS. */
+ mfs_tx_t *mfs = blk_alloc ();
+ mfs_tx_init (mfs, bcast, mme, lid, tei);
+ /* Default value for receiver window size */
+ mfs->window_size = mfs_window_size[MFS_WINDOW_SIZE_256];
+ if (seg_nb)
+ {
+ /* Add blocks to it. */
+ blk_t *blk_first, *blk_last;
+ blk_first = blk_alloc_desc_range (seg_nb, &blk_last);
+ pb_t *seg_first, *seg_last;
+ seg_first = PARENT_OF (pb_t, blk, blk_first);
+ seg_last = PARENT_OF (pb_t, blk, blk_last);
+ pb_t *seg, *lseg;
+ bool start_counting_holes = false;
+ uint expiration_count = 1;
+ for (lseg = NULL, seg = seg_first;
+ lseg != seg_last;
+ lseg = seg, seg = seg->next)
+ {
+ /* Use the bitmap to attribute the SSNs. */
+ while(holes_bmp & 1)
+ {
+ mfs->next_ssn++;
+ holes_bmp >>= 1;
+ if (start_counting_holes)
+ mfs->holes_seg_nb++;
+ }
+ start_counting_holes = true;
+ holes_bmp >>= 1;
+ seg->header.ssn = mfs->next_ssn++;
+ seg->header.mfbo = 0;
+ seg->header.vpbf = true;
+ seg->header.mmqf = mme;
+ seg->header.mfbf = false;
+ seg->header.opsf = false;
+ seg->header.rsvd = 0;
+ seg->expiration_ntb = expiration_count * UTILS_MFS_EXPIRATION_NTB_STEP
+ + TEST_PBPROC_NTB_OFFSET_TCK + TEST_PBPROC_EXPIRATION_DATE_OFFSET;
+ expiration_count++;
+ }
+ pbproc_mfs_insert_ (mfs, seg_first, seg_last, seg_nb);
+ pbproc_mfs_provide (mfs, seg_nb);
+ }
+ else
+ {
+ mfs->seg_nb = seg_nb;
+ }
+ return mfs;
+}
+
+static mfs_tx_t * local_mfs = NULL;
+
+mfs_tx_t *
+utils_mfs_tx_prepare_save (bool bcast, bool mme, uint lid, uint tei,
+ uint seg_nb)
+{
+ local_mfs = utils_mfs_tx_prepare(bcast, mme, lid, tei, seg_nb);
+ return local_mfs;
+}
+
+void
+utils_mfs_tx_cleanup (mfs_tx_t *mfs)
+{
+ if (mfs->head)
+ {
+ blk_release_desc_range (&mfs->head->blk, &mfs->tail->blk);
+ slist_init (mfs->, bare);
+ }
+ blk_release (mfs);
+}
+
+tonemap_t *
+utils_sta_prepare_default_tonemap (test_pbproc_t *tp, bool tx, uint tei,
+ uint tmi, uint tm_mod, uint tm_max_fl_tck,
+ uint *dx)
+{
+ dbg_assert (tmi < TONEMAP_INDEX_NB
+ || tmi == TONEMAP_INDEX_INITIAL_START
+ || tmi == TONEMAP_INDEX_INITIAL_ERROR
+ || tmi == TONEMAP_INDEX_INITIAL_SOUND_COMPLETE);
+ mac_store_sta_add (tp->store, tei);
+ sta_t *sta = mac_store_sta_get (tp->store, tei);
+ dbg_assert (sta);
+ if (tm_max_fl_tck)
+ {
+ uint max_fl_av = MAC_TCK_TO_FL (tm_max_fl_tck);
+ if (tx)
+ sta->tx_tonemaps->max_fl_av = max_fl_av;
+ else
+ sta->rx_tonemaps->max_fl_av = max_fl_av;
+ }
+ if (tx)
+ sta->tx_tonemaps->default_tmi = tmi;
+ else
+ sta->rx_tonemaps->default_tmi = tmi;
+ tonemap_t *tm = NULL;
+ if (tmi == TONEMAP_INDEX_INITIAL_START
+ || tmi == TONEMAP_INDEX_INITIAL_ERROR
+ || tmi == TONEMAP_INDEX_INITIAL_SOUND_COMPLETE)
+ {
+ /* Use ROBO. */
+ tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ }
+ else if (tmi >= PHY_MOD_ROBO_NB)
+ {
+ if (tm_mod)
+ {
+ /* Create a tonemap. */
+ tm = tonemap_alloc ();
+ if (tx)
+ sta->tx_tonemaps->tm[tmi] = tm;
+ else
+ sta->rx_tonemaps->tm[tmi] = tm;
+ tm->cpf = true;
+ tm->fecrate = PHY_FEC_RATE_16_21;
+ tm->gil = PHY_GIL_417;
+ tm->bits_per_symbol = tm_mod * tp->config.tonemask_info.carrier_nb;
+ tonemap_update (tm, TONEMAP_P_PBERROR_DEFAULT_UF32);
+ /* Do not fill tonemap, unused. */
+ }
+ else
+ {
+ /* Reuse previously defined one. */
+ if (tx)
+ tm = sta->tx_tonemaps->tm[tmi];
+ else
+ tm = sta->rx_tonemaps->tm[tmi];
+ /* If no tonemap, use ROBO for SOUND frame. */
+ if (!tm)
+ tm = &tp->config.tonemask_info.tonemap_robo[PHY_MOD_ROBO];
+ }
+ }
+ else
+ {
+ /* Use a ROBO one. */
+ tm = &tp->config.tonemask_info.tonemap_robo[tmi];
+ }
+ sta->rx_tonemaps->sound_frame_counter = TONEMAP_SOUND_FRAME_COUNTER;
+ blk_release (sta);
+ if (dx)
+ *dx = tm->gil == PHY_GIL_417 ? MAC_DX417_TCK
+ : (tm->gil == PHY_GIL_567 ? MAC_DX567_TCK : MAC_DX3534_TCK);
+ return tm;
+}
+
+uint
+utils_sta_prepare_intervals (test_pbproc_t *tp, uint tei,
+ utils_interval_t *intervals,
+ uint default_tmi)
+{
+ uint intervals_version;
+ utils_interval_t *i;
+ dbg_assert (tp);
+ sta_t *sta = mac_store_sta_get (tp->store, tei);
+ dbg_assert (sta);
+ tonemaps_t *tms = sta->tx_tonemaps;
+ dbg_assert (tms->default_tmi < TONEMAP_INDEX_NB);
+ for (i = intervals; i->end_offset_tck; i++)
+ {
+ dbg_check (mac_interval_append (
+ tms, MAC_TCK_TO_ATU (i->end_offset_tck), i->tmi));
+ if (i->tm_mod && !tms->tm[i->tmi])
+ {
+ tonemap_t *tm = tonemap_alloc ();
+ tms->tm[i->tmi] = tm;
+ tm->cpf = true;
+ tm->fecrate = PHY_FEC_RATE_16_21;
+ tm->gil = PHY_GIL_417;
+ tm->bits_per_symbol =
+ i->tm_mod * tp->config.tonemask_info.carrier_nb;
+ tonemap_update (tm, TONEMAP_P_PBERROR_DEFAULT_UF32);
+ /* Do not fill tonemap, unused. */
+ }
+ }
+ mac_interval_commit_changes (tms);
+ tms->default_tmi = default_tmi;
+ intervals_version = tms->intervals->version;
+ blk_release (sta);
+ return intervals_version;
+}
+
+void
+utils_prepare_encryption (test_pbproc_t *tp, bool encrypted, bool sta_auth,
+ uint tei, uint nek_switch)
+{
+ dbg_assert (tp);
+ dbg_assert (nek_switch == 0 || nek_switch == 1 || nek_switch == 2);
+ if (encrypted)
+ {
+ tp->config.authenticated = true;
+ tp->config.nek[nek_switch].eks = nek_switch;
+ tp->config.nek[nek_switch].nek_enc[0] = 0x0123567;
+ tp->config.nek[nek_switch].nek_enc[1] = 0x1235678;
+ tp->config.nek[nek_switch].nek_enc[2] = 0x2356789;
+ tp->config.nek[nek_switch].nek_enc[3] = 0x356789a;
+ tp->config.nek[nek_switch].nek_dec[0] = 0x1235678;
+ tp->config.nek[nek_switch].nek_dec[1] = 0x2356789;
+ tp->config.nek[nek_switch].nek_dec[2] = 0x356789a;
+ tp->config.nek[nek_switch].nek_dec[3] = 0x56789ab;
+ tp->config.nek[!nek_switch].eks = MAC_EKS_CLEAR;
+ /* Setup allocation. */
+ tp->pbproc->alloc.nek_switch = nek_switch;
+ if (sta_auth)
+ {
+ sta_t *sta = mac_store_sta_get (tp->store, tei);
+ dbg_assert (sta);
+ sta->authenticated = true;
+ blk_release (sta);
+ }
+ }
+ else
+ {
+ tp->config.authenticated = false;
+ tp->config.nek[0].eks = MAC_EKS_CLEAR;
+ tp->config.nek[1].eks = MAC_EKS_CLEAR;
+ }
+}
+
diff --git a/cesar/mac/sar/Config b/cesar/mac/sar/Config
index 813e961413..bce2aef26d 100644
--- a/cesar/mac/sar/Config
+++ b/cesar/mac/sar/Config
@@ -1,3 +1,4 @@
CONFIG_SAR_DROP_OLD_SEG=y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = n
CONFIG_SAR_BRG_JOB_ERROR=n
-CONFIG_SAR_PBPOOL_SIZE=500
+CONFIG_SAR_PBPOOL_SIZE=1500
diff --git a/cesar/mac/sar/inc/sar.h b/cesar/mac/sar/inc/sar.h
index f877c85795..eb674b712a 100644
--- a/cesar/mac/sar/inc/sar.h
+++ b/cesar/mac/sar/inc/sar.h
@@ -19,12 +19,6 @@
#define SAR_MPDU_RX_REFILL 1
-/**
- * Allow the SAR to segment or reassembly Ethernet packets to an MFS which
- * contains less or equal PB than the define.
- * MAC_SAR_EM_MAX_PB_ALLOWED: MAC SAR Exhausted Memory MAX PB allowed. */
-#define MAC_SAR_EM_MAX_PB_ALLOWED 5
-
BEGIN_DECLS
/**
diff --git a/cesar/mac/sar/inc/sar_context.h b/cesar/mac/sar/inc/sar_context.h
index 4c0f8b6fd9..dc5aaacb42 100644
--- a/cesar/mac/sar/inc/sar_context.h
+++ b/cesar/mac/sar/inc/sar_context.h
@@ -111,10 +111,20 @@ struct sar_stats_t
/** Total number of PB with a CRC error received by ourself (from
* anyone). */
u32 rx_pb_crc_error_count;
+ /** Total number of PB rejected by SAR. */
+ u32 rx_pb_rejected;
+ /** Total number of PB discarded by SAR expiration in tx mfs-s. */
+ u32 tx_pb_expired;
+ /** Total number of PB discarded by SAR expiration in rx mfs-s. */
+ u32 rx_pb_expired;
/** BER sum of all PBs correct received from any station in the AVLN. */
u64 ber_sum;
/** Number of times the PBPool had not been filled. */
u32 pb_pool_not_filled;
+ /** Number of rx jobs */
+ u32 rx_jobs_count;
+ /** Number of rx jobs waiting for buffer/unfinished */
+ u32 rx_jobs_waiting_count;
};
typedef struct sar_stats_t sar_stats_t;
#endif
diff --git a/cesar/mac/sar/sar_mf.h b/cesar/mac/sar/sar_mf.h
index d837a35717..59a8bac325 100644
--- a/cesar/mac/sar/sar_mf.h
+++ b/cesar/mac/sar/sar_mf.h
@@ -65,6 +65,9 @@ BEGIN_DECLS
void
sar_mf_header (pb_t *pb, uint offset, sar_mf_t *sar_mf);
+sar_mf_type_t
+sar_mf_header_get_type (pb_t *pb, uint offset);
+
END_DECLS
#endif /*SAR_MF_H_*/
diff --git a/cesar/mac/sar/src/sar.c b/cesar/mac/sar/src/sar.c
index 7849e22ad1..ae405375f4 100644
--- a/cesar/mac/sar/src/sar.c
+++ b/cesar/mac/sar/src/sar.c
@@ -29,6 +29,7 @@
#include "hal/arch/arch.h"
#include "common/defs/priority.h"
#include "config/sar.h"
+#include "config/mac/sar.h"
#include "lib/stats.h"
#include <string.h>
@@ -155,13 +156,13 @@ sar_rx_mfs_cmd_apply__cmd_init (sar_t *ctx, mfs_rx_t *mfs)
* \param ctx the SAR context.
* \param params the RX Parameters.
*/
-void
+static inline void
sar_rx_mfs_cmd_apply (sar_t *ctx, pbproc_rx_params_t *params)
{
mfs_rx_t *mfs;
- dbg_assert (ctx);
- dbg_assert (params);
- dbg_assert (MAC_TEI_IS_STA(params->tei));
+ dbg_claim (ctx);
+ dbg_claim (params);
+ dbg_claim (MAC_TEI_IS_STA(params->tei));
if (params->mfs_cmd_data == MFS_FSM_CMD_INIT)
{
@@ -232,7 +233,8 @@ sar_rx_get_associated_mfs__from_mac_store (
dbg_assert (MAC_TEI_IS_STA(rx->params.tei));
/* If the MFS is not a lid one and it request a DATA MFS return NULL.
* The SAR is not allowed to create non PLID MFSs. */
- if (!mme && !MAC_LID_IS_PLID (rx->params.lid))
+ if (!mme && !MAC_LID_IS_PLID (rx->params.lid)
+ && !CONFIG_MAC_SAR_EOC_PERMANENT_MFS)
{
local_mfs = mac_store_mfs_get_rx (
ctx->mac_store, rx->params.bcast, false /* data requested. */,
@@ -246,6 +248,8 @@ sar_rx_get_associated_mfs__from_mac_store (
/* Configure the MFS created, only do this if the MFS has been created*/
if (added)
{
+ if (pb)
+ local_mfs->ssn_min = pb->header.ssn;
sar_mfs_add (ctx, PARENT_OF (mfs_t, rx, local_mfs));
/* Special behavior for bcast MFS, the ssn min should be set to
* the first PB on the MPDU. This allow the station to receive PBs
@@ -366,7 +370,7 @@ sar_rx_mfs_ssn_min_update (sar_t *ctx, mfs_rx_t *mfs)
uint pb_missing, pb_dropped = 0;
bool chain_unchanged;
bool bcast_restart = false;
- dbg_assert (mfs);
+ dbg_claim (mfs);
pb = mfs->head;
u16 ssn_min_last = mfs->ssn_min;
while (pb)
@@ -375,11 +379,11 @@ sar_rx_mfs_ssn_min_update (sar_t *ctx, mfs_rx_t *mfs)
/* PB's SSN is the MIN SSN. */
if (pb->header.ssn == mfs->ssn_min)
mfs->ssn_min ++;
- /* PB is the OPSF. */
else if (pb->header.opsf && CONFIG_SAR_DROP_OLD_SEG)
mfs->ssn_min = pb->header.ssn + 1;
/* PB's SSN is greater than the SSN MAX. */
- else if (less_mod2p16 (mfs->window_size + mfs->ssn_min - 1,
+ else if (less_mod2p16 (mfs->window_size + mfs->ssn_min - 1
+ + MFS_WINDOW_TOLERANCE,
pb->header.ssn))
{
if (mfs->common.bcast)
@@ -447,7 +451,10 @@ sar_stats_init (sar_stats_t *ctx)
/* Reset to 0. */
ctx->rx_pb_count = 0;
ctx->rx_pb_crc_error_count = 0;
+ ctx->rx_pb_rejected = 0;
ctx->ber_sum = 0;
+ ctx->tx_pb_expired = 0;
+ ctx->rx_pb_expired = 0;
ctx->pb_pool_not_filled = 0;
/* Register our statistics. */
lib_stats_set_stat_value_notype ("rx_pb_count", &ctx->rx_pb_count,
@@ -709,15 +716,23 @@ sar_mpdu_add (void *user, pbproc_rx_desc_t *rx_desc)
{
sar_t *ctx;
sar_mpdu_t *mpdu;
+ sta_t *sta = NULL;
dbg_assert (user);
dbg_assert (rx_desc);
dbg_assert (rx_desc->rx);
ctx = (sar_t *) user;
-
/* Do not lock DSR, this function is called only in DSR context. */
mpdu = PARENT_OF (sar_mpdu_t, rx, rx_desc->rx);
+ /* Collect agc_gain value for station */
+ if (MAC_TEI_IS_STA (mpdu->rx.params.tei))
+ sta = mac_store_sta_get (ctx->mac_store, mpdu->rx.params.tei);
+ if (sta)
+ {
+ sta->upstream_att = mpdu->rx.params.agc_gain;
+ blk_release (sta);
+ }
dbg_assert (!mpdu->rx.mfs || mpdu->rx.mfs->common.mme == false);
dbg_assert (!mpdu->rx.mfs_mme || mpdu->rx.mfs_mme->common.mme == true);
@@ -825,10 +840,10 @@ void
sar_msdu_add (sar_t *ctx, u8 *buffer, u16 length, mfs_tx_t *mfs,
void *user_data, u32 arrival_time_ntb)
{
- dbg_assert (ctx);
- dbg_assert (mfs);
- dbg_assert (mfs->common.tx);
- dbg_assert ((length >= ETH_PACKET_MIN_SIZE_ALLOWED)
+ dbg_claim (ctx);
+ dbg_claim (mfs);
+ dbg_claim (mfs->common.tx);
+ dbg_claim ((length >= ETH_PACKET_MIN_SIZE_ALLOWED)
&& (length <= ETH_PACKET_MAX_SIZE));
/* Link statistics. */
@@ -839,8 +854,7 @@ sar_msdu_add (sar_t *ctx, u8 *buffer, u16 length, mfs_tx_t *mfs,
lib_seq_check_packet (&ctx->seq, buffer, length);
/* Enough block available to send a frame and SAR is activated ? */
- if (ctx->activate
- && (blk_slack () || mfs->seg_nb <= MAC_SAR_EM_MAX_PB_ALLOWED))
+ if ((blk_slack () || mfs->common.mme) && ctx->activate)
{
if (mfs->fsm_state == MFS_FSM_CMD_RELEASE)
{
@@ -910,8 +924,6 @@ sar_bridge_dma_free_head_rx (sar_t *ctx, sar_job_mfs_t *job)
bool sta_auth, encrypted;
sar_reassembly_done_cb_t sar_rea_done;
void *ul_ctx;
- sta_t *sta;
-
dbg_assert (ctx);
dbg_assert (job);
@@ -971,9 +983,10 @@ sar_bridge_dma_free_head_rx (sar_t *ctx, sar_job_mfs_t *job)
job->job.data_len, job->mfs);
if (sta_auth
+ && !CONFIG_MAC_SAR_EOC_PERMANENT_MFS
&& ((mfs_rx_t *) job->mfs)->common.tei != MAC_TEI_UNASSOCIATED)
{
- sta = mac_store_sta_get (ctx->mac_store,
+ sta_t * sta = mac_store_sta_get (ctx->mac_store,
((mfs_rx_t *) job->mfs)->common.tei);
if (sta)
{
@@ -1029,7 +1042,10 @@ sar_bridge_dma_free_head_tx (sar_t *ctx, sar_job_mfs_t *job)
/* Release the PBs in the job. */
blk_release_desc_range_nb ((blk_t *) job->job.first_pb_desc, pb_quantity);
pbproc_mfs_provide (&job->mfs->tx, pb_quantity);
- if (job->mfs->tx.fsm_state != MFS_FSM_CMD_RELEASE)
+ if ((!CONFIG_MAC_SAR_EOC_PERMANENT_MFS
+ || !job->mfs->tx.cfp)
+ && job->mfs->tx.fsm_state != MFS_FSM_CMD_RELEASE
+ && job->mfs->tx.ca_state != CA_MFS_STATE_REMOVED)
ca_mfs_update (ctx->ca, &job->mfs->tx);
sar_tx_done (ctx, job->job.data_addr, &job->mfs->tx, job->user_data);
}
@@ -1108,7 +1124,10 @@ sar_bridge_dma_free_head (sar_t *ctx)
blk_release (job->mfs);
/* Release the JOB only for RX jobs. TX is static. */
if (job->job.direction)
+ {
blk_release (job);
+ ctx->stats.rx_jobs_waiting_count--;
+ }
}
}
@@ -1186,12 +1205,14 @@ sar_reassembly_run (sar_t *ctx, sar_mpdu_t *rx)
sar_rx_mpdu_process (ctx, rx);
if (rx->rx.mfs)
{
- sar_expiration_mfs_update_ntb (ctx, rx->rx.mfs, rx->arrival_ntb);
+ if (rx->rx.pb_first)
+ sar_expiration_mfs_update_ntb (ctx, rx->rx.mfs, rx->arrival_ntb);
sar_mac_frame_reconstitute (ctx, &rx->rx.mfs->rx, &ctx->data_ctx);
}
if (rx->rx.mfs_mme)
{
- sar_expiration_mfs_update_ntb (ctx, rx->rx.mfs_mme,
+ if (rx->rx.pb_first)
+ sar_expiration_mfs_update_ntb (ctx, rx->rx.mfs_mme,
rx->arrival_ntb);
sar_mac_frame_reconstitute (ctx, &rx->rx.mfs_mme->rx,
&ctx->mme_ctx);
@@ -1367,8 +1388,11 @@ sar_rx_mpdu_process (sar_t *ctx, sar_mpdu_t * rx)
/* Increase statistics. */
ctx->stats.rx_pb_count += rx->rx.pb_nb;
ctx->stats.rx_pb_crc_error_count += pb_crc_error;
+ ctx->stats.rx_pb_rejected += pb_data_dropped;
ctx->stats.ber_sum += ber_sum;
#endif
+ if (rx->rx.pb_nb == pb_data_dropped + pb_crc_error)
+ rx->rx.pb_first = NULL;
/* Link statistics. Only DATA are incremented. */
if (rx->rx.mfs)
sar_stats_mpdu_process (&rx->rx.params, &rx->rx.mfs->rx,
@@ -1386,15 +1410,15 @@ sar_rx_mpdu_process (sar_t *ctx, sar_mpdu_t * rx)
* \param offset the offset of the Mac Frame in the first PB.
* \param sar_mf the sar_mf structure to have more details on the Mac frame.
*/
-static void
+static inline void
sar_rx_job_desc_create (phy_bridgedma_job_t *job, mfs_rx_t *mfs,
pb_t *first_pb, u16 offset, sar_mf_t *sar_mf)
{
/* Verify that the data are not null */
- dbg_assert (job);
- dbg_assert (mfs);
- dbg_assert (first_pb);
- dbg_assert (sar_mf);
+ dbg_claim (job);
+ dbg_claim (mfs);
+ dbg_claim (first_pb);
+ dbg_claim (sar_mf);
job->first_pb_desc = (blk_t *) first_pb;
job->first_pb_offset = offset;
@@ -1501,33 +1525,36 @@ static inline bool
sar_rx_mfs_detect_and_reconstitute_mf__possible (sar_t *ctx, mfs_rx_t *mfs,
pb_t *pb, sar_mf_t *sar_mf)
{
- dbg_assert (ctx);
- dbg_assert (mfs);
- dbg_assert (pb);
- dbg_assert (sar_mf);
- dbg_assert (pb->header.mfbf);
- /* Get the Mac Frame header. */
- sar_mf_header (pb, pb->header.mfbo, sar_mf);
- /* Frame is present and the length is correct ? */
- if ((sar_mf->type != SAR_MF_TYPE_NONE)
- && sar_mf->header_complete
- && (sar_mf->length <= ETH_PACKET_MAX_SIZE)
- && (sar_mf->length >= ETH_PACKET_MIN_SIZE_ALLOWED))
+ dbg_claim (ctx);
+ dbg_claim (mfs);
+ dbg_claim (pb);
+ dbg_claim (sar_mf);
+
+ /* Does a MF exists in the PB? and there are free blocks */
+ if (pb->header.mfbf)
{
- /* Check the MF Type with the MFS type. */
- if ((sar_mf->type == SAR_MF_TYPE_MME)
- && (mfs->common.mme == true))
- return true;
- else
+ /* Get the Mac Frame header. */
+ sar_mf_header (pb, pb->header.mfbo, sar_mf);
+
+ /* Frame is present and the length is correct ? */
+ if ((sar_mf->type != SAR_MF_TYPE_NONE)
+ && sar_mf->header_complete
+ && (sar_mf->length <= ETH_PACKET_MAX_SIZE)
+ && (sar_mf->length >= ETH_PACKET_MIN_SIZE_ALLOWED))
{
+ /* Check the MF Type with the MFS type. */
if ((sar_mf->type == SAR_MF_TYPE_DATA)
&& (mfs->common.ats == false))
return true;
+ else if ((sar_mf->type == SAR_MF_TYPE_MME)
+ && (mfs->common.mme == true))
+ return true;
else if ((sar_mf->type == SAR_MF_TYPE_DATA_ATS)
- && (mfs->common.ats == true))
+ && (mfs->common.ats == true))
return true;
}
}
+
return false;
}
@@ -1540,7 +1567,7 @@ sar_rx_mfs_detect_and_reconstitute_mf__possible (sar_t *ctx, mfs_rx_t *mfs,
*
* A MAC Frame is present in the PBs from the MFS's head to pb_mf_ends, the
* function will use the informations read from the MFS's head PB to create a
- * job for the Bridge DMA and provide the PBs containing the MAC Frame to
+ * job for the Bridge DMA and provide the PBs contining the MAC Frame to
* reconstitute.
*/
inline sar_job_mfs_t *
@@ -1549,9 +1576,9 @@ sar_rx_mfs_detect_and_reconstitute_mf__create_job (sar_t *ctx, mfs_rx_t *mfs,
pb_t *pb_mf_ends)
{
sar_job_mfs_t *job;
- dbg_assert (ctx);
- dbg_assert (mfs);
- dbg_assert (sar_mf);
+ dbg_claim (ctx);
+ dbg_claim (mfs);
+ dbg_claim (sar_mf);
dbg_assert (pb_mf_ends);
job = sar_job_mfs_create_rx ();
job->mfs = (mfs_t *) mfs;
@@ -1561,6 +1588,10 @@ sar_rx_mfs_detect_and_reconstitute_mf__create_job (sar_t *ctx, mfs_rx_t *mfs,
sar_rx_job_desc_create (&job->job, mfs, mfs->head,
mfs->head->header.mfbo,
sar_mf);
+
+ ctx->stats.rx_jobs_count++;
+ ctx->stats.rx_jobs_waiting_count++;
+
uint icv_pos_end = sar_mf->length_complete + offset;
/* Workaround for bridgedma bug see maria:#905 */
if (sar_mf->length > SAR_BRGBUG_SECOND_JOB_LENGTH
@@ -1586,14 +1617,38 @@ sar_rx_mfs_detect_and_reconstitute_mf__create_job (sar_t *ctx, mfs_rx_t *mfs,
#if CONFIG_SAR_BRG_JOB_ERROR
job->job.mf_header1 = 0xdeaddead;
#endif
- /* Add a reference on the last PB without trying to check if another mac
- * Frame is present, the parent will do it in the next loop. */
- blk_addref_desc (&pb_mf_ends->blk);
+
+ /* If the pb_mf_ends does not have a MAC Frame start, MFS's head should
+ * point to the next PB. */
+ if (!pb_mf_ends->header.mfbf)
+ mfs->head = pb_mf_ends->next;
+ else
+ {
+ sar_mf_type_t type =
+ sar_mf_header_get_type (pb_mf_ends, pb_mf_ends->header.mfbo);
+ if (type != SAR_MF_TYPE_NONE)
+ {
+ mfs->head = pb_mf_ends;
+ blk_addref_desc ((blk_t *) pb_mf_ends);
+ }
+ else
+ mfs->head = pb_mf_ends->next;
+ }
blk_addref ((blk_t *) mfs);
- mfs->head = pb_mf_ends;
+
return job;
}
+static inline bool
+sar_rx_mfs_enough_data (pb_t * head, u16 ssn_min)
+{
+ if ((u16)(head->header.ssn + 1) != ssn_min)
+ return true;
+ if (head->header.mfbo < BLK_SIZE - SAR_MF_LENGTH)
+ return true;
+ return false;
+}
+
/**
* Try to find a MF in the chained PBs in the MFS.
* \param mfs the MFS to use.
@@ -1610,10 +1665,11 @@ sar_rx_mfs_detect_and_reconstitute_mf (sar_t *ctx, mfs_rx_t *mfs)
dbg_assert (mfs);
/* Try to reassembly Frames. */
while (mfs->head
+ && sar_rx_mfs_enough_data (mfs->head, mfs->ssn_min)
&& lesseq_mod2p16 (mfs->head->header.ssn, mfs->ssn_min))
{
- if (mfs->head->header.mfbf
- && sar_rx_mfs_detect_and_reconstitute_mf__possible (
+ /* Verify type. */
+ if (sar_rx_mfs_detect_and_reconstitute_mf__possible (
ctx, mfs, mfs->head, &sar_mf))
{
pb_t *pb_mf_ends;
@@ -1630,7 +1686,7 @@ sar_rx_mfs_detect_and_reconstitute_mf (sar_t *ctx, mfs_rx_t *mfs)
if (qte == 0)
{
/* Enough memory ? */
- if (blk_slack ())
+ if (blk_slack () || mfs->common.mme)
{
job = sar_rx_mfs_detect_and_reconstitute_mf__create_job (
ctx, mfs, &sar_mf, pb_mf_ends);
@@ -1638,7 +1694,6 @@ sar_rx_mfs_detect_and_reconstitute_mf (sar_t *ctx, mfs_rx_t *mfs)
}
else
{
- /* Not enough memory available, drop the frame. */
SAR_TRACE (EXHAUSTED_MEMORY, mfs->head->header.ssn,
pb_mf_ends->header.ssn);
/* The whole mac frame is present in this PB, in the mean
@@ -1657,7 +1712,7 @@ sar_rx_mfs_detect_and_reconstitute_mf (sar_t *ctx, mfs_rx_t *mfs)
}
/* The segments are not contiguous and the missing PBs are outside
* the window. */
- else if (less_mod2p16 (pb_mf_ends->header.ssn + 1, mfs->ssn_min))
+ if (less_mod2p16 (pb_mf_ends->header.ssn + 1, mfs->ssn_min))
{
/* Next PB is outside the window. */
if (mfs->head == pb_mf_ends)
@@ -1679,19 +1734,10 @@ sar_rx_mfs_detect_and_reconstitute_mf (sar_t *ctx, mfs_rx_t *mfs)
/* Stop the loop. */
break;
}
- /* PB have got a MF boundary and the data read in the PB is
- * incomplete and the next PB is after the SSN min i.e. it can be
- * receive. */
- else if (mfs->head->header.mfbf
- && !sar_mf.header_complete
- && lesseq_mod2p16 (mfs->ssn_min, mfs->head->header.ssn + 1))
- {
- job = NULL;
- break;
- }
- /* Impossible to reassembly the Mac Frame. */
+ /* Impossible to reassembly the Mac Frame i.e. the PB is corrupt. */
else
{
+ /* Next PB is outside the window. */
SAR_TRACE (PB_EMPTY, mfs->head->header.ssn,
mfs->head->header.mfbo);
pb_missing += sar_stats_rx_gap_between_pb_ssn_min (
@@ -1707,8 +1753,8 @@ void
sar_rx_mfs_process (sar_t *ctx, mfs_rx_t * mfs, sar_reassembly_ctx_t *rea_ctx)
{
sar_job_mfs_t *job;
- dbg_assert (mfs);
- dbg_assert (rea_ctx);
+ dbg_claim (mfs);
+ dbg_claim (rea_ctx);
while ((job = sar_rx_mfs_detect_and_reconstitute_mf (ctx, mfs)))
{
@@ -2000,6 +2046,7 @@ sar_beacon_add (void *sar, pb_beacon_t *pb,
dbg_assert (((sar_t *)sar)->beacon_user_data);
ctx = (sar_t *) sar;
+
sar_pb_pool_refill (ctx, 1);
(*ctx->beacon_function_cb) (ctx->beacon_user_data, pb, params);
}
@@ -2137,7 +2184,11 @@ sar_mfs_free_tx (sar_t *ctx, mfs_tx_t *mfs)
dbg_assert (mfs);
dbg_assert (mfs->fsm_state == MFS_FSM_CMD_RELEASE);
SAR_TRACE (MFS_TX_FREE, phy_date (), mfs);
+#if CONFIG_MAC_SAR_EOC_PERMANENT_MFS
+ pbproc_mfs_remove_all (mfs);
+#else
dbg_assert (mfs->head == NULL);
+#endif
mac_store_mfs_remove (ctx->mac_store, PARENT_OF (mfs_t, tx, mfs));
}
diff --git a/cesar/mac/sar/src/sar_expiration.c b/cesar/mac/sar/src/sar_expiration.c
index d6cc611f66..840b413001 100644
--- a/cesar/mac/sar/src/sar_expiration.c
+++ b/cesar/mac/sar/src/sar_expiration.c
@@ -18,6 +18,7 @@
#include "mac/sar/inc/trace.h"
#include "mac/common/ntb.h"
#include "mac/common/mfs.h"
+#include "config/mac/sar/eoc.h"
/**
* Verify if the MFS had expired.
@@ -58,7 +59,10 @@ sar_expiration_mfs_purge_tx (sar_t *ctx, mfs_tx_t *mfs, u32 phy_curr_ntb)
old_first_ssn = mfs->head->header.ssn;
/* Call the PBprocessing to expire the PBs (only on MFS tx). */
mfs_empty = pbproc_mfs_expire (ctx->pbproc_ctx, (mfs_tx_t *) mfs,
- phy_curr_ntb, &expired_nb);
+ phy_curr_ntb, &expired_nb);
+ /* Increment stats. */
+ mfs->stats.num_segs_dropped += expired_nb;
+ ctx->stats.tx_pb_expired += expired_nb;
if (expired_nb)
{
SAR_TRACE (PB_TX_RELEASE, old_first_ssn,
@@ -70,7 +74,11 @@ sar_expiration_mfs_purge_tx (sar_t *ctx, mfs_tx_t *mfs, u32 phy_curr_ntb)
&& sar_expiration_mfs_expired (mfs, phy_curr_ntb)
&& !mfs->common.bcast)
{
- sar_mfs_remove (ctx, PARENT_OF (mfs_t, tx, mfs));
+ if(!CONFIG_MAC_SAR_EOC_PERMANENT_MFS || !mfs->cfp)
+ sar_mfs_remove (ctx, PARENT_OF (mfs_t, tx, mfs));
+ else
+ mfs->common.expiration_ntb = phy_curr_ntb +
+ MAC_MS_TO_TCK(MFS_ACTIVITY_DELAY_MS);
SAR_TRACE (MFS_RELEASE, phy_curr_ntb, mfs);
}
}
@@ -81,12 +89,18 @@ sar_expiration_mfs_purge_rx (sar_t *ctx, mfs_rx_t *mfs, u32 ntb)
bool mfs_empty = false;
dbg_assert (ctx);
dbg_assert (mfs);
+ u16 ssn_min=0, expired_nb = 0;
+ bool purged = false;
/* Expire all the PBs with the cache date lesser than the actual date. */
while (mfs->head && sar_expiration_mfs_head_expired (mfs, ntb))
{
SAR_TRACE (PB_RX_RELEASE, mfs->head->header.ssn, mfs);
+ ssn_min = mfs->head->header.ssn;
+ purged = true;
+ expired_nb++;
mfs->head = sar_pb_release (mfs->head);
}
+ ctx->stats.rx_pb_expired += expired_nb;
if (mfs->head == NULL)
mfs_empty = true;
/* If the whole MFS has expired i.e. it does not have PB's. */
diff --git a/cesar/mac/sar/src/sar_mf.c b/cesar/mac/sar/src/sar_mf.c
index a5bc9a0c4b..46379785ca 100644
--- a/cesar/mac/sar/src/sar_mf.c
+++ b/cesar/mac/sar/src/sar_mf.c
@@ -15,6 +15,7 @@
#include "common/std.h"
#include "mac/sar/sar_mf.h"
#include "hal/arch/arch.h"
+#include "lib/read_word.h"
/**
* Align address.
@@ -42,7 +43,6 @@ sar_mf_header__fill (sar_mf_t *sar_mf, u32 data, pb_t *pb, u16 offset)
{
dbg_assert (sar_mf);
dbg_assert (pb);
-
/* Compute the missing data. */
sar_mf->type = data & 0x3;
if (sar_mf->type != SAR_MF_TYPE_NONE)
@@ -127,10 +127,28 @@ sar_mf_header (pb_t *pb, uint offset, sar_mf_t *sar_mf)
dbg_assert (pb);
dbg_assert (sar_mf);
dbg_assert (offset < BLK_SIZE);
-
available_bytes = BLK_SIZE - offset;
if (available_bytes >= SAR_MF_MFH_SIZE)
sar_mf_header__all_in_pb (pb, offset, sar_mf);
else
sar_mf_header__in_two_pbs (pb, offset, sar_mf);
}
+
+sar_mf_type_t
+sar_mf_header_get_type (pb_t *pb, uint offset)
+{
+ dbg_assert (pb);
+ dbg_assert (offset < BLK_SIZE);
+ if (offset < BLK_SIZE)
+ {
+#ifdef __sparc__
+ u8* old = pb->data + offset;
+ arch_load_cache ((u32 *) (((uint) old) & ~3), sizeof(u32));
+#endif
+ u64 data = read_u8_from_word (pb->data + offset);
+
+ return data & 0x03;
+ }
+
+ return SAR_MF_TYPE_NONE;
+}
diff --git a/cesar/mac/sar/src/trace.c b/cesar/mac/sar/src/trace.c
index ea2b4aad26..a951e34075 100644
--- a/cesar/mac/sar/src/trace.c
+++ b/cesar/mac/sar/src/trace.c
@@ -35,8 +35,8 @@ sar_trace_init (sar_t *ctx)
TRACE_EVENT (SAR_TRACE_BRIDGE_TX,
"BRG TX SSN: %d, offset: %d, data length: %d, mfs: %x"),
TRACE_EVENT (SAR_TRACE_BRIDGE_RX,
- "BRG RX SSN: %d, offset: %d, data length: %d, mfs: %x"),
- TRACE_EVENT (SAR_TRACE_MFS_CMD, "MFS cmd mfs: %x, command nb: %d"),
+ "BRG TX SSN: %d, offset: %d, data length: %d, mfs: %x"),
+ TRACE_EVENT (SAR_TRACE_MFS_CMD, "MFS cmd mfs: %x, command nb: %d"),
TRACE_EVENT (SAR_TRACE_PB_ERROR, "PB error, ssn: %d"),
TRACE_EVENT (SAR_TRACE_MF_PB_OUTSIDE_WIN, "MF in PBs outside the window, ssn min %d size :%d PB ssn %d offset %d"),
TRACE_EVENT (SAR_TRACE_PB_EMPTY, "No new MF in PB ssn %d at offset %d"),
@@ -56,7 +56,7 @@ sar_trace_init (sar_t *ctx)
};
dbg_assert (ctx);
trace_namespace_init (&namespace, event_ids, COUNT (event_ids));
- trace_buffer_add (&ctx->trace, "sar", 8, 4, true, &namespace);
+ trace_buffer_add (&ctx->trace, "sar", 8, 64, true, &namespace);
}
void
diff --git a/cesar/mac/sar/stub/src/sar.c b/cesar/mac/sar/stub/src/sar.c
index 012ee19283..e0738bc075 100644
--- a/cesar/mac/sar/stub/src/sar.c
+++ b/cesar/mac/sar/stub/src/sar.c
@@ -94,6 +94,9 @@ void sar_mfs_add (sar_t *ctx, mfs_t *mfs) __attribute__((weak));
void
sar_cleanup (sar_t *ctx) __attribute__((weak));
+void
+sar_activate (sar_t *ctx, bool activate) __attribute__((weak));
+
sar_t *
sar_init (mac_store_t *mac_store, pbproc_t *pbproc, ca_t *ca, u32 seed)
{
@@ -173,3 +176,18 @@ void
sar_cleanup (sar_t *ctx)
{
}
+
+void
+sar_activate (sar_t *ctx, bool activate)
+{
+}
+
+uint sar_num_rx_jobs ( void)
+{
+ return 0;
+}
+
+uint sar_num_jobs ( void)
+{
+ return 0;
+}
diff --git a/cesar/mac/sar/test/functional/host-Config b/cesar/mac/sar/test/functional/host-Config
new file mode 100644
index 0000000000..63d7710058
--- /dev/null
+++ b/cesar/mac/sar/test/functional/host-Config
@@ -0,0 +1,3 @@
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+
diff --git a/cesar/mac/sar/test/functional/sparc-Config b/cesar/mac/sar/test/functional/sparc-Config
new file mode 100644
index 0000000000..63d7710058
--- /dev/null
+++ b/cesar/mac/sar/test/functional/sparc-Config
@@ -0,0 +1,3 @@
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c b/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c
index c5ad09052d..ffe327ddae 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c
@@ -91,7 +91,6 @@ test_case_sar_detect_mf (test_t test)
test_fail_unless (job->pb_quantity == 3);
/* Remove the add ref done by sar_rx_mfs_detect_and_reconstitute_mf. */
- blk_release_desc (&mfs->head->blk);
blk_release (mfs);
/* Remove the references from this test. */
@@ -273,8 +272,6 @@ test_case_sar_detect_mf_all_pb_offset (test_t test)
/* Release the references. */
if (job->job.next)
blk_release (job->job.next);
- if (mfs->head)
- blk_release_desc (&mfs->head->blk);
blk_release (job);
blk_release (mfs);
}
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/misc.c b/cesar/mac/sar/test/unit_test/ecos/src/misc.c
index ce8429fdcb..ede5971c9d 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/misc.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/misc.c
@@ -125,9 +125,6 @@ test_case_misc__add_pending_jobs_add_one_rx (sar_test_t *t, bool data)
slist_push_back (t->sar->data_ctx.jobs_pending_list., job, bare);
else
slist_push_back (t->sar->mme_ctx.jobs_pending_list., job, bare);
- /* Release the reference on the last PB which is duplicated. */
- blk_release_desc (&mfs->head->blk);
- mfs->head = NULL;
blk_release (mfs);
}
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/msdu_timeout.c b/cesar/mac/sar/test/unit_test/ecos/src/msdu_timeout.c
new file mode 100644
index 0000000000..cdc2aec3b5
--- /dev/null
+++ b/cesar/mac/sar/test/unit_test/ecos/src/msdu_timeout.c
@@ -0,0 +1,82 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file mac/sar/test/unit_test/ecos/src/msdu-timeout.c
+ * \brief Test the msdu expiration.
+ * \ingroup mac_sar
+ *
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "mac/sar/sar.h"
+#include "mac/common/ntb.h"
+
+#include "mac/sar/inc/sar_context.h"
+
+bool sar_tx_msdu_expiration (sar_t *ctx, sar_msdu_t * msdu);
+
+void
+test_case__sar_msdu_expiration (test_t test)
+{
+ uint sar;
+ mac_config_t mac_config;
+ sar_msdu_t msdu;
+ mfs_tx_t mfs;
+
+ test_case_begin (test, "MSDU expiration");
+ mac_config.ntb_offset_tck = 0;
+ mac_ntb_init (&mac_config);
+
+ test_begin (test, "MME Expiration")
+ {
+ msdu.mfs = &mfs;
+ msdu.mfs->common.ats = true;
+ msdu.ats_confounder = 0;
+ msdu.arrival_ntb = 0;
+ msdu.mfs->common.mme = true;
+ test_fail_if (sar_tx_msdu_expiration ((sar_t*) &sar, &msdu) != true);
+ }
+ test_end;
+
+ test_begin (test, "Data Expiration")
+ {
+ msdu.mfs = &mfs;
+ msdu.mfs->common.ats = true;
+ msdu.ats_confounder = 0;
+ msdu.arrival_ntb = 0;
+ msdu.mfs->common.mme = false;
+ test_fail_if (sar_tx_msdu_expiration ((sar_t*) &sar, &msdu) != true);
+ }
+ test_end;
+
+ test_begin (test, "No Expiration")
+ {
+ msdu.mfs = &mfs;
+ msdu.mfs->common.ats = true;
+ msdu.ats_confounder = 0;
+ msdu.arrival_ntb = 0;
+ msdu.mfs->common.mme = false;
+ test_fail_if (sar_tx_msdu_expiration ((sar_t*) &sar, &msdu) != false);
+ }
+ test_end;
+}
+
+void
+test_suite_msdu_expiration (test_t test)
+{
+ test_suite_begin (test, "MSDU expiration");
+ test_case__sar_msdu_expiration (test);
+
+ test_begin (test, "Memory")
+ {
+ test_fail_if (blk_check_memory() == false, "Memory not freed");
+ }
+ test_end;
+
+}
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c b/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c
index a98b05c82a..2beac67a1e 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/reassembly.c
@@ -1127,6 +1127,7 @@ test_case_reassembly_exhausted_memory (test_t test)
sar_test_t t;
sar_mpdu_t mpdu;
sar_test_init (&t, INVALID_PTR, INVALID_PTR);
+ memset (&mpdu, 0, sizeof (sar_mpdu_t));
/* Change free blocks to realize the test. */
head = blk_alloc_desc_range (CONFIG_BLK_NB - CONFIG_BLK_SLACK, &tail);
test_fail_unless (blk_slack () == false);
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/segmentation.c b/cesar/mac/sar/test/unit_test/ecos/src/segmentation.c
index 3cfa678fb2..3349e64463 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/segmentation.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/segmentation.c
@@ -19,9 +19,6 @@
#include "mac/sar/sar.h"
#include "mac/sar/inc/sar_context.h"
-#include "mac/sar/inc/sar.h"
-#include <string.h>
-#include "config.h"
/* Override context. */
#include "mac/pbproc/inc/context.h"
@@ -259,51 +256,6 @@ test_case_segmentation_mfs_release (test_t test)
}
void
-test_case_segmentation_em_max_pb_allowed_test (test_t test, sar_test_t ctx,
- mfs_tx_t *mfs)
-{
- u8 buffer[ETH_PACKET_MIN_SIZE_ALLOWED];
- memset (buffer, 0xff, ETH_PACKET_MIN_SIZE_ALLOWED);
- test_within (test);
- sar_msdu_add (ctx.sar, buffer, ETH_PACKET_MIN_SIZE_ALLOWED, mfs,
- NULL, 0x0);
- sar_bridge_dma_free_head (ctx.sar);
- test_fail_unless (mfs->seg_nb == MAC_SAR_EM_MAX_PB_ALLOWED + 1);
-}
-
-void
-test_case_segmentation_em_max_pb_allowed (test_t test)
-{
- sar_test_t ctx;
- bool added;
- test_case_begin (test, "Test MAC_SAR_EM_MAX_PB_ALLOWED");
- sar_test_init (&ctx, INVALID_PTR, INVALID_PTR);
- mfs_tx_t *mfs = mac_store_mfs_add_tx (ctx.mac_store, false, false, 1,
- 1, &added);
- blk_t *head, *tail;
- /* Allocate all available memory less some block under the slack value. */
- head = blk_alloc_desc_range (CONFIG_BLK_NB - CONFIG_BLK_SLACK + 2, &tail);
- sar_activate (ctx.sar, true);
- test_begin (test, "TX > MAC_SAR_EM_MAX_PB_ALLOWED")
- {
- mfs->seg_nb = MAC_SAR_EM_MAX_PB_ALLOWED + 1;
- test_case_segmentation_em_max_pb_allowed_test (test, ctx, mfs);
- }
- test_end;
- test_begin (test, "TX <= MAC_SAR_EM_MAX_PB_ALLOWED")
- {
- mfs->seg_nb = MAC_SAR_EM_MAX_PB_ALLOWED;
- test_case_segmentation_em_max_pb_allowed_test (test, ctx, mfs);
- }
- test_end;
- blk_release_desc_range (head, tail);
- sar_mfs_remove (ctx.sar, PARENT_OF (mfs_t, tx, mfs));
- blk_release (mfs);
- sar_sta_remove (ctx.sar, 1);
- sar_test_uninit (&ctx);
-}
-
-void
test_suite_segmentation (test_t test)
{
test_suite_begin (test, "Segmentation");
@@ -311,7 +263,6 @@ test_suite_segmentation (test_t test)
test_case_segmentation_message_too_short (test);
test_case_segmentation (test);
test_case_segmentation_mfs_release (test);
- test_case_segmentation_em_max_pb_allowed (test);
test_begin (test, "Memory")
{
diff --git a/cesar/mac/sar/test/unit_test/host/Makefile b/cesar/mac/sar/test/unit_test/host/Makefile
index 1eed775f22..9f65edd69a 100644
--- a/cesar/mac/sar/test/unit_test/host/Makefile
+++ b/cesar/mac/sar/test/unit_test/host/Makefile
@@ -4,6 +4,7 @@ HOST_PROGRAMS = lib_sar_mf
lib_sar_mf_SOURCES = lib_sar_mf.c phy_stub.c
lib_sar_mf_MODULES = lib mac/sar
+lib_sar_mf_CONFIG_MODULES = mac/common
mac_sar_MODULE_SOURCES = sar_mf.c
diff --git a/cesar/maximus/common/types/phy_types.h b/cesar/maximus/common/types/phy_types.h
index 497d549c4e..42debfbb95 100644
--- a/cesar/maximus/common/types/phy_types.h
+++ b/cesar/maximus/common/types/phy_types.h
@@ -101,11 +101,11 @@ enum Phy_Mpdu_Format
{
PHY_MPDU_FORMAT_NONE = 0x00,
PHY_MPDU_FORMAT_BEACON = 0x01, // Beacon => Long MPDU
- PHY_MPDU_FORMAT_SOF = 0x02, // Start Of Frame => Long MPDU
+ PHY_MPDU_FORMAT_SOF = 0x02, // Start Of Frame => Long MPDU (can be Short MPDU in case of EoC)
PHY_MPDU_FORMAT_SACK = 0x03, // Selective ACKnowledgement => Short MPDU (i.e. there is no payload)
PHY_MPDU_FORMAT_RTS_CTS = 0x04, // Request To Send / Clear To Send => Short MPDU (i.e. there is no payload)
PHY_MPDU_FORMAT_SOUND = 0x05, // Sound => Long MPDU
- PHY_MPDU_FORMAT_RSOF = 0x06, // Reverse Start Of Frame => Long MPDU
+ PHY_MPDU_FORMAT_RSOF = 0x06, // Reverse Start Of Frame => Long MPDU (can be Short MPDU in case of EoC)
PHY_MPDU_FORMAT_NB
};
diff --git a/cesar/maximus/common/types/sci_types.h b/cesar/maximus/common/types/sci_types.h
index cfdf8f4065..875c81b2bd 100644
--- a/cesar/maximus/common/types/sci_types.h
+++ b/cesar/maximus/common/types/sci_types.h
@@ -37,7 +37,7 @@ The original location of this file is /home/buret/eclipse/maximus/common/types/s
#define SCI_MSG_VERSION 0x02
#define SCI_MSG_ID_STATION 0x8000
#define SCI_MSG_ID_MASK 0x7fff
-#define SCI_MSG_MAX_SIZE 16384
+#define SCI_MSG_MAX_SIZE 4*16384
// Used by SciServer
//
diff --git a/cesar/maximus/phy/src/PhySciMsg.cpp b/cesar/maximus/phy/src/PhySciMsg.cpp
index 0b8bae74b1..da2012abac 100644
--- a/cesar/maximus/phy/src/PhySciMsg.cpp
+++ b/cesar/maximus/phy/src/PhySciMsg.cpp
@@ -253,10 +253,13 @@ bool PhySciMsg::checkValidity ( ) const
{
if (
(
+ (PHY_MPDU_FORMAT_SOF == getSpecializedSciMsgHeader().mpdu_format)
+ || (PHY_MPDU_FORMAT_RSOF == getSpecializedSciMsgHeader().mpdu_format)
+ )
+ ||
+ (
((PHY_MPDU_FORMAT_BEACON == getSpecializedSciMsgHeader().mpdu_format)
- || (PHY_MPDU_FORMAT_SOF == getSpecializedSciMsgHeader().mpdu_format)
- || (PHY_MPDU_FORMAT_SOUND == getSpecializedSciMsgHeader().mpdu_format)
- || (PHY_MPDU_FORMAT_RSOF == getSpecializedSciMsgHeader().mpdu_format))
+ || (PHY_MPDU_FORMAT_SOUND == getSpecializedSciMsgHeader().mpdu_format))
&& (0 != getSpecializedSciMsgHeader().pb_nb)
)
||
diff --git a/cesar/maximus/python/maximus/station/sta.py b/cesar/maximus/python/maximus/station/sta.py
index 167c9d4a11..0dd9a89d07 100644
--- a/cesar/maximus/python/maximus/station/sta.py
+++ b/cesar/maximus/python/maximus/station/sta.py
@@ -175,6 +175,11 @@ class STA:
rsp = mme.sendnrecv(maximus=self.__get_maximus(), station=self.get(), filter=mme_filter)
self.__check_cnf(rsp, DRV_STA_START)
+ def start(self):
+ """Send the MAC_START message to the station.
+ """
+ self.__start()
+
def stop(self):
"""Send the MAC_STOP message to the station.
"""
diff --git a/cesar/projects/eoc/Makefile b/cesar/projects/eoc/Makefile
new file mode 100644
index 0000000000..eeafd39fbc
--- /dev/null
+++ b/cesar/projects/eoc/Makefile
@@ -0,0 +1,16 @@
+all: master slave
+
+clean: master-clean slave-clean
+
+master: master-Makefile master-ecos.ecc.sh
+ make -f master-Makefile
+master-clean: master-Makefile
+ make -f master-Makefile clean
+
+slave: slave-Makefile slave-ecos.ecc.sh
+ make -f slave-Makefile
+slave-clean: slave-Makefile
+ make -f slave-Makefile clean
+
+distclean:
+ rm -rf obj
diff --git a/cesar/projects/eoc/master-Config b/cesar/projects/eoc/master-Config
new file mode 100644
index 0000000000..32c88d0197
--- /dev/null
+++ b/cesar/projects/eoc/master-Config
@@ -0,0 +1,48 @@
+CONFIG_TRACE_ON_FATAL = y
+CONFIG_TRACE = n
+CONFIG_DEBUG_CLAIM = n
+CONFIG_BLK_NB = 6344
+CONFIG_BLK_SLACK = 512
+CONFIG_SAR_PBPOOL_SIZE = 512
+CONFIG_MAC_PBPROC_EOC_EXHAUST_THRESHOLD = 100
+CONFIG_STATS_ON_FATAL = y
+
+CONFIG_GPIO_LED_TRAFFIC = y
+CONFIG_GPIO_LED_IS_CCO = y
+CONFIG_GPIO_LED_PBPROC_ALIVE = n
+CONFIG_GPIO_LED_PBPROC_ALIVE_GPIO = 0
+
+CONFIG_GPIO_LED_PBPROC_WORKING = n
+CONFIG_GPIO_LED_PBPROC_WORKING_GPIO = 0
+
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_STA_MGR_CCO_EOC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CL_DATA_RATE = n
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_SAR_DROP_OLD_SEG = y
+CONFIG_CP_EOC_CCO_WL_ALLOWED = y
+CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED = y
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 1
+CONFIG_BSU_ACLF_EOC = y
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_AV_ONLY_MODE = y
+CONFIG_CP_EOC_CCO_CON_ALLOWED = y
+
diff --git a/cesar/projects/eoc/master-Makefile b/cesar/projects/eoc/master-Makefile
new file mode 100644
index 0000000000..184762fbdf
--- /dev/null
+++ b/cesar/projects/eoc/master-Makefile
@@ -0,0 +1,25 @@
+BASE = ../..
+ECOS = y
+TARGET = sparc
+VARIANT = master
+TARGET_OPTIMIZE = -Os
+
+TARGET_PROGRAMS = master
+
+master_SOURCES = eoc.c
+master_MODULES = lib mac cl hle bsu interface hal station host ce hle/tools\
+ cp/beacon cp/cco/bw cp/cco/region cp/cl_interf \
+ cp/fsm cp/msg cp/secu cp/sta/core \
+ cp/sta/mgr cp cp/sta/action \
+ cp/eoc/cco/bw cp/eoc/sta/mgr \
+ cp/eoc/cco/action cp/eoc/multi_sta/action \
+ cp/eoc/multi_sta_fsm cp/eoc/sta/action
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_sta_action_MODULE_SOURCES = bridge.c vs.c misc.c
+cp_eoc_sta_action_MODULE_SOURCES = action.c cco_stub.c drv.c poweron.c vs_eoc.c
+cp_MODULE_MODULES =
+
+include $(BASE)/common/make/top.mk
+
+$(call src2obj,src/region_stub.c,target): $(BASE)/cp/fsm/fsm.h
diff --git a/cesar/projects/eoc/master-ecos.ecc.sh b/cesar/projects/eoc/master-ecos.ecc.sh
new file mode 100644
index 0000000000..db2208c6cc
--- /dev/null
+++ b/cesar/projects/eoc/master-ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new sparc_leon default
+cat >> $config <<'EOF'
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/projects/eoc/slave-Config b/cesar/projects/eoc/slave-Config
new file mode 100644
index 0000000000..0608bfaf7e
--- /dev/null
+++ b/cesar/projects/eoc/slave-Config
@@ -0,0 +1,35 @@
+CONFIG_TRACE_ON_FATAL = y
+CONFIG_TRACE = n
+CONFIG_DEBUG_CLAIM = n
+CONFIG_BLK_NB = 6144
+CONFIG_BLK_SLACK = 1280
+CONFIG_SAR_PBPOOL_SIZE = 768
+CONFIG_STATS_ON_FATAL = y
+
+CONFIG_GPIO_LED_TRAFFIC = y
+CONFIG_GPIO_LED_IS_CCO = y
+
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_sta.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CL_DATA_RATE = n
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 1
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_BSU_ACLF_EOC = y
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_AV_ONLY_MODE = y
+CONFIG_CP_EOC_STA_CON_ALLOWED = y
+CONFIG_BEACON_SPOC_UPDATE_INTERVAL_DEFAULT_MS = 1000
diff --git a/cesar/projects/eoc/slave-Makefile b/cesar/projects/eoc/slave-Makefile
new file mode 100644
index 0000000000..290890b7e7
--- /dev/null
+++ b/cesar/projects/eoc/slave-Makefile
@@ -0,0 +1,22 @@
+BASE = ../..
+ECOS = y
+TARGET = sparc
+VARIANT = slave
+TARGET_OPTIMIZE = -Os
+
+TARGET_PROGRAMS = slave
+
+slave_SOURCES = eoc.c
+slave_MODULES = lib mac cl hle bsu interface hal station host hle/tools\
+ ce cp/beacon cp/cco/bw cp/cco/region cp/cl_interf \
+ cp/msg cp/fsm cp/secu cp/sta/core \
+ cp/sta/mgr cp/sta/action \
+ cp/eoc/sta/action cp/eoc/cco/bw cp/eoc/sta/mgr cp
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_sta_action_MODULE_SOURCES = bridge.c vs.c misc.c
+cp_MODULE_MODULES =
+
+include $(BASE)/common/make/top.mk
+
+$(call src2obj,src/region_stub.c,target): $(BASE)/cp/fsm/fsm.h
diff --git a/cesar/projects/eoc/slave-ecos.ecc.sh b/cesar/projects/eoc/slave-ecos.ecc.sh
new file mode 100644
index 0000000000..db2208c6cc
--- /dev/null
+++ b/cesar/projects/eoc/slave-ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new sparc_leon default
+cat >> $config <<'EOF'
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/projects/eoc/src/eoc.c b/cesar/projects/eoc/src/eoc.c
new file mode 100644
index 0000000000..921d2edcc8
--- /dev/null
+++ b/cesar/projects/eoc/src/eoc.c
@@ -0,0 +1,24 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/eoc.c
+ * \brief EoC startup file
+ * \ingroup projects
+ */
+#include "common/std.h"
+
+#include "station/station.h"
+
+int
+cyg_user_start (void)
+{
+ /* Initialise Cesar */
+ cesar_init ();
+ return 0;
+}
+
diff --git a/cesar/station/src/station.c b/cesar/station/src/station.c
index 699ce01c53..d09a51d7ea 100644
--- a/cesar/station/src/station.c
+++ b/cesar/station/src/station.c
@@ -24,6 +24,11 @@
# include "hal/leon/fatal_button.h"
#endif
+#if MODULE_INCLUDED (hal_trace)
+# include "hal/trace/trace.h"
+# include "config/hal/trace/cpu.h"
+#endif
+
#include "lib/seq_check.h"
#include "lib/init.h"
@@ -40,6 +45,10 @@ cesar_init (void)
u32 seed = 0;
trace_init ();
+#if MODULE_INCLUDED (hal_trace)
+ hal_trace_init ();
+#endif
+
#if MODULE_INCLUDED (hal_leon) && CONFIG_LEON_FATAL_BUTTON
leon_fatal_button_init ();
#endif
diff --git a/cesar/test_general/maximus/integration/cl-sar-pbproc/Makefile b/cesar/test_general/maximus/integration/cl-sar-pbproc/Makefile
index 88619e8f16..65b9f94245 100644
--- a/cesar/test_general/maximus/integration/cl-sar-pbproc/Makefile
+++ b/cesar/test_general/maximus/integration/cl-sar-pbproc/Makefile
@@ -4,7 +4,7 @@ ECOS = y
TARGET_PROGRAMS = cl-sar-pbproc
cl-sar-pbproc_SOURCES = station.c
-cl-sar-pbproc_MODULES = hal/phy/maximus lib mac host cl \
- hal/phy/soft/bridgedma
+cl-sar-pbproc_MODULES = hal/phy/maximus lib mac host cl hal/watchdog hal/phy/soft/bridgedma
+cl-sar-pbproc_MODULES_CONFIG = cp/sta/mgr
include $(BASE)/common/make/top.mk
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Config b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Config
new file mode 100644
index 0000000000..d83c82a254
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Config
@@ -0,0 +1,9 @@
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_TRACE = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_CP_MSG_EOC_VS = y
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Makefile b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Makefile
new file mode 100644
index 0000000000..6a266da8e3
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/Makefile
@@ -0,0 +1,16 @@
+BASE = ../../../..
+
+ECOS = y
+
+INCLUDES = test_general/maximus/integration/cp-sar-pbproc-eoc/override
+
+TARGET_PROGRAMS = sar-pbproc
+
+sar-pbproc_SOURCES = station.c
+sar-pbproc_MODULES = hal/phy/maximus \
+ lib mac \
+ cp hle interface hal ce/stub \
+ host cp/eoc/cco/bw cl \
+ cp/eoc/cco/action
+# cp/eoc/test_eoc/station/fcall station
+include $(BASE)/common/make/top.mk
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/doc/test1.txt b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/doc/test1.txt
new file mode 100644
index 0000000000..8c4a02df01
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/doc/test1.txt
@@ -0,0 +1,76 @@
+= SAR - PBproc =
+
+This tests :
+ * The Tx transmission
+ * The Rx reception.
+
+This test is done with two stations (Station1 and Station2).
+
+== Test configuration ==
+
+The stations shall be configured first before launching the test :
+ * Snid, tei, CA shedules.
+ * Links in the Mac Store.
+ * Data buffers for the SAR.
+
+== Function Calls ==
+
+=== fc_station_init_config ===
+
+To configure the station.
+
+Parameters :
+ * snid : The snid of the station.
+ * tei : the station tei.
+ * auto_sched : To create automatically the schedules for the CA.
+
+=== fc_station_link_add ===
+
+Add a link to the station i.e. create a MFS in the mac store.
+
+Parameters :
+ * type : TX/RX MFS.
+ * bcast : Broadcast MFS
+ * mme : MME MFS.
+ * lid : The lid of the MFS.
+ * tei : The source/destination station.
+
+
+=== fc_sar_data_buffer_add ===
+
+Add a data buffer for the SAR to reassembly some Mac Frames.
+
+=== fc_sar_msdu_add ===
+
+Request the SAR to segment and send a MSDU.
+
+Parameters :
+ * tei : Station destination TEI.
+ * lid : Link identifier.
+ * bcast : broadcast link.
+ * mme : MME MFS (if setted, it will not use the lid value).
+ * length : The msdu length.
+ * buffer : The data to segment.
+
+=== fc_station_link_remove ===
+
+Remove a link from the station (and from the mac store).
+
+Parameters :
+ * type : TX/RX MFS.
+ * bcast : Broadcast MFS
+ * mme : MME MFS.
+ * lid : The lid of the MFS.
+ * tei : The source/destination station.
+
+=== fc_sar_print_trace ===
+
+To print the SAR traces taken during the test.
+To see the SAR traces add a Config file to the make directory with the
+following line.
+
+{{{
+CONFIG_TRACE=y
+}}}
+
+And compile again the test.
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/ecos.ecc.sh b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/ecos.ecc.sh
new file mode 100644
index 0000000000..7984aef8ed
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new maximus default
+cat >> $config <<EOF
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/override/cp/msg/inc/vs_eoc_get_topo.h b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/override/cp/msg/inc/vs_eoc_get_topo.h
new file mode 100644
index 0000000000..7fe987717e
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/override/cp/msg/inc/vs_eoc_get_topo.h
@@ -0,0 +1,31 @@
+#ifndef override_cp_msg_inc_vs_eoc_get_topo_h
+#define override_cp_msg_inc_vs_eoc_get_topo_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/inc/vs_eoc_get_topo.h
+ * \brief VS_EOC_GET_TOPO Structures.
+ * \ingroup cp_msg
+ */
+
+#ifndef CP_FSM_EVENT_TYPE_VS_EOC_GET_TOPO_REQ
+#define CP_FSM_EVENT_TYPE_VS_EOC_GET_TOPO_REQ CP_FSM_EVENT_TYPE_NB
+#endif
+
+/** VS_EOC_GET_TOPO.CNF result. */
+enum cp_msg_vs_eoc_get_topo_cnf_result_t
+{
+ CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_SUCCESS,
+ CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_FAILURE,
+ CP_MSG_VS_EOC_GET_TOPO_CNF_RESULT_NB
+};
+
+typedef enum cp_msg_vs_eoc_get_topo_cnf_result_t
+cp_msg_vs_eoc_get_topo_cnf_result_t;
+
+#endif /* override_cp_msg_inc_vs_eoc_get_topo_h */
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/src/station.c b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/src/station.c
new file mode 100644
index 0000000000..3fe1087e38
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/src/station.c
@@ -0,0 +1,1534 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file test_general/integration/interface-dp/src/station.c
+ * \brief Station interface - DP.
+ * \ingroup test_general
+ *
+ * Test the integration of the interface with the data plane.
+ * The sniffer will be added to this test later.
+ */
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+
+#include "common/std.h"
+#include "mac/common/timings.h"
+#include "host/station/station.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Library include. */
+#include "lib/read_word.h"
+#include "lib/trace.h"
+#include "lib/circular_buffer.h"
+#include "lib/list.h"
+
+/** Data include. */
+#include "mac/common/config.h"
+#include "mac/common/ntb.h"
+#include "mac/common/store.h"
+
+/** Layers include. */
+#include "mac/sar/sar.h"
+#include "mac/pbproc/pbproc.h"
+#include "mac/ca/ca.h"
+#include "mac/pbproc/inc/context.h"
+#include "mac/ca/inc/context.h"
+
+#include "mac/sar/inc/trace.h"
+#include "lib/rnd.h"
+
+/** for scheduler */
+#include "cl/cl.h"
+#include "hle/hle.h"
+#include "interface/interface.h"
+#include "cp/cp.h"
+#include "hal/timer/timer.h"
+#include "ce/rx/rx.h"
+#include "lib/stats.h"
+
+#include "cp/beacon/defs.h"
+#include "cp/eoc/cco/action/cco_action.h"
+#include "cp/eoc/cco/bw/bw.h"
+
+struct tei_node_t
+{
+ list_node_t node;
+ uint tei;
+};
+typedef struct tei_node_t tei_node_t;
+
+
+/** station context. */
+struct station_test_t
+{
+ /** The mac config. */
+ mac_config_t mac_config;
+ /** Short network identifier. */
+ u8 snid;
+ /** The mac store. */
+ mac_store_t *mac_store;
+
+ // Layers
+ /** Pbproc context. */
+ pbproc_t *pbproc;
+
+ /** SAR. */
+ sar_t *sar;
+
+ /** CL. */
+ cl_t *cl;
+
+ /** HLE */
+ hle_t *hle;
+
+ /** Interface. */
+ interface_t *interface;
+
+ /** Control Plane. */
+ cp_t *cp;
+
+ /** CE in RX. */
+ ce_rx_t *ce_rx;
+
+ /* Hal timer. */
+ hal_timer_t *hal_timer;
+
+ /* Schedule index. */
+ uint sched_index;
+ /* Pbproc activate. */
+ bool pbproc_activate;
+
+ cyg_handle_t sched_handle;
+ cyg_thread sched_thread;
+
+ /** Used to memorize the list of TEI inserted in the mac_Store to remove it
+ * in the future.
+ */
+ list_t tei_list;
+ /** create schedule only on CCo side */
+ bool create_schedule;
+ /** beacon alloc type: 0 csma only,1 mixed csma & tdma */
+ uint beacon_alloc_type;
+ /** mfs global type, csma or tdma */
+ uint mfs_cfp;
+ /** number of stations */
+ uint num_station;
+ /** type of tdma fill */
+ uint tdma_fill;
+};
+typedef struct station_test_t station_test_t;
+
+
+u8 mme_buffer [2048] __attribute__((aligned (2048)));
+u8 sched_stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
+
+//----------------------------------------------------------------------------
+static station_test_t station_test = {.num_station = 5, .tdma_fill=0};
+
+/****************** CALL BACKS DEFINITION ****************/
+
+/**
+ * Call back called by the SAR each time a packet is segmented.
+ * In this test it will only display a message.
+ * The buffer is a static buffer not a allocated one it does not need to be
+ * freed.
+ *
+ * \param user, User data
+ * \param buffer the address of the buffer.
+ */
+void sar_segmentation_ul_done (void *user, u8* buffer, void *cl_data)
+{
+ printf ("******************************************\n");
+ printf (" sar Segmentation done\n \n");
+ printf ("******************************************\n");
+}
+
+/**
+ * Implementation of the sar_reassembly_done_cb_t call back.
+ * Only used in this test.
+ * The buffer and the mfs shall be release.
+ *
+ * \param user, User data
+ * \param buffer the buffer address containing the data
+ * \param length the data length
+ * \param mfs the mfs used
+ */
+void sar_reassembly_ul_done (void *user, u8* buffer, uint length,
+ mfs_rx_t *mfs, bool encrypted)
+{
+ dbg_assert (buffer);
+ dbg_assert (length >= 60 && length <= 1518);
+ dbg_assert (mfs);
+
+ printf ("******************************************\n");
+ printf (" sar Reassembly done\n \n");
+ printf ("******************************************\n");
+
+ free (buffer);
+
+ blk_print_memory ();
+}
+
+/**
+ * Implementation of the sar_reassembly_done_cb_t call back.
+ * Only used in this test.
+ * The buffer and the mfs shall be release.
+ *
+ * \param user, User data
+ * \param buffer the buffer address containing the data
+ * \param length the data length
+ * \param mfs the mfs used
+ */
+void sar_reassembly_mme_done (void *user, u8* buffer, uint length,
+ mfs_rx_t *mfs, bool encrypted)
+{
+ dbg_assert (buffer);
+ dbg_assert (length >= 60 && length <= 1518);
+ dbg_assert (mfs);
+
+ printf ("******************************************\n");
+ printf (" sar Reassembly MME done\n");
+ printf ("******************************************\n");
+
+ sar_mme_buffer_add (station_test.sar, buffer);
+
+ blk_print_memory ();
+}
+
+// ---------------------------- Station functions --------------------------
+
+/**
+ * Add a link to the STAtion i.e. will create a MFS
+ *
+ * \param ctx the station context.
+ * \param type TX or RX link, it is a short 1 for TX 0 for RX.
+ * \param bcast short indicating if the link is a broadcast link
+ * \param mme short indicating if the link will be use to transmit MMEs
+ * \param lid short indicating if it is a link identitier.
+ * \param tei short the destination station.
+ */
+void station_test_link_add (station_test_t *ctx, uint type, uint bcast,
+ uint mme, uint lid, uint tei)
+{
+ bool added;
+ mfs_t *mfs;
+ sta_t *sta;
+
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_store);
+ dbg_assert (ctx->sar);
+
+ if (MAC_TEI_IS_STA (tei))
+ {
+ mac_store_sta_add (ctx->mac_store, tei);
+ sta = mac_store_sta_get (ctx->mac_store, tei);
+ sta->authenticated = true;
+ blk_release (sta);
+ }
+
+ mfs = mac_store_mfs_add (ctx->mac_store, type, bcast, mme, lid, tei,
+ &added);
+ dbg_assert (added);
+ /* impose tdma mfs with cfp = true */
+ if (station_test.mfs_cfp && mfs->common.tx)
+ mfs->tx.cfp = true;
+
+ // add the link to the sar.
+ sar_mfs_add (ctx->sar, mfs);
+
+ /* Authenticated the station. */
+
+ blk_release (mfs);
+}
+
+/**
+ * Inject SOUND frame
+ *
+ * \param ctx the station context.
+ * \param tei short the destination station.
+ */
+void station_test_sound_set (station_test_t *ctx, uint tei)
+{
+ sta_t *sta;
+
+ dbg_assert (ctx);
+
+ if (MAC_TEI_IS_STA (tei))
+ {
+ sta = mac_store_sta_get (ctx->mac_store, tei);
+ sta->tx_tonemaps->default_tmi = TONEMAP_INDEX_INITIAL_START;
+ blk_release (sta);
+ }
+
+ phy_chandata_conf_t chandata_conf[1] =
+ {
+ {.type =PHY_CHANDATA_TYPE_NRJ_SYMBOL, .last = 1},
+ };
+ pbproc_set_chandata_conf (
+ ctx->pbproc, (phy_chandata_conf_t *) chandata_conf, 1);
+
+}
+
+/**
+ * Remove a link to the STAtion i.e. will create a MFS
+ *
+ * \param ctx the station context.
+ * \param type TX or RX link, it is a short 1 for TX 0 for RX.
+ * \param bcast short indicating if the link is a broadcast link
+ * \param mme short indicating if the link will be use to transmit MMEs
+ * \param lid short indicating if it is a link identitier.
+ * \param tei short the destination station.
+ */
+void station_test_link_remove (station_test_t *ctx, uint type, uint bcast,
+ uint mme, uint lid, uint tei)
+{
+ /*
+ mfs_t *mfs;
+ pb_t *pb;
+ */
+
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_store);
+ dbg_assert (ctx->sar);
+ dbg_assert (MAC_TEI_IS_STA (tei));
+
+ sar_sta_remove (ctx->sar, tei);
+
+ /*
+ mfs = mac_store_mfs_get (ctx->mac_store, type, bcast, mme, lid, tei);
+
+ if (mfs != NULL)
+ {
+ while (type && mfs->tx.head)
+ {
+ pb = mfs->tx.head;
+ mfs->tx.head = mfs->tx.head->next;
+ blk_release_desc ((blk_t *) pb);
+ }
+
+ while (!type && mfs->rx.head)
+ {
+ pb = mfs->rx.head;
+ mfs->rx.head = mfs->rx.head->next;
+ blk_release_desc ((blk_t *) pb);
+ }
+
+ // remove the MFS from the sar
+ sar_mfs_remove (ctx->sar, mfs);
+
+ blk_release (mfs);
+ }
+ */
+}
+
+/* creation of false scheduling */
+void
+test_prepare_tdma_alloc_random(pbproc_t *ctx, uint max_length_tck,
+ uint num_station)
+{
+ lib_rnd_t rnd[1];
+ lib_rnd_init (rnd, 1234);
+ ca_eoc_sched_t * alloc = &ctx->ca->ca_eoc_sched;
+ alloc->record_nb = (128/num_station)*num_station;
+ alloc->record_curr = alloc->record_nb - 1;
+ uint i;
+ uint fixed_clk = MAC_RIFS_DEFAULT_TCK
+ + MAC_PREAMBLE_TCK + 2 * MAC_FC_AV_TCK;
+ for (i=0; i < alloc->record_nb; i++)
+ {
+ int j = (i%(station_test.num_station+1));
+
+ if (j)
+ {
+ alloc->sched_record[i].tei = 5 + j - 1;
+ alloc->sched_record[i].lid = 1;
+ }
+ else
+ {
+ alloc->sched_record[i].tei = 0xFF;
+ alloc->sched_record[i].lid = 0;
+ }
+
+ alloc->sched_record[i].cco_tx_duration = fixed_clk
+ + MAC_PAYLOAD_TCK (30+lib_rnd_uniform (rnd, 20),
+ MAC_DX417_TCK);
+
+ switch (station_test.tdma_fill)
+ {
+ case 0:
+ alloc->sched_record[i].sta_tx_duration = lib_rnd_uniform(rnd, 5) ?
+ fixed_clk + MAC_PAYLOAD_TCK (30+lib_rnd_uniform (rnd, 20),
+ MAC_DX417_TCK) : 0;
+ break;
+ case 1:
+ alloc->sched_record[i].sta_tx_duration = 0;
+ break;
+ }
+ }
+}
+
+/**
+ * Create a schedule for the Channel Access (beacon period) in CSMA only mode.
+ * Shall always be used to send or receive data.
+ *
+ * \param int_sta the pbproc context
+ * \param beacon_period_nb the quantity of beacon periods for the test.
+ */
+void create_schedule_csma_only (station_test_t *int_sta, uint beacon_period_nb)
+{
+ pbproc_t *pbproc;
+
+ dbg_assert (int_sta);
+
+ pbproc = int_sta->pbproc;
+ ca_beacon_period_t beacons_periods[beacon_period_nb];
+ uint i;
+
+ dbg_assert (pbproc);
+ dbg_assert (beacon_period_nb < CA_BEACON_PERIOD_NB);
+
+ /* Get and fill the schedule */
+ ca_schedule_t *sched = ca_alloc_get_schedule (pbproc_get_ca (pbproc),
+ int_sta->sched_index);
+
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = int_sta->snid;
+ sched->nek_switch = 0; //TODO
+ sched->allocations_nb = 1;
+ sched->allocations[0].end_offset_tck = 10000000;
+ sched->allocations[0].glid = 0xff;
+
+ /* Create a schedule for 14 beacon period */
+ for (i = 0; i < beacon_period_nb; i++)
+ {
+ beacons_periods[i].start_date = 2500000 * i
+ + my_station.current_tick_tck;
+ beacons_periods[i].schedule_index = int_sta->sched_index;
+ }
+
+ /* Use the new schedule */
+ ca_alloc_update_beacon_periods (pbproc_get_ca (pbproc), beacons_periods,
+ beacon_period_nb);
+
+ /* Activate the pbproc */
+ if (!int_sta->pbproc_activate)
+ {
+ pbproc_activate (pbproc, true);
+ int_sta->pbproc_activate = true;
+ }
+
+ int_sta->sched_index++;
+}
+
+void create_schedule_mixed_csma_tdma(station_test_t *int_sta,
+ uint beacon_period_nb, uint beacon_type)
+{
+ pbproc_t *pbproc;
+
+ dbg_assert (int_sta);
+
+ pbproc = int_sta->pbproc;
+ ca_beacon_period_t beacons_periods[beacon_period_nb];
+ uint i;
+
+ dbg_assert (pbproc);
+ dbg_assert (beacon_period_nb < CA_BEACON_PERIOD_NB);
+
+ /* Get and fill the schedule */
+ ca_schedule_t *sched = ca_alloc_get_schedule (pbproc_get_ca (pbproc),
+ int_sta->sched_index);
+
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = int_sta->snid;
+ sched->nek_switch = 0; //TODO
+ /* create scheduling only on CCo side. */
+ switch (beacon_type)
+ {
+ case 1:
+ sched->allocations_nb = 3;
+ sched->allocations[0].end_offset_tck = 25000;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[1].end_offset_tck = 100000;
+ sched->allocations[1].glid = MAC_LID_LOCAL_CSMA;
+ sched->allocations[2].end_offset_tck = 2500000;
+ sched->allocations[2].glid = MAC_LID_CFPI;
+ break;
+ case 2:
+ sched->allocations_nb = 2;
+ sched->allocations[0].end_offset_tck = 25000;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[1].end_offset_tck = 2000000;
+ sched->allocations[1].glid = MAC_LID_CFPI;
+ break;
+ case 3:
+ sched->allocations_nb = 2;
+ sched->allocations[0].end_offset_tck = 25000;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[1].end_offset_tck = 2000000;
+ sched->allocations[1].glid = MAC_LID_LOCAL_CSMA;
+ break;
+ }
+ /* Create a schedule for 14 beacon period */
+ for (i = 0; i < beacon_period_nb; i++)
+ {
+ beacons_periods[i].start_date = 2500000 * i
+ + my_station.current_tick_tck;
+ beacons_periods[i].schedule_index = int_sta->sched_index;
+ }
+
+ /* Use the new schedule */
+ ca_alloc_update_beacon_periods (pbproc_get_ca (pbproc), beacons_periods,
+ beacon_period_nb);
+
+ /* Activate the pbproc */
+ if (!int_sta->pbproc_activate)
+ {
+ pbproc_activate (pbproc, true);
+ int_sta->pbproc_activate = true;
+ }
+
+ int_sta->sched_index++;
+}
+
+/**
+ * Thread entry finction
+ *
+ * \param int_sta the sta context.
+ */
+void pbproc_sched (cyg_addrword_t int_sta)
+{
+ station_test_t *station_test;
+ station_test = (station_test_t *) int_sta;
+ uint beacon_type = station_test->beacon_alloc_type;
+ while (true)
+ {
+ switch (beacon_type)
+ {
+ case 0:
+ create_schedule_csma_only (station_test, 14);
+ station_test->sched_index ++;
+ //create the second schedule.
+ create_schedule_csma_only (station_test, 14);
+ station_test->sched_index ++;
+ //create the third schedule.
+ create_schedule_csma_only (station_test, 14);
+ station_test->sched_index ++;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ create_schedule_mixed_csma_tdma (station_test, 14, beacon_type);
+ station_test->sched_index ++;
+ //create the second schedule.
+ create_schedule_mixed_csma_tdma (station_test, 14, beacon_type);
+ station_test->sched_index ++;
+ //create the third schedule.
+ create_schedule_mixed_csma_tdma (station_test, 14, beacon_type);
+ station_test->sched_index ++;
+ break;
+ default:
+ printf ("Not implemented type %d\n", beacon_type);
+ }
+ cyg_thread_delay (500);
+ }
+}
+
+
+/**
+ * Provides the Tei of the STA and the SNID
+ *
+ * \param ctx the station context
+ * \param tei the tei of the station
+ * \param snid the snid of the AVLN
+ * \param beacon_period_auto generation automatic of the beacon period for
+ * the CA scheduling
+ * \param cco boolean informing if the sta is cco or not
+ * \param authenticated boolean informing if the sta is authenticated or
+ * not.
+ */
+void station_test_config (station_test_t *ctx, uint tei, uint snid,
+ bool beacon_period_auto, mac_t mac_addr)
+{
+ dbg_assert (ctx);
+
+ ctx->snid = snid;
+ ctx->mac_config.tei = tei;
+ ctx->create_schedule = MAC_TEI_IS_EOC_CCO(ctx->mac_config.tei);
+
+ if (mac_addr == 0)
+ {
+ ctx->mac_config.sta_mac_address = 0x123456789abcull;
+ }
+ else
+ ctx->mac_config.sta_mac_address = mac_addr;
+
+ if (ctx->create_schedule)
+ test_prepare_tdma_alloc_random (ctx->pbproc, 100000,
+ ctx->num_station);
+
+ if (beacon_period_auto)
+ {
+ // Create the Thread for the pbproc.
+ cyg_thread_create (9, &pbproc_sched, (cyg_addrword_t) ctx, "Sched",
+ sched_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL,
+ &ctx->sched_handle, &ctx->sched_thread);
+ cyg_thread_resume (ctx->sched_handle);
+ }
+
+ sar_mme_buffer_add (ctx->sar, mme_buffer);
+ sar_activate (ctx->sar, true);
+}
+
+/**
+ * Provides the TEI of all the station in the AVLN.
+ *
+ * \param ctx the station context.
+ * \param tei the tei list of the stations
+ * \param qte the quantity of TEIs in the list.
+ */
+void station_test_discover (station_test_t *ctx, uint *tei,
+ uint qte)
+{
+ tei_node_t *node;
+ uint i;
+
+ for (i = 0; i < qte; i++)
+ {
+ if (tei[i] != 0)
+ {
+ node = blk_alloc ();
+ list_init_node (&node->node);
+ node->tei = tei[i];
+ list_push (&ctx->tei_list, &node->node);
+
+ mac_store_sta_add (ctx->mac_store, tei[i]);
+ }
+ }
+}
+
+
+// ---------------------------- Function calls -----------------------------
+void
+tx_beacon_uninit (void);
+
+/** Uninitialise the function
+ */
+int fc_station_uninit (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint i;
+ sar_activate (station_test.sar, false);
+ pbproc_activate (station_test.pbproc, false);
+
+ for (i = MAC_TEI_STA_MIN; MAC_TEI_IS_STA (i); i++)
+ sar_sta_remove (station_test.sar, i);
+
+ tx_beacon_uninit();
+
+ sar_cleanup (station_test.sar);
+
+ cp_uninit (station_test.cp);
+ interface_uninit(station_test.interface);
+ hle_uninit (station_test.hle);
+ cl_uninit (station_test.cl);
+
+ sar_uninit (station_test.sar);
+ pbproc_uninit (station_test.pbproc);
+ ce_rx_uninit (station_test.ce_rx);
+ mac_store_uninit (station_test.mac_store);
+ hal_timer_uninit (station_test.hal_timer);
+
+ lib_stats_uninit ();
+ trace_uninit ();
+
+ blk_print_memory ();
+
+ return true;
+}
+
+/** Insert sound frame
+ */
+int fc_station_insert_sound (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei = 0;
+
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+
+ station_test_sound_set(&station_test, tei);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/** Creates a link in the STA.
+ *
+ * - dtei the tei of the station.
+ * - fw forward link
+ * - rw reverse link
+ * - bcast broadcast.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_add_mme_link (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint dtei = 0;
+ uint fw = 0;
+ uint rw = 0;
+ uint bcast = 0;
+
+ mfs_tx_t *mfs_tx;
+ mfs_rx_t *mfs_rx;
+ bool added;
+
+ fcall_param_bind_short (*param, *msg, "dtei", &dtei);
+ fcall_param_bind_short (*param, *msg, "fw", &fw);
+ fcall_param_bind_short (*param, *msg, "rw", &rw);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+
+ fcall_param_reset (*param);
+
+ if (fw)
+ {
+ mfs_tx = mac_store_mfs_add_tx (station_test.mac_store, bcast, true, MAC_LID_NONE, dtei, &added);
+
+ if (mfs_tx == NULL)
+ return false;
+
+ sar_mfs_add (station_test.sar, (mfs_t *) mfs_tx);
+ blk_release (mfs_tx);
+ }
+
+ if (rw)
+ {
+ mfs_rx = mac_store_mfs_add_rx (station_test.mac_store, bcast, true, MAC_LID_NONE, dtei, &added);
+
+ if (mfs_rx == NULL)
+ return false;
+
+ sar_mfs_add (station_test.sar, (mfs_t *) mfs_rx);
+ blk_release (mfs_rx);
+ }
+
+ return true;
+}
+
+/** Initialise the station parameters data as the mac address the tei.
+ *
+ * - stei.
+ * - mac_addr.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_config (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint stei = 0;
+ mac_t mac_address = 0;
+
+ fcall_param_bind_short (*param, *msg, "stei", &stei);
+ fcall_param_bind (*param, *msg, "mac_addr", sizeof(mac_t), &mac_address);
+
+ station_test.mac_config.sta_mac_address = mac_address;
+ station_test.mac_config.tei = stei;
+ station_test.mac_config.authenticated = true;
+ sar_activate (station_test.sar, true);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+int fc_station_config_bt (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint beacon_alloc_type=0;
+ uint mfs_cfp=0;
+
+ fcall_param_bind_short (*param, *msg, "beacon_alloc_type",
+ &beacon_alloc_type);
+ fcall_param_bind_short (*param, *msg, "mfs_cfp",
+ &mfs_cfp);
+
+ station_test.beacon_alloc_type = beacon_alloc_type;
+ station_test.mfs_cfp = mfs_cfp;
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/** Prepare the station to work.
+ * It will create default schedules for the Channel Access in CSMA-only mode
+ * and activate the pbproc to start the communication with the others
+ * stations.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_start (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ ca_beacon_period_t beacons_periods[4];
+ uint i;
+
+ /* Get and fill the schedule */
+ ca_schedule_t *sched = ca_alloc_get_schedule (pbproc_get_ca (station_test.pbproc),0);
+
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = station_test.snid;
+ sched->nek_switch = 0; //TODO
+ sched->allocations_nb = 1;
+ sched->allocations[0].end_offset_tck = BITS_ONES (24);
+ sched->allocations[0].glid = 0xff;
+
+ /* Create a schedule for 14 beacon period */
+ for (i = 0; i < 4; i++)
+ {
+ beacons_periods[i].start_date = BITS_ONES(24) * i
+ + my_station.current_tick_tck;
+ beacons_periods[i].schedule_index = 0;
+ }
+
+ /* Use the new schedule */
+ ca_alloc_update_beacon_periods (pbproc_get_ca (station_test.pbproc), beacons_periods,
+ 4);
+
+ /* Only run this one !!! */
+ pbproc_activate (station_test.pbproc, true);
+
+ return true;
+}
+
+/**
+ * Add a link to the Station in order to receive or transmit data.
+ *
+ * - type TX or RX link, it is a short 1 for TX 0 for RX.
+ * - bcast short indicating if the link is a broadcast link
+ * - mme short indicating if the link will be use to transmit MMEs
+ * - lid short indicating if it is a link identitier.
+ * - tei short the destination station.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_link_add (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint type;
+ uint bcast;
+ uint mme;
+ uint lid;
+ uint tei;
+
+ type = 0;
+ bcast = 0;
+ mme = 0;
+ lid = 0;
+ tei = 0;
+
+ fcall_param_bind_short (*param, *msg, "type", &type);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+ fcall_param_bind_short (*param, *msg, "mme", &mme);
+ fcall_param_bind_short (*param, *msg, "lid", &lid);
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+
+ if (type)
+ printf (
+ "[STATION : %d] TX link added, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+ else
+ printf (
+ "[STATION : %d] RX link added, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+
+ if (!mme && !bcast)
+ station_test_link_add (&station_test, 0, bcast, mme, lid, tei);
+
+ station_test_link_add (&station_test, 1, bcast, mme, lid, tei);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Remove a link to the Station in order to receive or transmit data.
+ *
+ * - type TX or RX link, it is a short 1 for TX 0 for RX.
+ * - bcast short indicating if the link is a broadcast link
+ * - mme short indicating if the link will be use to transmit MMEs
+ * - lid short indicating if it is a link identitier.
+ * - tei short the destination station.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_link_remove (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint type;
+ uint bcast;
+ uint mme;
+ uint lid;
+ uint tei;
+
+ type = 0;
+ bcast = 0;
+ mme = 0;
+ lid = 0;
+ tei = 0;
+
+ fcall_param_bind_short (*param, *msg, "type", &type);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+ fcall_param_bind_short (*param, *msg, "mme", &mme);
+ fcall_param_bind_short (*param, *msg, "lid", &lid);
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+
+ if (type)
+ printf (
+ "[STATION : %d] TX link removed, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+ else
+ printf (
+ "[STATION : %d] RX link removed, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+
+ station_test_link_remove (&station_test, 0, bcast, mme, lid, tei);
+ station_test_link_remove (&station_test, 1, bcast, mme, lid, tei);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Initialize the number of STAs
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_num_station (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint num_station=0;
+
+ fcall_param_bind_short (*param, *msg, "num_station", &num_station);
+
+ station_test.num_station = num_station;
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Initialize the configuration of the STA.
+ * The parameters we must provide are the TEI of the STA, the SNID and the
+ * boolean to indicate the auto generation of the beacon periods.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei;
+ uint snid;
+ uint beacon_period_auto;
+ mac_t mac;
+
+ tei = 0;
+ snid = 0;
+ beacon_period_auto = 0;
+
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+ fcall_param_bind_short (*param, *msg, "snid", &snid);
+ fcall_param_bind_short (*param, *msg, "auto_sched", &beacon_period_auto);
+
+ station_test_config (&station_test, tei, snid, beacon_period_auto, mac);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Configure type of MFS-s used in script: 0 ordinary (CSMA), 1 (TDMA)
+ * Configure allocations in beacon period.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config_bt (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint beacon_alloc_type=0;
+ uint mfs_cfp=0;
+
+ fcall_param_bind_short (*param, *msg, "beacon_alloc_type",
+ &beacon_alloc_type);
+ fcall_param_bind_short (*param, *msg, "mfs_cfp",
+ &mfs_cfp);
+
+ station_test.beacon_alloc_type = beacon_alloc_type;
+ station_test.mfs_cfp = mfs_cfp;
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Add a data buffer to the SAR.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_sar_data_buffer_add (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ u8 *buffer;
+
+ buffer = (u8*) malloc (2048 * sizeof(u8));
+ sar_data_buffer_add (station_test.sar, buffer);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Add Msdu to send
+ *
+ * - lid the link to use
+ * - tei the destination
+ * - bcast if the link is a bcast link
+ * - mme if it is a mme
+ * - buffer the buffer containing a frame
+ * - length the buffer length
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_sar_msdu_add (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei;
+ uint lid;
+ uint bcast;
+ uint mme;
+ uint length;
+ u8 *buffer;
+
+ mfs_tx_t *mfs;
+
+ tei = 0;
+ lid = 0;
+ bcast = 0;
+ mme = 0;
+ length = 0;
+
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+ fcall_param_bind_short (*param, *msg, "lid", &lid);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+ fcall_param_bind_short (*param, *msg, "mme", &mme);
+ fcall_param_bind_short (*param, *msg, "length", &length);
+
+ buffer = (u8 *) malloc (length * sizeof (length));
+ fcall_param_bind (*param, *msg, "buffer", length * sizeof(u8), buffer);
+
+ mfs = mac_store_mfs_get_tx (station_test.mac_store, bcast, mme, lid, tei);
+ dbg_assert (mfs);
+
+ sar_msdu_add (station_test.sar, buffer, length, mfs, NULL,
+ mac_ntb());
+
+ blk_release (mfs);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+mfs_tx_t * beacon_mfs = NULL;
+u32 user_data;
+
+/**
+ * Stub to inform that beacon is received.
+ *
+ */
+void
+cp_beacon_add (void *user_data, pb_beacon_t *beacon,
+ pbproc_rx_beacon_params_t *params);
+
+/**
+ * Init parameters for beacon sending and receiving.
+ *
+ */
+void
+tx_beacon_init (void)
+{
+ beacon_mfs = blk_alloc ();
+ mfs_tx_init (beacon_mfs, true, false, MAC_LID_SPC_CENTRAL,
+ MAC_TEI_BCAST);
+ beacon_mfs->beacon = true;
+
+ ca_mfs_update(pbproc_get_ca (station_test.pbproc), beacon_mfs);
+
+ sar_init_beacon_cb (station_test.sar, &user_data, cp_beacon_add);
+
+}
+
+/**
+ * Remove allocated beacon mfs.
+ *
+ */
+void
+tx_beacon_uninit (void)
+{
+ if (beacon_mfs)
+ {
+ ca_mfs_remove(pbproc_get_ca (station_test.pbproc), beacon_mfs);
+ blk_release(beacon_mfs);
+ }
+}
+
+/**
+ * Insert beacon. Insert one fake PB into mfs and update mfs heap.
+ * due to priority beacon mfs will be first to send in SCP_CENTRAL part to
+ * send one PB (beacon) to network.
+ *
+ */
+void
+tx_beacon_insert (void)
+{
+ pb_beacon_t *pb = PARENT_OF (pb_beacon_t, blk, blk_alloc_desc ());
+ pbproc_tx_beacon_params_t params = {
+ { 0x0123, 0x4242, 0xabab, 0x5555 }, pb->data + 123
+ };
+ pbproc_mfs_beacon_prepare (station_test.pbproc, beacon_mfs, pb, &params);
+ /* insert into list of mfs-s. */
+ ca_mfs_update(pbproc_get_ca (station_test.pbproc), beacon_mfs);
+}
+
+/**
+ * Interface: Call beacon init function.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config_bc (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+
+ tx_beacon_init();
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Interface: Call beacon insert function.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config_bc_insert (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+
+ tx_beacon_insert();
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Provide to the STA using the parameters of the function call the station
+ * use for the test. Each STA shall known the TEI of the others present in the
+ * AVLN.
+ *
+ * The function call parameters must be
+ * - qte the quantity of TEIs present in the paramters. One for each STA
+ * without this one.
+ * - tei The list of TEIs.
+ * - mac the list of mac address.
+ *
+ * This will be use to add the STA's to the mac store, the STA will keep a
+ * list of theses TEI to remove the STA during the uninit procedure.
+ *
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_discover (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei[256];
+ mac_t macs[256];
+ uint qte;
+ char val [2];
+ char id[5];
+ uint count;
+ uint error;
+
+ qte = 0;
+ fcall_param_bind_short (*param, *msg, "qte", &qte);
+
+ count = 0;
+ error = 0;
+ for (count = 0; count < qte; count ++)
+ {
+ tei[count] = 0;
+ macs[count] = 0;
+ sprintf (val, "%d", count);
+ strcpy (id, "tei");
+ strcat (id, val);
+ fcall_param_bind_short (*param, *msg, id, &tei[count]);
+ }
+
+ station_test_discover (&station_test, tei, qte);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * print the sar traces for the tests.
+ * if the trace_config == y the traces are printed to the stdio.
+ * otherwise nothing is printed.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_sar_print_trace (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ fcall_param_reset (*param);
+
+ sar_trace_print (station_test.sar);
+ /* trace_buffer_dbg_dump (&station_test.pbproc->trace);
+ trace_buffer_dbg_dump (&station_test.pbproc->ca->trace); */
+
+ return true;
+}
+
+
+// ---------------------------- Stub functions ----------------------------
+
+/**
+ * CE measurements. To be replace by the CE function to get the measurements
+ *
+ * Pb measurement RX callback for Channel estimation.
+ * This call back will return one or two block in order to insert all the
+ * measurements contained in each PB of the mpdu received.
+ * Two cases can happen, the first the pb_nb is lesser than the blk capacity,
+ * this callback will return only a blk pointed by the first and the last
+ * pointer.
+ * In the second case the quantity of PB are greater than one blk capacity, this
+ * callback will return two blk (chained) the first pointed by the first pointer
+ * and the last one by the last pointer.
+ *
+ * \param user User data
+ * \param rx_params Frame control information to know date and tonemap used
+ * \param number of pbs
+ * \param first blk to insert the measurements.
+ * \param last blk to insert the measurements.
+ * \param chandata chan data measurements
+ *
+ * \return boolean to indicate if a block had been returned or not.
+ */
+bool ce_measurements (void *user, pbproc_rx_params_t *rx_params, uint pb_nb,
+ blk_t **first, blk_t **last, pb_t *chandata, uint nb_chandata, uint
+ *blk_offset)
+{
+ dbg_assert (rx_params);
+
+ if (chandata)
+ {
+ blk_release_desc_range_nb ((blk_t *) chandata, nb_chandata);
+ }
+
+ return false;
+}
+
+
+/**
+* CP receives a new MME.
+* \param user_data the data registered by the actor in the init function.
+* \param mfs the mfs
+* \param buffer the buffer containing the MME.
+* \param length the MME length
+* \param mme_recv data use by the data plane.
+* \param encryption inform if the packet comes from the PWL if it had been
+* crypted or not.
+*/
+void
+cp_mme_recv (void *user_data, mfs_rx_t *mfs, u8 *buffer, uint length,
+ bool mme_recv, bool encryption)
+{
+ printf ("/*************************************************/\n");
+ printf ("/ STATION : %d Receive a MME **********/\n",
+ station_test.mac_config.tei);
+ printf ("/ MME length : %d **********/\n", length);
+ printf ("/ MME encrypted : %d **********/\n",
+ encryption);
+ printf ("/*************************************************/\n");
+}
+
+/**
+* CP receives a beacon.
+* \param user_data the data registered by the actor in the init function.
+* \param beacon the beacon freshly received.
+*/
+void
+cp_beacon_add (void *user_data, pb_beacon_t *beacon,
+ pbproc_rx_beacon_params_t *params)
+{
+ printf ("/*************************************************/\n");
+ printf ("/ STATION : %d Receive a beacon ********/\n",
+ station_test.mac_config.tei);
+ printf ("/*************************************************/\n");
+
+
+ // release the beacon.
+ blk_release_desc ((blk_t *) beacon);
+}
+
+
+//--------------------------------------------------------------------------
+// Simulation of CP environment
+int
+fc_send_eoc_beacon (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+
+ printf("=> fcall to station\n");
+
+ cp_eoc_cco_action_send_central_beacon (station_test.cp);
+
+ return 0;
+}
+
+int
+fc_cp_eoc_cco_bw_scheduler (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+
+ printf("=> schedule\n");
+
+ // cp_eoc_cco_action_send_central_beacon (station_test.cp);
+
+ cp_eoc_cco_bw_scheduler(station_test.cp);
+
+ return 0;
+}
+
+void
+pbproc_spoc_coeff_set (pbproc_t *pbproc, phy_spoc_coeff_t *coeff)
+{
+ dbg_assert (coeff);
+
+ blk_release (coeff->part2);
+ blk_release (coeff);
+}
+
+// -------------------------------------------------------------------------
+
+
+/** Cesar init function as described in the wiki
+ * http://pessac/cesar/trac/wiki/20071128Cesar#LEONcore
+ */
+void
+cesar_init (void)
+{
+ // Initialise the trace system.
+ trace_init ();
+
+ lib_stats_init ();
+
+ // Initialise the mac_store.
+ station_test.mac_store = mac_store_init ();
+
+ // Initialise the mac config.
+ mac_config_init (&station_test.mac_config);
+
+ // Intialise the pbproc.
+ station_test.pbproc = pbproc_init (&station_test.mac_config,
+ station_test.mac_store);
+
+ // Initialise the mac ntb.
+ mac_ntb_init (pbproc_get_phy(station_test.pbproc), &station_test.mac_config);
+
+ // Initialise the SAR.
+ station_test.sar = sar_init (station_test.mac_store, station_test.pbproc,
+ pbproc_get_ca (station_test.pbproc),
+ station_test.mac_config.seed);
+
+
+ /* Initialise the CL. */
+ station_test.cl = cl_init (station_test.mac_store, station_test.sar,
+ &station_test.mac_config);
+
+ /* Initialise the HLE. */
+ station_test.hle = hle_init (station_test.cl);
+
+ /* Initialise the interface. */
+ station_test.interface = interface_init(station_test.hle,
+ station_test.cl,
+ station_test.sar,
+ &station_test.mac_config);
+
+ /* Initialise the hal timer. */
+ station_test.hal_timer = hal_timer_init (
+ pbproc_get_phy(station_test.pbproc));
+
+ /* Initialize the CE in RX. */
+ station_test.ce_rx = ce_rx_init (station_test.mac_store,
+ station_test.sar, station_test.pbproc,
+ &station_test.mac_config);
+
+ /* Initialise the CP. */
+ station_test.cp = cp_init (&station_test.mac_config,
+ station_test.interface, station_test.hal_timer,
+ station_test.pbproc, station_test.mac_store,
+ station_test.sar, station_test.cl,
+ station_test.ce_rx,
+ station_test.mac_config.seed);
+
+ // start HLE...
+ hle_activate(station_test.hle, true);
+
+ // init the variables of the station.
+ station_test.pbproc_activate = false;
+ station_test.sched_index = 0;
+}
+
+
+/* ---------------------- Main function -------------------*/
+int
+cyg_user_start (void)
+{
+ cesar_init ();
+
+ station_log_set_level(&my_station, STATION_LOG_DEBUG);
+ my_station.pipe_log_fd = 1;
+
+ fcall_register (my_station.fcall, "fc_station_link_add",
+ &fc_station_link_add, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_link_remove",
+ &fc_station_link_remove, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_config",
+ &fc_station_init_config, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_config_bt",
+ &fc_station_config_bt, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_data_buffer_add",
+ &fc_sar_data_buffer_add, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_mme_buffer_add",
+ &fc_sar_data_buffer_add, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_msdu_add", &fc_sar_msdu_add,
+ NULL);
+
+ fcall_register (my_station.fcall, "fc_station_discover",
+ &fc_station_discover, NULL);
+
+ fcall_register (my_station.fcall, "fc_add_mme_link",
+ &fc_add_mme_link , NULL);
+
+ fcall_register (my_station.fcall, "fc_station_config",
+ &fc_station_config, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_start",
+ &fc_station_start, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_print_trace",
+ &fc_sar_print_trace, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_uninit",
+ &fc_station_uninit, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_insert_sound",
+ &fc_station_insert_sound, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_num_station",
+ &fc_station_init_num_station, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_config_bc_insert",
+ &fc_station_init_config_bc_insert, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_config_bc",
+ &fc_station_init_config_bc, NULL);
+
+ fcall_register (my_station.fcall, "fc_cp_eoc_cco_bw_scheduler",
+ &fc_cp_eoc_cco_bw_scheduler, NULL);
+
+ sar_init_data_context (station_test.sar, station_test.sar);
+ sar_init_mme_context (station_test.sar, station_test.sar);
+
+ sar_init_segmentation_data_cb (station_test.sar, sar_segmentation_ul_done);
+ sar_init_segmentation_mme_cb (station_test.sar, sar_segmentation_ul_done);
+ sar_init_reassembly_data_cb (station_test.sar, sar_reassembly_ul_done);
+ sar_init_reassembly_mme_cb (station_test.sar, sar_reassembly_mme_done);
+
+ sar_init_measure_context (station_test.sar, &station_test.sar);
+ sar_init_measurement_cb (station_test.sar, ce_measurements);
+
+ return 0;
+}
+
+void test_print_trace(void)
+{
+ sar_trace_print (station_test.sar);
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&station_test.pbproc->trace);
+ trace_buffer_dbg_dump (&station_test.pbproc->ca->trace);
+#endif
+}
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_2sta_bc.py b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_2sta_bc.py
new file mode 100644
index 0000000000..6cfd80af2e
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_2sta_bc.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config_bc")
+fc1.set_sta (station1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config_bc")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("beacon_alloc_type", 1)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 4)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 4)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 4)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 4)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+for x in range(1, 5):
+ maximus.wait (10000)
+ fc1 = maximus.create_fcall ("fc_cp_eoc_cco_bw_scheduler")
+ fc1.set_sta (station1)
+ fc1.send()
+ maximus.wait (2490000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 4)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 4)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_multista.py b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_multista.py
new file mode 100644
index 0000000000..61e9939b86
--- /dev/null
+++ b/cesar/test_general/maximus/integration/cp-sar-pbproc-eoc/test_eoc_multista.py
@@ -0,0 +1,236 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+# Number of stations
+N = 10
+# Traffic type 1 = tx, 2 = rx ,3 = txrx
+TR_TYPE = 3
+# Use sound frames
+SOUND = 1
+# Mix dead stations
+MIX_DEAD = 0
+# Send bcast data
+SEND_BCAST = 1
+#def LID
+LID = 4
+
+# Init
+stations = range(0, N+1)
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+for i in range(0, N):
+ stations[i] = maximus.create_sta()
+
+#stations[0].debug()
+
+# Init part for stations
+fc1 = maximus.create_fcall ("fc_station_init_num_station")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("num_station", N)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc1.set_sta (station1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc1.set_sta (station1)
+fc1.send()
+
+#Broadcast mfs
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 1)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 0)
+fc1.add_param_ushort ("tei", 255)
+fc1.send()
+
+for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_station_link_add")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("type", 1)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("lid", LID)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+
+for i in range(0, N):
+ fc2 = maximus.create_fcall ("fc_station_config_bt")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("beacon_alloc_type", 1)
+ fc2.add_param_ushort ("mfs_cfp", 1)
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_station_init_config")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("snid", 1)
+ fc2.add_param_ushort ("tei", 5+i)
+ fc2.add_param_ushort ("auto_sched", 1)
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_station_link_add")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("type", 0)
+ fc2.add_param_ushort ("bcast", 0)
+ fc2.add_param_ushort ("mme", 0)
+ fc2.add_param_ushort ("lid", LID)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+ fc2.set_sta (stations[i])
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+ fc2.set_sta (stations[i])
+ fc2.send()
+
+# real work
+for x in range(1, 12):
+ maximus.wait (10000)
+ fc1 = maximus.create_fcall ("fc_cp_eoc_cco_bw_scheduler")
+ fc1.set_sta (station1)
+ fc1.send()
+ for i in range(0, N):
+ if SOUND:
+ fc1 = maximus.create_fcall ("fc_station_insert_sound")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+
+ fc2 = maximus.create_fcall ("fc_station_insert_sound")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ if SEND_BCAST:
+ fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 255)
+ fc1.add_param_ushort ("lid", 0)
+ fc1.add_param_ushort ("bcast", 1)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("length", 106)
+ f = open ('../../packet1','r')
+ fc1.add_param ("buffer", f.read())
+ f.close()
+ fc1.send()
+ if TR_TYPE & 1:
+ for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.add_param_ushort ("lid", LID)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("length", 106)
+ f = open ('../../packet1','r')
+ fc1.add_param ("buffer", f.read())
+ f.close()
+ fc1.send()
+
+ if TR_TYPE & 2:
+ for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+ fc1.set_sta (stations[i])
+ fc1.add_param_ushort ("tei", 1)
+ fc1.add_param_ushort ("lid", LID)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("length", 106)
+ f = open ('../../packet1','r')
+ fc1.add_param ("buffer", f.read())
+ f.close()
+ fc1.send()
+ maximus.wait (2490000)
+
+# Clean part
+for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_station_link_remove")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("type", 1)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("lid", LID)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+ fc1 = maximus.create_fcall ("fc_station_link_remove")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("type", 0)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("lid", LID)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+
+for i in range(0, N):
+ fc2 = maximus.create_fcall ("fc_station_link_remove")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("type", 0)
+ fc2.add_param_ushort ("bcast", 0)
+ fc2.add_param_ushort ("mme", 0)
+ fc2.add_param_ushort ("lid", LID)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ fc2 = maximus.create_fcall ("fc_station_link_remove")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("type", 1)
+ fc2.add_param_ushort ("bcast", 0)
+ fc2.add_param_ushort ("mme", 0)
+ fc2.add_param_ushort ("lid", LID)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ CCO TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+for i in range(0, N):
+ print "\n************ STATION", i+1, "TRACE ***************\n"
+ fc2 = maximus.create_fcall ("fc_sar_print_trace")
+ fc2.set_sta(stations[i])
+ fc2.send();
+
+ fc2 = maximus.create_fcall ("fc_station_uninit")
+ fc2.set_sta(stations[i])
+ fc2.send();
+
+ stations[i].remove()
diff --git a/cesar/test_general/maximus/integration/hle-cl-sar-pbproc/Makefile b/cesar/test_general/maximus/integration/hle-cl-sar-pbproc/Makefile
index 0433f0098e..7a6b723d80 100644
--- a/cesar/test_general/maximus/integration/hle-cl-sar-pbproc/Makefile
+++ b/cesar/test_general/maximus/integration/hle-cl-sar-pbproc/Makefile
@@ -4,7 +4,7 @@ ECOS = y
TARGET_PROGRAMS = hle-cl-sar-pbproc
hle-cl-sar-pbproc_SOURCES = station.c
-hle-cl-sar-pbproc_MODULES = mac host lib cl hle hal/phy/maximus \
- hal/phy/soft/bridgedma
+hle-cl-sar-pbproc_MODULES = mac host lib cl hle hal/phy/maximus hal/watchdog hal/phy/soft/bridgedma
+hle-cl-sar-pbproc_MODULES_CONFIG = cp/sta/mgr
include $(BASE)/common/make/top.mk
diff --git a/cesar/test_general/maximus/integration/interface-dp/Makefile b/cesar/test_general/maximus/integration/interface-dp/Makefile
index 887e03f600..cf5480f1bc 100644
--- a/cesar/test_general/maximus/integration/interface-dp/Makefile
+++ b/cesar/test_general/maximus/integration/interface-dp/Makefile
@@ -2,7 +2,7 @@ BASE = ../../../..
ECOS = y
-TARGET_PROGRAMS = station
+TARGET_PROGRAMS = station
station_SOURCES = station.c
station_MODULES = lib hal mac cl hle interface station bsu host
diff --git a/cesar/test_general/maximus/integration/ipmbox-hle-cl-sar-pbproc/Makefile b/cesar/test_general/maximus/integration/ipmbox-hle-cl-sar-pbproc/Makefile
index b4a1bbec33..2d17d56c77 100644
--- a/cesar/test_general/maximus/integration/ipmbox-hle-cl-sar-pbproc/Makefile
+++ b/cesar/test_general/maximus/integration/ipmbox-hle-cl-sar-pbproc/Makefile
@@ -8,5 +8,6 @@ TARGET_PROGRAMS = ipmbox-hle-cl-sar-pbproc
ipmbox-hle-cl-sar-pbproc_SOURCES = station.c
ipmbox-hle-cl-sar-pbproc_MODULES = mac cl hle hal lib host
+ipmbox-hle-cl-sar-pbproc_MODULES_CONFIG = cp/sta/mgr
include $(BASE)/common/make/top.mk
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/Config b/cesar/test_general/maximus/integration/sar-pbproc-eoc/Config
new file mode 100644
index 0000000000..7ff1366199
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/Config
@@ -0,0 +1,4 @@
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_TRACE = n
+CONFIG_BLK_NB = 3096
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/Makefile b/cesar/test_general/maximus/integration/sar-pbproc-eoc/Makefile
new file mode 100644
index 0000000000..95ca41dbc2
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/Makefile
@@ -0,0 +1,14 @@
+BASE = ../../../..
+
+ECOS = y
+
+INCLUDES = test_general/station/overide/ \
+
+TARGET_PROGRAMS = sar-pbproc
+
+sar-pbproc_SOURCES = station.c
+sar-pbproc_MODULES = hal/phy/maximus \
+ lib mac host hal/watchdog hal/phy/soft/bridgedma
+sar-pbproc_MODULES_CONFIG = cp/sta/mgr
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/doc/test1.txt b/cesar/test_general/maximus/integration/sar-pbproc-eoc/doc/test1.txt
new file mode 100644
index 0000000000..8c4a02df01
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/doc/test1.txt
@@ -0,0 +1,76 @@
+= SAR - PBproc =
+
+This tests :
+ * The Tx transmission
+ * The Rx reception.
+
+This test is done with two stations (Station1 and Station2).
+
+== Test configuration ==
+
+The stations shall be configured first before launching the test :
+ * Snid, tei, CA shedules.
+ * Links in the Mac Store.
+ * Data buffers for the SAR.
+
+== Function Calls ==
+
+=== fc_station_init_config ===
+
+To configure the station.
+
+Parameters :
+ * snid : The snid of the station.
+ * tei : the station tei.
+ * auto_sched : To create automatically the schedules for the CA.
+
+=== fc_station_link_add ===
+
+Add a link to the station i.e. create a MFS in the mac store.
+
+Parameters :
+ * type : TX/RX MFS.
+ * bcast : Broadcast MFS
+ * mme : MME MFS.
+ * lid : The lid of the MFS.
+ * tei : The source/destination station.
+
+
+=== fc_sar_data_buffer_add ===
+
+Add a data buffer for the SAR to reassembly some Mac Frames.
+
+=== fc_sar_msdu_add ===
+
+Request the SAR to segment and send a MSDU.
+
+Parameters :
+ * tei : Station destination TEI.
+ * lid : Link identifier.
+ * bcast : broadcast link.
+ * mme : MME MFS (if setted, it will not use the lid value).
+ * length : The msdu length.
+ * buffer : The data to segment.
+
+=== fc_station_link_remove ===
+
+Remove a link from the station (and from the mac store).
+
+Parameters :
+ * type : TX/RX MFS.
+ * bcast : Broadcast MFS
+ * mme : MME MFS.
+ * lid : The lid of the MFS.
+ * tei : The source/destination station.
+
+=== fc_sar_print_trace ===
+
+To print the SAR traces taken during the test.
+To see the SAR traces add a Config file to the make directory with the
+following line.
+
+{{{
+CONFIG_TRACE=y
+}}}
+
+And compile again the test.
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/ecos.ecc.sh b/cesar/test_general/maximus/integration/sar-pbproc-eoc/ecos.ecc.sh
new file mode 100644
index 0000000000..7984aef8ed
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new maximus default
+cat >> $config <<EOF
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/src/station.c b/cesar/test_general/maximus/integration/sar-pbproc-eoc/src/station.c
new file mode 100644
index 0000000000..d4c39f4258
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/src/station.c
@@ -0,0 +1,1386 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file test_general/integration/interface-dp/src/station.c
+ * \brief Station interface - DP.
+ * \ingroup test_general
+ *
+ * Test the integration of the interface with the data plane.
+ * The sniffer will be added to this test later.
+ */
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+
+#include "common/std.h"
+#include "mac/common/timings.h"
+#include "host/station/station.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Library include. */
+#include "lib/read_word.h"
+#include "lib/trace.h"
+#include "lib/circular_buffer.h"
+#include "lib/list.h"
+
+/** Data include. */
+#include "mac/common/config.h"
+#include "mac/common/ntb.h"
+#include "mac/common/store.h"
+
+/** Layers include. */
+#include "mac/sar/sar.h"
+#include "mac/pbproc/pbproc.h"
+#include "mac/ca/ca.h"
+#include "mac/pbproc/inc/context.h"
+#include "mac/ca/inc/context.h"
+
+#include "mac/sar/inc/trace.h"
+#include "lib/rnd.h"
+
+struct tei_node_t
+{
+ list_node_t node;
+ uint tei;
+};
+typedef struct tei_node_t tei_node_t;
+
+
+/** station context. */
+struct station_test_t
+{
+ /** The mac config. */
+ mac_config_t mac_config;
+ /** Short network identifier. */
+ u8 snid;
+ /** The mac store. */
+ mac_store_t *mac_store;
+
+ // Layers
+ /** Pbproc context. */
+ pbproc_t *pbproc;
+ /** Sar context. */
+ sar_t *sar;
+
+ /* Schedule index. */
+ uint sched_index;
+ /* Pbproc activate. */
+ bool pbproc_activate;
+
+ cyg_handle_t sched_handle;
+ cyg_thread sched_thread;
+
+ /** Used to memorize the list of TEI inserted in the mac_Store to remove it
+ * in the future.
+ */
+ list_t tei_list;
+ /** create schedule only on CCo side */
+ bool create_schedule;
+ /** beacon alloc type: 0 csma only,1 mixed csma & tdma */
+ uint beacon_alloc_type;
+ /** mfs global type, csma or tdma */
+ uint mfs_cfp;
+ /** number of stations */
+ uint num_station;
+ /** type of tdma fill */
+ uint tdma_fill;
+};
+typedef struct station_test_t station_test_t;
+
+
+u8 mme_buffer [2048] __attribute__((aligned (2048)));
+u8 sched_stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
+
+//----------------------------------------------------------------------------
+static station_test_t station_test = {.num_station = 5, .tdma_fill=0};
+
+void tx_beacon_init (void);
+
+/****************** CALL BACKS DEFINITION ****************/
+
+/**
+ * Call back called by the SAR each time a packet is segmented.
+ * In this test it will only display a message.
+ * The buffer is a static buffer not a allocated one it does not need to be
+ * freed.
+ *
+ * \param user, User data
+ * \param buffer the address of the buffer.
+ */
+void sar_segmentation_ul_done (void *user, u8* buffer, void *cl_data)
+{
+ printf ("******************************************\n");
+ printf (" sar Segmentation done\n \n");
+ printf ("******************************************\n");
+}
+
+/**
+ * Implementation of the sar_reassembly_done_cb_t call back.
+ * Only used in this test.
+ * The buffer and the mfs shall be release.
+ *
+ * \param user, User data
+ * \param buffer the buffer address containing the data
+ * \param length the data length
+ * \param mfs the mfs used
+ */
+void sar_reassembly_ul_done (void *user, u8* buffer, uint length,
+ mfs_rx_t *mfs, bool encrypted)
+{
+ dbg_assert (buffer);
+ dbg_assert (length >= 60 && length <= 1518);
+ dbg_assert (mfs);
+
+ printf ("******************************************\n");
+ printf (" sar Reassembly done\n \n");
+ printf ("******************************************\n");
+
+ free (buffer);
+
+ blk_print_memory ();
+}
+
+/**
+ * Implementation of the sar_reassembly_done_cb_t call back.
+ * Only used in this test.
+ * The buffer and the mfs shall be release.
+ *
+ * \param user, User data
+ * \param buffer the buffer address containing the data
+ * \param length the data length
+ * \param mfs the mfs used
+ */
+void sar_reassembly_mme_done (void *user, u8* buffer, uint length,
+ mfs_rx_t *mfs, bool encrypted)
+{
+ dbg_assert (buffer);
+ dbg_assert (length >= 60 && length <= 1518);
+ dbg_assert (mfs);
+
+ printf ("******************************************\n");
+ printf (" sar Reassembly MME done\n");
+ printf ("******************************************\n");
+
+ sar_mme_buffer_add (station_test.sar, buffer);
+
+ blk_print_memory ();
+}
+
+// ---------------------------- Station functions --------------------------
+
+/**
+ * Add a link to the STAtion i.e. will create a MFS
+ *
+ * \param ctx the station context.
+ * \param type TX or RX link, it is a short 1 for TX 0 for RX.
+ * \param bcast short indicating if the link is a broadcast link
+ * \param mme short indicating if the link will be use to transmit MMEs
+ * \param lid short indicating if it is a link identitier.
+ * \param tei short the destination station.
+ */
+void station_test_link_add (station_test_t *ctx, uint type, uint bcast,
+ uint mme, uint lid, uint tei)
+{
+ bool added;
+ mfs_t *mfs;
+ sta_t *sta;
+
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_store);
+ dbg_assert (ctx->sar);
+
+ if (MAC_TEI_IS_STA (tei))
+ {
+ mac_store_sta_add (ctx->mac_store, tei);
+ sta = mac_store_sta_get (ctx->mac_store, tei);
+ sta->authenticated = true;
+ blk_release (sta);
+ }
+
+ mfs = mac_store_mfs_add (ctx->mac_store, type, bcast, mme, lid, tei,
+ &added);
+ dbg_assert (added);
+ /* impose tdma mfs with cfp = true */
+ if (station_test.mfs_cfp && mfs->common.tx)
+ mfs->tx.cfp = true;
+
+ // add the link to the sar.
+ sar_mfs_add (ctx->sar, mfs);
+
+ /* Authenticated the station. */
+
+ blk_release (mfs);
+}
+
+/**
+ * Inject SOUND frame
+ *
+ * \param ctx the station context.
+ * \param tei short the destination station.
+ */
+void station_test_sound_set (station_test_t *ctx, uint tei)
+{
+ sta_t *sta;
+
+ dbg_assert (ctx);
+
+ if (MAC_TEI_IS_STA (tei))
+ {
+ sta = mac_store_sta_get (ctx->mac_store, tei);
+ sta->tx_tonemaps->default_tmi = TONEMAP_INDEX_INITIAL_START;
+ blk_release (sta);
+ }
+
+ phy_chandata_conf_t chandata_conf[1] =
+ {
+ {.type =PHY_CHANDATA_TYPE_NRJ_SYMBOL, .last = 1},
+ };
+ pbproc_set_chandata_conf (
+ ctx->pbproc, (phy_chandata_conf_t *) chandata_conf, 1);
+
+}
+
+/**
+ * Remove a link to the STAtion i.e. will create a MFS
+ *
+ * \param ctx the station context.
+ * \param type TX or RX link, it is a short 1 for TX 0 for RX.
+ * \param bcast short indicating if the link is a broadcast link
+ * \param mme short indicating if the link will be use to transmit MMEs
+ * \param lid short indicating if it is a link identitier.
+ * \param tei short the destination station.
+ */
+void station_test_link_remove (station_test_t *ctx, uint type, uint bcast,
+ uint mme, uint lid, uint tei)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->mac_store);
+ dbg_assert (ctx->sar);
+ dbg_assert (MAC_TEI_IS_STA (tei));
+
+ sar_sta_remove (ctx->sar, tei);
+}
+
+/* creation of false scheduling */
+void
+test_prepare_tdma_alloc_random(pbproc_t *ctx, uint max_length_tck,
+ uint num_station)
+{
+ lib_rnd_t rnd[1];
+ lib_rnd_init (rnd, 1234);
+ ca_eoc_sched_t * alloc = &ctx->ca->ca_eoc_sched;
+ alloc->toggle = 0;
+ int j;
+ for (j = 0; j < 2; j++)
+ {
+ alloc->record_nb[j] = (64/num_station)*num_station;
+ alloc->record_curr[j] = alloc->record_nb[j] - 1;
+ uint i;
+ uint fixed_clk = MAC_RIFS_DEFAULT_TCK
+ + MAC_PREAMBLE_TCK + 2 * MAC_FC_AV_TCK;
+ for (i=0; i < alloc->record_nb[j]; i++)
+ {
+ int ob = (i%(station_test.num_station+1));
+
+ if (ob)
+ {
+ alloc->sched_record[j][i].tei = 5 + ob - 1;
+ alloc->sched_record[j][i].lid = 1;
+ }
+ else
+ {
+ alloc->sched_record[j][i].tei = 0xFF;
+ alloc->sched_record[j][i].lid = 0;
+ }
+
+ alloc->sched_record[j][i].cco_tx_duration = fixed_clk
+ + MAC_PAYLOAD_TCK (30+lib_rnd_uniform (rnd, 20),
+ MAC_DX417_TCK);
+
+ switch (station_test.tdma_fill)
+ {
+ case 0:
+ alloc->sched_record[j][i].sta_tx_duration = lib_rnd_uniform(rnd, 5) ?
+ fixed_clk + MAC_PAYLOAD_TCK (30+lib_rnd_uniform (rnd, 20),
+ MAC_DX417_TCK) : 0;
+ break;
+ case 1:
+ alloc->sched_record[j][i].sta_tx_duration = 0;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * Create a schedule for the Channel Access (beacon period) in CSMA only mode.
+ * Shall always be used to send or receive data.
+ *
+ * \param int_sta the pbproc context
+ * \param beacon_period_nb the quantity of beacon periods for the test.
+ */
+void create_schedule_csma_only (station_test_t *int_sta, uint beacon_period_nb)
+{
+ pbproc_t *pbproc;
+
+ dbg_assert (int_sta);
+
+ pbproc = int_sta->pbproc;
+ ca_beacon_period_t beacons_periods[beacon_period_nb];
+ uint i;
+
+ dbg_assert (pbproc);
+ dbg_assert (beacon_period_nb < CA_BEACON_PERIOD_NB);
+
+ /* Get and fill the schedule */
+ ca_schedule_t *sched = ca_alloc_get_schedule (pbproc_get_ca (pbproc),
+ int_sta->sched_index);
+
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = int_sta->snid;
+ sched->nek_switch = 0; //TODO
+ sched->allocations_nb = 1;
+ sched->allocations[0].end_offset_tck = 10000000;
+ sched->allocations[0].glid = 0xff;
+
+ /* Create a schedule for 14 beacon period */
+ for (i = 0; i < beacon_period_nb; i++)
+ {
+ beacons_periods[i].start_date = 1000000 * i
+ + my_station.current_tick_tck;
+ beacons_periods[i].schedule_index = int_sta->sched_index;
+ }
+
+ /* Use the new schedule */
+ ca_alloc_update_beacon_periods (pbproc_get_ca (pbproc), beacons_periods,
+ beacon_period_nb);
+
+ /* Activate the pbproc */
+ if (!int_sta->pbproc_activate)
+ {
+ pbproc_activate (pbproc, true);
+ int_sta->pbproc_activate = true;
+ }
+
+ int_sta->sched_index++;
+}
+
+void create_schedule_mixed_csma_tdma(station_test_t *int_sta,
+ uint beacon_period_nb, uint beacon_type)
+{
+ pbproc_t *pbproc;
+
+ dbg_assert (int_sta);
+
+ pbproc = int_sta->pbproc;
+ ca_beacon_period_t beacons_periods[beacon_period_nb];
+ uint i;
+
+ dbg_assert (pbproc);
+ dbg_assert (beacon_period_nb < CA_BEACON_PERIOD_NB);
+
+ /* Get and fill the schedule */
+ ca_schedule_t *sched = ca_alloc_get_schedule (pbproc_get_ca (pbproc),
+ int_sta->sched_index);
+
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = int_sta->snid;
+ sched->nek_switch = 0; //TODO
+ /* create scheduling only on CCo side. */
+ switch (beacon_type)
+ {
+ case 1:
+ sched->allocations_nb = 3;
+ sched->allocations[0].end_offset_tck = 100000;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[2].end_offset_tck = 1000000;
+ sched->allocations[2].glid = MAC_LID_CFPI;
+ sched->allocations[1].end_offset_tck = 200000;
+ sched->allocations[1].glid = MAC_LID_LOCAL_CSMA;
+ break;
+ case 2:
+ sched->allocations_nb = 2;
+ sched->allocations[0].end_offset_tck = 100000;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[1].end_offset_tck = 500000;
+ sched->allocations[1].glid = MAC_LID_CFPI;
+ break;
+ case 3:
+ sched->allocations_nb = 2;
+ sched->allocations[0].end_offset_tck = 100000;
+ sched->allocations[0].glid = MAC_LID_SPC_CENTRAL;
+ sched->allocations[1].end_offset_tck = 500000;
+ sched->allocations[1].glid = MAC_LID_LOCAL_CSMA;
+ break;
+ }
+ /* Create a schedule for 14 beacon period */
+ for (i = 0; i < beacon_period_nb; i++)
+ {
+ beacons_periods[i].start_date = 1000000 * i
+ + my_station.current_tick_tck;
+ beacons_periods[i].schedule_index = int_sta->sched_index;
+ }
+
+ /* Use the new schedule */
+ ca_alloc_update_beacon_periods (pbproc_get_ca (pbproc), beacons_periods,
+ beacon_period_nb);
+
+ /* Activate the pbproc */
+ if (!int_sta->pbproc_activate)
+ {
+ pbproc_activate (pbproc, true);
+ int_sta->pbproc_activate = true;
+ }
+
+ int_sta->sched_index++;
+}
+
+/**
+ * Thread entry finction
+ *
+ * \param int_sta the sta context.
+ */
+void pbproc_sched (cyg_addrword_t int_sta)
+{
+ station_test_t *station_test;
+ station_test = (station_test_t *) int_sta;
+ uint beacon_type = station_test->beacon_alloc_type;
+ while (true)
+ {
+ switch (beacon_type)
+ {
+ case 0:
+ create_schedule_csma_only (station_test, 14);
+ station_test->sched_index ++;
+ //create the second schedule.
+ create_schedule_csma_only (station_test, 14);
+ station_test->sched_index ++;
+ //create the third schedule.
+ create_schedule_csma_only (station_test, 14);
+ station_test->sched_index ++;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ create_schedule_mixed_csma_tdma (station_test, 14, beacon_type);
+ station_test->sched_index ++;
+ //create the second schedule.
+ create_schedule_mixed_csma_tdma (station_test, 14, beacon_type);
+ station_test->sched_index ++;
+ //create the third schedule.
+ create_schedule_mixed_csma_tdma (station_test, 14, beacon_type);
+ station_test->sched_index ++;
+ break;
+ default:
+ printf ("Not implemented type %d\n", beacon_type);
+ }
+ cyg_thread_delay (500);
+ }
+}
+
+
+/**
+ * Provides the Tei of the STA and the SNID
+ *
+ * \param ctx the station context
+ * \param tei the tei of the station
+ * \param snid the snid of the AVLN
+ * \param beacon_period_auto generation automatic of the beacon period for
+ * the CA scheduling
+ * \param cco boolean informing if the sta is cco or not
+ * \param authenticated boolean informing if the sta is authenticated or
+ * not.
+ */
+void station_test_config (station_test_t *ctx, uint tei, uint snid,
+ bool beacon_period_auto, mac_t mac_addr)
+{
+ dbg_assert (ctx);
+
+ ctx->snid = snid;
+ ctx->mac_config.tei = tei;
+ ctx->create_schedule = MAC_TEI_IS_EOC_CCO(ctx->mac_config.tei);
+
+ if (mac_addr == 0)
+ {
+ ctx->mac_config.sta_mac_address = 0x123456789abcull;
+ }
+ else
+ ctx->mac_config.sta_mac_address = mac_addr;
+
+ tx_beacon_init ();
+
+ if (ctx->create_schedule)
+ test_prepare_tdma_alloc_random (ctx->pbproc, 100000,
+ ctx->num_station);
+ if (beacon_period_auto)
+ {
+ // Create the Thread for the pbproc.
+ cyg_thread_create (9, &pbproc_sched, (cyg_addrword_t) ctx, "Sched",
+ sched_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL,
+ &ctx->sched_handle, &ctx->sched_thread);
+ cyg_thread_resume (ctx->sched_handle);
+ }
+
+ sar_mme_buffer_add (ctx->sar, mme_buffer);
+ sar_activate (ctx->sar, true);
+}
+
+/**
+ * Provides the TEI of all the station in the AVLN.
+ *
+ * \param ctx the station context.
+ * \param tei the tei list of the stations
+ * \param qte the quantity of TEIs in the list.
+ */
+void station_test_discover (station_test_t *ctx, uint *tei,
+ uint qte)
+{
+ tei_node_t *node;
+ uint i;
+
+ for (i = 0; i < qte; i++)
+ {
+ if (tei[i] != 0)
+ {
+ node = blk_alloc ();
+ list_init_node (&node->node);
+ node->tei = tei[i];
+ list_push (&ctx->tei_list, &node->node);
+
+ mac_store_sta_add (ctx->mac_store, tei[i]);
+ }
+ }
+}
+
+
+// ---------------------------- Function calls -----------------------------
+void
+tx_beacon_uninit (void);
+
+/** Uninitialise the function
+ */
+int fc_station_uninit (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint i;
+ sar_activate (station_test.sar, false);
+ pbproc_activate (station_test.pbproc, false);
+
+ for (i = MAC_TEI_STA_MIN; MAC_TEI_IS_STA (i); i++)
+ sar_sta_remove (station_test.sar, i);
+
+ tx_beacon_uninit();
+
+ sar_uninit (station_test.sar);
+ pbproc_uninit (station_test.pbproc);
+ mac_store_uninit (station_test.mac_store);
+
+ blk_print_memory ();
+
+ return true;
+}
+
+/** Insert sound frame
+ */
+int fc_station_insert_sound (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei = 0;
+
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+
+ station_test_sound_set(&station_test, tei);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/** Creates a link in the STA.
+ *
+ * - dtei the tei of the station.
+ * - fw forward link
+ * - rw reverse link
+ * - bcast broadcast.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_add_mme_link (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint dtei = 0;
+ uint fw = 0;
+ uint rw = 0;
+ uint bcast = 0;
+
+ mfs_tx_t *mfs_tx;
+ mfs_rx_t *mfs_rx;
+ bool added;
+
+ fcall_param_bind_short (*param, *msg, "dtei", &dtei);
+ fcall_param_bind_short (*param, *msg, "fw", &fw);
+ fcall_param_bind_short (*param, *msg, "rw", &rw);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+
+ fcall_param_reset (*param);
+
+ if (fw)
+ {
+ mfs_tx = mac_store_mfs_add_tx (station_test.mac_store, bcast, true, MAC_LID_NONE, dtei, &added);
+
+ if (mfs_tx == NULL)
+ return false;
+
+ sar_mfs_add (station_test.sar, (mfs_t *) mfs_tx);
+ blk_release (mfs_tx);
+ }
+
+ if (rw)
+ {
+ mfs_rx = mac_store_mfs_add_rx (station_test.mac_store, bcast, true, MAC_LID_NONE, dtei, &added);
+
+ if (mfs_rx == NULL)
+ return false;
+
+ sar_mfs_add (station_test.sar, (mfs_t *) mfs_rx);
+ blk_release (mfs_rx);
+ }
+
+ return true;
+}
+
+/** Initialise the station parameters data as the mac address the tei.
+ *
+ * - stei.
+ * - mac_addr.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_config (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint stei = 0;
+ mac_t mac_address = 0;
+
+ fcall_param_bind_short (*param, *msg, "stei", &stei);
+ fcall_param_bind (*param, *msg, "mac_addr", sizeof(mac_t), &mac_address);
+
+ station_test.mac_config.sta_mac_address = mac_address;
+ station_test.mac_config.tei = stei;
+ station_test.mac_config.authenticated = true;
+ sar_activate (station_test.sar, true);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+int fc_station_config_bt (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint beacon_alloc_type=0;
+ uint mfs_cfp=0;
+
+ fcall_param_bind_short (*param, *msg, "beacon_alloc_type",
+ &beacon_alloc_type);
+ fcall_param_bind_short (*param, *msg, "mfs_cfp",
+ &mfs_cfp);
+
+ station_test.beacon_alloc_type = beacon_alloc_type;
+ station_test.mfs_cfp = mfs_cfp;
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/** Prepare the station to work.
+ * It will create default schedules for the Channel Access in CSMA-only mode
+ * and activate the pbproc to start the communication with the others
+ * stations.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_start (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ ca_beacon_period_t beacons_periods[4];
+ uint i;
+
+ /* Get and fill the schedule */
+ ca_schedule_t *sched = ca_alloc_get_schedule (pbproc_get_ca (station_test.pbproc),0);
+
+ sched->coexistence_mode = MAC_COEXISTENCE_SHARED_CSMA_HYBRID_MODE;
+ sched->snid = station_test.snid;
+ sched->nek_switch = 0; //TODO
+ sched->allocations_nb = 1;
+ sched->allocations[0].end_offset_tck = BITS_ONES (24);
+ sched->allocations[0].glid = 0xff;
+
+ /* Create a schedule for 14 beacon period */
+ for (i = 0; i < 4; i++)
+ {
+ beacons_periods[i].start_date = BITS_ONES(24) * i
+ + my_station.current_tick_tck;
+ beacons_periods[i].schedule_index = 0;
+ }
+
+ /* Use the new schedule */
+ ca_alloc_update_beacon_periods (pbproc_get_ca (station_test.pbproc), beacons_periods,
+ 4);
+
+ /* Only run this one !!! */
+ pbproc_activate (station_test.pbproc, true);
+
+ return true;
+}
+
+/**
+ * Add a link to the Station in order to receive or transmit data.
+ *
+ * - type TX or RX link, it is a short 1 for TX 0 for RX.
+ * - bcast short indicating if the link is a broadcast link
+ * - mme short indicating if the link will be use to transmit MMEs
+ * - lid short indicating if it is a link identitier.
+ * - tei short the destination station.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_link_add (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint type;
+ uint bcast;
+ uint mme;
+ uint lid;
+ uint tei;
+
+ type = 0;
+ bcast = 0;
+ mme = 0;
+ lid = 0;
+ tei = 0;
+
+ fcall_param_bind_short (*param, *msg, "type", &type);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+ fcall_param_bind_short (*param, *msg, "mme", &mme);
+ fcall_param_bind_short (*param, *msg, "lid", &lid);
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+
+ if (type)
+ printf (
+ "[STATION : %d] TX link added, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+ else
+ printf (
+ "[STATION : %d] RX link added, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+
+ if (!mme && !bcast) /* for rx only ordinary traffic is received */
+ station_test_link_add (&station_test, 0, bcast, mme, lid, tei);
+
+ station_test_link_add (&station_test, 1, bcast, mme, lid, tei);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Remove a link to the Station in order to receive or transmit data.
+ *
+ * - type TX or RX link, it is a short 1 for TX 0 for RX.
+ * - bcast short indicating if the link is a broadcast link
+ * - mme short indicating if the link will be use to transmit MMEs
+ * - lid short indicating if it is a link identitier.
+ * - tei short the destination station.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_link_remove (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint type;
+ uint bcast;
+ uint mme;
+ uint lid;
+ uint tei;
+
+ type = 0;
+ bcast = 0;
+ mme = 0;
+ lid = 0;
+ tei = 0;
+
+ fcall_param_bind_short (*param, *msg, "type", &type);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+ fcall_param_bind_short (*param, *msg, "mme", &mme);
+ fcall_param_bind_short (*param, *msg, "lid", &lid);
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+
+ if (type)
+ printf (
+ "[STATION : %d] TX link removed, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+ else
+ printf (
+ "[STATION : %d] RX link removed, bcast : %d, mme : %d, lid : %d, tei : %d\n",
+ station_test.mac_config.tei, bcast, mme, lid, tei);
+
+ station_test_link_remove (&station_test, 0, bcast, mme, lid, tei);
+ station_test_link_remove (&station_test, 1, bcast, mme, lid, tei);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Initialize the number of STAs
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_num_station (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint num_station=0;
+
+ fcall_param_bind_short (*param, *msg, "num_station", &num_station);
+
+ station_test.num_station = num_station;
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Initialize the configuration of the STA.
+ * The parameters we must provide are the TEI of the STA, the SNID and the
+ * boolean to indicate the auto generation of the beacon periods.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei;
+ uint snid;
+ uint beacon_period_auto;
+ mac_t mac;
+
+ tei = 0;
+ snid = 0;
+ beacon_period_auto = 0;
+
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+ fcall_param_bind_short (*param, *msg, "snid", &snid);
+ fcall_param_bind_short (*param, *msg, "auto_sched", &beacon_period_auto);
+
+ station_test_config (&station_test, tei, snid, beacon_period_auto, mac);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Configure type of MFS-s used in script: 0 ordinary (CSMA), 1 (TDMA)
+ * Configure allocations in beacon period.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config_bt (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint beacon_alloc_type=0;
+ uint mfs_cfp=0;
+
+ fcall_param_bind_short (*param, *msg, "beacon_alloc_type",
+ &beacon_alloc_type);
+ fcall_param_bind_short (*param, *msg, "mfs_cfp",
+ &mfs_cfp);
+
+ station_test.beacon_alloc_type = beacon_alloc_type;
+ station_test.mfs_cfp = mfs_cfp;
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Add a data buffer to the SAR.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_sar_data_buffer_add (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ u8 *buffer;
+
+ buffer = (u8*) malloc (2048 * sizeof(u8));
+ sar_data_buffer_add (station_test.sar, buffer);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Add Msdu to send
+ *
+ * - lid the link to use
+ * - tei the destination
+ * - bcast if the link is a bcast link
+ * - mme if it is a mme
+ * - buffer the buffer containing a frame
+ * - length the buffer length
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_sar_msdu_add (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei;
+ uint lid;
+ uint bcast;
+ uint mme;
+ uint length;
+ u8 *buffer;
+
+ mfs_tx_t *mfs;
+
+ tei = 0;
+ lid = 0;
+ bcast = 0;
+ mme = 0;
+ length = 0;
+
+ fcall_param_bind_short (*param, *msg, "tei", &tei);
+ fcall_param_bind_short (*param, *msg, "lid", &lid);
+ fcall_param_bind_short (*param, *msg, "bcast", &bcast);
+ fcall_param_bind_short (*param, *msg, "mme", &mme);
+ fcall_param_bind_short (*param, *msg, "length", &length);
+
+ buffer = (u8 *) malloc (length * sizeof (length));
+ fcall_param_bind (*param, *msg, "buffer", length * sizeof(u8), buffer);
+
+ mfs = mac_store_mfs_get_tx (station_test.mac_store, bcast, mme, lid, tei);
+ dbg_assert (mfs);
+
+ sar_msdu_add (station_test.sar, buffer, length, mfs, NULL,
+ mac_ntb());
+
+ blk_release (mfs);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+mfs_tx_t * beacon_mfs = NULL;
+u32 user_data;
+
+/**
+ * Stub to inform that beacon is received.
+ *
+ */
+void
+cp_beacon_add (void *user_data, pb_beacon_t *beacon,
+ pbproc_rx_beacon_params_t *params);
+
+/**
+ * Init parameters for beacon sending and receiving.
+ *
+ */
+void
+tx_beacon_init (void)
+{
+ bool added;
+ beacon_mfs = mac_store_mfs_add_tx (station_test.mac_store, true, false,
+ MAC_LID_SPC_CENTRAL, MAC_TEI_BCAST, &added);
+ dbg_assert(added);
+ beacon_mfs->beacon = true;
+ ca_mfs_update(pbproc_get_ca (station_test.pbproc), beacon_mfs);
+ sar_init_beacon_cb (station_test.sar, &user_data, cp_beacon_add);
+}
+
+/**
+ * Remove allocated beacon mfs.
+ *
+ */
+void
+tx_beacon_uninit (void)
+{
+ ca_mfs_remove(pbproc_get_ca (station_test.pbproc), beacon_mfs);
+ mac_store_mfs_remove (station_test.mac_store, (mfs_t*) beacon_mfs);
+
+ if (beacon_mfs->seg_nb)
+ blk_release_desc_range_nb ((blk_t *) beacon_mfs->head,
+ beacon_mfs->seg_nb);
+ blk_release (beacon_mfs);
+}
+
+/**
+ * Insert beacon. Insert one fake PB into mfs and update mfs heap.
+ * due to priority beacon mfs will be first to send in SCP_CENTRAL part to
+ * send one PB (beacon) to network.
+ *
+ */
+void
+tx_beacon_insert (void)
+{
+ pb_beacon_t *pb = PARENT_OF (pb_beacon_t, blk, blk_alloc_desc ());
+ pbproc_tx_beacon_params_t params = {
+ { 0x0123, 0x4242, 0xabab, 0x5555 }, pb->data + 123
+ };
+ pbproc_mfs_beacon_prepare (station_test.pbproc, beacon_mfs, pb, &params);
+ /* insert into list of mfs-s. */
+ ca_mfs_update(pbproc_get_ca (station_test.pbproc), beacon_mfs);
+}
+
+/**
+ * Interface: Call beacon init function.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config_bc (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ fcall_param_reset (*param);
+ return true;
+}
+
+/**
+ * Interface: Call beacon insert function.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_init_config_bc_insert (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+
+ tx_beacon_insert();
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * Provide to the STA using the parameters of the function call the station
+ * use for the test. Each STA shall known the TEI of the others present in the
+ * AVLN.
+ *
+ * The function call parameters must be
+ * - qte the quantity of TEIs present in the paramters. One for each STA
+ * without this one.
+ * - tei The list of TEIs.
+ * - mac the list of mac address.
+ *
+ * This will be use to add the STA's to the mac store, the STA will keep a
+ * list of theses TEI to remove the STA during the uninit procedure.
+ *
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_station_discover (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ uint tei[256];
+ mac_t macs[256];
+ uint qte;
+ char val [2];
+ char id[5];
+ uint count;
+ uint error;
+
+ qte = 0;
+ fcall_param_bind_short (*param, *msg, "qte", &qte);
+
+ count = 0;
+ error = 0;
+ for (count = 0; count < qte; count ++)
+ {
+ tei[count] = 0;
+ macs[count] = 0;
+ sprintf (val, "%d", count);
+ strcpy (id, "tei");
+ strcat (id, val);
+ fcall_param_bind_short (*param, *msg, id, &tei[count]);
+ }
+
+ station_test_discover (&station_test, tei, qte);
+
+ fcall_param_reset (*param);
+
+ return true;
+}
+
+/**
+ * print the sar traces for the tests.
+ * if the trace_config == y the traces are printed to the stdio.
+ * otherwise nothing is printed.
+ *
+ * \param fcall the fcall context.
+ * \param param the fcall param
+ * \param msg the message
+ * \param data anything
+ */
+int fc_sar_print_trace (fcall_ctx_t *fcall, fcall_param_t **param,
+ sci_msg_t **msg, void *data)
+{
+ fcall_param_reset (*param);
+
+ sar_trace_print (station_test.sar);
+ /* trace_buffer_dbg_dump (&station_test.pbproc->trace);
+ trace_buffer_dbg_dump (&station_test.pbproc->ca->trace); */
+
+ return true;
+}
+
+
+// ---------------------------- Stub functions ----------------------------
+
+/**
+ * CE measurements. To be replace by the CE function to get the measurements
+ *
+ * Pb measurement RX callback for Channel estimation.
+ * This call back will return one or two block in order to insert all the
+ * measurements contained in each PB of the mpdu received.
+ * Two cases can happen, the first the pb_nb is lesser than the blk capacity,
+ * this callback will return only a blk pointed by the first and the last
+ * pointer.
+ * In the second case the quantity of PB are greater than one blk capacity, this
+ * callback will return two blk (chained) the first pointed by the first pointer
+ * and the last one by the last pointer.
+ *
+ * \param user User data
+ * \param rx_params Frame control information to know date and tonemap used
+ * \param number of pbs
+ * \param first blk to insert the measurements.
+ * \param last blk to insert the measurements.
+ * \param chandata chan data measurements
+ *
+ * \return boolean to indicate if a block had been returned or not.
+ */
+bool ce_measurements (void *user, pbproc_rx_params_t *rx_params, uint pb_nb,
+ blk_t **first, blk_t **last, pb_t *chandata, uint nb_chandata, uint
+ *blk_offset)
+{
+ dbg_assert (rx_params);
+
+ if (chandata)
+ {
+ blk_release_desc_range_nb ((blk_t *) chandata, nb_chandata);
+ }
+
+ return false;
+}
+
+
+/**
+* CP receives a new MME.
+* \param user_data the data registered by the actor in the init function.
+* \param mfs the mfs
+* \param buffer the buffer containing the MME.
+* \param length the MME length
+* \param mme_recv data use by the data plane.
+* \param encryption inform if the packet comes from the PWL if it had been
+* crypted or not.
+*/
+void
+cp_mme_recv (void *user_data, mfs_rx_t *mfs, u8 *buffer, uint length,
+ bool mme_recv, bool encryption)
+{
+ printf ("/*************************************************/\n");
+ printf ("/ STATION : %d Receive a MME **********/\n",
+ station_test.mac_config.tei);
+ printf ("/ MME length : %d **********/\n", length);
+ printf ("/ MME encrypted : %d **********/\n",
+ encryption);
+ printf ("/*************************************************/\n");
+}
+
+/**
+* CP receives a beacon.
+* \param user_data the data registered by the actor in the init function.
+* \param beacon the beacon freshly received.
+*/
+void
+cp_beacon_add (void *user_data, pb_beacon_t *beacon,
+ pbproc_rx_beacon_params_t *params)
+{
+ printf ("/*************************************************/\n");
+ printf ("/ STATION : %d Receive a beacon ********/\n",
+ station_test.mac_config.tei);
+ printf ("/*************************************************/\n");
+
+
+ // release the beacon.
+ blk_release_desc ((blk_t *) beacon);
+}
+
+// -------------------------------------------------------------------------
+
+
+/** Cesar init function as described in the wiki
+ * http://pessac/cesar/trac/wiki/20071128Cesar#LEONcore
+ */
+void
+cesar_init (void)
+{
+ // Initialise the trace system.
+ trace_init ();
+
+ // Initialise the mac_store.
+ station_test.mac_store = mac_store_init ();
+
+ // Initialise the mac config.
+ mac_config_init (&station_test.mac_config);
+
+ // Intialise the pbproc.
+ station_test.pbproc = pbproc_init (&station_test.mac_config,
+ station_test.mac_store);
+
+ // Initialise the mac ntb.
+ mac_ntb_init (pbproc_get_phy(station_test.pbproc), &station_test.mac_config);
+
+ // Initialise the SAR.
+ station_test.sar = sar_init (station_test.mac_store, station_test.pbproc,
+ pbproc_get_ca (station_test.pbproc),
+ station_test.mac_config.seed);
+
+ // init the variables of the station.
+ station_test.pbproc_activate = false;
+ station_test.sched_index = 0;
+}
+
+
+/* ---------------------- Main function -------------------*/
+int
+cyg_user_start (void)
+{
+ cesar_init ();
+
+ station_log_set_level(&my_station, STATION_LOG_DEBUG);
+ my_station.pipe_log_fd = 1;
+
+ fcall_register (my_station.fcall, "fc_station_link_add",
+ &fc_station_link_add, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_link_remove",
+ &fc_station_link_remove, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_config",
+ &fc_station_init_config, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_config_bt",
+ &fc_station_config_bt, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_data_buffer_add",
+ &fc_sar_data_buffer_add, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_mme_buffer_add",
+ &fc_sar_data_buffer_add, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_msdu_add", &fc_sar_msdu_add,
+ NULL);
+
+ fcall_register (my_station.fcall, "fc_station_discover",
+ &fc_station_discover, NULL);
+
+ fcall_register (my_station.fcall, "fc_add_mme_link",
+ &fc_add_mme_link , NULL);
+
+ fcall_register (my_station.fcall, "fc_station_config",
+ &fc_station_config, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_start",
+ &fc_station_start, NULL);
+
+ fcall_register (my_station.fcall, "fc_sar_print_trace",
+ &fc_sar_print_trace, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_uninit",
+ &fc_station_uninit, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_insert_sound",
+ &fc_station_insert_sound, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_num_station",
+ &fc_station_init_num_station, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_config_bc_insert",
+ &fc_station_init_config_bc_insert, NULL);
+
+ fcall_register (my_station.fcall, "fc_station_init_config_bc",
+ &fc_station_init_config_bc, NULL);
+
+ sar_init_data_context (station_test.sar, station_test.sar);
+ sar_init_mme_context (station_test.sar, station_test.sar);
+
+ sar_init_segmentation_data_cb (station_test.sar, sar_segmentation_ul_done);
+ sar_init_segmentation_mme_cb (station_test.sar, sar_segmentation_ul_done);
+ sar_init_reassembly_data_cb (station_test.sar, sar_reassembly_ul_done);
+ sar_init_reassembly_mme_cb (station_test.sar, sar_reassembly_mme_done);
+
+ sar_init_measure_context (station_test.sar, &station_test.sar);
+ sar_init_measurement_cb (station_test.sar, ce_measurements);
+
+ return 0;
+}
+
+void test_print_trace(void)
+{
+ sar_trace_print (station_test.sar);
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&station_test.pbproc->trace);
+ trace_buffer_dbg_dump (&station_test.pbproc->ca->trace);
+#endif
+}
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test1.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test1.py
new file mode 100644
index 0000000000..b035a588d2
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test1.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+
+maximus.wait (1000)
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test2.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test2.py
new file mode 100644
index 0000000000..db204117e8
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test2.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 2
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 1)
+fc1.add_param_ushort ("mme", 1)
+fc1.add_param_ushort ("lid", 248)
+fc1.add_param_ushort ("tei", 255)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 255)
+fc1.add_param_ushort ("lid", 248)
+fc1.add_param_ushort ("bcast", 1)
+fc1.add_param_ushort ("mme", 1)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+
+maximus.wait (1000)
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 255)
+fc1.add_param_ushort ("lid", 248)
+fc1.add_param_ushort ("bcast", 1)
+fc1.add_param_ushort ("mme", 1)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000000)
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 1)
+fc2.add_param_ushort ("mme", 1)
+fc2.add_param_ushort ("lid", 248)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta.py
new file mode 100644
index 0000000000..2823d2b6ac
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("beacon_alloc_type", 1)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+
+
+maximus.wait (10000000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_bc.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_bc.py
new file mode 100644
index 0000000000..6c104338f6
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_bc.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config_bc")
+fc1.set_sta (station1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config_bc")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("beacon_alloc_type", 1)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+for x in range(1, 5):
+ maximus.wait (990000)
+ fc1 = maximus.create_fcall ("fc_station_init_config_bc_insert")
+ fc1.set_sta (station1)
+ fc1.send()
+
+maximus.wait (100000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_csmaonly.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_csmaonly.py
new file mode 100644
index 0000000000..72fafc45c5
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2sta_csmaonly.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 3)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("beacon_alloc_type", 3)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2stasound.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2stasound.py
new file mode 100644
index 0000000000..2813fcea49
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_2stasound.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("beacon_alloc_type", 1)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+for x in range(1, 5):
+ fc1 = maximus.create_fcall ("fc_station_insert_sound")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5)
+ fc1.send()
+ fc2 = maximus.create_fcall ("fc_station_insert_sound")
+ fc2.set_sta (station2)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ maximus.wait (2000000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta.py
new file mode 100644
index 0000000000..7fbb1bb6b2
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta.py
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+stations = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+# TEI of station 2 will be 7
+station3 = maximus.create_sta()
+#station3.debug()
+
+# Init part for stations
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("beacon_alloc_type", 1)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc3 = maximus.create_fcall ("fc_station_config_bt")
+fc3.set_sta (station3)
+fc3.add_param_ushort ("beacon_alloc_type", 1)
+fc3.add_param_ushort ("mfs_cfp", 1)
+fc3.send()
+
+fc3 = maximus.create_fcall ("fc_station_init_config")
+fc3.set_sta (station3)
+fc3.add_param_ushort ("snid", 1)
+fc3.add_param_ushort ("tei", 7)
+fc3.add_param_ushort ("auto_sched", 1)
+fc3.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 7)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc3 = maximus.create_fcall ("fc_station_link_add")
+fc3.set_sta (station3)
+fc3.add_param_ushort ("type", 0)
+fc3.add_param_ushort ("bcast", 0)
+fc3.add_param_ushort ("mme", 0)
+fc3.add_param_ushort ("lid", 1)
+fc3.add_param_ushort ("tei", 1)
+fc3.send()
+
+fc3 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc3.set_sta (station3)
+fc3.send()
+
+fc3 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc3.set_sta (station3)
+fc3.send()
+
+# real work
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+for x in range(1, 5):
+ fc1 = maximus.create_fcall ("fc_station_insert_sound")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5)
+ fc1.send()
+ fc2 = maximus.create_fcall ("fc_station_insert_sound")
+ fc2.set_sta (station2)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ fc3 = maximus.create_fcall ("fc_station_insert_sound")
+ fc3.set_sta (station3)
+ fc3.add_param_ushort ("tei", 1)
+ fc3.send()
+ maximus.wait (2000000)
+
+# Clean part
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 7)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc3 = maximus.create_fcall ("fc_station_link_remove")
+fc3.set_sta (station3)
+fc3.add_param_ushort ("type", 0)
+fc3.add_param_ushort ("bcast", 0)
+fc3.add_param_ushort ("mme", 0)
+fc3.add_param_ushort ("lid", 1)
+fc3.add_param_ushort ("tei", 1)
+fc3.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
+
+print "\n************ STATION 3 TRACE ***************\n"
+fc3 = maximus.create_fcall ("fc_sar_print_trace")
+fc3.set_sta(station3)
+fc3.send();
+
+fc3 = maximus.create_fcall ("fc_station_uninit")
+fc3.set_sta(station3)
+fc3.send();
+
+station3.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta1bad.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta1bad.py
new file mode 100644
index 0000000000..a815f262a3
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_3sta1bad.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+station2 = maximus.create_sta()
+#station2.debug()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_config_bt")
+fc2.set_sta (station1)
+fc2.add_param_ushort ("beacon_alloc_type", 1)
+fc2.add_param_ushort ("mfs_cfp", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_station_init_config")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("snid", 1)
+fc2.add_param_ushort ("tei", 5)
+fc2.add_param_ushort ("auto_sched", 1)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 7)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_add")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc2.set_sta (station2)
+fc2.send()
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+maximus.wait (10000)
+
+fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("tei", 5)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("length", 106)
+f = open ('../../packet1','r')
+fc1.add_param ("buffer", f.read())
+fc1.send()
+
+for x in range(1, 5):
+ fc1 = maximus.create_fcall ("fc_station_insert_sound")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5)
+ fc1.send()
+ fc2 = maximus.create_fcall ("fc_station_insert_sound")
+ fc2.set_sta (station2)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ maximus.wait (2000000)
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 5)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_link_remove")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 0)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 1)
+fc1.add_param_ushort ("tei", 7)
+fc1.send()
+
+fc2 = maximus.create_fcall ("fc_station_link_remove")
+fc2.set_sta (station2)
+fc2.add_param_ushort ("type", 0)
+fc2.add_param_ushort ("bcast", 0)
+fc2.add_param_ushort ("mme", 0)
+fc2.add_param_ushort ("lid", 1)
+fc2.add_param_ushort ("tei", 1)
+fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ STATION 1 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+print "\n************ STATION 2 TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station2)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station2)
+fc1.send();
+
+station2.remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_multista.py b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_multista.py
new file mode 100644
index 0000000000..eb0397e39f
--- /dev/null
+++ b/cesar/test_general/maximus/integration/sar-pbproc-eoc/test_eoc_multista.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+
+import sys
+sys.path.append('../../../../maximus/python/obj');
+
+from interface import *
+from string import *
+from struct import *
+
+# Number of stations
+N = 10
+# Traffic type 1 = tx, 2 = rx ,3 = txrx
+TR_TYPE = 3
+# Use sound frames
+SOUND = 1
+# Mix dead stations
+MIX_DEAD = 0
+# Send mcast messages
+SEND_BCAST = 1
+
+# Init
+stations = range(0, N+1)
+
+maximus = Maximus()
+maximus.init (sys.argv + ['-e', './obj/sar-pbproc.elf'])
+
+# TEI of station 1 will be 1
+station1 = maximus.create_sta()
+#station1.debug()
+
+# TEI of station 2 will be 5
+for i in range(0, N):
+ stations[i] = maximus.create_sta()
+
+#stations[0].debug()
+
+# Init part for stations
+fc1 = maximus.create_fcall ("fc_station_init_num_station")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("num_station", N)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_config_bt")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("beacon_alloc_type", 1)
+fc1.add_param_ushort ("mfs_cfp", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_station_init_config")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("snid", 1)
+fc1.add_param_ushort ("tei", 1)
+fc1.add_param_ushort ("auto_sched", 1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc1.set_sta (station1)
+fc1.send()
+
+fc1 = maximus.create_fcall ("fc_sar_data_buffer_add")
+fc1.set_sta (station1)
+fc1.send()
+
+#Broadcast mfs
+fc1 = maximus.create_fcall ("fc_station_link_add")
+fc1.set_sta (station1)
+fc1.add_param_ushort ("type", 1)
+fc1.add_param_ushort ("bcast", 1)
+fc1.add_param_ushort ("mme", 0)
+fc1.add_param_ushort ("lid", 0)
+fc1.add_param_ushort ("tei", 255)
+fc1.send()
+
+#Ordinary mfs
+for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_station_link_add")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("type", 1)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("lid", 1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+
+for i in range(0, N):
+ fc2 = maximus.create_fcall ("fc_station_config_bt")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("beacon_alloc_type", 1)
+ fc2.add_param_ushort ("mfs_cfp", 1)
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_station_init_config")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("snid", 1)
+ fc2.add_param_ushort ("tei", 5+i)
+ fc2.add_param_ushort ("auto_sched", 1)
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_station_link_add")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("type", 0)
+ fc2.add_param_ushort ("bcast", 0)
+ fc2.add_param_ushort ("mme", 0)
+ fc2.add_param_ushort ("lid", 1)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+ fc2.set_sta (stations[i])
+ fc2.send()
+
+ fc2 = maximus.create_fcall ("fc_sar_data_buffer_add")
+ fc2.set_sta (stations[i])
+ fc2.send()
+
+# real work
+for x in range(1, 5):
+ for i in range(0, N):
+ if SOUND:
+ fc1 = maximus.create_fcall ("fc_station_insert_sound")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+
+ fc2 = maximus.create_fcall ("fc_station_insert_sound")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ if SEND_BCAST:
+ fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 255)
+ fc1.add_param_ushort ("lid", 0)
+ fc1.add_param_ushort ("bcast", 1)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("length", 106)
+ f = open ('../../packet1','r')
+ fc1.add_param ("buffer", f.read())
+ f.close()
+ fc1.send()
+ if TR_TYPE & 1:
+ for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.add_param_ushort ("lid", 1)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("length", 106)
+ f = open ('../../packet1','r')
+ fc1.add_param ("buffer", f.read())
+ f.close()
+ fc1.send()
+
+ if TR_TYPE & 2:
+ for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_sar_msdu_add")
+ fc1.set_sta (stations[i])
+ fc1.add_param_ushort ("tei", 1)
+ fc1.add_param_ushort ("lid", 1)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("length", 106)
+ f = open ('../../packet1','r')
+ fc1.add_param ("buffer", f.read())
+ f.close()
+ fc1.send()
+ maximus.wait (1000000)
+
+# Clean part
+for i in range(0, N):
+ fc1 = maximus.create_fcall ("fc_station_link_remove")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("type", 1)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("lid", 1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+ fc1 = maximus.create_fcall ("fc_station_link_remove")
+ fc1.set_sta (station1)
+ fc1.add_param_ushort ("type", 0)
+ fc1.add_param_ushort ("bcast", 0)
+ fc1.add_param_ushort ("mme", 0)
+ fc1.add_param_ushort ("lid", 1)
+ fc1.add_param_ushort ("tei", 5+i)
+ fc1.send()
+
+for i in range(0, N):
+ fc2 = maximus.create_fcall ("fc_station_link_remove")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("type", 0)
+ fc2.add_param_ushort ("bcast", 0)
+ fc2.add_param_ushort ("mme", 0)
+ fc2.add_param_ushort ("lid", 1)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+ fc2 = maximus.create_fcall ("fc_station_link_remove")
+ fc2.set_sta (stations[i])
+ fc2.add_param_ushort ("type", 1)
+ fc2.add_param_ushort ("bcast", 0)
+ fc2.add_param_ushort ("mme", 0)
+ fc2.add_param_ushort ("lid", 1)
+ fc2.add_param_ushort ("tei", 1)
+ fc2.send()
+
+maximus.wait(10000)
+
+print "\n************ CCO TRACE ***************\n"
+fc1 = maximus.create_fcall ("fc_sar_print_trace")
+fc1.set_sta(station1)
+fc1.send();
+
+fc1 = maximus.create_fcall ("fc_station_uninit")
+fc1.set_sta(station1)
+fc1.send();
+
+station1.remove()
+
+
+for i in range(0, N):
+ print "\n************ STATION", i+1, "TRACE ***************\n"
+ fc2 = maximus.create_fcall ("fc_sar_print_trace")
+ fc2.set_sta(stations[i])
+ fc2.send();
+
+ fc2 = maximus.create_fcall ("fc_station_uninit")
+ fc2.set_sta(stations[i])
+ fc2.send();
+
+ stations[i].remove()
diff --git a/cesar/test_general/maximus/integration/sar-pbproc/Makefile b/cesar/test_general/maximus/integration/sar-pbproc/Makefile
index 99b13d8c3f..7aba37aece 100644
--- a/cesar/test_general/maximus/integration/sar-pbproc/Makefile
+++ b/cesar/test_general/maximus/integration/sar-pbproc/Makefile
@@ -8,6 +8,7 @@ TARGET_PROGRAMS = sar-pbproc
sar-pbproc_SOURCES = station.c
sar-pbproc_MODULES = hal/phy/maximus \
- lib mac host hal/phy/soft/bridgedma
+ lib mac host hal/watchdog hal/phy/soft/bridgedma
+sar-pbproc_MODULES_CONFIG = cp/sta/mgr
include $(BASE)/common/make/top.mk
diff --git a/cesar/test_general/station/cco0/s2/Config b/cesar/test_general/station/cco0/s2/Config
index 121375179b..54cdd69001 100644
--- a/cesar/test_general/station/cco0/s2/Config
+++ b/cesar/test_general/station/cco0/s2/Config
@@ -1,2 +1,3 @@
CONFIG_BLK_NB = 2048
CONFIG_STATS=y
+CONFIG_MAC_PBPROC_EOC_FC = y
diff --git a/cesar/test_general/station/common_eoc/Module b/cesar/test_general/station/common_eoc/Module
new file mode 100644
index 0000000000..a0962164ec
--- /dev/null
+++ b/cesar/test_general/station/common_eoc/Module
@@ -0,0 +1 @@
+SOURCES := station.c
diff --git a/cesar/test_general/station/common_eoc/src/station.c b/cesar/test_general/station/common_eoc/src/station.c
new file mode 100644
index 0000000000..aa5db8c92a
--- /dev/null
+++ b/cesar/test_general/station/common_eoc/src/station.c
@@ -0,0 +1,162 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/station.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "common/defs/ethernet.h"
+#include "lib/trace.h"
+#include "lib/stats.h"
+
+#include "station/station.h"
+#include "cp/cp.h"
+#include "hle/hle.h"
+#include "cl/cl.h"
+#include "mac/sar/sar.h"
+#include "mac/pbproc/pbproc.h"
+#include "cp/sta/mgr/sta_mgr.h"
+#include "cp/cco/bw/bw.h"
+
+#include "host/fcall/fcall.h"
+#include "test_general/station/fcall/fcall.h"
+#include "ce/rx/inc/rx.h"
+
+/** Private include never use it in the station source code outside the own
+ * module. **/
+#if CONFIG_FCALL_MME
+#include "interface/inc/context.h"
+#endif
+#include "cl/inc/context.h"
+#include "mac/pbproc/inc/context.h"
+#include "mac/sar/inc/sar_context.h"
+#include "hal/phy/maximus/inc/maximus_phy_ctx.h"
+#include <stdio.h>
+
+#if !CONFIG_FCALL_MME
+extern station_ctx_t my_station;
+#endif
+
+#include "cp/inc/context.h"
+#include "cp/msg/inc/context.h"
+
+static cesar_t *cesar;
+
+
+#if CONFIG_STATS
+char callback_local_value_name[255] = "\nbonus_stat_added_each_time_idemButCallback(u64)_is_requested_in_order_to_fill_the_1st_page_quickly._This_explain_why_stat's_name_is_that_long._This_stat_gives_the_number_of_bonus_stats_added(u16)";
+u16 callback_local_value = 0;
+
+static u16*
+lib_stats_callback_test(void)
+{
+ callback_local_value++;
+
+ lib_stats_set_stat_value_notype (callback_local_value_name,
+ &callback_local_value,
+ LIB_STATS_ACCESS_READ_ONLY,
+ LIB_STATS_USER);
+
+ return &callback_local_value;
+}
+#endif
+
+
+/***************** Cesar *******************/
+
+int
+cyg_user_start (void)
+{
+ struct fcall_ctx *fcall = NULL;
+ struct probe_ctx *probe = NULL;
+
+ cesar = cesar_init ();
+
+#if CONFIG_FCALL_MME
+ fcall = cesar->interface->fcall->fcall_ctx;
+ probe = cesar->interface->fcall->probe_ctx;
+#else
+ fcall = my_station.fcall;
+ probe = my_station.probe;
+#endif
+
+ fcall_register (fcall, "fc_sta_own_data_public",
+ &fc_sta_own_data_public, cesar);
+
+ fcall_register (fcall, "fc_sta_own_data_private",
+ &fc_sta_own_data_private, cesar);
+
+ fcall_register (fcall, "fc_cc_leave_req",
+ &fc_cc_leave_req, cesar);
+
+ fcall_register (fcall, "fc_sta_mgr_get_unassoc_sta",
+ &fc_sta_mgr_get_unassoc_sta, cesar);
+
+ fcall_register (fcall, "fc_sta_is_mac_bridged",
+ &fc_sta_is_mac_bridged, cesar);
+ fcall_register (fcall, "fc_sta_get_mac_to_tei_entry",
+ &fc_sta_get_mac_to_tei_entry, cesar);
+
+ fcall_register (fcall, "fc_mac_store_sta_peer_is_authenticated",
+ &fc_mac_store_sta_peer_is_authenticated, cesar->mac_store);
+
+ fcall_register (fcall, "fc_cco_change_snid",
+ &fc_cco_change_snid, cesar);
+
+ fcall_register (fcall, "fc_cco_change_hm",
+ &fc_cco_change_hm, cesar);
+
+ fcall_register (fcall, "fc_cesar_uninit",
+ &fc_cesar_uninit, cesar);
+
+ fcall_register (fcall, "fc_memory_state",
+ &fc_memory_state, NULL);
+
+ fcall_register (fcall, "fc_ce_rx_initial_ce_started",
+ &fc_ce_rx_initial_ce_started, cesar);
+
+ fcall_register (fcall, "fc_cco_change_nek",
+ &fc_cco_change_nek, cesar);
+
+ fcall_register (fcall, "fc_nek_get", &fc_nek_get, cesar);
+
+#if CONFIG_TRACE
+ fcall_register (fcall, "fc_sta_trace_dump_cl",
+ &fc_sta_trace_dump, &cesar->cl->trace);
+ fcall_register (fcall, "fc_sta_trace_dump_phy",
+ &fc_sta_trace_dump, &cesar->pbproc->phy->trace);
+ fcall_register (fcall, "fc_sta_trace_dump_sar",
+ &fc_sta_trace_dump, &cesar->sar->trace);
+ fcall_register (fcall, "fc_sta_trace_dump_ce_rx",
+ &fc_sta_trace_dump, &cesar->ce_rx->trace);
+ fcall_register (fcall, "fc_sta_trace_dump_cp",
+ &fc_sta_trace_dump, &cesar->cp->trace);
+ fcall_register (fcall, "fc_sta_trace_dump_cp_verbose",
+ &fc_sta_trace_dump, &cesar->cp->trace_verbose);
+ fcall_register (fcall, "fc_sta_trace_dump_all",
+ &fc_sta_trace_dump_all, NULL);
+#endif
+
+#if !CONFIG_FCALL_MME
+ my_station.pipe_log_fd = 1;
+#endif
+
+#if CONFIG_STATS
+ lib_stats_set_stat_callback ("idemButCallback(u64)",
+ (lib_stats_cb_r_t) lib_stats_callback_test,
+ NULL,
+ sizeof (*(lib_stats_callback_test ())),
+ LIB_STATS_USER);
+#endif
+
+ return 0;
+}
+
diff --git a/cesar/test_general/station/compliance-eoc/Makefile b/cesar/test_general/station/compliance-eoc/Makefile
new file mode 100644
index 0000000000..50536a8201
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/Makefile
@@ -0,0 +1,25 @@
+all: board-cco board-sta simu-cco simu-sta
+boa: board-cco board-sta
+sim: simu-cco simu-sta
+
+clean: board-cco-clean board-sta-clean simu-sta-clean simu-cco-clean
+
+board-cco: board-cco-Makefile board-cco-ecos.ecc.sh
+ make -f board-cco-Makefile
+board-cco-clean: board-cco-Makefile
+ make -f board-cco-Makefile clean
+
+board-sta: board-sta-Makefile board-sta-ecos.ecc.sh
+ make -f board-sta-Makefile
+board-sta-clean: board-sta-Makefile
+ make -f board-sta-Makefile clean
+
+simu-sta: simu-sta-Makefile simu-sta-ecos.ecc.sh
+ make -f simu-sta-Makefile
+simu-sta-clean: simu-sta-Makefile
+ make -f simu-sta-Makefile clean
+
+simu-cco: simu-cco-Makefile simu-cco-ecos.ecc.sh
+ make -f simu-cco-Makefile
+simu-cco-clean: simu-cco-Makefile
+ make -f simu-cco-Makefile clean
diff --git a/cesar/test_general/station/compliance-eoc/Makefile-cco.mk b/cesar/test_general/station/compliance-eoc/Makefile-cco.mk
new file mode 100644
index 0000000000..594bee6c6d
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/Makefile-cco.mk
@@ -0,0 +1,21 @@
+TARGET_PROGRAMS = cco
+
+cco_SOURCES =
+cco_MODULES = lib mac/common mac cl hle bsu interface hal station \
+ host test_general/station/fcall \
+ test_general/station/common_eoc host ce\
+ cp/beacon cp/cco/bw cp/cco/region cp/cl_interf \
+ cp/fsm cp/msg cp/secu cp/sta/core \
+ cp/sta/mgr cp cp/sta/action \
+ cp/eoc/cco/bw cp/eoc/sta/mgr\
+ cp/eoc/cco/action cp/eoc/multi_sta/action \
+ cp/eoc/multi_sta_fsm cp/eoc/sta/action
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_sta_action_MODULE_SOURCES = bridge.c vs.c misc.c
+cp_eoc_sta_action_MODULE_SOURCES = action.c cco_stub.c drv.c poweron.c
+cp_MODULE_MODULES =
+
+include $(BASE)/common/make/top.mk
+
+$(call src2obj,src/region_stub.c,target): $(BASE)/cp/fsm/fsm.h
diff --git a/cesar/test_general/station/compliance-eoc/Makefile-sta.mk b/cesar/test_general/station/compliance-eoc/Makefile-sta.mk
new file mode 100644
index 0000000000..dbb0994765
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/Makefile-sta.mk
@@ -0,0 +1,19 @@
+TARGET_PROGRAMS = sta
+
+sta_SOURCES =
+sta_MODULES = lib mac/common mac cl bsu hle interface hal station \
+ host test_general/station/fcall \
+ test_general/station/common_eoc host ce\
+ cp/beacon cp/cco/bw cp/cco/region cp/cl_interf \
+ cp/msg cp/fsm cp/secu cp/sta/core \
+ cp/sta/mgr cp/sta/action\
+ cp/eoc/sta/action \
+ cp/eoc/cco/bw cp/eoc/sta/mgr cp
+
+cp_sta_mgr_MODULE_SOURCES = net.c sta.c
+cp_sta_action_MODULE_SOURCES = bridge.c vs.c misc.c
+cp_MODULE_MODULES =
+
+include $(BASE)/common/make/top.mk
+
+$(call src2obj,src/region_stub.c,target): $(BASE)/cp/fsm/fsm.h
diff --git a/cesar/test_general/station/compliance-eoc/board-cco-Config b/cesar/test_general/station/compliance-eoc/board-cco-Config
new file mode 100644
index 0000000000..3a327dc33d
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/board-cco-Config
@@ -0,0 +1,47 @@
+CONFIG_TRACE_ON_FATAL = y
+CONFIG_TRACE = n
+CONFIG_PHY_TRACE_MORE = n
+CONFIG_LEON_FATAL_BUTTON = n
+CONFIG_GPIO_LEON_FATAL_BUTTON_GPIO = 5
+CONFIG_DEBUG_CLAIM = n
+CONFIG_BLK_NB = 6144
+CONFIG_BLK_SLACK = 1280
+CONFIG_SAR_PBPOOL_SIZE = 768
+CONFIG_GPIO_LED_TRAFFIC = y
+CONFIG_GPIO_LED_IS_CCO = y
+CONFIG_GPIO_LED_PBPROC_ALIVE = n
+CONFIG_GPIO_LED_PBPROC_ALIVE_GPIO = 0
+
+CONFIG_GPIO_LED_PBPROC_WORKING = n
+CONFIG_GPIO_LED_PBPROC_WORKING_GPIO = 0
+
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_STA_MGR_CCO_EOC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CL_DATA_RATE = n
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_SAR_DROP_OLD_SEG = y
+CONFIG_CP_EOC_CCO_WL_ALLOWED = y
+CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED = y
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 1
+CONFIG_CP_EOC_CCO_CON_ALLOWED = y
+CONFIG_BSU_ACLF_EOC = y
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_AV_ONLY_MODE = y
diff --git a/cesar/test_general/station/compliance-eoc/board-cco-Makefile b/cesar/test_general/station/compliance-eoc/board-cco-Makefile
new file mode 100644
index 0000000000..b1367e15a1
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/board-cco-Makefile
@@ -0,0 +1,7 @@
+BASE = ../../..
+ECOS = y
+TARGET = sparc
+VARIANT = board-cco
+TARGET_OPTIMIZE = -Os
+
+include Makefile-cco.mk
diff --git a/cesar/test_general/station/compliance-eoc/board-cco-ecos.ecc.sh b/cesar/test_general/station/compliance-eoc/board-cco-ecos.ecc.sh
new file mode 100644
index 0000000000..db2208c6cc
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/board-cco-ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new sparc_leon default
+cat >> $config <<'EOF'
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/test_general/station/compliance-eoc/board-sta-Config b/cesar/test_general/station/compliance-eoc/board-sta-Config
new file mode 100644
index 0000000000..6e1f33cfe5
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/board-sta-Config
@@ -0,0 +1,42 @@
+CONFIG_TRACE_ON_FATAL = y
+CONFIG_TRACE = n
+CONFIG_PHY_TRACE_MORE = n
+CONFIG_LEON_FATAL_BUTTON = n
+CONFIG_GPIO_LEON_FATAL_BUTTON_GPIO = 5
+CONFIG_DEBUG_CLAIM = n
+CONFIG_BLK_NB = 6144
+CONFIG_BLK_SLACK = 1280
+CONFIG_SAR_PBPOOL_SIZE = 768
+
+CONFIG_GPIO_LED_TRAFFIC = y
+CONFIG_GPIO_LED_IS_CCO = y
+CONFIG_GPIO_LED_PBPROC_ALIVE = n
+CONFIG_GPIO_LED_PBPROC_ALIVE_GPIO = 0
+
+CONFIG_GPIO_LED_PBPROC_WORKING = n
+CONFIG_GPIO_LED_PBPROC_WORKING_GPIO = 0
+
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_sta.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CL_DATA_RATE = n
+CONFIG_CP_MSG_EOC_DRV_MME = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_SAR_DROP_OLD_SEG = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 1
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_CP_EOC_STA_CON_ALLOWED = y
+CONFIG_BSU_ACLF_EOC = y
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_AV_ONLY_MODE = y
diff --git a/cesar/test_general/station/compliance-eoc/board-sta-Makefile b/cesar/test_general/station/compliance-eoc/board-sta-Makefile
new file mode 100644
index 0000000000..271d91a2f8
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/board-sta-Makefile
@@ -0,0 +1,7 @@
+BASE = ../../..
+ECOS = y
+TARGET = sparc
+VARIANT = board-sta
+TARGET_OPTIMIZE = -Os
+
+include Makefile-sta.mk
diff --git a/cesar/test_general/station/compliance-eoc/board-sta-ecos.ecc.sh b/cesar/test_general/station/compliance-eoc/board-sta-ecos.ecc.sh
new file mode 100644
index 0000000000..db2208c6cc
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/board-sta-ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new sparc_leon default
+cat >> $config <<'EOF'
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/test_general/station/compliance-eoc/py/sc01_dut_as_a_cco.py b/cesar/test_general/station/compliance-eoc/py/sc01_dut_as_a_cco.py
new file mode 100644
index 0000000000..3f001f606a
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/sc01_dut_as_a_cco.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+
+#############################################################################
+# See Phase II certification
+# Compliance Certification Test plan.
+# Version 1.0.22
+#
+# Section 6.2.1 DUT as a CCo
+# Purpose: Verify that in a single AVLN there is only one DUT that is acting
+# as a Central Coordinator.
+#
+# Expected Results:
+# There is only one DUT with CCo Capability value equals to 0b01 or test is
+# failed.
+#############################################################################
+
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu/station.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+# Add two STA.
+macs = startup.get_macs ()
+print macs
+
+stas = []
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb))
+
+csi.process_init (argv, proto)
+csi.process_avlns_launch ()
+csi.process_wait_sec (30)
+
+# Class which do the real check.
+import unittest
+class TestDUTAsACCo(unittest.TestCase):
+ def setUp (self):
+ pass
+ def tearDown (self):
+ pass
+
+ def test (self):
+ # Check STA CCo status.
+ from own_data import Station_own_data
+
+ sta_data = Station_own_data ()
+ data = sta_data.get_data (csi.get_maximus(), stas[0].get_sta_cesar())
+ sta1_cco_status = data.is_cco
+
+ data = sta_data.get_data (csi.get_maximus(), stas[1].get_sta_cesar())
+ sta2_cco_status = data.is_cco
+
+ self.failUnless (sta1_cco_status ^ sta2_cco_status)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestDUTAsACCo)
+testResult = unittest.TextTestRunner(verbosity=2).run(suite)
+
+if options.trace:
+ for i in range (len (macs)):
+ csi.debug_trace_dump ('all', stas[i])
+
+csi.process_avlns_remove ()
+# For nightly build errors
+sys.exit ((1, 0)[testResult.wasSuccessful ()])
diff --git a/cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_cco.py b/cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_cco.py
new file mode 100644
index 0000000000..0abfdcf079
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_cco.py
@@ -0,0 +1,95 @@
+#!/usr/bin/python
+
+#############################################################################
+# See Phase II certification
+# Compliance Certification Test plan.
+# Version 1.0.22
+#
+# Section 6.2.1 DUT as a CCo
+# Purpose: Verify that in a single AVLN there is only one DUT that is acting
+# as a Central Coordinator.
+#
+# Expected Results:
+# There is only one DUT with CCo Capability value equals to 0b01 or test is
+# failed.
+#############################################################################
+
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+# Add one CCO.
+macs = ["00:01:01:00:00:01"]
+print macs
+
+stas = []
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], True, True,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb))
+
+csi.process_init (argv, proto)
+csi.process_avlns_launch ()
+csi.process_wait_sec (30)
+
+# Class which do the real check.
+import unittest
+class TestDUTAsACCo(unittest.TestCase):
+ def setUp (self):
+ pass
+ def tearDown (self):
+ pass
+
+ def test (self):
+ # Check STA CCo status.
+ from own_data import Station_own_data
+
+ sta_data = Station_own_data ()
+ data = sta_data.get_data (csi.get_maximus(), stas[0].get_sta_cesar())
+ sta1_cco_status = data.is_cco
+
+ self.failUnless (sta1_cco_status)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestDUTAsACCo)
+testResult = unittest.TextTestRunner(verbosity=2).run(suite)
+
+if options.trace:
+ for i in range (len (macs)):
+ csi.debug_trace_dump ('all', stas[i])
+
+csi.process_avlns_stop()
+csi.process_avlns_remove ()
+# For nightly build errors
+sys.exit ((1, 0)[testResult.wasSuccessful ()])
diff --git a/cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_sta.py b/cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_sta.py
new file mode 100644
index 0000000000..89e04fa665
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test01_eoc_init_one_sta.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+
+#############################################################################
+# See Phase II certification
+# Compliance Certification Test plan.
+# Version 1.0.22
+#
+# Section 6.2.1 DUT as a CCo
+# Purpose: Verify that in a single AVLN there is only one DUT that is acting
+# as a Central Coordinator.
+#
+# Expected Results:
+# There is only one DUT with CCo Capability value equals to 0b01 or test is
+# failed.
+#############################################################################
+
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-sta/sta.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+# Add one STA.
+macs = ["00:01:01:00:00:23"]
+print macs
+
+stas = []
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb))
+
+csi.process_init (argv, proto)
+csi.process_avlns_launch ()
+csi.process_wait_sec (30)
+
+# Class which do the real check.
+import unittest
+class TestDUTAsACCo(unittest.TestCase):
+ def setUp (self):
+ pass
+ def tearDown (self):
+ pass
+
+ def test (self):
+ # Check STA CCo status.
+ from own_data import Station_own_data
+
+ sta_data = Station_own_data ()
+ data = sta_data.get_data (csi.get_maximus(), stas[0].get_sta_cesar())
+ sta1_cco_status = data.is_cco
+
+ self.failUnless (sta1_cco_status == 0)
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestDUTAsACCo)
+testResult = unittest.TextTestRunner(verbosity=2).run(suite)
+
+if options.trace:
+ for i in range (len (macs)):
+ csi.debug_trace_dump ('all', stas[i])
+
+csi.process_avlns_remove ()
+# For nightly build errors
+sys.exit ((1, 0)[testResult.wasSuccessful ()])
diff --git a/cesar/test_general/station/compliance-eoc/py/test02_eoc_beacon.py b/cesar/test_general/station/compliance-eoc/py/test02_eoc_beacon.py
new file mode 100644
index 0000000000..d0bee21a5f
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test02_eoc_beacon.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+
+##############################################################################
+# The CCo and one station #
+# ---------------------------------------------------------------------- #
+# #
+# Objective: Send central beacon with EoC ScheduleBentry by the CCo, #
+# and verify the reception of beacon on the station, content of beacon #
+# is partly examined on maximus #
+##############################################################################
+
+import unittest
+import sys
+
+sys.path.append ('../../../maximus/python/tools/csi/')
+sys.path.append ('../../../maximus/python/obj/')
+sys.path.append ('../../../maximus/python/')
+sys.path.append ('../../../maximus/python/lib/cesar')
+
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import *
+from define import SECURITY_LEVEL_SC
+from maximus import *
+
+
+LOCAL_CSMA = int(0xfe) # 0xff < 1
+CFPI = int(0xf8) # 0xfc < 1
+SPC_CENTRAL = int(0xf6) # 0xfb < 1
+NON_PERSISTENT_SCHEDULE_BENTRY = 0
+
+# Initialize CSI.
+csi = csiCore(1234);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "CABLENET")
+
+macs = ["00:01:01:00:00:35"]
+
+print macs
+
+stas = []
+# Add CCO.
+stas.append (avln.sta_add ("00:01:01:00:00:01", False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station CCO",
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-cco/cco.elf"))
+
+# Add one STA
+stas.append (avln.sta_add (macs[0], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(1),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-sta/sta.elf"))
+
+csi.process_init (argv, proto)
+
+csi.process_avlns_launch ()
+
+class TestEocBeacon (unittest.TestCase):
+
+ def setUp (self):
+ pass
+
+ def tearDown (self):
+ pass
+
+ def testBeaconContent (self):
+ mpdu = recv (csi.get_maximus(), count = 1, filter = frame_filter_mpdu,
+ timeout = 8000000)
+ self.failUnless (mpdu != None)
+ mpdu0 = mpdu[0]
+ if mpdu0.get_type() is 'PHY_TYPE_MPDU_PAYLOAD':
+ print "Maximus received mpdu"
+ fc_av0 = mpdu0.get_fc_av()[0]
+ #Test if Central Beacon
+ self.failUnless((fc_av0 & 0x3) == 0)
+ #Beacon Content
+ pb = mpdu0.get_pblist()[0]
+ beacon_type = int (unpack ('128B',pb)[4])
+ non_persis = int (unpack ('128B', pb)[9])
+ glid1 = int (unpack ('128B',pb)[12])
+ glid2 = int (unpack ('128B',pb)[15])
+ glid3 = int (unpack ('128B',pb)[18])
+ self.failUnless ((beacon_type & 0x3) == 0)
+ self.failUnless (non_persis == NON_PERSISTENT_SCHEDULE_BENTRY)
+ self.failUnless (glid1 == SPC_CENTRAL, glid2 == LOCAL_CSMA)
+ self.failUnless (glid3 == CFPI)
+
+ def testBeaconReception (self):
+ probe = csi.get_maximus().create_probe ().add_param ("nb_beacon_recv")
+ probe.send (stas[1].get_sta_cesar().get())
+ nb_beacon_recv = unpack('L',probe.bind_param ("nb_beacon_recv"))
+
+ self.failUnless (int(nb_beacon_recv[0]) == 1)
+
+suite = unittest.TestLoader ().loadTestsFromTestCase (TestEocBeacon)
+testResult = unittest.TextTestRunner (verbosity = 2).run (suite)
+
+csi.process_avlns_remove ()
+# For nightly build errors
+sys.exit ((1, 0)[result and testResult.wasSuccessful ()])
diff --git a/cesar/test_general/station/compliance-eoc/py/test03_eoc_init_cco_sta.py b/cesar/test_general/station/compliance-eoc/py/test03_eoc_init_cco_sta.py
new file mode 100644
index 0000000000..a36da7dcc4
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test03_eoc_init_cco_sta.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+
+#############################################################################
+# See Phase II certification
+# Compliance Certification Test plan.
+# Version 1.0.22
+#
+# Section 6.2.1 DUT as a CCo
+# Purpose: Verify that in a single AVLN there is only one DUT that is acting
+# as a Central Coordinator.
+#
+# Expected Results:
+# There is only one DUT with CCo Capability value equals to 0b01 or test is
+# failed.
+#############################################################################
+
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import * #csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+# Add one CCO.
+macs = ["00:01:01:00:00:32"]
+print macs
+
+stas = []
+stas.append (avln.sta_add ("00:01:01:00:00:01", False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station CCO",
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-cco/cco.elf"))
+
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-sta/sta.elf"))
+
+csi.process_init (argv, proto)
+csi.process_avlns_launch ()
+
+csi.process_wait_sec (2)
+print "Start broadcast sending"
+csi.process_avlns_send_broadcast()
+
+csi.process_wait_sec (2)
+print "Start packet sending from CCo"
+packet = [csiPacket (150, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+csi.process_wait_sec (2)
+print "Start packet sending from STA"
+packet = [csiPacket (250, avln, stas[1], None, stas[0])]
+csi.process_data_send_traffic (packet)
+
+csi.process_wait_sec (50)
+csi.process_avlns_remove ()
diff --git a/cesar/test_general/station/compliance-eoc/py/test04_avln_start_stop.py b/cesar/test_general/station/compliance-eoc/py/test04_avln_start_stop.py
new file mode 100644
index 0000000000..e4ab6c112c
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test04_avln_start_stop.py
@@ -0,0 +1,95 @@
+#!/usr/bin/python
+
+#############################################################################
+# Testing connection and disconnection of CCo
+# Expectiong results: After several STA disconnects, STA must communicate
+# with CCo
+#############################################################################
+
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import * #csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+from maximus import *
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+# Add one CCO.
+macs = ["00:01:01:00:00:31"]
+print macs
+
+stas = []
+stas.append (avln.sta_add ("00:01:01:00:00:01", False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station CCO",
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-cco/cco.elf"))
+
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-sta/sta.elf"))
+
+csi.process_init (argv, proto)
+csi.get_maximus().disturb_channel(True)
+set_snr (csi.get_maximus(), value = 1)
+csi.process_avlns_launch ()
+
+csi.process_wait_sec (10)
+
+for i in range(0, 10):
+ print "Deactivate CCO"
+ stas[0].get_sta_cesar().stop()
+ csi.process_wait_sec (5)
+ print "Activate CCO"
+ stas[0].get_sta_cesar().start()
+ csi.process_wait_sec (5)
+ print "Send data"
+ for i in range (0, 10):
+ packet = [csiPacket (1400, avln, stas[0], None, stas[1])]
+ csi.process_data_send_traffic (packet)
+ csi.get_maximus().wait (200000)
+ for i in range (0, 10):
+ packet = [csiPacket (1400, avln, stas[1], None, stas[0])]
+ csi.process_data_send_traffic (packet)
+ csi.get_maximus().wait (200000)
+ csi.process_wait_sec (10)
+
+print "Deactivate STA. Send data"
+stas[1].get_sta_cesar().stop()
+csi.process_wait_sec (2)
+
+packet = [csiPacket (1400, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+csi.process_wait_sec (20)
+
+print "Fin"
+csi.process_avlns_stop ()
+csi.process_avlns_remove ()
diff --git a/cesar/test_general/station/compliance-eoc/py/test05_eoc_init_cco_multista.py b/cesar/test_general/station/compliance-eoc/py/test05_eoc_init_cco_multista.py
new file mode 100644
index 0000000000..2f82e01a2c
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test05_eoc_init_cco_multista.py
@@ -0,0 +1,182 @@
+#!/usr/bin/python
+
+#############################################################################
+# Test one CCO and multiple STA.
+# Send 10000 packets of data to STAs
+#############################################################################
+
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import * #csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+from maximus import *
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+macs = []
+
+N = 1
+N_SIM = 0
+N_SMALL = 0
+N_BIG = 0
+#Fill macs
+for i in range(0,N):
+ macs.append("00:01:01:00:00:" + str(20 + i))
+
+print macs
+
+stas = []
+# Add one CCO.
+stas.append (avln.sta_add ("00:01:01:00:00:01", False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station CCO",
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-cco/cco.elf"))
+
+# Add several STAs
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb and i < N_SIM,
+ executable = "./obj/simu-sta/sta.elf"))
+
+csi.process_init (argv, proto)
+#csi.get_maximus().disturb_channel(True)
+#set_snr (csi.get_maximus(), value = 1)
+
+csi.process_wait_sec (157)
+
+csi.process_avlns_launch ()
+
+print "Start broadcast sending"
+csi.process_avlns_send_broadcast()
+csi.get_maximus().wait (1000000)
+csi.process_avlns_send_broadcast()
+csi.get_maximus().wait (1000000)
+csi.process_avlns_send_broadcast()
+csi.get_maximus().wait (1000000)
+csi.process_avlns_send_broadcast()
+csi.get_maximus().wait (1000000)
+csi.process_avlns_send_broadcast()
+csi.get_maximus().wait (1000000)
+csi.process_avlns_send_broadcast()
+
+csi.process_wait_sec (1)
+print "Start packet sending from CCo"
+packet = [csiPacket (153, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+packet = [csiPacket (153, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+csi.process_wait_sec (1)
+print "Start packet sending from STA"
+packet = [csiPacket (253, avln, stas[1], None, stas[0])]
+csi.process_data_send_traffic (packet)
+packet = [csiPacket (253, avln, stas[1], None, stas[0])]
+csi.process_data_send_traffic (packet)
+packet = [csiPacket (492, avln, stas[1], None, stas[0])]
+csi.process_data_send_traffic (packet)
+packet = [csiPacket (492, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+packet = [csiPacket (236, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+packet = [csiPacket (236, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+
+csi.process_wait_sec (1)
+print "Send 10000 short packets, duration 4s"
+
+for i in range (0, N_SMALL):
+ if i % 50 == 0:
+ print "Packet ", i
+ if i % 10 == 0:
+ csi.get_maximus().wait (100000)
+ packet = [csiPacket (64 + random.randint(0, 200), avln, stas[0], None,
+ stas[1+(i%N)])]
+ csi.process_data_send_traffic (packet)
+
+csi.process_wait_sec (1)
+print "Send 500 long packets duration 50x10ms = 0,5s"
+
+for i in range (0, N_BIG):
+ if i % 50 == 0:
+ print "Packet ", i
+ if i % 10 == 0:
+ csi.get_maximus().wait (250000)
+ packet = [csiPacket (1200 + random.randint(0, 200), avln, stas[0], None,
+ stas[1+(i%N)])]
+ csi.process_data_send_traffic (packet)
+
+csi.process_wait_sec (1)
+
+print "Bandwidth test"
+
+SIZE_1Mb = 1024 * 128
+MS_TCK = 25000
+MS_PERIOD = 1
+MS_NUM = 1000
+OVERALL = 30000
+curr_size = 140
+MAX_SIZE = 150
+DIRECTION=1
+TOGGLE=0
+MAXIMUS_OFFSET = 14
+TO_ONE_STA = 0
+while curr_size < MAX_SIZE:
+ sta_curr = 0;
+ toggle = DIRECTION
+ p1size = 0
+ print "Bandwidth test, testing ", curr_size
+ for i in range(0,OVERALL/MS_PERIOD):
+ p1size += curr_size * SIZE_1Mb / (MS_NUM/MS_PERIOD)
+ if i % 20 == 0:
+ print 'Packet', i
+ while p1size >= 64:
+ len = min(p1size, 1200 + random.randint(0, 200)) - MAXIMUS_OFFSET
+ if TO_ONE_STA:
+ sta_pos = 0
+ else:
+ sta_pos = sta_curr % N
+ sta_curr = sta_curr + 1
+ if toggle:
+ packet = [csiPacket (len, avln, stas[0], None, stas[1+sta_pos])]
+ else:
+ packet = [csiPacket (len, avln, stas[1+sta_pos], None, stas[0])]
+ if TOGGLE:
+ toggle = 1 - toggle
+ csi.process_data_send_traffic (packet)
+ p1size -= len + MAXIMUS_OFFSET
+ # wait MS_PERIOD ms
+ csi.get_maximus().wait (MS_PERIOD*MS_TCK)
+ #wait 1 sec between iterations
+ csi.get_maximus().wait (MS_NUM*MS_TCK)
+ curr_size += 1
+
+#csi.process_verify_transmission()
+csi.process_avlns_remove ()
diff --git a/cesar/test_general/station/compliance-eoc/py/test06_eoc_change_nek.py b/cesar/test_general/station/compliance-eoc/py/test06_eoc_change_nek.py
new file mode 100644
index 0000000000..f4460f5827
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test06_eoc_change_nek.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+
+# Create an CCo and four stations and test NEK change
+
+import sys
+import unittest
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import *
+from define import SECURITY_LEVEL_SC
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1238);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+# Add four stations
+macs = ["00:01:01:00:00:32", "00:01:01:00:00:33", "00:01:01:00:00:34",
+ "00:01:01:00:00:35"]
+print macs
+
+stas = []
+stas.append (avln.sta_add ("00:01:01:00:00:01", False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station CCO",
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-cco/cco.elf"))
+
+for i in range (len (macs)):
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-sta/sta.elf"))
+
+# Start network
+csi.process_init (argv, proto)
+csi.process_avlns_launch ()
+csi.process_wait_sec (3)
+
+# Send a FCALL to initiate the NEK change.
+fcall = csi.get_maximus().create_fcall ("fc_cco_change_nek")
+fcall.set_sta (stas[0].get_sta_cesar().get())
+fcall.send()
+print "Change NEK"
+csi.process_wait_sec (2)
+
+print "Start packet sending from CCo"
+packet = [csiPacket (100, avln, stas[0], None, stas[1])]
+csi.process_data_send_traffic (packet)
+print "Start packet sending from STA1"
+packet = [csiPacket (100, avln, stas[1], None, stas[0])]
+csi.process_data_send_traffic (packet)
+csi.process_wait_sec (1)
+
+print "Start packet sending from CCo"
+packet = [csiPacket (150, avln, stas[0], None, stas[2])]
+csi.process_data_send_traffic (packet)
+print "Start packet sending from STA2"
+packet = [csiPacket (150, avln, stas[2], None, stas[0])]
+csi.process_data_send_traffic (packet)
+csi.process_wait_sec (1)
+
+print "Start packet sending from CCo"
+packet = [csiPacket (200, avln, stas[0], None, stas[3])]
+csi.process_data_send_traffic (packet)
+print "Start packet sending from STA3"
+packet = [csiPacket (200, avln, stas[3], None, stas[0])]
+csi.process_data_send_traffic (packet)
+csi.process_wait_sec (1)
+
+print "Start packet sending from CCo"
+packet = [csiPacket (100, avln, stas[0], None, stas[4])]
+csi.process_data_send_traffic (packet)
+print "Start packet sending from STA4"
+packet = [csiPacket (100, avln, stas[4], None, stas[0])]
+csi.process_data_send_traffic (packet)
+
+csi.process_wait_sec (2)
+csi.process_verify_transmission ()
+csi.process_avlns_remove ()
diff --git a/cesar/test_general/station/compliance-eoc/py/test07_eoc_startup.py b/cesar/test_general/station/compliance-eoc/py/test07_eoc_startup.py
new file mode 100644
index 0000000000..0e220fb196
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/test07_eoc_startup.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+
+##############################################################################
+# The CCo and many stations #
+# ---------------------------------------------------------------------- #
+# #
+# Objective: Test time needed to associate and authenticate all stations #
+# in the network depending on number of stations #
+##############################################################################
+
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-t', '--trace', action = 'store_true',
+ default = False,
+ help = 'dump trace of all stations using command: "pkill -USR2 -f'
+ + ' maximus"')
+argv, proto, options = startup.parse ()
+
+from csicore import * #csiCore, csiSta
+from define import SECURITY_LEVEL_SC
+
+
+# If trace dumping is enabled.
+if options.trace:
+ # Handler for dump all the trace of the station.
+ import signal
+ def trace_signal_handler (signal, frame):
+ dump_trace ()
+ # Bind handler to SIGUSR2.
+ signal.signal (signal.SIGUSR2, trace_signal_handler)
+
+# Initialize CSI.
+csi = csiCore(1247);
+# Create an AVLN.
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+
+macs = []
+# Number of stations in network
+N = 64
+for i in range(0,N):
+ macs.append("00:01:01:00:00:" + str(30 + i))
+
+stas = []
+# Add one CCo.
+stas.append (avln.sta_add ("00:01:01:00:00:01", False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station CCO",
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = options.gdb, executable = "./obj/simu-cco/cco.elf"))
+# Add stations
+for i in range (len (macs)):
+ if i != 22:
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = False, executable = "./obj/simu-sta/sta.elf"))
+ else:
+ stas.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom Station " + str(i),
+ "Spidcom Sta SPC300", SECURITY_LEVEL_SC,
+ debug = True, executable = "./obj/simu-sta/sta.elf"))
+
+
+csi.process_init (argv, proto)
+csi.process_avlns_launch ()
+
+csi.process_wait_sec (2)
+print "Start packet sending from CCo"
+for i in range (0,len (macs)):
+ packet = [csiPacket (400, avln, stas[0], None, stas[i+1])]
+ csi.process_data_send_traffic (packet)
+csi.process_wait_sec (5)
+print "Start packet sending from stations"
+for i in range (0,len (macs)):
+ packet = [csiPacket (386 + i, avln, stas[i+1], None, stas[0])]
+ csi.process_data_send_traffic (packet)
+
+csi.process_wait_sec (20)
+csi.process_avlns_remove ()
diff --git a/cesar/test_general/station/compliance-eoc/py/trace.py b/cesar/test_general/station/compliance-eoc/py/trace.py
new file mode 100644
index 0000000000..bf962efaf1
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/py/trace.py
@@ -0,0 +1,29 @@
+import sys
+sys.path.append('../../../maximus/python/obj');
+sys.path.append ('../../../maximus/python/lib/proto')
+
+from maximus_proto import MaximusProto
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.add_option ("-m", "--mac", dest="mac", help="Board mac address")
+parser.add_option ("-n", "--net", dest="net", help="Network interface")
+parser.add_option ("-a", "--aface", dest="aface",
+ help="Hardware address of the Ethernet interface used to send \
+ packets to boards")
+
+(options, args) = parser.parse_args()
+assert options.net
+assert options.mac
+assert options.aface
+
+maximus = MaximusProto ()
+maximus.init (sys.argv + ['-n', options.net, '-a', options.aface])
+
+sta = maximus.create_sta (options.mac)
+sta.set_name ('Sta')
+
+# Sends a fcall to uninit the station.
+fcall = maximus.create_fcall ("fc_sta_trace_dump_all")
+fcall.set_sta (sta)
+fcall.send()
diff --git a/cesar/test_general/station/compliance-eoc/simu-cco-Config b/cesar/test_general/station/compliance-eoc/simu-cco-Config
new file mode 100644
index 0000000000..3e4bbe4674
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/simu-cco-Config
@@ -0,0 +1,35 @@
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_TRACE = y
+CONFIG_BLAME = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_BLK_NB = 6144
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_BLK_SLACK = 512
+CONFIG_SAR_PBPOOL_SIZE = 512
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_EOC_MULTI_STA_FSM_DEF="cp/eoc/multi_sta_fsm/src/fsm/multi_sta.fsm"
+CONFIG_CP_STA_MGR_EOC = y
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_cco.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_MSG_EOC_MULTI_STA_MME = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CL_DATA_RATE = n
+CONFIG_CP_MSG_EOC_DRV_MME = n
+CONFIG_SAR_DROP_OLD_SEG = y
+CONFIG_CP_EOC_CCO_WL_ALLOWED = y
+CONFIG_CP_EOC_MULTI_STA_WL_ALLOWED = y
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 2
+CONFIG_CP_STA_MGR_CCO_EOC = y
+CONFIG_CP_EOC_CCO_CON_ALLOWED = y
+CONFIG_BSU_ACLF_EOC = y
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_AV_ONLY_MODE = y
diff --git a/cesar/test_general/station/compliance-eoc/simu-cco-Makefile b/cesar/test_general/station/compliance-eoc/simu-cco-Makefile
new file mode 100644
index 0000000000..23e3d745e3
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/simu-cco-Makefile
@@ -0,0 +1,5 @@
+BASE = ../../..
+ECOS = y
+VARIANT = simu-cco
+
+include Makefile-cco.mk
diff --git a/cesar/test_general/station/compliance-eoc/simu-cco-ecos.ecc.sh b/cesar/test_general/station/compliance-eoc/simu-cco-ecos.ecc.sh
new file mode 100644
index 0000000000..e0278271fe
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/simu-cco-ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new maximus default
+cat >> $config <<'EOF'
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/test_general/station/compliance-eoc/simu-sta-Config b/cesar/test_general/station/compliance-eoc/simu-sta-Config
new file mode 100644
index 0000000000..b038bd3f53
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/simu-sta-Config
@@ -0,0 +1,28 @@
+CONFIG_TRACE = y
+CONFIG_BLAME = y
+CONFIG_MAC_COMMON_EOC_SCHED = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_CP_BEACON_REGION = n
+CONFIG_ATU_FACTOR = 3
+CONFIG_BLK_NB = 4096
+CONFIG_CP_BEACON_DISCOVER = n
+CONFIG_BLK_SLACK = 2048
+CONFIG_CP_EOC_SCHEDULER = y
+CONFIG_MAC_COMMON_EOC_MFS = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
+CONFIG_CP_FSM_DEF = "cp/fsm/src/fsm/cp_eoc_sta.fsm"
+CONFIG_CP_EOC_CCO_FSM = y
+CONFIG_CP_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_CL_EOC_CLASSIFY = y
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS =y
+CONFIG_CL_EOC_ROUTE = y
+CONFIG_CL_DATA_RATE = n
+CONFIG_CP_MSG_EOC_DRV_MME = n
+CONFIG_CP_MSG_EOC_VS = y
+CONFIG_SAR_DROP_OLD_SEG = y
+CONFIG_CP_EOC_DBG_PRINT_LEVEL = 2
+CONFIG_CP_STA_ACTION_MISC_EOC = y
+CONFIG_CP_EOC_STA_CON_ALLOWED = y
+CONFIG_BSU_ACLF_EOC = y
+CONFIG_BSU_BEACON_EOC_SPC_CENTRAL = y
+CONFIG_AV_ONLY_MODE = y
diff --git a/cesar/test_general/station/compliance-eoc/simu-sta-Makefile b/cesar/test_general/station/compliance-eoc/simu-sta-Makefile
new file mode 100644
index 0000000000..f809b15b12
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/simu-sta-Makefile
@@ -0,0 +1,5 @@
+BASE = ../../..
+ECOS = y
+VARIANT = simu-sta
+
+include Makefile-sta.mk
diff --git a/cesar/test_general/station/compliance-eoc/simu-sta-ecos.ecc.sh b/cesar/test_general/station/compliance-eoc/simu-sta-ecos.ecc.sh
new file mode 100644
index 0000000000..e0278271fe
--- /dev/null
+++ b/cesar/test_general/station/compliance-eoc/simu-sta-ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new maximus default
+cat >> $config <<'EOF'
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/test_general/station/compliance/Makefile b/cesar/test_general/station/compliance/Makefile
index aa9b783b71..4546b5c3f3 100644
--- a/cesar/test_general/station/compliance/Makefile
+++ b/cesar/test_general/station/compliance/Makefile
@@ -1,6 +1,6 @@
-all: simu board
+all: simu board
-clean: simu-clean board-clean
+clean: simu-clean board-clean
simu: simu-Makefile simu-ecos.ecc.sh
make -f simu-Makefile
@@ -15,3 +15,4 @@ board: board-Makefile board-ecos.ecc.sh
board-clean: board-Makefile
make -f board-Makefile clean
+
diff --git a/cesar/test_general/station/fcall/src/beacon.c b/cesar/test_general/station/fcall/src/beacon.c
index bbb4bd53df..71091de3d9 100644
--- a/cesar/test_general/station/fcall/src/beacon.c
+++ b/cesar/test_general/station/fcall/src/beacon.c
@@ -67,7 +67,7 @@ fc_cco_change_nek (fcall_ctx_t *fcall, fcall_param_t **param,
dbg_assert (data);
/* Post the nek_change event. */
- cp_fsm_post_new_event (cesar->cp, bare, cco__nek_change);
+ cp_fsm_post_new_event (cesar->cp, bare, cco_change_nek);
fcall_param_reset (*param);
diff --git a/cesar/test_general/station/vs_eoc/py/vs_eoc_get_topo.py b/cesar/test_general/station/vs_eoc/py/vs_eoc_get_topo.py
new file mode 100644
index 0000000000..0ba4d71b6a
--- /dev/null
+++ b/cesar/test_general/station/vs_eoc/py/vs_eoc_get_topo.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+
+##############################################################################
+# VS_EOC_GET_TOPO #
+# ---------------------------------------------------------------------- #
+# Objective: Test behavior of mme VS_EOC_GET_TOPO #
+##############################################################################
+import unittest
+import sys
+import re
+import struct
+
+sys.path.append ('../../../maximus/python/tools/csi/')
+sys.path.append ('../../../maximus/python/obj/')
+sys.path.append ('../../../maximus/python/')
+sys.path.append ('../../../maximus/python/lib/cesar')
+
+from struct import pack, unpack
+from maximus.mme.mme import MME
+from maximus.mme.mmheader import MMHeader
+from maximus.mme.mmentry import MMEntry
+from maximus.simu.rx import recv
+from struct import pack, unpack
+from csicore import *
+
+# Some defines
+# Number of STA in the test
+sta_count = 1
+
+def data_msdu_filter (msdu):
+ if msdu.get_type () is 'ETHERNET_TYPE_MME':
+ # The received object is an MSDU
+ return True
+ else:
+ return False
+
+# Convert string representing hexa into octet value
+def string2octet (string, i):
+ (a, b) = unpack ("BB", string[i:i+2])
+ if (a >= 0x30) and (a<0x3A):
+ a = (a - 0x30)
+ else:
+ if (a >= 0x41) and (a < 0x47):
+ a = (a - 0x41 + 0xA);
+ else:
+ if (a >= 0x61) and (a < 0x67):
+ a = (a - 0x61 + 0xA);
+ else:
+ exit
+ if (b >= 0x30) and (b<0x3A):
+ b = (b - 0x30)
+ else:
+ if (b >= 0x41) and (b < 0x47):
+ b = (b - 0x41 + 0xA);
+ else:
+ if (b >= 0x61) and (b < 0x67):
+ b = (b - 0x61 + 0xA);
+ else:
+ exit
+ return (a*16 + b)
+
+# Send request to station (dest_sta)
+def send_vs_eoc_get_topo_req (self, dest_sta):
+ #dest_sta.get_sta_cesar().debug()
+
+ dest_mac = dest_sta.get_mac_addr()
+
+ # Convert entry data into a single string
+ data = ""
+
+ # Create and send mme message VS_EOC_GET_TOPO.REQ
+ mme = MME (MMHeader=MMHeader (dest_mac, "20:21:22:23:24:25", MTYPE = 0x88E1,
+ MMV = 1, MMTYPE = 0xA04C, FMI = 0),
+ MMEntry=MMEntry (data))
+ mme.send (csi.get_maximus(), dest_sta.get_sta_cesar().get())
+
+ # Wait for response
+ rsp = recv (csi.get_maximus (), count = 1, filter = data_msdu_filter,
+ timeout = 5000)
+
+ # Fail in case of no response
+ self.failUnless (rsp != None)
+ rsp = rsp[0] # take the first response of the list
+ entry = rsp.get_mmentry()
+ head = rsp.get_mmheader()
+
+ oda = ':'.join ("%02x" % i for i in unpack ("6B", head[0:6]))
+ osa = ':'.join ("%02x" % i for i in unpack ("6B", head[6:12]))
+ mtype = unpack ("H", head[12:14])[0] # no VLAN Tag
+ mmv = unpack ("B", head[14:15])[0]
+ mmtype = unpack ("H", head[15:17])[0]
+ fmi = unpack ("H", head[17:19])[0]
+
+ # Check that mmtype is correct
+ self.failUnless (mmtype == 0xA04D)
+ print " Check cnf ok"
+
+ # Extract data from entry field
+ result = unpack ('B', entry[0])[0]
+ sta_nb = unpack ('B', entry[1])[0]
+ mac_addr = unpack ('BBBBBB', entry[2:8])
+ auth_status = unpack ('B', entry[8])[0]
+ up_att = unpack ('B', entry[9])[0]
+
+ # Compare received value to expected value
+ self.failUnless (result == 0) # 0 is success
+ #self.failUnless (sta_nb == 1)
+ self.failUnless (sta_nb == 0)
+
+ return (mac_addr, auth_status, up_att)
+
+# Class which do the real check
+import unittest
+class TestVsEocGetTopo (unittest.TestCase):
+ def setUp (self):
+ pass
+ def tearDown (self):
+ pass
+ def testVsEocGetTopo (self):
+ print "\nGet topo"
+ (mac_addr, auth_status, up_att) = send_vs_eoc_get_topo_req (self, csista[0])
+
+ # Check results
+ #self.failUnless (mac_addr == (0x66, 0x55, 0x44, 0x33, 0x22, 0x11))
+ #self.failUnless (auth_status == 1)
+ #self.failUnless (up_att == 0)
+
+# Include startup script
+import sys
+base_path = sys.path[0] + '/../../../../'
+
+sys.path.append (base_path + '/test_general/station/common/py')
+from startup import Startup
+from define import *
+startup = Startup (base_path = base_path,
+ executable = sys.path[0] + '/../../compliance-eoc/obj/simu-cco/cco.elf')
+startup.add_option ('-g', '--gdb', action = 'store_true',
+ default = False, help = 'launch the test in debug mode')
+startup.add_option ('-v', '--verbose', action = 'store_true',
+ default = False, help = 'Verbose test output')
+argv, proto, options = startup.parse ()
+
+# Import CSI
+from csicore import csiCore, csiSta, csiPacket
+from sta_mgr import Sta_mgr
+from own_data import Station_own_data
+
+from maximus.channel import *
+
+# Initialize CSI
+csi = csiCore(4242);
+
+# Create an AVLN
+avln = csi.avln_add ("HomePlugAV0123", "AVLN")
+
+# Add one STA
+macs = startup.get_macs ()
+csista = []
+for i in range (sta_count):
+ csista.append (avln.sta_add (macs[i], False, False,
+ "ABCD-EFGH-IJKL-MNOP", "Spidcom station" + str (i),
+ "Spidcom Station SPC 300", SECURITY_LEVEL_SC, debug = options.gdb))
+
+# Start the simulation
+csi.process_init (argv, proto)
+maximus = csi.get_maximus ()
+for i in range (sta_count):
+ csi.process_sta_start (csista[i])
+
+# Run test
+suite = unittest.TestLoader ().loadTestsFromTestCase (TestVsEocGetTopo)
+testResult = unittest.TextTestRunner (verbosity = 2).run (suite)
+
+# For nightly build errors
+sys.exit ((1, 0)[testResult.wasSuccessful ()])
diff --git a/cesar/tools/sniffer_phy/Config b/cesar/tools/sniffer_phy/Config
index b711c51e0f..4d424d7cec 100644
--- a/cesar/tools/sniffer_phy/Config
+++ b/cesar/tools/sniffer_phy/Config
@@ -1 +1,4 @@
CONFIG_STATS = n
+CONFIG_MAC_SAR_EOC_PERMANENT_MFS = y
+CONFIG_MAC_PBPROC_EOC_FC = y
+CONFIG_MAC_COMMON_EOC_TONEMASK = y
diff --git a/cesar/tools/sniffer_phy/Makefile b/cesar/tools/sniffer_phy/Makefile
index 0ea6da7fb2..de198e32f0 100644
--- a/cesar/tools/sniffer_phy/Makefile
+++ b/cesar/tools/sniffer_phy/Makefile
@@ -7,11 +7,13 @@ TARGET_OPTIMIZE = -Os
HOST_PROGRAMS = test_mme
test_mme_SOURCES = mme.c test_mme.c
-test_mme_MODULES = lib
+test_mme_MODULES = lib mac/common
+test_mme_MODULES_SOURCES = tonemask.c
TARGET_PROGRAMS = sniffer_phy
sniffer_phy_SOURCES = sniffer_phy.c lhle.c lowlevel.c mme.c
sniffer_phy_MODULES = lib hal/phy mac/common hal/hle hle hal/arch
+sniffer_phy_MODULES_CONFIG = mac/sar cl
mac_common_MODULES_SOURCES = tonemask.c
include $(BASE)/common/make/top.mk
diff --git a/cesar/tools/sniffer_phy/src/lowlevel.c b/cesar/tools/sniffer_phy/src/lowlevel.c
index 8efbc9bf50..c39aeb4d95 100644
--- a/cesar/tools/sniffer_phy/src/lowlevel.c
+++ b/cesar/tools/sniffer_phy/src/lowlevel.c
@@ -86,8 +86,9 @@ lowlevel_fc_analyse (sniffer_phy_t *ctx, const u32 *fc_av,
else if (fc->sof.num_sym == 2)
symb_nb = 2;
else
- symb_nb = ((fl_tck - rifs_tck - 2 * MAC_DX567_TCK)
- / symbol_tck[mpdu->tm->gil] + 2);
+ symb_nb = (fl_tck > rifs_tck + 2 * MAC_DX567_TCK)?
+ ((fl_tck - rifs_tck - 2 * MAC_DX567_TCK)
+ / symbol_tck[mpdu->tm->gil] + 2):0;
/* Compute number of PB. */
uint bits_per_pb = mpdu->tm->bits_per_pb[PHY_PB_SIZE_520];
uint bits_per_symbol = mpdu->tm->bits_per_symbol;
@@ -293,7 +294,11 @@ lowlevel_activate (sniffer_phy_t *ctx, bool state)
ARCH_CPU_TO_DMA (ctx->lowlevel.tonemask_info->tonemask),
ctx->lowlevel.tonemask_info->carrier_nb);
/* Set RX mode. */
+#if CONFIG_MAC_PBPROC_EOC_FC
+ phy_rx_param (ctx->lowlevel.phy, PHY_FC_MODE_AV_1);
+#else
phy_rx_param (ctx->lowlevel.phy, PHY_FC_MODE_HYBRID_1);
+#endif
}
/* Change RX state. */
phy_rx_activate (ctx->lowlevel.phy, true, 0, state);
diff --git a/cesar/tools/sniffer_phy/src/mme.c b/cesar/tools/sniffer_phy/src/mme.c
index c90d88bf4a..2ab60a7ff6 100644
--- a/cesar/tools/sniffer_phy/src/mme.c
+++ b/cesar/tools/sniffer_phy/src/mme.c
@@ -158,6 +158,67 @@ mme_handle_drv_sta_set_mac_addr_req (sniffer_phy_t *ctx, mme_buffer_t *mme)
}
/**
+ * Receive a DRV_STA_SET_TONEMASK.REQ.
+ * \param ctx sniffer context
+ * \param mme MME data
+ * \param tonemask received tonemask
+ * \return true on success
+ */
+static bool
+mme_handle_drv_sta_set_tonemask_req_receive (sniffer_phy_t *ctx,
+ mme_buffer_t *mme, u32 *tonemask)
+{
+ int i;
+ u32 w;
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (tonemask);
+
+ /* Skip over unused carriers, and check they are unused. */
+ for (i = PHY_CARRIER_OFFSET; i >= 32; i -= 32)
+ {
+ w = bitstream_read (&mme->bitstream, 32);
+ if (w != ~0u)
+ return false;
+ }
+ if (i)
+ {
+ w = bitstream_read (&mme->bitstream, i);
+ if (w != BITS_ONES (i))
+ return false;
+ }
+ /* Read used carriers. */
+ for (i = 0; i < PHY_TONEMASK_WORDS; i++)
+ {
+ *tonemask++ = bitstream_read (&mme->bitstream, 32);
+ }
+ /* Check last carriers are unused. */
+ if (PHY_CARRIER_NB % 32)
+ {
+ w = tonemask[-1] | BITS_ONES (PHY_CARRIER_NB % 32);
+ if (w != ~0u)
+ return false;
+ }
+ /* Skip last unused carriers, and check they are unused. */
+ for (i = PHY_ALL_CARRIER_NB - PHY_TONEMASK_WORDS * 32
+ - PHY_CARRIER_OFFSET;
+ i >= 32; i -= 32)
+ {
+ w = bitstream_read (&mme->bitstream, 32);
+ if (w != ~0u)
+ return false;
+ }
+ if (i)
+ {
+ w = bitstream_read (&mme->bitstream, i);
+ if (w != BITS_ONES (i))
+ return false;
+ }
+
+ return true;
+}
+
+/**
* Send a VS_SNIFFER.CNF.
* \param ctx sniffer context
* \param mme mme data
@@ -258,13 +319,20 @@ mme_handle_decode (sniffer_phy_t *ctx, mme_buffer_t *mme)
case DRV_STA_SET_MAC_ADDR_REQ:
mme_handle_drv_sta_set_mac_addr_req (ctx, mme);
break;
+ case DRV_STA_SET_TONEMASK_REQ:
+ {
+ u32 tonemask[PHY_TONEMASK_WORDS];
+ mme_handle_drv_sta_set_tonemask_req_receive (ctx, mme, tonemask);
+ memcpy (ctx->lowlevel.tonemask_info->tonemask, tonemask,
+ sizeof (tonemask));
+ tonemask_update (ctx->lowlevel.tonemask_info);
+ }
case DRV_STA_SET_CCO_PREF_REQ:
case DRV_STA_SET_WAS_CCO_REQ:
case DRV_STA_SET_SL_REQ:
case DRV_STA_SET_M_STA_HFID_REQ:
case DRV_STA_SET_U_STA_HFID_REQ:
case DRV_STA_SET_AVLN_HFID_REQ:
- case DRV_STA_SET_TONEMASK_REQ:
case DRV_STA_MAC_START_REQ:
case DRV_STA_SET_KEY_REQ:
case DRV_STA_SET_DAK_REQ:
@@ -334,7 +402,12 @@ mme_report_mpdu (sniffer_phy_t *ctx, lowlevel_rx_t *rx)
bitstream_write (bs, rx->fc10_bad_crc, 1);
bitstream_write (bs, rx->fc_bad_crc, 1);
bitstream_write (bs, pb ? pb->pb_measurement.crc_error : 0, 1);
+#if CONFIG_MAC_PBPROC_EOC_FC
+ bitstream_write (bs, 0, 12);
+ bitstream_write (bs, 1, 1);
+#else
bitstream_write (bs, 0, 13);
+#endif
bitstream_write (bs, pb ? rx->pb_nb : 0, 8);
bitstream_write (bs, pb ? i : 0, 8);
bitstream_write (bs, rx->date, 32);
diff --git a/cesar/tools/sniffer_phy/src/test_mme.c b/cesar/tools/sniffer_phy/src/test_mme.c
index f1cb0bdda5..582cf1749f 100644
--- a/cesar/tools/sniffer_phy/src/test_mme.c
+++ b/cesar/tools/sniffer_phy/src/test_mme.c
@@ -16,6 +16,7 @@
#include "common/defs/ethernet.h"
#include "lib/test.h"
+#include "mac/pbproc/inc/fc.h"
#include <string.h>
@@ -430,7 +431,8 @@ mme_mpdu_test (test_t t, sniffer_phy_t *ctx, const char *test_name,
0x000000a0,
0x0102d713,
(fc10_bad_crc ? 0x0001 : 0)
- | (fc_bad_crc ? 0x0002 : 0),
+ | (fc_bad_crc ? 0x0002 : 0)
+ | ((CONFIG_MAC_PBPROC_EOC_FC) ? 0x8000 : 0),
rx.date,
fc10_bad_crc ? 0xffffffff : rx.fc10,
fc_bad_crc ? 0xffffffff : rx.fc[0],
@@ -491,7 +493,8 @@ mme_mpdu_pb_test (test_t t, sniffer_phy_t *ctx, const char *test_name,
0xffd71300, 0x13004523, 0x3412ffd7, 0x2e01e188,
0x000000a0, 0x0102d713,
(pb_bad_crc & (1 << pb) ? 0x0004 : 0)
- | pb_nb << 16 | pb << 24,
+ | pb_nb << 16 | pb << 24
+ | ((CONFIG_MAC_PBPROC_EOC_FC) ? 0x8000 : 0),
rx.date, rx.fc10,
rx.fc[0], rx.fc[1], rx.fc[2], rx.fc[3]
};
@@ -549,6 +552,8 @@ mme_test_suite (test_t t)
{
test_suite_begin (t, "mme");
sniffer_phy_t ctx;
+ tonemask_info_t tonemask_info;
+ ctx.lowlevel.tonemask_info = &tonemask_info;
mme_init (&ctx);
ctx.mme.mac = TEST_MME_MAC;
ctx.mme.mac_sniffer = TEST_MME_MAC_PEER;