/* Cesar project {{{ * * Copyright (C) 2010 Spidcom * * <<>> * * }}} */ /** * \file bsu/src/interface.c * \brief BSU interface functions. * \ingroup bsu * * BSU interface functions with the SAR and upper layer. */ #include "common/std.h" #include "hal/arch/arch.h" #include "lib/fixed.h" #include "lib/bitstream.h" #include "bsu/bsu.h" #include "bsu/inc/bsu.h" #include "bsu/inc/context.h" void bsu_beacon_send_upper_layer (bsu_t *ctx, bsu_beacon_t *beacon, bsu_beacon_direction_t direction) { beacon->params.direction = direction; (*ctx->ul_cb) (ctx->ul_data, beacon); } /** * Get the MFS from the MAC store. * \param ctx the module context. * \param type the beacon type. * \return the MFS. */ static inline mfs_tx_t* bsu_beacon_send_mfs_get (bsu_t *ctx, bsu_beacon_type_t type) { bool added; mfs_tx_t *mfs; /* Get lid from the beacon type. */ switch (type) { case BSU_BEACON_TYPE_CENTRAL: mfs = mac_store_mfs_add_tx (ctx->mac_store, true, false, MAC_LID_SPC_CENTRAL, MAC_TEI_BCAST, &added); break; case BSU_BEACON_TYPE_DISCOVER: mfs = mac_store_mfs_add_tx (ctx->mac_store, true, false, MAC_LID_DISCOVER, MAC_TEI_BCAST, &added); break; default: dbg_assert_default (); } dbg_assert (mfs); ctx->mfs_beacons[type] = mfs; /* If the MFS is new, configure it. */ if (added) { /* Highest priority for central beacon. */ if (type == BSU_BEACON_TYPE_CENTRAL) mfs->cap = 0x3; else mfs->cap = 0x2; mfs->beacon = true; ca_mfs_add (ctx->ca, mfs); } return mfs; } void bsu_beacon_send (bsu_t *ctx, bsu_beacon_type_t beacon_type, pb_beacon_t *beacon, void *bto_bpsto) { dbg_assert (ctx); dbg_assert (beacon); dbg_assert (beacon_type < BSU_BEACON_TYPE_NB); dbg_assert (bto_bpsto); dbg_assert (bitstream_direct_read (beacon->data, 32, 3) == beacon_type); mfs_tx_t *mfs = ctx->mfs_beacons[beacon_type]; if (!mfs) mfs = bsu_beacon_send_mfs_get (ctx, beacon_type); /* Hold the segment until the next beacon period. Only for central * beacons. To be done each time, the CA only held until the next beacon * period it is not forever. */ ctx->beacon_nb_sent[beacon_type]++; if (beacon_type == BSU_BEACON_TYPE_CENTRAL) ca_mfs_hold (ctx->ca, mfs); mfs->cfp = ctx->sta_avln->beacon.vf.hm == MAC_COEXISTENCE_AV_ONLY_MODE; beacon->expiration_ntb = bsu_aclf_beacon_expiration_date (ctx->aclf) + ctx->mac_config->ntb_offset_tck; /* Provide the beacon to the SAR. */ sar_beacon_send (ctx->sar, beacon, mfs, bto_bpsto); BSU_TRACE (BEACON_SEND, phy_date (), beacon_type); } void bsu_beacon_recv (bsu_t *ctx, pb_beacon_t *beacon, pbproc_rx_beacon_params_t *params) { dbg_assert (ctx); dbg_assert (beacon); dbg_assert (params); /* Load beacon into the cache. */ arch_load_cache (&beacon->first_data_word, 1); arch_load_cache ((u32*) beacon->data, BLK_SIZE / 4); /* Process the beacon received from the SAR. */ bsu_beacon_t *bsu_beacon = bsu_beacon_process (ctx, beacon, params); if (bsu_beacon) bsu_beacon_send_upper_layer (ctx, bsu_beacon, BSU_BEACON_DIRECTION_FROM_PLC); blk_release_desc ((blk_t*) beacon); }