summaryrefslogtreecommitdiff
path: root/cesar/mac/common/test
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/mac/common/test')
-rw-r--r--cesar/mac/common/test/ntb/Makefile10
-rw-r--r--cesar/mac/common/test/ntb/src/test_ntb.c55
-rw-r--r--cesar/mac/common/test/ntb/src/test_ntb_phy_unstub.c47
-rw-r--r--cesar/mac/common/test/pb/Makefile13
-rw-r--r--cesar/mac/common/test/pb/src/test_pb.c74
-rw-r--r--cesar/mac/common/test/store/Makefile10
-rw-r--r--cesar/mac/common/test/store/override/mac/common/mfs.h71
-rw-r--r--cesar/mac/common/test/store/override/mac/common/sta.h37
-rw-r--r--cesar/mac/common/test/store/src/test_store.c371
-rw-r--r--cesar/mac/common/test/tonemap/Makefile7
-rw-r--r--cesar/mac/common/test/tonemap/src/test_tonemap.c258
11 files changed, 953 insertions, 0 deletions
diff --git a/cesar/mac/common/test/ntb/Makefile b/cesar/mac/common/test/ntb/Makefile
new file mode 100644
index 0000000000..ca7ca69b34
--- /dev/null
+++ b/cesar/mac/common/test/ntb/Makefile
@@ -0,0 +1,10 @@
+BASE = ../../../..
+
+HOST_PROGRAMS = test_ntb test_ntb_phy_unstub
+test_ntb_SOURCES = test_ntb.c
+test_ntb_MODULES = mac/common lib
+
+test_ntb_phy_unstub_SOURCES = test_ntb_phy_unstub.c
+test_ntb_phy_unstub_MODULES = mac/common lib
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/common/test/ntb/src/test_ntb.c b/cesar/mac/common/test/ntb/src/test_ntb.c
new file mode 100644
index 0000000000..eb7e6570de
--- /dev/null
+++ b/cesar/mac/common/test/ntb/src/test_ntb.c
@@ -0,0 +1,55 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file mac/common/test/ntb/src/test_ntb.c
+ * \brief test the ntb date.
+ * \ingroup mac_common
+ *
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "lib/blk.h"
+#include "mac/common/ntb.h"
+#include "mac/common/config.h"
+#include "hal/phy/phy.h"
+
+
+int main (void)
+{
+ test_t test;
+
+ mac_config_t mac_config;
+ phy_t *phy;
+
+ test_init(test, 0, NULL);
+
+ phy = blk_alloc();
+
+ mac_ntb_init(phy, &mac_config);
+ mac_config.ntb_offset_tck = 10;
+
+ test_begin(test, "test ntb")
+ {
+ test_fail_if(mac_ntb() != 62, "Error on getting ntb date");
+ }
+ test_end;
+
+ mac_ntb_uninit();
+ blk_release(phy);
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
+
+u32
+phy_date (phy_t *phy)
+{
+ dbg_assert(phy);
+ return 52;
+}
+
diff --git a/cesar/mac/common/test/ntb/src/test_ntb_phy_unstub.c b/cesar/mac/common/test/ntb/src/test_ntb_phy_unstub.c
new file mode 100644
index 0000000000..2fbc005081
--- /dev/null
+++ b/cesar/mac/common/test/ntb/src/test_ntb_phy_unstub.c
@@ -0,0 +1,47 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file mac/common/test/ntb/src/test_ntb.c
+ * \brief test the ntb date.
+ * \ingroup mac_common
+ *
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "lib/blk.h"
+#include "mac/common/ntb.h"
+#include "mac/common/config.h"
+
+
+int main (void)
+{
+ test_t test;
+
+ mac_config_t mac_config;
+ phy_t *phy;
+
+ test_init(test, 0, NULL);
+
+ phy = blk_alloc();
+
+ mac_ntb_init (phy, &mac_config);
+ mac_config.ntb_offset_tck = 10;
+
+ test_begin(test, "test ntb")
+ {
+ test_fail_if(mac_ntb() != 52, "Error on getting ntb date");
+ }
+ test_end;
+
+ mac_ntb_uninit();
+ blk_release (phy);
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/mac/common/test/pb/Makefile b/cesar/mac/common/test/pb/Makefile
new file mode 100644
index 0000000000..35e3504cc4
--- /dev/null
+++ b/cesar/mac/common/test/pb/Makefile
@@ -0,0 +1,13 @@
+BASE = ../../../..
+
+TARGET = sparc
+
+HOST_PROGRAMS = test_pb
+test_pb_SOURCES = test_pb.c
+test_pb_MODULES = mac/common lib
+
+TARGET_PROGRAMS = test_pb_target
+test_pb_target_SOURCES = test_pb.c
+test_pb_target_MODULES = mac/common lib
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/common/test/pb/src/test_pb.c b/cesar/mac/common/test/pb/src/test_pb.c
new file mode 100644
index 0000000000..44b7b45531
--- /dev/null
+++ b/cesar/mac/common/test/pb/src/test_pb.c
@@ -0,0 +1,74 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_pb.c
+ * \brief Test the PB descriptor.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "mac/common/pb.h"
+
+#include "lib/test.h"
+
+void
+pb_basic_test_case (test_t t)
+{
+ pb_t pb;
+ pb_header_t h;
+ /* Fill using the bit-fields, read using the word. */
+ test_begin (t, "fields to words")
+ {
+ h.ssn = 0x4242;
+ h.mfbo = 0x12;
+ h.vpbf = true;
+ h.mmqf = false;
+ h.mfbf = true;
+ h.opsf = false;
+ h.rsvd = 0;
+ pb.header = h;
+ test_fail_unless (sizeof (h) == 4);
+ test_fail_unless (pb.phy_pb.pb_tx.header == 0x0a124242);
+ } test_end;
+ /* Fill using phy struct, read using MAC struct (this is not a real life
+ * test!). */
+ test_begin (t, "phy to mac")
+ {
+ pb.phy_pb.pb_tx.blk.next = (blk_t *) &pb;
+ pb.phy_pb.pb_tx.blk.data = NULL;
+ test_fail_unless (pb.next == &pb);
+ test_fail_unless (pb.data == NULL);
+ pb.phy_pb.pb_rx.pb_measurement.ber = 0x5aa5;
+ pb.phy_pb.pb_rx.pb_measurement.halfit = 0x12;
+ pb.phy_pb.pb_rx.pb_measurement.crc_error = true;
+ test_fail_unless ((pb.expiration_ntb & 0x3fffff) == 0x325aa5);
+ pb.phy_pb.chandata.size = 0x12;
+ pb.phy_pb.chandata.last = true;
+ pb.phy_pb.chandata.type = 6;
+ pb.phy_pb.chandata.address = 0x123;
+ test_fail_unless ((pb.phy_pb.pb_tx.header & 0xfff01fff) ==
+ 0x12300d12);
+ } test_end;
+}
+
+void
+pb_test_suite (test_t t)
+{
+ test_suite_begin (t, "pb");
+ pb_basic_test_case (t);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ pb_test_suite (t);
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/mac/common/test/store/Makefile b/cesar/mac/common/test/store/Makefile
new file mode 100644
index 0000000000..c25b723db7
--- /dev/null
+++ b/cesar/mac/common/test/store/Makefile
@@ -0,0 +1,10 @@
+BASE = ../../../..
+
+INCLUDES = mac/common/test/store/override
+
+HOST_PROGRAMS = test_store
+test_store_SOURCES = test_store.c
+test_store_MODULES = lib mac/common
+mac_common_MODULE_SOURCES = store.c
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/common/test/store/override/mac/common/mfs.h b/cesar/mac/common/test/store/override/mac/common/mfs.h
new file mode 100644
index 0000000000..d6740192ce
--- /dev/null
+++ b/cesar/mac/common/test/store/override/mac/common/mfs.h
@@ -0,0 +1,71 @@
+#ifndef overide_mac_common_mfs_h
+#define overide_mac_common_mfs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/common/mfs.h
+ * \brief Override the MFS definition for test.
+ * \ingroup test
+ */
+#include "mac/common/defs.h"
+
+struct mfs_common_t
+{
+ bool tx:1;
+ bool bcast:1;
+ bool mme:1;
+ u8 lid;
+ u8 tei;
+ u8 lid_alias;
+};
+typedef struct mfs_common_t mfs_common_t;
+
+struct mfs_rx_t
+{
+ mfs_common_t common;
+};
+typedef struct mfs_rx_t mfs_rx_t;
+
+struct mfs_tx_t
+{
+ mfs_common_t common;
+};
+typedef struct mfs_tx_t mfs_tx_t;
+
+union mfs_t
+{
+ mfs_common_t common;
+ mfs_rx_t rx;
+ mfs_tx_t tx;
+};
+typedef union mfs_t mfs_t;
+
+extern inline void
+mfs_init (mfs_t *mfs, bool tx, bool bcast, bool mme, uint lid, uint tei)
+{
+ mfs->common.tx = tx;
+ mfs->common.bcast = bcast;
+ mfs->common.mme = mme;
+ mfs->common.lid = lid;
+ mfs->common.tei = tei;
+ mfs->common.lid_alias = MAC_LID_NONE;
+}
+
+extern inline void
+mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
+{
+ mfs_init (PARENT_OF (mfs_t, tx, mfs), true, bcast, mme, lid, tei);
+}
+
+extern inline void
+mfs_rx_init (mfs_rx_t *mfs, bool bcast, bool mme, uint lid, uint tei)
+{
+ mfs_init (PARENT_OF (mfs_t, rx, mfs), false, bcast, mme, lid, tei);
+}
+
+#endif /* overide_mac_common_mfs_h */
diff --git a/cesar/mac/common/test/store/override/mac/common/sta.h b/cesar/mac/common/test/store/override/mac/common/sta.h
new file mode 100644
index 0000000000..90fd84983e
--- /dev/null
+++ b/cesar/mac/common/test/store/override/mac/common/sta.h
@@ -0,0 +1,37 @@
+#ifndef overide_mac_common_sta_h
+#define overide_mac_common_sta_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file overide/mac/common/sta.h
+ * \brief Override the STA definition for test.
+ * \ingroup test
+ */
+#include "lib/blk.h"
+
+struct sta_t
+{
+ uint tei;
+ u8 *dyn;
+};
+typedef struct sta_t sta_t;
+
+extern inline void
+sta_init (sta_t *sta, uint tei)
+{
+ sta->tei = tei;
+ sta->dyn = blk_alloc ();
+}
+
+static inline void
+sta_uninit (sta_t *sta)
+{
+ blk_release (sta->dyn);
+}
+
+#endif /* overide_mac_common_sta_h */
diff --git a/cesar/mac/common/test/store/src/test_store.c b/cesar/mac/common/test/store/src/test_store.c
new file mode 100644
index 0000000000..2ee9bb77a0
--- /dev/null
+++ b/cesar/mac/common/test/store/src/test_store.c
@@ -0,0 +1,371 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_store.c
+ * \brief Test MAC store.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "mac/common/store.h"
+#include "mac/common/mfs.h"
+#include "mac/common/sta.h"
+#include "mac/common/defs.h"
+
+#include "lib/test.h"
+#include "lib/rnd.h"
+#include "lib/blk.h"
+
+#include <string.h>
+
+#define NB_ITER 200000
+#define NB_MFS 10000
+
+struct test_store_t
+{
+ lib_rnd_t rnd[1];
+ mac_store_t *store;
+ mfs_t *used_mfs[NB_MFS];
+ bool used_mfs_set[2][2][2][MAC_LID_BEACON_MAX + 1][MAC_TEI_STA_MAX + 1];
+ uint used_mfs_nb, used_mfs_max;
+ bool used_tei[MAC_TEI_STA_MAX + 1];
+ uint used_tei_nb, used_tei_max;
+ uint travel_mfs_nb, travel_mfs_alias_nb;
+};
+typedef struct test_store_t test_store_t;
+
+/**
+ * Return a pointer to the used MFS set slot.
+ * \param ctx test_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
+ * \return pointer to the requested slot
+ */
+static bool *
+used_mfs (test_store_t *ctx, bool tx, bool bcast, bool mme, uint lid,
+ uint tei)
+{
+ /* GLID slots are the same for RX and TX. */
+ bool utx = MAC_LID_IS_GLID (lid) ? false : tx;
+ /* Connection based links use the same slot for unicast and broadcast. */
+ bool ubcast = MAC_LID_IS_CLID (lid) ? false : bcast;
+ /* GLID slots and TX LLID slots are the same for any TEI. */
+ uint utei = MAC_LID_IS_GLID (lid) || (MAC_LID_IS_LLID (lid) && tx) ? 0 : tei;
+ /* MAC_LID_NONE is not in the table. */
+ uint ulid = lid == MAC_LID_NONE ? 0 : lid;
+ return &ctx->used_mfs_set[utx][ubcast][mme][ulid][utei];
+}
+
+/**
+ * Create a random MFS.
+ * \param ctx test_store context
+ * \param t test context
+ */
+static void
+add_rnd_mfs (test_store_t *ctx, test_t t)
+{
+ test_within (t);
+ bool tx, bcast, mme;
+ uint lid, tei, lid_alias;
+ /* Find a free slot. */
+ do
+ {
+ 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);
+ if (lid >= MAC_LID_NB)
+ {
+ tx = true;
+ bcast = true;
+ mme = false;
+ lid = lid == MAC_LID_NB ? MAC_LID_DISCOVER : MAC_LID_SPC_CENTRAL;
+ }
+ lid_alias = MAC_LID_IS_GLID (lid)
+ ? lib_rnd_uniform (ctx->rnd, MAC_LLID_NB) + MAC_LLID_MIN
+ : MAC_LID_NONE;
+ tei = tx && bcast
+ ? MAC_TEI_BCAST
+ : lib_rnd_uniform (ctx->rnd, MAC_TEI_STA_NB) + MAC_TEI_STA_MIN;
+ } while (*used_mfs (ctx, tx, bcast, mme, lid, tei)
+ || (lid_alias != MAC_LID_NONE
+ && *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. */
+ if (MAC_TEI_IS_STA (tei) && !ctx->used_tei[tei]
+ && !((tx && bcast) || (tx && MAC_LID_IS_LLID (addlid))
+ || MAC_LID_IS_GLID (addlid)))
+ {
+ ctx->used_tei[tei] = true;
+ ctx->used_tei_nb++;
+ if (ctx->used_tei_nb > ctx->used_tei_max)
+ ctx->used_tei_nb = ctx->used_tei_max;
+ }
+ /* Add the MFS. */
+ bool added = false;
+ mfs_t *m = mac_store_mfs_add (ctx->store, tx, bcast, mme, addlid, tei,
+ &added);
+ test_fail_unless (added);
+ test_fail_unless (m);
+ blk_release (m);
+ m = mac_store_mfs_add (ctx->store, tx, bcast, mme, addlid, tei, &added);
+ test_fail_unless (!added);
+ test_fail_unless (m);
+ test_fail_unless (m->common.tx == tx && m->common.bcast == bcast
+ && m->common.mme == mme && m->common.lid == addlid
+ && m->common.tei == tei);
+ *used_mfs (ctx, tx, bcast, mme, addlid, tei) = true;
+ /* Add the alias. */
+ if (lid_alias != MAC_LID_NONE)
+ {
+ mac_store_mfs_alias (ctx->store, m, lid);
+ test_fail_unless (m->common.lid == lid
+ && m->common.lid_alias == lid_alias);
+ *used_mfs (ctx, tx, bcast, mme, lid, tei) = true;
+ }
+ blk_release (m);
+ /* Store a pointer in the used_mfs table, without any reference. THIS IS
+ * TEST ONLY CODE, DO NOT DO THE SAME! */
+ ctx->used_mfs[ctx->used_mfs_nb++] = m;
+ if (ctx->used_mfs_nb > ctx->used_mfs_max)
+ ctx->used_mfs_max = ctx->used_mfs_nb;
+ /* Check if the STA exists. */
+ if (MAC_TEI_IS_STA (tei))
+ {
+ sta_t *sta = mac_store_sta_get (ctx->store, tei);
+ if (sta)
+ {
+ test_fail_unless (ctx->used_tei[tei] && sta->tei == tei);
+ blk_release (sta);
+ }
+ else
+ {
+ test_fail_unless (!ctx->used_tei[tei]);
+ }
+ }
+}
+
+void
+remove_mfs (test_store_t *ctx, test_t t, int mfs_index)
+{
+ test_within (t);
+ dbg_assert (ctx);
+ dbg_assert (mfs_index < NB_MFS);
+ mfs_t *m = ctx->used_mfs[mfs_index];
+ mfs_common_t c = m->common;
+ /* Update test structure. */
+ ctx->used_mfs[mfs_index] = ctx->used_mfs[--ctx->used_mfs_nb];
+ ctx->used_mfs[ctx->used_mfs_nb] = NULL;
+ *used_mfs (ctx, c.tx, c.bcast, c.mme, c.lid, c.tei) = false;
+ if (c.lid_alias != MAC_LID_NONE)
+ *used_mfs (ctx, c.tx, c.bcast, c.mme, c.lid_alias, c.tei) = false;
+ /* Check it is in the store. */
+ mfs_t *m2;
+ m2 = mac_store_mfs_get (ctx->store, c.tx, c.bcast, c.mme, c.lid, c.tei);
+ test_fail_unless (m2 == m);
+ blk_release (m2);
+ if (c.lid_alias != MAC_LID_NONE)
+ {
+ m2 = mac_store_mfs_get (ctx->store, c.tx, c.bcast, c.mme, c.lid_alias,
+ c.tei);
+ test_fail_unless (m2 == m);
+ blk_release (m2);
+ }
+ /* Remove. */
+ mac_store_mfs_remove (ctx->store, m);
+ /* Check it is no longer in the store. */
+ m2 = mac_store_mfs_get (ctx->store, c.tx, c.bcast, c.mme, c.lid, c.tei);
+ test_fail_unless (m2 == NULL);
+ if (c.lid_alias != MAC_LID_NONE)
+ {
+ m2 = mac_store_mfs_get (ctx->store, c.tx, c.bcast, c.mme, c.lid_alias,
+ c.tei);
+ test_fail_unless (m2 == NULL);
+ }
+}
+
+static void
+travel_remove (mac_store_t *store, mfs_t *mfs, void *user)
+{
+ uint i;
+ dbg_assert (store && mfs && user);
+ test_store_t *ctx = user;
+ mac_store_mfs_remove (store, mfs);
+ for (i = 0; i < ctx->used_mfs_nb; i++)
+ if (ctx->used_mfs[i] == mfs)
+ break;
+ dbg_assert (i < ctx->used_mfs_nb);
+ ctx->used_mfs[i] = ctx->used_mfs[--ctx->used_mfs_nb];
+ ctx->used_mfs[ctx->used_mfs_nb] = NULL;
+}
+
+static void
+travel_mfs (mac_store_t *store, mfs_t *mfs, void *user)
+{
+ dbg_assert (store && mfs && user);
+ test_store_t *ctx = user;
+ ctx->travel_mfs_nb++;
+ if (mfs->common.lid_alias != MAC_LID_NONE)
+ ctx->travel_mfs_alias_nb++;
+}
+
+void
+store_basic_test_case (test_t t)
+{
+ uint i;
+ test_store_t ctx[1];
+ test_case_begin (t, "basic");
+ /* Initialise. */
+ memset (ctx, 0, sizeof (ctx));
+ lib_rnd_init (ctx->rnd, 1234);
+ ctx->store = mac_store_init ();
+ /* OK, we will choose a random operation with random parameter and
+ * proceed :). */
+ test_begin (t, "random operation")
+ {
+ for (i = 0; i < NB_ITER; i++)
+ {
+ if (lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.95)))
+ {
+ /* MFS operation. */
+ int m1i = lib_rnd_uniform (ctx->rnd, NB_MFS);
+ mfs_t *m1 = ctx->used_mfs[m1i];
+ mfs_common_t *c1 = m1 ? &m1->common : NULL;
+ if (lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.8)))
+ {
+ /* Get. */
+ if (m1)
+ {
+ mfs_t *m2 = mac_store_mfs_get (ctx->store, c1->tx,
+ c1->bcast, c1->mme,
+ c1->lid, c1->tei);
+ test_fail_unless (m1 == m2);
+ blk_release (m2);
+ if (c1->lid_alias != MAC_LID_NONE)
+ {
+ m2 = mac_store_mfs_get (ctx->store, c1->tx,
+ c1->bcast, c1->mme,
+ c1->lid_alias, c1->tei);
+ test_fail_unless (m1 == m2);
+ blk_release (m2);
+ }
+ }
+ }
+ else
+ {
+ /* Add or remove. */
+ if (!m1)
+ add_rnd_mfs (ctx, t);
+ else
+ remove_mfs (ctx, t, m1i);
+ }
+ }
+ else
+ {
+ /* STA operation. */
+ uint tei = lib_rnd_uniform (ctx->rnd, MAC_TEI_STA_NB)
+ + MAC_TEI_STA_MIN;
+ if (lib_rnd_flip_coin (ctx->rnd, LIB_RND_RATIO (0.8)))
+ {
+ /* Get. */
+ sta_t *sta = mac_store_sta_get (ctx->store, tei);
+ test_fail_unless
+ ((ctx->used_tei[tei] && sta && sta->tei == tei)
+ || (!ctx->used_tei[tei] && sta == NULL));
+ if (sta)
+ blk_release (sta);
+ }
+ else
+ {
+ /* Add or remove. */
+ if (!ctx->used_tei[tei])
+ {
+ /* Add the STA. */
+ sta_t *sta;
+ sta = mac_store_sta_get (ctx->store, tei);
+ test_fail_unless (sta == NULL);
+ ctx->used_tei[tei] = true;
+ mac_store_sta_add (ctx->store, tei);
+ ctx->used_tei_nb++;
+ if (ctx->used_tei_nb > ctx->used_tei_max)
+ ctx->used_tei_max = ctx->used_tei_nb;
+ sta = mac_store_sta_get (ctx->store, tei);
+ test_fail_unless (sta && sta->tei == tei);
+ blk_release (sta);
+ }
+ else
+ {
+ /* Remove the STA. */
+ mac_store_mfs_travel_by_tei (ctx->store, tei,
+ travel_remove, ctx);
+ ctx->used_tei[tei] = false;
+ bool ok = mac_store_sta_remove (ctx->store, tei);
+ test_fail_unless (ok);
+ ctx->used_tei_nb--;
+ }
+ }
+ }
+ 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);
+ }
+ } test_end;
+ test_begin (t, "travel")
+ {
+ mac_store_mfs_travel (ctx->store, travel_mfs, ctx);
+ test_fail_unless (ctx->travel_mfs_alias_nb % 2 == 0
+ && (ctx->travel_mfs_nb - ctx->travel_mfs_alias_nb / 2
+ == ctx->used_mfs_nb));
+ } test_end;
+ /* Clean up. */
+ test_begin (t, "cleanup")
+ {
+ while (ctx->used_mfs_nb)
+ remove_mfs (ctx, t, ctx->used_mfs_nb - 1);
+ for (i = MAC_TEI_STA_MIN; i <= MAC_TEI_STA_MAX; i++)
+ {
+ sta_t *sta = mac_store_sta_get (ctx->store, i);
+ if (ctx->used_tei[i])
+ {
+ test_fail_unless (sta && sta->tei == i);
+ ctx->used_tei[i] = false;
+ blk_release (sta);
+ bool ok = mac_store_sta_remove (ctx->store, i);
+ test_fail_unless (ok);
+ }
+ else
+ {
+ test_fail_unless (sta == NULL);
+ }
+ }
+ mac_store_uninit (ctx->store);
+ test_verbose_print ("used_mfs = %d, used_tei = %d", ctx->used_mfs_max,
+ ctx->used_tei_max);
+ } test_end;
+}
+
+void
+store_test_suite (test_t t)
+{
+ test_suite_begin (t, "store");
+ store_basic_test_case (t);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ store_test_suite (t);
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
diff --git a/cesar/mac/common/test/tonemap/Makefile b/cesar/mac/common/test/tonemap/Makefile
new file mode 100644
index 0000000000..4e8136ab1b
--- /dev/null
+++ b/cesar/mac/common/test/tonemap/Makefile
@@ -0,0 +1,7 @@
+BASE = ../../../..
+
+HOST_PROGRAMS = test_tonemap
+test_tonemap_SOURCES = test_tonemap.c
+test_tonemap_MODULES = lib mac/common
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/mac/common/test/tonemap/src/test_tonemap.c b/cesar/mac/common/test/tonemap/src/test_tonemap.c
new file mode 100644
index 0000000000..d7484c9c5d
--- /dev/null
+++ b/cesar/mac/common/test/tonemap/src/test_tonemap.c
@@ -0,0 +1,258 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_tonemap.c
+ * \brief Test tonemap functions.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/test.h"
+#include "lib/rnd.h"
+
+#include "mac/common/tonemap.h"
+#include "mac/common/tonemask.h"
+#include "mac/common/timings.h"
+
+void
+tonemap_comp_test_case (test_t t)
+{
+ test_case_begin (t, "comp");
+ test_begin (t, "ble")
+ {
+ struct ble_param_t
+ {
+ phy_fecrate_t fecrate;
+ u32 p_pberror_uf32;
+ phy_gil_t gil;
+ uint symbol_us;
+ };
+ static const struct ble_param_t ble_param[] = {
+ { PHY_FEC_RATE_1_2, CONST_UF32 (0.0), PHY_GIL_567,
+ MAC_TCK_TO_US (MAC_DX567_TCK) },
+ { PHY_FEC_RATE_1_2, CONST_UF32 (0.05), PHY_GIL_567,
+ MAC_TCK_TO_US (MAC_DX567_TCK) },
+ { PHY_FEC_RATE_1_2, CONST_UF32 (0.25), PHY_GIL_567,
+ MAC_TCK_TO_US (MAC_DX567_TCK) },
+ { PHY_FEC_RATE_1_2, CONST_UF32 (0.5), PHY_GIL_567,
+ MAC_TCK_TO_US (MAC_DX567_TCK) },
+ { PHY_FEC_RATE_1_2, CONST_UF32 (0.75), PHY_GIL_567,
+ MAC_TCK_TO_US (MAC_DX567_TCK) },
+ { PHY_FEC_RATE_16_21, CONST_UF32 (0.33), PHY_GIL_417,
+ MAC_TCK_TO_US (MAC_DX417_TCK) },
+ { PHY_FEC_RATE_1_2, CONST_UF32 (0.03), PHY_GIL_3534,
+ MAC_TCK_TO_US (MAC_DX3534_TCK) },
+ { PHY_FEC_RATE_16_21, CONST_UF32 (0.01), PHY_GIL_417,
+ MAC_TCK_TO_US (MAC_DX417_TCK) },
+ };
+ uint i;
+ for (i = 0; i < COUNT (ble_param); i++)
+ {
+ const struct ble_param_t *p = &ble_param[i];
+ uint bits_per_symbol;
+ for (bits_per_symbol = 1;
+ bits_per_symbol < TONEMAP_BITS_PER_SYMBOL_MAX;
+ bits_per_symbol++)
+ {
+ double ble_f = (double) bits_per_symbol
+ * (p->fecrate == PHY_FEC_RATE_1_2 ? 0.5 : 16.0 / 21.0)
+ * (1.0 - ((double) p->p_pberror_uf32 / (1ull << 32)))
+ / p->symbol_us;
+ uint ble_uf5 = (1u << 5) * ble_f + 0.5;
+ u8 ble = tonemap_ble (bits_per_symbol, p->fecrate,
+ p->p_pberror_uf32, p->gil);
+ uint mant, exp;
+ uint ble_l_uf5, ble_m_uf5;
+ /* One less. */
+ if (ble != 0)
+ {
+ u8 ble_l = ble >> 3 | ble << 5;
+ ble_l--;
+ ble_l = ble_l >> 5 | ble_l << 3;
+ mant = ble_l >> 3; exp = ble_l & 0x7;
+ ble_l_uf5 = ((mant + 32) << (exp + 1)) + (1 << exp);
+ }
+ else
+ ble_l_uf5 = 0;
+ /* One more. */
+ if (ble != 0xff)
+ {
+ u8 ble_m = ble >> 3 | ble << 5;
+ ble_m++;
+ ble_m = ble_m >> 5 | ble_m << 3;
+ mant = ble_m >> 3; exp = ble_m & 0x7;
+ ble_m_uf5 = ((mant + 32) << (exp + 1)) + (1 << exp);
+ }
+ else
+ ble_m_uf5 = 0xffffffff;
+ /* Is it in between? */
+ test_fail_unless (ble_l_uf5 <= ble_uf5
+ && ble_uf5 < ble_m_uf5);
+ }
+ }
+ } test_end;
+ test_begin (t, "bits per pb")
+ {
+ phy_fecrate_t fecrate;
+ phy_pb_size_t pb_size;
+ for (fecrate = 0; fecrate < PHY_FEC_RATE_NONE; fecrate++)
+ for (pb_size = 0; pb_size < PHY_PB_SIZE_NONE; pb_size++)
+ {
+ uint bits;
+ switch (pb_size)
+ {
+ case PHY_PB_SIZE_136:
+ bits = 136 * 8;
+ break;
+ case PHY_PB_SIZE_520:
+ bits = 520 * 8;
+ break;
+ default:
+ dbg_assert_default ();
+ }
+ switch (fecrate)
+ {
+ case PHY_FEC_RATE_1_2:
+ bits = bits * 2;
+ break;
+ case PHY_FEC_RATE_16_21:
+ bits = bits * 21 / 16;
+ break;
+ default:
+ dbg_assert_default ();
+ }
+ test_fail_unless (tonemap_bits_per_pb (fecrate, pb_size)
+ == bits);
+ }
+ } test_end;
+}
+
+void
+tonemap_lookup_test_case (test_t t)
+{
+ tonemaps_t tms;
+ lib_rnd_t rnd[1];
+ lib_rnd_init (rnd, 1234);
+ test_case_begin (t, "lookup");
+ test_begin (t, "interval find")
+ {
+ uint iter;
+ tms.intervals = tms.swap_intervals;
+ for (iter = 0; iter < 10000; iter++)
+ for (tms.intervals->intervals_nb = 0; tms.intervals->intervals_nb < TONEMAP_INTERVAL_NB;
+ tms.intervals->intervals_nb++)
+ {
+ /* Fill intervals. */
+ uint i;
+ uint bot = 1;
+ for (i = 0; i < tms.intervals->intervals_nb; i++)
+ {
+ bot = lib_rnd_uniform (rnd, 9) + bot;
+ tms.intervals->interval[i].end_offset_atu = bot;
+ bot++;
+ }
+ /* Test. */
+ uint ti;
+ for (i = 0, ti = 0; i < bot - 1; )
+ {
+ dbg_assert (ti != tms.intervals->intervals_nb);
+ test_fail_unless (tonemap_interval_find (&tms, i) == ti);
+ i++;
+ if (i == tms.intervals->interval[ti].end_offset_atu)
+ ti++;
+ }
+ test_fail_unless (tonemap_interval_find (&tms, i)
+ == tms.intervals->intervals_nb);
+ }
+ } test_end;
+}
+
+void
+tonemap_tonemask_test_case (test_t t)
+{
+ tonemask_info_t ti;
+ uint carrier_nb;
+ test_case_begin (t, "tonemask");
+ test_begin (t, "default")
+ {
+ carrier_nb = tonemask_default (ti.tonemask);
+ test_fail_unless (carrier_nb == 917);
+ test_fail_unless (ti.tonemask[0 / 8] == 0); /* 74 */
+ test_fail_unless (ti.tonemask[11 / 8] == 0xf0); /* 85 */
+ test_fail_unless (ti.tonemask[345 / 8] == 0xfc); /* 419 */
+ test_fail_unless (ti.tonemask[495 / 8] == 0xff); /* 569 */
+ test_fail_unless (ti.tonemask[782 / 8] == 0x7f); /* 856 */
+ test_fail_unless (ti.tonemask[1069 / 8] == 0x3f); /* 1143 */
+ test_fail_unless (ti.tonemask[1070 / 8] == 0x3f); /* 1144 */
+ test_fail_unless (ti.tonemask[1155 / 8] == 0x00); /* 1229 */
+ } test_end;
+ test_begin (t, "carrier nb")
+ {
+ test_fail_unless (carrier_nb == tonemask_carrier_nb (ti.tonemask));
+ } test_end;
+ test_begin (t, "update")
+ {
+ tonemask_update (&ti);
+ test_fail_unless (ti.carrier_nb == carrier_nb);
+ phy_mod_t mod;
+ for (mod = PHY_MOD_ROBO; mod < PHY_MOD_ROBO_NB; mod++)
+ {
+ tonemap_t *tm = &ti.tonemap_robo[mod];
+ uint bits_per_symbol;
+ u8 ble;
+ switch (mod)
+ {
+ case PHY_MOD_ROBO:
+ bits_per_symbol = carrier_nb / 4 * 2;
+ ble = tonemap_ble (bits_per_symbol, PHY_FEC_RATE_1_2,
+ CONST_UF32 (0.0), PHY_GIL_417);
+ break;
+ case PHY_MOD_HS_ROBO:
+ bits_per_symbol = carrier_nb / 2 * 2;
+ ble = tonemap_ble (bits_per_symbol, PHY_FEC_RATE_1_2,
+ CONST_UF32 (0.0), PHY_GIL_417);
+ break;
+ case PHY_MOD_MINI_ROBO:
+ bits_per_symbol = carrier_nb / 5 * 2;
+ ble = tonemap_ble (bits_per_symbol, PHY_FEC_RATE_1_2,
+ CONST_UF32 (0.0), PHY_GIL_567);
+ break;
+ default:
+ dbg_assert_default ();
+ }
+ test_fail_unless (!tm->strict && tm->cpf
+ && tm->fecrate == PHY_FEC_RATE_1_2
+ && ((mod == PHY_MOD_MINI_ROBO
+ && tm->gil == PHY_GIL_567)
+ || tm->gil == PHY_GIL_417)
+ && tm->ble == ble
+ && tm->tmdma_desc_head == NULL
+ && tm->bits_per_symbol == bits_per_symbol
+ );
+ }
+ } test_end;
+}
+
+void
+tonemap_test_suite (test_t t)
+{
+ test_suite_begin (t, "tonemap");
+ tonemap_comp_test_case (t);
+ tonemap_lookup_test_case (t);
+ tonemap_tonemask_test_case (t);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ tonemap_test_suite (t);
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}