summaryrefslogtreecommitdiff
path: root/cesar/interface/src
diff options
context:
space:
mode:
authorIPMbox Team2012-02-03 14:32:28 +0100
committerNicolas Schodet2012-02-20 10:08:46 +0100
commit3ed571f9d933e5c5dadef650c07e20e8aad06213 (patch)
tree761bfe80d4660605e00f52afb8532d9a2ef847b6 /cesar/interface/src
parent89328e8cc096f8c9f340a3eb8910d06748a3e572 (diff)
cesar, cleopatre, common: new ipmbox design, closes #848
Diffstat (limited to 'cesar/interface/src')
-rw-r--r--cesar/interface/src/interface.c320
1 files changed, 64 insertions, 256 deletions
diff --git a/cesar/interface/src/interface.c b/cesar/interface/src/interface.c
index 43bc1383a1..7df70dbc3e 100644
--- a/cesar/interface/src/interface.c
+++ b/cesar/interface/src/interface.c
@@ -13,9 +13,11 @@
*/
#include "common/std.h"
#include "common/defs/ethernet.h"
+#include "common/defs/priority.h"
#include "lib/swap.h"
-#include "hle/hle.h"
+#include "hal/arch/sem.h"
+
#include "interface/interface.h"
#include "interface/sniffer/mmtype.h"
#include "interface/fcall/defs.h"
@@ -24,8 +26,6 @@
#include "interface/inc/context.h"
#include "interface/inc/mme_process.h"
-#include "common/defs/priority.h"
-
#if CONFIG_INTERFACE_SNIFFER
# include "interface/sniffer/sniffer.h"
#endif
@@ -57,79 +57,38 @@ interface_thread_process (cyg_addrword_t data)
}
#endif
-#if CONFIG_INTERFACE_FCALL
-
-/**
- * Called by the interface fcall module when the buffer has been used.
- * This allows the HLE to know which buffer is newly available to be used or
- * give it back to the ARM. (the buffer is borrowed by the linux).
- *
- * \param ctx the interface context.
- * \param buffer the buffer used to send the data.
- */
-static void
-interface_hle_send_done (interface_t *ctx, u8 *buffer);
-
-#endif
-
-
-/**
- * Initialise the interface module.
- * \param hle the hle 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 (hle_t *hle, cl_t *cl, sar_t *sar, mac_config_t
- *mac_config)
+interface_init (cl_t *cl, cl_mbx_t *mbx, sar_t *sar, mac_config_t *mac_config,
+ bufmgr_t *bufmgr)
{
- dbg_assert (hle);
- dbg_assert (cl);
+ dbg_assert (mbx);
dbg_assert (sar);
dbg_assert (mac_config);
- interface_global.hle = hle;
interface_global.cl = cl;
+ interface_global.cl_mbx = mbx;
interface_global.sar = sar;
interface_global.mac_config = mac_config;
+ interface_global.bufmgr = bufmgr;
#if CONFIG_INTERFACE_SNIFFER
- interface_global.sniffer = interface_sniffer_init
- ((interface_sniffer_send_message_cb_t) interface_hle_send,
- &interface_global, mac_config);
+ interface_global.sniffer =
+ interface_sniffer_init (mbx, bufmgr, mac_config);
#endif /* CONFIG_INTERFACE_SNIFFER */
#if CONFIG_INTERFACE_FCALL
- interface_global.fcall = interface_fcall_init
- ((interface_fcall_send_message_cb_t) interface_hle_send,
- (interface_fcall_send_done_message_cb_t) interface_hle_send_done,
- (interface_fcall_get_buffer_cb_t) interface_buffer_work_get,
- &interface_global, mac_config);
+ interface_global.fcall =
+ interface_fcall_init (mbx, mac_config, bufmgr);
#endif /* CONFIG_INTERFACE_FCALL */
- mbox_init (&interface_global.buffers_mbox);
-
- // Integrate the HLE.
- hle_init_interface_cb (hle,
- (hle_interface_buffer_add_cb_t) interface_buffer_work_add,
- (hle_interface_mme_recv_cb_t) interface_hle_recv,
- &interface_global);
-
- // Integrate the CL.
- cl_mme_init_buffer_add_cb (cl,
- (cl_mme_buffer_add_cb_t) interface_buffer_add,
- &interface_global);
- cl_mme_recv_init (cl,(cl_mme_recv_cb_t) interface_mme_recv,
- &interface_global);
-
+ /* Integrate the CL MBX. */
+ cl_mbx_callback_register (mbx, (cl_mme_callback_t) interface_mme_recv,
+ &interface_global);
- // Create the mailbox.
+ /* Create the mailbox. */
mbox_init (&interface_global.mailbox);
#ifndef INTERFACE_UNIT_TEST
- // Create the interface thread.
cyg_thread_create(INTERFACE_THREAD_PRIORITY, &interface_thread_process,
(cyg_addrword_t) &interface_global,
"INTERFACE",
@@ -151,9 +110,7 @@ void
interface_uninit (interface_t *ctx)
{
dbg_assert (ctx);
-
mbox_uninit (&ctx->mailbox);
-
#ifndef INTERFACE_UNIT_TEST
cyg_thread_suspend (ctx->thread_handle);
#endif
@@ -165,71 +122,57 @@ interface_uninit (interface_t *ctx)
#endif /* CONFIG_INTERFACE_FCALL */
}
-/**
- * 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, void *user_data)
+interface_callback_init (
+ interface_t *ctx, interface_mme_recv_cb_t mme_recv_cb, void *user_data)
{
dbg_assert (ctx);
dbg_assert (mme_recv_cb);
- dbg_assert (buffer_add_cb);
-
ctx->mme_recv_cb = mme_recv_cb;
- ctx->buffer_add_cb = buffer_add_cb;
ctx->interface_mme_user_data = user_data;
}
-/** Receives an MME from the PWL or the HLE.
- * \param ctx the interface context
- * \param tei the station's source TEI.
- * \param buffer the buffer containing the MME.
- * \param length the MME length
- * \param mme_data data use by the CL.
- * \param encrypted inform if the packet comes from the PWL if it has been
- * crypted.
- */
void
interface_mme_recv (interface_t *ctx, uint tei, u8 *buffer, uint length,
- bool mme_data, bool encrypted)
+ bool encrypted)
{
dbg_assert (ctx);
dbg_assert (buffer);
dbg_assert ((length >= ETH_PACKET_MIN_SIZE_ALLOWED)
&& (length <= ETH_PACKET_MAX_SIZE));
-
#if CONFIG_INTERFACE_SNIFFER
if (interface_sniffer_mme_status_rx(ctx->sniffer))
{
- u8 *copy_buffer = interface_buffer_work_get (ctx);
-
- if (copy_buffer)
- {
- interface_sniffer_copy_mme_rx (ctx->sniffer, buffer, length,
- copy_buffer, encrypted);
- }
+ interface_sniffer_copy_mme_rx (ctx->sniffer, buffer, length,
+ encrypted);
}
#endif /* CONFIG_INTERFACE_SNIFFER */
-
- // Call the actor callback.
- dbg_assert (ctx->mme_recv_cb);
- (*ctx->mme_recv_cb) (ctx->interface_mme_user_data, tei, buffer,
- length, mme_data, encrypted);
-}
-
-void
-interface_mme_recv_done (interface_t *ctx, u8 *buffer, bool mme_recv)
-{
- dbg_assert (ctx);
- dbg_assert (ctx->cl);
-
- cl_mme_recv_done (ctx->cl, buffer, mme_recv);
+ /* Filter Interface MMType. */
+ uint ether_type, mmtype_bits_offset, mmtype_base;
+ /* Get the Ethernet type first to detect the VLAN. */
+ ether_type = bitstream_direct_read (
+ buffer, BYTES_SIZE_TO_BITS (HPAV_MTYPE_OFFSET),
+ BYTES_SIZE_TO_BITS (HPAV_MTYPE_SIZE));
+ mmtype_bits_offset = BYTES_SIZE_TO_BITS (HPAV_MMTYPE_OFFSET);
+ /* If the Ether type is an HPAV MME, there is no VLAN tag. */
+ if (swap16 (ether_type) != HPAV_MTYPE_MME)
+ mmtype_bits_offset = BYTES_SIZE_TO_BITS (HPAV_VLANTAG_SIZE);
+ /* Get the MME Type and convert it into the MME Type base. */
+ mmtype_base = bitstream_direct_read (
+ buffer, mmtype_bits_offset, BYTES_SIZE_TO_BITS (HPAV_MMTYPE_SIZE))
+ & ~0x3;
+ /* If MMTYPE is interface FCALL or Sniffer. */
+ if (mmtype_base == INTERFACE_FCALL_MMTYPE
+ || mmtype_base == INTERFACE_SNIFFER_MMTYPE)
+ {
+ mbox_put (&ctx->mailbox, (mbox_node_t *) buffer);
+ }
+ else
+ {
+ dbg_assert (ctx->mme_recv_cb);
+ (*ctx->mme_recv_cb) (ctx->interface_mme_user_data, tei, buffer,
+ length, encrypted);
+ }
}
/** Provides a MME to send to the CL. This MME can be send as a MME or a data.
@@ -245,21 +188,11 @@ interface_mme_send (interface_t *ctx, u8* buffer, uint length, uint tei)
dbg_assert (buffer);
dbg_assert ((length >= ETH_PACKET_MIN_SIZE_ALLOWED)
&& (length <= ETH_PACKET_MAX_SIZE));
-
#if CONFIG_INTERFACE_SNIFFER
if (interface_sniffer_mme_status_tx (ctx->sniffer))
- {
- u8 *copy_buffer = interface_buffer_work_get (ctx);
-
- if (copy_buffer)
- {
- interface_sniffer_copy_mme_tx (ctx->sniffer, buffer, length,
- copy_buffer, false);
- }
- }
+ interface_sniffer_copy_mme_tx (
+ ctx->sniffer, buffer, length, false);
#endif /* CONFIG_INTERFACE_SNIFFER */
-
- dbg_assert (ctx->cl);
cl_mme_send (ctx->cl, buffer, length, tei);
}
@@ -273,153 +206,42 @@ interface_beacon (interface_t *ctx, bsu_beacon_t *beacon)
if (beacon->params.direction == BSU_BEACON_DIRECTION_TO_PLC
&& interface_sniffer_beacon_status_tx (ctx->sniffer))
{
- u8 *buffer = interface_buffer_work_get (ctx);
- if (buffer)
- interface_sniffer_copy_beacon_tx (
- ctx->sniffer, beacon, buffer);
+ interface_sniffer_copy_beacon_tx (ctx->sniffer, beacon);
}
else if (beacon->params.direction == BSU_BEACON_DIRECTION_FROM_PLC
&& interface_sniffer_beacon_status_rx (ctx->sniffer))
{
- u8 *buffer = interface_buffer_work_get (ctx);
- if (buffer)
- interface_sniffer_copy_beacon_rx (
- ctx->sniffer, beacon, buffer);
+ interface_sniffer_copy_beacon_rx (ctx->sniffer, beacon);
}
#endif /* CONFIG_INTERFACE_SNIFFER */
}
-/**
- * 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_hle_send (interface_t *ctx, uint *data, uint length)
-{
- dbg_assert (ctx);
- dbg_assert (data);
- dbg_assert (length);
-
- hle_ipmbox_send (ctx->hle, data, length);
-}
-
-#if CONFIG_INTERFACE_FCALL
-
-/**
- * Called by the interface fcall module when the buffer has been used.
- * This allows the HLE to know which buffer is newly available to be used or
- * give it back to the ARM. (the buffer is borrowed by the linux).
- *
- * \param ctx the interface context.
- * \param buffer the buffer used to send the data.
- */
-static void
-interface_hle_send_done (interface_t *ctx, u8 *buffer)
-{
- dbg_assert (ctx);
- dbg_assert (buffer);
- dbg_assert (ctx->hle);
-
- hle_send_done (ctx->hle, buffer);
-}
-
-#endif /* CONFIG_INTERFACE_FCALL */
-
-/**
- * Add a buffer to the registered actor.
- * \param ctx the interface context.
- * \param buffer the buffer to add.
- */
-void
-interface_buffer_add (interface_t *ctx, u8 *buffer)
-{
- dbg_assert (ctx);
- dbg_assert (buffer);
- dbg_assert (ctx->buffer_add_cb);
-
- (*ctx->buffer_add_cb) (ctx->interface_mme_user_data, buffer);
-}
-
-/**
- * Add a buffer to its own list.
- * \param ctx the interface context.
- * \param buffer the buffer to add.
- */
-void
-interface_buffer_work_add (interface_t *ctx, u8 *buffer)
-{
- dbg_assert (ctx);
- dbg_assert (buffer);
-
- dbg_assert (ctx->buffer_add_cb);
-
- mbox_put (&ctx->buffers_mbox, (mbox_node_t *) 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_work_get (interface_t *ctx)
-{
- u8 *buffer;
- dbg_assert (ctx);
-
- buffer = (u8*) mbox_try_get (&ctx->buffers_mbox);
-
- return buffer;
-}
-
-/**
- * Receive a data from the HLE.
- * \param ctx the interface context.
- * \param buffer the Message received.
- *
- * This will be use by the Fcall module in the interface. It can be use by
- * anything in the future.
- */
-void
-interface_hle_recv (interface_t *ctx, u8 *buffer)
-{
- dbg_assert (ctx);
- dbg_assert (buffer);
-
- mbox_put (&ctx->mailbox, (mbox_node_t *) buffer);
-}
-
static inline bool
interface_read_mme (interface_t *ctx, u8 *mme, uint *mmtype)
{
bitstream_t stream;
- mac_t oda = 0;
- mac_t osa = 0;
- uint vlantag = 0;
uint mtype = 0;
uint mmv = 0;
uint fmi = 0;
- uint offset = 0;
bitstream_read_init (&stream, mme, ETH_PACKET_MAX_SIZE);
- oda = bitstream_read_large (&stream, 48);
- osa = bitstream_read_large (&stream, 48);
+ bitstream_skip (&stream, 48);
+ bitstream_skip (&stream, 48);
if (bitstream_direct_read (mme, 96, 16) != swap16(HPAV_MTYPE_MME))
- vlantag = bitstream_read (&stream, 32);
+ bitstream_skip (&stream, 32);
mtype = swap16(bitstream_read (&stream, 16));
mmv = bitstream_read (&stream, 8);
*mmtype = bitstream_read (&stream, 16);
fmi = bitstream_read (&stream, 16);
- offset = bitstream_finalise (&stream);
+ bitstream_finalise (&stream);
- if ((mtype == HPAV_MTYPE_MME)
- && (mmv == HPAV_MMV)
- && ((*mmtype == VS_SNIFFER_REQ)
- || (*mmtype == INTERFACE_FCALL_MMTYPE)))
+ if (mtype == HPAV_MTYPE_MME
+ && mmv == HPAV_MMV
+ && (*mmtype == VS_SNIFFER_REQ
+ || *mmtype == INTERFACE_FCALL_MMTYPE_IND)
+ && fmi == 0)
return true;
return false;
}
@@ -441,30 +263,16 @@ interface_process (interface_t *ctx)
// Configure the interface sniffer sub module.
case VS_SNIFFER_REQ:
{
- u8 *ans = interface_buffer_work_get (ctx);
+ u8 *ans = bufmgr_get_wait (ctx->bufmgr, 0);
interface_sniffer_configure_and_respond (ctx->sniffer, buffer,
ans);
- uint word[2];
- /* Give back the current buffer. */
- word[0] = BF_FILL (IPMBOX_REG, (MSG_TYPE,
- HLE_MSG_TYPE_SEND_DONE),
- (MSG_LENGTH, 1));
- word[1] = (uint) buffer;
- interface_hle_send (ctx, word, 2);
- /* Send the CNF MME. */
- word[0] = BF_FILL (IPMBOX_REG, (MSG_TYPE,
- HLE_MSG_TYPE_INTERFACE),
- (MSG_LENGTH, 1),
- (PARAM_INTERFACE_TYPE,
- INTERFACE_MODULE_SNIFFER),
- (PARAM_INTERFACE_LENGTH, 60));
- word[1] = (uint) ans;
- interface_hle_send (ctx, word, 2);
+ bufmgr_give_back (ctx->bufmgr, buffer);
+ cl_mme_send (ctx->cl, ans, 60, MAC_TEI_FOREIGN);
}
break;
#endif /* CONFIG_INTERFACE_SNIFFER */
#if CONFIG_INTERFACE_FCALL
- case INTERFACE_FCALL_MMTYPE:
+ case INTERFACE_FCALL_MMTYPE_IND:
interface_fcall_mme_recv (ctx->fcall, buffer);
break;
#endif /* CONFIG_INTERFACE_FCALL */