summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
Diffstat (limited to 'cesar')
-rw-r--r--cesar/ce/rx/bitloading/bitloading.h7
-rw-r--r--cesar/ce/rx/bitloading/src/transition.c39
-rw-r--r--cesar/ce/rx/bitloading/test/override/cyg/kernel/kapi.h2
-rw-r--r--cesar/ce/rx/bitloading/test/src/ecos_stub.c4
-rw-r--r--cesar/ce/rx/bitloading/test/src/test_fsm.c74
5 files changed, 123 insertions, 3 deletions
diff --git a/cesar/ce/rx/bitloading/bitloading.h b/cesar/ce/rx/bitloading/bitloading.h
index 87616a96f1..78d56928dc 100644
--- a/cesar/ce/rx/bitloading/bitloading.h
+++ b/cesar/ce/rx/bitloading/bitloading.h
@@ -149,6 +149,11 @@ typedef struct ce_rx_bitloading_t
ce_rx_bitloading_stats_t stats;
/** PBER context. */
ce_rx_bl_pber_t pber;
+ /** Need to resend tone map to TX? */
+ bool resend_tm;
+ /** Timer to know when to re-send the tone map (if TX peer does not use
+ * default TMI). */
+ uint resend_tm_date;
} ce_rx_bitloading_t;
/**
@@ -239,6 +244,8 @@ ce_rx_bitloading_init (ce_rx_bitloading_t *bt)
#if MODULE_INCLUDED (ce_rx_bitloading)
ce_rx_bl_pber_reset (&bt->pber);
#endif
+ bt->resend_tm = false;
+ bt->resend_tm_date = 0;
}
/**
diff --git a/cesar/ce/rx/bitloading/src/transition.c b/cesar/ce/rx/bitloading/src/transition.c
index ea2f5cb8b6..55d778e07f 100644
--- a/cesar/ce/rx/bitloading/src/transition.c
+++ b/cesar/ce/rx/bitloading/src/transition.c
@@ -32,6 +32,11 @@
#include <cyg/kernel/kapi.h>
/**
+ * Minimum time to wait before transmitting the tone map again (in ms).
+ */
+const uint ce_rx_bl_min_time_between_resend_tm_ms = 3000;
+
+/**
* Common handler for initial CE when receiving measure for sound frames.
* \param ce_rx the context of the CE in RX
* \param sta the peer station
@@ -312,6 +317,9 @@ ce_rx_bl_fsm__TRACKING__data (ce_rx_t *ce_rx,
tm->nb_pb += measure->total_pb_count;
}
+ ce_rx_bitloading_t *bl = &sta->ce_rx_bt;
+ dbg_assert (bl);
+
/* Measure should only be processed if the TMI used is the one we are
* expecting.
* FIXME: this will not work with intervals. */
@@ -321,8 +329,8 @@ ce_rx_bl_fsm__TRACKING__data (ce_rx_t *ce_rx,
* corresponding tonemap. */
dbg_assert (tm);
- ce_rx_bitloading_t *bl = &sta->ce_rx_bt;
- dbg_assert (bl);
+ /* Reset flag to resend tone map. */
+ bl->resend_tm = false;
u8 good_pb_count = measure->total_pb_count - measure->false_pb_count;
u16 pb_size =
@@ -442,6 +450,33 @@ ce_rx_bl_fsm__TRACKING__data (ce_rx_t *ce_rx,
}
}
}
+ else
+ {
+ /* Measure is not received on expected TMI (CE MME with new tone map
+ * not received by TX for example). */
+ /* If this is the first measure. */
+ if (!bl->resend_tm)
+ {
+ /* Setup timer to resend MME. */
+ bl->resend_tm_date = cyg_current_time ()
+ + MAC_MS_TO_TCK (ce_rx_bl_min_time_between_resend_tm_ms)
+ / ce_rx->tck_per_rtc;
+ bl->resend_tm = true;
+ }
+ /* If not first measure, has enough time elapsed? */
+ else if (lesseq_mod2p32 (bl->resend_tm_date, cyg_current_time ()))
+ {
+ /* Resend TM. */
+ ce_rx_cp_send_mme_new_tone_map (ce_rx, sta,
+ sta->rx_tonemaps->default_tmi, 0,
+ false);
+ /* Increase statistics. */
+ ce_rx->stats.resend_tm++;
+ /* Reset timer and flag. */
+ bl->resend_tm_date = 0;
+ bl->resend_tm = false;
+ }
+ }
ce_debug_gpio_event
(CE_DEBUG_GPIO_EVENT_CE_RX_BL_MEASURE_DATA_NORMAL, true);
return ce_rx_bl_fsm_next_branch (TRACKING, data, no_channel_change);
diff --git a/cesar/ce/rx/bitloading/test/override/cyg/kernel/kapi.h b/cesar/ce/rx/bitloading/test/override/cyg/kernel/kapi.h
index 13846e160d..ffc4b3b8f5 100644
--- a/cesar/ce/rx/bitloading/test/override/cyg/kernel/kapi.h
+++ b/cesar/ce/rx/bitloading/test/override/cyg/kernel/kapi.h
@@ -13,6 +13,8 @@
* \ingroup test
*/
+extern u32 ecos_time;
+
u32
cyg_current_time (void);
diff --git a/cesar/ce/rx/bitloading/test/src/ecos_stub.c b/cesar/ce/rx/bitloading/test/src/ecos_stub.c
index bbad9a07bf..0f1079a6a9 100644
--- a/cesar/ce/rx/bitloading/test/src/ecos_stub.c
+++ b/cesar/ce/rx/bitloading/test/src/ecos_stub.c
@@ -14,8 +14,10 @@
#include <cyg/kernel/kapi.h>
+u32 ecos_time = 0;
+
u32
cyg_current_time (void)
{
- return 0;
+ return ecos_time;
}
diff --git a/cesar/ce/rx/bitloading/test/src/test_fsm.c b/cesar/ce/rx/bitloading/test/src/test_fsm.c
index b0dacf1e85..be3bab8b9d 100644
--- a/cesar/ce/rx/bitloading/test/src/test_fsm.c
+++ b/cesar/ce/rx/bitloading/test/src/test_fsm.c
@@ -50,6 +50,7 @@ uint ce_rx_bl_pb_total_factor_;
uint ce_rx_bl_min_pb_per_frame_;
uint ce_rx_bl_min_frame_with_high_pb_err_rate_;
uint ce_rx_bl_ber_lower_bound_ = 38;
+extern uint ce_rx_bl_min_time_between_resend_tm_ms;
static uint const tmi_av = 24;
@@ -129,6 +130,7 @@ test_ce_rx_bl_fsm_base (test_t t)
scenario_globals_t globals = {
.ce = &ce,
};
+ ce.tck_per_rtc = 1;
sta_t sta;
tonemaps_t rx_tms, tx_tms;
@@ -954,6 +956,78 @@ test_ce_rx_bl_fsm_base (test_t t)
ce_rx_bitloading_uninit (&sta.ce_rx_bt);
}test_end;
+ test_case_begin (t, "TM resend mechanism");
+
+ ce_rx_bitloading_init (&sta.ce_rx_bt);
+ test_ce_rx_bl_reset (&sta.ce_rx_bt);
+ test_ce_rx_bl_measure_empty (&measure);
+ measure.rx_params.tmi_av = rx_tms.default_tmi - 1;
+ measure.total_pb_count = 0x42;
+ measure.false_pb_count = 0;
+ uint pos;
+ uint next_time = MAC_MS_TO_TCK (ce_rx_bl_min_time_between_resend_tm_ms)
+ / ce.tck_per_rtc;
+
+ test_begin (t, "first frame not on expected TMI, should init time & flag")
+ {
+ test_fail_if (sta.ce_rx_bt.resend_tm != false);
+ test_fail_if (sta.ce_rx_bt.resend_tm_date != 0);
+
+ ecos_time = 0x4242;
+ pos = 0;
+ scenario_test[pos++] = (scenario_entry_t)
+ SCENARIO_ACTION (TRACKING__data,
+ .sta = &sta,
+ .measure = measure,
+ .branch = ce_rx_bl_fsm_next_branch
+ (TRACKING, data, no_channel_change));
+ scenario_test[pos++] = scenario_end;
+ scenario_run (t, scenario_test, &globals);
+
+ test_fail_if (sta.ce_rx_bt.resend_tm != true);
+ test_fail_if (sta.ce_rx_bt.resend_tm_date != ecos_time + next_time);
+ } test_end;
+
+ test_begin (t, "many frames not on expected TMI, current time under resend one, "
+ "should not change time & flag")
+ {
+ pos = 0;
+ uint old_ecos_time = ecos_time;
+ for (i = 0; i < 42; i++, ++ecos_time)
+ {
+ scenario_test[pos++] = (scenario_entry_t)
+ SCENARIO_ACTION (TRACKING__data,
+ .sta = &sta,
+ .measure = measure,
+ .branch = ce_rx_bl_fsm_next_branch
+ (TRACKING, data, no_channel_change));
+ scenario_test[pos++] = scenario_end;
+ scenario_run (t, scenario_test, &globals);
+
+ test_fail_if (sta.ce_rx_bt.resend_tm != true);
+ test_fail_if (sta.ce_rx_bt.resend_tm_date != old_ecos_time + next_time);
+ }
+ } test_end;
+
+ test_begin (t, "enough time on next frame, send and reset flag & time")
+ {
+ pos = 0;
+ ecos_time = sta.ce_rx_bt.resend_tm_date + 1;
+ scenario_test[pos++] = (scenario_entry_t)
+ SCENARIO_ACTION (TRACKING__data,
+ .sta = &sta,
+ .measure = measure,
+ .branch = ce_rx_bl_fsm_next_branch
+ (TRACKING, data, no_channel_change));
+ scenario_test[pos++] = scenario_end;
+ scenario_run (t, scenario_test, &globals);
+
+ test_fail_if (sta.ce_rx_bt.resend_tm != false);
+ test_fail_if (sta.ce_rx_bt.resend_tm_date != 0);
+ } test_end;
+
+ /* Clean. */
+ ce_rx_bitloading_uninit (&sta.ce_rx_bt);
}
int