From 895f54a9383d34105de48602940a68340236fa75 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 2 Dec 2020 20:15:38 +0100 Subject: [PATCH 1/4] added no_DTX function to eNB. This fills the TX subframes which have no PDSCH with a fake pdsch. It avoids switching between TX/RX in TDD systems during the DL periods. --- openair1/PHY/INIT/lte_init.c | 29 +++++++++++++++++++++++++ openair1/PHY/defs_eNB.h | 3 +++ openair1/SCHED/phy_procedures_lte_eNb.c | 6 ++++- targets/RT/USER/lte-enb.c | 2 ++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 2c7e3e88eb..943e6cdddb 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -347,6 +347,31 @@ void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx, lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); } +void fill_subframe_mask(PHY_VARS_eNB *eNB) { + + AssertFatal(eNB->subframe_mask!=NULL,"Subframe mask is null\n"); + int32_t **dummy_tx=eNB->common_vars.txdataF; + eNB->common_vars.txdataF = eNB->subframe_mask; + + for (int sf=0;sf<10;sf++) { + if (subframe_select(&eNB->frame_parms,sf)==SF_DL) { + LTE_DL_eNB_HARQ_t *dlsch_harq=eNB->dlsch[0][0]->harq_processes[0]; + L1_rxtx_proc_t proc; + proc.frame_tx=0; + proc.subframe_tx=sf; + eNB->dlsch[0][0]->harq_ids[0][sf]=0; + eNB->dlsch[0][0]->rnti=0x1234; + dlsch_harq->nb_rb=12; + dlsch_harq->rb_alloc[0]=0xfff; + dlsch_harq->Qm=2; + dlsch_harq->Nl=1; + dlsch_harq->pdsch_start=1; + dlsch_harq->mimo_mode=(eNB->frame_parms.nb_antenna_ports_eNB>1) ? ALAMOUTI : SISO; + pdsch_procedures(eNB,&proc,0,eNB->dlsch[0][0]); + } + } + eNB->common_vars.txdataF = dummy_tx; +} int phy_init_lte_eNB(PHY_VARS_eNB *eNB, unsigned char is_secondary_eNB, @@ -400,6 +425,9 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, if (NFAPI_MODE!=NFAPI_MODE_VNF) { common_vars->rxdata = (int32_t **)NULL; common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t *)); + if (eNB->use_DTX==0) { + eNB->subframe_mask = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t *)); + } common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *)); LOG_I(PHY,"[INIT] NB_ANTENNA_PORTS_ENB:%d fp->nb_antenna_ports_eNB:%d\n", NB_ANTENNA_PORTS_ENB, fp->nb_antenna_ports_eNB); @@ -409,6 +437,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, LOG_I(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", i,common_vars->txdataF[i], fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t)); + if (inb_antenna_ports_eNB) eNB->subframe_mask[i] = malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); } } diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index f1021ead9b..1f18f114de 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -517,6 +517,9 @@ typedef struct PHY_VARS_eNB_s { uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE char eNB_generate_rar; + /// indicator that eNB signal generation uses DTX (i.e. signal is cleared in each subframe + int use_DTX; + int32_t **subframe_mask; /// Indicator set to 0 after first SR uint8_t first_sr[NUMBER_OF_UE_MAX]; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a37f95bcb3..a4e87d4981 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -521,7 +521,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, // clear the transmit data array for the current subframe for (aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) { - memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], 0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t)); + if (eNB->use_DTX==0) + memcpy(&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], + &eNB->subframe_mask[aa][subframe*fp->ofdm_symbol_size*fp->symbols_per_tti], + fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t)); + else memset(&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], 0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t)); } if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 1347d75fb0..dd69cc95e1 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1134,6 +1134,8 @@ void init_transport(PHY_VARS_eNB *eNB) { eNB->FULL_MUMIMO_transmissions = 0; eNB->check_for_SUMIMO_transmissions = 0; fp->pucch_config_common.deltaPUCCH_Shift = 1; + if (eNB->use_DTX == 0) fill_subframe_mask(eNB); + } From 0571020666695a04ab268751b6d695618f97a13a Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 3 Dec 2020 10:44:12 +0100 Subject: [PATCH 2/4] minor modifications in T_defs.h and for constant power (i.e. no DTX in TX subframes for TDD) --- common/utils/T/T_defs.h | 4 ++-- openair1/PHY/INIT/lte_init.c | 9 ++++++--- openair1/SCHED/phy_procedures_lte_eNb.c | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 7b5304b1cb..2f7e6e7570 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ /* let's have 100 RBs functional for the basic simulator */ # define T_BUFFER_MAX (1024*64*2) #else -# define T_BUFFER_MAX (1024*64) +# define T_BUFFER_MAX (1024*64*2) #endif /* size of the local cache for messages (must be pow(2,something)) */ @@ -52,7 +52,7 @@ /* we don't need much space for the basic simulator */ # define T_CACHE_SIZE 1024 #else -# define T_CACHE_SIZE (8192 * 2) +# define T_CACHE_SIZE (8192 ) #endif /* maximum number of bytes a message can contain */ diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 943e6cdddb..3603a5e672 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -361,13 +361,15 @@ void fill_subframe_mask(PHY_VARS_eNB *eNB) { proc.subframe_tx=sf; eNB->dlsch[0][0]->harq_ids[0][sf]=0; eNB->dlsch[0][0]->rnti=0x1234; - dlsch_harq->nb_rb=12; - dlsch_harq->rb_alloc[0]=0xfff; + dlsch_harq->nb_rb=48; + dlsch_harq->rb_alloc[0]=0xffffffffffff; dlsch_harq->Qm=2; dlsch_harq->Nl=1; dlsch_harq->pdsch_start=1; dlsch_harq->mimo_mode=(eNB->frame_parms.nb_antenna_ports_eNB>1) ? ALAMOUTI : SISO; - pdsch_procedures(eNB,&proc,0,eNB->dlsch[0][0]); + dlsch_harq->dl_power_off = 1; + computeRhoB_eNB(4,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,eNB->dlsch[0][0],dlsch_harq->dl_power_off); + pdsch_procedures(eNB,&proc,0,eNB->dlsch[0][0],NULL); } } eNB->common_vars.txdataF = dummy_tx; @@ -422,6 +424,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, eNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. + eNB->use_DTX=0; if (NFAPI_MODE!=NFAPI_MODE_VNF) { common_vars->rxdata = (int32_t **)NULL; common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t *)); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a4e87d4981..a264ee31a2 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -480,6 +480,8 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, subframe<<1); stop_meas(&eNB->dlsch_scrambling_stats); start_meas(&eNB->dlsch_modulation_stats); + if (frame==0) LOG_I(PHY,"Generating pdsch for %d.%d starting in symbol %d, Qm %d, nb_rb %d, rbmask %x\n", + frame,subframe,dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]); dlsch_modulation(eNB, eNB->common_vars.txdataF, AMP, From 7185b95591eaf63ac302ef690b686da0fdbd79e0 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 24 Dec 2020 16:10:03 +0100 Subject: [PATCH 3/4] debugging with AW2S RRU. Added statistics for ULSCH/UCI in PHY and MAC. --- cmake_targets/CMakeLists.txt | 6 + common/utils/lte/ue_power.c | 108 +++++++++ common/utils/lte/ue_power.h | 34 +++ .../PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c | 8 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 +- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 1 + openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 6 +- openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c | 3 - openair1/PHY/LTE_TRANSPORT/if5_tools.c | 2 +- openair1/PHY/LTE_TRANSPORT/prach.c | 31 ++- openair1/PHY/LTE_TRANSPORT/prach_common.c | 14 +- openair1/PHY/LTE_TRANSPORT/prach_extern.h | 11 - openair1/PHY/LTE_TRANSPORT/pucch.c | 207 ++++++++++++------ .../LTE_TRANSPORT/transport_common_proto.h | 8 +- openair1/PHY/LTE_TRANSPORT/transport_proto.h | 2 - openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 68 ++++++ .../PHY/LTE_TRANSPORT/ulsch_demodulation.c | 4 + openair1/PHY/defs_eNB.h | 49 ++++- openair1/SCHED/phy_procedures_lte_common.c | 67 ------ openair1/SCHED/phy_procedures_lte_eNb.c | 77 +++++-- openair1/SCHED/prach_procedures.c | 2 +- openair1/SCHED/ru_procedures.c | 27 +-- openair2/COMMON/platform_constants.h | 5 + openair2/LAYER2/MAC/eNB_scheduler.c | 6 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 21 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 5 +- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 114 +++------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 78 ++++--- openair2/LAYER2/MAC/mac.h | 4 +- openair2/LAYER2/MAC/pre_processor.c | 6 +- openair2/LAYER2/MAC/rar_tools.c | 6 +- targets/RT/USER/lte-enb.c | 3 + 32 files changed, 635 insertions(+), 352 deletions(-) create mode 100644 common/utils/lte/ue_power.c create mode 100644 common/utils/lte/ue_power.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 94d55d5fe5..2dcc318179 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2863,6 +2863,8 @@ add_executable(lte-softmodem ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_DIR}/common/utils/lte/ue_power.c + ${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} @@ -2904,6 +2906,8 @@ add_executable(ocp-enb ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_DIR}/common/utils/lte/ue_power.c + ${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} @@ -2970,6 +2974,8 @@ add_executable(lte-uesoftmodem ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_DIR}/common/utils/lte/ue_power.c + ${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} diff --git a/common/utils/lte/ue_power.c b/common/utils/lte/ue_power.c new file mode 100644 index 0000000000..b377abf2ff --- /dev/null +++ b/common/utils/lte/ue_power.c @@ -0,0 +1,108 @@ +/* + * 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 ue_power.c +* \brief Routines to compute UE TX power according to 36.213 +* \author R. Knopp, F. Kaltenberger +* \date 2020 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#include +#include +#include "PHY/defs_eNB.h" +#include "PHY/TOOLS/dB_routines.h" + +extern int16_t hundred_times_delta_TF[100]; +extern uint16_t hundred_times_log10_NPRB[100]; + +int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, int ncp, uint8_t use_srs) +{ + + /// The payload + CRC size in bits, "B" + uint32_t B; + /// Number of code segments + uint32_t C; + /// Number of "small" code segments + uint32_t Cminus; + /// Number of "large" code segments + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) + uint32_t Kplus; + /// Total number of bits across all segments + uint32_t sumKr; + /// Number of "Filler" bits + uint32_t F; + // num resource elements + uint32_t num_re=0.0; + // num symbols + uint32_t num_symb=0.0; + /// effective spectral efficiency of the PUSCH + uint32_t MPR_x100=0; + /// beta_offset + uint16_t beta_offset_pusch_x8=8; + /// delta mcs + float delta_mcs=0.0; + /// bandwidth factor + float bw_factor=0.0; + + B= tbs+24; + lte_segmentation(NULL, + NULL, + B, + &C, + &Cplus, + &Cminus, + &Kplus, + &Kminus, + &F); + + + sumKr = Cminus*Kminus + Cplus*Kplus; + num_symb = 12-(ncp<<1)-(use_srs==0?0:1); + num_re = num_symb * nb_rb * 12; + + if (num_re == 0) + return(0); + + MPR_x100 = 100*sumKr/num_re; + + if (control_only == 1 ) + beta_offset_pusch_x8=8; // fixme + + //(beta_offset_pusch_x8=ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; + + // if deltamcs_enabledm + delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0); + + bw_factor = (norm!=0) ? 0 : (hundred_times_log10_NPRB[nb_rb-1]/100.0); + LOG_D(PHY,"estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n", + (int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor); + return (int16_t)ceil(delta_mcs + bw_factor); + +} + diff --git a/common/utils/lte/ue_power.h b/common/utils/lte/ue_power.h new file mode 100644 index 0000000000..caeebec2c8 --- /dev/null +++ b/common/utils/lte/ue_power.h @@ -0,0 +1,34 @@ +/* + * 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 ue_power.h +* \brief support routines used in MAC and PHY +* \author R. Knopp, F. Kaltenberger +* \date 2020 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs); + diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c index f85162e095..367b700085 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c @@ -118,8 +118,8 @@ int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms, int temp, i, aa, max_pos=0, max_val=0; short Re,Im; - uint8_t cyclic_shift = 0; - int sync_pos = (frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size); + // uint8_t cyclic_shift = 0; + int sync_pos = 0;//(frame_parms->ofdm_symbol_size-cyclic_shift*frame_parms->ofdm_symbol_size/12)%(frame_parms->ofdm_symbol_size); AssertFatal(frame_parms->ofdm_symbol_size > 127,"frame_parms->ofdm_symbol_size %d<128\n",frame_parms->ofdm_symbol_size); AssertFatal(frame_parms->nb_antennas_rx >0 && frame_parms->nb_antennas_rx<3,"frame_parms->nb_antennas_rx %d not in [0,1]\n", @@ -142,9 +142,5 @@ int lte_est_timing_advance_pusch(LTE_DL_FRAME_PARMS *frame_parms, if (max_pos>frame_parms->ofdm_symbol_size/2) max_pos = max_pos-frame_parms->ofdm_symbol_size; - //#ifdef DEBUG_PHY - LOG_D(PHY,"max_pos = %d, sync_pos=%d\n",max_pos,sync_pos); - //#endif //DEBUG_PHY - return max_pos - sync_pos; } diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 8de011acef..dea0c27911 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -476,7 +476,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB, ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); + LOG_D(PHY,"TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_20MHz_FDD_t; ((DCI1A_20MHz_FDD_t *)dci_pdu)->type = 1; @@ -535,7 +535,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB, dlsch0->harq_mask |= (1 << rel8->harq_process); - if (rel8->rnti_type == 1) LOG_D(PHY,"DCI 1A: round %d, mcs %d, TBS %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,dlsch0_harq->TBS,rel8->resource_block_coding, + if (rel8->rnti != SI_RNTI) LOG_I(PHY,"DCI 1A: round %d, mcs %d, TBS %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,dlsch0_harq->TBS,rel8->resource_block_coding, rel8->redundancy_version_1,rel8->rnti,rel8->harq_process); break; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 3eb44d98fa..bba402d34a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -360,6 +360,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, proc->nbEncode=0; + // if (hadlsch->Ndi == 1) { // this is a new packet if (hadlsch->round == 0) { // this is a new packet // Add 24-bit crc (polynomial A) to payload diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 347fbb026b..c6a4e4f990 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2375,16 +2375,14 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, for (l=num_pdcch_symbols; lmimo_mode, pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), mod_order0, mod_order1, rb_alloc[0] ); -#endif } if (frame_parms->Ncp==0) { // normal prefix diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index d48164e07d..294dab45c0 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -113,9 +113,6 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1 for PMCH } -#ifdef DEBUG_SCRAMBLING - printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); -#endif s = lte_gold_generic(&x1, &x2, 1); for (n=0; n<(1+(G>>5)); n++) { diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index f39f3ef872..e78e3934a2 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -1469,7 +1469,7 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 // HYPOTHESIS: first packet per subframe has lowest timestamp of subframe // should detect out of order and act accordingly .... AssertFatal(aid==0 || aid==1,"aid %d != 0 or 1\n",aid); - //LOG_I(PHY,"rxp[%d] %p, dest %p, offset %d (%lld,%lld)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(timestamp[packet_id]-timestamp[0]),timestamp[packet_id],timestamp[0]); + LOG_D(PHY,"rxp[%d] %p, dest %p, offset %d (%lld,%lld)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(int)(timestamp[packet_id]-timestamp[0]),timestamp[packet_id],timestamp[0]); memcpy((void*)(rxp[aid]+(timestamp[packet_id]-timestamp[0])), (void*)temp_rx, spp_eth<<2); diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 31e97741fd..c67c37ef64 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -40,6 +40,7 @@ #include "prach_extern.h" #include #include +#include "common/utils/lte/prach_utils.h" void rx_prach0(PHY_VARS_eNB *eNB, RU_t *ru, @@ -112,7 +113,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, prach_ConfigIndex = fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[ce_level]; Ncs_config = fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; restricted_set = fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag; - n_ra_prb = get_prach_prb_offset(fp,prach_ConfigIndex, + n_ra_prb = get_prach_prb_offset(fp->frame_type,fp->tdd_config,fp->N_RB_UL,fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[ce_level], fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level], tdd_mapindex,Nf); // update pointers to results for ce_level @@ -124,7 +125,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag; - n_ra_prb = get_prach_prb_offset(fp,prach_ConfigIndex, + n_ra_prb = get_prach_prb_offset(fp->frame_type,fp->tdd_config,fp->N_RB_UL,fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset, tdd_mapindex,Nf); } @@ -140,7 +141,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, rxsigF = eNB->prach_vars_br.rxsigF[ce_level]; if (LOG_DEBUGFLAG(PRACH)) { - if (((frame_prach)&1023) < 20) LOG_I(PHY, + if (((frame_prach)&1023) < 20) LOG_D(PHY, "PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n", br_flag,ce_level,frame_prach,subframe, fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level], @@ -153,24 +154,24 @@ void rx_prach0(PHY_VARS_eNB *eNB, prachF = eNB->prach_vars.prachF; rxsigF = eNB->prach_vars.rxsigF[0]; - if (LOG_DEBUGFLAG(PRACH)) { - if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe, + //if (LOG_DEBUGFLAG(PRACH)) { + if (((frame_prach)&1023) < 20) LOG_D(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe, fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex); - } + //} } } else { if (br_flag == 1) { rxsigF = ru->prach_rxsigF_br[ce_level]; if (LOG_DEBUGFLAG(PRACH)) { - if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", + if (((frame_prach)&1023) < 20) LOG_D(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex); } } else { rxsigF = ru->prach_rxsigF[0]; if (LOG_DEBUGFLAG(PRACH)) { - if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", + if (((frame_prach)&1023) < 20) LOG_D(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex); } } @@ -299,11 +300,13 @@ void rx_prach0(PHY_VARS_eNB *eNB, case 6: if (prach_fmt == 4) { dft(DFT_256,prach2,rxsigF[aa],1); + fft_size=256; } else { dft(DFT_1536,prach2,rxsigF[aa],1); if (prach_fmt>1) dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); + fft_size=1536; } break; @@ -311,13 +314,14 @@ void rx_prach0(PHY_VARS_eNB *eNB, case 15: if (prach_fmt == 4) { dft(DFT_256,prach2,rxsigF[aa],1); + fft_size=256; } else { dft(DFT_3072,prach2,rxsigF[aa],1); if (prach_fmt>1) dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); } - + fft_size=3072; break; case 25: @@ -339,11 +343,13 @@ void rx_prach0(PHY_VARS_eNB *eNB, case 50: if (prach_fmt == 4) { dft(DFT_2048,prach2,rxsigF[aa],1); + fft_size=2048; } else { dft(DFT_12288,prach2,rxsigF[aa],1); if (prach_fmt>1) dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1); + fft_size=12288; } break; @@ -351,11 +357,13 @@ void rx_prach0(PHY_VARS_eNB *eNB, case 75: if (prach_fmt == 4) { dft(DFT_3072,prach2,rxsigF[aa],1); + fft_size=3072; } else { dft(DFT_18432,prach2,rxsigF[aa],1); if (prach_fmt>1) dft(DFT_18432,prach2+36864,rxsigF[aa]+36864,1); + fft_size=18432; } break; @@ -364,20 +372,24 @@ void rx_prach0(PHY_VARS_eNB *eNB, if (fp->threequarter_fs==0) { if (prach_fmt == 4) { dft(DFT_4096,prach2,rxsigF[aa],1); + fft_size=2048; } else { dft(DFT_24576,prach2,rxsigF[aa],1); if (prach_fmt>1) dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1); + fft_size=24576; } } else { if (prach_fmt == 4) { dft(DFT_3072,prach2,rxsigF[aa],1); + fft_size=3072; } else { dft(DFT_18432,prach2,rxsigF[aa],1); if (prach_fmt>1) dft(DFT_18432,prach2+36864,rxsigF[aa]+36864,1); + fft_size=18432; } } @@ -547,7 +559,6 @@ void rx_prach0(PHY_VARS_eNB *eNB, } log2_ifft_size = 10; - fft_size = 6144; if (new_dft == 1) { new_dft = 0; diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c index 393d4ca3f8..db5d524140 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach_common.c +++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c @@ -34,7 +34,7 @@ #include "PHY/phy_extern.h" #include "PHY/phy_extern_ue.h" #include "common/utils/LOG/vcd_signal_dumper.h" - +#include "common/utils/lte/prach_utils.h" uint16_t NCS_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; uint16_t NCS_restricted[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case @@ -44,6 +44,9 @@ int16_t ru[2*839]; // quantized roots of unity uint32_t ZC_inv[839]; // multiplicative inverse for roots u uint16_t du[838]; +extern PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7]; + +/* // This is table 5.7.1-4 from 36.211 PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = { // TDD Configuration Index 0 @@ -254,7 +257,7 @@ PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = { } }; - +*/ uint16_t prach_root_sequence_map0_3[838] = { 129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84, 755, 105, 734, 93, 746, 70, 769, 60, 779, 2, 837, 1, 838, @@ -377,7 +380,7 @@ uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index) { LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][0]->frame_parms; return(tdd_preamble_map[fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex][fp->tdd_config].map[tdd_map_index].f_ra); } - +/* uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type) { if (frame_type == FDD) // FDD return(prach_ConfigIndex>>4); @@ -556,14 +559,15 @@ int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex return(prach_mask); } +*/ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe) { uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - int prach_mask = is_prach_subframe0(frame_parms, prach_ConfigIndex, frame, subframe); + int prach_mask = is_prach_subframe0(frame_parms->tdd_config,frame_parms->frame_type, prach_ConfigIndex, frame, subframe); for (int i=0; i<4; i++) { if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1) - prach_mask |= (is_prach_subframe0(frame_parms, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i], + prach_mask |= (is_prach_subframe0(frame_parms->tdd_config,frame_parms->frame_type, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i], frame, subframe) << (i+1)); } diff --git a/openair1/PHY/LTE_TRANSPORT/prach_extern.h b/openair1/PHY/LTE_TRANSPORT/prach_extern.h index 47fbd93ad7..c9ff902260 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach_extern.h +++ b/openair1/PHY/LTE_TRANSPORT/prach_extern.h @@ -74,17 +74,6 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id); uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index); -uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type); - - -uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t prach_ConfigIndex, - uint8_t n_ra_prboffset, - uint8_t tdd_mapindex, uint16_t Nf); - - -int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe); - int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe); diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 8637e80137..627d51314c 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -65,6 +65,29 @@ int16_t cfo_pucch_ep[24*6] = {24278,-22005,29621,-14010,32412,-4808,32412,4807,2 +void dump_uci_stats(PHY_VARS_eNB *eNB,int frame) { + + for (int i=0;iuci_stats[i].rnti>0) { + eNB_UCI_STATS_t *uci_stats = &eNB->uci_stats[i]; + LOG_I(PHY,"UCI RNTI %x: pucch1_trials %d, pucch1_thres %d dB, current pucch1_stat %d dB,positive SR count %d\n", + uci_stats->rnti,uci_stats->pucch1_trials,uci_stats->pucch1_thres,dB_fixed(uci_stats->current_pucch1_stat),uci_stats->pucch1_positive_SR); + LOG_I(PHY,"UCI RNTI %x: pucch1_low (%d,%d)dB pucch1_high (%d,%d)dB\n", + uci_stats->rnti, + dB_fixed(uci_stats->pucch1_low_stat[0]), + dB_fixed(uci_stats->pucch1_low_stat[1]), + dB_fixed(uci_stats->pucch1_high_stat[0]), + dB_fixed(uci_stats->pucch1_high_stat[1])); + + LOG_I(PHY,"UCI RNTI %x: pucch1a_trials %d, pucch1a_stat (%d,%d) pucch1ab_DTX %d\n", + uci_stats->rnti, + uci_stats->pucch1a_trials, + uci_stats->current_pucch1a_stat_re, + uci_stats->current_pucch1a_stat_im, + uci_stats->pucch1ab_DTX); + } + +} /* PUCCH format3 >> */ /* SubCarrier Demap */ uint16_t pucchfmt3_subCarrierDeMapping( PHY_VARS_eNB *eNB, @@ -725,7 +748,7 @@ int16_t pucchfmt3_Decode( int16_t b[48], uint32_t rx_pucch(PHY_VARS_eNB *eNB, PUCCH_FMT_t fmt, - uint8_t UE_id, + uint8_t UCI_id, uint16_t n1_pucch, uint16_t n2_pucch, uint8_t shortened_format, @@ -747,7 +770,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, int16_t rxcomp[NB_ANTENNAS_RX][2*12*14]; uint8_t ns,N_UL_symb,nsymb,n_oc,n_oc0,n_oc1; uint8_t c = (frame_parms->Ncp==0) ? 3 : 2; - uint16_t nprime,nprime0,nprime1; + int16_t nprime,nprime0,nprime1; uint16_t i,j,re_offset,thres,h,off; uint8_t Nprime_div_deltaPUCCH_Shift,Nprime,d; uint8_t m,l,refs,phase,re,l2,phase_max=0; @@ -755,12 +778,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, int16_t tmp_re,tmp_im,W_re=0,W_im=0; int16_t *rxptr; uint32_t symbol_offset; - int16_t stat_ref_re,stat_ref_im,*cfo; + int16_t stat0_ref_re[NB_ANTENNAS_RX],stat0_ref_im[NB_ANTENNAS_RX],stat1_ref_re[NB_ANTENNAS_RX],stat1_ref_im[NB_ANTENNAS_RX],*cfo; int16_t chest0_re[NB_ANTENNAS_RX][12],chest0_im[NB_ANTENNAS_RX][12]; int16_t chest1_re[NB_ANTENNAS_RX][12],chest1_im[NB_ANTENNAS_RX][12]; int32_t chest_mag; - int32_t stat_re=0,stat_im=0; - uint32_t stat,stat_max=0; + int32_t stat0_re[NB_ANTENNAS_RX],stat1_re[NB_ANTENNAS_RX],stat0_im[NB_ANTENNAS_RX],stat1_im[NB_ANTENNAS_RX]; + uint32_t stat0[NB_ANTENNAS_RX],stat1[NB_ANTENNAS_RX],stat_max=0,stat0_max[NB_ANTENNAS_RX],stat1_max[NB_ANTENNAS_RX]; uint8_t log2_maxh; uint8_t deltaPUCCH_Shift = frame_parms->pucch_config_common.deltaPUCCH_Shift; uint8_t NRB2 = frame_parms->pucch_config_common.nRB_CQI; @@ -808,9 +831,20 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, first_call=0; } - + eNB_UCI_STATS_t *uci_stats = NULL; if(fmt!=pucch_format3) { /* PUCCH format3 */ + + eNB_UCI_STATS_t *first_uci_stats=NULL; + for (int i=0;iuci_stats[i].rnti == eNB->ulsch[UCI_id]->rnti) { + uci_stats = &eNB->uci_stats[i]; + break; + } else if (eNB->uci_stats[i].rnti == 0) first_uci_stats = &eNB->uci_stats[i]; + if (uci_stats == NULL) { uci_stats=first_uci_stats; uci_stats->rnti = eNB->ulsch[UCI_id]->rnti;} + + AssertFatal(uci_stats!=NULL,"No stat index found\n"); + uci_stats->frame = frame; // TODO // "SR+ACK/NACK" length is only 7 bits. // This restriction will be lifted in the future. @@ -1016,57 +1050,63 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, // Do cfo correction and MRC across symbols if (fmt == pucch_format1) { + uci_stats->pucch1_trials++; #ifdef DEBUG_PUCCH_RX printf("Doing PUCCH detection for format 1\n"); #endif stat_max = 0; for (phase=0; phase<7; phase++) { - stat=0; - + int stat=0; for (aa=0; aanb_antennas_rx; aa++) { + stat0[aa]=0;stat1[aa]=0; for (re=0; re<12; re++) { - stat_re=0; - stat_im=0; + stat0_re[aa]=0; + stat0_im[aa]=0; + stat1_re[aa]=0; + stat1_im[aa]=0; off=re<<1; cfo = (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase] : &cfo_pucch_ep[12*phase]; for (l=0; l<(nsymb>>1); l++) { - stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/nsymb; - stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/nsymb; + stat0_re[aa] += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/nsymb; + stat0_im[aa] += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/nsymb; off+=2; #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH subframe %d (%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) , stat %d\n",subframe,phase,l,re, rxcomp[aa][off],rxcomp[aa][1+off], cfo[l<<1],cfo[1+(l<<1)], - stat_re,stat_im,stat); + stat0_re[aa],stat0_im[aa],stat); #endif } for (l2=0,l=(nsymb>>1); l < nsymb; l++,l2++) { - stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb; - stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb; + stat1_re[aa] += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb; + stat1_im[aa] += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb; off+=2; #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH subframe %d (%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d), stat %d\n",subframe,phase,l2,re, rxcomp[aa][off],rxcomp[aa][1+off], cfo[l2<<1],cfo[1+(l2<<1)], - stat_re,stat_im,stat); + stat1_re[aa],stat1_im[aa],stat); #endif } - - stat += ((stat_re*stat_re) + (stat_im*stat_im)); + + stat0[aa] += ((stat0_re[aa]*stat0_re[aa]) + (stat0_im[aa]*stat0_im[aa])); + stat1[aa] += ((stat1_re[aa]*stat1_re[aa]) + (stat1_im[aa]*stat1_im[aa])); } //re + stat+=(stat0[aa]+stat1[aa]); } // aa - if (stat>stat_max) { stat_max = stat; phase_max = phase; + for (aa=0;aanb_antennas_rx;aa++) { + stat0_max[aa] = stat0[aa]; + stat1_max[aa] = stat1[aa]; + } } } //phase - // stat_max *= nsymb; // normalize to energy per symbol - // stat_max /= (frame_parms->N_RB_UL*12); // stat_max /= 12; #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max); @@ -1074,12 +1114,14 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #ifdef DEBUG_PUCCH_RX LOG_I(PHY,"[eNB] PUCCH fmt1: stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,eNB->measurements.n0_subband_power_tot_dBm[6],pucch1_thres,phase_max); #endif - eNB->pucch1_stats[UE_id][(subframe<<10)+eNB->pucch1_stats_cnt[UE_id][subframe]] = stat_max; - eNB->pucch1_stats_thres[UE_id][(subframe<<10)+eNB->pucch1_stats_cnt[UE_id][subframe]] = sigma2_dB+pucch1_thres; - eNB->pucch1_stats_cnt[UE_id][subframe] = (eNB->pucch1_stats_cnt[UE_id][subframe]+1)&1023; - T(T_ENB_PHY_PUCCH_1_ENERGY, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UE_id].rnti), T_INT(frame), T_INT(subframe), + eNB->pucch1_stats[UCI_id][(subframe<<10)+eNB->pucch1_stats_cnt[UCI_id][subframe]] = stat_max; + eNB->pucch1_stats_thres[UCI_id][(subframe<<10)+eNB->pucch1_stats_cnt[UCI_id][subframe]] = sigma2_dB+pucch1_thres; + eNB->pucch1_stats_cnt[UCI_id][subframe] = (eNB->pucch1_stats_cnt[UCI_id][subframe]+1)&1023; + uci_stats->pucch1_thres = sigma2_dB+pucch1_thres; + T(T_ENB_PHY_PUCCH_1_ENERGY, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UCI_id].rnti), T_INT(frame), T_INT(subframe), T_INT(stat_max), T_INT(sigma2_dB+pucch1_thres)); + /* if (eNB->pucch1_stats_cnt[UE_id][subframe] == 0) { LOG_M("pucch_debug.m","pucch_energy", @@ -1093,11 +1135,17 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, // This is a moving average of the PUCCH1 statistics conditioned on being above or below the threshold if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres)) { *payload = 1; + uci_stats->current_pucch1_stat = stat_max; + for (int aa=0;aanb_antennas_rx;aa++) { + uci_stats->pucch1_low_stat[aa]=stat0_max[aa]; + uci_stats->pucch1_high_stat[aa]=stat1_max[aa]; + uci_stats->pucch1_positive_SR++; + } } else { *payload = 0; } - if (UE_id==0) { + if (UCI_id==0) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SR_ENERGY,dB_fixed(stat_max)); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SR_THRES,sigma2_dB+pucch1_thres); } @@ -1106,29 +1154,30 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #ifdef DEBUG_PUCCH_RX LOG_D(PHY,"Doing PUCCH detection for format 1a/1b\n"); #endif - + int stat_re=0,stat_im=0; for (phase=0; phase<7; phase++) { - stat=0; - + int stat=0; for (aa=0; aanb_antennas_rx; aa++) { + stat0[aa]=0; + stat1[aa]=0; for (re=0; re<12; re++) { // compute received energy first slot, seperately for data and reference // by coherent combining across symbols but not resource elements // Note: assumption is that channel is stationary over symbols in slot after CFO - stat_re=0; - stat_im=0; - stat_ref_re=0; - stat_ref_im=0; + stat0_re[aa]=0; + stat0_im[aa]=0; + stat0_ref_re[aa]=0; + stat0_ref_im[aa]=0; off=re<<1; cfo = (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase] : &cfo_pucch_ep[12*phase]; for (l=0; l<(nsymb>>1); l++) { if ((l<2)||(l>(nsymb>>1) - 3)) { //data symbols - stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); - stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); + stat0_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); + stat0_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); } else { //reference symbols - stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); - stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); + stat0_ref_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); + stat0_ref_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); } off+=2; @@ -1141,21 +1190,21 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, } // this is total energy received, summed over data and reference - stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) + - ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + stat0[aa] += ((((stat0_re[aa]*stat0_re[aa])) + ((stat0_im[aa]*stat0_im[aa])) + + ((stat0_ref_re[aa]*stat0_ref_re[aa])) + ((stat0_ref_im[aa]*stat0_ref_im[aa])))/nsymb); // now second slot - stat_re=0; - stat_im=0; - stat_ref_re=0; - stat_ref_im=0; + stat1_re[aa]=0; + stat1_im[aa]=0; + stat1_ref_re[aa]=0; + stat1_ref_im[aa]=0; for (l2=0,l=(nsymb>>1); l< nsymb; l++,l2++) { if ((l2<2) || ((l2>(nsymb>>1) - 3)) ) { // data symbols - stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); - stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); + stat1_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); + stat1_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); } else { //reference_symbols - stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); - stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); + stat1_ref_re[aa] += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); + stat1_ref_im[aa] += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); } off+=2; @@ -1170,15 +1219,16 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #ifdef DEBUG_PUCCH_RX printf("aa%d re %d : phase %d : stat %d\n",aa,re,phase,stat); #endif - stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) + - ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + stat1[aa] += ((((stat1_re[aa]*stat1_re[aa])) + ((stat1_im[aa]*stat1_im[aa])) + + ((stat1_ref_re[aa]*stat1_ref_re[aa])) + ((stat1_ref_im[aa]*stat1_ref_im[aa])))/nsymb); } //re + stat+=(stat0[aa]+stat1[aa]); } // aa #ifdef DEBUG_PUCCH_RX LOG_D(PHY,"Format 1A: phase %d : stat %d\n",phase,stat); #endif - + if (stat>stat_max) { stat_max = stat; phase_max = phase; @@ -1189,8 +1239,6 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #ifdef DEBUG_PUCCH_RX LOG_I(PHY,"[eNB] PUCCH fmt1a/b: stat_max : %d (%d : sigma2 %d), phase_max : %d\n",stat_max,dB_fixed(stat_max),sigma2_dB,phase_max); #endif - stat_re=0; - stat_im=0; // Do detection now @@ -1198,13 +1246,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, // For instance i assume to skip pucch1_thres from the test below. // Not 100% sure - if (sigma2_dB<(dB_fixed(stat_max) - (IS_SOFTMODEM_IQPLAYER?0:pucch1_thres)) ) {// + if (sigma2_dB<(dB_fixed(stat_max) - (IS_SOFTMODEM_IQPLAYER?0:pucch1_thres)) ) {// chL = (nsymb>>1)-4; chest_mag=0; cfo = (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase_max] : &cfo_pucch_ep[12*phase_max]; for (aa=0; aanb_antennas_rx; aa++) { - // channel estimates first for (re=0; re<12; re++) { // channel estimate for first slot chest0_re[aa][re]=0; @@ -1238,6 +1285,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, // now do channel matched filter for (aa=0; aanb_antennas_rx; aa++) { + stat0_re[aa]=0; + stat0_im[aa]=0; + stat1_re[aa]=0; + stat1_im[aa]=0; + for (re=0; re<12; re++) { #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH subframe %d chest0[%d][%d] => (%d,%d)\n",subframe,aa,re, @@ -1249,8 +1301,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, off=(re<<1) + (24*l); tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); - stat_re += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh)); - stat_im += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh)); + stat0_re[aa] += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh)); + stat0_im[aa] += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh)); off+=2; #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re, @@ -1266,8 +1318,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, off=(re<<1) + (24*l); tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); - stat_re += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh)); - stat_im += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh)); + stat0_re[aa] += (((tmp_re*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh)); + stat0_im[aa] += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh)); off+=2; #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re, @@ -1288,8 +1340,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, off=(re<<1) + (24*l) + (nsymb>>1)*24; tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); - stat_re += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh)); - stat_im += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh)); + stat1_re[aa] += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh)); + stat1_im[aa] += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh)); off+=2; #ifdef DEBUG_PUCCH_RX printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re, @@ -1305,8 +1357,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, off=(re<<1) + (24*l) + (nsymb>>1)*24; tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); - stat_re += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh)); - stat_im += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh)); + stat1_re[aa] += (((tmp_re*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh)); + stat1_im[aa] += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh)); off+=2; #ifdef DEBUG_PUCCH_RX printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re, @@ -1321,29 +1373,42 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, printf("aa%d re %d : stat %d,%d\n",aa,re,stat_re,stat_im); #endif } //re + stat_re+=stat0_re[aa]+stat1_re[aa]; + stat_im+=stat0_im[aa]+stat1_im[aa]; } // aa LOG_D(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im, - (subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])); + (subframe<<10) + (eNB->pucch1ab_stats_cnt[UCI_id][subframe])); LOG_D(PHY,"In pucch.c PUCCH 1a/b: ACK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); - eNB->pucch1ab_stats[UE_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_re); - eNB->pucch1ab_stats[UE_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_im); - eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023; + eNB->pucch1ab_stats[UCI_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UCI_id][subframe])] = (stat_re); + eNB->pucch1ab_stats[UCI_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UCI_id][subframe])] = (stat_im); + eNB->pucch1ab_stats_cnt[UCI_id][subframe] = (eNB->pucch1ab_stats_cnt[UCI_id][subframe]+1)&1023; /* frame not available here - set to -1 for the moment */ - T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UE_id].rnti), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im)); + T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UCI_id].rnti), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im)); *payload = (stat_re<0) ? 1 : 2; // 1 == ACK, 2 == NAK - if (fmt==pucch_format1b) + if (fmt==pucch_format1b) { + uci_stats->pucch1b_trials++; *(1+payload) = (stat_im<0) ? 1 : 2; + uci_stats->current_pucch1b_stat_re = stat_re; + uci_stats->current_pucch1b_stat_im = stat_im; + } + else { + uci_stats->pucch1a_trials++; + uci_stats->current_pucch1a_stat_re = stat_re; + uci_stats->current_pucch1a_stat_im = stat_im; + } + } else { // insufficient energy on PUCCH so NAK LOG_D(PHY,"In pucch.c PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); *payload = 4; // DTX - ((int16_t *)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re); - ((int16_t *)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im); - eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023; + ((int16_t *)&eNB->pucch1ab_stats[UCI_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UCI_id][subframe])])[0] = (int16_t)(stat_re); + ((int16_t *)&eNB->pucch1ab_stats[UCI_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UCI_id][subframe])])[1] = (int16_t)(stat_im); + eNB->pucch1ab_stats_cnt[UCI_id][subframe] = (eNB->pucch1ab_stats_cnt[UCI_id][subframe]+1)&1023; if (fmt==pucch_format1b) *(1+payload) = 4; + uci_stats->pucch1ab_DTX++; } } else { LOG_E(PHY,"[eNB] PUCCH fmt2/2a/2b not supported\n"); diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h index 1944f06fab..622f37b3bc 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h @@ -223,7 +223,9 @@ uint8_t get_num_prach_tdd(module_id_t Mod_id); @param frame_type 0-FDD, 1-TDD @returns 0-1 accordingly */ +/* uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type); +*/ /*! \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index @@ -306,12 +308,12 @@ void init_scrambling_lut(void); void init_unscrambling_lut(void); - +/* uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t prach_ConfigIndex, uint8_t n_ra_prboffset, uint8_t tdd_mapindex, uint16_t Nf); - +*/ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe); uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); @@ -319,6 +321,6 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL); void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2); -int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs); +int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs); #endif diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 4ce113f78e..2de4c2698b 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -693,8 +693,6 @@ int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type); -uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type); - uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 92fe777201..17f95f31ce 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -468,6 +468,35 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB, ulsch_harq->Nsymb_pusch, nb_rb); //#endif + + eNB_SCH_STATS_t *stats=NULL; + int first_free=-1; + for (int i=0;iulsch_stats[i].rnti == 0 && first_free == -1) { + first_free = i; + stats=&eNB->ulsch_stats[i]; + } + if (eNB->ulsch_stats[i].rnti == ulsch->rnti) { + stats=&eNB->ulsch_stats[i]; + break; + } + } + if (stats) { + stats->rnti = ulsch->rnti; + stats->round_trials[ulsch_harq->round]++; + stats->frame=proc->frame_rx; + } + if (ulsch_harq->round == 0) { + if (stats) { + stats->current_Qm = Q_m; + stats->current_RI = 1; + stats->total_bytes_tx += ulsch_harq->TBS; + stats->current_TBS = ulsch_harq->TBS; + stats->current_G = ulsch_harq->G; + } + } + + //if (ulsch_harq->round == 0) { // delete for RB shortage pattern // This is a new packet, so compute quantities regarding segmentation ulsch_harq->B = A+24; @@ -1086,3 +1115,42 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB, ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag); return(ret); } + + +void dump_ulsch_stats(PHY_VARS_eNB *eNB,int frame) { + + for (int i=0;iulsch_stats[i].rnti>0) { + for (int aa=0;aaframe_parms.nb_antennas_rx;aa++) + LOG_I(PHY,"ULSCH RNTI %x: ulsch_power[%d] %d, ulsch_noise_power[%d] %d\n", + eNB->ulsch_stats[i].rnti, aa,eNB->ulsch_stats[i].ulsch_power[aa],aa,eNB->ulsch_stats[i].ulsch_noise_power[aa]); + + LOG_I(PHY,"ULSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d\n", + eNB->ulsch_stats[i].rnti, + eNB->ulsch_stats[i].round_trials[0], + (double)eNB->ulsch_stats[i].round_trials[1]/eNB->ulsch_stats[i].round_trials[0], + eNB->ulsch_stats[i].round_trials[1], + (double)eNB->ulsch_stats[i].round_trials[2]/eNB->ulsch_stats[i].round_trials[0], + eNB->ulsch_stats[i].round_trials[2], + (double)eNB->ulsch_stats[i].round_trials[3]/eNB->ulsch_stats[i].round_trials[0], + eNB->ulsch_stats[i].round_trials[3]); + LOG_I(PHY,"ULSCH RNTI %x: current_Qm %d, current_G %d, current_TBS %d, current_rate %f,current_RI %d, timing_offset %d, total_bytes RX/SCHED %d/%d\n", + eNB->ulsch_stats[i].rnti, + eNB->ulsch_stats[i].current_Qm, + eNB->ulsch_stats[i].current_G, + eNB->ulsch_stats[i].current_TBS, + (double)eNB->ulsch_stats[i].current_G/eNB->ulsch_stats[i].current_TBS, + eNB->ulsch_stats[i].current_RI, + eNB->ulsch_stats[i].timing_offset, + eNB->ulsch_stats[i].total_bytes_rx, + eNB->ulsch_stats[i].total_bytes_tx); + } + +} + +void clear_ulsch_stats(PHY_VARS_eNB *eNB) { + + for (int i=0;iulsch_stats[i],0,sizeof(eNB->ulsch_stats[i])); +} + diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 1b23fc99bf..5a8060091b 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1076,6 +1076,10 @@ void rx_ulsch(PHY_VARS_eNB *eNB, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)/correction_factor; LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_times10(pusch_vars->ulsch_power[i])); + pusch_vars->ulsch_noise_power[i]=0; + for (int rb=0;rbharq_processes[harq_pid]->nb_rb;rb++) + pusch_vars->ulsch_noise_power[i]+=eNB->measurements.n0_subband_power[i][rb]/ulsch[UE_id]->harq_processes[harq_pid]->nb_rb; + LOG_D(PHY,"noise power[%d] %d\n",i,dB_fixed_times10(pusch_vars->ulsch_noise_power[i])); } ulsch_channel_level(pusch_vars->drs_ch_estimates, diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 1f18f114de..32f22e9caf 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -164,8 +164,10 @@ typedef struct { /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_magb; - /// measured RX power based on DRS - int ulsch_power[2]; + /// measured RX power based on DMRS + int ulsch_power[4]; + /// measured RX power of noise + int ulsch_noise_power[4]; /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; @@ -421,6 +423,42 @@ typedef struct { int prach_I0; } PHY_MEASUREMENTS_eNB; +typedef struct { + uint16_t rnti; + int frame; + int round_trials[8]; + int total_bytes_tx; + int total_bytes_rx; + int current_G; + int current_TBS; + int current_Qm; + int current_mcs; + int current_RI; + int timing_offset; + int ulsch_power[4]; + int ulsch_noise_power[4]; +} eNB_SCH_STATS_t; + +typedef struct { + uint16_t rnti; + int frame; + int pucch1_trials; + int pucch1_thres; + int current_pucch1_stat; + int pucch1_positive_SR; + int pucch1_low_stat[4]; + int pucch1_high_stat[4]; + int pucch1_phase; + int pucch1a_trials; + int current_pucch1a_stat_re; + int current_pucch1a_stat_im; + int pucch1ab_DTX; + int pucch1b_trials; + int current_pucch1b_stat_re; + int current_pucch1b_stat_im; + int pucch3_trials; + int current_pucch3_stat; +} eNB_UCI_STATS_t; /// Top-level PHY Data Structure for eNB typedef struct PHY_VARS_eNB_s { @@ -591,7 +629,12 @@ typedef struct PHY_VARS_eNB_s { /// Information regarding TM5 MU_MIMO_mode mu_mimo_mode[NUMBER_OF_UE_MAX]; - + /// statistics for DLSCH measurement collection + eNB_SCH_STATS_t dlsch_stats[NUMBER_OF_SCH_STATS_MAX]; + /// statistics for ULSCH measurement collection + eNB_SCH_STATS_t ulsch_stats[NUMBER_OF_SCH_STATS_MAX]; + /// statis for UCI (PUCCH) measurement collection + eNB_UCI_STATS_t uci_stats[NUMBER_OF_SCH_STATS_MAX]; /// target_ue_dl_mcs : only for debug purposes uint32_t target_ue_dl_mcs; /// target_ue_ul_mcs : only for debug purposes diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index d162a413c1..7db0677f66 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -1086,72 +1086,5 @@ void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeri } } -// uint8_t eNB_id,uint8_t harq_pid, uint8_t UE_id, -int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs) -{ - - /// The payload + CRC size in bits, "B" - uint32_t B; - /// Number of code segments - uint32_t C; - /// Number of "small" code segments - uint32_t Cminus; - /// Number of "large" code segments - uint32_t Cplus; - /// Number of bits in "small" code segments (<6144) - uint32_t Kminus; - /// Number of bits in "large" code segments (<6144) - uint32_t Kplus; - /// Total number of bits across all segments - uint32_t sumKr; - /// Number of "Filler" bits - uint32_t F; - // num resource elements - uint32_t num_re=0.0; - // num symbols - uint32_t num_symb=0.0; - /// effective spectral efficiency of the PUSCH - uint32_t MPR_x100=0; - /// beta_offset - uint16_t beta_offset_pusch_x8=8; - /// delta mcs - float delta_mcs=0.0; - /// bandwidth factor - float bw_factor=0.0; - - B= tbs+24; - lte_segmentation(NULL, - NULL, - B, - &C, - &Cplus, - &Cminus, - &Kplus, - &Kminus, - &F); - sumKr = Cminus*Kminus + Cplus*Kplus; - num_symb = 12-(ncp<<1)-(use_srs==0?0:1); - num_re = num_symb * nb_rb * 12; - - if (num_re == 0) - return(0); - - MPR_x100 = 100*sumKr/num_re; - - if (control_only == 1 ) - beta_offset_pusch_x8=8; // fixme - - //(beta_offset_pusch_x8=ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; - - // if deltamcs_enabledm - delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0); - bw_factor = (hundred_times_log10_NPRB[nb_rb-1]/100.0); -#ifdef DEBUG_SEGMENTATION - printf("estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n", - (int16_t)ceil(delta_mcs + bw_factor), num_re, sumKr, MPR_x100, delta_mcs, bw_factor); -#endif - return (int16_t)ceil(delta_mcs + bw_factor); - -} diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a264ee31a2..414a0fe183 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -480,8 +480,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, subframe<<1); stop_meas(&eNB->dlsch_scrambling_stats); start_meas(&eNB->dlsch_modulation_stats); - if (frame==0) LOG_I(PHY,"Generating pdsch for %d.%d starting in symbol %d, Qm %d, nb_rb %d, rbmask %x\n", - frame,subframe,dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]); dlsch_modulation(eNB, eNB->common_vars.txdataF, AMP, @@ -1329,7 +1327,7 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { int nb=abortTpool(proc->threadPool, req->key); nb+=abortNotifiedFIFO(proc->respDecode, req->key); proc->nbDecode-=nb; - LOG_I(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); + LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb); AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n", ulsch_harq->processedSegments, nb, rdata->nbSegments); ulsch_harq->processedSegments=rdata->nbSegments; @@ -1385,6 +1383,15 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) { fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC ulsch_harq->status = SCH_IDLE; ulsch->harq_mask &= ~(1 << rdata->harq_pid); + for (int j=0;julsch_stats[j].rnti == ulsch->rnti) { + eNB->ulsch_stats[j].total_bytes_rx+=ulsch_harq->TBS; + for (int aa=0;aaframe_parms.nb_antennas_rx;aa++) { + eNB->ulsch_stats[j].ulsch_power[aa] = dB_fixed_times10(eNB->pusch_vars[rdata->UEid]->ulsch_power[aa]); + eNB->ulsch_stats[j].ulsch_noise_power[aa] = dB_fixed_times10(eNB->pusch_vars[rdata->UEid]->ulsch_noise_power[aa]); + } + break; + } T (T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti), T_INT(rdata->harq_pid)); } // ulsch not in error @@ -1541,7 +1548,7 @@ void kill_te_thread(PHY_VARS_eNB *eNB) { } void fill_rx_indication(PHY_VARS_eNB *eNB, - int UE_id, + int ULSCH_id, int frame, int subframe) { nfapi_rx_indication_pdu_t *pdu; @@ -1549,7 +1556,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, int sync_pos; uint32_t harq_pid; - if (eNB->ulsch[UE_id]->ue_type > 0) harq_pid = 0; + if (eNB->ulsch[ULSCH_id]->ue_type > 0) harq_pid = 0; else { harq_pid = subframe2harq_pid (&eNB->frame_parms, frame, subframe); @@ -1559,19 +1566,22 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, eNB->UL_INFO.rx_ind.sfn_sf = frame<<4| subframe; eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; pdu = &eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; - // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; + // pdu->rx_ue_information.handle = eNB->ulsch[ULSCH_id]->handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; - pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; + pdu->rx_ue_information.rnti = eNB->ulsch[ULSCH_id]->rnti; pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; - pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; + pdu->rx_indication_rel8.length = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes; + pdu->data = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->decodedBytes; // estimate timing advance for MAC - sync_pos = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time); - timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check + sync_pos = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[ULSCH_id]->drs_ch_estimates_time); + timing_advance_update = sync_pos; - // if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);} - // if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);} + for (int i=0;iulsch_stats[i].rnti == eNB->ulsch[ULSCH_id]->rnti) + eNB->ulsch_stats[i].timing_offset = sync_pos; + // if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,ULSCH_id); exit(-1);} + // if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,ULSCH_id); exit(-1);} switch (eNB->frame_parms.N_RB_DL) { case 6: /* nothing to do */ break; @@ -1611,7 +1621,13 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, pdu->rx_indication_rel8.timing_advance = timing_advance_update; // estimate UL_CQI for MAC - int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0] + ((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_power[1] : 0 )) - 10 * eNB->measurements.n0_subband_power_avg_dB; + int total_power=0, avg_noise_power=0; + for (int i=0;iframe_parms.nb_antennas_rx;i++) { + total_power+=(eNB->pusch_vars[ULSCH_id]->ulsch_power[i]); + avg_noise_power+=(eNB->pusch_vars[ULSCH_id]->ulsch_noise_power[i])/eNB->frame_parms.nb_antennas_rx; + } + int SNRtimes10 = dB_fixed_times10(total_power) - + dB_fixed_times10(avg_noise_power); if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi = 0; @@ -1620,9 +1636,11 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, else pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5; - LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d), timing_advance %d (update %d)\n", - harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,eNB->measurements.n0_subband_power_avg_dB,pdu->rx_indication_rel8.timing_advance, - timing_advance_update); + LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d,%d), timing_advance %d (update %d,sync_pos %d)\n", + harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,dB_fixed_times10(total_power),dB_fixed_times10(avg_noise_power),pdu->rx_indication_rel8.timing_advance,timing_advance_update,sync_pos); + for (int i=0;iframe_parms.nb_antennas_rx;i++) + LOG_D(PHY,"antenna %d: ulsch_power %d, noise_power %d\n",i,dB_fixed_times10(eNB->pusch_vars[ULSCH_id]->ulsch_power[i]),dB_fixed_times10(eNB->pusch_vars[ULSCH_id]->ulsch_noise_power[i])); + eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe; pthread_mutex_unlock(&eNB->UL_INFO_mutex); @@ -2151,6 +2169,29 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { LOG_I (PHY, "max_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, eNB->measurements.n0_subband_power_avg_dB); } + // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS + if ((frame&127) == 0 && subframe==3) { + dump_ulsch_stats(eNB); + dump_uci_stats(eNB); + } + + // clear unused statistics after 2 seconds + for (int i=0;iulsch_stats[i].frame <= frame) { + if ((eNB->ulsch_stats[i].frame + 200) < frame) eNB->ulsch_stats[i].rnti = 0; + } + else { + if (eNB->ulsch_stats[i].frame + 200 < (frame+1024)) eNB->ulsch_stats[i].rnti = 0; + } + if (eNB->uci_stats[i].frame <= frame) { + if ((eNB->uci_stats[i].frame + 200) < frame) eNB->uci_stats[i].rnti = 0; + } + else { + if (eNB->uci_stats[i].frame + 200 < (frame+1024)) eNB->uci_stats[i].rnti = 0; + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); } @@ -2188,6 +2229,8 @@ void release_rnti_of_phy(module_id_t mod_id) { if((ulsch != NULL) && (ulsch->rnti == rnti)) { LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti); clean_eNb_ulsch(ulsch); + for (j=0;julsch_stats[j].rnti == rnti) {eNB_PHY->ulsch_stats[j].rnti=0; break;} } for(j=0; jprach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) { - LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", + LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", eNB->Mod_id, eNB->CC_id, frame, diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index e472d64db4..7dc8124fe1 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -474,15 +474,16 @@ void feptx_prec(RU_t *ru, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+ru->idx , 1); for (aa=0;aanb_tx;aa++) { - memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti); - for (int p=0;pdo_precoding == 0) { - if (p==0) - memcpy((void*)ru->common.txdataF_BF[aa], - (void*)&eNB->common_vars.txdataF[aa][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size], - sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti); - } else { - if (pnb_antenna_ports_eNB) { + if (ru->do_precoding == 0) { + memcpy((void*)ru->common.txdataF_BF[aa], + (void*)&eNB->common_vars.txdataF[aa%fp->nb_antenna_ports_eNB][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size], + sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti); + + } + else { + memset(ru->common.txdataF_BF[aa],0,sizeof(int32_t)*fp->ofdm_symbol_size*fp->symbols_per_tti); + for (int p=0;pnb_antenna_ports_eNB) { // For the moment this does nothing different than below, except ignore antenna ports 5,7,8. for (l=0;lnum_pdcch_symbols;l++) beam_precoding(eNB->common_vars.txdataF, @@ -494,10 +495,10 @@ void feptx_prec(RU_t *ru, aa, p, eNB->Mod_id); - } //if (pnb_antenna_ports_eNB) + } //if (pnb_antenna_ports_eNB) // PDSCH region - if (pnb_antenna_ports_eNB || p==5 || p==7 || p==8) { + if (pnb_antenna_ports_eNB || p==5 || p==7 || p==8) { for (l=pdcch_vars->num_pdcch_symbols;lsymbols_per_tti;l++) { beam_precoding(eNB->common_vars.txdataF, ru->common.txdataF_BF, @@ -510,8 +511,8 @@ void feptx_prec(RU_t *ru, eNB->Mod_id); } // for (l=pdcch_vars ....) } // if (pnb_antenna_ports_eNB) ... - } // ru->do_precoding!=0 - } // for (p=0...) + } // for (p=0...) + } // if do_precoding } // for (aa=0 ...) if(ru->idx<2) diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 49cb2247bf..ff5d68b93b 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -86,9 +86,14 @@ #define MAX_gNB 2 #endif +#define NUMBER_OF_DLSCH_MAX 16 +#define NUMBER_OF_ULSCH_MAX 16 +#define NUMBER_OF_SCH_STATS_MAX 16 + #define NUMBER_OF_NR_DLSCH_MAX 2//16 #define NUMBER_OF_NR_ULSCH_MAX 2//16 #define NUMBER_OF_NR_SCH_STATS_MAX 16 + #define NUMBER_OF_NR_PUCCH_MAX 16 #define NUMBER_OF_NR_SR_MAX 16 #define NUMBER_OF_NR_PDCCH_MAX 16 diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 8f5aab99a7..20379b13c8 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -596,13 +596,13 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); if (((frameP & 127) == 0) && (subframeP == 0)) { - LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d (TPC accum %d) PUCCH SNR %d (TPC accum %d)\n", rnti, UE_scheduling_control->ul_out_of_sync == 0 ? "in synch" : "out of sync", UE_info->UE_template[CC_id][UE_id].phr_info, UE_scheduling_control->dl_cqi[CC_id], - (5 * UE_scheduling_control->pusch_snr[CC_id] - 640) / 10, - (5 * UE_scheduling_control->pucch1_snr[CC_id] - 640) / 10); + (5 * UE_scheduling_control->pusch_snr[CC_id] - 640) / 10, UE_scheduling_control->pucch_tpc_accumulated[CC_id], + (5 * UE_scheduling_control->pucch1_snr[CC_id] - 640) / 10, UE_scheduling_control->pusch_tpc_accumulated[CC_id]); } RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = -63; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index d1365b9ac3..273da77609 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -483,8 +483,8 @@ void generate_Msg2(module_id_t module_idP, first_rb = 0; vrb_map[first_rb] = 1; vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; + //vrb_map[first_rb + 2] = 1; + //vrb_map[first_rb + 3] = 1; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); @@ -495,12 +495,12 @@ void generate_Msg2(module_id_t module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 0; // no TPC dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 2); // This checks if the above DCI allocation is feasible in current subframe if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP, @@ -519,7 +519,7 @@ void generate_Msg2(module_id_t module_idP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 2); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block @@ -1295,9 +1295,9 @@ initiate_ra_proc(module_id_t module_idP, prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; } - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", - module_idP, CC_id, frameP, subframeP, preamble_index); + LOG_I(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d, timing offset %d\n", + module_idP, CC_id, frameP, subframeP, preamble_index, timing_offset); LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n", module_idP, CC_id, frameP, subframeP, rach_resource_type); @@ -1339,6 +1339,9 @@ initiate_ra_proc(module_id_t module_idP, abort(); case 1 : + case 3 : + case 4 : + case 5 : offset = 6; break; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 1f99f50ece..3dfab5baba 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1066,18 +1066,21 @@ schedule_ue_spec(module_id_t module_idP, if (snr > target_snr + 4) { tpc = 0; //-1 + ue_sched_ctrl->pucch_tpc_accumulated[CC_id]--; } else if (snr < target_snr - 4) { tpc = 2; //+1 + ue_sched_ctrl->pucch_tpc_accumulated[CC_id]--; } else { tpc = 1; //0 } - LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d (normal case)\n", + LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d (accumulated %d), snr/target snr %d/%d (normal case)\n", module_idP, frameP, subframeP, harq_pid, tpc, + ue_sched_ctrl->pucch_tpc_accumulated[CC_id], snr, target_snr); } // Po_PUCCH has been updated diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index f6220fa46d..2dcde6c852 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -47,7 +47,7 @@ #include "OCG_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "rlc.h" - +#include "common/utils/lte/prach_utils.h" #include "T.h" @@ -1042,48 +1042,6 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, } } -#ifdef TM5 - - // This has to be revisited!!!! - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; - - for (j = 0; j < N_RBG[CC_id]; j++) { - if (MIMO_mode_indicator[CC_id][j] == 2) { - i1 = i1 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 1) { - i2 = i2 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 0) { - i3 = i3 + 1; - } - } - - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_SUMIMO_transmissions + 1; - } - - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + - 1; - } - - if((i1 < N_RBG[CC_id]) && (i3 > 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_MUMIMO_transmissions + 1; - } - - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + - 1; - } - -#endif - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2) { @@ -1152,7 +1110,6 @@ schedule_ue_spec_fairRR(module_id_t module_idP, // int continue_flag = 0; int32_t snr, target_snr; int32_t tpc = 1; - static int32_t tpc_accumulated = 0; UE_sched_ctrl_t *ue_sched_ctl; int mcs; int i; @@ -1936,7 +1893,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, //#ifdef DEBUG_eNB_SCHEDULER if (ta_update != 31) { - LOG_D(MAC, + LOG_I(MAC, "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", module_idP, frameP, UE_id, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], @@ -2013,17 +1970,17 @@ schedule_ue_spec_fairRR(module_id_t module_idP, if (snr > target_snr + 4) { tpc = 0; //-1 - tpc_accumulated--; + ue_sched_ctl->pucch_tpc_accumulated[CC_id]--; } else if (snr < target_snr - 4) { tpc = 2; //+1 - tpc_accumulated++; + ue_sched_ctl->pucch_tpc_accumulated[CC_id]++; } else { tpc = 1; //0 } LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP,frameP, subframeP,harq_pid,tpc, - tpc_accumulated,snr,target_snr); + ue_sched_ctl->pucch_tpc_accumulated[CC_id],snr,target_snr); } // Po_PUCCH has been updated else { tpc = 1; //0 @@ -2241,7 +2198,6 @@ void ulsch_scheduler_pre_ue_select_fairRR( uint8_t first_ue_id[MAX_NUM_CCs][20]; uint8_t ul_inactivity_num[MAX_NUM_CCs]; uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={{0}}; - // LTE_DL_FRAME_PARMS *frame_parms; uint8_t ulsch_ue_max_num[MAX_NUM_CCs]; uint16_t saved_ulsch_dci[MAX_NUM_CCs]; rnti_t rnti; @@ -2564,7 +2520,6 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_info_t *UE_info= &eNB->UE_info; UE_TEMPLATE *UE_template = NULL; - LTE_DL_FRAME_PARMS *frame_parms = NULL; uint8_t ue_num_temp; uint8_t total_rbs=0; uint8_t average_rbs; @@ -2583,18 +2538,17 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, // MCS and RB assgin for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) { cc = &RC.mac[module_idP]->common_channels[CC_id]; - frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms); - + int N_RB_UL = to_prb(cc->ul_Bandwidth); if (cc->tdd_Config) { //TDD - if (frame_parms->N_RB_UL == 25) { + if (N_RB_UL == 25) { num_pucch_rb = 1; - } else if (frame_parms->N_RB_UL == 50) { + } else if (N_RB_UL == 50) { num_pucch_rb = 2; } else { num_pucch_rb = 3; } } else {//FDD - if (frame_parms->N_RB_UL == 25) { + if (N_RB_UL == 25) { num_pucch_rb = 1; } else { num_pucch_rb = 2; @@ -2619,13 +2573,13 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, continue; } - if (first_rb[CC_id] >= frame_parms->N_RB_UL-num_pucch_rb ) { + if (first_rb[CC_id] >= N_RB_UL-num_pucch_rb ) { LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id); break; } - total_rbs = frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id]; + total_rbs = N_RB_UL-num_pucch_rb-first_rb[CC_id]; average_rbs = (int)round((double)total_rbs/(double)ue_num_temp); if ( average_rbs < 3 ) { @@ -2677,21 +2631,24 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) { rb_table_index = 2; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); + tx_power= estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0); while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > bytes_to_schedule)) && (mcs > 3) ) { mcs--; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); + tx_power= estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0); } - while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && + while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(N_RB_UL-num_pucch_rb-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { rb_table_index++; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); + tx_power= estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0); } - + if (rb_table[rb_table_index]>40) LOG_I(MAC,"bytes_to_schedule %d, nb_rb %d tx_power %d PHR %d\n", + bytes_to_schedule,rb_table[rb_table_index], + estimate_ue_tx_power(0,tbs*8,rb_table[rb_table_index],0,cc->Ncp,0), + UE_template->phr_info); if ( rb_table[rb_table_index]<3 ) { rb_table_index=2; } @@ -2834,12 +2791,10 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]; memset(ulsch_ue_select, 0, sizeof(ulsch_ue_select)); - LTE_DL_FRAME_PARMS *frame_parms ; for (CC_id=0; CC_idcommon_channels[CC_id]; - frame_parms= &RC.eNB[module_idP][CC_id]->frame_parms; - + int N_RB_UL=to_prb(cc->ul_Bandwidth); // output of scheduling, the UE numbers in RBs, where it is in the code??? // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 // Msg3 is using 1 PRB so we need to increase first_rb accordingly @@ -2849,13 +2804,13 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_MSG3; if (cc->tdd_Config == NULL) { - if(frame_parms->N_RB_UL == 25) { + if(N_RB_UL == 25) { ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1; } else { ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2; } } else { - switch(frame_parms->N_RB_UL) { + switch(N_RB_UL) { case 25: default: ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1; @@ -2879,14 +2834,18 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, } //PRACH - if (is_prach_subframe(frame_parms,sched_frame,sched_subframe)==1) { + if (is_prach_subframe0(cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0,cc->tdd_Config!=NULL ? 1 : 0, + cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex, + sched_frame,sched_subframe)==1) { ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_PRACH; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = get_prach_prb_offset( - frame_parms, - frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, - 0,//tdd_mapindex - frameP); //Nf --> shouldn't it be sched_frame ??? + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = + get_prach_prb_offset(cc->tdd_Config!=NULL ? 1 : 0, + cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0, + to_prb(cc->ul_Bandwidth), + cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex, + cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset, + 0, + sched_frame); ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 6; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1; ulsch_ue_select[CC_id].ue_num++; @@ -2914,7 +2873,6 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, uint32_t cqi_req,cshift,ndi,tpc; int32_t snr; int32_t target_snr=0; - static int32_t tpc_accumulated=0; int CC_id,ulsch_ue_num; int N_RB_UL; eNB_MAC_INST *eNB = RC.mac[module_idP]; @@ -3095,10 +3053,10 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, if (snr > target_snr + 4) { tpc = 0; //-1 - tpc_accumulated--; + UE_sched_ctrl->pusch_tpc_accumulated[CC_id]--; } else if (snr < target_snr - 4) { tpc = 2; //+1 - tpc_accumulated++; + UE_sched_ctrl->pusch_tpc_accumulated[CC_id]++; } else { tpc = 1; //0 } @@ -3109,7 +3067,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, if (tpc!=1) { LOG_D(MAC,"[eNB %d] ULSCH schedulerRR: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP,frameP,subframeP,harq_pid,tpc, - tpc_accumulated,snr,target_snr); + UE_sched_ctrl->pusch_tpc_accumulated[CC_id],snr,target_snr); } // new transmission diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index b62df74082..b941f60458 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -57,7 +57,7 @@ #include "flexran_agent_mac.h" #include #include - +#include "common/utils/lte/prach_utils.h" #include "T.h" @@ -144,16 +144,18 @@ rx_sdu(const module_id_t enb_mod_idP, if (UE_id != -1) { UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id]; UE_template_ptr = &UE_info->UE_template[CC_idP][UE_id]; - LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH (%s) sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d, timing_advance %d\n", enb_mod_idP, harq_pid, CC_idP, frameP, subframeP, + sduP==NULL ? "in error" : "OK", UE_scheduling_control->round_UL[CC_idP][harq_pid], current_rnti, UE_id, - ul_cqi); + ul_cqi, + timing_advance); AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); if (sduP != NULL) { @@ -270,14 +272,17 @@ rx_sdu(const module_id_t enb_mod_idP, AssertFatal(mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 1, "maxHARQ %d should be greater than 1\n", (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); - LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + LOG_I(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu (%s) round %d from PHY (rnti %x, RA_id %d) ul_cqi %d, timing advance %d\n", enb_mod_idP, harq_pid, CC_idP, + sduP!=NULL ? "OK" : "in error", ra->msg3_round, current_rnti, RA_id, - ul_cqi); + ul_cqi, + timing_advance); + first_rb = ra->msg3_first_rb; if (sduP == NULL) { // we've got an error on Msg3 @@ -1214,16 +1219,19 @@ schedule_ulsch(module_id_t module_idP, /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */ for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) { - LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[module_idP][CC_id]->frame_parms; - if (is_prach_subframe(frame_parms, sched_frame, sched_subframe)) { - int start_rb = get_prach_prb_offset( - frame_parms, - frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, - 0, // tdd_mapindex - sched_frame); // Nf + + if (is_prach_subframe0(cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0,cc->tdd_Config!=NULL ? 1 : 0, + cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex, + sched_frame, sched_subframe)) { + int start_rb = get_prach_prb_offset(cc->tdd_Config!=NULL ? 1 : 0, + cc->tdd_Config!=NULL ? cc->tdd_Config->subframeAssignment : 0, + to_prb(cc->ul_Bandwidth), + cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex, + cc->radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset, + 0, // tdd_mapindex + sched_frame); // Nf for (int i = 0; i < 6; i++) - cc[CC_id].vrb_map_UL[start_rb + i] = 1; + cc->vrb_map_UL[start_rb + i] = 1; } /* HACK: let's remove the PUCCH from available RBs @@ -1235,24 +1243,24 @@ schedule_ulsch(module_id_t module_idP, */ switch (to_prb(cc[CC_id].ul_Bandwidth)) { case 25: - cc[CC_id].vrb_map_UL[0] = 1; - cc[CC_id].vrb_map_UL[24] = 1; + cc->vrb_map_UL[0] = 1; + cc->vrb_map_UL[24] = 1; break; case 50: - cc[CC_id].vrb_map_UL[0] = 1; - cc[CC_id].vrb_map_UL[1] = 1; - cc[CC_id].vrb_map_UL[48] = 1; - cc[CC_id].vrb_map_UL[49] = 1; + cc->vrb_map_UL[0] = 1; + cc->vrb_map_UL[1] = 1; + cc->vrb_map_UL[48] = 1; + cc->vrb_map_UL[49] = 1; break; case 100: - cc[CC_id].vrb_map_UL[0] = 1; - cc[CC_id].vrb_map_UL[1] = 1; - cc[CC_id].vrb_map_UL[2] = 1; - cc[CC_id].vrb_map_UL[97] = 1; - cc[CC_id].vrb_map_UL[98] = 1; - cc[CC_id].vrb_map_UL[99] = 1; + cc->vrb_map_UL[0] = 1; + cc->vrb_map_UL[1] = 1; + cc->vrb_map_UL[2] = 1; + cc->vrb_map_UL[97] = 1; + cc->vrb_map_UL[98] = 1; + cc->vrb_map_UL[99] = 1; break; default: @@ -1270,6 +1278,8 @@ schedule_ulsch(module_id_t module_idP, /* * Schedule the DCI0 for ULSCH */ + + void schedule_ulsch_rnti(module_id_t module_idP, int CC_id, @@ -1277,7 +1287,6 @@ schedule_ulsch_rnti(module_id_t module_idP, sub_frame_t subframeP, unsigned char sched_subframeP) { /* TODO: does this need to be static? */ - static int32_t tpc_accumulated = 0; /* values from 0 to 7 can be used for mapping the cyclic shift * (36.211 , Table 5.5.2.1.1-1) */ const uint32_t cshift = 0; @@ -1401,8 +1410,7 @@ schedule_ulsch_rnti(module_id_t module_idP, /* Power control */ /* * Compute the expected ULSCH RX snr (for the stats) - * This is the normalized RX snr and this should be constant (regardless - * of mcs) Is not in dBm, unit from nfapi, converting to dBm + * */ const int32_t snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10; const int32_t target_snr = mac->puSch10xSnr / 10; @@ -1423,10 +1431,10 @@ schedule_ulsch_rnti(module_id_t module_idP, if (snr > target_snr + 4) { tpc = 0; // -1 - tpc_accumulated--; + UE_sched_ctrl_ptr->pusch_tpc_accumulated[CC_id]--; } else if (snr < target_snr - 4) { tpc = 2; // +1 - tpc_accumulated++; + UE_sched_ctrl_ptr->pusch_tpc_accumulated[CC_id]++; } } if (tpc != 1) { @@ -1438,7 +1446,7 @@ schedule_ulsch_rnti(module_id_t module_idP, subframeP, harq_pid, tpc, - tpc_accumulated, + UE_sched_ctrl_ptr->pusch_tpc_accumulated[CC_id], snr, target_snr); } @@ -1998,10 +2006,10 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, if (snr > target_snr + 4) { tpc = 0; //-1 - UE_sched_ctrl->tpc_accumulated[CC_id]--; + UE_sched_ctrl->pusch_tpc_accumulated[CC_id]--; } else if (snr < target_snr - 4) { tpc = 2; //+1 - UE_sched_ctrl->tpc_accumulated[CC_id]++; + UE_sched_ctrl->pusch_tpc_accumulated[CC_id]++; } else { tpc = 1; //0 } @@ -2016,7 +2024,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, subframeP, harq_pid, tpc, - UE_sched_ctrl->tpc_accumulated[CC_id], + UE_sched_ctrl->pusch_tpc_accumulated[CC_id], snr, target_snr); } diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 7eccc6222d..30714bd5a9 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -775,7 +775,6 @@ typedef struct { uint32_t num_mac_sdu_rx; // Length of SDU Got from LC UL - Size array can be refined uint32_t sdu_length_rx[NB_RB_MAX]; - } eNB_UE_STATS; /*! \brief eNB template for UE context information */ @@ -964,7 +963,8 @@ typedef struct { uint16_t feedback_cnt[NFAPI_CC_MAX]; uint16_t timing_advance; uint16_t timing_advance_r9; - uint8_t tpc_accumulated[NFAPI_CC_MAX]; + int8_t pusch_tpc_accumulated[NFAPI_CC_MAX]; + int8_t pucch_tpc_accumulated[NFAPI_CC_MAX]; uint8_t periodic_wideband_cqi[NFAPI_CC_MAX]; uint8_t periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX]; uint8_t periodic_wideband_pmi[NFAPI_CC_MAX]; diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e720c1dfec..0ce8a3115c 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -730,13 +730,13 @@ void calculate_max_mcs_min_rb(module_id_t mod_id, int tbs = get_TBS_UL(*mcs, rb_table[*rb_index]); // fixme: set use_srs flag - *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0); + *tx_power = estimate_ue_tx_power(0,tbs * 8, rb_table[*rb_index], 0, Ncp, 0); /* find maximum MCS */ while ((phr - *tx_power < 0 || tbs > bytes) && *mcs > 3) { mcs--; tbs = get_TBS_UL(*mcs, rb_table[*rb_index]); - *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0); + *tx_power = estimate_ue_tx_power(0,tbs * 8, rb_table[*rb_index], 0, Ncp, 0); } /* find minimum necessary RBs */ @@ -746,7 +746,7 @@ void calculate_max_mcs_min_rb(module_id_t mod_id, && phr - *tx_power > 0) { (*rb_index)++; tbs = get_TBS_UL(*mcs, rb_table[*rb_index]); - *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0); + *tx_power = estimate_ue_tx_power(0,tbs * 8, rb_table[*rb_index], 0, Ncp, 0); } /* Decrease if we went to far in last iteration */ diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 23ac209389..d48952318a 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -67,8 +67,10 @@ fill_rar(const module_id_t module_idP, rar[5] = (uint8_t) (ra->rnti & 0xff); //ra->timing_offset = 0; ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4 + //rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4 + //rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4 + rar[0] = (uint8_t) (ra->timing_offset >> (4)); // 7 MSBs of timing advance + divide by 4 + rar[1] = (uint8_t) (ra->timing_offset << (4)) & 0xf0; // 4 LSBs of timing advance + divide by 4 COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; if(N_RB_UL == 25) { diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index dd69cc95e1..2591ab139d 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -331,6 +331,7 @@ static void *L1_thread_tx(void *param) { //wait_sync("tx_thread"); + proc->respEncode = eNB->proc.L1_proc.respEncode; while (!oai_exit) { LOG_D(PHY,"Waiting for TX (IC %d)\n",proc->instance_cnt); @@ -391,6 +392,8 @@ static void *L1_thread( void *param ) { } PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; + + char thread_name[100]; cpu_set_t cpuset; CPU_ZERO(&cpuset); From 79d0f7774fb22c91206c4450fb815443e5f177c0 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 24 Dec 2020 16:14:56 +0100 Subject: [PATCH 4/4] added missing files --- common/utils/lte/prach_utils.c | 425 +++++++++++++++++++++++++++++++++ common/utils/lte/prach_utils.h | 40 ++++ 2 files changed, 465 insertions(+) create mode 100644 common/utils/lte/prach_utils.c create mode 100644 common/utils/lte/prach_utils.h diff --git a/common/utils/lte/prach_utils.c b/common/utils/lte/prach_utils.c new file mode 100644 index 0000000000..9ef29e55a5 --- /dev/null +++ b/common/utils/lte/prach_utils.c @@ -0,0 +1,425 @@ +/* + * 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 common/utils/lte/prach_utils.c + * \brief utils for PRACH common to both PHY and MAC + * \author R. Knopp + * \date 2020 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ + +#include + + +#include "PHY/LTE_TRANSPORT/transport_common.h" + +// This is table 5.7.1-4 from 36.211 +PRACH_TDD_PREAMBLE_MAP tdd_preamble_map[64][7] = { + // TDD Configuration Index 0 + { {1,{{0,1,0,2}}},{1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {1,{{0,1,0,2}}}}, + // TDD Configuration Index 1 + { {1,{{0,2,0,2}}},{1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {1,{{0,2,0,2}}}}, + // TDD Configuration Index 2 + { {1,{{0,1,1,2}}},{1,{{0,1,1,1}}}, {1,{{0,1,1,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,1}}}}, + // TDD Configuration Index 3 + { {1,{{0,0,0,2}}},{1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {1,{{0,0,0,2}}}}, + // TDD Configuration Index 4 + { {1,{{0,0,1,2}}},{1,{{0,0,1,1}}}, {1,{{0,0,1,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,1}}}}, + // TDD Configuration Index 5 + { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, + // TDD Configuration Index 6 + { {2,{{0,0,0,2},{0,0,1,2}}}, {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {2,{{0,0,0,1},{0,0,0,2}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {2,{{0,0,0,2},{0,0,1,1}}}}, + // TDD Configuration Index 7 + { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,2}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, + // TDD Configuration Index 8 + { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,0,1}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{0,0,1,1}}}}, + // TDD Configuration Index 9 + { {3,{{0,0,0,1},{0,0,0,2},{0,0,1,2}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,0,2}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {3,{{0,0,0,1},{0,0,0,2},{0,0,1,1}}}}, + // TDD Configuration Index 10 + { {3,{{0,0,0,0},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,2},{0,0,1,0}}}}, + // TDD Configuration Index 11 + { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{0,0,0,1},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{0,0,1,1}}}}, + // TDD Configuration Index 12 + { {4,{{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, + {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,2}}}, + {4,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {4,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} + }, + // TDD Configuration Index 13 + { {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1}}} + }, + // TDD Configuration Index 14 + { {4,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} + }, + // TDD Configuration Index 15 + { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1}}}, + {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,1},{1,0,0,2}}}, + {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,1}}}, {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, + {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1}}} + }, + // TDD Configuration Index 16 + { {5,{{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,1,1}}}, + {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,1,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,2}}}, + {5,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}} + }, + // TDD Configuration Index 17 + { {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,2}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}} + }, + // TDD Configuration Index 18 + { {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{0,0,1,2}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, + {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{1,0,0,0},{1,0,0,1},{1,0,0,2}}}, + {6,{{0,0,0,0},{0,0,0,1},{1,0,0,0},{1,0,0,1},{2,0,0,0},{2,0,0,1}}}, + {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,0,2}}} + }, + // TDD Configuration Index 19 + { {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{1,0,0,0},{1,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,1,0},{0,0,1,1},{1,0,1,1}}} + }, + // TDD Configuration Index 20 + { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}}, + // TDD Configuration Index 21 + { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}}, + + // TDD Configuration Index 22 + { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}}, + + // TDD Configuration Index 23 + { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, + + // TDD Configuration Index 24 + { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}}, + + // TDD Configuration Index 25 + { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, + + // TDD Configuration Index 26 + { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}}, + + // TDD Configuration Index 27 + { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}} + }, + + // TDD Configuration Index 28 + { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}}, + {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}} + }, + + // TDD Configuration Index 29 + { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}}, + {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}}, + {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}} + }, + + + // TDD Configuration Index 30 + { {1,{{0,1,0,1}}},{1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,1}}}}, + + // TDD Configuration Index 31 + { {1,{{0,2,0,1}}},{1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,1}}}}, + + // TDD Configuration Index 32 + { {1,{{0,1,1,1}}},{1,{{0,1,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,1,0}}}}, + + // TDD Configuration Index 33 + { {1,{{0,0,0,1}}},{1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,1}}}}, + + // TDD Configuration Index 34 + { {1,{{0,0,1,1}}},{1,{{0,0,1,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,1,0}}}}, + + // TDD Configuration Index 35 + { {2,{{0,0,0,1},{0,0,1,1}}}, {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{1,0,0,1}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,1},{0,0,1,0}}}}, + + // TDD Configuration Index 36 + { {3,{{0,0,0,1},{0,0,1,1},{1,0,0,1}}}, {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{1,0,0,1},{2,0,0,1}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,1},{0,0,1,0},{1,0,0,1}}}}, + + // TDD Configuration Index 37 + { {4,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1}}}, {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0}}} + }, + + // TDD Configuration Index 38 + { {5,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1}}}, {5,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {5,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1}}}, + {5,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {5,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1}}} + }, + + // TDD Configuration Index 39 + { {6,{{0,0,0,1},{0,0,1,1},{1,0,0,1},{1,0,1,1},{2,0,0,1},{2,0,1,1}}}, + {6,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0},{2,0,0,0},{2,0,1,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{1,0,0,1},{2,0,0,1},{3,0,0,1},{4,0,0,1},{5,0,0,1}}}, + {6,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0},{4,0,0,0},{5,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {6,{{0,0,0,1},{0,0,1,0},{1,0,0,1},{1,0,1,0},{2,0,0,1},{2,0,1,0}}} + }, + + // TDD Configuration Index 40 + { {1,{{0,1,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,1,0,0}}}}, + // TDD Configuration Index 41 + { {1,{{0,2,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,2,0,0}}}}, + + // TDD Configuration Index 42 + { {1,{{0,1,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}}, + + // TDD Configuration Index 43 + { {1,{{0,0,0,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {1,{{0,0,0,0}}}}, + + // TDD Configuration Index 44 + { {1,{{0,0,1,0}}},{0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}, {0,{{0,0,0,0}}}}, + + // TDD Configuration Index 45 + { {2,{{0,0,0,0},{0,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0}}}, {2,{{0,0,0,0},{1,0,0,0}}}}, + + // TDD Configuration Index 46 + { {3,{{0,0,0,0},{0,0,1,0},{1,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, {3,{{0,0,0,0},{1,0,0,0},{2,0,0,0}}}}, + + // TDD Configuration Index 47 + { {4,{{0,0,0,0},{0,0,1,0},{1,0,0,0},{1,0,1,0}}}, {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {0,{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + {4,{{0,0,0,0},{1,0,0,0},{2,0,0,0},{3,0,0,0}}} + } +}; + + +uint8_t get_prach_fmt(int prach_ConfigIndex,int frame_type) { + if (frame_type == FDD) // FDD + return(prach_ConfigIndex>>4); + else { + if (prach_ConfigIndex < 20) + return (0); + + if (prach_ConfigIndex < 30) + return (1); + + if (prach_ConfigIndex < 40) + return (2); + + if (prach_ConfigIndex < 48) + return (3); + else + return (4); + } +} + +uint8_t get_prach_prb_offset(int frame_type, + int tdd_config, + int N_RB_UL, + uint8_t prach_ConfigIndex, + uint8_t n_ra_prboffset, + uint8_t tdd_mapindex, uint16_t Nf) { + uint8_t n_ra_prb; + uint8_t f_ra,t1_ra; + uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type); + uint8_t Nsp=2; + + if (frame_type == TDD) { // TDD + if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) { + LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex); + return(-1); + } + + // adjust n_ra_prboffset for frequency multiplexing (p.36 36.211) + f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra; + + if (prach_fmt < 4) { + if ((f_ra&1) == 0) { + n_ra_prb = n_ra_prboffset + 6*(f_ra>>1); + } else { + n_ra_prb = N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1); + } + } else { + if ((tdd_config >2) && (tdd_config<6)) + Nsp = 2; + + t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; + + if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) { + n_ra_prb = 6*f_ra; + } else { + n_ra_prb = N_RB_UL - 6*(f_ra+1); + } + } + } else { //FDD + n_ra_prb = n_ra_prboffset; + } + + return(n_ra_prb); +} + +int is_prach_subframe0(int tdd_config,int frame_type,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe) { + uint8_t t0_ra; + uint8_t t1_ra; + uint8_t t2_ra; + int prach_mask = 0; + + if (frame_type == FDD) { //FDD + //implement Table 5.7.1-2 from 36.211 (Rel-10, p.41) + if ((((frame&1) == 1) && (subframe < 9)) || + (((frame&1) == 0) && (subframe == 9))) // This is an odd frame, ignore even-only PRACH frames + if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50 + ((prach_ConfigIndex&0x1f)==18) || // 18,50 + ((prach_ConfigIndex&0xf)==15)) // 15,47 + return(0); + + switch (prach_ConfigIndex&0x1f) { + case 0: + case 3: + if (subframe==1) prach_mask = 1; + + break; + + case 1: + case 4: + if (subframe==4) prach_mask = 1; + + break; + + case 2: + case 5: + if (subframe==7) prach_mask = 1; + + break; + + case 6: + if ((subframe==1) || (subframe==6)) prach_mask=1; + + break; + + case 7: + if ((subframe==2) || (subframe==7)) prach_mask=1; + + break; + + case 8: + if ((subframe==3) || (subframe==8)) prach_mask=1; + + break; + + case 9: + if ((subframe==1) || (subframe==4) || (subframe==7)) prach_mask=1; + + break; + + case 10: + if ((subframe==2) || (subframe==5) || (subframe==8)) prach_mask=1; + + break; + + case 11: + if ((subframe==3) || (subframe==6) || (subframe==9)) prach_mask=1; + + break; + + case 12: + if ((subframe&1)==0) prach_mask=1; + + break; + + case 13: + if ((subframe&1)==1) prach_mask=1; + + break; + + case 14: + prach_mask=1; + break; + + case 15: + if (subframe==9) prach_mask=1; + + break; + } + } else { // TDD + AssertFatal(prach_ConfigIndex<64, + "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex); + AssertFatal(tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach>0, + "Illegal prach_ConfigIndex %d for ",prach_ConfigIndex); + t0_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t0_ra; + t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; + t2_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t2_ra; +#ifdef PRACH_DEBUG + LOG_I(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n", + prach_ConfigIndex, + subframe, + t0_ra,t1_ra,t2_ra); +#endif + + if ((((t0_ra == 1) && ((frame &1)==0))|| // frame is even and PRACH is in even frames + ((t0_ra == 2) && ((frame &1)==1))|| // frame is odd and PRACH is in odd frames + (t0_ra == 0)) && // PRACH is in all frames + (((subframe<5)&&(t1_ra==0)) || // PRACH is in 1st half-frame + (((subframe>4)&&(t1_ra==1))))) { // PRACH is in 2nd half-frame + if ((prach_ConfigIndex<48) && // PRACH only in normal UL subframe + (((subframe%5)-2)==t2_ra)) prach_mask=1; + else if ((prach_ConfigIndex>47) && (((subframe%5)-1)==t2_ra)) prach_mask=1; // PRACH can be in UpPTS + } + } + + return(prach_mask); +} + diff --git a/common/utils/lte/prach_utils.h b/common/utils/lte/prach_utils.h new file mode 100644 index 0000000000..995805fbd2 --- /dev/null +++ b/common/utils/lte/prach_utils.h @@ -0,0 +1,40 @@ +/* + * 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 common/utils/prach_utils.h +* \brief computation of some PRACH variables used in both MAC and PHY +* \author R. Knopp +* \date 2020 +* \version 0.1 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it +* \note +* \warning +*/ +uint8_t get_prach_fmt(int prach_ConfigIndex,int frame_type); + +uint8_t get_prach_prb_offset(int frame_type, + int tdd_config, + int N_RB_UL, + uint8_t prach_ConfigIndex, + uint8_t n_ra_prboffset, + uint8_t tdd_mapindex, uint16_t Nf); +int is_prach_subframe0(int tdd_config,int frame_type,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe);