diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index e1b2627c09a57c02a02aaef3c4c489a9be9adba8..e280b3f62578756236587ddd451be9237d475984 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -165,6 +165,12 @@ typedef enum { NGFI_RCC_IF4 // NGFI_RCC (NGFI radio cloud center, currently split at common - ue_specific interface, IF4) } eNB_func_t; +typedef enum { + synch_to_ext_device=0, // synch to RF or Ethernet device + synch_to_other // synch to another source (timer, other CC_id) +} eNB_timing_t; + + typedef struct UE_SCAN_INFO_s { /// 10 best amplitudes (linear) for each pss signals int32_t amp[3][10]; @@ -211,7 +217,7 @@ typedef struct { struct sched_param sched_param_rxtx; } eNB_rxtx_proc_t; /// Context data structure for eNB subframe processing -typedef struct { +typedef struct eNB_proc_t_s { /// Component Carrier index uint8_t CC_id; /// thread index @@ -226,29 +232,46 @@ typedef struct { int frame_rx; /// frame to act upon for PRACH int frame_prach; + /// \brief Instance count for FH processing thread. + /// \internal This variable is protected by \ref mutex_FH. + int instance_cnt_FH; /// \brief Instance count for rx processing thread. /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; - /// pthread structure for rx processing thread - pthread_t pthread_rx; + /// pthread structure for FH processing thread + pthread_t pthread_FH; + /// pthread structure for asychronous RX processing thread + pthread_t pthread_asynch_rx; /// flag to indicate first RX acquisition int first_rx; - /// pthread attributes for rx processing thread - pthread_attr_t attr_rx; + /// pthread attributes for FH processing thread + pthread_attr_t attr_FH; /// pthread attributes for prach processing thread pthread_attr_t attr_prach; - /// scheduling parameters for rx thread - struct sched_param sched_param_rx; + /// pthread attributes for asynchronous RX thread + pthread_attr_t attr_asynch_rx; + /// scheduling parameters for FH thread + struct sched_param sched_param_FH; /// scheduling parameters for prach thread struct sched_param sched_param_prach; - /// condition variable for prach processing thread + /// scheduling parameters for asynch_rx thread + struct sched_param sched_param_asynch_rx; + /// condition variable for FH thread pthread_t pthread_prach; - /// condition variable for rx processing thread; + /// condition variable for FH thread + pthread_cond_t cond_FH; + /// condition variable for PRACH processing thread; pthread_cond_t cond_prach; - /// mutex for tx processing thread + /// mutex for FH + pthread_mutex_t mutex_FH; + /// mutex for PRACH thread pthread_mutex_t mutex_prach; /// set of scheduling variables RXn-TXnp4 threads eNB_rxtx_proc_t proc_rxtx[2]; + /// number of slave threads + int num_slaves; + /// array of pointers to slaves + struct eNB_proc_t_s **slave_proc; } eNB_proc_t; @@ -311,6 +334,7 @@ typedef struct PHY_VARS_eNB_s { uint8_t CC_id; eNB_proc_t proc; eNB_func_t node_function; + eNB_timing_t node_timing; uint8_t local_flag; uint32_t rx_total_gain_dB; LTE_DL_FRAME_PARMS frame_parms; @@ -456,11 +480,6 @@ typedef struct PHY_VARS_eNB_s { time_stats_t phy_proc; time_stats_t phy_proc_tx; time_stats_t phy_proc_rx; - /* - time_stats_t phy_proc_sf[10]; // for each subframe - time_stats_t phy_proc_tx_sf[10]; - time_stats_t phy_proc_rx_sf[10]; - */ time_stats_t rx_prach; time_stats_t ofdm_mod_stats; @@ -505,11 +524,6 @@ typedef struct PHY_VARS_eNB_s { int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; -#if ENABLE_RAL - hash_table_t *ral_thresholds_timed; - SLIST_HEAD(ral_thresholds_gen_poll_enb_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; - SLIST_HEAD(ral_thresholds_lte_poll_enb_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; -#endif /// RF and Interface devices per CC openair0_device rfdevice; @@ -520,13 +534,6 @@ typedef struct PHY_VARS_eNB_s { } PHY_VARS_eNB; #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg -//#define debug_msg msg - -/* -typedef enum { - max_gain=0,med_gain,byp_gain -} rx_gain_t; -*/ /// Top-level PHY Data Structure for UE typedef struct { diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 653b5aeb1ec48b9ff45689e18fdd6eac343d84cf..1a1c2f4ad0bb75d58616644f399711b4837fb624 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2519,29 +2519,17 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl int i,l; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - void *rxp[fp->nb_antennas_rx]; - unsigned int rxs; + eNB_proc_t *proc = &eNB->proc; int subframe = proc->subframe_rx; int frame = proc->frame_rx; - int prach_rx; - uint8_t seqno=0; - uint16_t packet_type; - uint32_t symbol_number=0; - uint32_t symbol_mask, symbol_mask_full; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 ); - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } + - // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_COMMON_RX,1); start_meas(&eNB->phy_proc_rx); #ifdef DEBUG_PHY_PROC @@ -2549,77 +2537,11 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl #endif if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot) - - if ((eNB->node_function == NGFI_RRU_IF4) || - (eNB->node_function == NGFI_RRU_IF5) || - (eNB->node_function == eNodeB_3GPP)) { // acquisition from RF - - for (i=0; i<fp->nb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, - &proc->timestamp_rx, - rxp, - fp->samples_per_tti, - fp->nb_antennas_rx); - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - - if (proc->first_rx == 0) { - if (proc->subframe_rx != subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); - exit_fun("Exiting"); - } - if (proc->frame_rx != frame) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); - exit_fun("Exiting"); - } - } else { - proc->first_rx = 0; - } - // printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); - - if (rxs != fp->samples_per_tti) - exit_fun( "problem receiving samples" ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - } else if(eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF - /// **** recv_IF5 of rxdata from RRH **** /// - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); - recv_IF5(eNB, &proc->timestamp_rx, proc->subframe_rx, IF5_RRH_GW_UL); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); - - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - if (proc->first_rx == 0) { - if (proc->subframe_rx != subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); - //exit_fun("Exiting"); - } - if (proc->frame_rx != frame) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); - //exit_fun("Exiting"); - } - } else { - proc->first_rx = 0; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); - } - if ((eNB->node_function == NGFI_RRU_IF4) || - (eNB->node_function == eNodeB_3GPP) || - (eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing + (eNB->node_function == eNodeB_3GPP) || + (eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing // now do common RX processing for first slot in subframe VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1); @@ -2641,131 +2563,61 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl 0 ); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0); - if (eNB->node_function == NGFI_RRU_IF4 && is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)<=0) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0); + + if (eNB->node_function == NGFI_RRU_IF4) { /// **** send_IF4 of rxdataF to RCC (no prach now) **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 ); send_IF4(eNB, frame, subframe, IF4_PULFFT, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 ); } - /// **** send_IF4 of prach to RCC **** /// done in prach thread (below) - // check if we have to detect PRACH first - if (is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0) { - // wake up thread for PRACH RX - if (pthread_mutex_lock(&proc->mutex_prach) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach ); - exit_fun( "error locking mutex_prach" ); - return; - } - - int cnt_prach = ++proc->instance_cnt_prach; - // set timing for prach thread - proc->frame_prach = proc->frame_rx; - proc->subframe_prach = proc->subframe_rx; - - pthread_mutex_unlock( &proc->mutex_prach ); - - if (cnt_prach == 0) { - // the thread was presumably waiting where it should and can now be woken up - if (pthread_cond_signal(&proc->cond_prach) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - } else { - LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,cnt_prach); - exit_fun( "PRACH thread busy" ); - return; - } - } - } else if (eNB->node_function == NGFI_RRU_IF5) { + } + else if (eNB->node_function == NGFI_RRU_IF5) { /// **** send_IF5 of rxdata to BBU **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); - - } else if (eNB->node_function == NGFI_RCC_IF4) { - /// **** recv_IF4 of rxdataF from RRU **** /// - /// **** recv_IF4 of rxsigF from RRU **** /// - // get frame/subframe information from IF4 interface - // timed loop (200 us) - - symbol_number = 0; - symbol_mask = 0; - symbol_mask_full = (1<<fp->symbols_per_tti)-1; - prach_rx = 0; - - do { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); - recv_IF4(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); - - if (packet_type == IF4_PULFFT) { - symbol_mask = symbol_mask | (1<<symbol_number); - - } else if (packet_type == IF4_PRACH) { - // wake up thread for PRACH RX - prach_rx = 1; - - if (pthread_mutex_lock(&proc->mutex_prach) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach ); - exit_fun( "error locking mutex_prach" ); - return; - } - - int cnt_prach = ++proc->instance_cnt_prach; - // set timing for prach thread - proc->frame_prach = proc->frame_rx; - proc->subframe_prach = proc->subframe_rx; - - pthread_mutex_unlock( &proc->mutex_prach ); - - if (cnt_prach == 0) { - // the thread was presumably waiting where it should and can now be woken up - if (pthread_cond_signal(&proc->cond_prach) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - } else { - LOG_W( PHY,"[eNB] Frame %d, eNB PRACH thread busy!!\n", frame); - exit_fun( "PRACH thread busy" ); - return; - } - } - - } while( (symbol_mask != symbol_mask_full) && (prach_rx == 0)); - - if (proc->first_rx == 0) { - if (proc->subframe_rx != subframe){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); - //exit_fun("Exiting"); - } - if (proc->frame_rx != frame) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); - //exit_fun("Exiting"); - } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); + } + + /// **** send_IF4 of prach to RCC **** /// done in prach thread (below) + // check if we have to detect PRACH first + if ((eNB->node_function != NGFI_RRU_IF5) && + (is_prach_subframe(fp,proc->frame_rx,proc->subframe_rx)>0)) { // any other node must call prach procedure + // wake up thread for PRACH RX + if (pthread_mutex_lock(&proc->mutex_prach) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach ); + exit_fun( "error locking mutex_prach" ); + return; + } + + int cnt_prach = ++proc->instance_cnt_prach; + // set timing for prach thread + proc->frame_prach = proc->frame_rx; + proc->subframe_prach = proc->subframe_rx; + + pthread_mutex_unlock( &proc->mutex_prach ); + + if (cnt_prach == 0) { + // the thread was presumably waiting where it should and can now be woken up + if (pthread_cond_signal(&proc->cond_prach) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); + exit_fun( "ERROR pthread_cond_signal" ); + return; + } } else { - proc->first_rx = 0; + LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB PRACH thread busy (IC %d)!!\n", proc->frame_rx,proc->subframe_rx,cnt_prach); + exit_fun( "PRACH thread busy" ); + return; } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); - - // Tobi aka mr monaco: ETH - - } else { // should not get here - AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function); } - } else { // grab transport channel information from network interface } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 ); } @@ -2784,7 +2636,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 ); start_meas(&eNB->phy_proc_rx); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe); @@ -3346,7 +3198,8 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const phy_procedures_emos_eNB_RX(subframe,eNB); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); + stop_meas(&eNB->phy_proc_rx); } diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index bb00aced6661bb11d92e4012b66f954403e4fd55..c16fbb5e8d2ae4c4ecd07a6933bd919f9bf3e63c 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -435,14 +435,16 @@ static void* eNB_thread_rxtx( void* param ) { if (oai_exit) break; + // Common procedures + phy_procedures_eNB_common_RX(PHY_vars_eNB_g[0][proc->CC_id], 0); + // UE-specific RX processing for subframe n if ((PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP) || (PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) || (PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RCC_IF4)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 ); + // this is the ue-specific processing for the subframe and can be multi-threaded later phy_procedures_eNB_uespec_RX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); } // TX processing for subframe n+4 @@ -629,23 +631,122 @@ static void wait_system_ready (char *message, volatile int *start_flag) { } #endif +/*! + * \brief The Asynchronous RX FH thread of RAU/RCC/eNB. + * This handles the RX FH for an asynchronous RRU/UE + * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ +static void* eNB_thread_asynch_rx( void* param ) { + + eNB_proc_t *proc = (eNB_proc_t*)param; + PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + openair0_timestamp timestamp_rx; + int frame_rx,subframe_rx; + int first_rx = 1; + uint16_t packet_type; + uint32_t symbol_number=0; + uint32_t symbol_mask, symbol_mask_full; + int prach_rx; + + if (eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF + /// **** recv_IF5 of rxdata from RRH **** /// + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); + recv_IF5(eNB, ×tamp_rx, subframe_rx++, IF5_RRH_GW_UL); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); + if (first_rx == 1) { + first_rx = 0; + subframe_rx = (timestamp_rx/fp->samples_per_tti)%10; + } + else { + // check timestamp + if ((timestamp_rx - proc->timestamp_rx) < (2*fp->samples_per_tti)) + printf("RX overflow ...\n"); + + } + } // eNodeB_3GPP_BBU + + else if (eNB->node_function == NGFI_RCC_IF4) { + /// **** recv_IF4 of rxdataF from RRU **** /// + /// **** recv_IF4 of rxsigF from RRU **** /// + // get frame/subframe information from IF4 interface + // timed loop (200 us) + + symbol_number = 0; + symbol_mask = 0; + symbol_mask_full = (1<<fp->symbols_per_tti)-1; + prach_rx = 0; + + do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); + recv_IF4(eNB, &frame_rx, &subframe_rx, &packet_type, &symbol_number); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); + + if (packet_type == IF4_PULFFT) { + symbol_mask = symbol_mask | (1<<symbol_number); + + } else if (packet_type == IF4_PRACH) { + // wake up thread for PRACH RX + prach_rx = 1; + } + + + + } while( (symbol_mask != symbol_mask_full) && (prach_rx == 0)); + + if (proc->first_rx == 0) { + if (subframe_rx < proc->subframe_rx+2){ + LOG_E(PHY,"RX overflow (proc->subframe_rx %d, subframe_rx %d)\n",proc->subframe_rx,subframe_rx); + } + } else { + proc->first_rx = 0; + } + } // node_timing == synch_to_externs, node_function = NGFI_IF4 + else { // should not get here + AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function); + } + +} /*! - * \brief The RX common thread of eNB. + * \brief The Fronthaul thread of RRU/RAU/RCC/eNB + * In the case of RRU/eNB, handles interface with external RF + * In the case of RAU/RCC, handles fronthaul interface with RRU/RAU * \param param is a \ref eNB_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* eNB_thread_rx_common( void* param ) { +static void* eNB_thread_FH( void* param ) { - static int eNB_thread_rx_status; + static int eNB_thread_FH_status; eNB_proc_t *proc = (eNB_proc_t*)param; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - + void *rxp[fp->nb_antennas_rx]; + unsigned int rxs; FILE *rx_time_file = NULL; char rx_time_name[101]; struct timespec wait; + int i; + int prach_rx; + + + + uint16_t packet_type; + uint32_t symbol_number=0; + uint32_t symbol_mask, symbol_mask_full; + + int subframe = proc->subframe_rx; + int frame = proc->frame_rx; + if (subframe==9) { + subframe=0; + frame++; + frame&=1023; + } else { + subframe++; + } wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -655,7 +756,7 @@ static void* eNB_thread_rx_common( void* param ) { rx_time_file = fopen(rx_time_name,"w"); } // set default return value - eNB_thread_rx_status = 0; + eNB_thread_FH_status = 0; MSC_START_USE(); @@ -678,7 +779,7 @@ static void* eNB_thread_rx_common( void* param ) { if (sched_setattr(0, &attr, flags) < 0 ) { perror("[SCHED] eNB RX sched_setattr failed\n"); - return &eNB_thread_rx_status; + return &eNB_thread_FH_status; } LOG_I( HW, "[SCHED] eNB RX deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() ); @@ -796,32 +897,205 @@ static void* eNB_thread_rx_common( void* param ) { // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 ); - start_meas( &softmodem_stats_rx_sf ); if (oai_exit) break; - if ((((fp->frame_type == TDD )&&(subframe_select(fp,proc->subframe_rx)==SF_UL)) || - (fp->frame_type == FDD))) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 ); - // this spawns the prach inside and updates the frame and subframe counters - phy_procedures_eNB_common_RX(eNB, 0); + + if ((eNB->node_timing == synch_to_other) && + ((eNB->node_function == NGFI_RRU_IF4) || + (eNB->node_function == NGFI_RRU_IF5) || + (eNB->node_function == eNodeB_3GPP))) { // This case is for synchronization to another thread + //wait for event + + // how long should we wait here, for MOBIPASS this could be long + // if (pthread_mutex_timedlock(&proc->mutex_FH,&wait) != 0) { + if (pthread_mutex_lock(&proc->mutex_FH) != 0) { + LOG_E( PHY, "[SCHED][eNB] error locking mutex for FH\n"); + exit_fun( "error locking mutex" ); + break; + } + + while (proc->instance_cnt_FH < 0) { + // most of the time the thread is waiting here + // proc->instance_cnt_prach is -1 + pthread_cond_wait( &proc->cond_FH,&proc->mutex_FH ); // this unlocks mutex_rxtx while waiting and then locks it again + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 ); + proc->instance_cnt_FH++; + + } + // Remaining cases are all for synchronization on FH interface + else if ((eNB->node_timing == synch_to_ext_device) && + ((eNB->node_function == NGFI_RRU_IF4) || + (eNB->node_function == NGFI_RRU_IF5) || + (eNB->node_function == eNodeB_3GPP))) { // acquisition from RF + + for (i=0; i<fp->nb_antennas_rx; i++) + rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); + + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &proc->timestamp_rx, + rxp, + fp->samples_per_tti, + fp->nb_antennas_rx); + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; + proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + + + if (proc->first_rx == 0) { + if (proc->subframe_rx != subframe){ + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); + exit_fun("Exiting"); + } + if (proc->frame_rx != frame) { + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); + exit_fun("Exiting"); + } + } else { + proc->first_rx = 0; + } + + // printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); + + if (rxs != fp->samples_per_tti) + exit_fun( "problem receiving samples" ); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); + + } // node_timing==synch_to_ext_device && node_function == RRU || eNodeB + else if ((eNB->node_timing == synch_to_ext_device) && + (eNB->node_function == eNodeB_3GPP_BBU)) { // acquisition from IF + /// **** recv_IF5 of rxdata from RRH **** /// + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); + recv_IF5(eNB, &proc->timestamp_rx, proc->subframe_rx, IF5_RRH_GW_UL); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); + + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; + proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + + if (proc->first_rx == 0) { + if (proc->subframe_rx != subframe){ + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); + //exit_fun("Exiting"); + } + if (proc->frame_rx != frame) { + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); + //exit_fun("Exiting"); + } + } else { + proc->first_rx = 0; + } + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); + } // eNodeB_3GPP_BBU && node_timing == synch_to_ext_device + + else if ((eNB->node_timing == synch_to_ext_device) && + (eNB->node_function == NGFI_RCC_IF4)) { + /// **** recv_IF4 of rxdataF from RRU **** /// + /// **** recv_IF4 of rxsigF from RRU **** /// + // get frame/subframe information from IF4 interface + // timed loop (200 us) + + symbol_number = 0; + symbol_mask = 0; + symbol_mask_full = (1<<fp->symbols_per_tti)-1; + prach_rx = 0; + + do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 ); + recv_IF4(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 ); + + if (packet_type == IF4_PULFFT) { + symbol_mask = symbol_mask | (1<<symbol_number); + + } else if (packet_type == IF4_PRACH) { + // wake up thread for PRACH RX + prach_rx = 1; + } + + + + } while( (symbol_mask != symbol_mask_full) && (prach_rx == 0)); + + if (proc->first_rx == 0) { + if (proc->subframe_rx != subframe){ + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); + //exit_fun("Exiting"); + } + if (proc->frame_rx != frame) { + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); + //exit_fun("Exiting"); + } + } else { + proc->first_rx = 0; + } + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx ); + + } // node_timing == synch_to_externs, node_function = NGFI_IF4 + else { // should not get here + AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function); + } + + // At this point, all information for subframe has been received on FH interface + // If this proc is to provide synchronization, do so + for (i=0;i<proc->num_slaves;i++) { + eNB_proc_t *slave_proc = proc->slave_proc[i]; + // wake up slave FH thread + // lock the FH mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id); + exit_fun( "error locking mutex_rxtx" ); + break; + } + int cnt_slave = ++slave_proc->instance_cnt_FH; + slave_proc->frame_rx = proc->frame_rx; + slave_proc->subframe_rx = proc->subframe_rx; + slave_proc->timestamp_rx = proc->timestamp_rx; + + pthread_mutex_unlock( &slave_proc->mutex_FH ); + + if (cnt_slave == 0) { + // the thread was presumably waiting where it should and can now be woken up + if (pthread_cond_signal(&slave_proc->cond_FH) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id); + exit_fun( "ERROR pthread_cond_signal" ); + break; + } + } else { + LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_rxtx %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave); + exit_fun( "TX thread busy" ); + break; + } + } + + // wake up RXn_TXnp4 thread for the subframe // choose even or odd thread for RXn-TXnp4 processing eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[proc->subframe_rx&1]; // wake up TX for subframe n+4 // lock the TX mutex and make sure the thread is ready if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx ); + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); exit_fun( "error locking mutex_rxtx" ); break; } int cnt_rxtx = ++proc_rxtx->instance_cnt_rxtx; + // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). @@ -865,12 +1139,20 @@ static void* eNB_thread_rx_common( void* param ) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); } - - printf( "Exiting eNB thread rx_common\n"); + if (eNB->node_timing == synch_to_ext_device) { + proc->instance_cnt_FH--; + + if (pthread_mutex_unlock(&proc->mutex_FH) != 0) { + LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for FH\n"); + exit_fun( "error unlocking mutex" ); + } + } + + printf( "Exiting FH thread \n"); - eNB_thread_rx_status = 0; - return &eNB_thread_rx_status; + eNB_thread_FH_status = 0; + return &eNB_thread_FH_status; } @@ -1070,9 +1352,9 @@ void init_eNB_proc(void) { pthread_attr_setschedparam (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx); pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO); - proc->sched_param_rx.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&proc->attr_rx, &proc->sched_param_rx); - pthread_attr_setschedpolicy (&proc->attr_rx, SCHED_FIFO); + proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; + pthread_attr_setschedparam (&proc->attr_FH, &proc->sched_param_FH); + pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO); proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY; pthread_attr_setschedparam (&proc->attr_prach, &proc->sched_param_prach); @@ -1083,6 +1365,7 @@ void init_eNB_proc(void) { proc_rxtx[0].instance_cnt_rxtx = -1; proc_rxtx[1].instance_cnt_rxtx = -1; proc->instance_cnt_prach = -1; + proc->instance_cnt_FH = -1; proc->CC_id = CC_id; proc->first_rx=4; @@ -1093,24 +1376,30 @@ void init_eNB_proc(void) { pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); pthread_cond_init( &proc->cond_prach, NULL); + pthread_cond_init( &proc->cond_FH, NULL); #ifndef DEADLINE_SCHEDULER pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] ); - pthread_create( &proc->pthread_rx, &proc->attr_rx, eNB_thread_rx_common, &eNB->proc ); + pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc ); pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc ); + if (eNB->node_timing == synch_to_other) + pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc ); #else pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] ); pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] ); - pthread_create( &proc->pthread_rx, NULL, eNB_thread_rx_common, &eNB->proc ); + pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc ); pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc ); + if (eNB->node_timing == synch_to_other) + pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc ); + #endif char name[16]; snprintf( name, sizeof(name), "RXTX0 %d", i ); pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); snprintf( name, sizeof(name), "RXTX1 %d", i ); pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RX %d", i ); - pthread_setname_np( proc->pthread_rx, name ); + snprintf( name, sizeof(name), "FH %d", i ); + pthread_setname_np( proc->pthread_FH, name ); } /* setup PHY proc TX sync mechanism */ @@ -1142,63 +1431,27 @@ void kill_eNB_proc(void) { proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race! proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race! proc->instance_cnt_prach = 0; + proc->instance_cnt_FH = 0; pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); pthread_cond_signal( &proc_rxtx[1].cond_rxtx ); pthread_cond_signal( &proc->cond_prach ); + pthread_cond_signal( &proc->cond_FH ); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - pthread_join( proc->pthread_rx, (void**)&status ); - + pthread_join( proc->pthread_FH, (void**)&status ); + pthread_mutex_destroy( &proc->mutex_FH ); + pthread_cond_destroy( &proc->cond_FH ); + + pthread_join( proc->pthread_prach, (void**)&status ); + pthread_mutex_destroy( &proc->mutex_prach ); + pthread_cond_destroy( &proc->cond_prach ); - int result,i; + int i; for (i=0;i<2;i++) { pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); - -#ifdef DEBUG_THREADS - - if (result != 0) { - printf( "Error joining thread.\n" ); - } else { - if (status) { - printf( "status %d\n", *status ); - } else { - printf( "The thread was killed. No status available.\n" ); - } - } -#else - UNUSED(result); -#endif - pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); } - -#ifdef DEBUG_THREADS - printf( "Killing RX CC_id %d thread\n", CC_id); -#endif - -#ifdef DEBUG_THREADS - printf( "Joining eNB RX CC_id %d thread ...\n", CC_id); -#endif - - result = pthread_join( proc->pthread_rx, (void**)&status ); - -#ifdef DEBUG_THREADS - if (result != 0) { - printf( "Error joining thread.\n" ); - } else { - if (status) { - printf( "status %d\n", *status ); - } else { - printf( "The thread was killed. No status available.\n" ); - } - } -#else - UNUSED(result); -#endif - - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); } } diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 5a970ca038f2eaba14d563f059070bcbf46be2a4..867d578ce918f335fcc5b1150e76f85651aad478 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1166,17 +1166,6 @@ void init_ocm(void) LOG_D(OCM,"Initializing channel (%s, %d) from eNB %d to UE %d\n", oai_emulation.environment_system_config.fading.small_scale.selected_option, map_str_to_int(small_scale_names,oai_emulation.environment_system_config.fading.small_scale.selected_option), eNB_id, UE_id); - /* if (oai_emulation.info.transmission_mode == 5) - eNB2UE[eNB_id][UE_id] = new_channel_desc_scm(PHY_vars_eNB_g[eNB_id]->frame_parms.nb_antennas_tx, - PHY_vars_UE_g[UE_id]->frame_parms.nb_antennas_rx, - (UE_id == 0)? Rice1_corr : Rice1_anticorr, - oai_emulation.environment_system_config.system_bandwidth_MB, - forgetting_factor, - 0, - 0); - - else - */ eNB2UE[eNB_id][UE_id][CC_id] = new_channel_desc_scm(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.nb_antennas_tx,