summaryrefslogtreecommitdiff
path: root/interface
diff options
context:
space:
mode:
Diffstat (limited to 'interface')
-rw-r--r--interface/Module1
-rw-r--r--interface/inc/context.h53
-rw-r--r--interface/inc/interface.h37
-rw-r--r--interface/interface.h160
-rw-r--r--interface/interface_module.h23
-rw-r--r--interface/sniffer/Module1
-rw-r--r--interface/sniffer/inc/context.h42
-rw-r--r--interface/sniffer/sniffer.h196
-rw-r--r--interface/sniffer/src/sniffer.c215
-rw-r--r--interface/sniffer/test/Makefile9
-rw-r--r--interface/sniffer/test/src/test-sniffer.c294
-rw-r--r--interface/src/interface.c335
-rw-r--r--interface/test/Makefile9
-rw-r--r--interface/test/ecos.ecc.sh5
-rw-r--r--interface/test/src/cl_stub.c54
-rw-r--r--interface/test/src/ipmbox_stub.c22
-rw-r--r--interface/test/src/sar_stub.c33
-rw-r--r--interface/test/src/test-interface.c363
18 files changed, 1852 insertions, 0 deletions
diff --git a/interface/Module b/interface/Module
new file mode 100644
index 0000000000..b11d213940
--- /dev/null
+++ b/interface/Module
@@ -0,0 +1 @@
+SOURCES=interface.c
diff --git a/interface/inc/context.h b/interface/inc/context.h
new file mode 100644
index 0000000000..25e1ff9aac
--- /dev/null
+++ b/interface/inc/context.h
@@ -0,0 +1,53 @@
+#ifndef interface_inc_context_h
+#define interface_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/inc/context.h
+ * \brief Interface context.
+ * \ingroup interface
+ *
+ */
+#include "hal/hle/ipmbox.h"
+#include "lib/circular_buffer.h"
+
+#include "interface/interface.h"
+
+/** module includes. */
+#include "interface/sniffer/sniffer.h"
+
+struct interface_t
+{
+ /** cl context. */
+ cl_t *cl;
+ /** sar context. */
+ sar_t *sar;
+ /** ipmbox context. */
+ ipmbox_t *ipmbox;
+
+ /** sniffer context. */
+ interface_sniffer_t *sniffer;
+
+ /* callbacks functions. */
+ /** Callback to call on MME reception. */
+ interface_mme_recv_cb_t mme_recv_cb;
+ /** Callback on buffer add. */
+ interface_mme_buffer_add_cb_t buffer_add_cb;
+ /** Callback on beacon add. */
+ interface_beacon_add_cb_t beacon_add_cb;
+ /** Actor user data. */
+ void *actor_user_data;
+
+ /** Buffer management. */
+ u8 *buffer_list[INTERFACE_BUFFER_LIST_NUM_SLOTS];
+ circular_buffer_t buffers;
+
+ cyg_mutex_t buffer_mutex;
+};
+
+#endif /* interface_inc_context_h */
diff --git a/interface/inc/interface.h b/interface/inc/interface.h
new file mode 100644
index 0000000000..353b9b582f
--- /dev/null
+++ b/interface/inc/interface.h
@@ -0,0 +1,37 @@
+#ifndef interface_inc_interface_h
+#define interface_inc_interface_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/inc/interface.h
+ * \brief Interface private functions.
+ * \ingroup interface
+ *
+ */
+
+#include "interface/interface.h"
+
+/**
+ * Add a buffer to its own list. If the function returns true, the buffer has
+ * been kept in the other case the buffer shall be provided to the CP.
+ * \param ctx the interface context.
+ * \param buffer the buffer to add.
+ * \return true if the buffer had been added, false otherwise.
+ */
+bool
+interface_buffer_add (interface_t *ctx, u8 *buffer);
+
+/**
+ * Get a buffer from the list.
+ * \param ctx the interface context.
+ * \return the buffer to use, NULL if no buffer is available.
+ */
+u8*
+interface_buffer_get (interface_t *ctx);
+
+#endif /* interface_inc_interface_h */
diff --git a/interface/interface.h b/interface/interface.h
new file mode 100644
index 0000000000..48204078e1
--- /dev/null
+++ b/interface/interface.h
@@ -0,0 +1,160 @@
+#ifndef interface_interface_h
+#define interface_interface_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/interface.h
+ * \brief Inteface module public functions.
+ * \ingroup interface
+ *
+ * The interface module allows the communication between Actors and
+ * the Data plane.
+ */
+
+#include "hal/hle/ipmbox.h"
+#include "cl/cl.h"
+#include "mac/sar/sar.h"
+
+#include "interface/interface_module.h"
+
+#define INTERFACE_BUFFER_LIST_NUM_SLOTS 2
+
+/** Forward declaration. */
+typedef struct interface_t interface_t;
+
+/**
+ * Function to call when the interface receives a new MME.
+ * \param user_data the data registered by the actor in the init function.
+ * \param buffer the buffer containing the MME.
+ * \param length the MME length
+ * \param mme_recv data use by the data plane.
+ */
+typedef void
+(*interface_mme_recv_cb_t) (void *user_data, u8 *buffer, uint length, void *mme_recv);
+
+/**
+ * Function to call when the interface receives a empty buffer.
+ * \param user_data the data registered by the actor in the init function.
+ * \param buffer the buffer to add.
+ */
+typedef void
+(*interface_mme_buffer_add_cb_t) (void *user_data, u8 *buffer);
+
+/**
+ * Function to call when the interface receives a beacon.
+ * \param user_data the data registered by the actor in the init function.
+ * \param beacon the beacon freshly received.
+ */
+typedef void
+(*interface_beacon_add_cb_t) (void *user_data, pb_beacon_t *beacon);
+
+/**
+ * Initialise the interface module.
+ * \param ipmbox the ipmbox context.
+ * \param cl the cl context.
+ * \param sar the sar context.
+ * \param mac_config the mac config context.
+ * \return the interface module context.
+ */
+interface_t*
+interface_init (ipmbox_t *ipmbox, cl_t *cl, sar_t *sar, mac_config_t
+ *mac_config);
+
+/**
+ * Interface uninit.
+ * \param ctx the interface context.
+ */
+void
+interface_uninit (interface_t *ctx);
+
+/**
+ * Initialise the callbacks functions.
+ * \param ctx the interface context.
+ * \param mme_recv_cb the function to call on reception of a MME.
+ * \param buffer_add_cb the function to call on buffer reception.
+ * \param beacon_add_cb the function to call on beacon reception
+ * \param user_data the data to provide on each callback function.
+ */
+void
+interface_callback_init (interface_t *ctx, interface_mme_recv_cb_t mme_recv_cb,
+ interface_mme_buffer_add_cb_t buffer_add_cb,
+ interface_beacon_add_cb_t beacon_add_cb, void *user_data);
+
+
+/**
+ * Configure the interface.
+ * \param ctx the interface context.
+ * \param data the data to configure the module of sub module.
+ */
+void
+interface_configure (interface_t *ctx, u8 *data);
+
+
+/** Receives an MME from the PWL or the HLE.
+ * \param ctx the interface context
+ * \param buffer the buffer containing the MME.
+ * \param length the MME length
+ * \param mme_data data use by the CL.
+ */
+void
+interface_mme_recv (interface_t *ctx, u8 *buffer, uint length,
+ cl_mme_recv_t *mme_data);
+
+
+/**
+ * Inform the Data plane when the MME as been processed by the CP.
+ * \param ctx the interface context
+ * \param mme_recv the cl data (as a void pointer).
+ */
+void
+interface_mme_recv_done (interface_t *ctx, void *mme_recv);
+
+/** Provides a MME to send to the CL. This MME can be send as a MME or a data.
+ * \param ctx the interface context.
+ * \param buffer the buffer containing the MME.
+ * \param length the length of the MME.
+ * \param mfs the MFS to send the MME if the mme is to be sent over the PWL,
+ * otherwise this pointer is NULL.
+ */
+void
+interface_mme_send (interface_t *ctx, u8* buffer, uint length, mfs_tx_t *mfs);
+
+/**
+ * Sends a beacon, the interface will provide it to the SAR.
+ * \param ctx the interface context.
+ * \param beacon the beacon to send.
+ * \param the source mac address.
+ * \param beacon_mfs the mfs to use to send the beacon.
+ * \param bto_bpsto the four bto to use for the beacon and the bpsto address
+ * to be stamp by the pbproc.
+ */
+void
+interface_beacon_prepare (interface_t *ctx, pb_beacon_t *beacon, mac_t
+ mac_address, mfs_tx_t *beacon_mfs, void *bto_bpsto);
+
+/**
+* add a beacon to the interface.
+* It will provide it to the CP to process the beacon.
+*
+* \param ctx the interface context.
+* \param pb pb containing the beacon
+* \param params the rx params.
+*/
+void interface_beacon_add (interface_t *ctx, pb_beacon_t *pb,
+ pbproc_rx_beacon_params_t *params);
+
+/**
+ * Sends a message to the IPMbox
+ * \param ctx the interface context
+ * \param data the message to post in the ipmbox.
+ * \param length the length of the data in bytes.
+ */
+void
+interface_ipmbox_send (interface_t *ctx, u8 *data, uint length);
+
+#endif /* interface_interface_h */
diff --git a/interface/interface_module.h b/interface/interface_module.h
new file mode 100644
index 0000000000..3a606fa317
--- /dev/null
+++ b/interface/interface_module.h
@@ -0,0 +1,23 @@
+#ifndef interface_interface_module_h
+#define interface_interface_module_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/interface_module.h
+ * \brief Interface module indentifier.
+ * \ingroup interface
+ *
+ */
+
+enum interface_modules_t
+{
+ INTERFACE_MODULE_INTERFACE,
+ INTERFACE_MODULE_SNIFFER
+};
+
+#endif /* interface_interface_module_h */
diff --git a/interface/sniffer/Module b/interface/sniffer/Module
new file mode 100644
index 0000000000..059889da76
--- /dev/null
+++ b/interface/sniffer/Module
@@ -0,0 +1 @@
+SOURCES=sniffer.c
diff --git a/interface/sniffer/inc/context.h b/interface/sniffer/inc/context.h
new file mode 100644
index 0000000000..254250881e
--- /dev/null
+++ b/interface/sniffer/inc/context.h
@@ -0,0 +1,42 @@
+#ifndef interface_sniffer_inc_context_h
+#define interface_sniffer_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/sniffer/inc/context.h
+ * \brief Context of the sniffer.
+ * \ingroup inteface_sniffer
+ *
+ */
+
+#define SNIFFER_REG__SNIFF_MME_TX 0, 0
+#define SNIFFER_REG__SNIFF_MME_RX 1, 1
+#define SNIFFER_REG__SNIFF_BEACON_TX 2, 2
+#define SNIFFER_REG__SNIFF_BEACON_RX 3, 3
+
+#define SNIFFER_MME 1
+#define SNIFFER_BEACON 0
+
+struct interface_sniffer_t
+{
+ /** Sniff the beacon send. */
+ bool sniff_beacon_tx;
+ /** Sniff the beacon on reception. */
+ bool sniff_beacon_rx;
+ /** Sniff the MME on TX. */
+ bool sniff_mme_tx;
+ /** Sniff the MME on RX. */
+ bool sniff_mme_rx;
+
+ /** Call this function when it needs to post a message for the HLE. */
+ interface_sniffer_send_message_cb_t send_func;
+ /** data to provide on function callback. */
+ void *send_user_data;
+};
+
+#endif /* interface_sniffer_inc_context_h */
diff --git a/interface/sniffer/sniffer.h b/interface/sniffer/sniffer.h
new file mode 100644
index 0000000000..9c74647c7b
--- /dev/null
+++ b/interface/sniffer/sniffer.h
@@ -0,0 +1,196 @@
+#ifndef interface_sniffer_sniffer_h
+#define interface_sniffer_sniffer_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/sniffer/sniffer.h
+ * \brief Sniffer public functions.
+ * \ingroup interface_sniffer
+ *
+ */
+
+#include "mac/common/pb.h"
+#include "interface/interface_module.h"
+
+
+/** Send a message to the interface. This message shall be send to the linux driver.
+ * \param user_data  the data provided in the function registration
+ * \param message  the message to send.
+ * \param length  the message length
+ */
+typedef void (*interface_sniffer_send_message_cb_t) (void *user_data,
+ uint *message, uint length);
+
+
+/** Forward declaration. */
+typedef struct interface_sniffer_t interface_sniffer_t;
+
+
+/** Initialise the sniffer and all the callback of the sniffer.
+ * \param cb the function to call when the sniffer needs to send a message.
+ * \param user_data the data to provide on each function callback provided.
+ */
+interface_sniffer_t*
+interface_sniffer_init (interface_sniffer_send_message_cb_t cb, void *user_data);
+
+
+/** Uninitalise the sniffer.
+ * \param ctx the sniffer context.
+ */
+void
+interface_sniffer_uninit (interface_sniffer_t *ctx);
+
+/** Configure the sniffer.
+ * \param ctx the sniffer context
+ * \param data the data to configure the sniffer.
+ */
+void
+interface_sniffer_configure (interface_sniffer_t *ctx, uint data);
+
+
+/** Copy a MME to the buffer and request the interface to send the MME.
+ * \param ctx the sniffer context.
+ * \param mme the MME buffer
+ * \param length the MME length
+ * \param buffer the destination buffer.
+ * \param tx the MME way (TX/RX)
+ * \param encrypted if the MME has been encrypted or not.
+ */
+void
+interface_sniffer_copy_mme (interface_sniffer_t *ctx, u8 *mme, uint length,
+ u8 *buffer, bool tx, bool encrypted);
+
+/** Copy a MME to the buffer and request the interface to send the MME.
+ * \param ctx the sniffer context.
+ * \param mme the MME buffer
+ * \param length the MME length
+ * \param buffer the destination buffer.
+ * \param encrypted if the MME has been encrypted or not.
+ */
+extern inline void
+interface_sniffer_copy_mme_tx (interface_sniffer_t *ctx, u8 *mme, uint length,
+ u8 *buffer, bool encrypted)
+{
+ interface_sniffer_copy_mme (ctx, mme, length, buffer, true, encrypted);
+}
+
+/** Copy a MME to the buffer and request the interface to send the MME.
+ * \param ctx the sniffer context.
+ * \param mme the MME buffer
+ * \param length the MME length
+ * \param buffer the destination buffer.
+ * \param encrypted if the MME has been encrypted or not.
+ */
+extern inline void
+interface_sniffer_copy_mme_rx (interface_sniffer_t *ctx, u8 *mme, uint length,
+ u8 *buffer, bool encrypted)
+{
+ interface_sniffer_copy_mme (ctx, mme, length, buffer, false, encrypted);
+}
+
+/** Copy a beacon to the buffer and request the interface to send the copied beacon.
+ * Encapsulate the beacon in a MME.
+ * \param ctx the sniffer context.
+ * \param beacon the beacon
+ * \param buffer the destination buffer.
+ * \param tx the beacon way (TX/RX)
+ * \param mac_address the station mac address to fill the OSA ODA in the
+ * MME.
+ */
+void
+interface_sniffer_copy_beacon (interface_sniffer_t *ctx, pb_beacon_t *beacon,
+ u8 *buffer, bool tx, mac_t mac_address);
+
+/** Copy a beacon to the buffer and request the interface to send the copied beacon.
+ * Encapsulate the beacon in a MME.
+ * \param ctx the sniffer context.
+ * \param beacon the beacon
+ * \param buffer the destination buffer.
+ * \param mac_address the station mac address to fill the OSA ODA in the
+ * MME.
+ */
+extern inline void
+interface_sniffer_copy_beacon_tx (interface_sniffer_t *ctx, pb_beacon_t *beacon,
+ u8 *buffer, mac_t mac_address)
+{
+ interface_sniffer_copy_beacon (ctx, beacon, buffer, true, mac_address);
+}
+
+/** Copy a beacon to the buffer and request the interface to send the copied beacon.
+ * Encapsulate the beacon in a MME.
+ * \param ctx the sniffer context.
+ * \param beacon the beacon
+ * \param buffer the destination buffer.
+ * \param mac_address the station mac address to fill the OSA ODA in the
+ * MME.
+ */
+extern inline void
+interface_sniffer_copy_beacon_rx (interface_sniffer_t *ctx, pb_beacon_t *beacon,
+ u8 *buffer, mac_t mac_address)
+{
+ interface_sniffer_copy_beacon (ctx, beacon, buffer, false, mac_address);
+}
+
+/** Provides the MME sniff status.
+ * \param ctx the sniffer context.
+ * \param tx the way.
+ * \return the MME sniff status.
+ */
+bool
+interface_sniffer_mme_status (interface_sniffer_t *ctx, bool tx);
+
+
+/** Provides the MME sniff status.
+ * \param ctx the sniffer context.
+ * \return the MME sniff status.
+ */
+extern inline bool
+interface_sniffer_mme_status_tx (interface_sniffer_t *ctx)
+{
+ return interface_sniffer_mme_status(ctx, true);
+}
+
+/** Provides the MME sniff status.
+ * \param ctx the sniffer context.
+ * \return the MME sniff status.
+ */
+extern inline bool
+interface_sniffer_mme_status_rx (interface_sniffer_t *ctx)
+{
+ return interface_sniffer_mme_status(ctx, false);
+}
+
+/** Provides the beacon sniff status.
+ * \param ctx the sniffer context.
+ * \param tx the way.
+ * \return the beacon sniff status.
+ */
+bool
+interface_sniffer_beacon_status (interface_sniffer_t *ctx, bool tx);
+
+/** Provides the beacon sniff status.
+ * \param ctx the sniffer context.
+ * \return the beacon sniff status.
+ */
+extern inline bool
+interface_sniffer_beacon_status_tx (interface_sniffer_t *ctx)
+{
+ return interface_sniffer_beacon_status (ctx, true);
+}
+
+/** Provides the beacon sniff status.
+ * \param ctx the sniffer context.
+ * \return the beacon sniff status.
+ */
+extern inline bool
+interface_sniffer_beacon_status_rx (interface_sniffer_t *ctx)
+{
+ return interface_sniffer_beacon_status (ctx, false);
+}
+
+#endif /* interface_sniffer_sniffer_h */
diff --git a/interface/sniffer/src/sniffer.c b/interface/sniffer/src/sniffer.c
new file mode 100644
index 0000000000..68ee831402
--- /dev/null
+++ b/interface/sniffer/src/sniffer.c
@@ -0,0 +1,215 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/sniffer/src/sniffer.c
+ * \brief Sniffer source functions.
+ * \ingroup interface_sniffer
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "common/defs/ethernet.h"
+#include "common/defs/homeplugAV.h"
+
+#include "lib/bitstream.h"
+#include "hal/hle/ipmbox.h"
+#include "string.h"
+
+#include "mac/pbproc/pbproc.h"
+
+#include "interface/sniffer/sniffer.h"
+#include "interface/sniffer/inc/context.h"
+
+/* Static declaration. */
+static interface_sniffer_t sniffer_global;
+
+/** Initialise the sniffer and all the callback of the sniffer.
+ * \param cb the function to call when the sniffer needs to send a message.
+ * \param user_data the data to provide on each function callback provided.
+ */
+interface_sniffer_t*
+interface_sniffer_init (interface_sniffer_send_message_cb_t cb, void *user_data)
+{
+ dbg_assert (cb);
+
+ sniffer_global.sniff_beacon_tx = false;
+ sniffer_global.sniff_beacon_rx = false;
+ sniffer_global.sniff_mme_tx = false;
+ sniffer_global.sniff_mme_rx = false;
+
+ sniffer_global.send_func = cb;
+ sniffer_global.send_user_data = user_data;
+
+ return &sniffer_global;
+}
+
+
+/** Uninitalise the sniffer.
+ * \param ctx the sniffer context.
+ */
+void
+interface_sniffer_uninit (interface_sniffer_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+/** Configure the sniffer.
+ * \param ctx the sniffer context
+ * \param data the data to configure the sniffer.
+ */
+void
+interface_sniffer_configure (interface_sniffer_t *ctx, uint data)
+{
+ dbg_assert (ctx);
+ dbg_assert (data);
+
+ ctx->sniff_mme_tx = BF_GET(SNIFFER_REG__SNIFF_MME_TX, data);
+ ctx->sniff_mme_rx = BF_GET(SNIFFER_REG__SNIFF_MME_RX, data);
+ ctx->sniff_beacon_tx = BF_GET(SNIFFER_REG__SNIFF_BEACON_TX, data);
+ ctx->sniff_beacon_rx = BF_GET(SNIFFER_REG__SNIFF_BEACON_RX, data);
+}
+
+
+/** Copy a MME to the buffer and request the interface to send the MME.
+ * \param ctx the sniffer context.
+ * \param mme the MME buffer
+ * \param length the MME length
+ * \param buffer the destination buffer.
+ * \param tx the MME way (TX/RX)
+ */
+void
+interface_sniffer_copy_mme (interface_sniffer_t *ctx, u8 *mme, uint length,
+ u8 *buffer, bool tx, bool encrypted)
+{
+ uint word[2];
+
+ dbg_assert (ctx);
+ dbg_assert (mme);
+ dbg_assert (ETH_PACKET_MIN_SIZE <= length && length <=
+ ETH_PACKET_MAX_SIZE);
+ dbg_assert (buffer);
+ dbg_assert (ctx->send_func);
+
+ memcpy (buffer, mme, length);
+
+ word[0] = BF_FILL (IPMBOX_REG, (MSG_TYPE, INTERFACE_MODULE_SNIFFER),
+ (MSG_LENGTH, 1), (PARAM_SNIFFER_WAY, tx),
+ (PARAM_SNIFFER_EKC, encrypted),
+ (PARAM_SNIFFER_TYPE, SNIFFER_MME),
+ (PARAM_SNIFFER_LENGTH, length));
+
+ word[1] = (uint)buffer;
+
+
+ /** Request the interface to send the message to the linux driver. */
+ (*ctx->send_func) (ctx->send_user_data, word, 2);
+}
+
+/** Copy a beacon to the buffer and request the interface to send the copied beacon.
+ * Encapsulate the beacon in a MME.
+ * \param ctx the sniffer context.
+ * \param beacon the beacon
+ * \param buffer the destination buffer.
+ * \param tx the beacon way (TX/RX)
+ * \param mac_address the station mac address to fill the OSA ODA in the
+ * MME.
+ */
+void
+interface_sniffer_copy_beacon (interface_sniffer_t *ctx, pb_beacon_t *beacon,
+ u8 *buffer, bool tx, mac_t mac_address)
+{
+ bitstream_t bitstream;
+ uint data;
+ uint length;
+ uint word[2];
+
+ dbg_assert (ctx);
+ dbg_assert (buffer);
+ dbg_assert (beacon);
+
+ length = 136 + sizeof (pbproc_rx_beacon_params_t);
+
+ // Fill the buffer header.
+ bitstream_init (&bitstream, buffer, 25, BITSTREAM_WRITE);
+ bitstream_access (&bitstream, &mac_address, 48);
+ bitstream_access (&bitstream, &mac_address, 48);
+
+ /** Inserting the VLAN TAG. */
+ data = 0;
+ bitstream_access (&bitstream, &data, 32);
+
+ /** Inserting the MTYPE. */
+ data = ((HPAV_MTYPE_MME & 0xFF) << 8) | (HPAV_MTYPE_MME >> 8);
+ bitstream_access (&bitstream, &data, 16);
+
+ /** Inserting the MMV. */
+ data = 0x0;
+ bitstream_access (&bitstream, &data, 8);
+
+ /** Inserting the MMTYPE. */
+ data = 0xA036;
+ bitstream_access (&bitstream, &data, 16);
+
+ /** Inserting the module type. */
+ data = INTERFACE_MODULE_SNIFFER;
+ bitstream_access (&bitstream, &data, 8);
+
+ /** Inserting data type i.e. beacon == 0 */
+ data = 0;
+ bitstream_access (&bitstream, &data, 8);
+
+ /** Inserting length. */
+ bitstream_access (&bitstream, &length, 16);
+ bitstream_finalise (&bitstream);
+
+ word[0] = BF_FILL (IPMBOX_REG, (MSG_TYPE, INTERFACE_MODULE_SNIFFER),
+ (MSG_LENGTH, 1), (PARAM_SNIFFER_WAY, tx),
+ (PARAM_SNIFFER_EKC, false),
+ (PARAM_SNIFFER_TYPE, SNIFFER_BEACON),
+ (PARAM_SNIFFER_LENGTH, length));
+
+ word[1] = (uint)buffer;
+
+
+ /** Request the interface to send the message to the linux driver. */
+ (*ctx->send_func) (ctx->send_user_data, word, 2);
+}
+
+
+/** Provides the MME sniff status.
+ * \param ctx the sniffer context.
+ * \param tx the way.
+ * \return the MME sniff status.
+ */
+bool
+interface_sniffer_mme_status (interface_sniffer_t *ctx, bool tx)
+{
+ dbg_assert (ctx);
+
+ if (tx)
+ return ctx->sniff_mme_tx;
+ else
+ return ctx->sniff_mme_rx;
+}
+
+/** Provides the beacon sniff status.
+ * \param ctx the sniffer context.
+ * \param tx the way.
+ * \return the beacon sniff status.
+ */
+bool
+interface_sniffer_beacon_status (interface_sniffer_t *ctx, bool tx)
+{
+ dbg_assert (ctx);
+
+ if (tx)
+ return ctx->sniff_mme_tx;
+ else
+ return ctx->sniff_mme_rx;
+}
+
diff --git a/interface/sniffer/test/Makefile b/interface/sniffer/test/Makefile
new file mode 100644
index 0000000000..1fee49b3e5
--- /dev/null
+++ b/interface/sniffer/test/Makefile
@@ -0,0 +1,9 @@
+BASE = ../../..
+
+DEFS = -DINTERFACE_MODULE_SNIFFER=6
+
+HOST_PROGRAMS = test-sniffer
+test-sniffer_SOURCES = test-sniffer.c
+test-sniffer_MODULES = lib interface/sniffer
+
+include $(BASE)/common/make/top.mk
diff --git a/interface/sniffer/test/src/test-sniffer.c b/interface/sniffer/test/src/test-sniffer.c
new file mode 100644
index 0000000000..dabb36366a
--- /dev/null
+++ b/interface/sniffer/test/src/test-sniffer.c
@@ -0,0 +1,294 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/sniffer/test/src/test-sniffer.c
+ * \brief testing sniffer.
+ * \ingroup interface_sniffer
+ *
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "lib/read_word.h"
+#include "lib/bitstream.h"
+
+#include "interface/sniffer/sniffer.h"
+#include "interface/sniffer/inc/context.h"
+
+#include <string.h>
+
+uint ipmbox_msg[2];
+
+void test_sniffer_send_message (void *user_data, uint *message, uint length)
+{
+ memcpy (ipmbox_msg, message, 2*sizeof(uint));
+}
+
+int
+main (void)
+{
+ test_t test;
+ interface_sniffer_t *sniffer;
+ u8 data[10];
+ u8 mme[1500];
+ u8 copy_mme[1500];
+ uint i;
+ pb_beacon_t *beacon;
+
+ /** Data to process the ipmbox message. */
+ uint type;
+ uint data_tx;
+ uint data_length;
+ uint data_type;
+ uint data_ekc;
+ u8 *msg;
+ uint msg_len;
+ bitstream_t bitstream;
+
+ /** Process the MME beacon data. */
+ mac_t oda;
+ mac_t osa;
+ uint vlan;
+ uint mtype;
+ uint mmv;
+ uint mmtype;
+ uint module;
+ uint mme_data_type;
+ uint mme_data_length;
+
+ test_init (test, 0, NULL);
+
+
+ test_case_begin (test, "Sniffer init");
+ sniffer = interface_sniffer_init (test_sniffer_send_message, NULL);
+
+ test_begin (test, "sniffer init")
+ {
+ test_fail_if (sniffer->sniff_beacon_tx != false, "Error, sniffer should be unactivated");
+ test_fail_if (sniffer->sniff_beacon_rx != false, "Error, sniffer should be unactivated");
+ test_fail_if (sniffer->sniff_mme_tx != false, "Error, sniffer should be unactivated");
+ test_fail_if (sniffer->sniff_mme_rx != false, "Error, sniffer should be unactivated");
+ test_fail_if (sniffer->send_func == NULL, "Error, send function not filled");
+ }
+ test_end;
+
+ test_case_begin (test, "Activating the sniffer.");
+
+ data[0] = 0xF;
+ interface_sniffer_configure (sniffer, read_u8_from_word(data));
+ test_begin (test, "All sniffer part")
+ {
+ test_fail_if (sniffer->sniff_beacon_tx != true, "Error, beacon TX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_beacon_rx != true, "Error, beacon RX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_tx != true, "Error, MME TX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_rx != true, "Error, MME RX's sniffer should be activated");
+ }
+ test_end;
+
+ data[0] = 0xE;
+ interface_sniffer_configure (sniffer, read_u8_from_word(data));
+ test_begin (test, "Unactivate the sniffer on MME TX")
+ {
+ test_fail_if (sniffer->sniff_beacon_tx != true, "Error, beacon TX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_beacon_rx != true, "Error, beacon RX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_tx != false , "Error, MME TX's sniffer should be unactivated");
+ test_fail_if (sniffer->sniff_mme_rx != true, "Error, MME RX's sniffer should be activated");
+ }
+ test_end;
+
+ interface_sniffer_configure (sniffer, 0xD);
+ test_begin (test, "Unactivate the sniff MME on RX")
+ {
+ test_fail_if (sniffer->sniff_beacon_tx != true, "Error, beacon TX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_beacon_rx != true, "Error, beacon RX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_tx != true , "Error, MME TX's sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_rx != false , "Error, MME RX's sniffer should be unactivated");
+ }
+ test_end;
+
+ data[0] = 0xB;
+ interface_sniffer_configure (sniffer, read_u8_from_word(data));
+ test_begin (test, "Unactivate the sniff becon on rx")
+ {
+ test_fail_if (sniffer->sniff_beacon_tx != false, "Error, sniffer should be unactivated");
+ test_fail_if (sniffer->sniff_beacon_rx != true, "Error, sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_tx != true , "Error, sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_rx != true, "Error, sniffer should be activated");
+ }
+ test_end;
+
+ data[0] = 0x7;
+ interface_sniffer_configure (sniffer, read_u8_from_word(data));
+ test_begin (test, "Unactivate the sniff becon on tx")
+ {
+ test_fail_if (sniffer->sniff_beacon_tx != true, "Error, sniffer should be activated");
+ test_fail_if (sniffer->sniff_beacon_rx != false, "Error, sniffer should be unactivated");
+ test_fail_if (sniffer->sniff_mme_tx != true , "Error, sniffer should be activated");
+ test_fail_if (sniffer->sniff_mme_rx != true, "Error, sniffer should be activated");
+ }
+ test_end;
+
+
+ test_case_begin (test, "Copy a MME");
+
+ for (i = 0; i < 1500; i++)
+ {
+ mme[i] = i;
+ }
+
+ interface_sniffer_copy_mme_tx (sniffer, mme, 1500, copy_mme, false);
+
+ bitstream_init (&bitstream, ipmbox_msg, sizeof (uint), BITSTREAM_READ);
+ bitstream_access (&bitstream, &type, 8);
+ bitstream_access (&bitstream, &msg_len, 4);
+ bitstream_access (&bitstream, &data_tx, 1);
+ bitstream_access (&bitstream, &data_ekc, 1);
+ bitstream_access (&bitstream, &data_type, 3);
+ bitstream_access (&bitstream, &data_length, 12);
+ bitstream_finalise (&bitstream);
+
+ msg = (u8 *) ipmbox_msg[1];
+
+ test_begin (test, "Verify message posted in the IPMBOX")
+ {
+ test_fail_if (type != INTERFACE_SNIFFER, "Error on message type");
+ test_fail_if (msg_len != 1, "Error on message length");
+ test_fail_if (data_ekc != false, "Error on message encryption");
+ test_fail_if (data_tx != true, "Error on message way");
+ test_fail_if (data_type != 1, "Error on message data type");
+ test_fail_if (data_length != 1500, "Error on message data length");
+
+ for (i = 0; i < data_length; i++)
+ {
+ test_fail_if (msg[i] != (u8)i, "Error, mme_copy at index %d is not equal to %d", i, (u8)i);
+ }
+ }
+ test_end;
+
+ interface_sniffer_copy_mme_rx (sniffer, mme, 1500, copy_mme, true);
+
+ bitstream_init (&bitstream, ipmbox_msg, sizeof (uint), BITSTREAM_READ);
+ bitstream_access (&bitstream, &type, 8);
+ bitstream_access (&bitstream, &msg_len, 4);
+ bitstream_access (&bitstream, &data_tx, 1);
+ bitstream_access (&bitstream, &data_ekc, 1);
+ bitstream_access (&bitstream, &data_type, 3);
+ bitstream_access (&bitstream, &data_length, 12);
+ bitstream_finalise (&bitstream);
+
+ msg = (u8 *) ipmbox_msg[1];
+
+ test_begin (test, "Verify message posted in the IPMBOX")
+ {
+ test_fail_if (type != INTERFACE_SNIFFER, "Error on message type");
+ test_fail_if (msg_len != 1, "Error on message length");
+ test_fail_if (data_ekc != true, "Error on message encryption");
+ test_fail_if (data_tx != false, "Error on message way");
+ test_fail_if (data_type != 1, "Error on message data type");
+ test_fail_if (data_length != 1500, "Error on message data length");
+
+ for (i = 0; i < data_length; i++)
+ {
+ test_fail_if (msg[i] != (u8)i, "Error, mme_copy at index %d is not equal to %d", i, (u8)i);
+ }
+ }
+ test_end;
+
+
+ test_case_begin (test, "Beacon SNIFF");
+
+ beacon = (pb_beacon_t *)blk_alloc_desc ();
+ memcpy (&beacon->first_data_word, mme, 4);
+ memcpy (beacon->data, mme, 136);
+
+ interface_sniffer_copy_beacon_tx (sniffer, beacon, copy_mme,
+ 0x123456789abcull);
+
+ bitstream_init (&bitstream, ipmbox_msg, sizeof (uint), BITSTREAM_READ);
+ bitstream_access (&bitstream, &type, 8);
+ bitstream_access (&bitstream, &msg_len, 4);
+ bitstream_access (&bitstream, &data_tx, 1);
+ bitstream_access (&bitstream, &data_ekc, 1);
+ bitstream_access (&bitstream, &data_type, 3);
+ bitstream_access (&bitstream, &data_length, 11);
+ bitstream_finalise (&bitstream);
+
+ msg = (u8*)ipmbox_msg[1];
+ bitstream_init (&bitstream, msg, 25, BITSTREAM_READ);
+ bitstream_access (&bitstream, &oda, 48);
+ bitstream_access (&bitstream, &osa, 48);
+ bitstream_access (&bitstream, &vlan, 32);
+ bitstream_access (&bitstream, &mtype, 16);
+ bitstream_access (&bitstream, &mmv, 8);
+ bitstream_access (&bitstream, &mmtype, 16);
+ bitstream_access (&bitstream, &module, 8);
+ bitstream_access (&bitstream, &mme_data_type, 8);
+ bitstream_access (&bitstream, &mme_data_length, 16);
+ bitstream_finalise (&bitstream);
+
+ test_begin (test, "verify beacon data")
+ {
+ test_fail_if (oda != 0x123456789abcull, "Error on message ODA OSA");
+ test_fail_if (osa != 0x123456789abcull, "Error on message ODA OSA");
+ test_fail_if (vlan != 0, "Error on message vlan");
+ test_fail_if (mtype != 0xE188 , "Error on MTYPE");
+ test_fail_if (mmv != 0, "Error on message MMV");
+ test_fail_if (mmtype != 0xA036, "Error on message MMTYPE");
+ test_fail_if (mme_data_type != 0 , "Error on message data type");
+ test_fail_if (mme_data_length != 160 , "Error on message data length");
+ }
+ test_end;
+
+
+ test_begin (test, "verify beacon data")
+ {
+ test_fail_if (type != INTERFACE_SNIFFER, "Error on message type");
+ test_fail_if (msg_len != 1, "Error on message length");
+ test_fail_if (data_tx != true , "Error on message way");
+ test_fail_if (data_ekc != false, "Error on message encryption");
+ test_fail_if (data_type != 0, "Error on message data type");
+ test_fail_if (data_length != 160 , "Error on message data length");
+
+ for (i = 25; i < data_length; i++)
+ {
+ test_fail_if (msg[i] != (u8)i, "Error, mme_copy at index %d is not equal to %d", i, (u8)i);
+ }
+ }
+ test_end;
+
+ interface_sniffer_copy_beacon_rx (sniffer, beacon, copy_mme,
+ 0x123456789abcull);
+
+ bitstream_init (&bitstream, ipmbox_msg, sizeof (uint), BITSTREAM_READ);
+ bitstream_access (&bitstream, &type, 8);
+ bitstream_access (&bitstream, &msg_len, 4);
+ bitstream_access (&bitstream, &data_tx, 1);
+ bitstream_access (&bitstream, &data_ekc, 1);
+ bitstream_access (&bitstream, &data_type, 3);
+ bitstream_access (&bitstream, &data_length, 11);
+ bitstream_finalise (&bitstream);
+
+ test_begin (test, "verify beacon data")
+ {
+ test_fail_if (type != INTERFACE_SNIFFER, "Error on message type");
+ test_fail_if (msg_len != 1, "Error on message length");
+ test_fail_if (data_tx != false, "Error on message way");
+ test_fail_if (data_ekc != false, "Error on message encryption");
+ test_fail_if (data_type != 0, "Error on message data type");
+ test_fail_if (data_length != 160 , "Error on message data length");
+
+ for (i = 25; i < data_length; i++)
+ {
+ test_fail_if (msg[i] != (u8)i, "Error, mme_copy at index %d is not equal to %d", i, (u8)i);
+ }
+ }
+ test_end;
+
+
+ test_result (test);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
diff --git a/interface/src/interface.c b/interface/src/interface.c
new file mode 100644
index 0000000000..21e91d69fd
--- /dev/null
+++ b/interface/src/interface.c
@@ -0,0 +1,335 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/src/interface.c
+ * \brief Interface functions sources.
+ * \ingroup interface
+ *
+ */
+#include "common/std.h"
+#include "common/defs/ethernet.h"
+#include "lib/read_word.h"
+#include "lib/circular_buffer.h"
+
+#include "hal/hle/ipmbox.h"
+#include "interface/interface.h"
+#include "interface/sniffer/sniffer.h"
+
+#include "interface/inc/interface.h"
+#include "interface/inc/context.h"
+
+static interface_t interface_global;
+
+/**
+ * Initialise the interface module.
+ * \param ipmbox the ipmbox context.
+ * \param cl the cl context.
+ * \param sar the sar context.
+ * \param mac_config the mac config context.
+ * \return the interface module context.
+ */
+interface_t*
+interface_init (ipmbox_t *ipmbox, cl_t *cl, sar_t *sar, mac_config_t
+ *mac_config)
+{
+ dbg_assert (cl);
+ dbg_assert (sar);
+
+ interface_global.cl = cl;
+ interface_global.sar = sar;
+
+ interface_global.sniffer = interface_sniffer_init
+ ((interface_sniffer_send_message_cb_t) interface_ipmbox_send,
+ &interface_global);
+
+ circular_buffer_init (&interface_global.buffers,
+ interface_global.buffer_list,
+ INTERFACE_BUFFER_LIST_NUM_SLOTS);
+
+ cyg_mutex_init (&interface_global.buffer_mutex);
+
+ return &interface_global;
+}
+
+/**
+ * Interface uninit.
+ * \param ctx the interface context.
+ */
+void
+interface_uninit (interface_t *ctx)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->sniffer);
+
+ interface_sniffer_uninit (ctx->sniffer);
+}
+
+/**
+ * Initialise the callbacks functions.
+ * \param ctx the interface context.
+ * \param mme_recv_cb the function to call on reception of a MME.
+ * \param buffer_add_cb the function to call on buffer reception.
+ * \param beacon_add_cb the function to call on beacon reception
+ * \param user_data the data to provide on each callback function.
+ */
+void
+interface_callback_init (interface_t *ctx, interface_mme_recv_cb_t mme_recv_cb,
+ interface_mme_buffer_add_cb_t buffer_add_cb,
+ interface_beacon_add_cb_t beacon_add_cb, void *user_data)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme_recv_cb);
+ dbg_assert (buffer_add_cb);
+ dbg_assert (beacon_add_cb);
+
+ ctx->mme_recv_cb = mme_recv_cb;
+ ctx->buffer_add_cb = buffer_add_cb;
+ ctx->beacon_add_cb = beacon_add_cb;
+ ctx->actor_user_data = user_data;
+}
+
+
+/**
+ * Configure the interface.
+ * \param ctx the interface context.
+ * \param data the data to configure the module of sub module.
+ */
+void
+interface_configure (interface_t *ctx, u8 *data)
+{
+ dbg_assert (ctx);
+ dbg_assert (data);
+
+ switch (read_u8_from_word(data))
+ {
+ case INTERFACE_MODULE_SNIFFER:
+ /** The length contained in the second octet shall be equal to 1. */
+ dbg_assert (read_u8_from_word(data + 1) == 1);
+ interface_sniffer_configure (ctx->sniffer, read_u8_from_word (data + 2));
+ break;
+ default :
+ break;
+ }
+}
+
+/** Receives an MME from the PWL or the HLE.
+ * \param ctx the interface context
+ * \param buffer the buffer containing the MME.
+ * \param length the MME length
+ * \param mme_data data use by the CL.
+ */
+void
+interface_mme_recv (interface_t *ctx, u8 *buffer, uint length,
+ cl_mme_recv_t *mme_data)
+{
+ u8 *copy_buffer;
+
+ dbg_assert (ctx);
+ dbg_assert (buffer);
+ dbg_assert (ETH_PACKET_MIN_SIZE <= length && length <=
+ ETH_PACKET_MAX_SIZE);
+
+ if (interface_sniffer_mme_status_rx(ctx->sniffer))
+ {
+ copy_buffer = interface_buffer_get (ctx);
+
+ if (copy_buffer)
+ {
+ interface_sniffer_copy_mme_rx (ctx->sniffer, buffer, length,
+ copy_buffer, false);
+ }
+ }
+
+ // Call the actor callback.
+ dbg_assert (ctx->mme_recv_cb);
+ (*ctx->mme_recv_cb) (ctx->actor_user_data, buffer, length, mme_data);
+}
+
+
+/**
+ * Inform the Data plane when the MME as been processed by the CP.
+ * \param ctx the interface context
+ * \param mme_recv the cl data (as a void pointer).
+ */
+void
+interface_mme_recv_done (interface_t *ctx, void *mme_recv)
+{
+ dbg_assert (ctx);
+ dbg_assert (mme_recv);
+ dbg_assert (ctx->cl);
+
+ cl_mme_recv_done (ctx->cl, (cl_mme_recv_t*) mme_recv);
+}
+
+/** Provides a MME to send to the CL. This MME can be send as a MME or a data.
+ * \param ctx the interface context.
+ * \param buffer the buffer containing the MME.
+ * \param length the length of the MME.
+ * \param mfs the MFS to send the MME if the mme is to be sent over the PWL,
+ * otherwise this pointer is NULL.
+ */
+void
+interface_mme_send (interface_t *ctx, u8* buffer, uint length, mfs_tx_t *mfs)
+{
+ u8 *copy_buffer;
+
+ dbg_assert (ctx);
+ dbg_assert (buffer);
+ dbg_assert (length >= ETH_PACKET_MIN_SIZE && length <=
+ ETH_PACKET_MAX_SIZE);
+
+ if (interface_sniffer_mme_status_tx (ctx->sniffer))
+ {
+ copy_buffer = interface_buffer_get (ctx);
+
+ if (copy_buffer)
+ {
+ interface_sniffer_copy_mme_tx (ctx->sniffer, buffer, length,
+ copy_buffer, false);
+ }
+ }
+
+ dbg_assert (ctx->cl);
+ cl_mme_send (ctx->cl, buffer, length, mfs);
+}
+
+
+/**
+ * Sends a beacon, the interface will provide it to the SAR.
+ * \param ctx the interface context.
+ * \param beacon the beacon to send.
+ * \param the source mac address.
+ * \param beacon_mfs the mfs to use to send the beacon.
+ * \param bto_bpsto the four bto to use for the beacon and the bpsto address
+ * to be stamp by the pbproc.
+ */
+void
+interface_beacon_prepare (interface_t *ctx, pb_beacon_t *beacon, mac_t
+ mac_address, mfs_tx_t *beacon_mfs, void *bto_bpsto)
+{
+ u8 *buffer;
+
+ dbg_assert (ctx);
+ dbg_assert (beacon);
+ dbg_assert (ctx->sar);
+ dbg_assert (mac_address);
+
+ if (interface_sniffer_beacon_status_tx (ctx->sniffer))
+ {
+ buffer = interface_buffer_get (ctx);
+
+ if (buffer)
+ {
+ interface_sniffer_copy_beacon_tx (ctx->sniffer, beacon, buffer,
+ mac_address);
+ }
+ }
+
+ sar_beacon_send (ctx->sar, beacon, beacon_mfs, bto_bpsto);
+}
+
+/**
+* add a beacon to the interface.
+* It will provide it to the CP to process the beacon.
+*
+* \param ctx the interface context.
+* \param pb pb containing the beacon
+* \param params the rx params.
+*/
+void interface_beacon_add (interface_t *ctx, pb_beacon_t *pb,
+ pbproc_rx_beacon_params_t *params)
+{
+ u8 *buffer;
+
+ dbg_assert (ctx);
+ dbg_assert (pb);
+
+ /* Get the buffer to copy the data. */
+ if (interface_sniffer_beacon_status_rx (ctx->sniffer))
+ {
+ buffer = interface_buffer_get (ctx);
+
+ if (buffer)
+ {
+ // TODO replace the mac address with the right one.
+ interface_sniffer_copy_beacon_rx (ctx->sniffer, pb, buffer,
+ 0x123456789abcull);
+ }
+ }
+
+ dbg_assert (ctx->beacon_add_cb);
+ (*ctx->beacon_add_cb) (ctx->actor_user_data, pb);
+}
+
+
+/**
+ * Sends a message to the IPMbox
+ * \param ctx the interface context
+ * \param data the message to post in the ipmbox.
+ * \param length the length of the data in bytes.
+ */
+void
+interface_ipmbox_send (interface_t *ctx, u8 *data, uint length)
+{
+ uint word[length];
+
+ dbg_assert (ctx);
+ dbg_assert (data);
+ dbg_assert (length);
+
+ ipmbox_tx (ctx->ipmbox, word, length);
+}
+
+/**
+ * Add a buffer to its own list. If the function returns true, the buffer has
+ * been kept in the other case the buffer shall be provided to the CP.
+ * \param ctx the interface context.
+ * \param buffer the buffer to add.
+ * \return true if the buffer had been added, false otherwise.
+ */
+bool
+interface_buffer_add (interface_t *ctx, u8 *buffer)
+{
+ bool added;
+ dbg_assert (ctx);
+ dbg_assert (buffer);
+
+ dbg_assert (ctx->buffer_add_cb);
+
+ /* Lock the mutex. */
+ cyg_mutex_lock (&ctx->buffer_mutex);
+ added = circular_buffer_add (&ctx->buffers, buffer);
+ cyg_mutex_unlock (&ctx->buffer_mutex);
+
+ if (!added)
+ {
+ (*ctx->buffer_add_cb) (ctx->actor_user_data, buffer);
+ added = true;
+ }
+
+ return added;
+}
+
+/**
+ * Get a buffer from the list.
+ * \param ctx the interface context.
+ * \return the buffer to use, NULL if no buffer is available.
+ */
+u8*
+interface_buffer_get (interface_t *ctx)
+{
+ u8 *buffer;
+ dbg_assert (ctx);
+
+ cyg_mutex_lock (&ctx->buffer_mutex);
+ buffer = circular_buffer_get (&ctx->buffers);
+ cyg_mutex_unlock (&ctx->buffer_mutex);
+
+ return buffer;
+}
+
diff --git a/interface/test/Makefile b/interface/test/Makefile
new file mode 100644
index 0000000000..ca25e75a2f
--- /dev/null
+++ b/interface/test/Makefile
@@ -0,0 +1,9 @@
+BASE = ../..
+
+ECOS=y
+
+TARGET_PROGRAMS = test-interface
+test-interface_SOURCES = cl_stub.c sar_stub.c test-interface.c
+test-interface_MODULES = lib interface interface/sniffer
+
+include $(BASE)/common/make/top.mk
diff --git a/interface/test/ecos.ecc.sh b/interface/test/ecos.ecc.sh
new file mode 100644
index 0000000000..8253d98c9a
--- /dev/null
+++ b/interface/test/ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new linux default
+cat >> $config <<EOF
+EOF
+ecosconfig --config=$config check
diff --git a/interface/test/src/cl_stub.c b/interface/test/src/cl_stub.c
new file mode 100644
index 0000000000..45be38f203
--- /dev/null
+++ b/interface/test/src/cl_stub.c
@@ -0,0 +1,54 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/cl_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+#include "common/defs/ethernet.h"
+#include "lib/read_word.h"
+
+#include "cl/cl.h"
+#include "mac/sar/sar.h"
+#include "mac/pbproc/pbproc.h"
+
+#include "cl/inc/context.h"
+#include "cl/inc/cl.h"
+#include "cl/inc/trace.h"
+#include "cl/inc/cl_mactotei.h"
+
+#include "mac/common/ntb.h"
+
+static cl_t cl_global;
+
+cl_t *
+cl_init (mac_store_t *mac_store, sar_t *sar, mac_config_t *mac_config)
+{
+ return &cl_global;
+}
+
+void
+cl_mme_recv_done (cl_t *ctx, cl_mme_recv_t* mme_recv)
+{
+}
+
+
+void
+cl_mme_send_as_mme (cl_t *ctx, u8 *buffer, uint length, mfs_tx_t *mfs)
+{
+}
+
+void
+cl_mme_send_as_data (cl_t *ctx, u8 *buffer, uint length)
+{
+}
+
diff --git a/interface/test/src/ipmbox_stub.c b/interface/test/src/ipmbox_stub.c
new file mode 100644
index 0000000000..4c14998b0d
--- /dev/null
+++ b/interface/test/src/ipmbox_stub.c
@@ -0,0 +1,22 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/ipmbox_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+#include "hal/hle/ipmbox.h"
+
+
+void ipmbox_tx (ipmbox_t *ctx, u32 *first_msg, uint length)
+{
+}
+
diff --git a/interface/test/src/sar_stub.c b/interface/test/src/sar_stub.c
new file mode 100644
index 0000000000..25f199235b
--- /dev/null
+++ b/interface/test/src/sar_stub.c
@@ -0,0 +1,33 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/sar_stub.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+#include "common/std.h"
+
+#include "mac/sar/sar.h"
+#include "mac/sar/inc/sar_context.h"
+
+static sar_t sar_global;
+
+sar_t *
+sar_init (mac_store_t *mac_store, pbproc_t *pbproc, ca_t *ca)
+{
+ return &sar_global;
+}
+
+void
+sar_beacon_send (sar_t *ctx, pb_beacon_t *beacon, mfs_tx_t *beacon_mfs, void *bto_bpsto)
+{
+
+}
+
diff --git a/interface/test/src/test-interface.c b/interface/test/src/test-interface.c
new file mode 100644
index 0000000000..8dbdcdda77
--- /dev/null
+++ b/interface/test/src/test-interface.c
@@ -0,0 +1,363 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file interface/test/src/test-interface.c
+ * \brief Test the interface module.
+ * \ingroup interface
+ *
+ */
+#include "common/std.h"
+#include "lib/test.h"
+
+#include "hal/hle/ipmbox.h"
+#include "cl/cl.h"
+#include "mac/sar/sar.h"
+#include "interface/interface.h"
+
+#include "interface/sniffer/sniffer.h"
+
+#include "interface/inc/interface.h"
+#include "interface/inc/context.h"
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/kernel/kapi.h>
+
+#include <stdlib.h>
+
+
+interface_t *interface;
+bool test_buffer_add;
+bool test_copy;
+bool test_mme_recv;
+bool test_beacon_add;
+
+void
+test_interface_mme_buffer_add (void *user_data, u8 *buffer);
+
+void
+test_interface_mme_recv (void *user_data, u8 *buffer, uint length, void *mme_recv);
+
+void
+test_interface_beacon_add(void *user_data, pb_beacon_t *beacon);
+
+void ipmbox_tx (ipmbox_t *ctx, u32 *first_msg, uint length);
+
+
+void
+test_configure_sniffer (test_t test)
+{
+ u8 buffer[3];
+ test_case_begin (test, "Configure the sniffer");
+
+ buffer[0] = INTERFACE_MODULE_SNIFFER;
+ buffer[1] = 1;
+
+ buffer[2] = 0x1;
+ interface_configure (interface, buffer);
+ test_begin (test, "Activate the mme tx")
+ {
+ test_fail_if (interface_sniffer_mme_status_tx (interface->sniffer) !=
+ true, "Error sniffer mme TX shall be active");
+ }
+ test_end;
+
+ buffer[2] = 0x3;
+ interface_configure (interface, buffer);
+ test_begin (test, "Anactivate the mme tx/rx")
+ {
+ test_fail_if (interface_sniffer_mme_status_tx (interface->sniffer) !=
+ true, "Error sniffer mme TX shall be active");
+ test_fail_if (interface_sniffer_mme_status_rx (interface->sniffer) !=
+ true, "Error sniffer mme RX shall be active");
+ }
+ test_end;
+
+ buffer[2] = 0x7;
+ interface_configure (interface, buffer);
+ test_begin (test, "Anactivate the mme tx/rx, beacon Tx")
+ {
+ test_fail_if (interface_sniffer_mme_status_tx (interface->sniffer) !=
+ true, "Error sniffer mme TX shall be active");
+ test_fail_if (interface_sniffer_mme_status_rx (interface->sniffer) !=
+ true, "Error sniffer mme RX shall be active");
+ test_fail_if (interface_sniffer_beacon_status_tx (interface->sniffer) !=
+ true, "Error sniffer beacon TX shall be active");
+ }
+ test_end;
+
+ buffer[2] = 0xF;
+ interface_configure (interface, buffer);
+ test_begin (test, "Sniffer conf")
+ {
+ test_fail_if (interface_sniffer_beacon_status_rx (interface->sniffer)
+ != true, "Error sniffer beacon RX shall be active");
+ test_fail_if (interface_sniffer_beacon_status_tx (interface->sniffer)
+ != true, "Error sniffer beacon TX shall be active");
+ test_fail_if (interface_sniffer_mme_status_rx (interface->sniffer)
+ != true, "Error sniffer MME RX shall be active");
+ test_fail_if (interface_sniffer_mme_status_tx (interface->sniffer)
+ != true, "Error sniffer MME TX shall be active");
+
+ }
+ test_end;
+}
+
+void
+test_adding_buffers (test_t test)
+{
+ uint i;
+ u8 *real_buffer;
+ bool added;
+
+ test_case_begin (test, "Adding buffers");
+
+ test_begin (test, "add buffer")
+ {
+ for (i = 0; i < INTERFACE_BUFFER_LIST_NUM_SLOTS + 1; i++)
+ {
+ // Allocate buffers
+ real_buffer = malloc (2048);
+ test_buffer_add = false;
+ added = interface_buffer_add (interface, real_buffer);
+
+ test_fail_if (added != true, "Error, buffer shall be kept");
+
+ if (i < INTERFACE_BUFFER_LIST_NUM_SLOTS)
+ test_fail_if (test_buffer_add == true, "Error the buffer shall be kept by the interface");
+ else
+ test_fail_if (test_buffer_add == false, "Error the buffer shall be added to the CP");
+ }
+ }
+ test_end;
+}
+
+void
+test_copy_recv_mme (test_t test)
+{
+ u8 mme [1000];
+ u8 *buffer;
+ uint i;
+ bool added;
+
+ for (i = 0; i < 1000; i++)
+ {
+ mme[i] = i;
+ }
+
+ test_copy = false;
+ test_mme_recv = false;
+ interface_mme_recv (interface, mme, 1000, NULL);
+
+
+ test_case_begin (test, "Sniff a received MME");
+
+ test_begin (test, "verifing copy")
+ {
+ test_fail_if (test_copy == false, "MME not copied");
+ test_fail_if (test_mme_recv == false, "MME not send to the CP");
+ }
+ test_end;
+
+
+ /* The interface shall receive a buffer and keep it. */
+ buffer = malloc (2048);
+ test_buffer_add = false;
+ added = interface_buffer_add (interface, buffer);
+
+ test_begin (test, "adding a buffer")
+ {
+ test_fail_if (test_buffer_add == true, "Error the buffer shall be kept by the interface");
+ }
+ test_end;
+
+ interface_mme_recv_done (interface, interface);
+}
+
+void
+test_copy_send_mme(test_t test)
+{
+ u8 mme [1000];
+ u8 *buffer;
+ uint i;
+ bool added;
+
+ for (i = 0; i < 1000; i++)
+ {
+ mme[i] = i;
+ }
+
+ test_copy = false;
+ test_mme_recv = false;
+ interface_mme_send (interface, mme, 1000, NULL);
+
+
+ test_case_begin (test, "Sniff a MME tx");
+
+ test_begin (test, "verifing copy")
+ {
+ test_fail_if (test_copy == false, "MME not copied");
+ }
+ test_end;
+
+
+ /* The interface shall receive a buffer and keep it. */
+ buffer = malloc (2048);
+ test_buffer_add = false;
+ added = interface_buffer_add (interface, buffer);
+
+ test_begin (test, "adding a buffer")
+ {
+ test_fail_if (test_buffer_add == true, "Error the buffer shall be kept by the interface");
+ }
+ test_end;
+}
+
+void
+test_copy_send_beacon (test_t test)
+{
+ pb_beacon_t *beacon;
+ mfs_tx_t *mfs;
+ u8 *buffer;
+ bool added;
+
+ beacon = (pb_beacon_t *) blk_alloc_desc ();
+ mfs = blk_alloc ();
+
+
+ test_copy = false;
+ interface_beacon_prepare (interface, beacon, 0x123456789abcull, mfs, &beacon->first_data_word);
+
+ test_case_begin (test, "Sniff a beacon tx");
+
+ test_begin (test, "verifing copy")
+ {
+ test_fail_if (test_copy == false, "beacon not copied");
+ }
+ test_end;
+
+
+ /* The interface shall receive a buffer and keep it. */
+ buffer = malloc (2048);
+ test_buffer_add = false;
+ added = interface_buffer_add (interface, buffer);
+
+ test_begin (test, "adding a buffer")
+ {
+ test_fail_if (test_buffer_add == true, "Error the buffer shall be kept by the interface");
+ }
+ test_end;
+
+
+ blk_release_desc ((blk_t *) beacon);
+ blk_release (mfs);
+}
+
+void
+test_copy_recv_beacon (test_t test)
+{
+ pb_beacon_t *beacon;
+ u8 *buffer;
+ bool added;
+
+ beacon = (pb_beacon_t *) blk_alloc_desc ();
+
+
+ test_copy = false;
+ test_beacon_add = false;
+ interface_beacon_add (interface, beacon, NULL);
+
+ test_case_begin (test, "Sniff a beacon tx");
+
+ test_begin (test, "verifing copy")
+ {
+ test_fail_if (test_copy == false, "beacon not copied");
+ test_fail_if (test_beacon_add == false, "beacon not transmitted");
+ }
+ test_end;
+
+
+ /* The interface shall receive a buffer and keep it. */
+ buffer = malloc (2048);
+ test_buffer_add = false;
+ added = interface_buffer_add (interface, buffer);
+
+ test_begin (test, "adding a buffer")
+ {
+ test_fail_if (test_buffer_add == true, "Error the buffer shall be kept by the interface");
+ }
+ test_end;
+
+
+ blk_release_desc ((blk_t *) beacon);
+}
+
+
+int
+main (void)
+{
+ test_t test;
+ cl_t *cl;
+ sar_t *sar;
+ ipmbox_t *ipmbox;
+
+ test_init (test, 0, NULL);
+
+ cl = cl_init(NULL, NULL, NULL);
+ sar = sar_init (NULL, NULL, NULL);
+ ipmbox = blk_alloc ();
+
+ interface = interface_init (ipmbox, cl, sar, NULL);
+ interface_callback_init (interface, test_interface_mme_recv,
+ test_interface_mme_buffer_add,
+ test_interface_beacon_add, interface);
+
+
+ test_configure_sniffer (test);
+ test_adding_buffers (test);
+ test_copy_recv_mme (test);
+ test_copy_send_mme(test);
+ test_copy_send_beacon(test);
+ test_copy_recv_beacon (test);
+ interface_uninit (interface);
+ blk_release (ipmbox);
+
+ test_result (test);
+ HAL_PLATFORM_EXIT (test_nb_failed (test) == 0 ? 0 : 1);
+ return test_nb_failed (test) == 0 ? 0 : 1;
+}
+
+void
+test_interface_mme_buffer_add (void *user_data, u8 *buffer)
+{
+ dbg_assert (buffer);
+ free (buffer);
+
+ test_buffer_add = true;
+}
+
+
+void
+test_interface_mme_recv (void *user_data, u8 *buffer, uint length, void *mme_recv)
+{
+ dbg_assert (buffer);
+
+ test_mme_recv = true;
+}
+
+
+void
+test_interface_beacon_add(void *user_data, pb_beacon_t *beacon)
+{
+ dbg_assert (beacon);
+ test_beacon_add = true;
+}
+
+void ipmbox_tx (ipmbox_t *ctx, u32 *first_msg, uint length)
+{
+ test_copy = true;
+}