Skip to content
Snippets Groups Projects

Integration 2021 wk19

Merged Remi Hardy requested to merge integration_2021_wk19 into develop
9 files
+ 16
5
Compare changes
  • Side-by-side
  • Inline
Files
9
+ 282
262
@@ -51,7 +51,6 @@
#include "assertions.h"
#include "msc.h"
#include "PHY/defs_common.h"
#include "PHY/phy_extern.h"
#include "PHY/types.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
@@ -59,23 +58,11 @@
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY_INTERFACE/phy_interface.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h"
#include "SCHED/sched_eNB.h"
#include "UTIL/OPT/opt.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
#include "SCHED/sched_common.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "enb_config.h"
#include "targets/ARCH/COMMON/common_lib.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "targets/RT/USER/lte-softmodem.h"
//#include "PHY/TOOLS/time_meas.h"
/* these variables have to be defined before including ENB_APP/enb_paramdef.h */
@@ -86,29 +73,25 @@ static int DEFBFW[] = {0x00007fff};
#include "ENB_APP/enb_paramdef.h"
#include "common/config/config_userapi.h"
#ifndef OPENAIR2
#include "UTIL/OTG/otg_extern.h"
#endif
#include "s1ap_eNB.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#include "T.h"
#include "pdcp.h"
#include "executables/softmodem-common.h"
#define MBMS_EXPERIMENTAL
extern volatile int oai_exit;
extern int emulate_rf;
extern int numerology;
extern clock_source_t clock_source;
#include "executables/thread-common.h"
//extern PARALLEL_CONF_t get_thread_parallel_conf(void);
//extern WORKER_CONF_t get_thread_worker_conf(void);
extern void phy_init_RU(RU_t *);
void stop_RU(int nb_ru);
void prach_procedures(PHY_VARS_eNB *eNB,int br_flag);
void stop_RU(RU_t **rup,int nb_ru);
void do_ru_synch(RU_t *ru);
void configure_ru(int idx,
@@ -124,13 +107,24 @@ void wait_eNBs(void);
const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"};
extern const char NB_functions[7][20];
extern const char NB_timing[2][20];
extern uint16_t sf_ahead;
extern const char ru_if_types[MAX_RU_IF_TYPES][20];
#if defined(PRE_SCD_THREAD)
#include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/LAYER2/MAC/mac_extern.h"
extern uint8_t dlsch_ue_select_tbl_in_use;
void init_ru_vnf(void);
extern RAN_CONTEXT_t RC;
#endif
RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond);
/*************************************************************/
/* Functions to attach and configure RRU */
@@ -141,7 +135,7 @@ extern uint16_t sf_ahead;
// southbound IF5 fronthaul for 16-bit OAI format
static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t timestamp) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
ru->south_out_cnt++;
@@ -149,14 +143,12 @@ static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, uint64_t t
}
// southbound IF4p5 fronthaul
static inline void fh_if4p5_south_out(RU_t *ru,
int frame,
int subframe,
uint64_t timestamp) {
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"ENTERED fh_if4p5_south_out Sending IF4p5 for frame %d subframe %d ru %d\n",ru->proc.frame_tx,ru->proc.tti_tx,ru->idx);
@@ -166,7 +158,7 @@ static inline void fh_if4p5_south_out(RU_t *ru,
LOG_D(PHY,"south_out_cnt %d\n",ru->south_out_cnt);
}
/*if (ru == RC.ru[0] || ru == RC.ru[1]) {
/*if (ru->idx == 0 || ru->idx == ru) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU+ru->idx, ru->proc.frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU+ru->idx, ru->proc.subframe_tx );
}*/
@@ -227,31 +219,30 @@ void fh_if4p5_south_in(RU_t *ru,
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, ru %d, mask %x\n",ru->idx,*frame,*subframe,ru->idx,proc->symbol_mask[*subframe]);
AssertFatal(proc->symbol_mask[*subframe]==0 || proc->symbol_mask[*subframe]==symbol_mask_full,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]);
//AssertFatal(proc->symbol_mask[*subframe]==0 || proc->symbol_mask[*subframe]>=symbol_mask_full,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]); // >= because PULTICK for S-subframe could have been received during normal subframe
if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
if (proc->symbol_mask[*subframe]<symbol_mask_full) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
do {
recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf);
LOG_D(PHY,"fh_if4p5_south_in (%s/%d): RU %d, frame %d, subframe %d, f %d, sf %d, symbol %d\n",packet_type == IF4p5_PULFFT ? "PULFFT" : "PULTICK",packet_type,ru->idx,*frame,*subframe,f,sf,symbol_number);
if (oai_exit == 1 || ru->cmd== STOP_RU) break;
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number);
else if (packet_type == IF4p5_PULTICK) {
proc->symbol_mask[sf] = symbol_mask_full;
proc->symbol_mask[sf] = 0xffff;
pultick_received++;
/*
if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d (RU %d) \n",f,*frame, ru->idx);
else if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx);
else break; */
if (f==*frame || sf==*subframe) break;
//if (f==*frame || sf==*subframe) break;
} else if (packet_type == IF4p5_PRACH) {
// nothing in RU for RAU
}
LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]);
} while(proc->symbol_mask[sf] != symbol_mask_full);
LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol %d, symbol mask %x\n",ru->idx,*subframe,sf,symbol_number,proc->symbol_mask[sf]);
} while(proc->symbol_mask[*subframe] < symbol_mask_full);
} else {
f = *frame;
sf = *subframe;
@@ -263,7 +254,7 @@ void fh_if4p5_south_in(RU_t *ru,
proc->timestamp_rx = ((proc->frame_rx * 10) + proc->tti_rx ) * fp->samples_per_tti ;
// proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
if (get_nprocs()<=4) {
if (get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
proc->tti_tx = (sf+sf_ahead)%10;
proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f;
}
@@ -291,7 +282,7 @@ void fh_if4p5_south_in(RU_t *ru,
*subframe = proc->tti_rx;
}
/*if (ru == RC.ru[0] || ru == RC.ru[1]) {
/*if (ru->idx == 0 || ru->idx == 1) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU+ru->idx, f );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU+ru->idx, sf );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, f );
@@ -399,7 +390,7 @@ void fh_if4p5_north_in(RU_t *ru,
ru->north_in_cnt++;
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
if (ru->idx == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, *frame );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, *subframe );
}
@@ -491,7 +482,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,
LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,tti_tx);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
if (ru->idx == 0) {
/*VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );*/
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_NORTH_ASYNCH_IN, frame_tx);
@@ -557,8 +548,8 @@ volatile late_control_e late_control=STATE_BURST_NORMAL;
static void *emulatedRF_thread(void *param) {
RU_proc_t *proc = (RU_proc_t *) param;
int microsec = 500; // length of time to sleep, in miliseconds
int numerology = 0 ;
struct timespec req = {0};
int numerology = get_softmodem_params()->numerology;
req.tv_sec = 0;
req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2;
cpu_set_t cpuset;
@@ -609,7 +600,7 @@ void rx_rf(RU_t *ru,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx;
if(get_softmodem_params()->emulate_rf) {
if(ru->emulate_rf) {
wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
rxs = fp->samples_per_tti;
@@ -662,7 +653,7 @@ void rx_rf(RU_t *ru,
proc->tti_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
// synchronize first reception to frame 0 subframe 0
if (ru->fh_north_asynch_in == NULL) {
if (get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->fh_north_asynch_in == NULL) {
#ifdef PHY_TX_THREAD
proc->timestamp_phy_tx = proc->timestamp_rx+((sf_ahead-1)*fp->samples_per_tti);
proc->subframe_phy_tx = (proc->tti_rx+(sf_ahead-1))%10;
@@ -690,16 +681,12 @@ void rx_rf(RU_t *ru,
proc->frame_rx,
proc->tti_rx);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx );
}
if (ru->fh_north_asynch_in == NULL) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, proc->tti_tx );
}
}
// dump VCD output for first RU in list
if (ru->idx == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx );
}
if (proc->first_rx == 0) {
@@ -790,6 +777,7 @@ void tx_rf(RU_t *ru,
/* add fail safe for late command */
if(late_control!=STATE_BURST_NORMAL) { //stop burst
LOG_E(PHY,"%d.%d late_control : %d\n",frame,subframe,late_control);
switch (late_control) {
case STATE_BURST_TERMINATE:
flags=10; // end of burst and no time spec
@@ -818,12 +806,13 @@ void tx_rf(RU_t *ru,
break;
}
}
/* add fail safe for late command end */
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags);
/* add fail safe for late command end */
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
@@ -841,7 +830,7 @@ void tx_rf(RU_t *ru,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
// AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
if( (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */
if( usrp_tx_thread == 0 && (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */
late_control=STATE_BURST_TERMINATE;
LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
}
@@ -954,7 +943,7 @@ void *ru_thread_prach( void *param ) {
thread_top_init("ru_thread_prach",1,500000,1000000,20000000);
//wait_sync("ru_thread_prach");
while (RC.ru_mask>0 && ru->function!=eNodeB_3GPP) {
while (*ru->ru_mask>0 && ru->function!=eNodeB_3GPP) {
usleep(1e6);
LOG_D(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__);
}
@@ -1167,7 +1156,7 @@ void wakeup_L1s(RU_t *ru) {
if (ru == eNB->RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) {
//AssertFatal((proc->RU_mask&(1<<i)) == 0, "eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,eNB->num_RU,proc->RU_mask);
proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
} else if (/*eNB->RU_list[i]->state == RU_SYNC ||*/(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0) ) {
} else if (eNB->RU_list[i]->state == RU_SYNC ||(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] /*&& ru->is_slave==0*/) ) {
proc->RU_mask[ru->proc.tti_rx] |= (1<<i);
}
@@ -1307,7 +1296,7 @@ void fill_rf_config(RU_t *ru,
int numerology = get_softmodem_params()->numerology;
if(fp->N_RB_DL == 100) {
if(numerology == 0) {
if(ru->numerology == 0) {
if (fp->threequarter_fs) {
cfg->sample_rate=23.04e6;
cfg->samples_per_frame = 230400;
@@ -1319,12 +1308,12 @@ void fill_rf_config(RU_t *ru,
cfg->tx_bw = 10e6;
cfg->rx_bw = 10e6;
}
} else if(numerology == 1) {
} else if(ru->numerology == 1) {
cfg->sample_rate=61.44e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 20e6;
cfg->rx_bw = 20e6;
} else if(numerology == 2) {
} else if(ru->numerology == 2) {
cfg->sample_rate=122.88e6;
cfg->samples_per_frame = 307200;
cfg->tx_bw = 40e6;
@@ -1523,36 +1512,43 @@ static void *ru_thread_tx( void *param ) {
LOG_D(PHY,"ru_thread_tx (ru %d): Waiting for TX processing\n",ru->idx);
// wait until eNBs are finished subframe RX n and TX n+4
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
LOG_D(PHY,"ru_thread_tx: TX in %d.%d\n",ru->proc.frame_tx,ru->proc.tti_tx);
ret = pthread_mutex_lock(&proc->mutex_eNBs);
AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
int frame_tx=proc->frame_tx;
int tti_tx =proc->tti_tx;
uint64_t timestamp_tx = proc->timestamp_tx;
ret = pthread_mutex_unlock(&proc->mutex_eNBs);
AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
if (oai_exit) break;
// do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
if(!(get_softmodem_params()->emulate_rf)) { //if(!emulate_rf){
if(!(ru->emulate_rf)) { //if(!emulate_rf){
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx);
if (ru->fh_north_out) ru->fh_north_out(ru);
} else {
for (int i=0; i<ru->nb_tx; i++) {
if(proc->frame_tx == 2) {
sprintf(filename,"txdataF%d_frame%d_sf%d.m",i,proc->frame_tx,proc->tti_tx);
if(frame_tx == 2) {
sprintf(filename,"txdataF%d_frame%d_sf%d.m",i,frame_tx,tti_tx);
LOG_M(filename,"txdataF_frame",ru->common.txdataF_BF[i],fp->symbols_per_tti*fp->ofdm_symbol_size, 1, 1);
}
if(proc->frame_tx == 2 && proc->tti_tx==0) {
sprintf(filename,"txdata%d_frame%d.m",i,proc->frame_tx);
if(frame_tx == 2 && tti_tx==0) {
sprintf(filename,"txdata%d_frame%d.m",i,frame_tx);
LOG_M(filename,"txdata_frame",ru->common.txdata[i],fp->samples_per_tti*10, 1, 1);
}
}
}
LOG_D(PHY,"ru_thread_tx: releasing RU TX in %d.%d\n", proc->frame_tx, proc->tti_tx);
LOG_D(PHY,"ru_thread_tx: releasing RU TX in %d.%d\n", frame_tx, tti_tx);
release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
for(int i = 0; i<ru->num_eNB; i++) {
@@ -1568,7 +1564,7 @@ static void *ru_thread_tx( void *param ) {
eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx);
eNB_proc->RU_mask_tx |= (1<<j);
} else if (/*eNB->RU_list[j]->state==RU_SYNC ||*/ (eNB->RU_list[j]->is_slave==1 && eNB->RU_list[j]->wait_cnt>0 && ru!=eNB->RU_list[j] && ru->is_slave==0)) {
} else if (eNB->RU_list[j]->state==RU_SYNC ||(eNB->RU_list[j]->is_slave==1 && eNB->RU_list[j]->wait_cnt>0 && ru!=eNB->RU_list[j])) {
eNB_proc->RU_mask_tx |= (1<<j);
}
@@ -1584,7 +1580,7 @@ static void *ru_thread_tx( void *param ) {
AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock( &L1_proc->mutex_RUs))==0,"mutex_lock returns %d\n",ret);
L1_proc->instance_cnt_RUs = 0;
LOG_D(PHY,"ru_thread_tx: Signaling RU TX done in %d.%d\n", proc->frame_tx, proc->tti_tx);
LOG_D(PHY,"ru_thread_tx: Signaling RU TX done in %d.%d\n", frame_tx, tti_tx);
// the thread can now be woken up
LOG_D(PHY,"ru_thread_tx: clearing mask and Waking up L1 thread\n");
@@ -1637,10 +1633,10 @@ static void *ru_thread( void *param ) {
}
LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
RC.ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(&RC.ru_cond);
AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(ru->ru_mutex))==0,"mutex_lock returns %d\n",ret);
*ru->ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(ru->ru_cond);
AssertFatal((ret=pthread_mutex_unlock(ru->ru_mutex))==0,"mutex_unlock returns %d\n",ret);
ru->state = RU_RUN;
} else if (ru->has_ctrl_prt == 0) {
// There is no control port: start everything here
@@ -1660,10 +1656,10 @@ static void *ru_thread( void *param ) {
exit(-1);
}
AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
RC.ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(&RC.ru_cond);
AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(ru->ru_mutex))==0,"mutex_lock returns %d\n",ret);
*ru->ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(ru->ru_cond);
AssertFatal((ret=pthread_mutex_unlock(ru->ru_mutex))==0,"mutex_unlock returns %d\n",ret);
ru->state = RU_RUN;
}
@@ -1672,6 +1668,17 @@ static void *ru_thread( void *param ) {
pthread_cond_signal(&proc->cond_FH1);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_FH1))==0,"mutex_unlock returns %d\n",ret);
if(usrp_tx_thread == 1){
if (ru->start_write_thread){
if(ru->start_write_thread(ru) != 0){
LOG_E(HW,"Could not start tx write thread\n");
}
else{
LOG_I(PHY,"tx write thread ready\n");
}
}
}
while (!oai_exit) {
if (ru->if_south != LOCAL_RF && ru->is_slave==1) {
ru->wait_cnt = 100;
@@ -1682,10 +1689,12 @@ static void *ru_thread( void *param ) {
// wait to be woken up
if (ru->function!=eNodeB_3GPP && ru->has_ctrl_prt == 1) {
LOG_D(PHY,"RU %d: Waiting for control thread to say go\n",ru->idx);
if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break;
} else wait_sync("ru_thread");
} else wait_sync("ru_thread");
LOG_D(PHY,"RU %d: Got start from control thread\n",ru->idx);
if(!(get_softmodem_params()->emulate_rf)) {
if(!(ru->emulate_rf)) {
if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]);
else if (ru->is_slave == 1) AssertFatal(ru->state == RU_SYNC || ru->state == RU_RUN ||
ru->state == RU_CHECK_SYNC,"ru %d state = %s != RU_SYNC or RU_RUN or RU_CHECK_SYNC\n",ru->idx,ru_states[ru->state]);
@@ -1711,7 +1720,7 @@ static void *ru_thread( void *param ) {
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
LOG_D(PHY,"Starting steady-state operation\n");
if (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) LOG_I(PHY,"RU %d Starting steady-state operation\n",ru->idx);
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (ru->state == RU_RUN || ru->state == RU_CHECK_SYNC) {
@@ -1772,14 +1781,14 @@ static void *ru_thread( void *param ) {
ru->wait_cnt--;
LOG_D(PHY,"RU thread %d, frame %d, subframe %d, wait_cnt %d \n",ru->idx, frame, subframe, ru->wait_cnt);
if (ru->if_south!=LOCAL_RF && ru->wait_cnt <=20 && subframe == 5 && frame != RC.ru[0]->proc.frame_rx && resynch_done == 0) {
if (ru->if_south!=LOCAL_RF && ru->wait_cnt <=20 && subframe == 5 && frame != ru->ru0->proc.frame_rx && resynch_done == 0) {
// Send RRU_frame adjust
RRU_CONFIG_msg_t rru_config_msg;
rru_config_msg.type = RRU_frame_resynch;
rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len
((uint16_t *)&rru_config_msg.msg[0])[0] = RC.ru[0]->proc.frame_rx;
((uint16_t *)&rru_config_msg.msg[0])[0] = ru->ru0->proc.frame_rx;
ru->cmd=WAIT_RESYNCH;
LOG_I(PHY,"Sending Frame Resynch %d to RRU %d\n", RC.ru[0]->proc.frame_rx,ru->idx);
LOG_I(PHY,"Sending Frame Resynch %d to RRU %d\n", ru->ru0->proc.frame_rx,ru->idx);
AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU\n");
resynch_done=1;
}
@@ -1837,9 +1846,9 @@ static void *ru_thread( void *param ) {
#ifdef MBMS_EXPERIMENTAL
//Workaround ... this must be properly handled
if(ru->if_south==LOCAL_RF && ru->function==eNodeB_3GPP && RC.eNB[0][0]!=NULL){
if(ru->frame_parms->num_MBSFN_config!=RC.eNB[0][0]->frame_parms.num_MBSFN_config){
ru->frame_parms = &RC.eNB[0][0]->frame_parms;//->frame_parms;
if(ru->if_south==LOCAL_RF && ru->function==eNodeB_3GPP && ru->eNB_list[0]!=NULL){
if(ru->frame_parms->num_MBSFN_config!=ru->eNB_list[0]->frame_parms.num_MBSFN_config){
ru->frame_parms = &ru->eNB_list[0]->frame_parms;//->frame_parms;
LOG_W(PHY,"RU MBSFN SF PARAMS Updated\n");
}
}
@@ -1854,7 +1863,7 @@ static void *ru_thread( void *param ) {
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru, proc->frame_tx, proc->tti_tx);
if(!(get_softmodem_params()->emulate_rf)) { //if(!emulate_rf){
if(!(ru->emulate_rf)) { //if(!emulate_rf){
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru, proc->frame_tx, proc->tti_tx, proc->timestamp_tx);
@@ -1888,12 +1897,12 @@ static void *ru_thread( void *param ) {
#endif
} // else wait_cnt == 0
} // ru->state = RU_RUN
} // ru->state = RU_RUN || RU_CHECK_SYNC
} // while !oai_exit
LOG_I(PHY, "Exiting ru_thread \n");
if (!(get_softmodem_params()->emulate_rf)) {
if (!(ru->emulate_rf)) {
if (ru->stop_rf != NULL) {
if (ru->stop_rf(ru) != 0)
LOG_E(HW,"Could not stop the RF device\n");
@@ -1908,7 +1917,7 @@ static void *ru_thread( void *param ) {
// This thread run the initial synchronization like a UE
void *ru_thread_synch(void *arg) {
RU_t *ru = (RU_t *)arg;
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
LTE_DL_FRAME_PARMS *fp;
int64_t peak_val, avg;
static int ru_thread_synch_status = 0;
int cnt=0;
@@ -1917,6 +1926,8 @@ void *ru_thread_synch(void *arg) {
// initialize variables for PSS detection
ru_sync_time_init(ru); //lte_sync_time_init(ru->frame_parms);
fp = ru->frame_parms;
int last_rxoff=0;
while (!oai_exit) {
// wait to be woken up
if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break;
@@ -1930,17 +1941,18 @@ void *ru_thread_synch(void *arg) {
&avg);
LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg));
cnt++;
//if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
if (ru->rx_offset >= 0 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
int abs_diff= ru->rx_offset - last_rxoff;
if (abs_diff<0) abs_diff=-abs_diff;
if (ru->rx_offset >= 0 && abs_diff<6 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset);
ru->in_synch = 1;
/*
/*
LOG_M("ru_sync_rx.m","rurx",&ru->common.rxdata[0][0],LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,1);
LOG_M("ru_sync_corr.m","sync_corr",ru->dmrs_corr,LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti,1,6);
LOG_M("ru_dmrs.m","rudmrs",&ru->dmrssync[0],fp->ofdm_symbol_size,1,1);
*/
//exit(-1);
exit(-1);
*/
} // sync_pos > 0
else { //AssertFatal(cnt<1000,"Cannot find synch reference\n");
if (cnt>200) {
@@ -1950,6 +1962,7 @@ void *ru_thread_synch(void *arg) {
exit(-1);
}
}
last_rxoff=ru->rx_offset;
} // ru->in_synch==0
if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break;
@@ -2113,7 +2126,7 @@ static void *rf_tx( void *param ) {
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
if(!emulate_rf) {
if(!ru->emulate_rf) {
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
@@ -2185,6 +2198,9 @@ void reset_proc(RU_t *ru) {
for (i=0; i<10; i++) proc->symbol_mask[i]=0;
}
int start_write_thread(RU_t *ru) {
return(ru->rfdevice.trx_write_init(&ru->rfdevice));
}
void init_RU_proc(RU_t *ru) {
int i=0;
@@ -2282,7 +2298,7 @@ void init_RU_proc(RU_t *ru) {
pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void *)ru );
#endif
if (get_softmodem_params()->emulate_rf)
if (ru->emulate_rf)
pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void *)proc );
if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
@@ -2317,10 +2333,10 @@ void init_RU_proc(RU_t *ru) {
if (ru->function == eNodeB_3GPP) {
usleep(10000);
LOG_I(PHY, "Signaling main thread that RU %d (is_slave %d,send_dmrs %d) is ready in state %s\n",ru->idx,ru->is_slave,ru->generate_dmrs_sync,ru_states[ru->state]);
AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret);
RC.ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(&RC.ru_cond);
AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_lock(ru->ru_mutex))==0,"mutex_lock returns %d\n",ret);
*ru->ru_mask &= ~(1<<ru->idx);
pthread_cond_signal(ru->ru_cond);
AssertFatal((ret=pthread_mutex_unlock(ru->ru_mutex))==0,"mutex_unlock returns %d\n",ret);
}
*/
}
@@ -2448,22 +2464,22 @@ void kill_RU_proc(RU_t *ru) {
}
void init_precoding_weights(PHY_VARS_eNB *eNB) {
int layer,ru_id,aa,re,ue,tb;
void init_precoding_weights(RU_t **rup,int nb_RU,PHY_VARS_eNB *eNB) {
int layer,ru_id,aa,re,tb;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
RU_t *ru;
LTE_eNB_DLSCH_t *dlsch;
// init precoding weigths
for (ue=0; ue<NUMBER_OF_UE_MAX; ue++) {
for (int dlsch_id=0; dlsch_id<NUMBER_OF_DLSCH_MAX; dlsch_id++) {
for (tb=0; tb<2; tb++) {
dlsch = eNB->dlsch[ue][tb];
dlsch = eNB->dlsch[dlsch_id][tb];
for (layer=0; layer<4; layer++) {
int nb_tx=0;
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
ru = RC.ru[ru_id];
for (ru_id=0; ru_id<nb_RU; ru_id++) {
ru = rup[ru_id];
nb_tx+=ru->nb_tx;
}
@@ -2547,6 +2563,7 @@ void set_function_spec_param(RU_t *ru) {
ru->fh_north_out = NULL; // no outgoing fronthaul to north
ru->start_if = NULL; // no if interface
ru->rfdevice.host_type = RAU_HOST;
ru->start_write_thread = start_write_thread;
}
ru->fh_south_in = rx_rf; // local synchronous RF RX
@@ -2641,60 +2658,61 @@ void set_function_spec_param(RU_t *ru) {
}
//extern void RCconfig_RU(void);
void init_RU0(RU_t *ru,int ru_id,char *rf_config_file, int send_dmrssync) {
ru->rf_config_file = rf_config_file;
ru->idx = ru_id;
ru->ts_offset = 0;
if (ru->is_slave == 1) {
ru->in_synch = 0;
ru->generate_dmrs_sync = 0;
} else {
ru->in_synch = 1;
ru->generate_dmrs_sync = send_dmrssync;
}
ru->cmd = EMPTY;
ru->south_out_cnt = 0;
// use eNB_list[0] as a reference for RU frame parameters
// NOTE: multiple CC_id are not handled here yet!
//ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
ru->generate_dmrs_sync = 1;
else
ru->generate_dmrs_sync = 0;
ru->wakeup_L1_sleeptime = 2000;
ru->wakeup_L1_sleep_cnt_max = 3;
}
void init_RU(char *rf_config_file, int send_dmrssync) {
// This part if on eNB side
void init_RU(RU_t **rup,int nb_RU,PHY_VARS_eNB ***eNBp,int nb_L1,int *nb_CC,char *rf_config_file, int send_dmrssync) {
int ru_id, i, CC_id;
RU_t *ru;
PHY_VARS_eNB *eNB0 = (PHY_VARS_eNB *)NULL;
LTE_DL_FRAME_PARMS *fp = (LTE_DL_FRAME_PARMS *)NULL;
// create status mask
RC.ru_mask= (1 << RC.nb_RU) - 1;
pthread_mutex_init(&RC.ru_mutex,NULL);
pthread_cond_init(&RC.ru_cond,NULL);
if (RC.nb_CC != 0)
for (i=0; i<RC.nb_L1_inst; i++)
for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++) RC.eNB[i][CC_id]->num_RU=0;
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
LOG_D(PHY,"Process RC.ru[%d]\n",ru_id);
ru = RC.ru[ru_id];
ru->rf_config_file = rf_config_file;
ru->idx = ru_id;
ru->ts_offset = 0;
if (ru->is_slave == 1) {
ru->in_synch = 0;
ru->generate_dmrs_sync = 0;
} else {
ru->in_synch = 1;
ru->generate_dmrs_sync = send_dmrssync;
}
ru->cmd = EMPTY;
ru->south_out_cnt = 0;
// use eNB_list[0] as a reference for RU frame parameters
// NOTE: multiple CC_id are not handled here yet!
//ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
ru->generate_dmrs_sync = 1;
else
ru->generate_dmrs_sync = 0;
if (nb_CC != NULL)
for (i=0; i<nb_L1; i++)
for (CC_id=0; CC_id<nb_CC[i]; CC_id++) eNBp[i][CC_id]->num_RU=0;
ru->wakeup_L1_sleeptime = 2000;
ru->wakeup_L1_sleep_cnt_max = 3;
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",nb_RU);
for (ru_id=0; ru_id<nb_RU; ru_id++) {
LOG_D(PHY,"Process ru[%d]\n",ru_id);
ru = rup[ru_id];
init_RU0(ru,ru_id,rf_config_file,send_dmrssync);
ru->ru0 = rup[0];
if (ru->num_eNB > 0) {
LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file);
LOG_D(PHY, "%s() ru[%d].num_eNB:%d ru->eNB_list[0]:%p eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], eNBp[0][0], ru->rf_config_file);
if (ru->eNB_list[0] == 0) {
LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
ru->eNB_list[0] = RC.eNB[0][0];
LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
ru->eNB_list[0] = eNBp[0][0];
ru->num_eNB=1;
//
// DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU
@@ -2703,7 +2721,7 @@ void init_RU(char *rf_config_file, int send_dmrssync) {
LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
}
}
eNB0 = ru->eNB_list[0];
fp = ru->frame_parms;
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
@@ -2777,10 +2795,10 @@ void stop_ru(RU_t *ru) {
}
void stop_RU(int nb_ru) {
void stop_RU(RU_t **rup,int nb_ru) {
for (int inst = 0; inst < nb_ru; inst++) {
LOG_I(PHY, "Stopping RU %d processing threads\n", inst);
kill_RU_proc(RC.ru[inst]);
kill_RU_proc(rup[inst]);
}
}
@@ -2801,7 +2819,7 @@ void init_ru_vnf(void) {
pthread_cond_init(&RC.ru_cond,NULL);
// read in configuration file)
LOG_I(PHY,"configuring RU from file\n");
RCconfig_RU();
RC.ru = RCconfig_RU(RC.nb_RU,RC.nb_L1_inst,RC.eNB,&RC.ru_mask,&RC.ru_mutex,&RC.ru_cond);
LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs());
if (RC.nb_CC != 0)
@@ -2877,183 +2895,185 @@ void init_ru_vnf(void) {
/* --------------------------------------------------------*/
/* from here function to use configuration module */
void RCconfig_RU(void) {
RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond) {
int i = 0;
paramdef_t RUParams[] = RUPARAMS_DESC;
paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL);
RU_t **ru=NULL;
if ( RUParamList.numelt > 0) {
RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *));
for (int j = 0; j < RC.nb_RU; j++) {
RC.ru[j] = (RU_t *)malloc(sizeof(RU_t));
memset((void *)RC.ru[j],0,sizeof(RU_t));
RC.ru[j]->idx = j;
LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
RC.ru[j]->if_timing = synch_to_ext_device;
if (RC.nb_L1_inst >0)
RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
ru = (RU_t **)malloc(nb_RU*sizeof(RU_t *));
for (int j = 0; j < nb_RU; j++) {
ru[j] = (RU_t *)malloc(sizeof(RU_t));
memset((void *)ru[j],0,sizeof(RU_t));
ru[j]->idx = j;
LOG_I(PHY,"Creating ru[%d]:%p\n", j, ru[j]);
ru[j]->if_timing = synch_to_ext_device;
ru[j]->ru_mask = ru_mask;
ru[j]->ru_mutex = ru_mutex;
ru[j]->ru_cond = ru_cond;
if (nb_L1_inst >0)
ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
else
RC.ru[j]->num_eNB = 0;
ru[j]->num_eNB = 0;
for (i=0; i<RC.ru[j]->num_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
for (i=0; i<ru[j]->num_eNB; i++) ru[j]->eNB_list[i] = eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
RC.ru[j]->has_ctrl_prt = 0;
ru[j]->has_ctrl_prt = 0;
if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
}
if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) {
if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) {
RC.ru[j]->openair0_cfg.clock_source = internal;
ru[j]->openair0_cfg.clock_source = internal;
LOG_D(PHY, "RU clock source set as internal\n");
} else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) {
RC.ru[j]->openair0_cfg.clock_source = external;
ru[j]->openair0_cfg.clock_source = external;
LOG_D(PHY, "RU clock source set as external\n");
} else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) {
RC.ru[j]->openair0_cfg.clock_source = gpsdo;
ru[j]->openair0_cfg.clock_source = gpsdo;
LOG_D(PHY, "RU clock source set as gpsdo\n");
} else {
LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
}
}
else {
RC.ru[j]->openair0_cfg.clock_source = unset;
ru[j]->openair0_cfg.clock_source = unset;
}
if (config_isparamset(RUParamList.paramarray[j], RU_SDR_TME_SRC)) {
if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "internal") == 0) {
RC.ru[j]->openair0_cfg.time_source = internal;
ru[j]->openair0_cfg.time_source = internal;
LOG_D(PHY, "RU time source set as internal\n");
} else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "external") == 0) {
RC.ru[j]->openair0_cfg.time_source = external;
ru[j]->openair0_cfg.time_source = external;
LOG_D(PHY, "RU time source set as external\n");
} else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "gpsdo") == 0) {
RC.ru[j]->openair0_cfg.time_source = gpsdo;
ru[j]->openair0_cfg.time_source = gpsdo;
LOG_D(PHY, "RU time source set as gpsdo\n");
} else {
LOG_E(PHY, "Erroneous RU time source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
}
}
else {
RC.ru[j]->openair0_cfg.time_source = unset;
ru[j]->openair0_cfg.time_source = unset;
}
LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) ru[j]->is_slave=1;
else ru[j]->is_slave=0;
LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) ru[j]->ota_sync_enable=1;
else ru[j]->ota_sync_enable=0;
if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = eNodeB_3GPP;
RC.ru[j]->state = RU_RUN;
LOG_I(PHY,"Setting function for RU %d to eNodeB_3GPP\n",j);
ru[j]->if_south = LOCAL_RF;
ru[j]->function = eNodeB_3GPP;
ru[j]->state = RU_RUN;
printf("Setting function for RU %d to eNodeB_3GPP\n",j);
} else {
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
// Check if control port set
if (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) {
LOG_I(PHY,"Removing control port for RU %d\n",j);
RC.ru[j]->has_ctrl_prt = 0;
ru[j]->has_ctrl_prt = 0;
} else {
RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
LOG_I(PHY," Control port %u \n",RC.ru[j]->eth_params.my_portc);
ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
LOG_I(PHY," Control port %u \n",ru[j]->eth_params.my_portc);
}
if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
ru[j]->if_south = LOCAL_RF;
ru[j]->function = NGFI_RRU_IF5;
ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
ru[j]->if_south = LOCAL_RF;
ru[j]->function = NGFI_RRU_IF5;
ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
RC.ru[j]->has_ctrl_prt =1;
ru[j]->if_south = LOCAL_RF;
ru[j]->function = NGFI_RRU_IF4p5;
ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
ru[j]->has_ctrl_prt =1;
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
RC.ru[j]->has_ctrl_prt =1;
ru[j]->if_south = LOCAL_RF;
ru[j]->function = NGFI_RRU_IF4p5;
ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
ru[j]->has_ctrl_prt =1;
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
}
LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1;
else RC.ru[j]->ota_sync_enable=0;
}
RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
/* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */
RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr);
for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
for (i=0; i<ru[j]->num_bands; i++) ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
} //strcmp(local_rf, "yes") == 0
else {
else {
LOG_I(PHY,"RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));
ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr));
ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
ru[j]->if_south = REMOTE_IF5;
ru[j]->function = NGFI_RAU_IF5;
ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ecpri_if5") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE;
ru[j]->if_south = REMOTE_IF5;
ru[j]->function = NGFI_RAU_IF5;
ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
RC.ru[j]->if_south = REMOTE_IF5;
RC.ru[j]->function = NGFI_RAU_IF5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
ru[j]->if_south = REMOTE_IF5;
ru[j]->function = NGFI_RAU_IF5;
ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
RC.ru[j]->has_ctrl_prt = 1;
ru[j]->if_south = REMOTE_IF4p5;
ru[j]->function = NGFI_RAU_IF4p5;
ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
ru[j]->has_ctrl_prt = 1;
} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
RC.ru[j]->has_ctrl_prt = 1;
ru[j]->if_south = REMOTE_IF4p5;
ru[j]->function = NGFI_RAU_IF4p5;
ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
ru[j]->has_ctrl_prt = 1;
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) ru[j]->is_slave=1;
else ru[j]->is_slave=0;
}
} /* strcmp(local_rf, "yes") != 0 */
RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
*ru_mask= (*ru_mask)|(1<<j);
}// j=0..num_rus
} else {
RC.nb_RU = 0;
} // setting != NULL
return;
}
return ru;
}
Loading