/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file ../../src/rx.c * \brief « brief description » * \ingroup « module » * * « long description » */ #include "common/std.h" #include "ce/inc/rx.h" #define RXCE #include "ce/inc/cei.h" #include "ce/test/common/print_utils.h" #include "cp/cp.h" #include "ce/test/rx/inc/test_rx.h" //Will be a pbproc.h rxce_t ctx; rxce_t * rxce_init (mac_store_t *mac_store_ctx, mac_config_t *mac_config_ctx) { //my_print ("rxce_init\n"); dbg_assert (mac_store_ctx); dbg_assert (mac_config_ctx); ctx.mac_store_ctx = mac_store_ctx; // Initialize THRESHOLD NOISE for computation frame_measurement_init (); // Initialize FIFO for cei message to create. cei_param_fifo_init(); // Initialize RXCE with no 'job' to do. cyg_semaphore_init (&ctx.job, 0); // Initialize the pointer to he global tonemask ctx.mask = mac_config_ctx->tonemask_info.tonemask; return (&ctx); } void pbproc_need_scf_cb (uint tei, uint src) { //my_print ("pbproc_need_scf_cb\n"); dbg_assert (&ctx); dbg_assert (&ctx.job); dbg_assert (MAC_TEI_IS_STA(tei)); dbg_assert ( (src>=0x04 && src<=0x1F) || (src>=0xFC && src<=0xFF) ); // Don't add job if CE didn't have process previous pbproc_need_scf. // This callback can't be interrupted by rxce_process. if (!ctx.pbproc_need_scf) { cyg_semaphore_post (&ctx.job); } ctx.pbproc_scf_tei = tei; ctx.pbproc_scf_src = src; ctx.pbproc_need_scf = true; } bool sar_mpdu_measurement_cb (void*user, pbproc_rx_params_t *rx_params, uint pb_nb, blk_t **f, blk_t **l, pb_t *noise) { //my_print ("sar_mpdu_measurement_cb\n"); dbg_assert (rx_params); bool b; pb_measurement_list_t **first = (pb_measurement_list_t **) f; pb_measurement_list_t **last = (pb_measurement_list_t **) l; // Allocate block if necessary. The SAR will fill blocks after !couldn't be stopped by RXCE!. b = frame_measurement_append (rx_params, pb_nb, first, last, (phy_chandata_t *) noise); // Give 'job' to RXCE that will process the previous frame. if (b) cyg_semaphore_post (&ctx.job); //else my_print ("frame measurement dropped\n"); return (b); } /** todo Cf SPEC HPAV HPAV-FrameControl -- SoundVariantField -- SoundReasonCode */ bool compute_scf (void) { //my_print ("compute scf\n"); bool ret = false; sta_t *sta; tonemaps_t *tms; if (ctx.pbproc_scf_src >= 0x04 && ctx.pbproc_scf_src <= 0x1F) //Interval with an invalid tonemap. { sta = mac_store_sta_get(ctx.mac_store_ctx, ctx.pbproc_scf_tei); tms = sta->rx_tonemaps; cei_param_t cei; cei.tms = tms; cei.new_tmi = ctx.pbproc_scf_src - 4; cei.old_tmi = TONEMAP_INDEX_NULL; cei.priority = CEI_PRIORITY; cei.dtei = ctx.pbproc_scf_tei; // add cei_param with the above parameters and add a 'job' for rxce. cei_param_add (&cei); cyg_semaphore_post (&ctx.job); ret = true; blk_release (sta); } if (ctx.pbproc_scf_src == 0xFC ) { //TODO SEND ALL VALID TM ret = true; } if (ctx.pbproc_scf_src == 0xFD ) { sta = mac_store_sta_get(ctx.mac_store_ctx, ctx.pbproc_scf_tei); tms = sta->rx_tonemaps; if (tms->cp_tmi_av != TONEMAP_INDEX_NULL) { ret = true; } else { ret = false; } blk_release (sta); } if (ctx.pbproc_scf_src == 0xFE) { // IF INTERVAL CONCERNED HAS TM ret = true;and cei_param_add // ELSE ret = false; // todo - it will be necessary to know the date. } if (ctx.pbproc_scf_src == 0xFF) { ret = false; } return (ret); } int // tei of destination station rxce_create_mme (u8 *cp_mme_buffer, u8 *mask) { //my_print ("create_mme\n"); dbg_assert (cp_mme_buffer); dbg_assert (mask); cei_param_t *to_build = cei_param_get(); dbg_assert (to_build); cei_tonemaps_to_mme (*to_build, cp_mme_buffer, mask); return (to_build->dtei); } void rxce_compute_measurement (void) { //my_print ("compute_measurement\n"); //frame_measurement_t *frame_measurement = frame_measurement_get_first(); frame_measurement_t *frame_measurement = frame_measurement_get_next (); dbg_assert (frame_measurement); pbproc_rx_params_t *rx_params = frame_measurement->rx_params; dbg_assert (rx_params); //my_print ("@rx_params = 0x%x, tei = %d\n", rx_params, rx_params->tei); sta_t *ssta = mac_store_sta_get (ctx.mac_store_ctx, rx_params->tei); dbg_assert (ssta); if ( ssta->rx_tonemaps->cp_tmi_av == TONEMAP_INDEX_NULL ) // no default_tonemap { rxce_initial (ssta, frame_measurement); } else { rxce_dynamic (ssta, frame_measurement); } ssta->rxce.measurement_computed_nb++; blk_release (ssta); frame_measurement_release (frame_measurement); } void rxce_initial (sta_t *ssta, frame_measurement_t *frame_measurement) { //my_print ("initial_ce\n"); dbg_assert (ssta); dbg_assert (frame_measurement); tonemaps_t *tms = ssta->rx_tonemaps; //todo if (null ber) if (is_time_noise_stable(frame_measurement->type_head[PHY_CHANDATA_TYPE_TIME_NOISE])) { //TODO if ROBO ssta->rxce.stable_ROBO_nb++; // else stable_nonROBO_nb compute_worst_tonemap (&ssta->rxce.tm_in_build, frame_measurement->type_head[PHY_CHANDATA_TYPE_FREQ_NOISE]); if (ssta->rxce.stable_ROBO_nb >= SOUND_NB) { tms->cp_tmi_av = tonemap_set_first_free (tms, ssta->rxce.tm_in_build); ssta->rxce.tm_in_build = NULL; cei_param_t cei_param; cei_param.tms = tms; cei_param.new_tmi = tms->cp_tmi_av; cei_param.old_tmi = 0; cei_param.priority = CEI_PRIORITY; cei_param.dtei = ssta->tei; cei_param_add (&cei_param); cyg_semaphore_post (&ctx.job); } //TODO else if timestamp_ROBO_us > 20000 } else { //TODO if ROBO ssta->rxce.unstable_ROBO_nb++; // else stable_nonROBO_nb //TODO manage_interval (tms, frame_measurement); } //if (ssta->rx_tonemaps->cp_tmi_av != NULL_TONEMAP_INDEX ) print_tonemap (ssta->rx_tonemaps->tm[ssta->rx_tonemaps->cp_tmi_av]); } void rxce_dynamic (sta_t *sta, frame_measurement_t *frame_measurement) { //my_print ("dynamic_ce\n"); dbg_assert (sta); dbg_assert (frame_measurement); if (!sta->rxce.tm_in_build) sta->rxce.tm_in_build = tonemap_alloc (); //print_tonemap (sta->rxce.tm_in_build); // SOMETHING TODO BUT WHAT...??? } void rxce_process (cyg_addrword_t data) { while (true) { //my_print ("rxce wait\n"); cyg_semaphore_wait (&ctx.job); //my_print("rxce works\n"); if (ctx.pbproc_need_scf) // At first, verify if pbproc waits information about scf. { //TODO ATOMIC ctx.pbproc_need_scf = false; bool b = compute_scf (); if (b) { pbproc_scf (); // a pbproc function. } } else { if (cei_param_fifo.number > 0 ) // Then Create CEI if waited. { u8 *buf = cp_give_buffer (); cp_rxce_send_mme (rxce_create_mme (buf, ctx.mask), buf); } else // Compute measurement { //dbg_assert (frame_measurement_get()); rxce_compute_measurement (); } } } }