/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file cl/src/cl_mactotei.c * \brief MAC to TEI table interface between the CL and the CP. * \ingroup cl */ #include "common/std.h" #include "mac/common/defs.h" #include "cl/cl_mactotei.h" #include "cl/inc/context.h" /** * Set a TEI and a tag in an extra information field. * \param tei TEI to set. * \param tag Tag to set. * \return The extra information value with the TEI and tag set correctly. */ static inline u16 cl_mactotei_set_tei_tag (uint tei, uint tag) { /* Check parameters. */ dbg_assert (MAC_TEI_IS_STA (tei) || (tei == MAC_TEI_BCAST)); dbg_assert (tag <= 0xFF); u16 extra_info = 0; extra_info = tei; extra_info <<= 8; extra_info |= tag; return extra_info; } /** * Internal release of a MAC to TEI table. * \param mactotei_table MAC to TEI table to release. * * This function supports to have a NULL mactotei_table (in this case, it does * nothing). It can be used to do an atomic release of the MAC to TEI table. * The differences with the cl_mactotei_release_table function are: * - it does not depend on the CL context, it only needs a * cl_mactotei_table_t, * - this function is private. */ static inline void cl_mactotei_release_table_internal (cl_mactotei_table_t *mactotei_table) { /* If there is a table to release. */ if (mactotei_table) { /* Release. */ mac_lookup_table_release (mactotei_table); } } cl_mactotei_blk_t * cl_mactotei_new (void) { return mac_lookup_table_create (); } void cl_mactotei_copy_tei_and_tag (cl_t *ctx, cl_mactotei_blk_t *table, uint tei, uint tag) { /* Check parameters. */ dbg_assert (ctx); /* Nothing to copy. */ if (ctx->mactotei == NULL) return; /* Copy entries with matching TEI and tag. */ mac_lookup_table_copy (ctx->mactotei, table, 0xFFFF, cl_mactotei_set_tei_tag (tei, tag)); } void cl_mactotei_copy_tei (cl_t *ctx, cl_mactotei_blk_t *table, uint tei) { /* Check parameters. */ dbg_assert (ctx); /* Nothing to copy. */ if (ctx->mactotei == NULL) return; /* Copy entries with matching TEI. */ mac_lookup_table_copy (ctx->mactotei, table, 0xFF00, cl_mactotei_set_tei_tag (tei, 0)); } void cl_mactotei_addr_add (cl_mactotei_blk_t *table, mac_t mac_addr, uint tei, uint tag) { /* No need to check parameters, they are not directly used by this * function. */ /* Add MAC address and extra information associated to the table. */ mac_lookup_table_add_entry (table, mac_addr, cl_mactotei_set_tei_tag (tei, tag)); } void cl_mactotei_release_table (cl_t *ctx) { /* Check parameters. */ dbg_assert (ctx); /* Copy the MAC to TEI table into a temporary one. */ cl_mactotei_table_t *tmp = ctx->mactotei; /* Atomic release. */ ctx->mactotei = NULL; /* Do the real release. */ cl_mactotei_release_table_internal (tmp); /* Clear data_send_link cache. */ cl_data_send_link_clear (ctx); } void cl_mactotei_use_table (cl_t *ctx, cl_mactotei_blk_t *table) { /* Check parameter that need it. */ dbg_assert (ctx); /* Copy the MAC to TEI table into a temporary one. */ cl_mactotei_table_t *tmp = ctx->mactotei; /* Atomic set up new table. */ ctx->mactotei = mac_lookup_table_convert (table); /* Do the real release of previous table. */ cl_mactotei_release_table_internal (tmp); /* Clear data_send_link cache. */ cl_data_send_link_clear (ctx); } uint cl_mactotei_table_find_tei_from_mac (cl_t *ctx, mac_t mac) { /* Check parameter. */ dbg_assert (ctx); /* Empty MAC to TEI table? */ if (ctx->mactotei) { u16 extra_info; /* Entry exist? */ if (mac_lookup_table_find_entry (ctx->mactotei, mac, &extra_info)) { CL_TRACE (MACTOTEI_FIND_TEI, phy_date (), TRACE_U64 (mac), true, extra_info >> 8); return extra_info >> 8; } } /* Entry does not exist. */ CL_TRACE (MACTOTEI_FIND_TEI, phy_date (), TRACE_U64 (mac), false, MAC_TEI_UNASSOCIATED); return MAC_TEI_UNASSOCIATED; } uint ARCH_ILRAM_PRIO (4) cl_mactotei_table_find_tei_and_tag_from_mac (cl_t *ctx, mac_t mac, uint *tag) { /* Check parameter. */ dbg_assert (ctx); /* Empty MAC to TEI table? */ if (ctx->mactotei) { u16 extra_info; /* Entry exist? */ if (mac_lookup_table_find_entry (ctx->mactotei, mac, &extra_info)) { CL_TRACE (MACTOTEI_FIND_TEI, phy_date (), TRACE_U64 (mac), true, extra_info >> 8); *tag = extra_info & 0xFF; return extra_info >> 8; } } /* Entry does not exist. */ CL_TRACE (MACTOTEI_FIND_TEI, phy_date (), TRACE_U64 (mac), false, MAC_TEI_UNASSOCIATED); return MAC_TEI_UNASSOCIATED; } void cl_mactotei_copy_except_tag (cl_t *ctx, cl_mactotei_blk_t *table, uint tag) { /* Check parameters. */ dbg_assert (ctx); /* Nothing to copy. */ if (ctx->mactotei == NULL) return; /* Copy entries with matching TEI and tag. */ mac_lookup_table_copy_except (ctx->mactotei, table, 0x00FF, tag); } void cl_mactotei_copy_except_tei (cl_t *ctx, cl_mactotei_blk_t *table, uint tei) { /* Check parameters. */ dbg_assert (ctx); /* Nothing to copy. */ if (ctx->mactotei == NULL) return; /* Copy entries with matching TEI and tag. */ mac_lookup_table_copy_except ( ctx->mactotei, table, 0xFF00, cl_mactotei_set_tei_tag (tei, 0)); } void cl_mactotei_cancel (cl_mactotei_blk_t *table) { /* Release table from memory. */ mac_lookup_table_delete (table); } uint cl_mactotei_table_size (cl_t *ctx) { dbg_assert (ctx); if (ctx->mactotei == NULL) return 0; return mac_lookup_entry_count (ctx->mactotei); } void cl_mactotei_table_get_entry (cl_t *ctx, uint index, cl_mactotei_entry_t* data) { u16 extra_info; dbg_assert (ctx); dbg_assert (data); if (ctx->mactotei == NULL) return; mac_lookup_table_get_entry (ctx->mactotei, index, &data->mac, &extra_info); data->tei = extra_info >> 8; data->tag = extra_info & 0x00FF; }