From 8950a77999717977315b75d7d5f57cc3b25f28c1 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 8 Mar 2019 18:21:44 +0100 Subject: [PATCH 01/35] SSB periodicity at gNB hardcoded in config_common and passed down, to be taken from config file in next commit --- openair1/PHY/INIT/nr_init.c | 1 + openair1/SCHED_NR/phy_procedures_nr_gNB.c | 30 +++++++++++++++++------ openair2/LAYER2/NR_MAC_gNB/config.c | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index c52f5e5245..5c1d9fe008 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -403,6 +403,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20); gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value; gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value; + gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value; if (phy_config->cfg->subframe_config.duplex_mode.value == 0) { gNB_config->subframe_config.duplex_mode.value = TDD; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index aeda4b3549..c23af9c4ea 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -91,12 +91,20 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t ssb_index, n_hf; int ssb_start_symbol, rel_slot; - + printf("Frame %d\n",frame); n_hf = cfg->sch_config.half_frame_index.value; + + // if SSB periodicity is 5ms, they are transmitted in both half frames + if ( cfg->sch_config.ssb_periodicity.value == 5) { + if (slot<10) + n_hf=0; + else + n_hf=1; + } + // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be rel_slot = (n_hf)? (slot-10) : slot; - LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot); if(rel_slot<10 && rel_slot>=0) { @@ -114,7 +122,10 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); + if (fp->Lmax == 4) + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); + else + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); nr_generate_pbch(&gNB->pbch, pbch_pdu, @@ -139,6 +150,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; nfapi_nr_config_request_t *cfg = &gNB->gNB_config; int offset = gNB->CC_id; + uint8_t ssb_frame_periodicity; // every how many frames SSB are generated + + if (cfg->sch_config.ssb_periodicity.value < 20) + ssb_frame_periodicity = 1; + else + ssb_frame_periodicity = (cfg->sch_config.ssb_periodicity.value)/10 ; // 10ms is the frame length if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return; @@ -151,10 +168,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); } - if (nfapi_mode == 0 || nfapi_mode == 1) { - nr_common_signal_procedures(gNB,frame, slot); - //if (frame == 9) - //write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1); + if (nfapi_mode == 0 || nfapi_mode == 1) { + if (!(frame%ssb_frame_periodicity)) // generate SSB only for given frames according to SSB periodicity + nr_common_signal_procedures(gNB,frame, slot); } num_dci = gNB->pdcch_vars.num_dci; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 12d01981d2..d48e8f013e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -197,6 +197,7 @@ void config_common(int Mod_idP, cfg->sch_config.physical_cell_id.value = cellid; cfg->sch_config.ssb_scg_position_in_burst.value = ssb_pattern; + cfg->sch_config.ssb_periodicity.value = 20; // FDD cfg->subframe_config.duplex_mode.value = 1; From 6e33fcfe28eeed78dc8b97d009fc7f6ffb9b77d7 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 11 Mar 2019 10:54:20 +0100 Subject: [PATCH 02/35] SSB periodicity at gNB from config file --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair2/LAYER2/NR_MAC_gNB/config.c | 27 +++++++++++++++++++ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 3 ++- openair2/RRC/NR/rrc_gNB.c | 2 +- .../gnb.band22.tm1.106PRB.adrv9371zc706.conf | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpx300.conf | 2 +- .../CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 2 +- 8 files changed, 35 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index c23af9c4ea..cd25ebc15a 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -91,7 +91,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t ssb_index, n_hf; int ssb_start_symbol, rel_slot; - printf("Frame %d\n",frame); + n_hf = cfg->sch_config.half_frame_index.value; // if SSB periodicity is 5ms, they are transmitted in both half frames diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index d48e8f013e..a12981dafa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -187,6 +187,7 @@ void config_common(int Mod_idP, int cellid, int nr_bandP, uint64_t ssb_pattern, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, uint32_t dl_BandwidthP ){ @@ -242,6 +243,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int p_gNB, int nr_bandP, uint64_t ssb_pattern, + uint16_t ssb_enum_periodicity, uint64_t dl_CarrierFreqP, int dl_BandwidthP, NR_BCCH_BCH_Message_t *mib, @@ -249,6 +251,30 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ){ + uint16_t ssb_periodicity; + + switch (ssb_enum_periodicity) { + case 0: + ssb_periodicity = 5; + break; + case 1: + ssb_periodicity = 10; + break; + case 2: + ssb_periodicity = 20; + break; + case 3: + ssb_periodicity = 40; + break; + case 4: + ssb_periodicity = 80; + break; + case 5: + ssb_periodicity = 160; + break; + + } + if( mib != NULL ){ config_nr_mib(Mod_idP, CC_idP, @@ -273,6 +299,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, cellid, nr_bandP, ssb_pattern, + ssb_periodicity, dl_CarrierFreqP, dl_BandwidthP ); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a214b160a2..36adc84d19 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -38,10 +38,11 @@ void mac_top_init_gNB(void); int rrc_mac_config_req_gNB(module_id_t Mod_idP, int CC_id, - int cellid, + int cellid, int p_gNB, int nr_bandP, uint64_t ssb_pattern, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, int dl_BandwidthP, NR_BCCH_BCH_Message_t *mib, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 801673b2ef..5af4ad0f4e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -260,13 +260,13 @@ static void init_NR_SI(const protocol_ctxt_t* const ctxt_pP, ); LOG_I(NR_RRC,"Done init_NR_SI\n"); - rrc_mac_config_req_gNB(ctxt_pP->module_id, CC_id, RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].p_gNB, configuration->nr_band[CC_id], + configuration->ServingCellConfigCommon_ssb_periodicityServingCell[CC_id], configuration->ServingCellConfigCommon_ssb_PositionsInBurst_PR[CC_id], RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, configuration->N_RB_DL[CC_id], diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf index 5fd4b465b3..c121cce0aa 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_ssb_periodicityServingCell = 20; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 077d1e5bd3..774fabd60f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_ssb_periodicityServingCell = 20; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index be98106d1e..3593f2681a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_ssb_periodicityServingCell = 20; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index dbd937d61a..36c0fb58ea 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_ssb_periodicityServingCell = 20; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; From aa12c954c1c5b61c69edad42808454eb4e0f7829 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 11 Mar 2019 12:36:57 +0100 Subject: [PATCH 03/35] bugfix --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- openair2/RRC/NR/rrc_gNB.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index a12981dafa..257687b99b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -198,7 +198,7 @@ void config_common(int Mod_idP, cfg->sch_config.physical_cell_id.value = cellid; cfg->sch_config.ssb_scg_position_in_burst.value = ssb_pattern; - cfg->sch_config.ssb_periodicity.value = 20; + cfg->sch_config.ssb_periodicity.value = ssb_periodicity; // FDD cfg->subframe_config.duplex_mode.value = 1; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5af4ad0f4e..4f83b4fd8a 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -266,8 +266,8 @@ static void init_NR_SI(const protocol_ctxt_t* const ctxt_pP, RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].p_gNB, configuration->nr_band[CC_id], - configuration->ServingCellConfigCommon_ssb_periodicityServingCell[CC_id], configuration->ServingCellConfigCommon_ssb_PositionsInBurst_PR[CC_id], + configuration->ServingCellConfigCommon_ssb_periodicityServingCell[CC_id], RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, configuration->N_RB_DL[CC_id], (NR_BCCH_BCH_Message_t *)&RC.nrrrc[ctxt_pP->module_id]->carrier[CC_id].mib, From 41b18e210b4e96d4a51e358ea900196d028bbbb0 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 11 Mar 2019 17:22:59 +0100 Subject: [PATCH 04/35] UE SSB periodicity (hardcoded) --- openair1/SCHED_NR_UE/defs.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 20 ++++++++++---------- targets/RT/USER/nr-ue.c | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 5a8dc96fab..ad06543718 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -123,7 +123,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t e @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying @param phy_vars_rn pointer to RN variables */ -int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode); +int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode,fapi_nr_pbch_config_t pbch_config); int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 89ae3c0696..224ced0468 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -4958,18 +4958,20 @@ int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_pr int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, - uint8_t do_pdcch_flag,runmode_t mode) { + uint8_t do_pdcch_flag,runmode_t mode, + fapi_nr_pbch_config_t pbch_config) { int l,l2; int pilot1; - int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 8; // to be updated by higher layer uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; + uint8_t ssb_periodicity = 20; // TODO hardcoded to be taken from upper layers? + uint8_t ssb_frame_periodicity; LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); @@ -5094,18 +5096,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } + ssb_frame_periodicity = ssb_periodicity/10 ; // 10ms is the frame length - - if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) + // looking for pbch only in frames according to ssb periodicity + if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1) && !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) { LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - uint8_t i_ssb = ue->rx_ind.rx_indication_body[0].mib_pdu.ssb_index; - uint8_t n_hf = (((ue->rx_ind.rx_indication_body[0].mib_pdu.additional_bits)>>4)&0x01); - for (int i=1; i<4; i++) { nr_slot_fep(ue, - (ue->symbol_offset+i), //mu=1 case B + (ue->symbol_offset+i), nr_tti_rx, 0, 0, @@ -5114,7 +5114,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); #endif - nr_pbch_channel_estimation(ue,0,0,ue->symbol_offset+i,i-1,i_ssb,n_hf); + nr_pbch_channel_estimation(ue,0,0,ue->symbol_offset+i,i-1,(pbch_config.ssb_index)&7,pbch_config.half_frame_bit); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); #endif @@ -5183,7 +5183,7 @@ start_meas(&ue->generic_stat); if(nr_tti_rx==5 && ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){ //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); //write_output("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - +openair1/SCHED_NR/phy_procedures_nr_gNB.c write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); //write_output("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); diff --git a/targets/RT/USER/nr-ue.c b/targets/RT/USER/nr-ue.c index 020dd9adbf..2bce41a4f5 100644 --- a/targets/RT/USER/nr-ue.c +++ b/targets/RT/USER/nr-ue.c @@ -638,7 +638,7 @@ static void *UE_thread_synch(void *arg) { return &UE_thread_synch_retval; } -void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { +void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { // Process Rx data for one sub-frame if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { //clean previous FAPI MESSAGE @@ -661,7 +661,7 @@ void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { #ifdef UE_SLOT_PARALLELISATION phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else - phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode); + phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode, UE_mac->phy_config.config_req.pbch_config); // printf(">>> nr_ue_pdcch_procedures ended\n"); #endif } @@ -725,7 +725,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { } AssertFatal ( 0== pthread_mutex_unlock(&proc->mutex_rxtx), "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - processSubframeRX(UE, proc); + processSlotRX(UE, proc); //printf(">>> mac ended\n"); // Prepare the future Tx data #if 0 @@ -1123,7 +1123,7 @@ void *UE_thread(void *arg) { // pickStaticTime(lastTime); } //UE->mode != loop_through_memory else { - processSubframeRX(UE,proc); + processSlotRX(UE,proc); getchar(); } // else loop_through_memory } // while !oai_exit From aab238173fa26a6a6cfd89ec26b04a4020f0b76c Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 22 Mar 2019 13:07:26 +0100 Subject: [PATCH 05/35] taking into account trashed frames (and commenting ghost frame addition) --- openair1/PHY/defs_nr_UE.h | 2 ++ openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 6 +++++- targets/RT/USER/nr-ue.c | 7 ++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index a482a48207..40f9d2d46c 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -1019,6 +1019,8 @@ typedef struct { NR_DL_FRAME_PARMS frame_parms_before_ho; NR_UE_COMMON common_vars; + int16_t trashed_frames; + nr_ue_if_module_t *if_inst; nr_downlink_indication_t dl_indication; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 224ced0468..1bc4017cfc 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2978,6 +2978,8 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t * ue->high_speed_flag); if (ret==0) { + + ue->trashed_frames = 0; ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; @@ -5098,6 +5100,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ssb_frame_periodicity = ssb_periodicity/10 ; // 10ms is the frame length + frame_rx += ue->trashed_frames; + // looking for pbch only in frames according to ssb periodicity if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1) && !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) { @@ -5183,7 +5187,7 @@ start_meas(&ue->generic_stat); if(nr_tti_rx==5 && ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){ //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); //write_output("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); -openair1/SCHED_NR/phy_procedures_nr_gNB.c + write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); //write_output("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); diff --git a/targets/RT/USER/nr-ue.c b/targets/RT/USER/nr-ue.c index 2bce41a4f5..0d024ce697 100644 --- a/targets/RT/USER/nr-ue.c +++ b/targets/RT/USER/nr-ue.c @@ -456,7 +456,7 @@ static void *UE_thread_synch(void *arg) { #else LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); #endif - + UE->trashed_frames = 0; if (nr_initial_sync( UE, UE->mode ) == 0) { //write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_slot), 1, 1); freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync @@ -936,6 +936,7 @@ void *UE_thread(void *arg) { } else { // grab 10 ms of signal into dummy buffer to wait result of sync detection trashFrame(UE, ×tamp); + UE->trashed_frames++; } } @@ -949,12 +950,12 @@ void *UE_thread(void *arg) { syncInFrame(UE, ×tamp); UE->rx_offset=0; UE->time_sync_cell=0; - UE->proc.proc_rxtx[0].frame_rx++; + /*UE->proc.proc_rxtx[0].frame_rx++; //UE->proc.proc_rxtx[1].frame_rx++; for (th_id=1; th_id < RX_NB_TH; th_id++) { UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx; - } + }*/ //printf("first stream frame rx %d\n",UE->proc.proc_rxtx[0].frame_rx); // read in first symbol From e6fa2079b7ce9689fea7f16b017cfcbcb36c0a0b Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 27 Mar 2019 10:29:51 +0100 Subject: [PATCH 06/35] ssb periodicity in UE and initialized at nr_ue_init --- openair1/PHY/INIT/nr_init_ue.c | 2 ++ openair1/PHY/defs_nr_UE.h | 1 + openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index a150717e42..858b587507 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -906,6 +906,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->decode_MIB = 1; ue->decode_SIB = 1; + ue->ssb_periodicity = 20; // initialization of ssb periodicity + init_prach_tables(839); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 40f9d2d46c..c521b05db4 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -1143,6 +1143,7 @@ typedef struct { // uint8_t prach_timer; uint8_t decode_SIB; uint8_t decode_MIB; + uint8_t ssb_periodicity; /// temporary offset during cell search prior to MIB decoding int ssb_offset; uint16_t symbol_offset; // offset in terms of symbols for detected ssb in sync diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 1bc4017cfc..1d3646bc4c 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -4972,7 +4972,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 8; // to be updated by higher layer uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; - uint8_t ssb_periodicity = 20; // TODO hardcoded to be taken from upper layers? + uint8_t ssb_periodicity = ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now uint8_t ssb_frame_periodicity; LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); From a8e8d55f29e3c4b2ddf6b0562fd36526b3dc5e97 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Tue, 2 Apr 2019 10:02:32 +0200 Subject: [PATCH 07/35] changing calls to slot fep and ch estimation in procedure_nr_ue for slot based processing --- executables/nr-ue.c | 6 ++--- openair1/PHY/MODULATION/slot_fep_nr.c | 15 +++++------ .../nr_dl_channel_estimation.c | 25 ++++++++++--------- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 2 -- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 13 +++++----- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 13 ++++++---- .../gnb.band22.tm1.106PRB.adrv9371zc706.conf | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpx300.conf | 2 +- .../CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 2 +- 10 files changed, 41 insertions(+), 41 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 402c379687..e22ed52f99 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -358,7 +358,7 @@ static void UE_synch(void *arg) { } } -void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { +void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { // Process Rx data for one sub-frame if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { //clean previous FAPI MESSAGE @@ -381,7 +381,7 @@ void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { #ifdef UE_SLOT_PARALLELISATION phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else - phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode); + phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode, UE_mac->phy_config.config_req.pbch_config); // printf(">>> nr_ue_pdcch_procedures ended\n"); #endif } @@ -417,7 +417,7 @@ void UE_processing(void *arg) { processingData_t *rxtxD=(processingData_t *) arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; - processSubframeRX(UE, proc); + processSlotRX(UE, proc); //printf(">>> mac ended\n"); // Prepare the future Tx data #if 0 diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 6ce486e3a0..717633c1f5 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -35,7 +35,7 @@ #endif*/ int nr_slot_fep(PHY_VARS_NR_UE *ue, - unsigned char l, + unsigned char symbol, unsigned char Ns, int sample_offset, int no_prefix, @@ -44,7 +44,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; unsigned char aa; - unsigned char symbol = l;//+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame unsigned int nb_prefix_samples; unsigned int nb_prefix_samples0; if (ue->is_synchronized) { @@ -146,7 +145,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples); #endif - if (l==0) { + if (symbol==0) { if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], @@ -171,8 +170,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #endif } } else { - rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// + - // (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); + rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol; + // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((void *)&common_vars->rxdata[aa][frame_length_samples], @@ -215,14 +214,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, case NR_PDCCH_EST: #ifdef DEBUG_FEP - printf("PDCCH Channel estimation aatx %d, slot %d, symbol %d start_sc %d\n",aa,Ns,l,coreset_start_subcarrier); + printf("PDCCH Channel estimation aatx %d, slot %d, symbol %d start_sc %d\n",aa,Ns,symbol,coreset_start_subcarrier); #endif #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); #endif nr_pdcch_channel_estimation(ue,0, Ns, - l, symbol, coreset_start_subcarrier, nb_rb_coreset); @@ -234,7 +232,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, case NR_PDSCH_EST: #ifdef DEBUG_FEP - printf("Channel estimation aatx %d, slot %d, symbol %d\n",aa,Ns,l); + printf("Channel estimation aatx %d, slot %d, symbol %d\n",aa,Ns,symbol); #endif #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); @@ -246,7 +244,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, nr_pdsch_channel_estimation(ue,0, Ns, p, - l, symbol, bwp_start_subcarrier, nb_rb_pdsch); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 917734f8ec..711a06d7a6 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -67,7 +67,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -326,6 +326,9 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + #ifdef DEBUG_CH printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif @@ -413,7 +416,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t eNB_offset, unsigned char Ns, - unsigned char l, unsigned char symbol, unsigned short coreset_start_subcarrier, unsigned short nb_rb_coreset) @@ -444,8 +446,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, k = coreset_start_subcarrier; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, - ue->frame_parms.Ncp,l,Ns,k, symbol); + printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp,Ns,k, symbol); #endif fl = filt16a_l1; @@ -616,14 +618,14 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, break; } - if( (Ns== 1) && (l == 0)) + if( (Ns== 1) && (symbol == 0)) { // do ifft of channel estimate for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) { if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx]) { - LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], l); + LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol); idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0], (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1); } @@ -637,11 +639,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t eNB_offset, unsigned char Ns, unsigned short p, - unsigned char l, unsigned char symbol, - unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch) -{ + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pdsch) { + int pilot[1320] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; @@ -669,8 +670,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int re_offset = k; #ifdef DEBUG_CH - printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, - ue->frame_parms.Ncp,l,Ns,k, symbol); + printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp,Ns,k, symbol); #endif switch (nushift) { diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 29400bbdc7..1a4250028e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -45,7 +45,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t eNB_offset, unsigned char Ns, - unsigned char l, unsigned char symbol, unsigned short coreset_start_subcarrier, unsigned short nb_rb_coreset); @@ -69,7 +68,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t eNB_offset, unsigned char Ns, unsigned short p, - unsigned char l, unsigned char symbol, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index a50edecb2c..f9a8057db0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -410,7 +410,7 @@ unsigned char sign(int8_t x) { uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,6,23}; int nr_rx_pbch( PHY_VARS_NR_UE *ue, - int subframe_rx, + int Ns, NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, uint8_t eNB_id, @@ -443,20 +443,21 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int symbol_offset=1; if (ue->is_synchronized > 0) - symbol_offset=ue->symbol_offset; + symbol_offset=(ue->symbol_offset)%(frame_parms->symbols_per_slot); else symbol_offset=0; + #ifdef DEBUG_PBCH - //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF); + //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF); write_output("rxdataF0_pbch.m","rxF0pbch", - &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); + &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); #endif // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot for (symbol=1; symbol<4; symbol++) { - nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF, - nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id], + nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF, + nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_id], nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->dl_ch_estimates_ext, symbol, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 20cae07a89..3ca667616a 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2938,7 +2938,7 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t * VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id); - ret = nr_rx_pbch(ue, proc->subframe_rx, + ret = nr_rx_pbch(ue, nr_tti_rx, ue->pbch_vars[eNB_id], &ue->frame_parms, eNB_id, @@ -4941,7 +4941,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 8; // to be updated by higher layer uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; - uint8_t ssb_periodicity = ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now + uint8_t ssb_periodicity = 10; //ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now uint8_t ssb_frame_periodicity; uint8_t dci_cnt = 0; @@ -5085,15 +5085,18 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ssb_frame_periodicity = ssb_periodicity/10 ; // 10ms is the frame length frame_rx += ue->trashed_frames; + int ssb_slot = (pbch_config.ssb_index)/2; + // looking for pbch only in frames according to ssb periodicity - if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1) && !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) + if ((ue->decode_MIB == 1) && (nr_tti_rx == ssb_slot) )//&& !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) { LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); for (int i=1; i<4; i++) { + nr_slot_fep(ue, - (ue->symbol_offset+i), + (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot), nr_tti_rx, 0, 0, @@ -5102,7 +5105,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); #endif - nr_pbch_channel_estimation(ue,0,0,ue->symbol_offset+i,i-1,(pbch_config.ssb_index)&7,pbch_config.half_frame_bit); + nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config.ssb_index)&7,pbch_config.half_frame_bit); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); #endif diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf index c121cce0aa..5fd4b465b3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band22.tm1.106PRB.adrv9371zc706.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 20; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 4d0df95225..f22abf3112 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 20; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index 3593f2681a..be98106d1e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 20; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 36c0fb58ea..dbd937d61a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 20; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; From 385dcea7ebbd0e668e81de9131023c4d6b1a2851 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 3 Apr 2019 15:07:45 +0200 Subject: [PATCH 08/35] intial sync over two frames (not working, still need to debug) --- executables/nr-ue.c | 8 +- openair1/PHY/INIT/nr_init_ue.c | 5 +- openair1/PHY/MODULATION/slot_fep_nr.c | 19 +-- openair1/PHY/NR_REFSIG/pss_nr.h | 3 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 108 +++++++++--------- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 65 ++++++----- openair1/PHY/defs_nr_UE.h | 5 + openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- 9 files changed, 118 insertions(+), 99 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index e22ed52f99..e7c71aede8 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -444,16 +444,16 @@ void UE_processing(void *arg) { #endif } -void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { +void readFrames(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { void *rxp[NB_ANTENNAS_RX]; void *dummy_tx[UE->frame_parms.nb_antennas_tx]; for (int i=0; iframe_parms.nb_antennas_tx; i++) dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); - for(int x=0; x<10; x++) { + for(int x=0; x<20; x++) { // two frames for initial sync for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; + rxp[i] = ((void *)&UE->common_vars.rxdata_is[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; AssertFatal( UE->frame_parms.samples_per_subframe == UE->rfdevice.trx_read_func(&UE->rfdevice, @@ -575,7 +575,7 @@ void *UE_thread(void *arg) { } else trashFrame(UE, ×tamp); } else { - readFrame(UE, ×tamp); + readFrames(UE, ×tamp); pushTpool(Tpool, syncMsg); syncRunning=true; } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 3a2ca5a172..226e89e489 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -710,14 +710,15 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } // init RX buffers - + common_vars->rxdata_is= (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); common_vars->rxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); for (th_id=0; th_idcommon_vars_rx_data_per_thread[th_id].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); } for (i=0; inb_antennas_rx; i++) { - common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_subframe*10+2048)*sizeof(int32_t) ); + common_vars->rxdata_is[i] = (int32_t*) malloc16_clear( (fp->samples_per_frame*2+2048)*sizeof(int32_t) ); + common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_frame+2048)*sizeof(int32_t) ); for (th_id=0; th_idcommon_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 717633c1f5..86ca29d902 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -46,11 +46,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, unsigned char aa; unsigned int nb_prefix_samples; unsigned int nb_prefix_samples0; + int **rxdata = NULL; if (ue->is_synchronized) { + rxdata = common_vars->rxdata; nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); } else { + rxdata = common_vars->rxdata_is; nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples); } @@ -148,13 +151,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (symbol==0) { if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], - (short *)&common_vars->rxdata[aa][0], + memcpy((short*) &(rxdata[aa][frame_length_samples]), + (short*) &(rxdata[aa][0]), frame_parms->ofdm_symbol_size*sizeof(int)); if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs memcpy((void *)tmp_dft_in, - (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples], + (void *) &(rxdata[aa][rx_offset % frame_length_samples]), frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); @@ -163,7 +166,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, start_meas(&ue->rx_dft_stats); #endif - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], + dft((int16_t *) &(rxdata[aa][(rx_offset) % frame_length_samples]), (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); @@ -174,8 +177,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((void *)&common_vars->rxdata[aa][frame_length_samples], - (void *)&common_vars->rxdata[aa][0], + memcpy((void *) &(rxdata[aa][frame_length_samples]), + (void *) &(rxdata[aa][0]), frame_parms->ofdm_symbol_size*sizeof(int)); #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); @@ -183,13 +186,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs memcpy((void *)tmp_dft_in, - (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], + (void *) &(rxdata[aa][(rx_offset) % frame_length_samples]), frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], + dft((int16_t *) &(rxdata[aa][(rx_offset) % frame_length_samples]), (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index dc20ab24d7..5233acac15 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -134,10 +134,11 @@ void free_context_synchro_nr(void); void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue); void free_context_pss_nr(void); int set_pss_nr(int ofdm_symbol_size); -int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change); +int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change); int pss_search_time_nr(int **rxdata, ///rx data in time domain NR_DL_FRAME_PARMS *frame_parms, int fo_flag, + int corr_samples, int *eNB_id, int *f_off); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 40cbb0d23e..e2e837398f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -222,10 +222,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,fp->N_RB_DL,n_ssb_crb,0); LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", fp->N_RB_DL); - /* - write_output("rxdata0.m","rxd0",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1); - exit(-1); - */ + /* Initial synchronisation * @@ -242,26 +239,27 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) cnt++; if (1){ // (cnt>100) - cnt =0; + cnt =0; - /* process pss search on received buffer */ - sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE); + // initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame + for(int is=0; is<2;is++) { + + /* process pss search on received buffer */ + sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE); - if (sync_pos >= fp->nb_prefix_samples) - ue->ssb_offset = sync_pos - fp->nb_prefix_samples; - else - ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples; + if (sync_pos >= fp->nb_prefix_samples) + ue->ssb_offset = sync_pos - fp->nb_prefix_samples; + else + ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples; - //write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1); - #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id); - LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset); + LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id); + LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset); #endif - // digital compensation of FFO for SSB symbols - if (ue->UE_fo_compensation){ + // digital compensation of FFO for SSB symbols + if (ue->UE_fo_compensation){ double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample @@ -270,17 +268,17 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) for(int n=start; nnb_antennas_rx; ar++) { - re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]); - im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]); - ((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); - ((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); + re = ((double)(((short *)ue->common_vars.rxdata_is[ar]))[2*n]); + im = ((double)(((short *)ue->common_vars.rxdata_is[ar]))[2*n+1]); + ((short *)ue->common_vars.rxdata_is[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); + ((short *)ue->common_vars.rxdata_is[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); } } - } + } - /* check that SSS/PBCH block is continuous inside the received buffer */ - if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) { + /* check that SSS/PBCH block is continuous inside the received buffer */ + if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) { /* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */ /* for NR this is not the case but slot_fep is still used for computing FFT of samples */ @@ -288,37 +286,37 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) /* symbol number are from beginning of SS/PBCH blocks as below: */ /* Signal PSS PBCH SSS PBCH */ /* symbol number 0 1 2 3 */ - /* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ + /* time samples in buffer rxdata_is are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ - for(int i=0; i<4;i++) - nr_slot_fep(ue, - i, - 0, - ue->ssb_offset, - 0, - NR_PBCH_EST); + for(int i=0; i<4;i++) + nr_slot_fep(ue, + i, + 0, + ue->ssb_offset, + 0, + NR_PBCH_EST); #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"Calling sss detection (normal CP)\n"); + LOG_I(PHY,"Calling sss detection (normal CP)\n"); #endif - rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp); + rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp); - //FK: why do we need to do this again here? - //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0); + //FK: why do we need to do this again here? + //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0); - nr_gold_pbch(ue); - ret = nr_pbch_detection(ue,1,mode); // start pbch detection at first symbol after pss + nr_gold_pbch(ue); + ret = nr_pbch_detection(ue,1,mode); // start pbch detection at first symbol after pss - if (ret == 0) { - // sync at symbol ue->symbol_offset - // computing the offset wrt the beginning of the frame - sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); - ue->rx_offset = ue->ssb_offset - sync_pos_frame; - } + if (ret == 0) { + // sync at symbol ue->symbol_offset + // computing the offset wrt the beginning of the frame + sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); + ue->rx_offset = ue->ssb_offset - sync_pos_frame; + } - nr_gold_pdcch(ue,0, 2); + nr_gold_pdcch(ue,0, 2); /* int nb_prefix_samples0 = fp->nb_prefix_samples0; fp->nb_prefix_samples0 = fp->nb_prefix_samples; @@ -334,16 +332,20 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ue->common_vars.freq_offset ); */ + #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n", - fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret); + LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d\n", + fp->Nid_cell,metric_tdd_ncp,phase_tdd_ncp,ret); #endif - } - else { + + } + else { #ifdef DEBUG_INITIAL_SYNCH - LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos); + LOG_I(PHY,"TDD Normal prefix: SSS error condition: sync_pos %d\n", sync_pos); #endif - } + } + if (ret == 0) break; + } } else { ret = -1; @@ -432,13 +434,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) // do a measurement on the best guess of the PSS //for (aarx=0; aarxnb_antennas_rx; aarx++) - // rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2], + // rx_power += signal_energy(&ue->common_vars.rxdata_is[aarx][sync_pos2], // frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); /* // do a measurement on the full frame for (aarx=0; aarxnb_antennas_rx; aarx++) - rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0], + rx_power += signal_energy(&ue->common_vars.rxdata_is[aarx][0], frame_parms->samples_per_subframe*10); */ diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 40945bebef..1e43a26be6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -608,10 +608,14 @@ void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_ch * ********************************************************************/ -void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **rxdata) +void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int is, int **rxdata) { + int samples_for_frame; NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; + if (is==0) + samples_for_frame = frame_parms->samples_per_frame + frame_parms->ofdm_symbol_size; + else + samples_for_frame = frame_parms->samples_per_frame; AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti); @@ -626,11 +630,11 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r /* build with cic filter does not work properly. Performances are significantly deteriorated */ #ifdef CIC_DECIMATOR - cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][0]), (int16_t *)&(rxdata[0][0]), + cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][is*frame_parms->samples_per_frame]), (int16_t *)&(rxdata[0][0]), samples_for_frame, rate_change, CIC_FILTER_STAGE_NUMBER, 0, FIR_RATE_CHANGE); #else - fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][0]), (int16_t *)&(rxdata[0][0]), + fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][frame_parms->samples_per_frame]), (int16_t *)&(rxdata[0][0]), samples_for_frame, rate_change, 0); #endif @@ -658,37 +662,43 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r * *********************************************************************/ -int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) +int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); int synchro_position; - int **rxdata = NULL; + int **rxdata; int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation + int samples_for_frame; + + // to take into account the possibility of PSS to be found between the two frames + // the analysis of the first of two frames is extended by one symbol (duration of PSS) + if (is==0) + samples_for_frame = frame_parms->samples_per_frame + frame_parms->ofdm_symbol_size; + else + samples_for_frame = frame_parms->samples_per_frame; #ifdef DBG_PSS_NR - - int samples_for_frame = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - - LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1); - + LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], 2*frame_parms->samples_per_frame, 1, 1); #endif + rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); + for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) + rxdata[aa] = (int32_t*) malloc16_clear( (samples_for_frame+8192)*sizeof(int32_t)); + if (rate_change != 1) { - rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); - - for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) { - rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+8192)*sizeof(int32_t)); - } #ifdef SYNCHRO_DECIMAT - decimation_synchro_nr(PHY_vars_UE, rate_change, rxdata); + decimation_synchro_nr(PHY_vars_UE, rate_change, is, rxdata); #endif } else { + for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) + memcpy(&(rxdata[aa][0]), + &(PHY_vars_UE->common_vars.rxdata[aa][is*frame_parms->samples_per_frame]), + samples_for_frame*sizeof(int32_t)); - rxdata = PHY_vars_UE->common_vars.rxdata; } #ifdef DBG_PSS_NR @@ -708,6 +718,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) synchro_position = pss_search_time_nr(rxdata, frame_parms, fo_flag, + samples_for_frame, (int *)&PHY_vars_UE->common_vars.eNb_id, (int *)&PHY_vars_UE->common_vars.freq_offset); @@ -727,21 +738,16 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) #endif #ifdef SYNCHRO_DECIMAT + if (rate_change != 1) + restore_frame_context_pss_nr(frame_parms, rate_change); +#endif - if (rate_change != 1) { - - if (rxdata[0] != NULL) { - - for (int aa=0;aanb_antennas_rx;aa++) { + if (rxdata[0] != NULL) { + for (int aa=0;aanb_antennas_rx;aa++) free(rxdata[aa]); - } free(rxdata); - } - - restore_frame_context_pss_nr(frame_parms, rate_change); } -#endif return synchro_position; } @@ -820,6 +826,7 @@ static inline double angle64(int64_t x) int pss_search_time_nr(int **rxdata, ///rx data in time domain NR_DL_FRAME_PARMS *frame_parms, int fo_flag, + int corr_samples, int *eNB_id, int *f_off) { @@ -830,7 +837,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain double ffo_est=0; - unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */ + unsigned int length = corr_samples; AssertFatal(length>0,"illegal length %d\n",length); for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 155b34a948..8b812caba1 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -409,6 +409,11 @@ typedef struct { /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ int32_t **rxdata; + /// \brief Holds the received data in time domain for initial sync. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+...[ + int32_t **rxdata_is; + NR_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX]; /// holds output of the sync correlator diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 3ca667616a..30870bf62e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -4941,7 +4941,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 8; // to be updated by higher layer uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; - uint8_t ssb_periodicity = 10; //ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now + uint8_t ssb_periodicity = ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now uint8_t ssb_frame_periodicity; uint8_t dci_cnt = 0; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index f22abf3112..4d0df95225 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_ssb_periodicityServingCell = 20; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; From ecaa424cbb9cc3dd460826b0d4e62c62d1244557 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 3 Apr 2019 17:11:56 +0200 Subject: [PATCH 09/35] fixes in how sync for two frames is handled in pss functions, it works --- openair1/PHY/NR_REFSIG/pss_nr.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 88 ++++++++++--------- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 5233acac15..a2e66d4e11 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -138,7 +138,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change); int pss_search_time_nr(int **rxdata, ///rx data in time domain NR_DL_FRAME_PARMS *frame_parms, int fo_flag, - int corr_samples, + int is, int *eNB_id, int *f_off); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 1e43a26be6..e637844ed7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -608,14 +608,10 @@ void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_ch * ********************************************************************/ -void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int is, int **rxdata) +void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **rxdata) { - int samples_for_frame; NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - if (is==0) - samples_for_frame = frame_parms->samples_per_frame + frame_parms->ofdm_symbol_size; - else - samples_for_frame = frame_parms->samples_per_frame; + int samples_for_frame = 2*frame_parms->samples_per_frame; AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti); @@ -630,11 +626,11 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int is, /* build with cic filter does not work properly. Performances are significantly deteriorated */ #ifdef CIC_DECIMATOR - cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][is*frame_parms->samples_per_frame]), (int16_t *)&(rxdata[0][0]), + cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata_is[0][0]), (int16_t *)&(rxdata[0][0]), samples_for_frame, rate_change, CIC_FILTER_STAGE_NUMBER, 0, FIR_RATE_CHANGE); #else - fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][frame_parms->samples_per_frame]), (int16_t *)&(rxdata[0][0]), + fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata_is[0][0]), (int16_t *)&(rxdata[0][0]), samples_for_frame, rate_change, 0); #endif @@ -666,44 +662,36 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); int synchro_position; - int **rxdata; + int **rxdata = NULL; int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation - int samples_for_frame; - - // to take into account the possibility of PSS to be found between the two frames - // the analysis of the first of two frames is extended by one symbol (duration of PSS) - if (is==0) - samples_for_frame = frame_parms->samples_per_frame + frame_parms->ofdm_symbol_size; - else - samples_for_frame = frame_parms->samples_per_frame; #ifdef DBG_PSS_NR - LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], 2*frame_parms->samples_per_frame, 1, 1); -#endif - rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); - for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) - rxdata[aa] = (int32_t*) malloc16_clear( (samples_for_frame+8192)*sizeof(int32_t)); + LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata_is[0][0], frame_parms->samples_per_frame, 1, 1); + +#endif if (rate_change != 1) { + rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); + + for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) { + rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_frame+8192)*sizeof(int32_t)); + } #ifdef SYNCHRO_DECIMAT - decimation_synchro_nr(PHY_vars_UE, rate_change, is, rxdata); + decimation_synchro_nr(PHY_vars_UE, rate_change, rxdata); #endif } else { - for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) - memcpy(&(rxdata[aa][0]), - &(PHY_vars_UE->common_vars.rxdata[aa][is*frame_parms->samples_per_frame]), - samples_for_frame*sizeof(int32_t)); + rxdata = PHY_vars_UE->common_vars.rxdata_is; } #ifdef DBG_PSS_NR - LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1); + LOG_M("rxdata0_des.m","rxd0_des", &rxdata[0][0], frame_parms->samples_per_frame,1,1); #endif @@ -718,7 +706,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) synchro_position = pss_search_time_nr(rxdata, frame_parms, fo_flag, - samples_for_frame, + is, (int *)&PHY_vars_UE->common_vars.eNb_id, (int *)&PHY_vars_UE->common_vars.freq_offset); @@ -738,20 +726,26 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) #endif #ifdef SYNCHRO_DECIMAT - if (rate_change != 1) - restore_frame_context_pss_nr(frame_parms, rate_change); -#endif - if (rxdata[0] != NULL) { - for (int aa=0;aanb_antennas_rx;aa++) + if (rate_change != 1) { + + if (rxdata[0] != NULL) { + + for (int aa=0;aanb_antennas_rx;aa++) { free(rxdata[aa]); + } free(rxdata); + } + + restore_frame_context_pss_nr(frame_parms, rate_change); } +#endif return synchro_position; } + static inline int abs32(int x) { return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1])); @@ -777,7 +771,7 @@ static inline double angle64(int64_t x) * * PARAMETERS : received buffer * frame parameters -* +*https://www.ilpost.it/ * RETURN : position of detected pss * * DESCRIPTION : Synchronisation on pss sequence is based on a time domain correlation between received samples and pss sequence @@ -826,7 +820,7 @@ static inline double angle64(int64_t x) int pss_search_time_nr(int **rxdata, ///rx data in time domain NR_DL_FRAME_PARMS *frame_parms, int fo_flag, - int corr_samples, + int is, int *eNB_id, int *f_off) { @@ -836,13 +830,18 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain int64_t avg[NUMBER_PSS_SEQUENCE]; double ffo_est=0; - - unsigned int length = corr_samples; + // performing the correlation on a frame length plus one symbol for the first of the two frame + // to take into account the possibility of PSS in between the two frames + unsigned int length; + if (is==0) + length = frame_parms->samples_per_frame + (2*frame_parms->ofdm_symbol_size); + else + length = frame_parms->samples_per_frame; AssertFatal(length>0,"illegal length %d\n",length); for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i); - + printf("%d\n\n",length); peak_value = 0; peak_position = 0; pss_source = 0; @@ -878,7 +877,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain /* perform correlation of rx data and pss sequence ie it is a dot product */ result = dot_product64((short*)primary_synchro_time_nr[pss_index], - (short*) &(rxdata[ar][n]), + (short*) &(rxdata[ar][n])+(is*frame_parms->samples_per_frame), frame_parms->ofdm_symbol_size, shift); pss_corr_ue[pss_index][n] += abs64(result); @@ -912,13 +911,13 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain int64_t result1,result2; // Computing cross-correlation at peak on half the symbol size for first half of data result1 = dot_product64((short*)primary_synchro_time_nr[pss_source], - (short*) &(rxdata[0][peak_position]), + (short*) &(rxdata[0][peak_position])+(is*frame_parms->samples_per_frame), frame_parms->ofdm_symbol_size>>1, shift); // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift result2 = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size), - (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size), + (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size+(is*frame_parms->samples_per_frame)), frame_parms->ofdm_symbol_size>>1, shift); @@ -957,7 +956,10 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6); LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6); LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6); - LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1); + if (is) + LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1); + else + LOG_M("rxdata0.m","rxd0",rxdata[0],length,1,1); } else { debug_cnt++; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 4d0df95225..f22abf3112 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -71,7 +71,7 @@ gNBs = UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 20; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; ServingCellConfigCommon_ss_PBCH_BlockPower = -60; From e5a682c690e76f94559861e95af73444eacb2942 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 3 Apr 2019 17:14:47 +0200 Subject: [PATCH 10/35] Update pss_nr.c --- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index e637844ed7..626ba15022 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -771,7 +771,7 @@ static inline double angle64(int64_t x) * * PARAMETERS : received buffer * frame parameters -*https://www.ilpost.it/ +* * RETURN : position of detected pss * * DESCRIPTION : Synchronisation on pss sequence is based on a time domain correlation between received samples and pss sequence From a08e120c1c73a27b98be06459cb527611497da35 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 3 Apr 2019 17:16:54 +0200 Subject: [PATCH 11/35] Removing an unwanted printf --- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 626ba15022..6875fdeab9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -841,7 +841,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain AssertFatal(length>0,"illegal length %d\n",length); for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i); - printf("%d\n\n",length); peak_value = 0; peak_position = 0; pss_source = 0; From e0986d2de3df653198fb6d2bdb6660019631b1b9 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 4 Apr 2019 18:01:13 +0200 Subject: [PATCH 12/35] removing my trashed frames --- openair1/PHY/defs_nr_UE.h | 2 -- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 9 +++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 53c21c726e..9270a96d95 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -913,8 +913,6 @@ typedef struct { NR_DL_FRAME_PARMS frame_parms_before_ho; NR_UE_COMMON common_vars; - int16_t trashed_frames; - nr_ue_if_module_t *if_inst; nr_downlink_indication_t dl_indication; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2638b2481b..2821c61a7f 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2835,7 +2835,6 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t * if (ret==0) { - ue->trashed_frames = 0; ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; @@ -4314,7 +4313,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 9; // to be updated by higher layer uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; - uint8_t ssb_periodicity = ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now + uint8_t ssb_periodicity = 10; //ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now uint8_t ssb_frame_periodicity; uint8_t dci_cnt = 0; @@ -4465,12 +4464,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ssb_frame_periodicity = ssb_periodicity/10 ; // 10ms is the frame length - frame_rx += ue->trashed_frames; int ssb_slot = (pbch_config.ssb_index)/2; - - // looking for pbch only in frames according to ssb periodicity - if ((ue->decode_MIB == 1) && (nr_tti_rx == ssb_slot) )//&& !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) + // looking for pbch only in frames according to ssb periodicity and in slot where decoded ssb is found + if ((ue->decode_MIB == 1) && (nr_tti_rx == ssb_slot) && !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) { LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); From 2feed73050d8a00252fac399b9c2739ba6f7dfb6 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 4 Apr 2019 18:36:31 +0200 Subject: [PATCH 13/35] fixing counter of trashed frames for two frames synchronization --- executables/nr-ue.c | 4 ++++ openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 5 ++++- openair1/PHY/defs_nr_UE.h | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index bca68ed37d..c8ed8d45cf 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -592,6 +592,10 @@ void *UE_thread(void *arg) { // and we shifted above to the first slot of next frame // the synch thread proc context is hard linked to regular processing thread context, thread id = 0 UE_nr_rxtx_proc_t *proc=&(((processingData_t *)NotifiedFifoData(processingMsg[0]))->proc); + // synchronization is on two frame basis + // if it succeeds on the first frame the second one needs to be considered as trashed + if(!UE->is_synchronized_on_frame) + trashed_frames++; // shift the frame index with all the frames we trashed meanwhile we perform the synch search proc->decoded_frame_rx=(proc->decoded_frame_rx + trashed_frames) % MAX_FRAME_NUMBER; decoded_frame_rx=proc->decoded_frame_rx; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 78dbe83b80..4ba7c67339 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -208,6 +208,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) int32_t metric_tdd_ncp=0; uint8_t phase_tdd_ncp; double im, re; + int is; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; int ret=-1; @@ -242,7 +243,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) cnt =0; // initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame - for(int is=0; is<2;is++) { + for(is=0; is<2;is++) { /* process pss search on received buffer */ sync_pos = pss_synchro_nr(ue, is, NO_RATE_CHANGE); @@ -372,6 +373,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) #endif //#endif + ue->is_synchronized_on_frame = is; // to notify on which of the two frames sync was successful + if (ue->UE_scan_carrier == 0) { #if UE_AUTOTEST_TRACE diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 9270a96d95..213ce98924 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -878,8 +878,10 @@ typedef struct { int UE_scan_carrier; /// \brief Indicator that UE should enable estimation and compensation of frequency offset int UE_fo_compensation; - /// \brief Indicator that UE is synchronized to an eNB + /// \brief Indicator that UE is synchronized to a gNB int is_synchronized; + /// \brief Indicates on which frame is synchronized in a two frame synchronization + int is_synchronized_on_frame; /// Data structure for UE process scheduling UE_nr_proc_t proc; /// Flag to indicate the UE shouldn't do timing correction at all From 91121c6bd31ae6e9a141e9fdc5d37a6567a797a4 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 5 Apr 2019 11:57:20 +0200 Subject: [PATCH 14/35] default ssb periodicity 5ms and function to compute if ssb is in slot --- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 32 ++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 226e89e489..af3c548686 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -912,7 +912,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->decode_MIB = 1; ue->decode_SIB = 1; - ue->ssb_periodicity = 20; // initialization of ssb periodicity + ue->ssb_periodicity = 5; // initialization of ssb periodicity to 5ms according to TS38.213 section 4.1 init_prach_tables(839); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2821c61a7f..01bd952e81 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -4299,6 +4299,26 @@ void *UE_thread_slot1_dl_processing(void *arg) { #endif +int is_pbch_in_slot(fapi_nr_pbch_config_t pbch_config, int frame, int slot, int periodicity, uint16_t slots_per_frame) { + + int ssb_slot_decoded = (pbch_config.ssb_index)/2; + + if (periodicity == 5) { + // check for pbch in corresponding slot each half frame + if (pbch_config.half_frame_bit) + return(slot == ssb_slot_decoded || slot == ssb_slot_decoded - slots_per_frame/2); + else + return(slot == ssb_slot_decoded || slot == ssb_slot_decoded + slots_per_frame/2); + } + else { + // if the current frame is supposed to contain ssb + if (!((frame-(pbch_config.system_frame_number))%(periodicity/10))) + return(slot == ssb_slot_decoded); + else + return 0; + } +} + int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t do_pdcch_flag,runmode_t mode, @@ -4310,11 +4330,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN int pilot1; int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; + int slot_pbch; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; uint16_t nb_symb_sch = 9; // to be updated by higher layer uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; - uint8_t ssb_periodicity = 10; //ue->ssb_periodicity; // initialized to 20ms in nr_init_ue and never changed for now - uint8_t ssb_frame_periodicity; + uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) uint8_t dci_cnt = 0; LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); @@ -4462,12 +4482,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } - ssb_frame_periodicity = ssb_periodicity/10 ; // 10ms is the frame length + slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame); - int ssb_slot = (pbch_config.ssb_index)/2; - - // looking for pbch only in frames according to ssb periodicity and in slot where decoded ssb is found - if ((ue->decode_MIB == 1) && (nr_tti_rx == ssb_slot) && !((frame_rx-(pbch_config.system_frame_number))%ssb_frame_periodicity)) + // looking for pbch only in slot where it is supposed to be + if ((ue->decode_MIB == 1) && slot_pbch) { LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); From 43a98185db2e920e0733bffa37b2ec48c7cde48b Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 5 Apr 2019 18:02:26 +0200 Subject: [PATCH 15/35] fix on pbchsim for -I but still not working without initial sync --- executables/nr-ue.c | 2 +- openair1/PHY/MODULATION/slot_fep_nr.c | 2 -- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 6 ++--- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 +++- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair1/SIMULATION/NR_PHY/pbchsim.c | 23 ++++++++----------- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index c8ed8d45cf..56a6aa68a4 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -239,7 +239,7 @@ static void UE_synch(void *arg) { case pbch: LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (nr_initial_sync( syncD->proc, UE, UE->mode ) == 0) { + if (nr_initial_sync( syncD->proc, UE, UE->mode,2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot; LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 86ca29d902..0c17b5d964 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -133,8 +133,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, return(-1); } - - for (aa=0; aanb_antennas_rx; aa++) { memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 4ba7c67339..94dffb07fa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -201,7 +201,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini char duplex_string[2][4] = {"FDD","TDD"}; char prefix_string[2][9] = {"NORMAL","EXTENDED"}; -int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) +int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int n_frames) { int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2, @@ -243,7 +243,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode) cnt =0; // initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame - for(is=0; is<2;is++) { + // only one frame is used for symulation tools + for(is=0; isssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples; - #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id); LOG_I(PHY,"sync_pos %d ssb_offset %d \n",sync_pos,ue->ssb_offset); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 6290a700c5..408331c137 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1435,7 +1435,9 @@ void generate_RIV_tables(void); @param mode current running mode */ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, - PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode); + PHY_VARS_NR_UE *phy_vars_ue, + runmode_t mode, + int n_frames); /*! diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index ae8d3062ad..424ac6db7a 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -685,7 +685,7 @@ int main(int argc, char **argv) } if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx); + ret = nr_initial_sync(&proc, UE, normal_txrx,1); printf("nr_initial_sync1 returns %d\n",ret); if (ret<0) n_errors++; } diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 36a913f939..b50b2d4cb0 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -478,8 +478,7 @@ int main(int argc, char **argv) if(eps!=0.0) UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation - if (init_nr_ue_signal(UE, 1, 0) != 0) - { + if (init_nr_ue_signal(UE, 1, 0) != 0) { printf("Error at UE NR initialisation\n"); exit(-1); } @@ -588,39 +587,37 @@ int main(int argc, char **argv) for (i=0; inb_antennas_rx; aa++) { - ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata_is[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata_is[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } if (n_trials==1) { - LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_parms->samples_per_frame,1,1); + LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata_is[0],frame_parms->samples_per_frame,1,1); if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1); + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata_is[1],frame_parms->samples_per_frame,1,1); } if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx); + ret = nr_initial_sync(&proc, UE, normal_txrx,1); printf("nr_initial_sync1 returns %d\n",ret); if (ret<0) n_errors++; } else { UE->rx_offset=0; - uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb - UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index, n_hf); + int ssb_slot = (ssb_index/2)+(n_hf*frame_parms->slots_per_frame); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { nr_slot_fep(UE, - i, - 0, + i%frame_parms->symbols_per_slot, + ssb_slot, 0, 0, NR_PBCH_EST); - - nr_pbch_channel_estimation(UE,0,0,i,i-(UE->symbol_offset+1),ssb_index%8,n_hf); + nr_pbch_channel_estimation(UE,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); } UE_nr_rxtx_proc_t proc={0}; From f5d6aa4ca6ce737f4d28e0ccea7940e31765fa14 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 5 Apr 2019 18:18:49 +0200 Subject: [PATCH 16/35] fix on pbchsim without -I --- openair1/PHY/MODULATION/slot_fep_nr.c | 1 - openair1/SIMULATION/NR_PHY/pbchsim.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 0c17b5d964..e4e4d185f3 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -173,7 +173,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } else { rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol; // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((void *) &(rxdata[aa][frame_length_samples]), (void *) &(rxdata[aa][0]), diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index b50b2d4cb0..72ab7e93f3 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -605,6 +605,7 @@ int main(int argc, char **argv) if (ret<0) n_errors++; } else { + UE->common_vars.rxdata = UE->common_vars.rxdata_is; UE->rx_offset=0; uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb From 09cca53829e0a8cb7c3d332101b481706c766e0b Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 8 Apr 2019 17:17:48 +0200 Subject: [PATCH 17/35] using only one structure for rxdata --- executables/nr-ue.c | 2 +- openair1/PHY/INIT/nr_init_ue.c | 4 +--- openair1/PHY/MODULATION/slot_fep_nr.c | 19 ++++++++----------- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 14 +++++++------- openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 8 ++++---- openair1/PHY/defs_nr_UE.h | 7 +------ openair1/SIMULATION/NR_PHY/pbchsim.c | 9 ++++----- 7 files changed, 26 insertions(+), 37 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 56a6aa68a4..dad6a6147f 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -442,7 +442,7 @@ void readFrames(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { for(int x=0; x<20; x++) { // two frames for initial sync for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = ((void *)&UE->common_vars.rxdata_is[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; + rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; AssertFatal( UE->frame_parms.samples_per_subframe == UE->rfdevice.trx_read_func(&UE->rfdevice, diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index af3c548686..1846b06b47 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -710,15 +710,13 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } // init RX buffers - common_vars->rxdata_is= (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); common_vars->rxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); for (th_id=0; th_idcommon_vars_rx_data_per_thread[th_id].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); } for (i=0; inb_antennas_rx; i++) { - common_vars->rxdata_is[i] = (int32_t*) malloc16_clear( (fp->samples_per_frame*2+2048)*sizeof(int32_t) ); - common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_frame+2048)*sizeof(int32_t) ); + common_vars->rxdata[i] = (int32_t*) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); for (th_id=0; th_idcommon_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index e4e4d185f3..f096499580 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -46,14 +46,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, unsigned char aa; unsigned int nb_prefix_samples; unsigned int nb_prefix_samples0; - int **rxdata = NULL; if (ue->is_synchronized) { - rxdata = common_vars->rxdata; nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); } else { - rxdata = common_vars->rxdata_is; nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples); } @@ -149,13 +146,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (symbol==0) { if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((short*) &(rxdata[aa][frame_length_samples]), - (short*) &(rxdata[aa][0]), + memcpy((short*) &common_vars->rxdata[aa][frame_length_samples], + (short*) &common_vars->rxdata[aa][0], frame_parms->ofdm_symbol_size*sizeof(int)); if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs memcpy((void *)tmp_dft_in, - (void *) &(rxdata[aa][rx_offset % frame_length_samples]), + (void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); @@ -164,7 +161,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, start_meas(&ue->rx_dft_stats); #endif - dft((int16_t *) &(rxdata[aa][(rx_offset) % frame_length_samples]), + dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); @@ -174,8 +171,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol; // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((void *) &(rxdata[aa][frame_length_samples]), - (void *) &(rxdata[aa][0]), + memcpy((void *) &common_vars->rxdata[aa][frame_length_samples], + (void *) &common_vars->rxdata[aa][0], frame_parms->ofdm_symbol_size*sizeof(int)); #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); @@ -183,13 +180,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs memcpy((void *)tmp_dft_in, - (void *) &(rxdata[aa][(rx_offset) % frame_length_samples]), + (void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly - dft((int16_t *) &(rxdata[aa][(rx_offset) % frame_length_samples]), + dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 94dffb07fa..860f36ab3c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -269,10 +269,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, for(int n=start; nnb_antennas_rx; ar++) { - re = ((double)(((short *)ue->common_vars.rxdata_is[ar]))[2*n]); - im = ((double)(((short *)ue->common_vars.rxdata_is[ar]))[2*n+1]); - ((short *)ue->common_vars.rxdata_is[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); - ((short *)ue->common_vars.rxdata_is[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); + re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]); + im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]); + ((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle))); + ((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle))); } } } @@ -286,7 +286,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, /* symbol number are from beginning of SS/PBCH blocks as below: */ /* Signal PSS PBCH SSS PBCH */ /* symbol number 0 1 2 3 */ - /* time samples in buffer rxdata_is are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ + /* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */ /* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */ for(int i=0; i<4;i++) @@ -436,13 +436,13 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, // do a measurement on the best guess of the PSS //for (aarx=0; aarxnb_antennas_rx; aarx++) - // rx_power += signal_energy(&ue->common_vars.rxdata_is[aarx][sync_pos2], + // rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2], // frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); /* // do a measurement on the full frame for (aarx=0; aarxnb_antennas_rx; aarx++) - rx_power += signal_energy(&ue->common_vars.rxdata_is[aarx][0], + rx_power += signal_energy(&ue->common_vars.rxdata[aarx][0], frame_parms->samples_per_subframe*10); */ diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 990d89a545..a880959864 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -626,11 +626,11 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r /* build with cic filter does not work properly. Performances are significantly deteriorated */ #ifdef CIC_DECIMATOR - cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata_is[0][0]), (int16_t *)&(rxdata[0][0]), + cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][0]), (int16_t *)&(rxdata[0][0]), samples_for_frame, rate_change, CIC_FILTER_STAGE_NUMBER, 0, FIR_RATE_CHANGE); #else - fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata_is[0][0]), (int16_t *)&(rxdata[0][0]), + fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][0]), (int16_t *)&(rxdata[0][0]), samples_for_frame, rate_change, 0); #endif @@ -667,7 +667,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) #ifdef DBG_PSS_NR - LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata_is[0][0], frame_parms->samples_per_frame, 1, 1); + LOG_M("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], frame_parms->samples_per_frame, 1, 1); #endif @@ -686,7 +686,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change) } else { - rxdata = PHY_vars_UE->common_vars.rxdata_is; + rxdata = PHY_vars_UE->common_vars.rxdata; } #ifdef DBG_PSS_NR diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 213ce98924..b47e288607 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -303,14 +303,9 @@ typedef struct { /// \brief Holds the received data in time domain. /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ + /// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[ int32_t **rxdata; - /// \brief Holds the received data in time domain for initial sync. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+...[ - int32_t **rxdata_is; - NR_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX]; /// holds output of the sync correlator diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 72ab7e93f3..54687d6b68 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -587,15 +587,15 @@ int main(int argc, char **argv) for (i=0; inb_antennas_rx; aa++) { - ((short*) UE->common_vars.rxdata_is[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) UE->common_vars.rxdata_is[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } if (n_trials==1) { - LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata_is[0],frame_parms->samples_per_frame,1,1); + LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_parms->samples_per_frame,1,1); if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata_is[1],frame_parms->samples_per_frame,1,1); + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1); } if (UE->is_synchronized == 0) { @@ -605,7 +605,6 @@ int main(int argc, char **argv) if (ret<0) n_errors++; } else { - UE->common_vars.rxdata = UE->common_vars.rxdata_is; UE->rx_offset=0; uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb From ca4627836fb7135598e1987d01c46d35c9738ff9 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 15 Apr 2019 15:46:37 +0200 Subject: [PATCH 18/35] fixing compilation error --- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 4152ef9322..b56573f2b3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -460,7 +460,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, for (symbol=1; symbol<4; symbol++) { nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF, - nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_id], + nr_ue_pbch_vars->dl_ch_estimates, nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->dl_ch_estimates_ext, symbol, From f6fbd72cae93eae616eab89aa8d6243b91fb2639 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 17 Apr 2019 12:15:27 +0200 Subject: [PATCH 19/35] initialization of nr_tti_rx in initial sync --- executables/nr-ue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index e7150463fe..54a9dfdd96 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -164,10 +164,12 @@ static void UE_synch(void *arg) { syncData_t *syncD=(syncData_t *) arg; int i, hw_slot_offset; PHY_VARS_NR_UE *UE = syncD->UE; + UE_nr_rxtx_proc_t *proc = syncD->proc; sync_mode_t sync_mode = pbch; int CC_id = UE->CC_id; int freq_offset=0; UE->is_synchronized = 0; + proc->nr_tti_rx = 0; if (UE->UE_scan == 0) { get_band(downlink_frequency[CC_id][0], &UE->frame_parms.eutra_band, &uplink_frequency_offset[CC_id][0], &UE->frame_parms.frame_type); From c254ce07a06b323fc6921b9c19a26025a6bb5da9 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Tue, 14 May 2019 14:39:39 +0200 Subject: [PATCH 20/35] a unnotified conflict resolved --- openair2/LAYER2/NR_MAC_gNB/config.c | 3 +-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 417caabf17..81e59a7dd2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -85,8 +85,7 @@ void config_common(int Mod_idP, uint64_t ssb_pattern, uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, - uint32_t dl_BandwidthP - ){ + uint32_t dl_BandwidthP){ nfapi_nr_config_request_t *cfg = &RC.nrmac[Mod_idP]->config[CC_idP]; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 32e3f6a6d0..4f5e3b5938 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -38,9 +38,10 @@ void mac_top_init_gNB(void); void config_common(int Mod_idP, int CC_idP, - int Nid_cell, + int Nid_cell, int nr_bandP, - uint64_t ssb_pattern, + uint64_t ssb_pattern, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, uint32_t dl_BandwidthP); From f1539df7f176ebd24cd59d6fb7401e856ae64a62 Mon Sep 17 00:00:00 2001 From: laurent Date: Sat, 18 May 2019 14:31:41 +0200 Subject: [PATCH 21/35] fix UE switch from read only to R+W --- targets/ARCH/rfsimulator/simulator.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 099e1c190a..e1ca17a5a1 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -3,6 +3,12 @@ copyleft: OpenAirInterface Software Alliance and it's licence */ +/* + * Open issues and limitations + * The read and write should be called in the same thread, that is not new USRP UHD design + * When the opposite side switch from passive reading to active R+Write, the synchro is not fully deterministic + */ + #include #include #include @@ -111,7 +117,7 @@ void setblocking(int sock, enum blocking_t active) { AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); } -static bool flushInput(rfsimulator_state_t *t); +static bool flushInput(rfsimulator_state_t *t, int timeout); void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if (t->saveIQfile != -1) { @@ -134,7 +140,9 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { continue; if(errno==EAGAIN) { - flushInput(t); + // The opposite side is saturated + // we read incoming sockets meawhile waiting + flushInput(t, 5); continue; } else return; @@ -229,14 +237,17 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi lastW=timestamp; LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); + // Let's verify we don't have incoming data + // This is mandatory when the opposite side don't transmit + flushInput(t, 0); return nsamps; } -static bool flushInput(rfsimulator_state_t *t) { +static bool flushInput(rfsimulator_state_t *t, int timeout) { // Process all incoming events on sockets // store the data in lists struct epoll_event events[FD_SETSIZE]= {0}; - int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 20); + int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout); if ( nfds==-1 ) { if ( errno==EINTR || errno==EAGAIN ) @@ -356,7 +367,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo if ( first_sock == FD_SETSIZE ) { // no connected device (we are eNB, no UE is connected) - if (!flushInput(t)) { + if (!flushInput(t, 10)) { for (int x=0; x < nbAnt; x++) memset(samplesVoid[x],0,sampleToByte(nsamps,1)); @@ -385,7 +396,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ptr->lastReceivedTS, t->nextTimestamp+nsamps); */ - flushInput(t); + flushInput(t, 3); } while (have_to_wait); } From cc239de2c79168832708d83252cfb1c0f2881bc7 Mon Sep 17 00:00:00 2001 From: laurent Date: Sat, 18 May 2019 15:03:23 +0200 Subject: [PATCH 22/35] fix UE switch from read only to R+W --- executables/nr-uesoftmodem.c | 2 +- executables/nr-uesoftmodem.h | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 2 +- targets/ARCH/rfsimulator/simulator.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 8300f10675..c8143879b1 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -393,7 +393,7 @@ static void get_options(void) { uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; uint32_t start_telnetsrv=0; - paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 078a8066c3..4d45e08722 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -150,7 +150,7 @@ /* command line parameters common to eNodeB and UE */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_PARAMS_DESC { \ +#define CMDLINE_PARAMS_DESC_UE { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 92409d96dc..c7b500007d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -1181,7 +1181,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) ctxt_pP->subframe, ctxt_pP->module_id); - for (dst_id = 0; dst_id Date: Tue, 21 May 2019 15:07:26 +0200 Subject: [PATCH 23/35] make dlsim compile again --- openair1/SIMULATION/NR_PHY/dlsim.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 7af35f760d..f1991dfc35 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -113,7 +113,8 @@ void config_common(int Mod_idP, int CC_idP, int Nid_cell, int nr_bandP, - uint64_t ssb_pattern, + uint64_t SSB_positions, + uint16_t ssb_periodicity, uint64_t dl_CarrierFreqP, uint32_t dl_BandwidthP ); @@ -166,7 +167,7 @@ int main(int argc, char **argv) //int pbch_tx_ant; int N_RB_DL=273,mu=1; - uint64_t ssb_pattern = 0x01; + uint16_t ssb_periodicity = 10; //unsigned char frame_type = 0; unsigned char pbch_phase = 0; @@ -520,7 +521,7 @@ int main(int argc, char **argv) mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; - config_common(0,0,Nid_cell,78,ssb_pattern,(uint64_t)3640000000L,N_RB_DL); + config_common(0,0,Nid_cell,78,SSB_positions,ssb_periodicity,(uint64_t)3640000000L,N_RB_DL); config_nr_mib(0,0,1,kHz30,0,0,0,0,0); nr_l2_init_ue(); @@ -681,6 +682,10 @@ int main(int argc, char **argv) UE_mac->scheduled_response.frame = frame; UE_mac->scheduled_response.slot = slot; + UE_mac->phy_config.config_req.pbch_config.system_frame_number = frame; + UE_mac->phy_config.config_req.pbch_config.ssb_index = 0; + UE_mac->phy_config.config_req.pbch_config.half_frame_bit = 0; + for (SNR=snr0; SNRphy_config.config_req.pbch_config); if (n_trials==1) { LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],slot_length_complex_samples_no_prefix,1,1); From aaa3afb722c0fe26deda8dfcb0c39249ac224482 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 21 May 2019 16:02:34 +0200 Subject: [PATCH 24/35] fix in usrp_lib.cpp --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 819a8d0c5b..a56f6c4a16 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -465,14 +465,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, } } - boolean_t first_packet_state=false,last_packet_state=false,first_packet_has_timespec=false; + boolean_t first_packet_state=false,last_packet_state=false; if (flags == 2) { // start of burst // s->tx_md.start_of_burst = true; // s->tx_md.end_of_burst = false; first_packet_state = true; last_packet_state = false; - first_packet_has_timespec=true; } else if (flags == 3) { // end of burst //s->tx_md.start_of_burst = false; //s->tx_md.end_of_burst = true; @@ -483,7 +482,6 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, // s->tx_md.end_of_burst = true; first_packet_state = true; last_packet_state = true; - first_packet_has_timespec=true; } else if (flags==1) { // middle of burst // s->tx_md.start_of_burst = false; // s->tx_md.end_of_burst = false; @@ -497,7 +495,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, first_packet_state=false; last_packet_state=true; } - s->tx_md.has_time_spec = first_packet_has_timespec; + s->tx_md.has_time_spec = true; s->tx_md.start_of_burst = first_packet_state; s->tx_md.end_of_burst = last_packet_state; s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); From 4cd3d635f7383462684e918ffb30c6f9f6ee28dd Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 21 May 2019 19:25:02 +0200 Subject: [PATCH 25/35] more pthread protection in nr-gnb.c --- executables/nr-gnb.c | 11 ++++++++--- executables/nr-ru.c | 2 +- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 9 ++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 78d898cd74..11c8d57feb 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -293,12 +293,12 @@ static void *gNB_L1_thread_tx(void *param) { pthread_mutex_lock( &L1_proc_tx->mutex ); L1_proc_tx->instance_cnt = -1; - pthread_mutex_unlock(&L1_proc_tx->mutex); // the thread can now be woken up if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } + pthread_mutex_unlock(&L1_proc_tx->mutex); wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); @@ -423,18 +423,23 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",500000); + waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",1000000); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); if (waitret == ETIMEDOUT) { - LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 2 slot times (1000us)\n",frame_tx,slot_tx); + LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx); AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); gNB->proc.RU_mask_tx = 0; AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); + proc->instance_cnt_RUs = 0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 6f173109cd..58272eeaa0 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1298,7 +1298,7 @@ static void *ru_thread_tx( void *param ) { if (L1_proc->instance_cnt_RUs==-1) { AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, "ERROR pthread_cond_signal for gNB_L1_thread\n"); - } else AssertFatal(1==0,"gNB TX thread is not ready\n"); + } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); L1_proc->instance_cnt_RUs = 0; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); AssertFatal((ret=pthread_mutex_unlock(&L1_proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index a56f6c4a16..a698ab872b 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -98,6 +98,7 @@ typedef struct { int64_t rx_count; int wait_for_first_pps; int use_gps; + int first_tx; //! timestamp of RX packet openair0_timestamp rx_timestamp; @@ -323,10 +324,10 @@ static int trx_usrp_start(openair0_device *device) { cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); s->tx_md.has_time_spec = true; s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; + s->tx_md.end_of_burst = false;*/ s->rx_count = 0; s->tx_count = 0; s->rx_timestamp = 0; @@ -496,10 +497,12 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, last_packet_state=true; } s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = first_packet_state; + s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; s->tx_md.end_of_burst = last_packet_state; s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_count++; + if (cc>1) { std::vector buff_ptrs; From e84a73f66cc9cd37bd6ad3bf97b7c6fb0a35dc0d Mon Sep 17 00:00:00 2001 From: prasanth Date: Tue, 21 May 2019 23:18:20 +0530 Subject: [PATCH 26/35] this commit includes pucch format0 receiver and testbench for pucch format0 without ofdm. Also it has some fixes to pucch_nr.c --- cmake_targets/CMakeLists.txt | 9 + cmake_targets/build_oai | 2 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 163 +++++++ openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 44 +- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h | 26 +- openair1/SIMULATION/NR_PHY/pucchsim.c | 557 ++++++++++++++++++++++++ 6 files changed, 773 insertions(+), 28 deletions(-) create mode 100644 openair1/PHY/NR_TRANSPORT/pucch_rx.c create mode 100644 openair1/SIMULATION/NR_PHY/pucchsim.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index af9c3edf68..c05f89be9e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1292,6 +1292,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/TOOLS/lut.c ${PHY_POLARSRC} ${PHY_LDPCSRC} + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c # added by prasanth ) set(PHY_NR_UE_SRC @@ -2551,6 +2552,14 @@ add_executable(nr_pbchsim ${T_SOURCE}) target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) +#PUCCH ---> Prashanth +add_executable(nr_pucchsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c + ${OPENAIR_DIR}/common/utils/backtrace.c + ${T_SOURCE}) +target_link_libraries(nr_pucchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) +#PUCCH ---> Prashanth + add_executable(nr_dlsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR_DIR}/common/utils/backtrace.c diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 3bbc1ccb71..4ac63a376f 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -691,7 +691,7 @@ function main() { echo_info "Compiling unitary tests simulators" # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim #simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" - simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim" + simlist="nr_pucchsim dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim" for f in $simlist ; do compilations \ phy_simulators $f \ diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c new file mode 100644 index 0000000000..805a3227a8 --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "PHY/impl_defs_nr.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/NR_UE_TRANSPORT/pucch_nr.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#include "T.h" + + +void nr_decode_pucch0( int32_t **rxdataF, + pucch_GroupHopping_t pucch_GroupHopping, + uint32_t n_id, // hoppingID higher layer parameter + uint8_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, // should come from resource set + uint8_t nrofSymbols, // should come from resource set + uint8_t startingSymbolIndex, // should come from resource set + uint16_t startingPRB, // should come from resource set + uint8_t nr_bit) { // is number of UCI bits to be decoded + int nr_sequences; + uint8_t *mcs; + if(nr_bit==1){ + mcs=table1_mcs; + nr_sequences=4; + } + else if(nr_bit==2){ + mcs=table2_mcs; + nr_sequences=8; + } + /* + * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation + * + */ + /* + * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + */ + // alpha is cyclic shift + double alpha; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + //uint8_t lnormal; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + //uint8_t lprime; + // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME! + //uint8_t mcs; + + /* + * in TS 38.213 Subclause 9.2.1 it is said that: + * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift + * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift + */ + + /* + * Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to: + * x(l*12+n) = r_u_v_alpha_delta(n) + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0;//,delta=0; + // if frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping + // n_hop = 0 + // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + //uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!! + + // x_n contains the sequence r_u_v_alpha_delta(n) + int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24]; + int n,i,l; + for(i=0;i>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))>>15); // Re part of base sequence shifted by alpha + x_n_im[i][(12*l)+n] =(int16_t)((int32_t)(amp)* (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))>>15); // Im part of base sequence shifted by alpha + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", + u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]); + #endif + } + } + } + int16_t r_re[24],r_im[24]; + /* + * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME! + */ + uint32_t re_offset=0; + for (l=0; lN_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); + } + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; + } + if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + for (n=0; n<12; n++){ + if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + r_re[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[0]; + r_im[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[1]; + #ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, + l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]); + #endif + re_offset++; + } + } + double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences]; + memset(corr,0,nr_sequences*sizeof(double)); + memset(corr_re,0,nr_sequences*sizeof(double)); + memset(corr_im,0,nr_sequences*sizeof(double)); + for(i=0;imax_corr){ + index= i; + max_corr=corr[i]; + } + } + *payload=(uint8_t)index; // payload bits 00..b3b2b0, b0 is the SR bit and b3b2 are HARQ bits +} + diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 2327a5036b..f876c8f6c2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -48,14 +48,12 @@ #endif //#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) -void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_nr.puch_GroupHopping, - //uint8_t PUCCH_GroupHopping, - PHY_VARS_NR_UE *ue, - //uint32_t n_id, - uint8_t n_hop, - int nr_tti_tx, - uint8_t *u, - uint8_t *v) { +void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, + uint8_t n_hop, + int nr_tti_tx, + uint8_t *u, + uint8_t *v) { /* * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * The following variables are set by higher layers: @@ -69,12 +67,12 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n * n_hop=1 for the second hop */ // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v - pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!! + //pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!! // n_id defined as per TS 38.211 subclause 6.3.2.2.1 (is given by the higher-layer parameter hoppingId) // it is hoppingId from PUCCH-ConfigCommon: // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) - uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! + //uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! #ifdef DEBUG_NR_PUCCH_TX // initialization to be removed PUCCH_GroupHopping=neither; @@ -84,8 +82,8 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n uint8_t f_ss=0,f_gh=0; *u=0; *v=0; - uint32_t c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v - uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 + uint32_t c_init = 0; + uint32_t x1,s; // TS 38.211 Subclause 5.2.1 int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX @@ -97,6 +95,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n } if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled' + c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 for (int m=0; m<8; m++) { while(minShift >= l) { s = lte_gold_generic(&x1, &c_init, 0); @@ -118,6 +117,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n } if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled' + c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v f_ss = n_id%30; l = 32, minShift = (2*nr_tti_tx+n_hop); @@ -137,7 +137,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n #endif } -double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, +double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t m0, uint8_t mcs, uint8_t lnormal, @@ -153,7 +153,7 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, */ // alpha_init initialized to 2*PI/12=0.5235987756 double alpha = 0.5235987756; - uint32_t c_init = ue->pucch_config_common_nr->hoppingId; // we initialize c_init again to calculate n_cs + uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs #ifdef DEBUG_NR_PUCCH_TX // initialization to be remo.ved c_init=10; @@ -246,8 +246,8 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, for (int l=0; lpucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l); #endif @@ -435,8 +435,8 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", n_hop,nr_tti_tx); #endif - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_tti_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -753,8 +753,8 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", n_hop,nr_tti_tx); #endif - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue,m0,mcs,lnormal,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,lnormal,lprime,nr_tti_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -1571,7 +1571,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop - nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies @@ -1617,7 +1617,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, } uint16_t j=0; - alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx); + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx); for (int rb=0; rbpucch_config_common_nr.puch_GroupHopping, - //uint8_t PUCCH_GroupHopping, - PHY_VARS_NR_UE *ue, - //uint32_t n_id, +void nr_decode_pucch0( int32_t **rxdataF, + pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, //PHY_VARS_gNB *gNB, generally rxdataf is in gNB->common_vars + uint8_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, // should come from resource set + uint8_t nrofSymbols, // should come from resource set + uint8_t startingSymbolIndex, // should come from resource set + uint16_t startingPRB, // should come from resource set + uint8_t nr_bit); + +void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, uint8_t n_hop, int nr_tti_tx, uint8_t *u, uint8_t *v); -double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, +double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t m0, uint8_t mcs, uint8_t lnormal, @@ -111,6 +122,11 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, uint8_t nr_bit, uint8_t occ_length_format4, uint8_t occ_index_format4); + +// tables for mcs values for different payloads + static const uint8_t table1_mcs[]={0,3,6,9}; + static const uint8_t table2_mcs[]={0,1,3,4,6,7,9,10}; + /* * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1) * Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24} diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c new file mode 100644 index 0000000000..cedbc3f4d2 --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -0,0 +1,557 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include +#include +#include + +#include "common/config/config_userapi.h" +#include "common/utils/LOG/log.h" +#include "common/ran_context.h" + +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" +#include "PHY/types.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/defs_gNB.h" +#include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_REFSIG/nr_mod_table.h" +#include "PHY/MODULATION/modulation_eNB.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/INIT/phy_init.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +#include "SCHED_NR/sched_nr.h" + +#include "PHY/NR_UE_TRANSPORT/pucch_nr.h" + + +PHY_VARS_gNB *gNB; +PHY_VARS_NR_UE *UE; +RAN_CONTEXT_t RC; + + +double cpuf; + +// dummy functions +int nfapi_mode=0; +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } + +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} + +uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn) {return(0);} +int32_t get_uldl_offset(int nr_bandP) {return(0);} + +NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} + +void exit_function(const char* file, const char* function, const int line,const char *s) { + const char * msg= s==NULL ? "no comment": s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); +} + +// needed for some functions +PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}}; + +int main(int argc, char **argv) +{ + + char c; + + int i,aa;//,l; + double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; + double cfo=0; + uint8_t snr1set=0; + int **txdata; + double **s_re,**s_im,**r_re,**r_im; + double iqim = 0.0; + double ip =0.0; + unsigned char pbch_pdu[6]; + // int sync_pos, sync_pos_slot; + // FILE *rx_frame_file; + FILE *output_fd = NULL; + uint8_t write_output_file=0; + //int result; + //int freq_offset; + // int subframe_offset; + // char fname[40], vname[40]; + int trial,n_trials=1,n_errors=0,n_errors_payload=0; + uint8_t transmission_mode = 1,n_tx=1,n_rx=1; + uint16_t Nid_cell=0; + + channel_desc_t *gNB2UE; + + uint8_t extended_prefix_flag=0; + int8_t interf1=-21,interf2=-21; + + FILE *input_fd=NULL,*pbch_file_fd=NULL; + + //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; + //char input_val_str[50],input_val_str2[50]; + //uint8_t frame_mod4,num_pdcch_symbols = 0; + //double pbch_sinr; + //int pbch_tx_ant; + + SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + + + int N_RB_DL=273,mu=1; + + unsigned char frame_type = 0; + unsigned char pbch_phase = 0; + + int frame=0,subframe=0; + int frame_length_complex_samples; + int frame_length_complex_samples_no_prefix; + NR_DL_FRAME_PARMS *frame_parms; + nfapi_nr_config_request_t *gNB_config; + + int ret, payload_ret=0; + int run_initial_sync=0; + + int loglvl=OAILOG_WARNING; + + float target_error_rate = 0.01; + + cpuf = get_cpu_freq_GHz(); + + if ( load_configmodule(argc,argv) == 0) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + randominit(0); + + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:o:s:S:t:x:y:z:N:F:GR:dP:IL:")) != -1) { + switch (c) { + case 'f': + write_output_file=1; + output_fd = fopen(optarg,"w"); + + if (output_fd==NULL) { + printf("Error opening %s\n",optarg); + exit(-1); + } + + break; + + case 'd': + frame_type = 1; + break; + + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; + + case 'B': + channel_model=SCM_B; + break; + + case 'C': + channel_model=SCM_C; + break; + + case 'D': + channel_model=SCM_D; + break; + + case 'E': + channel_model=EPA; + break; + + case 'F': + channel_model=EVA; + break; + + case 'G': + channel_model=ETU; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + + break; + + case 'i': + interf1=atoi(optarg); + break; + + case 'j': + interf2=atoi(optarg); + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 'o': + cfo = atof(optarg); + msg("Setting CFO to %f Hz\n",cfo); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; + + /* + case 't': + Td= atof(optarg); + break; + */ + case 'p': + extended_prefix_flag=1; + break; + + /* + case 'r': + ricean_factor = pow(10,-.1*atof(optarg)); + if (ricean_factor>1) { + printf("Ricean factor must be between 0 and 1\n"); + exit(-1); + } + break; + */ + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + + break; + + case 'y': + n_tx=atoi(optarg); + + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } + + break; + + case 'z': + n_rx=atoi(optarg); + + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + + break; + + case 'N': + Nid_cell = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + break; + + case 'F': + input_fd = fopen(optarg,"r"); + + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } + + break; + + case 'P': + pbch_phase = atoi(optarg); + + if (pbch_phase>3) + printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); + + break; + + case 'I': + run_initial_sync=1; + target_error_rate=0.1; + break; + + case 'L': + loglvl = atoi(optarg); + break; + + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-p Use extended prefix mode\n"); + printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-o Carrier frequency offset in Hz\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + // printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; + } + } + + logInit(); + set_glog(loglvl); + T_stdout = 1; + + if (snr1set==0) + snr1 = snr0+10; + + printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL); + + RC.gNB = (PHY_VARS_gNB***) malloc(sizeof(PHY_VARS_gNB **)); + RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); + RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); + gNB = RC.gNB[0][0]; + gNB_config = &gNB->gNB_config; + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + frame_parms->N_RB_DL = N_RB_DL; + frame_parms->N_RB_UL = N_RB_DL; + frame_parms->Nid_cell = Nid_cell; + + nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell); + phy_init_nr_gNB(gNB,0,0); + + double fs,bw,scs,eps; + + if (mu == 1 && N_RB_DL == 217) { + fs = 122.88e6; + bw = 80e6; + scs = 30000; + } + else if (mu == 1 && N_RB_DL == 245) { + fs = 122.88e6; + bw = 90e6; + scs = 30000; + } + else if (mu == 1 && N_RB_DL == 273) { + fs = 122.88e6; + bw = 100e6; + scs = 30000; + } + else if (mu == 1 && N_RB_DL == 106) { + fs = 61.44e6; + bw = 40e6; + scs = 30000; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + + // cfo with respect to sub-carrier spacing + eps = cfo/scs; + + // computation of integer and fractional FO to compare with estimation results + int IFO; + if(eps!=0.0){ + printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); + if (eps>0) + IFO=(int)(eps+0.5); + else + IFO=(int)(eps-0.5); + printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); + } + + gNB2UE = new_channel_desc_scm(n_tx, + n_rx, + channel_model, + fs, + bw, + 0, + 0, + 0); + + if (gNB2UE==NULL) { + msg("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + + s_re = malloc(2*sizeof(double*)); + s_im = malloc(2*sizeof(double*)); + r_re = malloc(2*sizeof(double*)); + r_im = malloc(2*sizeof(double*)); + txdata = malloc(2*sizeof(int*)); + + for (i=0; i<2; i++) { + + s_re[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(s_re[i],frame_length_complex_samples*sizeof(double)); + s_im[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(s_im[i],frame_length_complex_samples*sizeof(double)); + + r_re[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(r_re[i],frame_length_complex_samples*sizeof(double)); + r_im[i] = malloc(frame_length_complex_samples*sizeof(double)); + bzero(r_im[i],frame_length_complex_samples*sizeof(double)); + + printf("Allocating %d samples for txdata\n",frame_length_complex_samples); + txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); + bzero(r_re[i],frame_length_complex_samples*sizeof(int)); + + } + if (pbch_file_fd!=NULL) { + load_pbch_desc(pbch_file_fd); + } + + + //configure UE + UE = malloc(sizeof(PHY_VARS_NR_UE)); + memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + //phy_init_nr_top(UE); //called from init_nr_ue_signal +/* if (run_initial_sync==1) UE->is_synchronized = 0; + else UE->is_synchronized = 1; */ + + UE->perfect_ce = 0; + + if(eps!=0.0) + UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation + + if (init_nr_ue_signal(UE, 1, 0) != 0) + { + printf("Error at UE NR initialisation\n"); + exit(-1); + } + int16_t amp=0x1FFF; + int nr_tti_tx=0; //According to standards it is Slot number within a frame for subcarrier spacing configuration μ but not sure why he made the variable name so 4.3.2,38.211 + nr_gold_pbch(UE); + // generate signal +// pucch_config_common_nr should assign values for this if not done before structure in ue being used by functions + uint8_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 + uint8_t mcs; + int nr_bit=1; +/*if(nr_bit==1){ + mcs=table1_mcs[actual_payload]; + } + else{ + mcs=table2_mcs[actual_payload]; + }*/ + uint8_t m0=0;// higher layer paramater initial cyclic shift + uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 + uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided + uint16_t startingPRB=5; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided + pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping; + uint32_t n_id=UE->pucch_config_common_nr->hoppingId; + printf("\nsnr1=%f\n",snr1); + for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ + n_errors = 0; + n_errors_payload = 0; + sigma2_dB = 20*log10((double)amp/32767)-SNR; + sigma2 = pow(10,sigma2_dB/10); + printf("entering SNR value %f\n",SNR); + for (trial=0; trialpucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); + + for (i=0; i1) + r_re[0][i]=1; + if(r_im[0][i]<-1) + r_im[0][i]=-1; + else if(r_im[0][i]>1) + r_im[0][0]=1; + ((int16_t *)txdata[0])[(i<<1)] = (int16_t)round(r_re[0][i]*32767); + ((int16_t *)txdata[0])[(i<<1)+1] =(int16_t)round(r_im[0][i]*32767); + + } + nr_decode_pucch0(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,nr_bit); + n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; + //printf("actual_payload=%x,payload_received=%x",actual_payload,payload_received); + } + printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,n_errors); + } + for (i=0; i<2; i++) { + free(s_re[i]); + free(s_im[i]); + free(r_re[i]); + free(r_im[i]); + free(txdata[i]); + } + + free(s_re); + free(s_im); + free(r_re); + free(r_im); + free(txdata); + + if (output_fd) + fclose(output_fd); + + if (input_fd) + fclose(input_fd); + + return(n_errors); + +} + + + From 06dcc1095a8dd6833665933b4879144eb8e4b3fa Mon Sep 17 00:00:00 2001 From: prasanth Date: Wed, 22 May 2019 11:26:21 +0530 Subject: [PATCH 27/35] fix for nr_pucchsim --- openair1/SIMULATION/NR_PHY/pucchsim.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index cedbc3f4d2..c5b7d63eaf 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -52,7 +52,7 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; - +openair0_config_t openair0_cfg[MAX_CARDS]; double cpuf; @@ -106,6 +106,7 @@ int main(int argc, char **argv) int trial,n_trials=1,n_errors=0,n_errors_payload=0; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; + uint64_t SSB_positions=0x01; channel_desc_t *gNB2UE; @@ -367,7 +368,7 @@ int main(int argc, char **argv) frame_parms->N_RB_UL = N_RB_DL; frame_parms->Nid_cell = Nid_cell; - nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell); + nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); double fs,bw,scs,eps; From a4426236f1d678082aa3771947e1815c5e18ea99 Mon Sep 17 00:00:00 2001 From: prasanth Date: Wed, 22 May 2019 13:19:08 +0530 Subject: [PATCH 28/35] Fixing critical warnings in pucchsim --- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 4 ++-- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 2 ++ openair1/SIMULATION/NR_PHY/pucchsim.c | 20 ++------------------ 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 805a3227a8..3513c198cb 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -31,12 +31,12 @@ void nr_decode_pucch0( int32_t **rxdataF, uint16_t startingPRB, // should come from resource set uint8_t nr_bit) { // is number of UCI bits to be decoded int nr_sequences; - uint8_t *mcs; + const uint8_t *mcs; if(nr_bit==1){ mcs=table1_mcs; nr_sequences=4; } - else if(nr_bit==2){ + else{ mcs=table2_mcs; nr_sequences=8; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index accf663e9d..2771874bd3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -96,6 +96,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled' c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211 + s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 for (int m=0; m<8; m++) { while(minShift >= l) { s = lte_gold_generic(&x1, &c_init, 0); @@ -118,6 +119,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled' c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v + s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 f_ss = n_id%30; l = 32, minShift = (2*nr_tti_tx+n_hop); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index c5b7d63eaf..19e0e7dc25 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -92,9 +92,6 @@ int main(int argc, char **argv) uint8_t snr1set=0; int **txdata; double **s_re,**s_im,**r_re,**r_im; - double iqim = 0.0; - double ip =0.0; - unsigned char pbch_pdu[6]; // int sync_pos, sync_pos_slot; // FILE *rx_frame_file; FILE *output_fd = NULL; @@ -103,7 +100,7 @@ int main(int argc, char **argv) //int freq_offset; // int subframe_offset; // char fname[40], vname[40]; - int trial,n_trials=1,n_errors=0,n_errors_payload=0; + int trial,n_trials=1,n_errors=0; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; uint64_t SSB_positions=0x01; @@ -135,13 +132,8 @@ int main(int argc, char **argv) NR_DL_FRAME_PARMS *frame_parms; nfapi_nr_config_request_t *gNB_config; - int ret, payload_ret=0; - int run_initial_sync=0; - int loglvl=OAILOG_WARNING; - float target_error_rate = 0.01; - cpuf = get_cpu_freq_GHz(); if ( load_configmodule(argc,argv) == 0) { @@ -307,11 +299,6 @@ int main(int argc, char **argv) printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); break; - - case 'I': - run_initial_sync=1; - target_error_rate=0.1; - break; case 'L': loglvl = atoi(optarg); @@ -458,8 +445,6 @@ int main(int argc, char **argv) UE = malloc(sizeof(PHY_VARS_NR_UE)); memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); //phy_init_nr_top(UE); //called from init_nr_ue_signal -/* if (run_initial_sync==1) UE->is_synchronized = 0; - else UE->is_synchronized = 1; */ UE->perfect_ce = 0; @@ -478,7 +463,7 @@ int main(int argc, char **argv) // pucch_config_common_nr should assign values for this if not done before structure in ue being used by functions uint8_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 uint8_t mcs; - int nr_bit=1; + int nr_bit=1; // maximum value possible is 2 /*if(nr_bit==1){ mcs=table1_mcs[actual_payload]; } @@ -494,7 +479,6 @@ int main(int argc, char **argv) printf("\nsnr1=%f\n",snr1); for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ n_errors = 0; - n_errors_payload = 0; sigma2_dB = 20*log10((double)amp/32767)-SNR; sigma2 = pow(10,sigma2_dB/10); printf("entering SNR value %f\n",SNR); From e0c76c5a6bec6b793ca844c59c14a55236169317 Mon Sep 17 00:00:00 2001 From: prasanth Date: Wed, 22 May 2019 16:23:23 +0530 Subject: [PATCH 29/35] CI fix --- ci-scripts/oai-ci-vm-tool | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 3d9fb87cba..f5ede896a7 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -252,7 +252,7 @@ case $key in VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim LOG_PATTERN=.Rel15.txt - NB_PATTERN_FILES=10 + NB_PATTERN_FILES=11 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" @@ -331,7 +331,7 @@ case $key in VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim LOG_PATTERN=.Rel15.txt - NB_PATTERN_FILES=10 + NB_PATTERN_FILES=11 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" From 21abb9a4b94196ff322729e6c211d90e8ba34e42 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 23 May 2019 06:50:24 +0200 Subject: [PATCH 30/35] attempting to fix regression problems --- executables/openairinterface5g_limits.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/executables/openairinterface5g_limits.h b/executables/openairinterface5g_limits.h index ca29078758..53ee79a61d 100644 --- a/executables/openairinterface5g_limits.h +++ b/executables/openairinterface5g_limits.h @@ -8,10 +8,10 @@ #define NUMBER_OF_NR_RU_MAX 2 #ifndef PHYSIM #ifndef UE_EXPANSION - #define NUMBER_OF_UE_MAX 4 - #define NUMBER_OF_NR_UE_MAX 4 - #define NUMBER_OF_CONNECTED_eNB_MAX 1 - #define NUMBER_OF_CONNECTED_gNB_MAX 1 + #define NUMBER_OF_UE_MAX 16 + #define NUMBER_OF_NR_UE_MAX 16 + #define NUMBER_OF_CONNECTED_eNB_MAX 3 + #define NUMBER_OF_CONNECTED_gNB_MAX 3 #else #define NUMBER_OF_UE_MAX 256 #define NUMBER_OF_NR_UE_MAX 256 From e0b7efb596915858d3fe8a24a3608375ceb4a587 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 27 May 2019 00:28:58 +0200 Subject: [PATCH 31/35] fixing regression in dlsim --- openair1/SIMULATION/LTE_PHY/dlsim.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3807c51b96..5e3f7e2df6 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -68,8 +68,8 @@ #include "PHY/INIT/phy_init.h" -void feptx_ofdm(RU_t *ru); -void feptx_prec(RU_t *ru); +void feptx_ofdm(RU_t *ru,int frame,int subframe); +void feptx_prec(RU_t *ru,int frame,int subframe); double cpuf; @@ -1440,6 +1440,7 @@ int main(int argc, char **argv) } eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]]; + proc_eNB->frame_tx = 0; if (input_fd==NULL) { @@ -1652,8 +1653,8 @@ int main(int argc, char **argv) ru->proc.tti_tx=subframe; memcpy((void*)ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - feptx_prec(ru); - feptx_ofdm(ru); + feptx_prec(ru,proc_eNB->frame_tx,subframe); + feptx_ofdm(ru,proc_eNB->frame_tx,subframe); stop_meas(&eNB->ofdm_mod_stats); @@ -1671,8 +1672,8 @@ int main(int argc, char **argv) ru->proc.tti_tx=(subframe+1)%10; - feptx_prec(ru); - feptx_ofdm(ru); + feptx_prec(ru,proc_eNB->frame_tx,subframe+1); + feptx_ofdm(ru,proc_eNB->frame_tx,subframe+1); proc_eNB->frame_tx++; From 8e77370dd8da1308dd9e2635461765faae8aeea4 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 29 May 2019 04:41:13 +0200 Subject: [PATCH 32/35] removing nr-softmodem files from targets/RT/USER --- executables/nr-softmodem.c | 2 + targets/RT/USER/nr-gnb.c | 1018 ------------- targets/RT/USER/nr-ru.c | 2438 -------------------------------- targets/RT/USER/nr-softmodem.c | 1328 ----------------- targets/RT/USER/nr-softmodem.h | 253 ---- 5 files changed, 2 insertions(+), 5037 deletions(-) delete mode 100644 targets/RT/USER/nr-gnb.c delete mode 100644 targets/RT/USER/nr-ru.c delete mode 100644 targets/RT/USER/nr-softmodem.c delete mode 100644 targets/RT/USER/nr-softmodem.h diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 93a0b9fc04..d02ca100a1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -976,6 +976,8 @@ int main( int argc, char **argv ) { exit(-1); } + openair0_cfg[0].threequarter_fs = threequarter_fs; + #if T_TRACER T_Config_Init(); #endif diff --git a/targets/RT/USER/nr-gnb.c b/targets/RT/USER/nr-gnb.c deleted file mode 100644 index 77d4dea5e7..0000000000 --- a/targets/RT/USER/nr-gnb.c +++ /dev/null @@ -1,1018 +0,0 @@ -/*/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file lte-enb.c - * \brief Top-level threads for gNodeB - * \author R. Knopp, F. Kaltenberger, Navid Nikaein - * \date 2012 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr - * \note - * \warning - */ - -#define _GNU_SOURCE -#include - -#include "time_utils.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "rt_wrapper.h" - -#include "assertions.h" - - -#include "PHY/types.h" - -#include "PHY/INIT/phy_init.h" - -#include "PHY/defs_gNB.h" -#include "SCHED/sched_eNB.h" -#include "SCHED_NR/sched_nr.h" -#include "SCHED_NR/fapi_nr_l1.h" -#include "PHY/LTE_TRANSPORT/transport_proto.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "../../ARCH/COMMON/common_lib.h" - -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" - -#include "PHY/phy_extern.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 "PHY_INTERFACE/phy_interface.h" -#include "common/utils/LOG/log_extern.h" -#include "UTIL/OTG/otg_tx.h" -#include "UTIL/OTG/otg_externs.h" -#include "UTIL/MATH/oml.h" -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "enb_config.h" - - -#ifndef OPENAIR2 -#include "UTIL/OTG/otg_extern.h" -#endif - -#if defined(ENABLE_ITTI) -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -# include "SIMULATION/ETH_TRANSPORT/proto.h" -#endif -# endif -#endif - -#include "T.h" - -//#define DEBUG_THREADS 1 - -//#define USRP_DEBUG 1 -struct timing_info_t { - //unsigned int frame, hw_slot, last_slot, next_slot; - RTIME time_min, time_max, time_avg, time_last, time_now; - //unsigned int mbox0, mbox1, mbox2, mbox_target; - unsigned int n_samples; -} timing_info; - -// Fix per CC openair rf/if device update -// extern openair0_device openair0; - - -#if defined(ENABLE_ITTI) -extern volatile int start_gNB; -extern volatile int start_UE; -#endif -extern volatile int oai_exit; - -extern openair0_config_t openair0_cfg[MAX_CARDS]; - -extern int transmission_mode; - -uint16_t sl_ahead=4; -uint16_t sf_ahead=4; -//pthread_t main_gNB_thread; - -time_stats_t softmodem_stats_mt; // main thread -time_stats_t softmodem_stats_hw; // hw acquisition -time_stats_t softmodem_stats_rxtx_sf; // total tx time -time_stats_t nfapi_meas; // total tx time -time_stats_t softmodem_stats_rx_sf; // total rx time - -/* mutex, cond and variable to serialize phy proc TX calls - * (this mechanism may be relaxed in the future for better - * performances) - */ -static struct { - pthread_mutex_t mutex_phy_proc_tx; - pthread_cond_t cond_phy_proc_tx; - volatile uint8_t phy_proc_CC_id; -} sync_phy_proc; - -extern double cpuf; - -void init_gNB(int,int); -void stop_gNB(int nb_inst); - -int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx); -int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx); -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); - - -void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe); - -extern uint8_t nfapi_mode; -extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); -extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); - -//#define TICK_TO_US(ts) (ts.diff) -#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) - - -static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { - start_meas(&softmodem_stats_rxtx_sf); - - // ******************************************************************* - - if (nfapi_mode == 1) { - - // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - - //add_subframe(&frame, &subframe, 4); - - start_meas(&nfapi_meas); - oai_subframe_ind(frame_rx, slot_rx); - stop_meas(&nfapi_meas); - - if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| - gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || - gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || - gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || - gNB->UL_INFO.cqi_ind.number_of_cqis - ) { - LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d \n", - NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, - NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, - NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, - NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, - gNB->UL_INFO.cqi_ind.number_of_cqis, - frame_rx, slot_rx); - } - } - - /// NR disabling - - // **************************************** - // Common RX procedures subframe n - - T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); -/* - // if this is IF5 or 3GPP_gNB - if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { - wakeup_prach_gNB(gNB,NULL,frame_rx,slot_rx); - } - - // UE-specific RX processing for subframe n - if (nfapi_mode == 0 || nfapi_mode == 1) { - phy_procedures_gNB_uespec_RX(gNB, frame_rx,slot_rx, no_relay ); - } -*/ - pthread_mutex_lock(&gNB->UL_INFO_mutex); - - gNB->UL_INFO.frame = frame_rx; - gNB->UL_INFO.slot = slot_rx; - gNB->UL_INFO.module_id = gNB->Mod_id; - gNB->UL_INFO.CC_id = gNB->CC_id; - - gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); - - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - -/// end - // ***************************************** - // TX processing for subframe n+sl_ahead - // run PHY TX procedures the one after the other for all CCs to avoid race conditions - // (may be relaxed in the future for performance reasons) - // ***************************************** - //if (wait_CCs(proc)<0) return(-1); - - if (oai_exit) return(-1); - if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - - stop_meas( &softmodem_stats_rxtx_sf ); - - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); - - - return(0); -} - -static void* gNB_L1_thread_tx(void* param) { - - PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param; - gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; - - - char thread_name[100]; - - // This tells L1_thread (RX) that L1_thread_tx is not ready yet - pthread_mutex_lock(&L1_proc_tx->mutex); - L1_proc_tx->instance_cnt = -2; - pthread_mutex_unlock(&L1_proc_tx->mutex); - - sprintf(thread_name,"gNB_L1_thread_tx\n"); - - thread_top_init(thread_name,1,870000L,1000000L,1000000L); - - pthread_mutex_lock(&L1_proc_tx->mutex); - L1_proc_tx->instance_cnt++; - pthread_mutex_unlock(&L1_proc_tx->mutex); - - while (!oai_exit) { - - if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 ); - if (oai_exit) break; - // ***************************************** - // TX processing for subframe n+4 - // run PHY TX procedures the one after the other for all CCs to avoid race conditions - // (may be relaxed in the future for performance reasons) - // ***************************************** - int frame_tx = L1_proc_tx->frame_tx; - int slot_tx = L1_proc_tx->slot_tx; - uint64_t timestamp_tx = L1_proc_tx->timestamp_tx; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); - - phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - - pthread_mutex_lock( &L1_proc_tx->mutex ); - L1_proc_tx->instance_cnt = -1; - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for L1_threa_tx\n"); - exit_fun( "ERROR pthread_cond_signal" ); - } - pthread_mutex_unlock( &L1_proc_tx->mutex ); - wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); - } - - return 0; -} - -/*! - * \brief The RX UE-specific and TX thread of gNB. - * \param param is a \ref gNB_L1_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* gNB_L1_thread( void* param ) { - - static int gNB_thread_rxtx_status; - PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)param; - gNB_L1_proc_t *gNB_proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc; - - - char thread_name[100]; - - // This tells ru_thread that L1_thread is not ready - pthread_mutex_lock(&L1_proc->mutex); - L1_proc->instance_cnt = -2; - pthread_mutex_unlock(&L1_proc->mutex); - - // set default return value - gNB_thread_rxtx_status = 0; - - - sprintf(thread_name,"gNB_L1_thread"); - - thread_top_init(thread_name,1,870000L,1000000L,1000000L); - - // This tells ru_thread that L1_thread is ready - pthread_mutex_lock(&L1_proc->mutex); - L1_proc->instance_cnt++; - pthread_mutex_unlock(&L1_proc->mutex); - - while (!oai_exit) { - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 ); - if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 ); - - int frame_rx = L1_proc->frame_rx; - int slot_rx = L1_proc->slot_rx; - int frame_tx = L1_proc->frame_tx; - int slot_tx = L1_proc->slot_tx; - uint64_t timestamp_tx = L1_proc->timestamp_tx; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx); - - if (oai_exit) break; - - if (gNB->CC_id==0) - { - if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break; - - } - if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break; - - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx); - - - } // while !oai_exit - - - LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n"); - - gNB_thread_rxtx_status = 0; - return &gNB_thread_rxtx_status; -} - - -#if 0 //defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) -// Wait for gNB application initialization to be complete (gNB registration to MME) -static void wait_system_ready (char *message, volatile int *start_flag) { - - static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", - " ....", " ...", " ..", " .", " "}; - int i = 0; - - while ((!oai_exit) && (*start_flag == 0)) { - LOG_N(EMU, message, indicator[i]); - fflush(stdout); - i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0])); - usleep(200000); - } - - LOG_D(EMU,"\n"); -} -#endif - - - - - -void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) -{ - gNB_L1_proc_t *proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *ru_proc=&ru->proc; - - proc->frame_rx = frame_rx; - proc->slot_rx = slot_rx; - - if (!oai_exit) { - T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx)); - - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - - if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id); - ru_proc->timestamp_tx = L1_proc->timestamp_tx; - ru_proc->tti_tx = L1_proc->slot_tx; - ru_proc->frame_tx = L1_proc->frame_tx; - } -} - -int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - - RU_t *ru; - RU_proc_t *ru_proc; - - int waitret; - struct timespec wait; - wait.tv_sec=0; - wait.tv_nsec=10000000L; - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); - -// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time - waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",500000); - - if (waitret == ETIMEDOUT) { - LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 2 slot times (1000us)\n",frame_tx,slot_tx); - - pthread_mutex_lock(&gNB->proc.mutex_RU_tx); - gNB->proc.RU_mask_tx = 0; - pthread_mutex_unlock(&gNB->proc.mutex_RU_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0); - - return(-1); - } - else if (release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); - - for(int i=0; inum_RU; i++) - { - ru = gNB->RU_list[i]; - ru_proc = &ru->proc; - if (ru_proc->instance_cnt_gNBs == 0) { - LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx); - pthread_mutex_lock(&gNB->proc.mutex_RU_tx); - gNB->proc.RU_mask_tx = 0; - pthread_mutex_unlock(&gNB->proc.mutex_RU_tx); - return(-1); - } - if ((waitret = pthread_mutex_timedlock(&ru_proc->mutex_gNBs,&wait)) == ETIMEDOUT) { - LOG_W( PHY, "[eNB] ERROR pthread_mutex_lock timed out on mutex_gNBs L1_thread_tx (timeout)\n"); - return(-1); - } - else AssertFatal(waitret==0,"pthread_mutex_timedlock returned %d\n",waitret); - - ru_proc->instance_cnt_gNBs = 0; - ru_proc->timestamp_tx = timestamp_tx; - ru_proc->tti_tx = slot_tx; - ru_proc->frame_tx = frame_tx; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs); - pthread_mutex_unlock( &ru_proc->mutex_gNBs ); - - LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx); - // the thread can now be woken up - if (pthread_cond_signal(&ru_proc->cond_gNBs) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - } - - return(0); -} - -int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - - - gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; - - - struct timespec wait; - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - - if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) { - LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n"); - exit_fun("ERROR pthread_lock"); - return(-1); - } - if (L1_proc_tx->instance_cnt == -2) { // L1_thread_tx isn't ready yet so return - pthread_mutex_unlock( &L1_proc_tx->mutex); - return(0); - } - - while(L1_proc_tx->instance_cnt == 0){ - pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex); - } - - L1_proc_tx->instance_cnt = 0; - - - L1_proc_tx->slot_rx = slot_rx; - L1_proc_tx->frame_rx = frame_rx; - L1_proc_tx->slot_tx = slot_tx; - L1_proc_tx->frame_tx = frame_tx; - L1_proc_tx->timestamp_tx = timestamp_tx; - - pthread_mutex_unlock( &L1_proc_tx->mutex); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0); - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - - return(0); -} - -int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { - - gNB_L1_proc_t *proc=&gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - RU_proc_t *ru_proc=&ru->proc; - - int i; - struct timespec wait; - - pthread_mutex_lock(&proc->mutex_RU); - for (i=0;inum_RU;i++) { - if (ru == gNB->RU_list[i]) { - if ((proc->RU_mask&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask); - proc->RU_mask |= (1<RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return - LOG_E(PHY,"Not all RUs have provided their info\n"); - pthread_mutex_unlock(&proc->mutex_RU); - return(0); - } - else { // all RUs have provided their information so continue on and wakeup gNB processing - proc->RU_mask = 0; - pthread_mutex_unlock(&proc->mutex_RU); - } - - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - // wake up TX for subframe n+sl_ahead - // lock the TX mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB L1 thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt ); - exit_fun( "error locking mutex" ); - return(-1); - } - - if (L1_proc->instance_cnt==-2) { // L1_thread isn't ready yet so return - pthread_mutex_unlock( &L1_proc->mutex ); - return(0); - } - - if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe - pthread_mutex_unlock( &L1_proc->mutex ); - LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); - } - - ++L1_proc->instance_cnt; - - // 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). - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti, - // and proc->slot_tx = proc->slot_rx+sl_ahead - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - - LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead); - - pthread_mutex_unlock( &L1_proc->mutex ); - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - return(0); -} -/* -void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) { - - gNB_L1_proc_t *proc = &gNB->proc; - LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms; - int i; - - if (ru!=NULL) { - pthread_mutex_lock(&proc->mutex_RU_PRACH); - for (i=0;inum_RU;i++) { - if (ru == gNB->RU_list[i]) { - LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU); - if ((proc->RU_mask_prach&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n", - gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach); - proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return - pthread_mutex_unlock(&proc->mutex_RU_PRACH); - return; - } - else { // all RUs have provided their information so continue on and wakeup gNB processing - proc->RU_mask_prach = 0; - pthread_mutex_unlock(&proc->mutex_RU_PRACH); - } - } - - // check if we have to detect PRACH first - if (is_prach_subframe(fp,frame,subframe)>0) { - LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe); - if (proc->instance_cnt_prach == 0) { - LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe); - return; - } - - // wake up thread for PRACH RX - if (pthread_mutex_lock(&proc->mutex_prach) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach); - exit_fun( "error locking mutex_prach" ); - return; - } - - ++proc->instance_cnt_prach; - // set timing for prach thread - proc->frame_prach = frame; - proc->subframe_prach = subframe; - - // the thread can now be woken up - if (pthread_cond_signal(&proc->cond_prach) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - - pthread_mutex_unlock( &proc->mutex_prach ); - } - -}*/ - -/*! - * \brief The prach receive thread of gNB. - * \param param is a \ref gNB_L1_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* gNB_thread_prach( void* param ) { - static int gNB_thread_prach_status; - - - PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param; - gNB_L1_proc_t *proc = &gNB->proc; - - // set default return value - gNB_thread_prach_status = 0; - - thread_top_init("gNB_thread_prach",1,500000L,1000000L,20000000L); - - - while (!oai_exit) { - - if (oai_exit) break; - - - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break; - - LOG_D(PHY,"Running gNB prach procedures\n"); - prach_procedures(gNB -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 -#endif - ); - - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting gNB thread PRACH\n"); - - gNB_thread_prach_status = 0; - return &gNB_thread_prach_status; -} -*/ - -extern void init_td_thread(PHY_VARS_gNB *, pthread_attr_t *); -extern void init_te_thread(PHY_VARS_gNB *, pthread_attr_t *); - -void init_gNB_proc(int inst) { - - int i=0; - int CC_id; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *proc; - gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx; - pthread_attr_t *attr0=NULL,*attr1=NULL; - //*attr_prach=NULL; - - LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]); - - for (CC_id=0; CC_idproc; - - L1_proc = &proc->L1_proc; - L1_proc_tx = &proc->L1_proc_tx; - L1_proc->instance_cnt = -2; - L1_proc_tx->instance_cnt = -2; - L1_proc->instance_cnt_RUs = 0; - L1_proc_tx->instance_cnt_RUs = 0; - proc->instance_cnt_prach = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->CC_id = CC_id; - - proc->first_rx =1; - proc->first_tx =1; - proc->RU_mask =0; - proc->RU_mask_tx = (1<num_RU)-1; - proc->RU_mask_prach =0; - - pthread_mutex_init( &gNB->UL_INFO_mutex, NULL); - pthread_mutex_init( &L1_proc->mutex, NULL); - pthread_mutex_init( &L1_proc_tx->mutex, NULL); - pthread_cond_init( &L1_proc->cond, NULL); - pthread_cond_init( &L1_proc_tx->cond, NULL); - - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_RU,NULL); - pthread_mutex_init( &proc->mutex_RU_tx,NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); - - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - - pthread_attr_init( &proc->attr_prach); - pthread_attr_init( &proc->attr_asynch_rxtx); - // pthread_attr_init( &proc->attr_td); - // pthread_attr_init( &proc->attr_te); - pthread_attr_init( &L1_proc->attr); - pthread_attr_init( &L1_proc_tx->attr); - attr0 = &L1_proc->attr; - attr1 = &L1_proc_tx->attr; - - LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); - - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - pthread_create( &L1_proc->pthread, attr0, gNB_L1_thread, gNB ); - pthread_create( &L1_proc_tx->pthread, attr1, gNB_L1_thread_tx, gNB); - } - //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB ); - - char name[16]; - if (gNB->single_thread_flag==0) { - snprintf( name, sizeof(name), "L1 %d", i ); - pthread_setname_np( L1_proc->pthread, name ); - snprintf( name, sizeof(name), "L1TX %d", i ); - pthread_setname_np( L1_proc_tx->pthread, name ); - } - - AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); - - - } - - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; -} - - - -/*! - * \brief Terminate gNB TX and RX threads. - */ -void kill_gNB_proc(int inst) { - - int *status; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *proc; - gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx; - for (int CC_id=0; CC_idproc; - L1_proc = &proc->L1_proc; - L1_proc_tx = &proc->L1_proc_tx; - - LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - pthread_mutex_lock(&L1_proc->mutex); - L1_proc->instance_cnt = 0; - pthread_cond_signal(&L1_proc->cond); - pthread_mutex_unlock(&L1_proc->mutex); - - pthread_mutex_lock(&L1_proc_tx->mutex); - L1_proc_tx->instance_cnt = 0; - pthread_cond_signal(&L1_proc_tx->cond); - pthread_mutex_unlock(&L1_proc_tx->mutex); - } - proc->instance_cnt_prach = 0; - pthread_cond_signal( &proc->cond_prach ); - - pthread_cond_signal( &proc->cond_asynch_rxtx ); - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - -// LOG_D(PHY, "joining pthread_prach\n"); -// pthread_join( proc->pthread_prach, (void**)&status ); - - LOG_I(PHY, "Destroying prach mutex/cond\n"); - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); - - LOG_I(PHY, "Destroying UL_INFO mutex\n"); - pthread_mutex_destroy(&gNB->UL_INFO_mutex); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - LOG_I(PHY, "Joining L1_proc mutex/cond\n"); - pthread_join( L1_proc->pthread, (void**)&status ); - LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n"); - pthread_join( L1_proc_tx->pthread, (void**)&status ); - } - LOG_I(PHY, "Destroying L1_proc mutex/cond\n"); - pthread_mutex_destroy( &L1_proc->mutex ); - pthread_cond_destroy( &L1_proc->cond ); - LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n"); - pthread_mutex_destroy( &L1_proc_tx->mutex ); - pthread_cond_destroy( &L1_proc_tx->cond ); - - - pthread_mutex_destroy( &proc->mutex_RU ); - pthread_mutex_destroy( &proc->mutex_RU_tx ); - } -} - - - - -void reset_opp_meas(void) { - - int sfn; - reset_meas(&softmodem_stats_mt); - reset_meas(&softmodem_stats_hw); - - for (sfn=0; sfn < 10; sfn++) { - reset_meas(&softmodem_stats_rxtx_sf); - reset_meas(&softmodem_stats_rx_sf); - } -} - - -void print_opp_meas(void) { - - int sfn=0; - print_meas(&softmodem_stats_mt, "Main gNB Thread", NULL, NULL); - print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); - - for (sfn=0; sfn < 10; sfn++) { - print_meas(&softmodem_stats_rxtx_sf,"[gNB][total_phy_proc_rxtx]",NULL, NULL); - print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL); - } -} - - -/// eNB kept in function name for nffapi calls, TO FIX -void init_eNB_afterRU(void) { - - int inst,CC_id,ru_id,i,aa; - PHY_VARS_gNB *gNB; - - LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst); - - for (inst=0;instnum_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id); - LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id); - - //LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]); - - //gNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); - - LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU); - - for (ru_id=0,aa=0;ru_idnum_RU;ru_id++) { - - AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL, - "RU %d : common.rxdataF is NULL\n", - gNB->RU_list[ru_id]->idx); - - AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL, - "RU %d : prach_rxsigF is NULL\n", - gNB->RU_list[ru_id]->idx); - - for (i=0;iRU_list[ru_id]->nb_rx;aa++,i++) { - LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); -// gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i]; - gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; - } - } - - - - /* TODO: review this code, there is something wrong. - * In monolithic mode, we come here with nb_antennas_rx == 0 - * (not tested in other modes). - */ - - //init_precoding_weights(RC.gNB[inst][CC_id]); - } - init_gNB_proc(inst); - } - - for (ru_id=0;ru_idnr_wakeup_rxtx = wakeup_rxtx; -// RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_gNB; - RC.ru[ru_id]->gNB_top = gNB_top; - } -} - -void init_gNB(int single_thread_flag,int wait_for_sync) { - - int CC_id; - int inst; - PHY_VARS_gNB *gNB; - - LOG_I(PHY,"[nr-softmodem.c] gNB structure about to allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]); - - if (RC.gNB == NULL) RC.gNB = (PHY_VARS_gNB***) malloc(RC.nb_nr_L1_inst*sizeof(PHY_VARS_gNB **)); - LOG_I(PHY,"[lte-softmodem.c] gNB structure RC.gNB allocated\n"); - for (inst=0;instabstraction_flag = 0; - gNB->single_thread_flag = single_thread_flag; - /*nr_polar_init(&gNB->nrPolar_params, - NR_POLAR_PBCH_MESSAGE_TYPE, - NR_POLAR_PBCH_PAYLOAD_BITS, - NR_POLAR_PBCH_AGGREGATION_LEVEL);*/ - - LOG_I(PHY,"Initializing gNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag); -#ifndef OCP_FRAMEWORK - LOG_I(PHY,"Initializing gNB %d CC_id %d\n",inst,CC_id); -#endif - - LOG_I(PHY,"Registering with MAC interface module\n"); - AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface"); - gNB->if_inst->NR_Schedule_response = nr_schedule_response; - gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; - memset((void*)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); - memset((void*)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); - LOG_I(PHY,"Setting indication lists\n"); - gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; - gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list; - gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list; - gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; - gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; - gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list; - gNB->prach_energy_counter = 0; - } - - } - - LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n"); -} - - -void stop_gNB(int nb_inst) { - - for (int inst=0;inst. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - -*******************************************************************************/ - -/*! \file lte-enb.c - * \brief Top-level threads for eNodeB - * \author R. Knopp, F. Kaltenberger, Navid Nikaein - * \date 2012 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr - * \note - * \warning - */ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rt_wrapper.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "assertions.h" -#include "msc.h" - -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" - -#include "PHY/LTE_TRANSPORT/if4_tools.h" -#include "PHY/LTE_TRANSPORT/if5_tools.h" - -#include "PHY/types.h" -#include "PHY/defs_nr_common.h" -#include "PHY/phy_extern.h" -#include "PHY/LTE_TRANSPORT/transport_proto.h" -#include "PHY/INIT/phy_init.h" -#include "SCHED/sched_eNB.h" -#include "SCHED_NR/sched_nr.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 "PHY_INTERFACE/phy_interface.h" - -#include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" - -#include "enb_config.h" - -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif - -/* these variables have to be defined before including ENB_APP/enb_paramdef.h */ -static int DEFBANDS[] = {7}; -static int DEFENBS[] = {0}; - -#include "ENB_APP/enb_paramdef.h" -#include "common/config/config_userapi.h" - -#ifndef OPENAIR2 -#include "UTIL/OTG/otg_extern.h" -#endif - -#if defined(ENABLE_ITTI) -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -# include "SIMULATION/ETH_TRANSPORT/proto.h" -#endif -# endif -#endif - -#include "T.h" -#include "nfapi_interface.h" - -extern volatile int oai_exit; - - -extern void nr_phy_init_RU(RU_t*); -extern void nr_phy_free_RU(RU_t*); -extern void nr_phy_config_request(NR_PHY_Config_t *gNB); - -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); - -void init_RU(char*); -void stop_RU(int nb_ru); -void do_ru_sync(RU_t *ru); - -void configure_ru(int idx, - void *arg); - -void configure_rru(int idx, - void *arg); - -int attach_rru(RU_t *ru); - -int connect_rau(RU_t *ru); - -extern uint16_t sl_ahead; - -extern int emulate_rf; -extern int numerology; - -/*************************************************************/ -/* Functions to attach and configure RRU */ - -extern void wait_gNBs(void); - -int attach_rru(RU_t *ru) { - - ssize_t msg_len,len; - RRU_CONFIG_msg_t rru_config_msg; - int received_capabilities=0; - - wait_gNBs(); - // Wait for capabilities - while (received_capabilities==0) { - - memset((void*)&rru_config_msg,0,sizeof(rru_config_msg)); - rru_config_msg.type = RAU_tick; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; - LOG_I(PHY,"Sending RAU tick to RRU %d\n",ru->idx); - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d cannot access remote radio\n",ru->idx); - - msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - - // wait for answer with timeout - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { - LOG_I(PHY,"Waiting for RRU %d\n",ru->idx); - } - else if (rru_config_msg.type == RRU_capabilities) { - AssertFatal(rru_config_msg.len==msg_len,"Received capabilities with incorrect length (%d!=%d)\n",(int)rru_config_msg.len,(int)msg_len); - LOG_I(PHY,"Received capabilities from RRU %d (len %d/%d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n",ru->idx, - (int)rru_config_msg.len,(int)msg_len, - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->num_bands, - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->max_pdschReferenceSignalPower[0], - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->max_rxgain[0], - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->nb_tx[0], - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->nb_rx[0]); - received_capabilities=1; - } - else { - LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); - } - } - configure_ru(ru->idx, - (RRU_capabilities_t *)&rru_config_msg.msg[0]); - - rru_config_msg.type = RRU_config; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); - LOG_I(PHY,"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",ru->idx, - ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); - - - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d failed send configuration to remote radio\n",ru->idx); - - return 0; -} - -int connect_rau(RU_t *ru) { - - RRU_CONFIG_msg_t rru_config_msg; - ssize_t msg_len; - int tick_received = 0; - int configuration_received = 0; - RRU_capabilities_t *cap; - int i; - int len; - - // wait for RAU_tick - while (tick_received == 0) { - - msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; - - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { - LOG_I(PHY,"Waiting for RAU\n"); - } - else { - if (rru_config_msg.type == RAU_tick) { - LOG_I(PHY,"Tick received from RAU\n"); - tick_received = 1; - } - else LOG_E(PHY,"Received erroneous message (%d)from RAU, expected RAU_tick\n",rru_config_msg.type); - } - } - - // send capabilities - - rru_config_msg.type = RRU_capabilities; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - cap = (RRU_capabilities_t*)&rru_config_msg.msg[0]; - LOG_I(PHY,"Sending Capabilities (len %d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n", - (int)rru_config_msg.len,ru->num_bands,ru->max_pdschReferenceSignalPower,ru->max_rxgain,ru->nb_tx,ru->nb_rx); - switch (ru->function) { - case NGFI_RRU_IF4p5: - cap->FH_fmt = OAI_IF4p5_only; - break; - case NGFI_RRU_IF5: - cap->FH_fmt = OAI_IF5_only; - break; - case MBP_RRU_IF5: - cap->FH_fmt = MBP_IF5; - break; - default: - AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function); - break; - } - cap->num_bands = ru->num_bands; - for (i=0;inum_bands;i++) { - LOG_I(PHY,"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d\n", - ru->band[i],ru->nb_rx,ru->nb_tx,ru->max_pdschReferenceSignalPower,ru->max_rxgain); - cap->band_list[i] = ru->band[i]; - cap->nb_rx[i] = ru->nb_rx; - cap->nb_tx[i] = ru->nb_tx; - cap->max_pdschReferenceSignalPower[i] = ru->max_pdschReferenceSignalPower; - cap->max_rxgain[i] = ru->max_rxgain; - } - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d failed send capabilities to RAU\n",ru->idx); - - // wait for configuration - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); - while (configuration_received == 0) { - - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - rru_config_msg.len))<0) { - LOG_I(PHY,"Waiting for configuration from RAU\n"); - } - else { - LOG_I(PHY,"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n", - ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); - - configure_rru(ru->idx, - (void*)&rru_config_msg.msg[0]); - configuration_received = 1; - } - } - return 0; -} -/*************************************************************/ -/* Southbound Fronthaul functions, RCC/RAU */ - -// southbound IF5 fronthaul for 16-bit OAI format -static inline void fh_if5_south_out(RU_t *ru) { - if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_RRH_GW_DL); -} - -// southbound IF5 fronthaul for Mobipass packet format -static inline void fh_if5_mobipass_south_out(RU_t *ru) { - if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.tti_tx, &ru->seqno, IF5_MOBIPASS); -} - -// southbound IF4p5 fronthaul -static inline void fh_if4p5_south_out(RU_t *ru) { - if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); - if (nr_slot_select(&ru->gNB_list[0]->gNB_config,ru->proc.tti_tx)!=SF_UL) - send_IF4p5(ru,ru->proc.frame_tx, ru->proc.tti_tx, IF4p5_PDLFFT); -} - -/*************************************************************/ -/* Input Fronthaul from south RCC/RAU */ - -// Synchronous if5 from south -void fh_if5_south_in(RU_t *ru,int *frame, int *tti) { - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - - recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL); - - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*20))&1023; - proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%20; - - if (proc->first_rx == 0) { - if (proc->tti_rx != *tti){ - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*tti); - 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; - *frame = proc->frame_rx; - *tti = proc->tti_rx; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - -} - -// Synchronous if4p5 from south -void fh_if4p5_south_in(RU_t *ru,int *frame,int *slot) { - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - int f,sl; - - - uint16_t packet_type; - uint32_t symbol_number=0; - uint32_t symbol_mask_full=0; -/* - if ((fp->frame_type == TDD) && (subframe_select(fp,*slot)==SF_S)) - symbol_mask_full = (1<ul_symbols_in_S_subframe)-1; - else - symbol_mask_full = (1<symbols_per_slot)-1; - - AssertFatal(proc->symbol_mask[*slot]==0,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*slot,proc->symbol_mask[*slot]);*/ - do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - recv_IF4p5(ru, &f, &sl, &packet_type, &symbol_number); - - if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sl] = proc->symbol_mask[sl] | (1<first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d\n",f,*frame); - if ((proc->first_rx==0) && (sl!=*slot)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sl,*slot,proc->first_rx); - break; - - } else if (packet_type == IF4p5_PRACH) { - // nothing in RU for RAU - } - LOG_D(PHY,"rx_fh_if4p5: subframe %d symbol mask %x\n",*slot,proc->symbol_mask[sl]); - } while(proc->symbol_mask[sl] != symbol_mask_full); - - //caculate timestamp_rx, timestamp_tx based on frame and subframe - proc->tti_rx = sl; - proc->frame_rx = f; - proc->timestamp_rx = ((proc->frame_rx * fp->slots_per_frame) + proc->tti_rx ) * fp->samples_per_slot ; - // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe); - proc->tti_tx = (sl+sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (sl>(fp->slots_per_frame-sl_ahead)) ? (f+1)&1023 : f; - - if (proc->first_rx == 0) { - if (proc->tti_rx != *slot){ - LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*slot); - exit_fun("Exiting"); - } - if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp (IF4p5) 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; - *frame = proc->frame_rx; - *slot = proc->tti_rx; - } - - if (ru == RC.ru[0]) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, f ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, sl); - 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 ); - } - - proc->symbol_mask[proc->tti_rx] = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - LOG_D(PHY,"RU %d: fh_if4p5_south_in sleeping ...\n",ru->idx); -} - -// asynchronous inbound if4p5 fronthaul from south -void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *slot) { - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - - uint16_t packet_type; - uint32_t symbol_number,symbol_mask,prach_rx; -// uint32_t got_prach_info=0; - - symbol_number = 0; - symbol_mask = (1<<(fp->symbols_per_slot))-1; - prach_rx = 0; - - do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! - recv_IF4p5(ru, &proc->frame_rx, &proc->tti_rx, &packet_type, &symbol_number); - // grab first prach information for this new subframe - /*if (got_prach_info==0) { - prach_rx = is_prach_subframe(fp, proc->frame_rx, proc->tti_rx); - got_prach_info = 1; - }*/ - if (proc->first_rx != 0) { - *frame = proc->frame_rx; - *slot = proc->tti_rx; - proc->first_rx = 0; - } - else { - if (proc->frame_rx != *frame) { - LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); - exit_fun("Exiting"); - } - if (proc->tti_rx != *slot) { - LOG_E(PHY,"tti_rx %d is not what we expect %d\n",proc->tti_rx,*slot); - exit_fun("Exiting"); - } - } - if (packet_type == IF4p5_PULFFT) symbol_mask &= (~(1< 0) || (prach_rx >0)); // haven't received all PUSCH symbols and PRACH information -} - - - - - -/*************************************************************/ -/* Input Fronthaul from North RRU */ - -// RRU IF4p5 TX fronthaul receiver. Assumes an if_device on input and if or rf device on output -// receives one subframe's worth of IF4p5 OFDM symbols and OFDM modulates -void fh_if4p5_north_in(RU_t *ru,int *frame,int *slot) { - - uint32_t symbol_number=0; - uint32_t symbol_mask, symbol_mask_full; - uint16_t packet_type; - - - /// **** incoming IF4p5 from remote RCC/RAU **** /// - symbol_number = 0; - symbol_mask = 0; - symbol_mask_full = (1<<(ru->nr_frame_parms->symbols_per_slot))-1; - - do { - recv_IF4p5(ru, frame, slot, &packet_type, &symbol_number); - symbol_mask = symbol_mask | (1<nr_frame_parms; - RU_proc_t *proc = &ru->proc; - int tti_tx,frame_tx; - openair0_timestamp timestamp_tx; - - recv_IF5(ru, ×tamp_tx, *slot, IF5_RRH_GW_DL); - // printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); - - tti_tx = (timestamp_tx/fp->samples_per_slot)%fp->slots_per_frame; - frame_tx = (timestamp_tx/(fp->samples_per_slot*fp->slots_per_frame))&1023; - - if (proc->first_tx != 0) { - *slot = tti_tx; - *frame = frame_tx; - proc->first_tx = 0; - } - else { - AssertFatal(tti_tx == *slot, - "tti_tx %d is not what we expect %d\n",tti_tx,*slot); - AssertFatal(frame_tx == *frame, - "frame_tx %d is not what we expect %d\n",frame_tx,*frame); - } -} - -void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; - RU_proc_t *proc = &ru->proc; - - uint16_t packet_type; - uint32_t symbol_number,symbol_mask,symbol_mask_full=0; - int slot_tx,frame_tx; - - LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru); - symbol_number = 0; - symbol_mask = 0; -// symbol_mask_full = ((subframe_select(fp,*slot) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_slot))-1; - do { - recv_IF4p5(ru, &frame_tx, &slot_tx, &packet_type, &symbol_number); - if ((nr_slot_select(cfg,slot_tx) == SF_DL) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); - LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n", - *slot,nr_slot_select(cfg,*slot),frame_tx,slot_tx,symbol_number); - if (proc->first_tx != 0) { - *frame = frame_tx; - *slot = slot_tx; - proc->first_tx = 0; - //symbol_mask_full = ((subframe_select(fp,*slot) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_slot))-1; - } - else { - AssertFatal(frame_tx == *frame, - "frame_tx %d is not what we expect %d\n",frame_tx,*frame); - AssertFatal(slot_tx == *slot, - "slot_tx %d is not what we expect %d\n",slot_tx,*slot); - } - if (packet_type == IF4p5_PDLFFT) { - symbol_mask = symbol_mask | (1<rx_fhaul); - - proc->tti_tx = slot_tx; - proc->frame_tx = frame_tx; - - if ((frame_tx == 0)&&(slot_tx == 0)) proc->frame_tx_unwrap += 1024; - - proc->timestamp_tx = ((((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->slots_per_frame) + (uint64_t)slot_tx) * (uint64_t)fp->samples_per_slot; - - 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,slot_tx); - // 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_TX0_RU, frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx ); - } - - if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx); - if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx); -} - -void fh_if5_north_out(RU_t *ru) { - - RU_proc_t *proc=&ru->proc; - uint8_t seqno=0; - - /// **** send_IF5 of rxdata to BBU **** /// - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); - send_IF5(ru, proc->timestamp_rx, proc->tti_rx, &seqno, IF5_RRH_GW_UL); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); - -} - -// RRU IF4p5 northbound interface (RX) -void fh_if4p5_north_out(RU_t *ru) { - - RU_proc_t *proc=&ru->proc; - //NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - //const int subframe = proc->tti_rx; - if (ru->idx==0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx ); -/* - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { - /// **** in TDD during DL send_IF4 of ULTICK to RCC **** /// - send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULTICK); - return; - }*/ - - start_meas(&ru->tx_fhaul); - send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULFFT); - stop_meas(&ru->tx_fhaul); - -} - -static void* emulatedRF_thread(void* param) { - RU_proc_t *proc = (RU_proc_t *) param; - int microsec = 500; // length of time to sleep, in miliseconds - struct timespec req = {0}; - req.tv_sec = 0; - req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2; - cpu_set_t cpuset; - CPU_SET(1,&cpuset); - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - - int policy; - struct sched_param sparam; - memset(&sparam, 0, sizeof(sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); - policy = SCHED_FIFO ; - pthread_setschedparam(pthread_self(), policy, &sparam); - - wait_sync("emulatedRF_thread"); - while(!oai_exit){ - nanosleep(&req, (struct timespec *)NULL); - pthread_mutex_lock(&proc->mutex_emulateRF); - ++proc->instance_cnt_emulateRF; - pthread_mutex_unlock(&proc->mutex_emulateRF); - pthread_cond_signal(&proc->cond_emulateRF); - } - return 0; -} - -void rx_rf(RU_t *ru,int *frame,int *slot) { - - RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - void *rxp[ru->nb_rx]; - unsigned int rxs; - int i; - openair0_timestamp ts,old_ts; - - AssertFatal(*slotslots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame); - for (i=0; inb_rx; i++) - rxp[i] = (void*)&ru->common.rxdata[i][*slot*fp->samples_per_slot]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - - old_ts = proc->timestamp_rx; - - LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]); - - if(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_slot; - ts = old_ts + rxs; - } - else{ - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &ts, - rxp, - fp->samples_per_slot, - ru->nb_rx); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - proc->timestamp_rx = ts-ru->ts_offset; - - //AssertFatal(rxs == fp->samples_per_subframe, - //"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs); - if (rxs != fp->samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_slot,rxs); - - if (proc->first_rx == 1) { - ru->ts_offset = proc->timestamp_rx; - proc->timestamp_rx = 0; - } - else { - if (proc->timestamp_rx - old_ts != fp->samples_per_slot) { - LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset); - ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot); - proc->timestamp_rx = ts-ru->ts_offset; - } - - } - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023; - proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame; - // synchronize first reception to frame 0 subframe 0 - - - // 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 (proc->first_rx == 0) { - if (proc->tti_rx != *slot){ - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot); - exit_fun("Exiting"); - } - - if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame); - exit_fun("Exiting"); - } - } else { - proc->first_rx = 0; - *frame = proc->frame_rx; - *slot = proc->tti_rx; - } - - //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - - if (rxs != fp->samples_per_slot) - { - //exit_fun( "problem receiving samples" ); - LOG_E(PHY, "problem receiving samples\n"); - } -} - - -void tx_rf(RU_t *ru,int frame_tx,int tti_tx,uint64_t timestamp_tx) { - - RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; - void *txp[ru->nb_tx]; - unsigned int txs; - int i; - - T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame_tx), T_INT(tti_tx), - T_INT(0), T_BUFFER(&ru->common.txdata[0][tti_tx * fp->samples_per_slot], fp->samples_per_slot * 4)); - - nr_subframe_t SF_type = nr_slot_select(cfg,tti_tx%fp->slots_per_frame); - int sf_extension = 0; - - if ((SF_type == SF_DL) || - (SF_type == SF_S)) { - - int siglen=fp->samples_per_slot,flags=1; - -/* - if (SF_type == SF_S) { - siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); - flags=3; // end of burst - } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { - flags = 2; // start of burst - sf_extension = ru->N_TA_offset<<1; - } - - if ((cfg->subframe_config.duplex_mode == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = ru->N_TA_offset<<1; - } */ - 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 ); - - for (i=0; inb_tx; i++) - - txp[i] = (void*)&ru->common.txdata[i][(tti_tx*fp->samples_per_slot)-sf_extension]; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); - 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_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - 4);//flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)timestamp_tx,frame_tx,proc->frame_tx_unwrap,tti_tx); - 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); - - } -} - - -/*! - * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. - * This handles the RX FH for an asynchronous RRU/UE - * \param param is a \ref gNB_L1_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* ru_thread_asynch_rxtx( void* param ) { - - static int ru_thread_asynch_rxtx_status; - - RU_t *ru = (RU_t*)param; - RU_proc_t *proc = &ru->proc; - - - - int subframe=0, frame=0; - - thread_top_init("ru_thread_asynch_rxtx",1,870000L,1000000L,1000000L); - - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - - wait_sync("ru_thread_asynch_rxtx"); - - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - printf( "waiting for devices (ru_thread_asynch_rx)\n"); - - wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); - - printf( "devices ok (ru_thread_asynch_rx)\n"); - - - while (!oai_exit) { - - if (oai_exit) break; - - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } - LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); - // asynchronous receive from south (Mobipass) - if (ru->fh_south_asynch_in) ru->fh_south_asynch_in(ru,&frame,&subframe); - // asynchronous receive from north (RRU IF4/IF5) - else if (ru->fh_north_asynch_in) { - if (nr_slot_select(&ru->gNB_list[0]->gNB_config,subframe)!=SF_UL) - ru->fh_north_asynch_in(ru,&frame,&subframe); - } - else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); - } - - ru_thread_asynch_rxtx_status=0; - return(&ru_thread_asynch_rxtx_status); -} - - - - -/*! - * \brief The prach receive thread of RU. - * \param param is a \ref RU_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* ru_thread_prach( void* param ) { - - static int ru_thread_prach_status; - - RU_t *ru = (RU_t*)param; - RU_proc_t *proc = (RU_proc_t*)&ru->proc; - - // set default return value - ru_thread_prach_status = 0; - - thread_top_init("ru_thread_prach",1,500000L,1000000L,20000000L); - - while (RC.ru_mask>0) { - usleep(1e6); - LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__); - } - LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__); - - while (!oai_exit) { - - if (oai_exit) break; - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - /*if (ru->gNB_list[0]){ - prach_procedures( - ru->gNB_list[0] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 -#endif - ); - } - else { - rx_prach(NULL, - ru, - NULL, - NULL, - NULL, - proc->frame_prach, - 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 -#endif - ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); */ - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting RU thread PRACH\n"); - - ru_thread_prach_status = 0; - return &ru_thread_prach_status; -} - - -int wakeup_synch(RU_t *ru){ - - struct timespec wait; - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - // wake up synch thread - // lock the synch mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) { - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch ); - exit_fun( "error locking mutex_synch" ); - return(-1); - } - - ++ru->proc.instance_cnt_synch; - - // the thread can now be woken up - if (pthread_cond_signal(&ru->proc.cond_synch) != 0) { - LOG_E( PHY, "[RU] ERROR pthread_cond_signal for RU synch thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - pthread_mutex_unlock( &ru->proc.mutex_synch ); - - return(0); -} - -void do_ru_synch(RU_t *ru) { - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - int i; - void *rxp[2],*rxp2[2]; - int32_t dummy_rx[ru->nb_rx][fp->samples_per_subframe] __attribute__((aligned(32))); - int rxs; - int ic; - - // initialize the synchronization buffer to the common_vars.rxdata - for (int i=0;inb_rx;i++) - rxp[i] = &ru->common.rxdata[i][0]; - - double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0]; - double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0]; - for (i=0;i<4;i++) { - ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i]; - ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1; - } - ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); - - while ((ru->in_synch ==0)&&(!oai_exit)) { - // read in frame - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - fp->samples_per_subframe*10, - ru->nb_rx); - if (rxs != fp->samples_per_subframe*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_subframe*10,rxs); - - // wakeup synchronization processing thread - wakeup_synch(ru); - ic=0; - - while ((ic>=0)&&(!oai_exit)) { - // continuously read in frames, 1ms at a time, - // until we are done with the synchronization procedure - - for (i=0; inb_rx; i++) - rxp2[i] = (void*)&dummy_rx[i][0]; - for (i=0;i<10;i++) - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp2, - fp->samples_per_subframe, - ru->nb_rx); - pthread_mutex_lock(&ru->proc.mutex_synch); - ic = ru->proc.instance_cnt_synch; - pthread_mutex_unlock(&ru->proc.mutex_synch); - } // ic>=0 - } // in_synch==0 - // read in rx_offset samples - LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset); - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - ru->rx_offset, - ru->nb_rx); - for (i=0;i<4;i++) { - ru->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1; - ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2; - } - - ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); - -} - - - -void wakeup_gNB_L1s(RU_t *ru) { - - int i; - PHY_VARS_gNB **gNB_list = ru->gNB_list; - - LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top); - - if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { - // call gNB function directly - - char string[20]; - sprintf(string,"Incoming RU %d",ru->idx); - LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx); - ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru); - } - else { - - LOG_D(PHY,"ru->num_gNB:%d\n", ru->num_gNB); - - for (i=0;inum_gNB;i++) - { - LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx); - if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) - { - LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.tti_rx); - } - } - } -} - -static inline int wakeup_prach_ru(RU_t *ru) { - - struct timespec wait; - - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - if (pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait) !=0) { - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach); - exit_fun( "error locking mutex_rxtx" ); - return(-1); - } - if (ru->proc.instance_cnt_prach==-1) { - ++ru->proc.instance_cnt_prach; - ru->proc.frame_prach = ru->proc.frame_rx; - ru->proc.subframe_prach = ru->proc.tti_rx; - - // DJP - think prach_procedures() is looking at gNB frame_prach - if (ru->gNB_list[0]) { - ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx; - ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx; - } - LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx); - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); - } - else LOG_W(PHY,"RU prach thread busy, skipping\n"); - pthread_mutex_unlock( &ru->proc.mutex_prach ); - - return(0); -} - -// this is for RU with local RF unit -void fill_rf_config(RU_t *ru, char *rf_config_file) { - - int i; - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index - openair0_config_t *cfg = &ru->openair0_cfg; - int N_RB = gNB_config->rf_config.dl_carrier_bandwidth.value; - int mu = gNB_config->subframe_config.numerology_index_mu.value; - - if (mu == NR_MU_0) { //or if LTE - if(N_RB == 100) { - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - } else if(N_RB == 50) { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } else if (N_RB == 25) { - cfg->sample_rate=7.68e6; - cfg->samples_per_frame = 76800; - cfg->tx_bw = 2.5e6; - cfg->rx_bw = 2.5e6; - } else if (N_RB == 6) { - cfg->sample_rate=1.92e6; - cfg->samples_per_frame = 19200; - cfg->tx_bw = 1.5e6; - cfg->rx_bw = 1.5e6; - } - else AssertFatal(1==0,"Unknown N_RB %d\n",N_RB); - } - else if (mu == NR_MU_1) { - if(N_RB == 217) { - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - } else if(N_RB == 106) { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } else { - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else { - AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); - } - - if (gNB_config->subframe_config.duplex_mode.value==TDD) - cfg->duplex_mode = duplex_mode_TDD; - else //FDD - cfg->duplex_mode = duplex_mode_FDD; - - cfg->Mod_id = 0; - cfg->num_rb_dl=N_RB; - cfg->tx_num_channels=ru->nb_tx; - cfg->rx_num_channels=ru->nb_rx; - - for (i=0; inb_tx; i++) { - - cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; - cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - - cfg->tx_gain[i] = ru->att_tx; - cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; - - cfg->configFilename = rf_config_file; - printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", - i, cfg->tx_gain[i], - cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i]); - } -} - -/* this function maps the RU tx and rx buffers to the available rf chains. - Each rf chain is is addressed by the card number and the chain on the card. The - rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple - antennas are mapped to successive RF chains on the same card. */ -int setup_RU_buffers(RU_t *ru) { - - int i,j; - int card,ant; - - //uint16_t N_TA_offset = 0; - - NR_DL_FRAME_PARMS *frame_parms; - //nfapi_nr_config_request_t *gNB_config = ru->gNB_list[0]->gNB_config; //tmp index - - if (ru) { - frame_parms = ru->nr_frame_parms; - printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); - } else { - printf("RU[%d] not initialized\n", ru->idx); - return(-1); - } - - -/* if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624; - else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; - else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; - } */ - if (ru->openair0_cfg.mmapped_dma == 1) { - // replace RX signal buffers with mmaped HW versions - - for (i=0; inb_rx; i++) { - card = i/4; - ant = i%4; - printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); - free(ru->common.rxdata[i]); - ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; - - printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); - for (j=0; j<16; j++) { - printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); - ru->common.rxdata[i][j] = 16-j; - } - } - - for (i=0; inb_tx; i++) { - card = i/4; - ant = i%4; - printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); - free(ru->common.txdata[i]); - ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; - - printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); - - for (j=0; j<16; j++) { - printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); - ru->common.txdata[i][j] = 16-j; - } - } - } - else { // not memory-mapped DMA - //nothing to do, everything already allocated in lte_init - } - return(0); -} - -static void* ru_stats_thread(void* param) { - - RU_t *ru = (RU_t*)param; - - wait_sync("ru_stats_thread"); - - while (!oai_exit) { - sleep(1); - if (opp_enabled == 1) { - if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); - if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); - if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); - if (ru->fh_north_out) { - print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); - print_meas(&ru->compression,"compression",NULL,NULL); - print_meas(&ru->transport,"transport",NULL,NULL); - } - } - } - return(NULL); -} - -static void* ru_thread_tx( void* param ) { - RU_t *ru = (RU_t*)param; - RU_proc_t *proc = &ru->proc; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *gNB_proc; - gNB_L1_rxtx_proc_t *L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - char filename[40]; - int print_frame = 8; - int i = 0; - - - - thread_top_init("ru_thread_tx",0,400000,500000,500000); - - wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - - - while (!oai_exit) { - - if (oai_exit) break; - - - LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); - // wait until eNBs are finished subframe RX n and TX n+4 - - wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - - - pthread_mutex_lock(&proc->mutex_gNBs); - int frame_tx=proc->frame_tx; - int tti_tx =proc->tti_tx; - uint64_t timestamp_tx = proc->timestamp_tx; - - pthread_mutex_unlock(&proc->mutex_gNBs); - - if (oai_exit) break; - -//printf("~~~~~~~~~~~~~~~~start process for ru_thread_tx %d.%d\n", proc->frame_tx, proc->tti_tx); - 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 ); - // do TX front-end processing if needed (precoding and/or IDFTs) - 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,frame_tx,tti_tx); - 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,frame_tx,tti_tx,timestamp_tx); - if (ru->fh_north_out) ru->fh_north_out(ru); - } - else - { - if(frame_tx == print_frame) - { - for (i=0; inb_tx; i++) - { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); - if(proc->tti_tx == 9) - { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } - else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - }//if(proc->tti_tx == 9) - }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) - }//else emulate_rf - release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs); - - for(i = 0; inum_gNB; i++) - { - gNB = ru->gNB_list[i]; - gNB_proc = &gNB->proc; - L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc; - pthread_mutex_lock(&gNB_proc->mutex_RU_tx); - for (int j=0;jnum_RU;j++) { - if (ru == gNB->RU_list[j]) { - if ((gNB_proc->RU_mask_tx&(1< 0) - LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx); - gNB_proc->RU_mask_tx |= (1<RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - } - else { // all RUs TX are finished so send the ready signal to eNB processing - gNB_proc->RU_mask_tx = 0; - pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - - pthread_mutex_lock(&L1_proc->mutex_RUs_tx); - L1_proc->instance_cnt_RUs = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); - pthread_mutex_unlock( &L1_proc->mutex_RUs_tx ); - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB L1 TX thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - } - } - } - } - release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - return 0; -} - -static void* ru_thread( void* param ) { - - static int ru_thread_status; - - RU_t *ru = (RU_t*)param; - RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - int ret; - int slot = fp->slots_per_frame-1; - int frame =1023; - char filename[40],threadname[40]; - int print_frame = 8; - int i = 0; - - // set default return value - ru_thread_status = 0; - - - // set default return value - sprintf(threadname,"ru_thread %d",ru->idx); - thread_top_init(threadname,0,870000,1000000,1000000); - - LOG_D(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); - - if(emulate_rf){ - fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp); - nr_dump_frame_parms(fp); - nr_phy_init_RU(ru); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - } - } - else{ - // Start IF device if any - if (ru->start_if) { - LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); - AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); - if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); - else ret = attach_rru(ru); - AssertFatal(ret==0,"Cannot connect to remote radio\n"); - } - if (ru->if_south == LOCAL_RF) { // configure RF parameters only - fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp); - nr_dump_frame_parms(fp); - nr_phy_init_RU(ru); - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - AssertFatal(ret==0,"Cannot connect to local radio\n"); - } - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - } - } - - LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx); - pthread_mutex_lock(&RC.ru_mutex); - RC.ru_mask &= ~(1<idx); - pthread_cond_signal(&RC.ru_cond); - pthread_mutex_unlock(&RC.ru_mutex); - - wait_sync("ru_thread"); - - if(!emulate_rf){ - // Start RF device if any - if (ru->start_rf) { - if (ru->start_rf(ru) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); - } - else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - - - // if an asnych_rxtx thread exists - // wakeup the thread because the devices are ready at this point - - if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx=0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - } - else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); - - // if this is a slave RRU, try to synchronize on the DL frequency - if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); - } - - pthread_mutex_lock(&proc->mutex_FH1); - proc->instance_cnt_FH1 = 0; - pthread_mutex_unlock(&proc->mutex_FH1); - pthread_cond_signal(&proc->cond_FH1); - - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices - while (!oai_exit) { - - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. - // They are set on the first rx/tx in the underly FH routines. - if (slot==(fp->slots_per_frame-1)) { - slot=0; - frame++; - frame&=1023; - } else { - slot++; - } - - // synchronization on input FH interface, acquire signals/data and block - if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); - else AssertFatal(1==0, "No fronthaul interface at south port"); - - LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n", - frame,slot, - proc->frame_rx,proc->tti_rx, - proc->frame_tx,proc->tti_tx, - RC.gNB[0][0]->proc.frame_rx,RC.gNB[0][0]->proc.slot_rx, - RC.gNB[0][0]->proc.frame_tx); -/* - LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", - ru->do_prach, - is_prach_subframe(fp, proc->frame_rx, proc->tti_rx), - proc->frame_rx,proc->tti_rx); - - if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->tti_rx)==1)) { - wakeup_prach_ru(ru); - }*/ - - // adjust for timing offset between RU -//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx); - if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; - - - // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru); - - // At this point, all information for subframe has been received on FH interface - - // wakeup all gNB processes waiting for this RU - if (ru->num_gNB>0) wakeup_gNB_L1s(ru); - - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB==0) - { - // 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); - - // 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) - { - // 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_out) ru->fh_north_out(ru); - } - else - { - if(proc->frame_tx == print_frame) - { - for (i=0; inb_tx; i++) - { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_slot_wCP, 1, 1); - if(proc->tti_tx == 9) - { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } - else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - }//if(proc->tti_tx == 9) - }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) - }//else emulate_rf - proc->emulate_rf_busy = 0; - }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) - } - - - printf( "Exiting ru_thread \n"); - - if (ru->stop_rf != NULL) { - if (ru->stop_rf(ru) != 0) - LOG_E(HW,"Could not stop the RF device\n"); - else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); - } - - ru_thread_status = 0; - return &ru_thread_status; - -} -/* -// This thread run the initial synchronization like a UE -void *ru_thread_synch(void *arg) { - - RU_t *ru = (RU_t*)arg; - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - int32_t sync_pos,sync_pos2; - uint32_t peak_val; - uint32_t sync_corr[307200] __attribute__((aligned(32))); - static int ru_thread_synch_status; - - - thread_top_init("ru_thread_synch",0,5000000,10000000,10000000); - - wait_sync("ru_thread_synch"); - - // initialize variables for PSS detection - lte_sync_time_init(ru->nr_frame_parms); - - 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; - - // if we're not in synch, then run initial synch - if (ru->in_synch == 0) { - // run intial synch like UE - LOG_I(PHY,"Running initial synchronization\n"); - - sync_pos = lte_sync_time_gNB(ru->common.rxdata, - fp, - fp->samples_per_subframe*5, - &peak_val, - sync_corr); - LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val); - - if (sync_pos >= 0) { - if (sync_pos >= fp->nb_prefix_samples) - sync_pos2 = sync_pos - fp->nb_prefix_samples; - else - sync_pos2 = sync_pos + (fp->samples_per_subframe*10) - fp->nb_prefix_samples; - - if (fp->frame_type == FDD) { - - // PSS is hypothesized in last symbol of first slot in Frame - int sync_pos_slot = (fp->samples_per_subframe>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; - - if (sync_pos2 >= sync_pos_slot) - ru->rx_offset = sync_pos2 - sync_pos_slot; - else - ru->rx_offset = (fp->samples_per_subframe*10) + sync_pos2 - sync_pos_slot; - } - else { - - } - - LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); - - if ((peak_val > 300000) && (sync_pos > 0)) { - // if (sync_pos++ > 3) { - write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_subframe*5,1,2); - write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_subframe*10,1,1); - exit(-1); - } - - ru->in_synch=1; - } - } - - if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; - } // oai_exit - - ru_thread_synch_status = 0; - return &ru_thread_synch_status; - -} -*/ - -int start_if(struct RU_t_s *ru,struct PHY_VARS_gNB_s *gNB) { - return(ru->ifdevice.trx_start_func(&ru->ifdevice)); -} - -int start_rf(RU_t *ru) { - return(ru->rfdevice.trx_start_func(&ru->rfdevice)); -} - -int stop_rf(RU_t *ru) -{ - ru->rfdevice.trx_end_func(&ru->rfdevice); - return 0; -} - -extern void init_nr_feptx_thread(RU_t *ru,pthread_attr_t *attr); - -void init_RU_proc(RU_t *ru) { - - int i=0; - RU_proc_t *proc; - pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL, *attr_emulateRF=NULL;// *attr_synch=NULL; - //pthread_attr_t *attr_fep=NULL; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - //pthread_attr_t *attr_prach_br=NULL; -#endif - char name[100]; - -#ifndef OCP_FRAMEWORK - LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); -#endif - proc = &ru->proc; - memset((void*)proc,0,sizeof(RU_proc_t)); - - proc->ru = ru; - proc->instance_cnt_prach = -1; - proc->instance_cnt_synch = -1; ; - proc->instance_cnt_FH = -1; - proc->instance_cnt_FH1 = -1; - proc->instance_cnt_gNBs = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->instance_cnt_emulateRF = -1; - proc->first_rx = 1; - proc->first_tx = 1; - proc->frame_offset = 0; - proc->num_slaves = 0; - proc->frame_tx_unwrap = 0; - - for (i=0;i<10;i++) proc->symbol_mask[i]=0; - - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_synch,NULL); - pthread_mutex_init( &proc->mutex_FH,NULL); - pthread_mutex_init( &proc->mutex_FH1,NULL); - pthread_mutex_init( &proc->mutex_emulateRF,NULL); - pthread_mutex_init( &proc->mutex_gNBs, NULL); - - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_FH, NULL); - pthread_cond_init( &proc->cond_FH1, NULL); - pthread_cond_init( &proc->cond_emulateRF, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - pthread_cond_init( &proc->cond_synch,NULL); - pthread_cond_init( &proc->cond_gNBs, NULL); - - pthread_attr_init( &proc->attr_FH); - pthread_attr_init( &proc->attr_FH1); - pthread_attr_init( &proc->attr_emulateRF); - pthread_attr_init( &proc->attr_prach); - pthread_attr_init( &proc->attr_synch); - pthread_attr_init( &proc->attr_asynch_rxtx); - pthread_attr_init( &proc->attr_fep); - - -#ifndef DEADLINE_SCHEDULER - attr_FH = &proc->attr_FH; - attr_FH1 = &proc->attr_FH1; - attr_emulateRF = &proc->attr_emulateRF; - attr_prach = &proc->attr_prach; - //attr_synch = &proc->attr_synch; - attr_asynch = &proc->attr_asynch_rxtx; -#endif - - pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) - pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru ); - if(emulate_rf) - pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc ); - if (ru->function == NGFI_RRU_IF4p5) { - pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); - ///tmp deactivation of synch thread -// if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru); - - - if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru ); - - snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx ); - pthread_setname_np( proc->pthread_FH, name ); - - } - else if (ru->function == gNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF - LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); - pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); - } - - if (get_nprocs()>=2) { - if (ru->feprx) init_fep_thread(ru,NULL); - if (ru->feptx_ofdm) nr_init_feptx_thread(ru,NULL); - } - if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void*)ru); - -} - -void kill_RU_proc(int inst) -{ - RU_t *ru = RC.ru[inst]; - RU_proc_t *proc = &ru->proc; - - pthread_mutex_lock(&proc->mutex_FH); - proc->instance_cnt_FH = 0; - pthread_mutex_unlock(&proc->mutex_FH); - pthread_cond_signal(&proc->cond_FH); - - pthread_mutex_lock(&proc->mutex_prach); - proc->instance_cnt_prach = 0; - pthread_mutex_unlock(&proc->mutex_prach); - pthread_cond_signal(&proc->cond_prach); - - pthread_mutex_lock(&proc->mutex_synch); - proc->instance_cnt_synch = 0; - pthread_mutex_unlock(&proc->mutex_synch); - pthread_cond_signal(&proc->cond_synch); - - pthread_mutex_lock(&proc->mutex_gNBs); - proc->instance_cnt_gNBs = 0; - pthread_mutex_unlock(&proc->mutex_gNBs); - pthread_cond_signal(&proc->cond_gNBs); - - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx = 0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - - LOG_D(PHY, "Joining pthread_FH\n"); - pthread_join(proc->pthread_FH, NULL); - if (ru->function == NGFI_RRU_IF4p5) { - LOG_D(PHY, "Joining pthread_prach\n"); - pthread_join(proc->pthread_prach, NULL); - - if (ru->is_slave) { - LOG_D(PHY, "Joining pthread_\n"); - pthread_join(proc->pthread_synch, NULL); - } - - if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) { - LOG_D(PHY, "Joining pthread_asynch_rxtx\n"); - pthread_join(proc->pthread_asynch_rxtx, NULL); - } - } - if (get_nprocs() >= 2) { - if (ru->feprx) { - pthread_mutex_lock(&proc->mutex_fep); - proc->instance_cnt_fep = 0; - pthread_mutex_unlock(&proc->mutex_fep); - pthread_cond_signal(&proc->cond_fep); - LOG_D(PHY, "Joining pthread_fep\n"); - pthread_join(proc->pthread_fep, NULL); - pthread_mutex_destroy(&proc->mutex_fep); - pthread_cond_destroy(&proc->cond_fep); - } - if (ru->feptx_ofdm) { - pthread_mutex_lock(&proc->mutex_feptx); - proc->instance_cnt_feptx = 0; - pthread_mutex_unlock(&proc->mutex_feptx); - pthread_cond_signal(&proc->cond_feptx); - LOG_D(PHY, "Joining pthread_feptx\n"); - pthread_join(proc->pthread_feptx, NULL); - pthread_mutex_destroy(&proc->mutex_feptx); - pthread_cond_destroy(&proc->cond_feptx); - } - } - if (opp_enabled) { - LOG_D(PHY, "Joining ru_stats_thread\n"); - pthread_join(ru->ru_stats_thread, NULL); - } - - pthread_mutex_destroy(&proc->mutex_prach); - pthread_mutex_destroy(&proc->mutex_asynch_rxtx); - pthread_mutex_destroy(&proc->mutex_synch); - pthread_mutex_destroy(&proc->mutex_FH); - pthread_mutex_destroy(&proc->mutex_gNBs); - - pthread_cond_destroy(&proc->cond_prach); - pthread_cond_destroy(&proc->cond_FH); - pthread_cond_destroy(&proc->cond_asynch_rxtx); - pthread_cond_destroy(&proc->cond_synch); - pthread_cond_destroy(&proc->cond_gNBs); - - pthread_attr_destroy(&proc->attr_FH); - pthread_attr_destroy(&proc->attr_prach); - pthread_attr_destroy(&proc->attr_synch); - pthread_attr_destroy(&proc->attr_asynch_rxtx); - pthread_attr_destroy(&proc->attr_fep); - -} - -int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { - - FH_fmt_options_t fmt = cap->FH_fmt; - - int i; - int found_band=0; - - LOG_I(PHY,"RRU %d, num_bands %d, looking for band %d\n",ru->idx,cap->num_bands,ru->nr_frame_parms->eutra_band); - for (i=0;inum_bands;i++) { - LOG_I(PHY,"band %d on RRU %d\n",cap->band_list[i],ru->idx); - if (ru->nr_frame_parms->eutra_band == cap->band_list[i]) { - found_band=1; - break; - } - } - - if (found_band == 0) { - LOG_I(PHY,"Couldn't find target EUTRA band %d on RRU %d\n",ru->nr_frame_parms->eutra_band,ru->idx); - return(-1); - } - - switch (ru->if_south) { - case LOCAL_RF: - AssertFatal(1==0, "This RU should not have a local RF, exiting\n"); - return(0); - break; - case REMOTE_IF5: - if (fmt == OAI_IF5_only || fmt == OAI_IF5_and_IF4p5) return(0); - break; - case REMOTE_IF4p5: - if (fmt == OAI_IF4p5_only || fmt == OAI_IF5_and_IF4p5) return(0); - break; - case REMOTE_MBP_IF5: - if (fmt == MBP_IF5) return(0); - break; - default: - LOG_I(PHY,"No compatible Fronthaul interface found for RRU %d\n", ru->idx); - return(-1); - } - - return(-1); -} - - -char rru_format_options[4][20] = {"OAI_IF5_only","OAI_IF4p5_only","OAI_IF5_and_IF4p5","MBP_IF5"}; - -char rru_formats[3][20] = {"OAI_IF5","MBP_IF5","OAI_IF4p5"}; -char ru_if_formats[4][20] = {"LOCAL_RF","REMOTE_OAI_IF5","REMOTE_MBP_IF5","REMOTE_OAI_IF4p5"}; - -void configure_ru(int idx, - void *arg) { - - RU_t *ru = RC.ru[idx]; - RRU_config_t *config = (RRU_config_t *)arg; - RRU_capabilities_t *capabilities = (RRU_capabilities_t*)arg; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; - int ret; - - LOG_I(PHY, "Received capabilities from RRU %d\n",idx); - - - if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]); - - AssertFatal((ret=check_capabilities(ru,capabilities)) == 0, - "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret); - // take antenna capabilities of RRU - ru->nb_tx = capabilities->nb_tx[0]; - ru->nb_rx = capabilities->nb_rx[0]; - - // Pass configuration to RRU - LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->nr_frame_parms->eutra_band); - // wait for configuration - config->FH_fmt = ru->if_south; - config->num_bands = 1; - config->band_list[0] = ru->nr_frame_parms->eutra_band; - config->tx_freq[0] = ru->nr_frame_parms->dl_CarrierFreq; - config->rx_freq[0] = ru->nr_frame_parms->ul_CarrierFreq; - //config->tdd_config[0] = ru->nr_frame_parms->tdd_config; - //config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S; - config->att_tx[0] = ru->att_tx; - config->att_rx[0] = ru->att_rx; - config->N_RB_DL[0] = gNB_config->rf_config.dl_carrier_bandwidth.value; - config->N_RB_UL[0] = gNB_config->rf_config.ul_carrier_bandwidth.value; - config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs; -/* if (ru->if_south==REMOTE_IF4p5) { - config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; - config->prach_ConfigIndex[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);*/ - - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms); - nr_phy_init_RU(ru); -} - -void configure_rru(int idx, - void *arg) { - - RRU_config_t *config = (RRU_config_t *)arg; - RU_t *ru = RC.ru[idx]; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; - - ru->nr_frame_parms->eutra_band = config->band_list[0]; - ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0]; - ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0]; - if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) { - gNB_config->subframe_config.duplex_mode.value = TDD; - //ru->nr_frame_parms->tdd_config = config->tdd_config[0]; - //ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0]; - } - else - gNB_config->subframe_config.duplex_mode.value = FDD; - ru->att_tx = config->att_tx[0]; - ru->att_rx = config->att_rx[0]; - gNB_config->rf_config.dl_carrier_bandwidth.value = config->N_RB_DL[0]; - gNB_config->rf_config.ul_carrier_bandwidth.value = config->N_RB_UL[0]; - ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0]; - //ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; - if (ru->function==NGFI_RRU_IF4p5) { - ru->nr_frame_parms->att_rx = ru->att_rx; - ru->nr_frame_parms->att_tx = ru->att_tx; -/* - LOG_I(PHY,"Setting ru->function to NGFI_RRU_IF4p5, prach_FrequOffset %d, prach_ConfigIndex %d, att (%d,%d)\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0],ru->att_tx,ru->att_rx); - ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset = config->prach_FreqOffset[0]; - ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = config->prach_ConfigIndex[0]; */ - - } - fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms); - - nr_phy_init_RU(ru); - -} - -/* -void init_precoding_weights(PHY_VARS_gNB *gNB) { - - int layer,ru_id,aa,re,ue,tb; - LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms; - RU_t *ru; - LTE_gNB_DLSCH_t *dlsch; - - // init precoding weigths - for (ue=0;uedlsch[ue][tb]; - for (layer=0; layer<4; layer++) { - int nb_tx=0; - for (ru_id=0;ru_idnb_tx; - } - dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(nb_tx*sizeof(int32_t*)); - - for (aa=0; aaue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(fp->ofdm_symbol_size*sizeof(int32_t)); - for (re=0;reofdm_symbol_size; re++) { - dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; - } - } - } - } - } -}*/ - -void set_function_spec_param(RU_t *ru) -{ - int ret; - - switch (ru->if_south) { - case LOCAL_RF: // this is an RU with integrated RF (RRU, gNB) - if (ru->function == NGFI_RRU_IF5) { // IF5 RRU - ru->do_prach = 0; // no prach processing in RU - ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north - ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously - ru->feprx = NULL; // nothing (this is a time-domain signal) - ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) - ru->feptx_prec = NULL; // nothing (this is a time-domain signal) - ru->start_if = start_if; // need to start the if interface for if5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - } - else if (ru->function == NGFI_RRU_IF4p5) { - ru->do_prach = 1; // do part of prach processing in RU - ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north - ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_nprocs()<=2) ? fep_full :ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? nr_feptx_ofdm : nr_feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) - ru->feptx_prec = NULL; - ru->start_if = start_if; // need to start the if interface for if4p5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - malloc_IF4p5_buffer(ru); - } - else if (ru->function == gNodeB_3GPP) { - ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_nprocs()<=2) ? fep_full : ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? nr_feptx_ofdm : nr_feptx_ofdm_2thread; // this is fep with idft and precoding - ru->feptx_prec = feptx_prec; // this is fep with idft and precoding - ru->fh_north_in = NULL; // no incoming fronthaul from north - ru->fh_north_out = NULL; // no outgoing fronthaul to north - ru->start_if = NULL; // no if interface - ru->rfdevice.host_type = RAU_HOST; - } - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface - ru->stop_rf = stop_rf; - printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); - -/* - if (ru->function == gNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - nr_phy_init_RU(ru); - } - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - }*/ - break; - - case REMOTE_IF5: // the remote unit is IF5 RRU - ru->do_prach = 0; - ru->feprx = (get_nprocs()<=2) ? fep_full : fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_nprocs()<=2) ? nr_feptx_ofdm : nr_feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - ru->start_rf = NULL; // no local RF - ru->stop_rf = NULL; - ru->start_if = start_if; // need to start if interface for IF5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - break; - - case REMOTE_IF4p5: - ru->do_prach = 0; - ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation - ru->feptx_ofdm = NULL; // no OFDM mod - ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception - ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission - ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other - ru->fh_north_out = NULL; - ru->fh_north_asynch_in = NULL; - ru->start_rf = NULL; // no local RF - ru->stop_rf = NULL; - ru->start_if = start_if; // need to start if interface for IF4p5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - - malloc_IF4p5_buffer(ru); - - break; - - default: - LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); - break; - } // switch on interface type -} - -extern void RCconfig_RU(void); - -void init_RU(char *rf_config_file) { - - int ru_id; - RU_t *ru; - PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL; - NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL; - int i; - int CC_id; - - // create status mask - RC.ru_mask = 0; - pthread_mutex_init(&RC.ru_mutex,NULL); - pthread_cond_init(&RC.ru_cond,NULL); - - // read in configuration file) - printf("configuring RU from file\n"); - RCconfig_RU(); - LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs()); - - if (RC.nb_nr_CC != 0) - for (i=0;inum_RU=0; - - LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - for (ru_id=0;ru_idrf_config_file = rf_config_file; - ru->idx = ru_id; - ru->ts_offset = 0; - // use gNB_list[0] as a reference for RU frame parameters - // NOTE: multiple CC_id are not handled here yet! - - if (ru->num_gNB > 0) { - LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p RC.gNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], RC.gNB[0][0], ru->rf_config_file); - - if (ru->gNB_list[0] == 0) - { - LOG_E(PHY,"%s() DJP - ru->gNB_list ru->num_gNB are not initialized - so do it manually\n", __FUNCTION__); - ru->gNB_list[0] = RC.gNB[0][0]; - ru->num_gNB=1; - // - // DJP - feptx_prec() / feptx_ofdm() parses the gNB_list (based on num_gNB) and copies the txdata_F to txdata in RU - // - } - else - { - LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); - } - } - gNB0 = ru->gNB_list[0]; - fp = ru->nr_frame_parms; - LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); - - if (gNB0) - { - if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) - AssertFatal(gNB0!=NULL,"gNB0 is null!\n"); - - if (gNB0) { - LOG_I(PHY,"Copying frame parms from gNB %d to ru %d\n",gNB0->Mod_id,ru->idx); - memcpy((void*)fp,(void*)&gNB0->frame_parms,sizeof(NR_DL_FRAME_PARMS)); - memset((void*)ru->frame_parms, 0, sizeof(LTE_DL_FRAME_PARMS)); - - // attach all RU to all gNBs in its list/ - LOG_D(PHY,"ru->num_gNB:%d gNB0->num_RU:%d\n", ru->num_gNB, gNB0->num_RU); - for (i=0;inum_gNB;i++) { - gNB0 = ru->gNB_list[i]; - gNB0->RU_list[gNB0->num_RU++] = ru; - } - } - } - // LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],gNB_timing[ru->if_timing],ru->function); - - set_function_spec_param(ru); - LOG_I(PHY,"Starting ru_thread %d\n",ru_id); - - init_RU_proc(ru); - - - - } // for ru_id - - // sleep(1); - LOG_D(HW,"[nr-softmodem.c] RU threads created\n"); - - -} - - - - -void stop_RU(int nb_ru) -{ - for (int inst = 0; inst < nb_ru; inst++) { - LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - kill_RU_proc(inst); - } -} - - -/* --------------------------------------------------------*/ -/* from here function to use configuration module */ -void RCconfig_RU(void) { - - int j = 0; - 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); - - - if ( RUParamList.numelt > 0) { - - RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*)); - - RC.ru_mask=(1<idx = j; - RC.ru[j]->nr_frame_parms = (NR_DL_FRAME_PARMS*)malloc(sizeof(NR_DL_FRAME_PARMS)); - RC.ru[j]->frame_parms = (LTE_DL_FRAME_PARMS*)malloc(sizeof(LTE_DL_FRAME_PARMS)); - - printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); - - RC.ru[j]->if_timing = synch_to_ext_device; - if (RC.nb_nr_L1_inst >0) - RC.ru[j]->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; - else - RC.ru[j]->num_gNB = 0; - for (i=0;inum_gNB;i++) RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][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)); - } - - 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; - 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; - 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; - 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)); - } - } - - 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 = gNodeB_3GPP; - printf("Setting function for RU %d to gNodeB_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_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); - - 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; - printf("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; - printf("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; - printf("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; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); - } - } - 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; - for (i=0;inum_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; - } //strcmp(local_rf, "yes") == 0 - else { - printf("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); - 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; - } 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; - } 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; - } 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; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->if_timing = synch_to_other; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; - } - } /* 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); - }// j=0..num_rus - } else { - RC.nb_RU = 0; - } // setting != NULL - - return; - -} diff --git a/targets/RT/USER/nr-softmodem.c b/targets/RT/USER/nr-softmodem.c deleted file mode 100644 index 3aafb821a0..0000000000 --- a/targets/RT/USER/nr-softmodem.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - - -#define _GNU_SOURCE /* See feature_test_macros(7) */ -#include - - -#include "T.h" - -#include "rt_wrapper.h" - - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "assertions.h" -#include "msc.h" - -#include "PHY/types.h" -#include "common/ran_context.h" - -#include "PHY/defs_gNB.h" -#include "common/config/config_userapi.h" -#include "common/utils/load_module_shlib.h" -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "../../ARCH/COMMON/common_lib.h" -#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" - -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "PHY/phy_vars.h" -#include "SCHED/sched_common_vars.h" -#include "LAYER2/MAC/mac_vars.h" - -#include "LAYER2/MAC/mac.h" -#include "LAYER2/MAC/mac_proto.h" -#include "RRC/LTE/rrc_vars.h" -#include "PHY_INTERFACE/phy_interface_vars.h" -#include "gnb_config.h" - -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif - -#include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" - -#include "UTIL/OPT/opt.h" - -//#include "PHY/TOOLS/time_meas.h" - -#ifndef OPENAIR2 -#include "UTIL/OTG/otg_vars.h" -#endif - -#if defined(ENABLE_ITTI) -#include "intertask_interface.h" -#include "create_nr_tasks.h" -#endif - -#include "PHY/INIT/phy_init.h" - -#include "system.h" - -#ifdef XFORMS -#include "PHY/TOOLS/lte_phy_scope.h" -#include "stats.h" -#endif -#include "nr-softmodem.h" -#include "NB_IoT_interface.h" - -#ifdef XFORMS -// current status is that every UE has a DL scope for a SINGLE eNB (gnb_id=0) -// at eNB 0, an UL scope for every UE - -FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; -FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; -FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; -char title[255]; -unsigned char scope_enb_num_ue = 2; -static pthread_t forms_thread; //xforms - -#endif //XFORMS - -short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655}; - - -pthread_cond_t nfapi_sync_cond; -pthread_mutex_t nfapi_sync_mutex; -int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex - -uint8_t nfapi_mode = 0; // Default to monolithic mode - -pthread_cond_t sync_cond; -pthread_mutex_t sync_mutex; -int sync_var=-1; //!< protected by mutex \ref sync_mutex. -int config_sync_var=-1; - -uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] -uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] - -#if defined(ENABLE_ITTI) -volatile int start_gNB = 0; -#endif -volatile int oai_exit = 0; - -static clock_source_t clock_source = internal; -static int wait_for_sync = 0; - -unsigned int mmapped_dma=0; -int single_thread_flag=1; - -static int8_t threequarter_fs=0; - -uint32_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; - -//Temp fix for inexisting NR upper layer -unsigned char NB_gNB_INST = 1; - -#if defined(ENABLE_ITTI) -static char *itti_dump_file = NULL; -#endif - -int UE_scan = 1; -int UE_scan_carrier = 0; -runmode_t mode = normal_txrx; - -FILE *input_fd=NULL; - - -#if MAX_NUM_CCs == 1 -rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; -double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}}; -double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}}; -#else -rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}}; -double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; -double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; -#endif - -double rx_gain_off = 0.0; - -double sample_rate=30.72e6; -double bw = 10.0e6; - -static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; - -char rf_config_file[1024]="/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; - -int chain_offset=0; -int phy_test = 0; -uint8_t usim_test = 0; - -uint8_t dci_Format = 0; -uint8_t agregation_Level =0xFF; - -uint8_t nb_antenna_tx = 1; -uint8_t nb_antenna_rx = 1; - -char ref[128] = "internal"; -char channels[128] = "0"; - -int rx_input_level_dBm; - -#ifdef XFORMS -extern int otg_enabled; -static char do_forms=0; -#else -int otg_enabled; -#endif -//int number_of_cards = 1; - - -//static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -//static nfapi_nr_config_request_t *config[MAX_NUM_CCs]; -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; -uint32_t timing_advance = 0; -uint8_t exit_missed_slots=1; -uint64_t num_missed_slots=0; // counter for the number of missed slots - - -extern void reset_opp_meas(void); -extern void print_opp_meas(void); - -extern void init_eNB_afterRU(void); - -int transmission_mode=1; -int emulate_rf = 0; -int numerology = 0; -char *parallel_config = NULL; -char *worker_config = NULL; - -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} - - -/* struct for ethernet specific parameters given in eNB conf file */ -eth_params_t *eth_params; - -openair0_config_t openair0_cfg[MAX_CARDS]; - -double cpuf; - -extern char uecap_xer[1024]; -char uecap_xer_in=0; - -/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed - * this is very hackish - find a proper solution - */ -uint8_t abstraction_flag=0; - -/* forward declarations */ -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); - -/*---------------------BMC: timespec helpers -----------------------------*/ - -struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; -struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - -struct timespec clock_difftime(struct timespec start, struct timespec end) { - struct timespec temp; - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - return temp; -} - -void print_difftimes(void) { -#ifdef DEBUG - printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); -#else - LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); -#endif -} - -void update_difftimes(struct timespec start, struct timespec end) { - struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - int changed = 0; - diff_time = clock_difftime(start, end); - if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { - min_diff_time.tv_nsec = diff_time.tv_nsec; - changed = 1; - } - if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { - max_diff_time.tv_nsec = diff_time.tv_nsec; - changed = 1; - } -#if 1 - if (changed) print_difftimes(); -#endif -} - -/*------------------------------------------------------------------------*/ - -unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) { - return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); -} -unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { - return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); -} - -#if !defined(ENABLE_ITTI) -void signal_handler(int sig) { - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - printf("trying to exit gracefully...\n"); - oai_exit = 1; - } -} -#endif -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KBLU "\x1B[34m" -#define RESET "\033[0m" - -#if defined(ENABLE_ITTI) -void signal_handler_itti(int sig) { - // Call exit function - char msg[256]; - memset(msg, 0, 256); - sprintf(msg, "caught signal %s\n", strsignal(sig)); - exit_function(__FILE__, __FUNCTION__, __LINE__, msg); -} -#endif - -void exit_function(const char* file, const char* function, const int line, const char* s) -{ - - int ru_id; - - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } - - oai_exit = 1; - - - if (RC.ru == NULL) - exit(-1); // likely init not completed, prevent crash or hang, exit now... - for (ru_id=0; ru_idrfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } - - - sleep(1); //allow lte-softmodem threads to exit first -#if defined(ENABLE_ITTI) - itti_terminate_tasks (TASK_UNKNOWN); -#endif - exit(1); - -} - -#ifdef XFORMS - - -void reset_stats(FL_OBJECT *button, long arg) -{ - int i,j,k; - PHY_VARS_gNB *phy_vars_gNB = RC.gNB[0][0]; - - for (i=0; idlsch[i][0]->Mlimit; j++) { - phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0; - phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0; - phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0; - } - - phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0; - phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0; - phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0; - - - phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0; - phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0; - phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0; -*/ - } - } -} - -static void *scope_thread(void *arg) { - -# ifdef ENABLE_XFORMS_WRITE_STATS - FILE *gNB_stats; -# endif - struct sched_param sched_param; - int UE_id, CC_id; - int ue_cnt=0; - - sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; - sched_setscheduler(0, SCHED_FIFO,&sched_param); - - printf("Scope thread has priority %d\n",sched_param.sched_priority); - -# ifdef ENABLE_XFORMS_WRITE_STATS - - gNB_stats = fopen("gNB_stats.txt", "w"); - -#endif - - while (!oai_exit) { - - ue_cnt=0; - for(UE_id=0; UE_id 0) { - opt_type = OPT_PCAP; - opt_enabled=1; - printf("Enabling OPT for PCAP with the following file %s \n",in_path); - } - if (strlen(in_ip) > 0) { - opt_enabled=1; - opt_type = OPT_WIRESHARK; - printf("Enabling OPT for wireshark for local interface"); - } - - config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); - if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { - set_glog_onlinelog(online_log_messages); - } - if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { - set_glog(glog_level); - } - - if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0,NULL); - } - -#if T_TRACER - paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; - config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); -#endif - - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - memset((void*)&RC,0,sizeof(RC)); - /* Read RC configuration file */ - NRRCConfig(); - NB_gNB_INST = RC.nb_nr_inst; - NB_RU = RC.nb_RU; - printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %d\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU); - } - if(parallel_config != NULL) set_parallel_conf(parallel_config); - if(worker_config != NULL) set_worker_conf(worker_config); -} - - -#if T_TRACER -int T_nowait = 0; /* by default we wait for the tracer */ -int T_port = 2021; /* default port to listen to to wait for the tracer */ -int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ -#endif - - - -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { - - int CC_id; - - for (CC_id=0; CC_idsubframe_config.numerology_index_mu.value =1; - config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD - config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL - config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; - config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; - config[CC_id]->sch_config.physical_cell_id.value = 0; - ///dl frequency to be filled in - -/* //Set some default values that may be overwritten while reading options - frame_parms[CC_id]->frame_type = FDD; - frame_parms[CC_id]->tdd_config = 3; - frame_parms[CC_id]->tdd_config_S = 0; - frame_parms[CC_id]->N_RB_DL = 100; - frame_parms[CC_id]->N_RB_UL = 100; - frame_parms[CC_id]->Ncp = NORMAL; - frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms[CC_id]->Nid_cell = 0; - frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms[CC_id]->nb_antenna_ports_eNB = 1; - frame_parms[CC_id]->nb_antennas_tx = 1; - frame_parms[CC_id]->nb_antennas_rx = 1; - - frame_parms[CC_id]->nushift = 0; - - frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; - frame_parms[CC_id]->phich_config_common.phich_duration = normal; - // UL RS Config - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - - frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; - -// downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31. -// downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; -// downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; -// downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; - //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]); - frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0]; -*/ - } - -} - -/* -void init_openair0(void) { - - int card; - int i; - - for (card=0; cardrf_config.dl_carrier_bandwidth.value == 100) { - if (frame_parms[0]->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - } else if(config[0]->rf_config.dl_carrier_bandwidth.value == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; - } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; - } - - - if (config[0]->subframe_config.duplex_mode.value==TDD) - openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD - openair0_cfg[card].duplex_mode = duplex_mode_FDD; - - printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value, - RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value ); - openair0_cfg[card].Mod_id = 0; - - openair0_cfg[card].num_rb_dl=config[0]->rf_config.dl_carrier_bandwidth.value; - - openair0_cfg[card].clock_source = clock_source; - - - openair0_cfg[card].tx_num_channels=min(2,RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value ); - openair0_cfg[card].rx_num_channels=min(2,RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value ); - - for (i=0; i<4; i++) { - - if (irx_total_gain_dB; - - - openair0_cfg[card].configFilename = rf_config_file; - printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", - card,i, openair0_cfg[card].tx_gain[i], - openair0_cfg[card].rx_gain[i], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } - } // for loop on cards -} -*/ - -void wait_RUs(void) { - - LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); - - // wait for all RUs to be configured over fronthaul - pthread_mutex_lock(&RC.ru_mutex); - while (RC.ru_mask>0) { - pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); - printf("RC.ru_mask:%02lx\n", RC.ru_mask); - } - pthread_mutex_unlock(&RC.ru_mutex); - - LOG_I(PHY,"RUs configured\n"); -} - -void wait_gNBs(void) { - - int i,j; - int waiting=1; - - - while (waiting==1) { - printf("Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst %d)\n",RC.nb_nr_L1_inst); - usleep(50*1000); - waiting=0; - for (i=0;iconfigured==0) { - waiting=1; - break; - } - } - } - } - printf("gNB L1 are configured\n"); -} - -#if defined(ENABLE_ITTI) -/* - * helper function to terminate a certain ITTI task - */ -void terminate_task(task_id_t task_id, module_id_t mod_id) -{ - LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); - MessageDef *msg; - msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); - itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); -} - -//extern void free_transport(PHY_VARS_gNB *); -extern void nr_phy_free_RU(RU_t*); - -int stop_L1L2(module_id_t gnb_id) -{ - LOG_W(ENB_APP, "stopping nr-softmodem\n"); - oai_exit = 1; - - if (!RC.ru) { - LOG_F(ENB_APP, "no RU configured\n"); - return -1; - } - - /* stop trx devices, multiple carrier currently not supported by RU */ - if (RC.ru[gnb_id]) { - if (RC.ru[gnb_id]->rfdevice.trx_stop_func) { - RC.ru[gnb_id]->rfdevice.trx_stop_func(&RC.ru[gnb_id]->rfdevice); - LOG_I(ENB_APP, "turned off RU rfdevice\n"); - } else { - LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n"); - } - if (RC.ru[gnb_id]->ifdevice.trx_stop_func) { - RC.ru[gnb_id]->ifdevice.trx_stop_func(&RC.ru[gnb_id]->ifdevice); - LOG_I(ENB_APP, "turned off RU ifdevice\n"); - } else { - LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n"); - } - } else { - LOG_W(ENB_APP, "no RU found for index %d\n", gnb_id); - return -1; - } - - /* these tasks need to pick up new configuration */ - terminate_task(TASK_RRC_ENB, gnb_id); - terminate_task(TASK_L2L1, gnb_id); - LOG_I(ENB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id); - kill_gNB_proc(gnb_id); - LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", gnb_id); - kill_RU_proc(gnb_id); - oai_exit = 0; - for (int cc_id = 0; cc_id < RC.nb_nr_CC[gnb_id]; cc_id++) { - //free_transport(RC.gNB[gnb_id][cc_id]); - phy_free_nr_gNB(RC.gNB[gnb_id][cc_id]); - } - nr_phy_free_RU(RC.ru[gnb_id]); - free_lte_top(); - return 0; -} - -/* - * Restart the nr-softmodem after it has been soft-stopped with stop_L1L2() - */ -int restart_L1L2(module_id_t gnb_id) -{ - RU_t *ru = RC.ru[gnb_id]; - int cc_id; - MessageDef *msg_p = NULL; - - LOG_W(ENB_APP, "restarting nr-softmodem\n"); - - /* block threads */ - sync_var = -1; - - for (cc_id = 0; cc_id < RC.nb_nr_L1_CC[gnb_id]; cc_id++) { - RC.gNB[gnb_id][cc_id]->configured = 0; - } - - RC.ru_mask |= (1 << ru->idx); - /* copy the changed frame parameters to the RU */ - /* TODO this should be done for all RUs associated to this gNB */ - memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id][0]->frame_parms, sizeof(NR_DL_FRAME_PARMS)); - set_function_spec_param(RC.ru[gnb_id]); - - LOG_I(ENB_APP, "attempting to create ITTI tasks\n"); - if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { - LOG_E(RRC, "Create task for RRC eNB failed\n"); - return -1; - } else { - LOG_I(RRC, "Re-created task for RRC gNB successfully\n"); - } - if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { - LOG_E(PDCP, "Create task for L2L1 failed\n"); - return -1; - } else { - LOG_I(PDCP, "Re-created task for L2L1 successfully\n"); - } - - /* pass a reconfiguration request which will configure everything down to - * RC.eNB[i][j]->frame_parms, too */ - msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); - RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[gnb_id]->configuration; - itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); - /* TODO XForms might need to be restarted, but it is currently (09/02/18) - * broken, so we cannot test it */ - - wait_gNBs(); - init_RU_proc(ru); - ru->rf_map.card = 0; - ru->rf_map.chain = 0; /* CC_id + chain_offset;*/ - wait_RUs(); - init_eNB_afterRU(); - - printf("Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); - - return 0; -} -#endif - -static void wait_nfapi_init(char *thread_name) { - - printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); - pthread_mutex_lock( &nfapi_sync_mutex ); - - while (nfapi_sync_var<0) - pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); - - pthread_mutex_unlock(&nfapi_sync_mutex); - - printf( "NFAPI: got sync (%s)\n", thread_name); -} - -int main( int argc, char **argv ) -{ - int i; -#if defined (XFORMS) - //void *status; -#endif - - int CC_id; - int ru_id; -#if defined (XFORMS) - int ret; -#endif - - start_background_system(); - ///static configuration for NR at the moment - if ( load_configmodule(argc,argv) == NULL) { - exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); - } - -#ifdef DEBUG_CONSOLE - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); -#endif - - mode = normal_txrx; - memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); - - memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); - - set_latency_target(); - - logInit(); - - printf("Reading in command-line options\n"); - - get_options (); - if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { - fprintf(stderr,"Getting configuration failed\n"); - exit(-1); - } - openair0_cfg[0].threequarter_fs = threequarter_fs; - - -#if T_TRACER - T_Config_Init(); -#endif - - - - //randominit (0); - set_taus_seed (0); - - printf("configuring for RAU/RRU\n"); - - if (opp_enabled ==1) { - reset_opp_meas(); - } - cpuf=get_cpu_freq_GHz(); - -#if defined(ENABLE_ITTI) - - printf("ITTI init\n"); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); - - // initialize mscgen log after ITTI - MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); -#endif - - if (opt_type != OPT_NONE) { - if (init_opt(in_path, in_ip) == -1) - LOG_E(OPT,"failed to run OPT \n"); - } - -#ifdef PDCP_USE_NETLINK - printf("PDCP netlink\n"); - netlink_init(); -#if defined(PDCP_USE_NETLINK_QUEUES) - pdcp_netlink_init(); -#endif -#endif - -#if !defined(ENABLE_ITTI) - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); -#endif - - - check_clock(); - -#ifndef PACKAGE_VERSION -# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" -#endif - - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - - - - - printf("Before CC \n"); - - printf("Runtime table\n"); - fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); - - -#ifndef DEADLINE_SCHEDULER - - printf("NO deadline scheduler\n"); - /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ - - cpu_set_t cpuset; - int s; - char cpu_affinity[1024]; - CPU_ZERO(&cpuset); -#ifdef CPU_AFFINITY - int j; - if (get_nprocs() > 2) { - // CPU_SET(1, &cpuset); - for (j = 2; j < get_nprocs(); j++) - { - CPU_SET(j, &cpuset); - } - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - LOG_I(HW, "Setting the affinity of main function to all CPUs, for device library to use CPU 0 only!\n"); - } -#endif - - /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (int j = 0; j < CPU_SETSIZE; j++) { - if (CPU_ISSET(j, &cpuset)) { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - } - LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); -#endif - - - - -#if defined(ENABLE_ITTI) - if (RC.nb_nr_inst > 0) { - - // don't create if node doesn't connect to RRC/S1/GTP - if (create_gNB_tasks(1) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - printf("ITTI tasks created\n"); - } - else { - printf("No ITTI, Initializing L1\n"); - RCconfig_L1(); - } -#endif - - /* Start the agent. If it is turned off in the configuration, it won't start */ - RCconfig_nr_flexran(); - for (i = 0; i < RC.nb_nr_L1_inst; i++) { - flexran_agent_start(i); - } - - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); - - mlockall(MCL_CURRENT | MCL_FUTURE); - - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - -#ifdef XFORMS - - int UE_id; - - printf("XFORMS\n"); - - if (do_forms==1) { - fl_initialize (&argc, argv, NULL, 0, 0); - - form_stats_l2 = create_form_stats_form(); - fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - - for(UE_id=0; UE_idlte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - if (otg_enabled) { - fl_set_button(form_enb[CC_id][UE_id]->button_0,1); - fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON"); - } else { - fl_set_button(form_enb[CC_id][UE_id]->button_0,0); - fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF"); - } - } // CC_id - } // UE_id - - ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); - - if (ret == 0) - pthread_setname_np( forms_thread, "xforms" ); - - printf("Scope thread created, ret=%d\n",ret); - } - -#endif - - rt_sleep_ns(10*100000000ULL); - - if (nfapi_mode) { - - printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - } - - const char *nfapi_mode_str = ""; - - switch(nfapi_mode) { - case 0: - nfapi_mode_str = "MONOLITHIC"; - break; - case 1: - nfapi_mode_str = "PNF"; - break; - case 2: - nfapi_mode_str = "VNF"; - break; - default: - nfapi_mode_str = ""; - break; - } - printf("NFAPI MODE:%s\n", nfapi_mode_str); - - if (nfapi_mode==2) // VNF - wait_nfapi_init("main?"); - - printf("START MAIN THREADS\n"); - - // start the main threads - - number_of_cards = 1; - printf("RC.nb_nr_L1_inst:%d\n", RC.nb_nr_L1_inst); - if (RC.nb_nr_L1_inst > 0) { - printf("Initializing gNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); - init_gNB(single_thread_flag,wait_for_sync); - } - - printf("wait_gNBs()\n"); - wait_gNBs(); - - printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - if (RC.nb_RU >0) { - printf("Initializing RU threads\n"); - init_RU(rf_config_file); - for (ru_id=0;ru_idrf_map.card=0; - RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset; - } - } - - config_sync_var=0; - - if (nfapi_mode==1) { // PNF - wait_nfapi_init("main?"); - } - - printf("wait RUs\n"); - wait_RUs(); - printf("ALL RUs READY!\n"); - printf("RC.nb_RU:%d\n", RC.nb_RU); - // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) - printf("ALL RUs ready - init gNBs\n"); - - if (nfapi_mode != 1 && nfapi_mode != 2) - { - printf("Not NFAPI mode - call init_eNB_afterRU()\n"); - init_eNB_afterRU(); - } - else - { - printf("NFAPI mode - DO NOT call init_gNB_afterRU()\n"); - } - - printf("ALL RUs ready - ALL gNBs ready\n"); - - - // connect the TX/RX buffers - - - printf("Sending sync to all threads\n"); - - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); - printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); - end_configmodule(); - printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); - - // wait for end of program - printf("TYPE TO TERMINATE\n"); - fflush(stdout); - fflush(stderr); - //getchar(); - -#if defined(ENABLE_ITTI) - printf("Entering ITTI signals handler\n"); - itti_wait_tasks_end(); - printf("Returned from ITTI signal handler\n"); - oai_exit=1; - printf("oai_exit=%d\n",oai_exit); -#else - - while (oai_exit==0) - rt_sleep_ns(100000000ULL); - printf("Terminating application - oai_exit=%d\n",oai_exit); - -#endif - - // stop threads -#ifdef XFORMS -/* - printf("waiting for XFORMS thread\n"); - - if (do_forms==1) { - pthread_join(forms_thread,&status); - fl_hide_form(form_stats->stats_form); - fl_free_form(form_stats->stats_form); - - fl_hide_form(form_stats_l2->stats_form); - fl_free_form(form_stats_l2->stats_form); - - for(UE_id=0; UE_idlte_phy_scope_enb); - fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); - } - } - } -*/ -#endif - - printf("stopping MODEM threads\n"); - - // cleanup - stop_gNB(NB_gNB_INST); - stop_RU(NB_RU); - /* release memory used by the RU/gNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - for (int inst = 0; inst < NB_gNB_INST; inst++) { - for (int cc_id = 0; cc_id < RC.nb_nr_CC[inst]; cc_id++) { - //free_transport(RC.gNB[inst][cc_id]); - phy_free_nr_gNB(RC.gNB[inst][cc_id]); - } - } - for (int inst = 0; inst < NB_RU; inst++) { - nr_phy_free_RU(RC.ru[inst]); - } - free_lte_top(); - - - pthread_cond_destroy(&sync_cond); - pthread_mutex_destroy(&sync_mutex); - - pthread_cond_destroy(&nfapi_sync_cond); - pthread_mutex_destroy(&nfapi_sync_mutex); - - pthread_mutex_destroy(&ue_pf_po_mutex); - - // *** Handle per CC_id openair0 - - for(ru_id=0; ru_idrfdevice.trx_end_func) - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - if (RC.ru[ru_id]->ifdevice.trx_end_func) - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - - } - - if (opt_enabled == 1) - terminate_opt(); - - logClean(); - - printf("Bye.\n"); - - return 0; -} diff --git a/targets/RT/USER/nr-softmodem.h b/targets/RT/USER/nr-softmodem.h deleted file mode 100644 index 5ee2880f3d..0000000000 --- a/targets/RT/USER/nr-softmodem.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef NR_SOFTMODEM_H -#define NR_SOFTMODEM_H - -#define _GNU_SOURCE -#include -#include -#include -#include -#include "rt_wrapper.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "rt_wrapper.h" -#include "../../ARCH/COMMON/common_lib.h" -#undef MALLOC -#include "assertions.h" -#include "msc.h" -#include "PHY/types.h" - -#include "flexran_agent.h" -#include "PHY/defs_gNB.h" - -#if defined(ENABLE_ITTI) -#if defined(ENABLE_USE_MME) -#include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -#include "SIMULATION/ETH_TRANSPORT/proto.h" -#endif -#endif -#endif - -/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ -#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" -#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" -#define CONFIG_HLP_CALUER "set UE RX calibration\n" -#define CONFIG_HLP_CALUERM "" -#define CONFIG_HLP_CALUERB "" -#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n" -#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n" -#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n" -#define CONFIG_HLP_UERXG "set UE RX gain\n" -#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n" -#define CONFIG_HLP_UETXG "set UE TX gain\n" -#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n" -#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n" -#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n" -#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n" -#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" -#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" -#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" -#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" -#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n" -#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" -#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" -#define CONFIG_HLP_TADV "Set timing_advance\n" -#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" -#define CONFIG_HLP_CHOFF "Channel id offset\n" -#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" -#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" -#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" -#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" -#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" -#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" -#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" -#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" -#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" -#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" -#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n" -#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n" -#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n" -#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" -#define CONFIG_HLP_TPORT "tracer port\n" -#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" -#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" -#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" - -#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" -#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" -#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" -#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" - -/***************************************************************************************************************************************/ -/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument - when calling config_get or config_getlist functions */ - - -/*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters defining UE running mode */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_UEMODEPARAMS_DESC { \ -{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ -{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ -{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ -{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ -{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ -{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ -{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \ -{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \ -} -#define CMDLINE_CALIBUERX_IDX 0 -#define CMDLINE_CALIBUERXMED_IDX 1 -#define CMDLINE_CALIBUERXBYP_IDX 2 -#define CMDLINE_DEBUGUEPRACH_IDX 3 -#define CMDLINE_NOL2CONNECT_IDX 4 -#define CMDLINE_CALIBPRACHTX_IDX 5 -#define CMDLINE_MEMLOOP_IDX 6 -#define CMDLINE_DUMPMEMORY_IDX 7 -/*------------------------------------------------------------------------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters specific to UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*--------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_UEPARAMS_DESC { \ -{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ -{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \ -{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ -{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \ -{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ -{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ -{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ -{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ -{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ -} - -#define DEFAULT_DLF 2680000000 - -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_PARAMS_DESC { \ -{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ -{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ -{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ -{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ -{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ -{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ -{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ -{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ -{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ -{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \ -{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ -{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ -{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ -{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ -{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ -{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ -{"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ -{"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ -{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ -{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ -{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ -{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ -{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ -{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ -{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ -} - -#define CONFIG_HLP_FLOG "Enable online log \n" -#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n" -#define CONFIG_HLP_LOGV "Set the global log verbosity \n" -#define CONFIG_HLP_TELN "Start embedded telnet server \n" -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters for LOG utility */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_LOGPARAMS_DESC { \ -{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ -{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ -{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \ -{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ -} -#define CMDLINE_ONLINELOG_IDX 0 -#define CMDLINE_GLOGLEVEL_IDX 1 -#define CMDLINE_GLOGVERBO_IDX 2 -#define CMDLINE_STARTTELN_IDX 3 - - -extern int T_port; -extern int T_nowait; -extern int T_dont_fork; - - -/***************************************************************************************************************************************/ -/* */ -extern pthread_cond_t sync_cond; -extern pthread_mutex_t sync_mutex; -extern int sync_var; - - -extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; -extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; - -extern int rx_input_level_dBm; -extern uint8_t exit_missed_slots; -extern uint64_t num_missed_slots; // counter for the number of missed slots - -extern int oaisim_flag; -extern volatile int oai_exit; - -extern openair0_config_t openair0_cfg[MAX_CARDS]; -extern pthread_cond_t sync_cond; -extern pthread_mutex_t sync_mutex; -extern int sync_var; -extern int transmission_mode; -extern double cpuf; - -#if defined(ENABLE_ITTI) -extern volatile int start_gNB; -#endif - -#include "threads_t.h" -extern threads_t threads; - -// In nr-gnb.c -extern void init_gNB(int single_thread_flag,int wait_for_sync); -extern void stop_gNB(int); -extern void kill_gNB_proc(int inst); - -// In nr-ru.c -extern void init_RU(const char*); -extern void init_RU_proc(RU_t *ru); -extern void stop_RU(int nb_ru); -extern void kill_RU_proc(int inst); -extern void set_function_spec_param(RU_t *ru); - -extern void reset_opp_meas(void); -extern void print_opp_meas(void); - -extern void init_fep_thread(PHY_VARS_gNB *, pthread_attr_t *); - -void init_gNB_afterRU(void); - -extern int stop_L1L2(module_id_t gnb_id); -extern int restart_L1L2(module_id_t gnb_id); - -#endif - From ed5749370f58ae2bd7f9b09e4d8f317b7979be70 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 29 May 2019 20:25:03 +0200 Subject: [PATCH 33/35] removing some more unused files --- .../oaisim_build_oai/CMakeLists.template | 60 ------------- .../oaisim_mme_build_oai/CMakeLists.template | 62 ------------- .../oaisim_noS1_build_oai/CMakeLists.template | 63 ------------- executables/openairinterface5g_limits.h | 89 ------------------- 4 files changed, 274 deletions(-) delete mode 100644 cmake_targets/oaisim_build_oai/CMakeLists.template delete mode 100644 cmake_targets/oaisim_mme_build_oai/CMakeLists.template delete mode 100644 cmake_targets/oaisim_noS1_build_oai/CMakeLists.template delete mode 100644 executables/openairinterface5g_limits.h diff --git a/cmake_targets/oaisim_build_oai/CMakeLists.template b/cmake_targets/oaisim_build_oai/CMakeLists.template deleted file mode 100644 index 22faac75b5..0000000000 --- a/cmake_targets/oaisim_build_oai/CMakeLists.template +++ /dev/null @@ -1,60 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) -set ( DEBUG_OMG False ) -set ( DISABLE_XER_PRINT False ) -set ( DRIVER2013 True ) -set ( ENABLE_ITTI True ) -set ( ENABLE_NAS_UE_LOGGING True ) -set ( ENABLE_NEW_MULTICAST True ) -set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY True ) -set ( ENABLE_STANDALONE_EPC False) -set ( ENABLE_USE_CPU_EXECUTION_TIME True ) -set ( ENABLE_USE_MME True ) -set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True) -set ( ENABLE_VCD_FIFO False ) -set ( ENB_MODE True ) -set ( EXMIMO_IOT True ) -set ( JUMBO_FRAME True ) -set ( LARGE_SCALE False ) -set ( LINK_ENB_PDCP_TO_GTPV1U True) -set ( LINUX_LIST False ) -set ( LINUX True ) -set ( LOCALIZATION False ) -set ( LOG_NO_THREAD True ) -set ( DEADLINE_SCHEDULER False ) -set ( MAC_CONTEXT 1 ) -set ( MAX_NUM_CCs 1 ) -set ( MESSAGE_CHART_GENERATOR False) -set ( MSG_PRINT False ) -set ( MU_RECEIVER False ) -set ( NAS_ADDRESS_FIX False ) -set ( NAS_BUILT_IN_UE True) -set ( NAS_MME False ) -set ( NAS_UE True ) -set ( NB_ANTENNAS_RX "2" ) -set ( NB_ANTENNAS_TX "2" ) -set ( NO_RRM True ) -set ( OAISIM True ) -set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) -set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR2 True ) -set ( OPENAIR_LTE True ) -set ( PACKAGE_NAME "oaisim" ) -set ( PDCP_USE_NETLINK True ) -set ( PDCP_MSG_PRINT False ) -set ( PHY_CONTEXT False ) -set ( PHY_EMUL False ) -set ( PHYSIM True ) -set ( RF_BOARD "False" ) -set ( RLC_STOP_ON_LOST_PDU False ) -set ( RRC_ASN1_VERSION "Rel10" ) -set ( RRC_DEFAULT_RAB_IS_AM True) -set ( RRC_MSG_PRINT False ) -set ( SECU False ) -set ( SMBV False ) -set ( TEST_OMG False ) -set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) -set ( USE_MME "R10" ) -set ( XER_PRINT False ) diff --git a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template b/cmake_targets/oaisim_mme_build_oai/CMakeLists.template deleted file mode 100644 index b18b23ee9a..0000000000 --- a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template +++ /dev/null @@ -1,62 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) -set ( DEBUG_OMG False ) -set ( DISABLE_XER_PRINT False ) -set ( DRIVER2013 False ) -set ( ENABLE_ITTI True ) -set ( ENABLE_NAS_UE_LOGGING False ) -set ( ENABLE_NEW_MULTICAST False ) -set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY False ) -set ( ENABLE_STANDALONE_EPC False ) -set ( ENABLE_USE_CPU_EXECUTION_TIME False ) -set ( ENABLE_USE_MME False ) -set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True) -set ( ENABLE_VCD_FIFO False ) -set ( ENB_MODE False ) -set ( EPC_BUILD True ) -set ( EXMIMO_IOT False ) -set ( JUMBO_FRAME False ) -set ( LARGE_SCALE False ) -set ( LINK_ENB_PDCP_TO_GTPV1U True) -set ( LINUX_LIST False ) -set ( LINUX False ) -set ( LOCALIZATION False ) -set ( LOG_NO_THREAD False ) -set ( DEADLINE_SCHEDULER False ) -set ( MAC_CONTEXT 1 ) -set ( MAX_NUM_CCs 1 ) -set ( MSG_PRINT False ) -set ( MU_RECEIVER False ) -set ( NAS_ADDRESS_FIX False ) -set ( NAS_BUILT_IN_EPC True ) -set ( NAS_MME True ) -set ( NAS_NETLINK False ) -set ( NAS_UE False ) -set ( NB_ANTENNAS_RX "2" ) -set ( NB_ANTENNAS_TX "2" ) -set ( NO_RRM False ) -set ( OAISIM False ) -set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) -set ( OAI_NW_DRIVER_USE_NETLINK False ) -set ( OPENAIR2 False ) -set ( OPENAIR_LTE False ) -set ( PACKAGE_NAME "EPC" ) -set ( PDCP_MSG_PRINT False ) -set ( PHY_CONTEXT False ) -set ( PHY_EMUL False ) -set ( PHYSIM False ) -set ( RF_BOARD "False" ) -set ( RRC_ASN1_VERSION "Rel10" ) -set ( RLC_STOP_ON_LOST_PDU False ) -set ( RRC_MSG_PRINT False ) -set ( SECU False ) -set ( SMBV False ) -set ( TEST_OMG False ) -set ( UPDATE_RELEASE_9 True) -set ( UPDATE_RELEASE_10 True) -set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) -set ( USE_MME "R10" ) -set ( XER_PRINT False ) -set ( XFORMS False ) diff --git a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template deleted file mode 100644 index bc416cff55..0000000000 --- a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template +++ /dev/null @@ -1,63 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set ( DEBUG_OMG False ) -set ( DISABLE_XER_PRINT False ) -set ( DRIVER2013 True ) -set ( ENABLE_ITTI True ) -set ( ENABLE_NAS_UE_LOGGING False ) -set ( ENABLE_NEW_MULTICAST True ) -set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY False ) -set ( ENABLE_STANDALONE_EPC False) -set ( ENABLE_USE_CPU_EXECUTION_TIME True ) -set ( ENABLE_USE_MME False ) -set ( ENABLE_USE_RAW_SOCKET_FOR_SGI False) -set ( ENABLE_VCD_FIFO False ) -set ( ENB_MODE True ) -set ( EXMIMO_IOT True ) -set ( JUMBO_FRAME True ) -set ( LARGE_SCALE False ) -set ( LINK_ENB_PDCP_TO_GTPV1U False) -set ( LINUX_LIST False ) -set ( LINUX True ) -set ( LOCALIZATION False ) -set ( LOG_NO_THREAD 1 ) -set ( DEADLINE_SCHEDULER False ) -set ( MAC_CONTEXT 1 ) -set ( MAX_NUM_CCs 1 ) -set ( MESSAGE_CHART_GENERATOR False ) -set ( MESSAGE_CHART_GENERATOR_RLC_MAC False ) -set ( MESSAGE_CHART_GENERATOR_PHY False ) -set ( MSG_PRINT False ) -set ( MU_RECEIVER False ) -set ( NAS_ADDRESS_FIX False ) -set ( NAS_BUILT_IN_UE False) -set ( NAS_MME False ) -set ( NAS_UE False ) -set ( NB_ANTENNAS_RX "2" ) -set ( NB_ANTENNAS_TX "2" ) -set ( NO_RRM True ) -set ( OAISIM True ) -set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) -set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR2 True ) -set ( OPENAIR_LTE True ) -set ( PACKAGE_NAME "oaisim" ) -set ( PDCP_USE_NETLINK True ) -set ( PDCP_MSG_PRINT False ) -set ( PHY_CONTEXT False ) -set ( PHY_EMUL False ) -set ( PHYSIM True ) -set ( RF_BOARD "False" ) -set ( RRC_ASN1_VERSION "Rel10" ) -set ( RLC_STOP_ON_LOST_PDU False ) -set ( RRC_MSG_PRINT False ) -set ( SECU False ) -set ( SMBV False ) -set ( TEST_OMG False ) -set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) -set ( USE_MME "R10" ) -set ( XER_PRINT False ) -set ( DEBUG_PHY False ) -set ( DEBUG_PHY_PROC False) -set ( DEBUG_DLSCH False) diff --git a/executables/openairinterface5g_limits.h b/executables/openairinterface5g_limits.h deleted file mode 100644 index 53ee79a61d..0000000000 --- a/executables/openairinterface5g_limits.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef OPENAIRINTERFACE5G_LIMITS_H_ -#define OPENAIRINTERFACE5G_LIMITS_H_ - -#if 1 /*defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)*/ - #define NUMBER_OF_eNB_MAX 1 - #define NUMBER_OF_gNB_MAX 1 - #define NUMBER_OF_RU_MAX 2 - #define NUMBER_OF_NR_RU_MAX 2 - #ifndef PHYSIM - #ifndef UE_EXPANSION - #define NUMBER_OF_UE_MAX 16 - #define NUMBER_OF_NR_UE_MAX 16 - #define NUMBER_OF_CONNECTED_eNB_MAX 3 - #define NUMBER_OF_CONNECTED_gNB_MAX 3 - #else - #define NUMBER_OF_UE_MAX 256 - #define NUMBER_OF_NR_UE_MAX 256 - #define NUMBER_OF_CONNECTED_eNB_MAX 1 - #define NUMBER_OF_CONNECTED_gNB_MAX 1 - #endif - #else - #define NUMBER_OF_UE_MAX 1 - #define NUMBER_OF_NR_UE_MAX 1 - #define NUMBER_OF_CONNECTED_eNB_MAX 1 - #define NUMBER_OF_CONNECTED_gNB_MAX 1 - #endif -#else - #define NUMBER_OF_eNB_MAX 7 - #define NUMBER_OF_gNB_MAX 7 - #define NUMBER_OF_RU_MAX 32 - #define NUMBER_OF_NR_RU_MAX 32 - #ifndef UE_EXPANSION - #define NUMBER_OF_UE_MAX 20 - #define NUMBER_OF_NR_UE_MAX 20 - #define NUMBER_OF_CONNECTED_eNB_MAX 3 - #define NUMBER_OF_CONNECTED_gNB_MAX 3 - #else - #define NUMBER_OF_UE_MAX 256 - #define NUMBER_OF_NR_UE_MAX 256 - #define NUMBER_OF_CONNECTED_eNB_MAX 1 - #define NUMBER_OF_CONNECTED_gNB_MAX 1 - #endif - #if defined(STANDALONE) && STANDALONE==1 - #undef NUMBER_OF_eNB_MAX - #undef NUMBER_OF_gNB_MAX - - #undef NUMBER_OF_UE_MAX - #undef NUMBER_OF_NR_UE_MAX - - #undef NUMBER_OF_RU_MAX - #undef NUMBER_OF_NR_RU_MAX - - #define NUMBER_OF_eNB_MAX 3 - #define NUMBER_OF_gNB_MAX 3 - - #define NUMBER_OF_UE_MAX 3 - #define NUMBER_OF_NR_UE_MAX 3 - - #define NUMBER_OF_RU_MAX 3 - #define NUMBER_OF_NR_RU_MAX 3 - #endif - #if defined(LARGE_SCALE) && LARGE_SCALE - #undef NUMBER_OF_eNB_MAX - #undef NUMBER_OF_gNB_MAX - - #undef NUMBER_OF_UE_MAX - #undef NUMBER_OF_NR_UE_MAX - - #undef NUMBER_OF_CONNECTED_eNB_MAX - #undef NUMBER_OF_CONNECTED_gNB_MAX - - #undef NUMBER_OF_RU_MAX - #undef NUMBER_OF_NR_RU_MAX - - #define NUMBER_OF_eNB_MAX 2 - #define NUMBER_OF_gNB_MAX 2 - - #define NUMBER_OF_UE_MAX 120 - #define NUMBER_OF_NR_UE_MAX 120 - - #define NUMBER_OF_RU_MAX 16 - #define NUMBER_OF_NR_RU_MAX 16 - - #define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory - #define NUMBER_OF_CONNECTED_gNB_MAX 1 - #endif -#endif - -#endif /* OPENAIRINTERFACE5G_LIMITS_H_ */ From 02a2f909da65498425a544de982acc6482c3d5f5 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Sat, 1 Jun 2019 01:28:36 +0200 Subject: [PATCH 34/35] fixing a bug for gNB single thread operation (harmonizing with eNB) --- executables/nr-ru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 58272eeaa0..9f84b3ed3a 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1445,7 +1445,7 @@ static void *ru_thread( void *param ) { // wakeup all gNB processes waiting for this RU if (ru->num_gNB>0) wakeup_gNB_L1s(ru); - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB==0) { + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) { // 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); From 7e57a8428ed685b993e91a1e6b7d77aaf65ab938 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Sat, 1 Jun 2019 04:08:00 +0200 Subject: [PATCH 35/35] fixing some more bad merges --- targets/COMMON/openairinterface5g_limits.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 92e89eb1da..9645acf4dd 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -6,14 +6,12 @@ # define NUMBER_OF_gNB_MAX 1 # define NUMBER_OF_RU_MAX 2 # define NUMBER_OF_NR_RU_MAX 2 -# define NUMBER_OF_NR_DLSCH_MAX 16 -# define NUMBER_OF_NR_ULSCH_MAX 16 # ifndef PHYSIM # ifndef UE_EXPANSION -# define NUMBER_OF_UE_MAX 4 -# define NUMBER_OF_NR_UE_MAX 4 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -# define NUMBER_OF_CONNECTED_gNB_MAX 1 +# define NUMBER_OF_UE_MAX 16 +# define NUMBER_OF_NR_UE_MAX 16 +# define NUMBER_OF_CONNECTED_eNB_MAX 3 +# define NUMBER_OF_CONNECTED_gNB_MAX 3 # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_NR_UE_MAX 256