From 03f66cb85ee36598b3d987cf1751ae7c778fc158 Mon Sep 17 00:00:00 2001 From: "S. Sandeep Kumar" Date: Fri, 17 Jun 2016 04:14:41 +0530 Subject: [PATCH] handle prach rx for enb node functions --- openair1/PHY/LTE_TRANSPORT/if4_tools.c | 53 +++-- openair1/PHY/LTE_TRANSPORT/if4_tools.h | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 266 +++++++++++++----------- targets/RT/USER/lte-enb.c | 2 +- 4 files changed, 182 insertions(+), 141 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index a8a27b2c09..24b338f5a4 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -45,11 +45,11 @@ #include "PHY/TOOLS/ALAW/alaw_lut.h" // Get device information -void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - int32_t **txdataF = eNB->common_vars.txdataF[0]; +void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint16_t packet_type) { + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + int32_t **txdataF = eNB->common_vars.txdataF[0]; - uint16_t symbol_id, element_id; + uint16_t symbol_id, element_id; uint16_t db_fulllength = 12*fp->N_RB_DL; uint16_t db_halflength = db_fulllength>>1; int slotoffsetF = (proc->subframe_tx)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1; @@ -58,7 +58,7 @@ void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { int16_t *data_block = (int16_t*)malloc(db_fulllength*sizeof(int16_t)); // Caller: RCC - DL *** handle RRU case - UL and PRACH *** - if (eNB->node_function == NGFI_RCC_IF4) { + if (packet_type == IF4_PDLFFT) { IF4_dl_packet_t *dl_packet = (IF4_dl_packet_t*)malloc(sizeof_IF4_dl_packet_t); gen_IF4_dl_packet(dl_packet, proc); @@ -93,7 +93,7 @@ void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { slotoffsetF += fp->ofdm_symbol_size; blockoffsetF += fp->ofdm_symbol_size; } - }else { + } else if (packet_type == IF4_PULFFT) { IF4_ul_packet_t *ul_packet = (IF4_ul_packet_t*)malloc(sizeof_IF4_ul_packet_t); gen_IF4_ul_packet(ul_packet, proc); @@ -101,7 +101,7 @@ void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { for (symbol_id=0; symbol_idsymbols_per_tti; symbol_id++) { - // Do compression of the two parts and generate data blocks - rxdataF + // Do compression of the two parts and generate data blocks - rxdataF for (element_id=0; element_id>16) + 32768 ]<<8; @@ -118,19 +118,23 @@ void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { slotoffsetF += fp->ofdm_symbol_size; blockoffsetF += fp->ofdm_symbol_size; } - } - + } else if (packet_type == IF4_PRACH) { + + + } else { + AssertFatal(1==0, "send_IF4 - Unknown packet_type %x", packet_type); + } + + return; } void recv_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint16_t *packet_type, uint32_t *symbol_number) { - // Caller: RRU - DL *** handle RCC case - UL and PRACH *** - if (eNB->node_function == NGFI_RRU_IF4) { - - printf("\n Recv IF4 for frame %d, subframe %d and symbol %d\n", proc->frame_tx, proc->subframe_tx, symbol_id); - + *packet_type = 0; + int16_t *data_block=NULL; + + // Read packet(s) from the fronthaul // for(i=0; isymbols_per_tti; i++) { - // Read packet(s) from the fronthaul // if (dev->eth_dev.trx_read_func (&dev->eth_dev, // timestamp_rx, // rx_eNB, @@ -139,16 +143,27 @@ void recv_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint16_t *packet_type, u // ) < 0) { // perror("RRU : ETHERNET read"); // } +// printf("\n Recv IF4 for frame %d, subframe %d and symbol %d\n", proc->frame_tx, proc->subframe_tx, symbol_id); + + //*packet_type = ; + + if (*packet_type == IF4_PDLFFT) { // Apply reverse processing - decompression // txAlawtolinear( Datablock ) // Generate and return the OFDM symbols (txdataF) - //txDataF - //} - }else { + // txDataF - } + } else if (*packet_type == IF4_PULFFT) { + + } else if (*packet_type == IF4_PRACH) { + + } else { + AssertFatal(1==0, "recv_IF4 - Unknown packet_type %x", *packet_type); + } + + return; } void gen_IF4_dl_packet(IF4_dl_packet_t *dl_packet, eNB_rxtx_proc_t *proc) { diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.h b/openair1/PHY/LTE_TRANSPORT/if4_tools.h index d7a0461169..a6ca7eb5c0 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.h +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.h @@ -181,6 +181,6 @@ void gen_IF4_ul_packet(IF4_ul_packet_t*, eNB_rxtx_proc_t*); void gen_IF4_prach_packet(IF4_prach_packet_t*, eNB_rxtx_proc_t*); -void send_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*); +void send_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint16_t); void recv_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint16_t*, uint32_t*); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 087404d10a..ae6627939c 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -44,6 +44,8 @@ #include "SCHED/defs.h" #include "SCHED/extern.h" +#include "PHY/LTE_TRANSPORT/if4_tools.h" + #ifdef EMOS #include "SCHED/phy_procedures_emos.h" #endif @@ -2471,7 +2473,6 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p } - void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_flag) { int i,l; @@ -2481,158 +2482,183 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl eNB_proc_t *proc = &eNB->proc; int subframe = proc->subframe_rx; int frame = proc->frame_rx; - int symbol_number, symbol_mask, symbol_mask_full, prach_rx, packet_type; + + int prach_rx; + + uint16_t packet_type; + uint32_t symbol_number; + uint32_t symbol_mask, symbol_mask_full; if (subframe==9) { subframe=0; frame++; frame&=1023; + } else { + subframe++; } - 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 LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe); #endif if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot) - + + if ((eNB->node_function == NGFI_RRU_IF4) || + (eNB->node_function == eNodeB_3GPP)) { // acquisition from RF and front-end processing - if ((eNB->node_function == NGFI_RRU_IF4) || - (eNB->node_function == eNodeB_3GPP)) { // acquisition from RF and front-end processing - for (i=0; inb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; + for (i=0; inb_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) { - AssertFatal(proc->subframe_rx == subframe, "Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)",proc->subframe_rx,subframe); - AssertFatal(proc->frame_rx == frame, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)",proc->frame_rx,frame); - } - else - proc->first_rx = 0; + 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; - // printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); + if (proc->first_rx == 0) { + AssertFatal(proc->subframe_rx == subframe, "Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)",proc->subframe_rx,subframe); + AssertFatal(proc->frame_rx == frame, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)",proc->frame_rx,frame); + } 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, frame ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, subframe ); + //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, frame ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, subframe ); - if (rxs != fp->samples_per_tti) - exit_fun( "problem receiving samples" ); + 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 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - // 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); - remove_7_5_kHz(eNB,subframe<<1); - remove_7_5_kHz(eNB,1+(subframe<<1)); - for (l=0; lsymbols_per_tti/2; l++) { - slot_fep_ul(fp, - &eNB->common_vars, - l, - subframe<<1, - 0, - 0 - ); - slot_fep_ul(fp, - &eNB->common_vars, - l, - 1+(subframe<<1), - 0, - 0 - ); - } + // 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); + remove_7_5_kHz(eNB,subframe<<1); + remove_7_5_kHz(eNB,1+(subframe<<1)); + for (l=0; lsymbols_per_tti/2; l++) { + slot_fep_ul(fp, + &eNB->common_vars, + l, + subframe<<1, + 0, + 0 + ); + slot_fep_ul(fp, + &eNB->common_vars, + l, + 1+(subframe<<1), + 0, + 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 **** /// - /// Handle routing to prach thread for sending prach - } + if (eNB->node_function == NGFI_RRU_IF4 && is_prach_subframe(fp, frame, subframe)<=0) { - } - else if (eNB->node_function == NGFI_RCC_IF4) { - /// **** recv_IF4 of rxdataF from RRU **** /// - /// **** recv_IF4 of prachF from RRU **** /// - // get frame/subframe information from IF4 interface - // timed loop (200 us) - - //symbol_mask = 0; - //symbol_mask_full = (1<symbols_per_tti)-1; - //if (is_prach_subframe(fp,frame,subframe)>0) - //prach_rx = 0; - //else - //prach_rx = 1; - - //do { - //recv_IF4(eNB, proc, &packet_type, &symbol_number); - //if (is_prach_subframe(fp,frame,subframe)>0 && packet_type == PRACH) { - //// wake up prach_rx - //prach_rx = 1; - //} - //if (packet_type == IF4_PULFFT) - //symbol_mask = symbol_mask | (1<node_function %d",eNB->node_function); - } - - - // check if we have to detect PRACH first - if (is_prach_subframe(fp,frame,subframe)>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 = frame; - proc->subframe_prach = subframe; - - 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; + /// **** send_IF4 of rxdataF to RCC (no prach now) **** /// } + /// **** send_IF4 of prach to RCC **** /// done in prach thread (below) + // check if we have to detect PRACH first + if (is_prach_subframe(fp,frame,subframe)>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 = frame; + proc->subframe_prach = subframe; + 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; + } + } + + } else if (eNB->node_function == NGFI_RCC_IF4) { + /// **** recv_IF4 of rxdataF from RRU **** /// + /// **** recv_IF4 of prachF from RRU **** /// + // get frame/subframe information from IF4 interface + // timed loop (200 us) + + symbol_mask = 0; + symbol_mask_full = (1<symbols_per_tti)-1; + prach_rx = 0; + + do { + //recv_IF4(eNB, proc, &packet_type, &symbol_number); + + if (packet_type == IF4_PULFFT) { + symbol_mask = symbol_mask | (1<0 && packet_type == 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 = frame; + proc->subframe_prach = subframe; + + 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)); + + // 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 + } else { // grab transport channel information from network interface } + } + void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const uint8_t abstraction_flag,const relaying_type_t r_type) { //RX processing for ue-specific resources (i diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 918c1f82ee..3a836d6bdb 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -483,7 +483,7 @@ static void* eNB_thread_rxtx( void* param ) { } else { /// **** recv_IF4 of txdataF from RCC **** /// - //recv_IF4( eNB, proc, packet_type, symbol_number); + //recv_IF4(eNB, proc, packet_type, symbol_number); } }