From 3ed571f9d933e5c5dadef650c07e20e8aad06213 Mon Sep 17 00:00:00 2001 From: IPMbox Team Date: Fri, 3 Feb 2012 14:32:28 +0100 Subject: cesar, cleopatre, common: new ipmbox design, closes #848 --- cesar/interface/src/interface.c | 320 ++++++++-------------------------------- 1 file changed, 64 insertions(+), 256 deletions(-) (limited to 'cesar/interface/src') 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 */ -- cgit v1.2.3