summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-05-23 14:48:07 +0200
committerNélio Laranjeiro2011-06-01 14:25:58 +0200
commit4d5995cea08e09e7ef3cf8fa4b690d7269ef5e10 (patch)
tree4aef9dd4fa3f30cb0247d2a30f2379dc9f933b1d
parentd6bb308c4b569c1048ddd8d867ed2f8c29806b32 (diff)
cesar/cl: learn source mac address on RX path, closes #442
-rw-r--r--cesar/cl/Module2
-rw-r--r--cesar/cl/brg_rx.h79
-rw-r--r--cesar/cl/inc/context.h4
-rw-r--r--cesar/cl/src/brg_rx.c65
-rw-r--r--cesar/cl/src/cl.c6
-rw-r--r--cesar/cl/stub/Module2
-rw-r--r--cesar/cl/stub/src/brg_rx.c41
-rw-r--r--cesar/cl/test/utest/Makefile2
-rw-r--r--cesar/cl/test/utest/src/brg_rx.c64
-rw-r--r--cesar/cl/test/utest/src/cl.c4
10 files changed, 265 insertions, 4 deletions
diff --git a/cesar/cl/Module b/cesar/cl/Module
index 517ee1f635..13768e9721 100644
--- a/cesar/cl/Module
+++ b/cesar/cl/Module
@@ -1,4 +1,4 @@
-SOURCES := cl.c cl_mactotei.c bridge_table.c data_rate.c
+SOURCES := cl.c cl_mactotei.c bridge_table.c data_rate.c brg_rx.c
ifeq ($(CONFIG_TRACE),y)
SOURCES += trace.c
endif
diff --git a/cesar/cl/brg_rx.h b/cesar/cl/brg_rx.h
new file mode 100644
index 0000000000..768c27a598
--- /dev/null
+++ b/cesar/cl/brg_rx.h
@@ -0,0 +1,79 @@
+#ifndef cl_brg_rx_h
+#define cl_brg_rx_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/brg_rx.h
+ * \brief RX bridge Table for data only.
+ * \ingroup cl
+ *
+ * Allow the CL to learn the source mac address of the packets received and
+ * associate it with the TEI of the MFS. Those entries should be added in the
+ * mac to TEI table by a non real time process.
+ * An entry is invalid if it is not present in the CM_BRG_TABLE sent by
+ * the associated station.
+ */
+
+/** Number of entries for the temporary RX bridge table. */
+#define CL_BRG_RX_ENTRY_NB 10
+
+struct cl_brg_rx_entry_t
+{
+ /** Mac address. */
+ mac_t mac;
+ /** TEI associated with the mac address bridged. */
+ uint tei;
+};
+typedef struct cl_brg_rx_entry_t cl_brg_rx_entry_t;
+
+struct cl_brg_rx_t
+{
+ /** Number of entries. */
+ uint nb_entry;
+ /** Table of entries. */
+ cl_brg_rx_entry_t entry[CL_BRG_RX_ENTRY_NB];
+};
+typedef struct cl_brg_rx_t cl_brg_rx_t;
+
+BEGIN_DECLS
+
+/**
+ * Add an entry to the table.
+ * \param ctx the module context.
+ * \param mac the source mac address.
+ * \param tei the TEI associated.
+ */
+void
+cl_brg_rx_add (cl_t *ctx, mac_t smac, uint tei);
+
+/**
+ * Get the table.
+ * \param ctx the module context.
+ * \return the table.
+ *
+ * This function will return the temporary table stored in a dynamic blk, the
+ * client is responsible for releasing the block. Once the table is returned,
+ * the CL will not use it anymore, if it receives a new Mac address bridged it
+ * will create a new table.
+ */
+cl_brg_rx_t *
+cl_brg_rx_get (cl_t *ctx);
+
+/**
+ * Release the Bridge RX table.
+ * \param ctx the module context.
+ *
+ * The bridge table is destroyed and the CL will create another one to add new
+ * bridged entries.
+ */
+void
+cl_brg_rx_release (cl_t *ctx);
+
+END_DECLS
+
+#endif /* cl_brg_rx_h */
diff --git a/cesar/cl/inc/context.h b/cesar/cl/inc/context.h
index 54314c5a0a..954e101e08 100644
--- a/cesar/cl/inc/context.h
+++ b/cesar/cl/inc/context.h
@@ -22,6 +22,7 @@
#include "mac/common/config.h"
#include "mac/sar/sar.h"
#include "cl/cl_mactotei.h"
+#include "cl/brg_rx.h"
#include "cl/inc/bridge_table.h" // bridge_table_context_t
#include "cl/inc/trace.h"
@@ -152,6 +153,9 @@ struct cl_t
/** Groups for multi-unicast. */
igmp_groups_t groups;
+ /** RX bridge Table. */
+ cl_brg_rx_t *brg_rx;
+
/** Tracing system */
#if CONFIG_TRACE
/** cl Trace */
diff --git a/cesar/cl/src/brg_rx.c b/cesar/cl/src/brg_rx.c
new file mode 100644
index 0000000000..8770635465
--- /dev/null
+++ b/cesar/cl/src/brg_rx.c
@@ -0,0 +1,65 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/src/brx_rx.c
+ * \brief RX bridge Table for data only.
+ * \ingroup cl
+ */
+#include "common/std.h"
+#include "cl/cl.h"
+#include "cl/brg_rx.h"
+#include "hal/arch/arch.h"
+
+#include "cl/inc/cl.h"
+
+void
+cl_brg_rx_add (cl_t *ctx, mac_t smac, uint tei)
+{
+ if (MAC_TEI_IS_STA (tei) && MAC_IS_VALID (smac))
+ {
+ if (!ctx->brg_rx)
+ {
+ ctx->brg_rx = (cl_brg_rx_t*) blk_alloc ();
+ ctx->brg_rx->nb_entry = 0;
+ }
+ if (ctx->brg_rx->nb_entry < CL_BRG_RX_ENTRY_NB)
+ {
+ /* Does the entry already exists ? */
+ bool found;
+ uint i, nb_entry = ctx->brg_rx->nb_entry;
+ for (i = 0, found = false; !found && i < nb_entry; i++)
+ found = smac == ctx->brg_rx->entry[i].mac;
+ if (!found)
+ {
+ ctx->brg_rx->entry[nb_entry].mac = smac;
+ ctx->brg_rx->entry[nb_entry].tei = tei;
+ ctx->brg_rx->nb_entry++;
+ }
+ }
+ }
+}
+
+cl_brg_rx_t *
+cl_brg_rx_get (cl_t *ctx)
+{
+ arch_dsr_lock ();
+ cl_brg_rx_t *t = ctx->brg_rx;
+ ctx->brg_rx = NULL;
+ arch_dsr_unlock ();
+ return t;
+}
+
+void
+cl_brg_rx_release (cl_t *ctx)
+{
+ arch_dsr_lock ();
+ if (ctx->brg_rx)
+ blk_release (ctx->brg_rx);
+ ctx->brg_rx = NULL;
+ arch_dsr_unlock ();
+}
diff --git a/cesar/cl/src/cl.c b/cesar/cl/src/cl.c
index 9d2e5200a4..129a58ba7e 100644
--- a/cesar/cl/src/cl.c
+++ b/cesar/cl/src/cl.c
@@ -280,6 +280,7 @@ cl_init (mac_store_t *mac_store, sar_t *sar, mac_config_t *mac_config)
/* Initialize the local bridge table module. */
bridge_table_init (ctx);
+ ctx->brg_rx = NULL;
/* Initialise the data link. */
ctx->data_send_link.mfs = NULL;
@@ -324,6 +325,7 @@ void cl_uninit (cl_t *ctx)
{
cl_mactotei_release_table (ctx);
}
+ cl_brg_rx_release (ctx);
/* Uninitialise the slab cache. */
slab_cache_uninit (&ctx->slab_buffer_handler);
@@ -924,8 +926,10 @@ void cl_data_recv (cl_t *ctx, u8 *buffer, uint length, mfs_rx_t *mfs)
CL_TRACE (DATA_RECV, phy_date (), buffer, TRACE_U64(dest),
TRACE_U64(src), length);
}
-
+ mac_t smac, dmac;
+ bitstream_direct_read_macs (buffer, &dmac, &smac);
(*ctx->data_rx.cb) (ctx->data_rx.user, buffer, length);
+ cl_brg_rx_add (ctx, smac, mfs->common.tei);
/* update data rate informations associated to the RX
* from the associated sta to the local sta */
diff --git a/cesar/cl/stub/Module b/cesar/cl/stub/Module
index 7b0e17bdad..2ad195744b 100644
--- a/cesar/cl/stub/Module
+++ b/cesar/cl/stub/Module
@@ -1 +1 @@
-SOURCES:=cl.c cl_mactotei.c bridge_table.c
+SOURCES:=cl.c cl_mactotei.c bridge_table.c brg_rx.c
diff --git a/cesar/cl/stub/src/brg_rx.c b/cesar/cl/stub/src/brg_rx.c
new file mode 100644
index 0000000000..e48f1b0684
--- /dev/null
+++ b/cesar/cl/stub/src/brg_rx.c
@@ -0,0 +1,41 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/stub/src/brg_rx.c
+ * \brief Stub the brg rx functions
+ * \ingroup cl
+ *
+ */
+#include "common/std.h"
+#include "cl/cl.h"
+#include "cl/brg_rx.h"
+
+void
+cl_brg_rx_add (cl_t *ctx, mac_t smac, uint tei) __attribute__((weak));
+
+cl_brg_rx_t *
+cl_brg_rx_get (cl_t *ctx) __attribute__((weak));
+
+void
+cl_brg_rx_release (cl_t *ctx) __attribute__((weak));
+
+void
+cl_brg_rx_add (cl_t *ctx, mac_t smac, uint tei)
+{
+}
+
+cl_brg_rx_t *
+cl_brg_rx_get (cl_t *ctx)
+{
+ return NULL;
+}
+
+void
+cl_brg_rx_release (cl_t *ctx)
+{
+}
diff --git a/cesar/cl/test/utest/Makefile b/cesar/cl/test/utest/Makefile
index 9034432f9e..959c0fd9fc 100644
--- a/cesar/cl/test/utest/Makefile
+++ b/cesar/cl/test/utest/Makefile
@@ -2,7 +2,7 @@ BASE = ../../..
HOST_PROGRAMS = cl
-cl_SOURCES = cl.c test.c send.c receive.c misc.c
+cl_SOURCES = cl.c test.c send.c receive.c misc.c brg_rx.c
cl_MODULES = lib cl mac/common \
mac/sar/stub
diff --git a/cesar/cl/test/utest/src/brg_rx.c b/cesar/cl/test/utest/src/brg_rx.c
new file mode 100644
index 0000000000..11a73ab49d
--- /dev/null
+++ b/cesar/cl/test/utest/src/brg_rx.c
@@ -0,0 +1,64 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2011 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/brg_rx.c
+ * \brief Test the bridge RX table.
+ * \ingroup cl
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "lib/bitstream.h"
+#include "mac/common/timings.h"
+#include "cl/test/utest/test.h"
+#include "cl/inc/context.h"
+#include "cl/inc/cl.h"
+
+void
+cl_test_brg_rx (test_t test)
+{
+ test_case_begin (test, "BRG RX table");
+ cl_test_t ctx;
+ cl_test_init (&ctx, 124);
+ test_begin (test, "Add Mac addresses")
+ {
+ uint i;
+ for (i = 0; i < CL_BRG_RX_ENTRY_NB + 10; i++)
+ cl_brg_rx_add (ctx.cl, i, i);
+ test_fail_unless (ctx.cl->brg_rx->nb_entry == CL_BRG_RX_ENTRY_NB);
+ for (i = 0; i < CL_BRG_RX_ENTRY_NB; i++)
+ {
+ test_fail_unless (ctx.cl->brg_rx->entry[i].mac == i + 1);
+ test_fail_unless (ctx.cl->brg_rx->entry[i].tei == i + 1);
+ }
+ /* Get the table. */
+ cl_brg_rx_t *table = cl_brg_rx_get (ctx.cl);
+ test_fail_unless (!ctx.cl->brg_rx);
+ test_fail_unless (table->nb_entry == CL_BRG_RX_ENTRY_NB);
+ for (i = 0; i < CL_BRG_RX_ENTRY_NB; i++)
+ {
+ test_fail_unless (table->entry[i].mac == i + 1);
+ test_fail_unless (table->entry[i].tei == i + 1);
+ }
+ blk_release (table);
+ }
+ test_end;
+ test_begin (test, "double entry / Invalid mac address")
+ {
+ cl_brg_rx_release (ctx.cl);
+ cl_brg_rx_add (ctx.cl, 1, 1);
+ cl_brg_rx_add (ctx.cl, 1, 1);
+ cl_brg_rx_add (ctx.cl, MAC_BROADCAST, 1);
+ cl_brg_rx_add (ctx.cl, MAC_ZERO, 1);
+ test_fail_unless (ctx.cl->brg_rx->nb_entry == 1);
+ test_fail_unless (ctx.cl->brg_rx->entry[0].mac == 1);
+ test_fail_unless (ctx.cl->brg_rx->entry[0].tei == 1);
+ cl_brg_rx_release (ctx.cl);
+ }
+ test_end;
+ cl_test_uninit (&ctx);
+}
diff --git a/cesar/cl/test/utest/src/cl.c b/cesar/cl/test/utest/src/cl.c
index c35336395f..031f8ea520 100644
--- a/cesar/cl/test/utest/src/cl.c
+++ b/cesar/cl/test/utest/src/cl.c
@@ -25,6 +25,9 @@ cl_test_suite_receive (test_t test);
void
cl_test_suite_misc (test_t test);
+void
+cl_test_brg_rx (test_t test);
+
int
main (int argc, char **argv)
{
@@ -34,6 +37,7 @@ main (int argc, char **argv)
cl_test_suite_send (test);
cl_test_suite_receive (test);
cl_test_suite_misc (test);
+ cl_test_brg_rx (test);
trace_uninit ();
test_begin (test, "Memory")
{