summaryrefslogtreecommitdiff
path: root/cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c')
-rw-r--r--cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c353
1 files changed, 353 insertions, 0 deletions
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..d61c8b35c0
--- /dev/null
+++ b/cesar/mac/pbproc/test/pbproc_eoc/src/rx_sound.c
@@ -0,0 +1,353 @@
+/* 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 ctx reception status. */
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ prep->valid = true;
+ prep->bbf = true;
+ prep->dtei = 25;
+ /* 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 = 25,
+ .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,
+ .lid = lid,
+ .fl_tck = rx_fl_tck,
+ .pending_seg_info = 0,
+ .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, 25, 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, 25));
+ } 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,
+ NFU_WRONG_STATION,
+};
+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;
+ /* Prepare context. */
+ pbproc_prep_mpdu_t *prep = &tp->pbproc->prep_mpdu;
+ prep->valid = true;
+ prep->bbf = true;
+ prep->dtei = nfu == NFU_WRONG_STATION ? 100 : 25;
+ /* 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. Direction is STA->CCO. */
+ pbproc_fc_sound_t sound_fc = {
+ .dt_av = PBPROC_FC_DT_SOUND,
+ .access = false,
+ .snid = tp->snid,
+ .dtei = 25,
+ .direction = 1,
+ .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,
+ };
+ /* Late set of date. */
+ prep->tx_date = date;
+ 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;
+ if (nfu == NFU_OUT_OF_ALLOC)
+ date = TEST_PBPROC_ALLOC_END_DATE + MAC_TOLERANCE_TCK
+ - length_tck + MAC_CIFS_TCK + 1;
+ 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 = nfu == NFU_WRONG_STATION ? 0 : 1,
+ .rx_nfu = nfu == NFU_WRONG_STATION ? 1 : 0,
+ .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_begin (t, "nfu wrong station")
+ {
+ rx_sound_nfu_test (t, &tp, 123456, NFU_WRONG_STATION);
+ } 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;
+}
+