summaryrefslogtreecommitdiff
path: root/cesar/cp/msg
diff options
context:
space:
mode:
authorJérôme Jutteau2011-06-09 16:28:37 +0200
committerJérôme Jutteau2011-06-20 15:49:28 +0200
commit4db07063953ce1b8d090b107a2a222b5f167c831 (patch)
treeb6f80fed5023c5caa55ecead28ec1226996a8838 /cesar/cp/msg
parent6d5f11b59e9df2fccb28f6a904f05ee393ce3d44 (diff)
cesar/cp/msg: add a VS_GET_CE_STATS.CNF, refs #2375
Diffstat (limited to 'cesar/cp/msg')
-rw-r--r--cesar/cp/msg/inc/msg_vs.h16
-rw-r--r--cesar/cp/msg/inc/vs_get_ce_stats.h27
-rw-r--r--cesar/cp/msg/src/msg_vs.c148
-rw-r--r--cesar/cp/msg/test/src/msg_vs.c177
4 files changed, 368 insertions, 0 deletions
diff --git a/cesar/cp/msg/inc/msg_vs.h b/cesar/cp/msg/inc/msg_vs.h
index ea7b5cef09..a4d552773a 100644
--- a/cesar/cp/msg/inc/msg_vs.h
+++ b/cesar/cp/msg/inc/msg_vs.h
@@ -285,6 +285,22 @@ bool
cp_msg_vs_get_ce_stats_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
mac_t *mac_addr);
+/**
+ * Send a VS_GET_CE_STATS.CNF.
+ * \param ctx the control plane context.
+ * \param peer the peer info.
+ * \param version version of the mme.
+ * \param result result of VS_GET_CE_STATS.CNF.
+ * 0 if peer exists (success), 1 otherwise (failure).
+ * \param sta peer to stat. Ignored if result corresponds to failure.
+ * \param ti tonemask. Ignored if result corresponds to failure.
+ */
+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);
END_DECLS
#endif /* cp_msg_inc_msg_vs_h */
diff --git a/cesar/cp/msg/inc/vs_get_ce_stats.h b/cesar/cp/msg/inc/vs_get_ce_stats.h
new file mode 100644
index 0000000000..e8cffad487
--- /dev/null
+++ b/cesar/cp/msg/inc/vs_get_ce_stats.h
@@ -0,0 +1,27 @@
+#ifndef vs_get_ce_stats_h
+#define vs_get_ce_stats_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/msg/inc/vs_get_ce_stats.h
+ * \brief VS_GET_CE_STATS MME structures.
+ * \ingroup cp_msg
+ *
+ * For details about CE stats, look at
+ * cleopatre/devkit/docs/cleopatre_mme_specs.odt
+ */
+
+/** VS_GET_CE_STATS.CNF result. */
+enum cp_msg_vs_get_ce_stats_cnf_result_t
+{
+ CP_MSG_VS_GET_CE_STATS_CNF_RESULT_SUCCESS,
+ CP_MSG_VS_GET_CE_STATS_CNF_RESULT_FAILURE,
+ CP_MSG_VS_GET_CE_STATS_CNF_RESULT_NB
+};
+
+#endif /* vs_get_ce_stats_h */
diff --git a/cesar/cp/msg/src/msg_vs.c b/cesar/cp/msg/src/msg_vs.c
index c886e5512d..559948b5c7 100644
--- a/cesar/cp/msg/src/msg_vs.c
+++ b/cesar/cp/msg/src/msg_vs.c
@@ -25,6 +25,8 @@
#include "cp/msg/inc/msg.h"
#include "lib/stats.h"
+#include "ce/common/mod.h"
+
/**
* Receive a VS_GET_TONEMAP.REQ.
* \param ctx the control plane context.
@@ -681,3 +683,149 @@ cp_msg_vs_get_ce_stats_req_receive (cp_t *ctx, cp_mme_rx_t *mme,
}
return false;
}
+
+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)
+{
+ dbg_assert (ctx);
+ dbg_assert (result < CP_MSG_VS_GET_CE_STATS_CNF_RESULT_NB);
+
+ cp_mme_tx_t *mme = cp_msg_mme_init (ctx, peer, VS_GET_CE_STATS_CNF);
+ dbg_assert (mme);
+
+ bitstream_write (&mme->bitstream, version, 8);
+ bitstream_write (&mme->bitstream, result, 8);
+ /* Result success, peer exists. */
+ if (result == CP_MSG_VS_GET_CE_STATS_CNF_RESULT_SUCCESS)
+ {
+ dbg_assert (sta);
+ dbg_assert (sta->rx_tonemaps);
+ dbg_assert (sta->rx_tonemaps->intervals);
+ dbg_assert (ti);
+ bitstream_write (&mme->bitstream, sta->rx_tonemaps->default_tmi, 8);
+ u8 intervals_nb = sta->rx_tonemaps->intervals->intervals_nb;
+ bitstream_write (&mme->bitstream, intervals_nb, 8);
+ /* For each intervals. */
+ int i, m;
+ for (i = 0; i < intervals_nb; i++)
+ {
+ bitstream_write (
+ &mme->bitstream,
+ sta->rx_tonemaps->intervals->interval[i].end_offset_atu, 16);
+ if (sta->intervals)
+ bitstream_write (&mme->bitstream,
+ (i % mac_interval_repetition_count_) + 1,
+ 8);
+ else
+ bitstream_write (&mme->bitstream, 0, 8);
+ }
+ /* For each FSM. */
+ tonemap_t *tm;
+ int fsm_count = (sta->intervals ? mac_interval_fsm_count_ + 1 : 1);
+ for (i = 0; i < fsm_count; i++)
+ {
+ ce_rx_bitloading_t *bl;
+ u8 tmi;
+ /* Main FSM corresponds to 0. */
+ if (i == 0)
+ {
+ bl = &sta->ce_rx_bt;
+ tmi = sta->rx_tonemaps->default_tmi;
+ }
+ else
+ {
+ dbg_assert (sta->intervals);
+ bl = &sta->intervals->intervals[i - 1];
+ tmi = sta->intervals->tmi[i - 1];
+ }
+ dbg_assert (bl);
+ bitstream_write (&mme->bitstream, i, 8);
+ bitstream_write (&mme->bitstream, bl->fsm, 8);
+ bitstream_write (&mme->bitstream, tmi, 8);
+ bool is_negociated = TONEMAP_INDEX_IS_NEGOTIATED (tmi);
+ if (is_negociated)
+ tm = tonemap_get (sta->rx_tonemaps, tmi);
+ else if (tmi < PHY_MOD_ROBO_NB)
+ tm = &ti->tonemap_robo[tmi];
+ else
+ tm = NULL;
+
+ if (tm)
+ {
+ bitstream_write (&mme->bitstream, tm->fecrate, 8);
+ bitstream_write (&mme->bitstream, tm->ble, 8);
+
+ /* Simplified representation of tone map. */
+ u16 mod_count[CE_MOD_COUNT];
+ for (m = 0; m < CE_MOD_COUNT; m++)
+ mod_count[m] = 0;
+ if (is_negociated)
+ {
+ TONEMAP_READ_BEGIN (tm, ti->tonemask, m)
+ {
+ mod_count[m]++;
+ }
+ TONEMAP_READ_END;
+ }
+ for (m = 0; m < CE_MOD_COUNT; m++)
+ bitstream_write (&mme->bitstream, mod_count[m], 2 * 8);
+ bitstream_write_large (&mme->bitstream,
+ tm->ber_target,
+ 8 * 8);
+ bitstream_write_large (&mme->bitstream,
+ tm->ber_target_reached,
+ 8 * 8);
+ bitstream_write (&mme->bitstream, tm->nb_frame, 4 * 8);
+ bitstream_write (&mme->bitstream, tm->nb_pb, 4 * 8);
+ }
+ else
+ {
+ int tm_part_size = (1 + 1 + 16 + 8 + 8 + 4 + 4) * 8;
+ for (m = 0; m < tm_part_size / 64; m++)
+ bitstream_write_large (&mme->bitstream, 0, 64);
+ uint tmp = tm_part_size % 64;
+ if (tmp <= 32)
+ bitstream_write (&mme->bitstream, 0, tmp);
+ else
+ bitstream_write_large (&mme->bitstream, 0, tmp);
+ }
+
+ bitstream_write (&mme->bitstream, bl->stats.curr_nb_pb, 8);
+ bitstream_write (&mme->bitstream,
+ bl->stats.curr_nb_pb_crc_false,
+ 8);
+ bitstream_write (&mme->bitstream, bl->stats.curr_ber_sum, 4 * 8);
+ for (m = 0; m < CE_RX_BL_BER_SLIDING_MEAN_NB; m++)
+ bitstream_write_large (&mme->bitstream,
+ bl->stats.curr_ber_mean[m],
+ 8 * 8);
+ bitstream_write (&mme->bitstream,
+ bl->stats.curr_pberr_rate_mean,
+ 4 * 8);
+ for (m = 0; m < CE_RX_BL_RESTART_REASON_NB; m++)
+ bitstream_write (&mme->bitstream, bl->stats.restart_reason[m],
+ 4 * 8);
+ bitstream_write_large (&mme->bitstream,
+ bl->stats.prev_ber_target,
+ 8 * 8);
+ bitstream_write_large (&mme->bitstream,
+ bl->stats.prev_ber_target_reached,
+ 8 * 8);
+ for (m = 0; m < CE_RX_BL_BER_SLIDING_MEAN_NB; m++)
+ bitstream_write_large (&mme->bitstream,
+ bl->stats.prev_ber_mean[m],
+ 8 * 8);
+ bitstream_write (&mme->bitstream,
+ bl->stats.prev_pberr_rate_mean,
+ 4 * 8);
+ bitstream_write (&mme->bitstream, bl->stats.last_restart_reason, 8);
+ }
+ }
+
+ bitstream_write_finalise (&mme->bitstream);
+ cp_msg_mme_send (ctx, mme);
+}
diff --git a/cesar/cp/msg/test/src/msg_vs.c b/cesar/cp/msg/test/src/msg_vs.c
index af78406ce1..b06e955f38 100644
--- a/cesar/cp/msg/test/src/msg_vs.c
+++ b/cesar/cp/msg/test/src/msg_vs.c
@@ -28,6 +28,7 @@
#include "cp/msg/inc/msg.h"
#include "mac/common/tonemap.h"
+#include "ce/common/mod.h"
struct mme_header_t
{
@@ -1569,6 +1570,88 @@ test_case_msg_vs_get_ce_stats_req_receive_test_case (test_t test,
}
void
+test_case_msg_vs_get_ce_stats_cnf_send_test_case (test_t test,
+ bitstream_t *stream,
+ u8 version_id,
+ u8 result, sta_t *sta,
+ tonemask_info_t *ti,
+ u16 mod_array[CE_MOD_COUNT])
+{
+ test_within (test);
+ mme_header_t header;
+ mme_header_t expected;
+ int i;
+
+ /* Expected header */
+ expected.oda = peer.mac;
+ expected.osa = own_mac_addr;
+ expected.mmtype = VS_GET_CE_STATS_CNF;
+ expected.fmi_inf = 0;
+ expected.fmi_mi = 0;
+ expected.fmi_ssn = 0;
+
+ /* Read MME for Data comparison. */
+ test_read_header (test, false, &header, &expected, stream);
+
+ test_fail_unless (bitstream_read (stream, OUI_SIZE_BITS) == SPC_OUI);
+ test_fail_unless (bitstream_read (stream, 8) == version_id);
+ test_fail_unless (bitstream_read (stream, 8) == result);
+ if (result)
+ return;
+ tonemaps_t *tms = sta->rx_tonemaps;
+ test_fail_unless (bitstream_read (stream, 8) == tms->default_tmi);
+ uint inb = tms->intervals->intervals_nb;
+ test_fail_unless (bitstream_read (stream, 8) == inb);
+ /* We don't support FSM intervals at this time TODO */
+ dbg_assert (inb == 0);
+
+ /* Id 0 must be the first FSM. */
+ test_fail_unless (bitstream_read (stream, 8) == 0);
+ ce_rx_bitloading_t *bt = &sta->ce_rx_bt;
+ test_fail_unless (bitstream_read (stream, 8) == bt->fsm);
+ uint tmi = tms->default_tmi;
+ test_fail_unless (bitstream_read (stream, 8) == tmi);
+ tonemap_t *tm = NULL;
+ if (TONEMAP_INDEX_IS_NEGOTIATED (tmi))
+ tm = tonemap_get (sta->rx_tonemaps, tmi);
+ else if (tmi < PHY_MOD_ROBO_NB)
+ tm = &ti->tonemap_robo[tmi];
+ test_fail_unless (bitstream_read (stream, 8) == (tm ? tm->fecrate : 0));
+ test_fail_unless (bitstream_read (stream, 8) == (tm ? tm->ble : 0));
+
+ for (i = 0; i < CE_MOD_COUNT; i++)
+ test_fail_unless (bitstream_read (stream, 16) == mod_array[i]);
+
+ test_fail_unless (bitstream_read_large (stream, 64)
+ == (tm ? tm->ber_target : 0));
+ test_fail_unless (bitstream_read_large (stream, 64)
+ == (tm ? tm->ber_target_reached : 0));
+ test_fail_unless (bitstream_read (stream, 32)
+ == (tm ? tm->nb_frame : 0));
+ test_fail_unless (bitstream_read (stream, 32)
+ == (tm ? tm->nb_pb : 0));
+
+ ce_rx_bitloading_stats_t *s = &bt->stats;
+ test_fail_unless (bitstream_read (stream, 8) == s->curr_nb_pb);
+ test_fail_unless (bitstream_read (stream, 8) == s->curr_nb_pb_crc_false);
+ test_fail_unless (bitstream_read (stream, 32) == s->curr_ber_sum);
+ for (i = 0; i < CE_RX_BL_BER_SLIDING_MEAN_NB; i++)
+ test_fail_unless (bitstream_read_large (stream, 64)
+ == s->curr_ber_mean[i]);
+ test_fail_unless (bitstream_read (stream, 32) == s->curr_pberr_rate_mean);
+ for (i = 0; i < CE_RX_BL_RESTART_REASON_NB; i++)
+ test_fail_unless (bitstream_read (stream, 32) == s->restart_reason[i]);
+ test_fail_unless (bitstream_read_large (stream, 64) == s->prev_ber_target);
+ test_fail_unless (bitstream_read_large (stream, 64)
+ == s->prev_ber_target_reached);
+ for (i = 0; i < CE_RX_BL_BER_SLIDING_MEAN_NB; i++)
+ test_fail_unless (bitstream_read_large (stream, 64)
+ == s->prev_ber_mean[i]);
+ test_fail_unless (bitstream_read (stream, 32) == s->prev_pberr_rate_mean);
+ test_fail_unless (bitstream_read (stream, 8) == s->last_restart_reason);
+}
+
+void
test_case_msg_vs_get_ce_stats (test_t test)
{
test_case_begin (test, "VS_GET_CE_STATS.REQ");
@@ -1596,6 +1679,100 @@ test_case_msg_vs_get_ce_stats (test_t test)
false);
}
test_end;
+
+ test_case_begin (test, "VS_GET_CE_STATS.CNF");
+
+ bitstream_t stream;
+ cp_msg_init (&cp);
+ sta_t sta;
+ sta_init (&sta, 51);
+ tonemask_info_t ti;
+ ti.carrier_nb = tonemask_default (ti.tonemask);
+ tonemask_update (&ti);
+ u16 mod_count[CE_MOD_COUNT];
+ int i;
+ test_begin (test, "result fail")
+ {
+ cp_msg_vs_get_ce_stats_cnf_send (&cp, &peer, 1, 1, NULL, NULL);
+ test_case_msg_vs_get_ce_stats_cnf_send_test_case (test, &stream, 1, 1,
+ NULL, NULL, NULL);
+ }
+ test_end;
+
+ test_begin (test, "result success, not having a negotiated tone map yet.")
+ {
+ for (i = 0; i < CE_MOD_COUNT; i++)
+ mod_count[i] = 0;
+ cp_msg_vs_get_ce_stats_cnf_send (&cp, &peer, 42, 0, &sta, &ti);
+ test_case_msg_vs_get_ce_stats_cnf_send_test_case (test, &stream, 42, 0,
+ &sta, &ti, mod_count);
+ }
+ test_end;
+
+ test_begin (test, "result success, having a tone map.")
+ {
+ tonemap_t *tm = tonemap_alloc ();
+
+ /* Create a tone map. */
+ for (i = 0; i < CE_MOD_COUNT; i++)
+ mod_count[i] = 0;
+ int cpt = 0;
+ TONEMAP_WRITE_BEGIN (tm, ti.tonemask)
+ {
+ mod_count[cpt]++;
+ TONEMAP_WRITE_MOD (cpt++);
+ if (cpt == CE_MOD_COUNT)
+ cpt = 0;
+ }
+ TONEMAP_WRITE_END;
+ tm->fecrate = cpt++;
+ tm->ble = cpt++;
+ tm->ber_target = cpt++;
+ tm->ber_target_reached = cpt++;
+ tm->nb_frame = cpt++;
+ tm->nb_pb = cpt++;
+
+ sta.ce_rx_bt.fsm = cpt++;
+ sta.rx_tonemaps->default_tmi =
+ tonemaps_set_first_free_tmi (sta.rx_tonemaps, tm);
+
+ /* Tweak stats. */
+ ce_rx_bitloading_stats_t *s = &sta.ce_rx_bt.stats;
+ s->curr_nb_pb = cpt++;
+ s->curr_nb_pb_crc_false = cpt++;
+ s->curr_ber_sum = cpt++;
+ for (i = 0; i < CE_RX_BL_BER_SLIDING_MEAN_NB; i++)
+ s->curr_ber_mean[i] = cpt++;
+ s->curr_pberr_rate_mean = cpt++;
+ for (i = 0; i < CE_RX_BL_RESTART_REASON_NB; i++)
+ s->restart_reason[i] = cpt++;
+ s->prev_ber_target = cpt++;
+ s->prev_ber_target_reached = cpt++;
+ for (i = 0; i < CE_RX_BL_BER_SLIDING_MEAN_NB; i++)
+ s->prev_ber_mean[i] = cpt++;
+ s->prev_pberr_rate_mean = cpt++;
+ s->last_restart_reason = cpt++;
+
+ cp_msg_vs_get_ce_stats_cnf_send (&cp, &peer, 42, 0, &sta, &ti);
+ test_case_msg_vs_get_ce_stats_cnf_send_test_case (test, &stream, 42, 0,
+ &sta, &ti, mod_count);
+ }
+ test_end;
+
+ test_begin (test, "result success, using a ROBO tone map.")
+ {
+ for (i = 0; i < CE_MOD_COUNT; i++)
+ mod_count[i] = 0;
+ sta.rx_tonemaps->default_tmi = PHY_MOD_ROBO;
+
+ cp_msg_vs_get_ce_stats_cnf_send (&cp, &peer, 42, 0, &sta, &ti);
+ test_case_msg_vs_get_ce_stats_cnf_send_test_case (test, &stream, 42, 0,
+ &sta, &ti, mod_count);
+ }
+ test_end;
+
+ sta_uninit (&sta);
+ cp_msg_uninit (&cp);
}
void