From 43dc75f92fea0785782ff93a3f596768ac62a7f0 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:39:12 +0200 Subject: [PATCH 01/34] fembms: reference config files re-arranged --- .../conf_files/enb.band17.tm1.25PRB.usrpb210.conf | 1 + .../enb.band17.tm1.mbms.25PRB.usrpb210.conf | 14 ++++++++------ ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf | 14 +++++++++++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf index db1c5eae2a..d834b23e30 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf @@ -105,6 +105,7 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "DISABLE" //Parameters for SIB18 rxPool_sc_CP_Len = "normal"; diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf index de58950df4..e36d970b5b 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf @@ -105,6 +105,8 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "DISABLE" + //Parameters for SIB18 rxPool_sc_CP_Len = "normal"; @@ -271,12 +273,12 @@ MCEs = ( mcch_update_time = 10; mbms_area_config_list = ( { - common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6) + common_sf_allocation_period = 1; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6) mbms_area_id = 0; pmch_config_list = ( { - allocated_sf_end=64; - data_mcs=10; + allocated_sf_end=40; + data_mcs=20; mch_scheduling_period = 0; #rf8(0) mbms_session_list = ( { @@ -288,7 +290,7 @@ MCEs = ( mnc_length = 2; } service_id=0; - lcid=5; #this must be properly defined lcid:8+service:0 -> rab_id:5 + lcid=5; #this must be properly defined lcid:8+service:0 -> rab_id:5 //with new RLC set lcid either 4 or 5 } ); } @@ -296,10 +298,10 @@ MCEs = ( mbms_sf_config_list = ( { - radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) + radioframe_allocation_period=0; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) radioframe_alloocation_offset=0; num_frame="oneFrame"; - subframe_allocation=57; #xx100000 + subframe_allocation=59; #xx111011 #57; #xx111001 //num_frame="fourFrame"; //subframe_allocation=14548987; # } diff --git a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf index 53261ec32d..3d5a859156 100644 --- a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf @@ -102,6 +102,7 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "DISABLE" //Parameters for SIB18 rxPool_sc_CP_Len = "normal"; @@ -295,8 +296,8 @@ MCEs = ( pmch_config_list = ( { allocated_sf_end=32; - data_mcs=14; - mch_scheduling_period = 0; #rf8(0) + data_mcs=15; + mch_scheduling_period = 0; #rf8(0) rf16(1) rf32(2) rf64(3) rf128(4) rf256(5) rf512(6) rf1024(7) mbms_session_list = ( { #plnm + service_id ->tmgi @@ -337,7 +338,7 @@ MCEs = ( offset = 0; modification_period = 0; #rf512(0; rf1024(1) subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000 - mcs = 1; #n2(0), n7(1), n13(2), n19(3) + mcs = 0; #n2(0), n7(1), n13(2), n19(3) } ); @@ -416,3 +417,10 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; + +//rfsimulator : +//{ + //options = ("chanmod"); + //modelname = "AWGN"; +//}; + -- GitLab From eb0dacc4432158807ebff8adba6a798c4c1c62c7 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:41:56 +0200 Subject: [PATCH 02/34] fembms: L1 prototypes and params added --- executables/split_headers.h | 2 +- openair1/PHY/INIT/lte_init.c | 1 + openair1/PHY/INIT/lte_init_ue.c | 6 +++--- openair1/PHY/INIT/lte_parms.c | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/executables/split_headers.h b/executables/split_headers.h index 4e328f74c4..1866e42159 100644 --- a/executables/split_headers.h +++ b/executables/split_headers.h @@ -279,7 +279,7 @@ int init_rf(RU_t *ru); void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc); void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc); void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe); -void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); +void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int fembms_flag); bool dlsch_procedures(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int harq_pid, diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 2d65521ab3..2c7e3e88eb 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -275,6 +275,7 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->soundingrs_ul_config_common.srs_MaxUpPts = cfg->srs_config.max_up_pts.value; fp->num_MBSFN_config = 0; fp->NonMBSFN_config_flag =cfg->fembms_config.non_mbsfn_config_flag.value; + fp->FeMBMS_active = fp->NonMBSFN_config_flag; fp->NonMBSFN_config.non_mbsfn_SubframeConfig = cfg->fembms_config.non_mbsfn_subframeconfig.value; fp->NonMBSFN_config.radioframeAllocationPeriod = cfg->fembms_config.radioframe_allocation_period.value; fp->NonMBSFN_config.radioframeAllocationOffset = cfg->fembms_config.radioframe_allocation_offset.value; diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 082db61da9..64a5992a64 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -137,7 +137,7 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { fp->MBSFN_config[i].fourFrames_flag = 0; fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %d\n", i, + LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] oneFrame pattern is %d\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration fp->MBSFN_config[i].fourFrames_flag = 1; @@ -145,7 +145,7 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %x\n", i, + LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] fourFrame pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } } @@ -212,7 +212,7 @@ void phy_config_sib1_fembms_ue(module_id_t Mod_id,int CC_id, LTE_DL_FRAME_PARMS *fp = &ue->frame_parms; if (nonMBSFN_SubframeConfig != NULL) { - fp->NonMBSFN_config_flag = 0; + fp->NonMBSFN_config_flag = 1; fp->NonMBSFN_config.radioframeAllocationPeriod=nonMBSFN_SubframeConfig->radioFrameAllocationPeriod_r14; fp->NonMBSFN_config.radioframeAllocationOffset=nonMBSFN_SubframeConfig->radioFrameAllocationOffset_r14; fp->NonMBSFN_config.non_mbsfn_SubframeConfig=(nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]>>7); diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c index 12a5646df6..f5b7a6c7e8 100644 --- a/openair1/PHY/INIT/lte_parms.c +++ b/openair1/PHY/INIT/lte_parms.c @@ -93,6 +93,11 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms, frame_parms->N_RBGS = 4; frame_parms->N_RBG = 25; + frame_parms->ofdm_symbol_size_khz_1dot25 = 2*2*6144*osf; + frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800*2*2; + frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf); + frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf); + break; case 75: @@ -104,6 +109,12 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms, frame_parms->nb_prefix_samples0=(frame_parms->nb_prefix_samples0*3)>>2; frame_parms->N_RBGS = 4; frame_parms->N_RBG = 25; + + frame_parms->ofdm_symbol_size_khz_1dot25 = 2*6144*osf; + frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800*2; + frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf); + frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf); + break; case 50: @@ -115,6 +126,10 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms, frame_parms->nb_prefix_samples0>>=(1-log2_osf); frame_parms->N_RBGS = 3; frame_parms->N_RBG = 17; + frame_parms->ofdm_symbol_size_khz_1dot25 = 2*6144*osf; + frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800*2; + frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf); + frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf); break; case 25: -- GitLab From c5799e1ccac1dcad93f0c275c0dba7e3e32e0815 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:42:47 +0200 Subject: [PATCH 03/34] fembms: missing protype added --- openair1/PHY/LTE_REFSIG/lte_refsig.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openair1/PHY/LTE_REFSIG/lte_refsig.h b/openair1/PHY/LTE_REFSIG/lte_refsig.h index 45402436f7..84a2676082 100644 --- a/openair1/PHY/LTE_REFSIG/lte_refsig.h +++ b/openair1/PHY/LTE_REFSIG/lte_refsig.h @@ -106,6 +106,16 @@ int lte_dl_mbsfn(PHY_VARS_eNB *phy_vars_eNB, int32_t *output, short amp, int subframe, unsigned char l); +/*! \brief This function generates the 1.25KHz MBSFN reference signal sequence (36-211, Sec 6.10.1.2) +@param phy_vars_eNB Pointer to eNB variables +@param output Output vector for OFDM symbol (Frequency Domain) +@param amp Q15 amplitude +*/ + +int lte_dl_mbsfn_khz_1dot25(PHY_VARS_eNB *phy_vars_eNB, int32_t *output, + short amp, + int subframe); + /*!\brief This function generates the cell-specific reference signal sequence (36-211, Sec 6.10.1.1) for channel estimation upon reception -- GitLab From da5ae9c8d1ddafa56b41323984ff31519434610d Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:48:26 +0200 Subject: [PATCH 04/34] fembms: L1 prototypes for FeMBMS eNB procedures Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/transport_common.h | 1 + .../LTE_TRANSPORT/transport_common_proto.h | 3 + openair1/PHY/LTE_TRANSPORT/transport_proto.h | 73 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h index 321789d54b..ab2921c2b9 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h @@ -67,6 +67,7 @@ #if !defined(SI_RNTI) #define SI_RNTI (rnti_t)0xffff + #define SI_RNTI_MBMS (rnti_t)0xfff9 #endif #if !defined(M_RNTI) #define M_RNTI (rnti_t)0xfffd diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h index e4f5d9a17f..1944f06fab 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h @@ -270,6 +270,9 @@ int is_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parm */ int is_fembms_cas_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); +int is_fembms_nonMBSFN_subframe (frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); + + /*! \brief Return the status of MBSFN in this frame/subframe @param frame Frame index diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 3988923bb9..4ce113f78e 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -123,6 +123,42 @@ int32_t dlsch_encoding(PHY_VARS_eNB *eNB, time_stats_t *te_stats, time_stats_t *i_stats); +/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *input_buffer, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe) + \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are: + - CRC computation and addition + - Code block segmentation and sub-block CRC addition + - Channel coding (Turbo coding) + - Rate matching (sub-block interleaving, bit collection, selection and transmission + - Code block concatenation + @param eNB Pointer to eNB PHY context + @param input_buffer Pointer to input buffer for sub-frame + @param frame_parms Pointer to frame descriptor structure + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch Pointer to dlsch to be encoded + @param frame Frame number + @param subframe Subframe number + @param rm_stats Time statistics for rate-matching + @param te_stats Time statistics for turbo-encoding + @param i_stats Time statistics for interleaving + @returns status +*/ +int32_t dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc, + uint8_t *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); + @@ -269,6 +305,30 @@ int mch_modulation(int32_t **txdataF, LTE_DL_FRAME_PARMS *frame_parms, LTE_eNB_DLSCH_t *dlsch); +/* + \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH. + @param txdataF Table of pointers for frequency-domain TX signals + @param amp Amplitude of signal + @param subframe_offset Offset of this subframe in units of subframes (usually 0) + @param frame_parms Pointer to frame descriptor + @param dlsch Pointer to DLSCH descriptor for this allocation +*/ +int mch_modulation_khz_1dot25(int32_t **txdataF, + int16_t amp, + uint32_t subframe_offset, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_eNB_DLSCH_t *dlsch); + + +/** \brief Top-level generation function for eNB TX of MBSFN + @param phy_vars_eNB Pointer to eNB variables + @param a Pointer to transport block + @param abstraction_flag + +*/ +void generate_mch_khz_1dot25(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t *a); + + /** \brief Top-level generation function for eNB TX of MBSFN @param phy_vars_eNB Pointer to eNB variables @param a Pointer to transport block @@ -318,6 +378,12 @@ int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB, uint16_t slot, int first_pilot_only); +int32_t generate_mbsfn_pilot_khz_1dot25(PHY_VARS_eNB *phy_vars_eNB, + L1_rxtx_proc_t *proc, + int32_t **txdataF, + int16_t amp); + + int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB, L1_rxtx_proc_t *proc, int32_t **txdataF, @@ -350,6 +416,13 @@ int32_t generate_pbch(LTE_eNB_PBCH *eNB_pbch, uint8_t *pbch_pdu, uint8_t frame_mod4); +int32_t generate_pbch_fembms(LTE_eNB_PBCH *eNB_pbch, + int32_t **txdataF, + int32_t amp, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t *pbch_pdu, + uint8_t frame_mod16); + -- GitLab From 4923ba301a4e15fbdb1a41429e206284505018ca Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:49:58 +0200 Subject: [PATCH 05/34] fembms: Addapting top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212 with FeMBMS support Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 109 +++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 14036ad43a..ce4e6fba9f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -20,12 +20,12 @@ */ /*! \file PHY/LTE_TRANSPORT/dlsch_coding.c - * \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03 + * \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03, V14.1 2017 (includes FeMBMS support) * \author R. Knopp * \date 2011 * \version 0.1 * \company Eurecom - * \email: knopp@eurecom.fr + * \email: knopp@eurecom.fr, jaiver.morgade@ieee.org * \note * \warning */ @@ -425,3 +425,108 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } + +int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc, + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats) { + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe]; + if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) { + LOG_E(PHY,"dlsch_encoding illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); + return(-1); + } + + LTE_DL_eNB_HARQ_t *hadlsch=dlsch->harq_processes[harq_pid]; + uint8_t beamforming_mode=0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); + + if(hadlsch->mimo_mode == TM7) + beamforming_mode = 7; + else if(hadlsch->mimo_mode == TM8) + beamforming_mode = 8; + else if(hadlsch->mimo_mode == TM9_10) + beamforming_mode = 9; + + unsigned int G = get_G_khz_1dot25(frame_parms,hadlsch->nb_rb, + hadlsch->rb_alloc, + hadlsch->Qm, // mod order + hadlsch->Nl, + num_pdcch_symbols, + frame,subframe,beamforming_mode); + + 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 + unsigned int A=hadlsch->TBS; //6228; + unsigned int crc = crc24a(a, + A)>>8; + a[A>>3] = ((uint8_t *)&crc)[2]; + a[1+(A>>3)] = ((uint8_t *)&crc)[1]; + a[2+(A>>3)] = ((uint8_t *)&crc)[0]; + // printf("CRC %x (A %d)\n",crc,A); + hadlsch->B = A+24; + // hadlsch->b = a; + memcpy(hadlsch->b,a,(A/8)+4); + + if (lte_segmentation(hadlsch->b, + hadlsch->c, + hadlsch->B, + &hadlsch->C, + &hadlsch->Cplus, + &hadlsch->Cminus, + &hadlsch->Kplus, + &hadlsch->Kminus, + &hadlsch->F)<0) + return(-1); + } + + for (int r=0, r_offset=0; rC; r++) { + + union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}}; + notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode); + turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req); + rdata->input=hadlsch->c[r]; + rdata->Kr_bytes= ( rCminus ? hadlsch->Kminus : hadlsch->Kplus) >>3; + rdata->filler=(r==0) ? hadlsch->F : 0; + rdata->r=r; + rdata->harq_pid=harq_pid; + rdata->dlsch=dlsch; + rdata->rm_stats=rm_stats; + rdata->te_stats=te_stats; + rdata->i_stats=i_stats; + rdata->round=hadlsch->round; + rdata->r_offset=r_offset; + rdata->G=G; + + if ( proc->threadPool->activated ) { + pushTpool(proc->threadPool,req); + proc->nbEncode++; + } else { + TPencode(rdata); + delNotifiedFIFO_elt(req); + } + + int Qm=hadlsch->Qm; + int C=hadlsch->C; + int Nl=hadlsch->Nl; + int Gp = G/Nl/Qm; + int GpmodC = Gp%C; + if (r < (C-(GpmodC))) + r_offset += Nl*Qm * (Gp/C); + else + r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); + } + + return(0); +} + + -- GitLab From 3d11b3d65dd794942bf5540dc578b854c3f2dc93 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:51:51 +0200 Subject: [PATCH 06/34] fembms: FeMBMS (eNB) Top-level routines for generating the PDSCH physical channel from 36-211 V14.1 Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 261 +++++++++++++++++- 1 file changed, 259 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 475c8bd521..eeb701657a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -20,12 +20,12 @@ */ /*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c - * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03 + * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03, V14.1 2017 (FeMBMS) * \author R. Knopp, F. Kaltenberger * \date 2011 * \version 0.1 * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, javier.morgade@ieee.irg * \note * \warning */ @@ -2910,3 +2910,260 @@ int mch_modulation(int32_t **txdataF, return (re_allocated); } + +int allocate_REs_in_RB_MCH_khz_1dot25(int32_t **txdataF, + uint32_t *jj, + uint16_t re_offset, + uint32_t symbol_offset, + uint8_t *x0, + uint8_t subframe, + uint8_t mod_order, + int16_t amp, + int16_t *qam_table_s, + uint32_t *re_allocated, + uint8_t skip_dc, + LTE_DL_FRAME_PARMS *frame_parms) +{ + uint32_t tti_offset; + uint8_t re,offset; + uint8_t qam64_table_offset_re = 0; + uint8_t qam64_table_offset_im = 0; + uint8_t qam16_table_offset_re = 0; + uint8_t qam16_table_offset_im = 0; + int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2; + int16_t re_off=re_offset; + gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); + uint8_t first_re,last_re; + int inc; +#ifdef DEBUG_DLSCH_MODULATION + LOG_I(PHY,"allocate_re_MCH khz_1dot25 (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]); +#endif + + /*last_re=12; + first_re=0; + inc=1; + + if ((l==2)||(l==10)) { + inc=2; + first_re=1; + } else if (l==6) { + inc=2; + }*/ + last_re=144; //12*12 + if ((subframe&0x1)==0){ // n_sf mod 2 == 0: even + first_re=1; + offset=0; + }else{ + first_re=0; + offset=3; + } + inc=1; + + for (re=first_re; reofdm_symbol_size_khz_1dot25+1; + } + + tti_offset = symbol_offset + re_off + re; + + //LOG_I(PHY,"re %d (jj %d)\n",re,*jj); + *re_allocated = *re_allocated + 1; + + + switch (mod_order) { + + case 2: //QPSK + + LOG_D(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i + + *jj = *jj + 1; + + ((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} + + *jj = *jj + 1; + + LOG_D(PHY,"subframe%d alloc[%d][%d][%d](%d,%d)\n",subframe,tti_offset,symbol_offset,tti_offset-symbol_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + break; + + + case 4: //16QAM + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; + + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + + *jj=*jj+1; + + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + + *jj=*jj+1; + + + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + break; + + case 6: //64QAM + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + + *jj=*jj+1; + + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + break; + + } + } + return(0); +} + +int mch_modulation_khz_1dot25(int32_t **txdataF, + int16_t amp, + uint32_t subframe_offset, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_eNB_DLSCH_t *dlsch) +{ + uint8_t nsymb,nsymb_pmch; + uint32_t i,jj,re_allocated,symbol_offset; + uint16_t l,rb,re_offset; + uint8_t skip_dc=0; + uint8_t mod_order = dlsch->harq_processes[0]->Qm; + int16_t qam16_table_a[4],qam64_table_a[8];//,qam16_table_b[4],qam64_table_b[8]; + int16_t *qam_table_s; + + nsymb_pmch = 1; + nsymb = (frame_parms->Ncp == NORMAL) ? 14 : 12; + + if (mod_order == 4) + for (i=0; i<4; i++) { + qam16_table_a[i] = (int16_t)(((int32_t)qam16_table[i]*amp)>>15); + } + else if (mod_order == 6) + for (i=0; i<8; i++) { + qam64_table_a[i] = (int16_t)(((int32_t)qam64_table[i]*amp)>>15); + } + + jj=0; + re_allocated=0; + + + + + + // LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); + for (l=0; lfirst_carrier_offset_khz_1dot25; + symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); + + for (rb=0; rbN_RB_DL; rb++) { + + + if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL + + if (rb==(frame_parms->N_RB_DL>>1)) + skip_dc = 1; + else + skip_dc = 0; + + } + + if (mod_order == 4) + qam_table_s = qam16_table_a; + else if (mod_order == 6) + qam_table_s = qam64_table_a; + else + qam_table_s = NULL; + + //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp); + allocate_REs_in_RB_MCH_khz_1dot25(txdataF, + &jj, + re_offset, + symbol_offset, + dlsch->harq_processes[0]->eDL, + subframe_offset, + mod_order, + amp, + qam_table_s, + &re_allocated, + skip_dc, + frame_parms); + + re_offset+=144; // go to next RB 12*12 + + // check if we crossed the symbol boundary and skip DC + if (re_offset >= frame_parms->ofdm_symbol_size_khz_1dot25) { + if (skip_dc == 0) //even number of RBs (doesn't straddle DC) + re_offset=1; + else + re_offset=73; // odd number of RBs + } + } + } + +#ifdef DEBUG_DLSCH_MODULATION + LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/)); + LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d\n",jj,re_allocated); +#endif + + return (re_allocated); +} + -- GitLab From 3fca8304a446b82966c38dd11af4d5116bb52490 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:54:01 +0200 Subject: [PATCH 07/34] fembms: FeMBMS top-level routines for generating and decoding the PBCH/BCH physical/transport channel Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/pbch.c | 283 +++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c index 37997c94b4..a142f22a54 100644 --- a/openair1/PHY/LTE_TRANSPORT/pbch.c +++ b/openair1/PHY/LTE_TRANSPORT/pbch.c @@ -20,12 +20,12 @@ */ /*! \file PHY/LTE_TRANSPORT/pbch.c -* \brief Top-level routines for generating and decoding the PBCH/BCH physical/transport channel V8.6 2009-03 +* \brief Top-level routines for generating and decoding the PBCH/BCH physical/transport channel V8.6 2009-03, V14.1 (FeMBMS) * \author R. Knopp, F. Kaltenberger * \date 2011 * \version 0.1 * \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger.fr +* \email: knopp@eurecom.fr,florian.kaltenberger.fr, javier.morgade@ieee.org * \note * \warning */ @@ -139,6 +139,285 @@ int allocate_pbch_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, return(0); } +void pbch_scrambling_fembms(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t *pbch_e, + uint32_t length) +{ + int i; + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in lte_gold_generic + x2 = frame_parms->Nid_cell + (1<<9); //this is c_init for FeMBMS in 36.211 Sec 6.6.1 + // msg("pbch_scrambling: Nid_cell = %d\n",x2); + + for (i=0; i>(i&0x1f))&1); + + } +} + +int generate_pbch_fembms(LTE_eNB_PBCH *eNB_pbch, + int32_t **txdataF, + int amp, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t *pbch_pdu, + uint8_t frame_mod4) +{ + + int i, l; + + uint32_t pbch_D,pbch_E;//,pbch_coded_bytes; + uint8_t pbch_a[PBCH_A>>3]; + uint8_t RCC; + + uint32_t nsymb = (frame_parms->Ncp==NORMAL) ? 14:12; + uint32_t pilots; +#ifdef INTERFERENCE_MITIGATION + uint32_t pilots_2; +#endif + uint32_t second_pilot = (frame_parms->Ncp==NORMAL) ? 4 : 3; + uint32_t jj=0; + uint32_t re_allocated=0; + uint32_t rb, re_offset, symbol_offset; + uint16_t amask=0; + + pbch_D = 16+PBCH_A; + + pbch_E = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) + // pbch_E_bytes = pbch_coded_bits>>3; + + LOG_D(PHY,"%s(eNB_pbch:%p txdataF:%p amp:%d frame_parms:%p pbch_pdu:%p frame_mod4:%d)\n", __FUNCTION__, eNB_pbch, txdataF, amp, frame_parms, pbch_pdu, frame_mod4==0); + + if (frame_mod4==0) { + bzero(pbch_a,PBCH_A>>3); + bzero(eNB_pbch->pbch_e,pbch_E); + memset(eNB_pbch->pbch_d,LTE_NULL,96); + // Encode data + + // CRC attachment + // crc = (uint16_t) (crc16(pbch_pdu, pbch_crc_bits-16) >> 16); + + /* + // scramble crc with PBCH CRC mask (Table 5.3.1.1-1 of 3GPP 36.212-860) + switch (frame_parms->nb_antenna_ports_eNB) { + case 1: + crc = crc ^ (uint16_t) 0; + break; + case 2: + crc = crc ^ (uint16_t) 0xFFFF; + break; + case 4: + crc = crc ^ (uint16_t) 0xAAAA; + break; + default: + msg("[PBCH] Unknown number of TX antennas!\n"); + break; + } + */ + + // Fix byte endian of PBCH (bit 23 goes in first) + for (i=0; i<(PBCH_A>>3); i++) + pbch_a[(PBCH_A>>3)-i-1] = pbch_pdu[i]; + + // pbch_data[i] = ((char*) &crc)[0]; + // pbch_data[i+1] = ((char*) &crc)[1]; + //#ifdef DEBUG_PBCH + + for (i=0; i<(PBCH_A>>3); i++) + LOG_D(PHY,"[PBCH] pbch_data[%d] = %x\n",i,pbch_a[i]); + + //#endif + + if (frame_parms->nb_antenna_ports_eNB == 1) + amask = 0x0000; + else { + switch (frame_parms->nb_antenna_ports_eNB) { + case 1: + amask = 0x0000; + break; + + case 2: + amask = 0xffff; + break; + + case 4: + amask = 0x5555; + } + } + + ccodelte_encode(PBCH_A,2,pbch_a,eNB_pbch->pbch_d+96,amask); + + +#ifdef DEBUG_PBCH_ENCODING + + for (i=0; i<16+PBCH_A; i++) + LOG_D(PHY,"%d : (%d,%d,%d)\n",i,*(eNB_pbch->pbch_d+96+(3*i)),*(eNB_pbch->pbch_d+97+(3*i)),*(eNB_pbch->pbch_d+98+(3*i))); + +#endif //DEBUG_PBCH_ENCODING + + // Bit collection + /* + j2=0; + for (j=0;j 0) { // bit is to be transmitted + pbch_coded_data2[j2++] = pbch_coded_data[j]&1; + //Bit is repeated + if ((pbch_coded_data[j]&0x40)>0) + pbch_coded_data2[j2++] = pbch_coded_data[j]&1; + } + } + + #ifdef DEBUG_PBCH + msg("[PBCH] rate matched bits=%d, pbch_coded_bits=%d, pbch_crc_bits=%d\n",j2,pbch_coded_bits,pbch_crc_bits); + #endif + + #ifdef DEBUG_PBCH + LOG_M"pbch_encoded_output2.m","pbch_encoded_out2", + pbch_coded_data2, + pbch_coded_bits, + 1, + 4); + #endif //DEBUG_PBCH + */ +#ifdef DEBUG_PBCH_ENCODING + LOG_D(PHY,"Doing PBCH interleaving for %d coded bits, e %p\n",pbch_D,eNB_pbch->pbch_e); +#endif + RCC = sub_block_interleaving_cc(pbch_D,eNB_pbch->pbch_d+96,eNB_pbch->pbch_w); + + lte_rate_matching_cc(RCC,pbch_E,eNB_pbch->pbch_w,eNB_pbch->pbch_e); + +#ifdef DEBUG_PBCH_ENCODING + LOG_D(PHY,"PBCH_e:\n"); + + for (i=0; ipbch_e+i)); + + LOG_D(PHY,"\n"); +#endif + + + +#ifdef DEBUG_PBCH + if (frame_mod4==0) { + LOG_M("pbch_e.m","pbch_e", + eNB_pbch->pbch_e, + pbch_E, + 1, + 4); + + for (i=0; i<16; i++) + printf("e[%d] %d\n",i,eNB_pbch->pbch_e[i]); + } +#endif //DEBUG_PBCH + // scrambling + + pbch_scrambling_fembms(frame_parms, + eNB_pbch->pbch_e, + pbch_E); +#ifdef DEBUG_PBCH + if (frame_mod4==0) { + LOG_M("pbch_e_s.m","pbch_e_s", + eNB_pbch->pbch_e, + pbch_E, + 1, + 4); + + for (i=0; i<16; i++) + printf("e_s[%d] %d\n",i,eNB_pbch->pbch_e[i]); + } +#endif //DEBUG_PBCH + } // frame_mod4==0 + + // modulation and mapping (slot 1, symbols 0..3) + for (l=(nsymb>>1); l<(nsymb>>1)+4; l++) { + + pilots=0; +#ifdef INTERFERENCE_MITIGATION + pilots_2 = 0; +#endif + + if ((l==0) || (l==(nsymb>>1))) { + pilots=1; +#ifdef INTERFERENCE_MITIGATION + pilots_2=1; +#endif + } + + if ((l==1) || (l==(nsymb>>1)+1)) { + pilots=1; + } + + if ((l==second_pilot)||(l==(second_pilot+(nsymb>>1)))) { + pilots=1; + } + +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] l=%d, pilots=%d\n",l,pilots); +#endif + + + re_offset = frame_parms->ofdm_symbol_size-3*12; + symbol_offset = frame_parms->ofdm_symbol_size*l; + + for (rb=0; rb<6; rb++) { + +#ifdef DEBUG_PBCH + LOG_D(PHY,"RB %d, jj %d, re_offset %d, symbol_offset %d, pilots %d, nushift %d\n",rb,jj,re_offset, symbol_offset, pilots,frame_parms->nushift); +#endif + allocate_pbch_REs_in_RB(frame_parms, + txdataF, + &jj, + re_offset, + symbol_offset, + &eNB_pbch->pbch_e[frame_mod4*(pbch_E>>2)], + pilots, +#ifdef INTERFERENCE_MITIGATION + (pilots_2==1)?(amp/3):amp, +#else + amp, +#endif + &re_allocated); + + re_offset+=12; // go to next RB + + // check if we crossed the symbol boundary and skip DC + + if (re_offset >= frame_parms->ofdm_symbol_size) + re_offset=1; + } + + // } + } + +#ifdef DEBUG_PBCH + printf("[PBCH] txdataF=\n"); + + for (i=0; iofdm_symbol_size; i++) { + printf("%d=>(%d,%d)",i,((short*)&txdataF[0][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[0], + ((short*)&txdataF[0][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[1]); + + if (frame_parms->nb_antenna_ports_eNB!=1) { + printf("(%d,%d)\n",((short*)&txdataF[1][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[0], + ((short*)&txdataF[1][frame_parms->ofdm_symbol_size*(nsymb>>1)+i])[1]); + } else { + printf("\n"); + } + } + +#endif + + + return(0); +} + void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t *pbch_e, uint32_t length) -- GitLab From 459eff02d1488ac190a20773f8f3730411848ad6 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:58:57 +0200 Subject: [PATCH 08/34] fembms: Top-level routines for generating DL mbsfn reference signals for FeMBMS (eNB) Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- openair1/PHY/LTE_TRANSPORT/pbch.c | 2 +- openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c | 34 +++++++++++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index ce4e6fba9f..3eb44d98fa 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -21,7 +21,7 @@ /*! \file PHY/LTE_TRANSPORT/dlsch_coding.c * \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03, V14.1 2017 (includes FeMBMS support) - * \author R. Knopp + * \author R. Knopp, J. Morgade * \date 2011 * \version 0.1 * \company Eurecom diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index eeb701657a..8c07421b7e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -21,7 +21,7 @@ /*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03, V14.1 2017 (FeMBMS) - * \author R. Knopp, F. Kaltenberger + * \author R. Knopp, F. Kaltenberger, J. Morgade * \date 2011 * \version 0.1 * \company Eurecom diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c index a142f22a54..dfa990269e 100644 --- a/openair1/PHY/LTE_TRANSPORT/pbch.c +++ b/openair1/PHY/LTE_TRANSPORT/pbch.c @@ -21,7 +21,7 @@ /*! \file PHY/LTE_TRANSPORT/pbch.c * \brief Top-level routines for generating and decoding the PBCH/BCH physical/transport channel V8.6 2009-03, V14.1 (FeMBMS) -* \author R. Knopp, F. Kaltenberger +* \author R. Knopp, F. Kaltenberger, J. Morgade * \date 2011 * \version 0.1 * \company Eurecom diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c index 475102b57c..47ef6428cb 100644 --- a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c +++ b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c @@ -20,12 +20,12 @@ */ /*! \file PHY/LTE_TRANSPORT/pilots_mbsfn.c -* \brief Top-level routines for generating DL mbsfn reference signals -* \authors S. Paranche, R. Knopp +* \brief Top-level routines for generating DL mbsfn reference signals / DL mbsfn reference signals for FeMBMS +* \authors S. Paranche, R. Knopp, J. Morgade * \date 2012 * \version 0.1 * \company Eurecom -* \email: knopp@eurecom.fr +* \email: knopp@eurecom.fr, javier.morgade@ieee.org * \note * \warning */ @@ -85,3 +85,31 @@ int generate_mbsfn_pilot(PHY_VARS_eNB *eNB, } +int generate_mbsfn_pilot_khz_1dot25(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc, + int32_t **txdataF, + int16_t amp) + +{ + + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + uint32_t subframe_offset,Nsymb; + int subframe = proc->subframe_tx; + + + if (subframe<0 || subframe>= 10) { + LOG_E(PHY,"generate_mbsfn_pilots_subframe: subframe not in range (%d)\n",subframe); + return(-1); + } + + Nsymb = (frame_parms->Ncp==NORMAL) ? 7 : 6; + + subframe_offset = subframe*frame_parms->ofdm_symbol_size*Nsymb<<1; + + lte_dl_mbsfn_khz_1dot25(eNB, + &txdataF[0][subframe_offset+0], + amp,subframe); + + return(0); +} + -- GitLab From 58bd55b9b39ffdca2a234871c707f32a357c7a3d Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 11:02:18 +0200 Subject: [PATCH 09/34] fembms: -Increase buffer size in PHY_ofdm_mod to accomodate FeMBMS sizes -New FFT sizes added (IDFT_12288, IDFT_24576) to enable support for FeMBMS 10MHz and 20MHz channels BWs Signed-off-by: Javier Morgade --- openair1/PHY/MODULATION/ofdm_mod.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 855e649cc5..e1d21af9b9 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -88,7 +88,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input if(nb_symbols == 0) return; - short temp[4096*4] __attribute__((aligned(32))); + short temp[2*2*6144*4] __attribute__((aligned(32))); unsigned short i,j; short k; @@ -125,9 +125,23 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input case 3072: idftsize = IDFT_3072; break; + case 4096: idftsize = IDFT_4096; break; + + case 6144: + idftsize= IDFT_6144; + break; + + case 12288: + idftsize= IDFT_12288; + break; + + case 24576: + idftsize= IDFT_24576; + break; + default: idftsize = IDFT_512; break; -- GitLab From 8eac27b83b4b3792921e6758d000c649f8d6af2e Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 15:07:05 +0200 Subject: [PATCH 10/34] fembms: Added support for FeMBMS UE Channel Estimation Procedures for 10 and 20 MHz BWs @ FeMBMS 1.25KHz Carrier Spacing Signed-off-by: Javier Morgade --- .../lte_dl_mbsfn_channel_estimation.c | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c index 333a6f0866..4ad050ccea 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c @@ -22,7 +22,7 @@ /*! \file config_ue.c * \brief This includes FeMBMS UE Channel Estimation Procedures for FeMBMS 1.25KHz Carrier Spacing * \author Javier Morgade - * \date 2019 + * \date 2020 * \version 0.1 * \email: javier.morgade@ieee.org * @ingroup _phy @@ -768,8 +768,8 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, module_id_t eNB_id, uint8_t eNB_offset, int subframe) { - int pilot_khz_1dot25[600] __attribute__((aligned(16))); - unsigned char aarx/*,aa*/; + int pilot_khz_1dot25[2*2*600] __attribute__((aligned(16))); + unsigned char aarx,aa; //unsigned int rb; int16_t ch[2]; short *pil,*rxF,*dl_ch/*,*ch0,*ch1,*ch11,*chp,*ch_prev*/; @@ -783,7 +783,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; ch_offset = 0;//(l*(ue->frame_parms.ofdm_symbol_size)); symbol_offset = 0;//ch_offset;//phy_vars_ue->lte_frame_parms.ofdm_symbol_size*l; - AssertFatal( ue->frame_parms.N_RB_DL==25,"OFDM symbol size %d not yet supported for FeMBMS\n",ue->frame_parms.N_RB_DL); + //AssertFatal( ue->frame_parms.N_RB_DL==25,"OFDM symbol size %d not yet supported for FeMBMS\n",ue->frame_parms.N_RB_DL); if( (subframe&0x1) == 0) { f=filt24_0_khz_1dot25; @@ -823,7 +823,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, k=3; } - if(ue->frame_parms.N_RB_DL==25) { + if(1/*ue->frame_parms.N_RB_DL==25*/) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(fl, @@ -843,7 +843,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, rxF+=12; dl_ch+=16; - for(pilot_cnt=2; pilot_cnt<299; pilot_cnt+=2) { + for(pilot_cnt=2; pilot_cntframe_parms.N_RB_DL*12-1/*299*/; pilot_cnt+=2) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(f, @@ -866,7 +866,7 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; //Skip DC offset - for(pilot_cnt=0; pilot_cnt<297; pilot_cnt+=2) { + for(pilot_cnt=0; pilot_cntframe_parms.N_RB_DL*12-3/*297*/; pilot_cnt+=2) { ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); multadd_real_vector_complex_scalar(f, @@ -905,6 +905,32 @@ int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, } } + // do ifft of channel estimate + for (aa=0; aaframe_parms.nb_antennas_rx*ue->frame_parms.nb_antennas_tx; aa++) { + if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa]) { + switch (ue->frame_parms.N_RB_DL) { + case 25: + idft(IDFT_6144,(int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa][8], + (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[0][aa], + 1); + break; + case 50: + idft(IDFT_12288,(int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa][8], + (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[0][aa], + 1); + break; + case 100: + idft(IDFT_24576,(int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0][aa][8], + (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[0][aa], + 1); + break; + default: + break; + } + } + } + + return(0); } -- GitLab From 5eb6dac7db84acf874107e3b14ba83e31f13db3a Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 15:09:38 +0200 Subject: [PATCH 11/34] fembms: routines for decoding the UE FeMBMS/PMCH physical/multicast/transport channel 3GPP TS 36.211 version 14.2.0 Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/pmch.c | 50 +++++++++++ openair1/PHY/LTE_TRANSPORT/pmch_common.c | 103 ++++++++++++++++++----- 2 files changed, 134 insertions(+), 19 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index 90e2836b1e..7b508239a9 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -128,3 +128,53 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a) } +void generate_mch_khz_1dot25(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a) +{ + + int G; + int subframe = proc->subframe_tx; + int frame = proc->frame_tx; + //int bits; + + G = get_G_khz_1dot25(&eNB->frame_parms, + eNB->frame_parms.N_RB_DL, + eNB->dlsch_MCH->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1, + 2,proc->frame_tx,subframe,0); + + //FeMBMS + eNB->dlsch_MCH->harq_processes[0]->Qm = get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs); + + + generate_mbsfn_pilot_khz_1dot25(eNB,proc, + eNB->common_vars.txdataF, + AMP); + + + AssertFatal(dlsch_encoding_fembms_pmch(eNB, + proc, + // a, + eNB->dlsch_MCH->harq_processes[0]->pdu, + 1, + eNB->dlsch_MCH, + proc->frame_tx, + subframe, + &eNB->dlsch_rate_matching_stats, + &eNB->dlsch_turbo_encoding_stats, + &eNB->dlsch_interleaving_stats)==0, + "problem in dlsch_encoding"); + + + /*for(bits=0;bitsdlsch_MCH->harq_processes[0]->e[bits]); + printf("\n");*/ + + dlsch_scrambling(&eNB->frame_parms,1,eNB->dlsch_MCH,0,G,0,frame,subframe<<1); + + mch_modulation_khz_1dot25(eNB->common_vars.txdataF, + AMP, + subframe, + &eNB->frame_parms, + eNB->dlsch_MCH); +} + diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c index 03bf5a378b..8d65dd2744 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c @@ -37,23 +37,84 @@ int is_fembms_cas_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) { - uint32_t period; - - if(frame_parms->NonMBSFN_config_flag ) { - period = 4<NonMBSFN_config.radioframeAllocationPeriod; - - if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + //uint32_t period; + + //if(frame_parms->NonMBSFN_config_flag ) { + // period = 4<NonMBSFN_config.radioframeAllocationPeriod; + + // if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + // switch (subframe) { + // case 0: + // return(1); //This should be CAS + // break; + // } + // } + //} + if(frame_parms->NonMBSFN_config_flag || frame_parms->FeMBMS_active){ + if ((frame&3)==0) { switch (subframe) { case 0: - return(1); //This should be CAS - break; + return(1); //This should be CAS + break; } - } + } + } return (0); } +int is_fembms_nonMBSFN_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms){ + uint32_t period; + if(frame_parms->NonMBSFN_config_flag ) { + period = 4<NonMBSFN_config.radioframeAllocationPeriod; + if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + switch (subframe) { + case 0: + return(1); //This should be CAS + break; + case 1: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x100) > 0) + return(1); + break; + case 2: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x80) > 0) + return(1); + break; + case 3: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x40) > 0) + return(1); + break; + case 4: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x20) > 0) + return(1); + break; + case 5: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x10) > 0) + return(1); + break; + case 6: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x8) > 0) + return(1); + break; + case 7: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x4) > 0) + return(1); + break; + case 8: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x2) > 0) + return(1); + break; + case 9: + if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x1) > 0) + return(1); + break; + } + } + } + return (0); +} + int is_fembms_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) { uint32_t period; @@ -62,63 +123,67 @@ int is_fembms_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *fr if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { switch (subframe) { + case 0: + return(0); + break; case 1: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x100) > 0) - return(1); + return(0); break; case 2: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x80) > 0) - return(1); + return(0); break; case 3: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x40) > 0) - return(1); + return(0); break; case 4: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x20) > 0) - return(1); + return(0); break; case 5: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x10) > 0) - return(1); + return(0); break; case 6: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x8) > 0) - return(1); + return(0); break; case 7: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x4) > 0) - return(1); + return(0); break; case 8: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x2) > 0) - return(1); + return(0); break; case 9: if ((frame_parms->NonMBSFN_config.non_mbsfn_SubframeConfig & 0x1) > 0) - return(1); + return(0); break; } - } else { //Then regular MBSFN FeMBMS subframe + } else if((frame_parms->FeMBMS_active == 1 || frame_parms->NonMBSFN_config_flag == 1 ) && !is_fembms_cas_subframe(frame,subframe,frame_parms) ) { //Then regular MBSFN FeMBMS subframe return(1); } + return(1); } return(0); -- GitLab From 0bef84d0a5bf4027a9538590e3d6f4119568fbe2 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 15:16:49 +0200 Subject: [PATCH 12/34] fembms: - FeMBMS 36.213 eNB procedures v14.2 - FeMBMS 36.213 UE procedures v14.2 - Implementation of OFDM encoding for FeMBMS/eNB v14.2 Signed-off-by: Javier Morgade --- openair1/SCHED/phy_procedures_lte_eNb.c | 138 ++++++++++++++++++++-- openair1/SCHED/ru_procedures.c | 25 +++- openair1/SCHED_UE/phy_procedures_lte_ue.c | 50 +++++++- 3 files changed, 198 insertions(+), 15 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index fc9407f8d0..6717b045ac 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -20,12 +20,12 @@ */ /*! \file phy_procedures_lte_eNB.c - * \brief Implementation of eNB procedures from 36.213 LTE specifications - * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas + * \brief Implementation of eNB procedures from 36.213 LTE specifications / FeMBMS 36.231 LTE procedures v14.2 + * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas, J. Morgade * \date 2011 * \version 0.1 * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk, javier.morgade@ieee.org * \note * \warning */ @@ -122,12 +122,32 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr } #ifdef MBMS_NFAPI_SCHEDULER -void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { +void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, int fembms_flag) { int subframe = proc->subframe_tx; // This is DL-Cell spec pilots in Control region - generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1); - if(eNB->dlsch_MCH->active==1) - generate_mch (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/); + if(!fembms_flag){ + generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1); + generate_mbsfn_pilot(eNB,proc, + eNB->common_vars.txdataF, + AMP); + }else + generate_mbsfn_pilot_khz_1dot25(eNB,proc, + eNB->common_vars.txdataF, + AMP); + + if(eNB->dlsch_MCH->active==1){ + if(!fembms_flag){ + generate_mch (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/); + } + else{ + generate_mch_khz_1dot25 (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/); + } + + LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (TBS %d) fembms %d \n", + eNB->Mod_id,proc->frame_tx,subframe, + eNB->dlsch_MCH->harq_processes[0]->TBS>>3,fembms_flag); + + } eNB->dlsch_MCH->active = 0; } #else @@ -171,6 +191,80 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { } #endif +void common_signal_procedures_fembms (PHY_VARS_eNB *eNB,int frame, int subframe) { + LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; + int **txdataF = eNB->common_vars.txdataF; + uint8_t *pbch_pdu=&eNB->pbch_pdu[0]; + + if((frame&3)!=0 /*&& subframe != 0*/) + return; + + LOG_I(PHY,"common_signal_procedures: frame %d, subframe %d fdd:%s dir:%s index:%d\n",frame,subframe,fp->frame_type == FDD?"FDD":"TDD", subframe_select(fp,subframe) == SF_DL?"DL":"UL?",(frame&15)/4); + // generate Cell-Specific Reference Signals for both slots + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1); + + + if(subframe_select(fp,subframe) == SF_S) + generate_pilots_slot(eNB, + txdataF, + AMP, + subframe<<1,1); + else + generate_pilots_slot(eNB, + txdataF, + AMP, + subframe<<1,0); + + // check that 2nd slot is for DL + if (subframe_select (fp, subframe) == SF_DL) + generate_pilots_slot (eNB, txdataF, AMP, (subframe << 1) + 1, 0); + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX, 0); + + // First half of PSS/SSS (FDD, slot 0) + if (subframe == 0) { + //if (fp->frame_type == FDD) { + generate_pss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 0); + generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 5 : 4, 0); + //} + + /// First half of SSS (TDD, slot 1) + + //if (fp->frame_type == TDD) { + generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 1); + //} + + // generate PBCH (Physical Broadcast CHannel) info + + /// generate PBCH + if ((frame&15)==0) { + //AssertFatal(eNB->pbch_configured==1,"PBCH was not configured by MAC\n"); + if (eNB->pbch_configured!=1) return; + + eNB->pbch_configured=0; + } + + T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_BUFFER(pbch_pdu, 3)); + generate_pbch_fembms (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, (frame & 15)/4); + } //else if ((subframe == 1) && (fp->frame_type == TDD)) { + //generate_pss (txdataF, AMP, fp, 2, 2); + // } + // Second half of PSS/SSS (FDD, slot 10) + else if ((subframe == 5) && (fp->frame_type == FDD) && is_fembms_nonMBSFN_subframe(frame,subframe,fp)) { + generate_pss (txdataF, AMP, &eNB->frame_parms, (fp->Ncp == NORMAL) ? 6 : 5, 10); + generate_sss (txdataF, AMP, &eNB->frame_parms, (fp->Ncp == NORMAL) ? 5 : 4, 10); + } + // Second-half of SSS (TDD, slot 11) + // else if ((subframe == 5) && (fp->frame_type == TDD)) { + // generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 11); + // } + // Second half of PSS (TDD, slot 12) + // else if ((subframe == 6) && (fp->frame_type == TDD)) { + // generate_pss (txdataF, AMP, fp, 2, 12); + // } +} + void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int **txdataF = eNB->common_vars.txdataF; @@ -417,12 +511,30 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { + if (is_fembms_pmch_subframe(frame,subframe,fp)) { +#ifdef MBMS_NFAPI_SCHEDULER + pmch_procedures(eNB,proc,1); + LOG_D(MAC,"frame %d, subframe %d -> PMCH\n",frame,subframe); + return; +#endif + }else if(is_fembms_cas_subframe(frame,subframe,fp) || is_fembms_nonMBSFN_subframe(frame,subframe,fp)){ + LOG_D(MAC,"frame %d, subframe %d -> CAS\n",frame,subframe); + common_signal_procedures_fembms(eNB,proc->frame_tx, proc->subframe_tx); + //return; + } + + if((!is_fembms_cas_subframe(frame,subframe,fp)) && (!is_fembms_nonMBSFN_subframe(frame,subframe,fp))){ if (is_pmch_subframe(frame,subframe,fp)) { +#ifdef MBMS_NFAPI_SCHEDULER + pmch_procedures(eNB,proc,0); +#else pmch_procedures(eNB,proc); +#endif } else { // this is not a pmch subframe, so generate PSS/SSS/PBCH common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx); } + } } // clear existing ulsch dci allocations before applying info from MAC (this is table @@ -508,6 +620,18 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, if (do_meas==1) start_meas(&eNB->dlsch_ue_specific); + if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { + if (is_fembms_pmch_subframe(frame,subframe,fp)) { +#ifdef MBMS_NFAPI_SCHEDULER + pmch_procedures(eNB,proc,1); + return; +#endif + }else if(is_fembms_cas_subframe(frame,subframe,fp)){ + common_signal_procedures_fembms(eNB,proc->frame_tx, proc->subframe_tx); + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); // Now scan UE specific DLSCH diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index cb03821388..e472d64db4 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -41,6 +41,17 @@ * \warning */ +/*! \function feptx0 + * \brief Implementation of ofdm encoding for FeMBMS profile in one eNB + * \author J. Morgade + * \date 2020 + * \version 0.1 + * \email: javier.morgade@ieee.org + * \note + * \warning + */ + + #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" @@ -76,7 +87,7 @@ void feptx0(RU_t *ru, int slot_sizeF = (fp->ofdm_symbol_size) * ((fp->Ncp==1) ? 6 : 7); int subframe = ru->proc.tti_tx; - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(slot&1) , 1 ); slot_offset = slot*(fp->samples_per_tti>>1); //slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1)); @@ -91,7 +102,17 @@ void feptx0(RU_t *ru, fp->nb_prefix_samples, CYCLIC_PREFIX); } else { - if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){ + if(is_fembms_pmch_subframe(ru->proc.frame_tx,subframe,fp)){ + if((slot&1)==0){//just use one slot chance + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size_khz_1dot25, + 1, + fp->ofdm_symbol_size_khz_1dot25>>2, + CYCLIC_PREFIX); + LOG_D(HW,"Generating PMCH FeMBMS TX subframe %d %d\n",subframe,fp->ofdm_symbol_size_khz_1dot25); + } + } else if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){ if ((slot&1) == 0) {//just use one slot chance normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF], (int*)&ru->common.txdata[aa][slot_offset], diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index e0ea4ef2b2..9f0b965e0c 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2383,10 +2383,12 @@ void ue_pbch_procedures(uint8_t eNB_id, if (pbch_phase>=4) pbch_phase=0; +if((ue->frame_parms.FeMBMS_active == 0)|| is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || first_run) { + for (pbch_trials=0; pbch_trials<4; pbch_trials++) { //for (pbch_phase=0;pbch_phase<4;pbch_phase++) { //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id); - if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { + if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || ue->frame_parms.FeMBMS_active) { pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, ue->pbch_vars[eNB_id], &ue->frame_parms, @@ -2431,9 +2433,10 @@ void ue_pbch_procedures(uint8_t eNB_id, ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; - if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { + if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || ue->frame_parms.FeMBMS_active) { frame_tx = (int)((ue->pbch_vars[eNB_id]->decoded_output[2]&31)<<1); frame_tx += ue->pbch_vars[eNB_id]->decoded_output[1]>>7; + frame_tx = frame_tx<<4; frame_tx +=4*pbch_phase; } else { frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8); @@ -2501,6 +2504,17 @@ void ue_pbch_procedures(uint8_t eNB_id, ue->frame_parms.phich_config_common.phich_duration, ue->frame_parms.phich_config_common.phich_resource); } + LOG_I(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n", + ue->Mod_id, + frame_rx, + subframe_rx, + ue->frame_parms.nb_antenna_ports_eNB, + pbch_tx_ant, + frame_tx, + ue->frame_parms.N_RB_DL, + ue->frame_parms.phich_config_common.phich_duration, + ue->frame_parms.phich_config_common.phich_resource); + } else { if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n", @@ -2533,6 +2547,8 @@ void ue_pbch_procedures(uint8_t eNB_id, ue->pbch_vars[eNB_id]->pdu_errors_conseq); } +} //if((ue->frame_parms.FeMBMS_active == 0)|| is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || first_run) + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } @@ -2691,6 +2707,7 @@ int ue_pdcch_procedures(uint8_t eNB_id, if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); } + LOG_W(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); if (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, @@ -2709,7 +2726,7 @@ int ue_pdcch_procedures(uint8_t eNB_id, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], 0)==0) { ue->dlsch_SI_received[eNB_id]++; - LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); + LOG_W(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } } else if ((dci_alloc_rx[i].rnti == P_RNTI) && @@ -2877,10 +2894,19 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, int l; int ret=0; - if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { + if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) || fembms_flag) { // LOG_D(PHY,"ue calling pmch subframe ..\n "); LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", ue->Mod_id,frame_rx,subframe_rx); + if(fembms_flag) + pmch_mcs = ue_query_mch_fembms(ue->Mod_id, + CC_id, + frame_rx, + subframe_rx, + eNB_id, + &sync_area, + &mcch_active); + else pmch_mcs = ue_query_mch(ue->Mod_id, CC_id, frame_rx, @@ -2960,6 +2986,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, LOG_D(PHY,"start turbo decode for MCH %d.%d --> Nl %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Nl); LOG_D(PHY,"start turbo decode for MCH %d.%d --> G %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G); LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo); + ret = dlsch_decoding(ue, ue->pdsch_vars_MCH[ue->current_thread_id[subframe_rx]][0]->llr[0], &ue->frame_parms, @@ -3007,14 +3034,14 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, // if (subframe_rx==9) // mac_xface->macphy_exit("Why are we exiting here?"); } else { // decoding successful - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH OK (%d,%d), passing to L2 (TBS %d, iter %d,G %d)\n", + LOG_I(PHY,"[UE %d] Frame %d, subframe %d: PMCH OK (%d,%d), passing to L2 (TBS %d, iter %d,G %d) ret %d\n", ue->Mod_id, frame_rx,subframe_rx, ue->dlsch_mcch_errors[sync_area][0], ue->dlsch_mtch_errors[sync_area][0], ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, ue->dlsch_MCH[0]->max_turbo_iterations, - ue->dlsch_MCH[0]->harq_processes[0]->G); + ue->dlsch_MCH[0]->harq_processes[0]->G,ret); ue_send_mch_sdu(ue->Mod_id, CC_id, frame_rx, @@ -3022,6 +3049,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, eNB_id,// not relevant in eMBMS context sync_area); + //dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); + //exit_fun("nothing to add"); if (mcch_active == 1) ue->dlsch_mcch_received[sync_area][0]++; @@ -4429,6 +4458,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue, ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag,1); return 0; } else { // this gets closed at end + if (is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms) || is_fembms_nonMBSFN_subframe(frame_rx,subframe_rx,&ue->frame_parms) ) { + l=0; + slot_fep(ue, + l, + subframe_rx<<1, + 0, + 0, + 0); + } pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; if (do_pdcch_flag) { -- GitLab From 220ba2ebc83a5a7ffcd114e439f0a5c07e095bcf Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 15:20:10 +0200 Subject: [PATCH 13/34] fembms: new mbmssim target (TOCHECK) Signed-off-by: Javier Morgade --- openair1/SIMULATION/LTE_PHY/mbmssim.c | 2530 +++++++++++++++++++++---- 1 file changed, 2172 insertions(+), 358 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index 65415e7c68..5073be24f5 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -19,204 +19,1048 @@ * contact@openairinterface.org */ +/*! \file mbmssim.c + \brief Top-level MBMS DL simulator + \authors R. Knopp, J. Morgade + \date 2011 - 2014 (Knopp) / 2020 (Morgade) + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr, javier.morgade@ieee.org + \note + \warning +*/ + #include #include #include -#include -#include -#include +#include +#include -#include "SIMULATION/TOOLS/defs.h" -#include "SIMULATION/RF/defs.h" +#include "SIMULATION/TOOLS/sim.h" #include "PHY/types.h" -#include "PHY/defs.h" -#include "PHY/vars.h" -#include "SCHED/defs.h" -#include "SCHED/vars.h" -#include "LAYER2/MAC/vars.h" - -#ifdef XFORMS - #include "PHY/TOOLS/lte_phy_scope.h" -#endif //XFORMS +#include "PHY/defs_eNB.h" +#include "PHY/defs_UE.h" +#include "PHY/phy_vars.h" +#include "SCHED/sched_eNB.h" +#include "SCHED/sched_common_vars.h" +#include "LAYER2/MAC/mac_vars.h" #include "OCG_vars.h" +#include "common/utils/LOG/log.h" +#include "UTIL/LISTS/list.h" + #include "unitary_defs.h" -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; +#include "PHY/TOOLS/lte_phy_scope.h" + +#include "dummy_functions.c" + +#include "PHY/MODULATION/modulation_common.h" +#include "PHY/MODULATION/modulation_eNB.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "SCHED/sched_eNB.h" +#include "SCHED_UE/sched_UE.h" +#include "common/config/config_load_configmodule.h" +#include "PHY/INIT/phy_init.h" +#include "nfapi/oai_integration/vendor_ext.h" + +#define ENABLE_MBMS_SIM + +int enable_fembms=1; + +void feptx_ofdm(RU_t *ru); +void feptx_prec(RU_t *ru); double cpuf; +#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +//#define MCS_COUNT 23//added for PHY abstraction +#include + +int otg_enabled=0; +/*the following parameters are used to control the processing times calculations*/ +double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */ +double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */ +double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ +double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ +int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ +int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ + +THREAD_STRUCT thread_struct; + +int emulate_rf = 0; + +void handler(int sig) { + void *array[10]; + size_t size; + // get void*'s for all entries on the stack + size = backtrace(array, 10); + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(1); +} + + + +//DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2]; DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2]; +uint64_t DLSCH_alloc_pdu_1[2]; + #define UL_RB_ALLOC 0x1ff; #define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2) +//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 +//#define DLSCH_RB_ALLOC 0x0001 +void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) { + int aa, slot_offset, slot_offset_F; + slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7); + slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); + + for (aa=0; aanb_antennas_tx; aa++) { + // printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc()); + if (frame_parms->Ncp == 1) + PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input + &txdata[aa][slot_offset], // output + frame_parms->ofdm_symbol_size, + 6, // number of symbols + frame_parms->nb_prefix_samples, // number of prefix samples + CYCLIC_PREFIX); + else { + normal_prefix_mod(&txdataF[aa][slot_offset_F], + &txdata[aa][slot_offset], + 7, + frame_parms); + } + } +} + +void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], + double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) { + int i,u; + int aa,aarx,aatx; + double channelx,channely; + double sigma2_dB,sigma2; + double iqim=0.0; + + // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag); + for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + if (awgn_flag == 0) { + s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + } else { + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + if (aa==0) { + r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + } else { + r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + } + } + } + } + } + + // Multipath channel + if (awgn_flag == 0) { + multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, + 2*UE->frame_parms.samples_per_tti,hold_channel); + + // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); + if(abstx==1 && num_rounds>1) + if(round==0 && hold_channel==0) { + random_channel(eNB2UE[1],0); + random_channel(eNB2UE[2],0); + random_channel(eNB2UE[3],0); + } + + if (UE->perfect_ce==1) { + // fill in perfect channel estimates + freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); + /* + LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8); + */ + } + } + + if(abstx) { + if (trials==0 && round==0) { + // calculate freq domain representation to compute SINR + freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + // snr=pow(10.0,.1*SNR); + fprintf(csv_fd,"%f,",SNR); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarxnb_rx; aarx++) { + for (aatx=0; aatxnb_tx; aatx++) { + channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; + channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + if(num_rounds>1) { + freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarxnb_rx; aarx++) { + for (aatx=0; aatxnb_tx; aatx++) { + channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; + channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarxnb_rx; aarx++) { + for (aatx=0; aatxnb_tx; aatx++) { + channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; + channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarxnb_rx; aarx++) { + for (aatx=0; aatxnb_tx; aatx++) { + channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; + channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + } + } + } + + //AWGN + // tx_lev is the average energy over the whole subframe + // but SNR should be better defined wrt the energy in the reference symbols + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR; + sigma2 = pow(10,sigma2_dB/10); + + for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { + for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { + //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = + (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = + (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + } + } +} + +uint16_t +fill_tx_req(nfapi_tx_request_body_t *tx_req_body, + uint16_t absSF, + uint16_t pdu_length, + uint16_t pdu_index, + uint8_t *pdu) { + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", + tx_req_body->number_of_pdus, pdu_length); + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = pdu_index; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req_body->number_of_pdus++; + return (((absSF / 10) << 4) + (absSF % 10)); +} + +void +fill_mch_config(nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint16_t resource_block_coding, + uint8_t modulation, + uint16_t transmission_power, + uint8_t mbsfn_area_id){ + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mch_pdu)); + dl_config_pdu->mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG; + dl_config_pdu->mch_pdu.mch_pdu_rel8.length = length; + dl_config_pdu->mch_pdu.mch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->mch_pdu.mch_pdu_rel8.rnti = rnti; + dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->mch_pdu.mch_pdu_rel8.modulation = modulation; + dl_config_pdu->mch_pdu.mch_pdu_rel8.transmission_power = transmission_power; + dl_config_pdu->mch_pdu.mch_pdu_rel8.mbsfn_area_id = mbsfn_area_id; + dl_req->number_pdu++; +} + +void +fill_dlsch_config(nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector) { + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; + dl_req->number_pdu++; +} + +void fill_MCH(PHY_VARS_eNB *eNB, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], + int n_rnti, + int common_flag, + int NB_RB, + int TPC, + int mcs1){ + + nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; + int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC); + dl_req->number_dci=0; + dl_req->number_pdu=0; + TX_req->number_of_pdus=0; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + fill_mch_config( + dl_req, + get_TBS_DL(mcs1,NB_RB4TBS), + 0, + 0xfffd, + 0, + get_Qm(mcs1), + mcs1, + 6000, //equal to RS power + 0 //mbsfn_area_id + ); + + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB4TBS), + 0, + input_buffer[0]); +} + +void fill_DCI(PHY_VARS_eNB *eNB, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], + int n_rnti, + int n_users, + int transmission_mode, + int retrans, + int common_flag, + int NB_RB, + int DLSCH_RB_ALLOC, + int TPC, + int mcs1, + int mcs2, + int ndi, + int rv, + int pa, + int *num_common_dci, + int *num_ue_spec_dci, + int *num_dci) { + int k; + nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; + int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC); + dl_req->number_dci=0; + dl_req->number_pdu=0; + TX_req->number_of_pdus=0; + + for(k=0; kdl_config_pdu_list[dl_req->number_pdu]; + 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)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = (common_flag == 0) ? NFAPI_DL_DCI_FORMAT_1 : NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = (common_flag == 0) ? n_rnti+k : SI_RNTI; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (common_flag ==0 ) ? 1: 2; // CRNTI : 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 = TPC; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = (common_flag == 0) ? ndi : 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = (common_flag == 0) ? DLSCH_RB_ALLOC : computeRIV(eNB->frame_parms.N_RB_DL,0,NB_RB); + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + AssertFatal(TPC>=0 && TPC<2, "TPC should be 0 or 1\n"); + if(1){ + fill_mch_config( + dl_req, + get_TBS_DL(mcs1,NB_RB4TBS), + 0, + 0xfffd, + 0, + get_Qm(mcs1), + mcs1, + 6000, //equal to RS power + 0 //mbsfn_area_id + ); + + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB4TBS), + 0, + input_buffer[0]); + + }else{ + fill_dlsch_config(dl_req, + get_TBS_DL(mcs1,NB_RB4TBS), + (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ + (common_flag == 0) ? n_rnti : SI_RNTI, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + DLSCH_RB_ALLOC, // resource_block_coding, + get_Qm(mcs1), + rv, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + transmission_mode == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + pa, // pa + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + transmission_mode, + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB4TBS), + 0, + input_buffer[k]); + } + break; + + case 3: + if (common_flag == 0) { + if (eNB->frame_parms.nb_antennas_tx == 2) { + if (eNB->frame_parms.frame_type == TDD) { + } else { + } + } + } + + break; + + case 4: + if (common_flag == 0) { + if (eNB->frame_parms.nb_antennas_tx == 2) { + if (eNB->frame_parms.frame_type == TDD) { + } else { + } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { + } + } else { + } + + break; + + case 5: + case 6: + break; + + default: + printf("Unsupported Transmission Mode %d!!!\n",transmission_mode); + exit(-1); + break; + } + } + + *num_dci = dl_req->number_dci; + *num_ue_spec_dci = dl_req->number_dci; + *num_common_dci = 0; +} + +int n_users = 1; +int subframe=7; +int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; +uint16_t n_rnti=0x1234; + +int abstx=0; +int Nid_cell=0; +int N_RB_DL=25; +int tdd_config=3; +int dci_flag=0; +int threequarter_fs=0; +double snr_step=1,input_snr_step=1, snr_int=30; +double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel +int test_perf=0; +int n_frames; +int n_ch_rlz = 1; +int rx_sample_offset = 0; +int xforms=0; +int dump_table=0; +int loglvl=OAILOG_WARNING; +int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0; +int two_thread_flag=0; +int num_rounds = 4;//,fix_rounds=0; +int perfect_ce = 0; +int extended_prefix_flag=0; +int verbose=0, help=0; +double SNR,snr0=-2.0,snr1,rate = 0; +int print_perf=0; + int main(int argc, char **argv) { - char c; - int i,l,l2,aa,aarx,k; - double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0; - uint8_t snr1set=0; - double snr_step=1,input_snr_step=1; - int **txdata; - double s_re0[2*30720],s_im0[2*30720],s_re1[2*30720],s_im1[2*30720]; - double r_re0[2*30720],r_im0[2*30720],r_re1[2*30720],r_im1[2*30720]; - double *s_re[2]= {s_re0,s_re1},*s_im[2]= {s_im0,s_im1},*r_re[2]= {r_re0,r_re1},*r_im[2]= {r_im0,r_im1}; - double iqim = 0.0; - int subframe=1; - char fname[40];//, vname[40]; - uint8_t transmission_mode = 1,n_tx=1,n_rx=2; - uint16_t Nid_cell=0; - FILE *fd; - int eNB_id = 0; - unsigned char mcs=0,awgn_flag=0,round; - int n_frames=1; - channel_desc_t *eNB2UE; - uint32_t nsymb,tx_lev,tx_lev_dB; - uint8_t extended_prefix_flag=1; + int k,i,j,aa; + int re; + int s,Kr,Kr_bytes; LTE_DL_FRAME_PARMS *frame_parms; + double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2]; + double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2]; + double *s_re[2]= {s_re0,s_re1}; + double *s_im[2]= {s_im0,s_im1}; + double *r_re[2]= {r_re0,r_re1}; + double *r_im[2]= {r_im0,r_im1}; + uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; + int eNB_id = 0; + unsigned char round; + unsigned char i_mod = 2; + int NB_RB; + SCM_t channel_model=Rayleigh1; + // unsigned char *input_data,*decoded_output; + DCI_ALLOC_t da; + DCI_ALLOC_t *dci_alloc = &da; + unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; + unsigned int tx_lev=0,tx_lev_dB=0,trials; + unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers; + memset(errs,0,4*sizeof(unsigned int)); + memset(errs2,0,4*sizeof(unsigned int)); + memset(round_trials,0,4*sizeof(unsigned int)); + memset(dci_errors,0,4*sizeof(unsigned int)); + //int re_allocated; + char fname[32],vname[32]; + FILE *bler_fd; + char bler_fname[256]; + FILE *time_meas_fd; + char time_meas_fname[256]; + // FILE *tikz_fd; + // char tikz_fname[256]; + FILE *input_trch_fd=NULL; + unsigned char input_trch_file=0; + FILE *input_fd=NULL; + unsigned char input_file=0; + channel_desc_t *eNB2UE[4]; + //uint8_t num_pdcch_symbols_2=0; + //char stats_buffer[4096]; + //int len; + //int u; + int n=0; + //int iii; + int ch_realization; + //int pmi_feedback=0; int hold_channel=0; - uint16_t NB_RB=25; - int tdd_config=3; - SCM_t channel_model=MBSFN; - unsigned char *input_buffer; - unsigned short input_buffer_length; - unsigned int ret; - unsigned int trials,errs[4]= {0,0,0,0}; //,round_trials[4]={0,0,0,0}; - uint8_t N_RB_DL=25,osf=1; - uint32_t perfect_ce = 0; - lte_frame_type_t frame_type = FDD; - uint32_t Nsoft = 1827072; - /* - #ifdef XFORMS - FD_lte_phy_scope_ue *form_ue; + // void *data; + // int ii; + // int bler; + double blerr[4]; + short *uncoded_ber_bit=NULL; + int osf=1; + frame_t frame_type = FDD; + FD_lte_phy_scope_ue *form_ue = NULL; char title[255]; + int numCCE=0; + //int dci_length_bytes=0,dci_length=0; + //double channel_bandwidth = 5.0, sampling_rate=7.68; + int common_flag=0,TPC=0; + double cpu_freq_GHz; + // time_stats_t ts;//,sts,usts; + int avg_iter,iter_trials; + int rballocset=0; + int test_passed=0; + double effective_rate=0.0; + char channel_model_input[10]="I"; + int TB0_active = 1; + // LTE_DL_UE_HARQ_t *dlsch0_ue_harq; + // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; + uint8_t Kmimo; + uint8_t ue_category=4; + uint32_t Nsoft; + int sf; + int CCE_table[800]; + opp_enabled=1; // to enable the time meas + FILE *csv_fd=NULL; + char csv_fname[FILENAME_MAX]; + int DLSCH_RB_ALLOC = 0; + int dci_received; + PHY_VARS_eNB *eNB; + RU_t *ru; + PHY_VARS_UE *UE=NULL; + nfapi_dl_config_request_t DL_req; + nfapi_ul_config_request_t UL_req; + nfapi_hi_dci0_request_t HI_DCI0_req; + nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU]; + nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; + nfapi_tx_request_t TX_req; + Sched_Rsp_t sched_resp; + int pa=dB0; +#if defined(__arm__) + FILE *proc_fd = NULL; + char buf[64]; + memset(buf,0,sizeof(buf)); + proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r"); + + if(!proc_fd) + printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq"); + else { + while(fgets(buf, 63, proc_fd)) + printf("%s", buf); + } - fl_initialize (&argc, argv, NULL, 0, 0); - form_ue = create_lte_phy_scope_ue(); - sprintf (title, "LTE DL SCOPE UE"); - fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - #endif - */ - cpuf = get_cpu_freq_GHz(); - logInit(); - number_of_cards = 1; + fclose(proc_fd); + cpu_freq_GHz = ((double)atof(buf))/1e6; +#else + cpu_freq_GHz = get_cpu_freq_GHz(); +#endif + printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + memset((void *)&sched_resp,0,sizeof(sched_resp)); + sched_resp.DL_req = &DL_req; + sched_resp.UL_req = &UL_req; + sched_resp.HI_DCI0_req = &HI_DCI0_req; + sched_resp.TX_req = &TX_req; + memset((void *)&DL_req,0,sizeof(DL_req)); + memset((void *)&UL_req,0,sizeof(UL_req)); + memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void *)&TX_req,0,sizeof(TX_req)); + DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list; + TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; + set_parallel_conf("PARALLEL_SINGLE_THREAD"); + cpuf = cpu_freq_GHz; + //signal(SIGSEGV, handler); + //signal(SIGABRT, handler); + // default parameters + n_frames = 1000; + snr0 = 0; + // num_layers = 1; + perfect_ce = 0; + static paramdef_t options[] = { + { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "Abstx", "Turns on calibration mode for abstraction.", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 }, + { "bTDD", "Set the tdd configuration mode",0, iptr:&tdd_config, defintval:3, TYPE_INT, 0 }, + { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 }, + { "cPdcch", "Number of PDCCH symbols",0, iptr:&num_pdcch_symbols, defintval:1, TYPE_INT, 0 }, + { "CnidCell", "The cell id ",0, iptr:&Nid_cell, defintval:0, TYPE_INT, 0 }, + { "dciFlag", "Transmit the DCI and compute its error statistics", PARAMFLAG_BOOL, iptr:&dci_flag, defintval:0, TYPE_INT, 0 }, + { "Dtdd", "Enable tdd", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "eRounds", "Number of rounds",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 }, + { "f_snr_step", "step size of SNR, default value is 1.",0, dblptr:&input_snr_step, defdblval:1, TYPE_DOUBLE, 0 }, + { "Forgetting", "forgetting factor (0 new channel every trial, 1 channel constant)",0, dblptr:&forgetting_factor, defdblval:0.0, TYPE_DOUBLE, 0 }, + { "input_file", "input IQ data file",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Input_file_trch", " Input filename for TrCH data (binary)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "WtwoThreads", "two_thread_flag", PARAMFLAG_BOOL, iptr:&two_thread_flag, defintval:0, TYPE_INT, 0 }, + { "lMuMimo", "offset_mumimo_llr_drange_fix",0, u8ptr:&offset_mumimo_llr_drange_fix, defintval:0, TYPE_UINT8, 0 }, + { "mcs1", "The MCS for TB 1", 0, iptr:&mcs1, defintval:0, TYPE_INT, 0 }, + { "Mcs2", "The MCS for TB 2", 0, iptr:&mcs2, defintval:0, TYPE_INT, 0 }, + { "Operf", "Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, + { "tmcs_i", "MCS of interfering UE",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 }, + { "offsetRxSample", "Sample offset for receiver", 0, iptr:&rx_sample_offset, defintval:0, TYPE_INT, 0 }, + { "rballocset", "ressource block allocation (see section 7.1.6.3 in 36.213)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "snr", "Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated", dblptr:&snr0, defdblval:-2.0, TYPE_DOUBLE, 0 }, + { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 }, + { "N_ch_rlzN0", "Determines the number of Channel Realizations in Abstraction mode. Default value is 1",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 }, + { "prefix_extended","Enable extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag, defintval:0, TYPE_INT, 0 }, + { "RNumRound", "Number of HARQ rounds (fixed)",0, iptr:&num_rounds, defintval:4, TYPE_INT, 0 }, + { "Subframe", "subframe ",0, iptr:&subframe, defintval:7, TYPE_INT, 0 }, + { "Trnti", "rnti",0, u16ptr:&n_rnti, defuintval:0x1234, TYPE_UINT16, 0 }, + { "vi_mod", "i_mod",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Qparallel", "Enable parallel execution",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, + { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:&print_perf, defintval:0, TYPE_INT, 0 }, + { "q_tx_port", "Number of TX antennas ports used in eNB",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "xTransmission","Transmission mode (1,2,6,7 for the moment)",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "yn_tx_phy","Number of TX antennas used in eNB",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, + { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 }, + { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, + { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_DEBUG, TYPE_INT, 0 }, + { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL, defintval:2, TYPE_INT, 0 }, + { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, + { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "mmse", "Use MMSE whitening", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, + { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + }; + struct option *long_options = parse_oai_options(options); + int option_index; + int res; + + while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) { + if (options[option_index].voidptr != NULL ) { + if (long_options[option_index].has_arg==no_argument) + *(bool *)options[option_index].iptr=1; + else switch (options[option_index].type) { + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; + + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; + + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: + printf("not decoded type.\n"); + exit(1); + } + + continue; + } - while ((c = getopt (argc, argv, "ahA:Cp:n:s:S:t:x:y:z:N:F:R:O:dm:i:Y")) != -1) { - switch (c) { + switch (long_options[option_index].name[0]) { case 'a': - awgn_flag=1; + awgn_flag = 1; + channel_model = AWGN; break; - case 'd': - frame_type = 0; + case 'D': + frame_type=TDD; break; - case 'n': - n_frames = atoi(optarg); + case 'e': + num_rounds=1; + common_flag = 1; + TPC = atoi(optarg); break; - case 'm': - mcs=atoi(optarg); + case 'i': + input_fd = fopen(optarg,"r"); + input_file=1; + dci_flag = 1; break; - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); + case 'I': + input_trch_fd = fopen(optarg,"r"); + input_trch_file=1; break; - case 'i': - input_snr_step = atof(optarg); + case 't': + mcs_i = atoi(optarg); + i_mod = get_Qm(mcs_i); break; - case 'S': - snr1 = atof(optarg); - snr1set=1; - msg("Setting SNR1 to %f\n",snr1); + case 'r': + DLSCH_RB_ALLOC = atoi(optarg); + rballocset = 1; break; - case 'p': // subframe no; - subframe=atoi(optarg); + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'F',EVA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; + + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + break; + } + + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); break; - case 'z': - n_rx=atoi(optarg); + case 'u': + dual_stream_UE=1; - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); + if (UE != NULL) + UE->use_ia_receiver = 1; + else { + printf("UE is NULL\n"); + exit(-1); + } + + if ((n_tx_port!=2) || (transmission_mode!=5)) { + printf("IA receiver only supported for TM5!"); exit(-1); } break; - case 'N': - Nid_cell = atoi(optarg); + case 'v': + i_mod = atoi(optarg); + + if (i_mod!=2 && i_mod!=4 && i_mod!=6) { + printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + exit(-1); + } + break; - case 'R': - N_RB_DL = atoi(optarg); + case 'q': + n_tx_port=atoi(optarg); - if ((N_RB_DL!=6) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=100)) { - printf("Unsupported Bandwidth %d\n",N_RB_DL); + if ((n_tx_port==0) || ((n_tx_port>2))) { + printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port); exit(-1); } break; - case 'O': - osf = atoi(optarg); + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=3) && + (transmission_mode!=4) && + (transmission_mode!=5) && + (transmission_mode!=6) && + (transmission_mode!=7)) { + printf("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + + if (transmission_mode>1 && transmission_mode<7) { + n_tx_port = 2; + } + break; - case 'Y': - perfect_ce = 1; + case 'y': + n_tx_phy=atoi(optarg); + + if (n_tx_phy < n_tx_port) { + printf("n_tx_phy mush not be smaller than n_tx_port"); + exit(-1); + } + + if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) { + printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); + exit(-1); + } + + if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { + printf("Physical number of antennas not supported for TM7.\n"); + exit(-1); + } + + break; + + case 'z': + n_rx=atoi(optarg); + + if ((n_rx==0) || (n_rx>2)) { + printf("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + + break; + + case 'Q': + set_parallel_conf(optarg); break; default: - case 'h': - printf("%s -h(elp) -p(subframe) -N cell_id -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -i snr increment -z RXant \n",argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN Channel\n"); - printf("-p Use extended prefix mode\n"); - printf("-d Use TDD\n"); - printf("-n Number of frames to simulate\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-N Nid_cell\n"); - printf("-R N_RB_DL\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); - printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); - printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); - printf("-f Output filename (.txt format) for Pe/SNR results\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit (-1); + printf("Wrong option: %s\n",long_options[option_index].name); + exit(1); break; } } - if (awgn_flag == 1) - channel_model = AWGN; + if ( res != -1 ) { + printf("A wrong option has been found\n"); + exit(1); + } - // check that subframe is legal for eMBMS + if (help || verbose ) + display_options_values(options, true); - if ((subframe == 0) || (subframe == 5) || // TDD and FDD SFn 0,5; - ((frame_type == FDD) && ((subframe == 4) || (subframe == 9))) || // FDD SFn 4,9; - ((frame_type == TDD ) && ((subframe<3) || (subframe==6)))) { // TDD SFn 1,2,6; - printf("Illegal subframe %d for eMBMS transmission (frame_type %d)\n",subframe,frame_type); - exit(-1); + if (help) + exit(0); + if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD) + set_worker_conf("WORKER_ENABLE"); + + if (transmission_mode>1) pa=dBm3; + + printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); + AssertFatal(load_configmodule(argc,argv, CONFIG_ENABLECMDLINEONLY) != NULL, + "cannot load configuration module, exiting\n"); + logInit(); + set_glog_onlinelog(true); + // enable these lines if you need debug info + set_glog(loglvl); + SET_LOG_DEBUG(UE_TIMING); + // moreover you need to init itti with the following line + // however itti will catch all signals, so ctrl-c won't work anymore + // alternatively you can disable ITTI completely in CMakeLists.txt + //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); + + if (common_flag == 0) { + switch (N_RB_DL) { + case 6: + if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; + + num_pdcch_symbols = 3; + break; + + case 25: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; + + break; + + case 50: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; + + break; + + case 100: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; + + break; + } + + NB_RB = conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); + } else { + if (rballocset==0) NB_RB = 8; + else NB_RB = DLSCH_RB_ALLOC; + + AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB); } - if (transmission_mode==2) - n_tx=2; + if (xforms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + form_ue = create_lte_phy_scope_ue(); + sprintf (title, "LTE PHY SCOPE eNB"); + fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + if (!dual_stream_UE==0) { + if (UE) { + UE->use_ia_receiver = 1; + fl_set_button(form_ue->button_0,1); + fl_set_object_label(form_ue->button_0, "IA Receiver ON"); + fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); + } else { + printf("UE is NULL\n"); + exit(-1); + } + } + } + + if (transmission_mode==5) { + n_users = 2; + printf("dual_stream_UE=%d\n", dual_stream_UE); + } - lte_param_init(n_tx, - n_tx, + RC.nb_L1_inst = 1; + RC.nb_RU = 1; + lte_param_init(&eNB,&UE,&ru, + n_tx_port, + n_tx_phy, + 1, n_rx, transmission_mode, extended_prefix_flag, @@ -224,281 +1068,1251 @@ int main(int argc, char **argv) { Nid_cell, tdd_config, N_RB_DL, - 0, + pa, + threequarter_fs, osf, perfect_ce); + RC.eNB = (PHY_VARS_eNB ** *)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + printf("lte_param_init done\n"); + + if ((transmission_mode==1) || (transmission_mode==7)) { + for (aa=0; aanb_tx; aa++) + for (re=0; reframe_parms.ofdm_symbol_size; re++) + ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; + } + + if (transmission_mode<7) + ru->do_precoding=0; + else + ru->do_precoding=1; - if (snr1set==0) { - if (n_frames==1) - snr1 = snr0+.1; - else - snr1 = snr0+5.0; + eNB->mac_enabled=1; + + +#ifdef ENABLE_MBMS_SIM + //eNB->pbch_configured=1; + eNB_MAC_INST ** mac; + mac = malloc16(1 * sizeof(eNB_MAC_INST *)); + for (int ii = 0;ii < 1; ii++) { + mac[ii] = malloc16(sizeof(eNB_MAC_INST)); + bzero(mac[ii], sizeof(eNB_MAC_INST)); + } + RC.mac = mac; + COMMON_channels_t *cc = &RC.mac[0]->common_channels[0]; + cc->MCH_pdu.mcs = 9; + cc->MCH_pdu.Pdu_size = get_TBS_DL(cc->MCH_pdu.mcs,N_RB_DL); + printf("MCH_pdu.Pdu_size %d\n",cc->MCH_pdu.Pdu_size); + cc->MCH_pdu.sync_area =0; + for(int ii=0; ii < cc->MCH_pdu.Pdu_size; ii++) + cc->MCH_pdu.payload[ii] = (char)(taus() & 0xff); + eNB->frame_parms.Nid_cell_mbsfn=0; +#endif + + + if(get_thread_worker_conf() == WORKER_ENABLE) { + extern void init_td_thread(PHY_VARS_eNB *); + extern void init_te_thread(PHY_VARS_eNB *); + init_td_thread(eNB); + init_te_thread(eNB); } + // callback functions required for phy_procedures_tx + // eNB_id_i = UE->n_connected_eNB; + printf("Setting mcs1 = %d\n",mcs1); + printf("Setting mcs2 = %d\n",mcs2); + printf("NPRB = %d\n",NB_RB); + printf("n_frames = %d\n",n_frames); + printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag); + snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000]; + + for (i=0; iframe_parms; + nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; + printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); + printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n", + SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8); - if (awgn_flag == 0) - sprintf(fname,"embms_%d_%d.m",mcs,N_RB_DL); + if(transmission_mode==5) + sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod); else - sprintf(fname,"embms_awgn_%d_%d.m",mcs,N_RB_DL); + sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1); + + bler_fd = fopen(bler_fname,"w"); - if (!(fd = fopen(fname,"w"))) { - printf("Cannot open %s, check permissions\n",fname); + if (bler_fd==NULL) { + fprintf(stderr,"Cannot create file %s!\n",bler_fname); exit(-1); } - if (awgn_flag==0) - fprintf(fd,"SNR_%d_%d=[];errs_mch_%d_%d=[];mch_trials_%d_%d=[];\n", - mcs,N_RB_DL, - mcs,N_RB_DL, - mcs,N_RB_DL); - else - fprintf(fd,"SNR_awgn_%d_%d=[];errs_mch_awgn_%d_%d=[];mch_trials_awgn_%d_%d=[];\n", - mcs,N_RB_DL, - mcs,N_RB_DL, - mcs,N_RB_DL); - - fflush(fd); - txdata = eNB->common_vars.txdata[0]; - nsymb = 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d, AWGN %d\n",NUMBER_OF_OFDM_CARRIERS, - frame_parms->Ncp,frame_parms->samples_per_tti,nsymb,awgn_flag); - eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, - UE->frame_parms.nb_antennas_rx, - channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), - 0, - 0, - 0); - // Create transport channel structures for 2 transport blocks (MIMO) - eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); - - if (!eNB->dlsch_MCH) { - printf("Can't get eNB dlsch structures\n"); - exit(-1); + fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); + + if (test_perf != 0) { + char hostname[1024]; + hostname[1023] = '\0'; + gethostname(hostname, 1023); + printf("Hostname: %s\n", hostname); + //char dirname[FILENAME_MAX]; + //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname ); + sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv", + N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode); + //mkdir(dirname,0777); + time_meas_fd = fopen(time_meas_fname,"w"); + + if (time_meas_fd==NULL) { + fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); + exit(-1); + } } - UE->dlsch_MCH[0] = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0); - eNB->frame_parms.num_MBSFN_config = 1; - eNB->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0; - eNB->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0; - eNB->frame_parms.MBSFN_config[0].fourFrames_flag = 0; - eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes - UE->frame_parms.num_MBSFN_config = 1; - UE->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0; - UE->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0; - UE->frame_parms.MBSFN_config[0].fourFrames_flag = 0; - UE->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes - fill_eNB_dlsch_MCH(eNB,mcs,1,0); - fill_UE_dlsch_MCH(UE,mcs,1,0,0); - - if (is_pmch_subframe(0,subframe,&eNB->frame_parms)==0) { - printf("eNB is not configured for MBSFN in subframe %d\n",subframe); - exit(-1); - } else if (is_pmch_subframe(0,subframe,&UE->frame_parms)==0) { - printf("UE is not configured for MBSFN in subframe %d\n",subframe); - exit(-1); + if(abstx) { + // CSV file + sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds); + csv_fd = fopen(csv_fname,"w"); + + if (csv_fd==NULL) { + fprintf(stderr,"Cannot create file %s!\n",csv_fname); + exit(-1); + } + + fprintf(csv_fd,"data_all%d=[",mcs1); } - input_buffer_length = eNB->dlsch_MCH->harq_processes[0]->TBS/8; - input_buffer = (unsigned char *)malloc(input_buffer_length+4); - memset(input_buffer,0,input_buffer_length+4); + /* + //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames); + sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames); + tikz_fd = fopen(tikz_fname,"w"); + //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {"); + switch (mcs) + { + case 0: + fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {"); + break; + case 1: + fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {"); + break; + case 2: + fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {"); + break; + case 3: + fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {"); + break; + case 4: + fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {"); + break; + case 5: + fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {"); + break; + case 6: + fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {"); + break; + case 7: + fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {"); + break; + case 8: + fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {"); + break; + case 9: + fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {"); + break; + case 10: + fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {"); + break; + case 11: + fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {"); + break; + case 12: + fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {"); + break; + case 13: + fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {"); + break; + case 14: + fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {"); + break; + case 15: + fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {"); + break; + case 16: + fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {"); + break; + case 17: + fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {"); + break; + case 18: + fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {"); + break; + case 19: + fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {"); + break; + case 20: + fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {"); + break; + case 21: + fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {"); + break; + case 22: + fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {"); + break; + case 23: + fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {"); + break; + case 24: + fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {"); + break; + case 25: + fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {"); + break; + case 26: + fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {"); + break; + case 27: + fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {"); + break; + case 28: + fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {"); + break; + } + */ + UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti; + UE->n_connected_eNB = 1; + printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx); + eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, + UE->frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + forgetting_factor, + rx_sample_offset, + 0); + reset_meas(&eNB2UE[0]->random_channel); + reset_meas(&eNB2UE[0]->interp_time); + + if(num_rounds>1) { + for(n=1; n<4; n++) { + eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, + UE->frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + forgetting_factor, + rx_sample_offset, + 0); + reset_meas(&eNB2UE[n]->random_channel); + reset_meas(&eNB2UE[n]->interp_time); + } + } - for (i=0; iproc.proc_rxtx[0].frame_tx=0; - eNB->proc.proc_rxtx[0].frame_tx=0; - eNB->proc.proc_rxtx[0].subframe_tx=subframe; - errs[0]=0; - errs[1]=0; - errs[2]=0; - errs[3]=0; - /* - round_trials[0] = 0; - round_trials[1] = 0; - round_trials[2] = 0; - round_trials[3] = 0;*/ - printf("********************** SNR %f (step %f)\n",SNR,snr_step); - - for (trials = 0; trialsfirst_run = 1; - eNB2UE->first_run = 1; - memset(&eNB->common_vars.txdataF[0][0][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); - generate_mch(eNB,&eNB->proc.proc_rxtx[0],input_buffer); - PHY_ofdm_mod(eNB->common_vars.txdataF[0][0], // input, - txdata[0], // output - frame_parms->ofdm_symbol_size, - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb, // number of symbols - frame_parms->nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); + switch (ue_category) { + case 1: + Nsoft = 250368; + break; - if (n_frames==1) { - LOG_M("txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); - //if (eNB->frame_parms.nb_antennas_tx>1) - //LOG_M("txsigF1.m","txsF1", &eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); - } + case 2: + case 3: + Nsoft = 1237248; + break; - tx_lev = 0; + case 4: + Nsoft = 1827072; + break; - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa] - [subframe*eNB->frame_parms.samples_per_tti], - eNB->frame_parms.samples_per_tti); - } + default: + printf("Unsupported UE category %d\n",ue_category); + exit(-1); + break; + } - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + for (k=0; kdlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); - if (n_frames==1) { - printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - // LOG_M("txsig0.m","txs0", &eNB->common_vars.txdata[0][0][subframe* eNB->frame_parms.samples_per_tti], - // eNB->frame_parms.samples_per_tti,1,1); + if (!eNB->dlsch[k][i]) { + printf("Can't get eNB dlsch structures\n"); + exit(-1); } - for (i=0; i<2*frame_parms->samples_per_tti; i++) { - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); - s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); - } + eNB->dlsch[k][i]->rnti = n_rnti+k; + } + } + +#ifdef ENABLE_MBMS_SIM + eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL, 0, &eNB->frame_parms); +#endif + + + /* allocate memory for both subframes (only one is really used + * but there is now "copy_harq_proc_struct" which needs both + * to be valid) + * TODO: refine this somehow (necessary?) + */ + for (sf = 0; sf < 2; sf++) { + for (i=0; i<2; i++) { + UE->dlsch[sf][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + + if (!UE->dlsch[sf][0][i]) { + printf("Can't get ue dlsch structures\n"); + exit(-1); } - //Multipath channel - multipath_channel(eNB2UE,s_re,s_im,r_re,r_im, - 2*frame_parms->samples_per_tti,hold_channel); - //AWGN - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(NB_RB*12)) - SNR; - sigma2 = pow(10,sigma2_dB/10); - - if (n_frames==1) - printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB); - - for (i=0; i<2*frame_parms->samples_per_tti; i++) { - for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { - //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = - (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = - (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - } + UE->dlsch[sf][0][i]->rnti = n_rnti; + } + } + +#ifdef ENABLE_MBMS_SIM + UE->dlsch_MCH[0] = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0); + UE->dlsch_MCH[0]->active = 1; + UE->dlsch_MCH[0]->harq_processes[0]->mcs = mcs1; +#endif + + UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); + // structure for SIC at UE + UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); + + if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { + eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); + + if (n_users>1) + eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI + } else { + eNB->UE_stats[0].DL_pmi_single = 0; + + if (n_users>1) + eNB->UE_stats[1].DL_pmi_single = 0; + } + + L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc; + + if (input_fd==NULL) { + DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols; + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + // UE specific DCI + fill_DCI(eNB, + proc_eNB->frame_tx,subframe, + &sched_resp, + input_buffer, + n_rnti, + n_users, + transmission_mode, + 0, + common_flag, + NB_RB, + DLSCH_RB_ALLOC, + TPC, + mcs1, + mcs2, + 1, + 0, + pa, + &num_common_dci, + &num_ue_spec_dci, + &num_dci); + numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe)); + + if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d, num_dci %d/%d/%d\n",num_pdcch_symbols,numCCE, num_dci,num_ue_spec_dci,num_common_dci); + } + + eNB->frame_parms.Nid_cell_mbsfn=0; + if(enable_fembms){ + lte_gold_mbsfn_khz_1dot25 (&eNB->frame_parms, eNB->lte_gold_mbsfn_khz_1dot25_table, eNB->frame_parms.Nid_cell_mbsfn); + eNB->frame_parms.NonMBSFN_config_flag=1; + }else{ + lte_gold_mbsfn (&eNB->frame_parms, eNB->lte_gold_mbsfn_table, eNB->frame_parms.Nid_cell_mbsfn); + eNB->frame_parms.num_MBSFN_config=1; + eNB->frame_parms.MBSFN_config[0].radioframeAllocationPeriod=0; + eNB->frame_parms.MBSFN_config[0].fourFrames_flag=0; + eNB->frame_parms.MBSFN_config[0].radioframeAllocationOffset=0; + //eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xC0; + eNB->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xFC; + } + + + + snr_step = input_snr_step; + UE->high_speed_flag = 1; + UE->ch_est_alpha=0; + + for (ch_realization=0; ch_realizationproc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0; + errs[0]=0; + errs[1]=0; + errs[2]=0; + errs[3]=0; + errs2[0]=0; + errs2[1]=0; + errs2[2]=0; + errs2[3]=0; + round_trials[0] = 0; + round_trials[1] = 0; + round_trials[2] = 0; + round_trials[3] = 0; + dci_errors[0]=0; + dci_errors[1]=0; + dci_errors[2]=0; + dci_errors[3]=0; + // avg_ber = 0; + round=0; + avg_iter = 0; + iter_trials=0; + reset_meas(&eNB->phy_proc_tx); // total eNB tx + reset_meas(&eNB->dlsch_scrambling_stats); + reset_meas(&UE->dlsch_unscrambling_stats); + reset_meas(&eNB->ofdm_mod_stats); + reset_meas(&eNB->dlsch_modulation_stats); + reset_meas(&eNB->dlsch_encoding_stats); + reset_meas(&eNB->dlsch_interleaving_stats); + reset_meas(&eNB->dlsch_rate_matching_stats); + reset_meas(&eNB->dlsch_turbo_encoding_stats); + reset_meas(&eNB->dlsch_common_and_dci); + reset_meas(&eNB->dlsch_ue_specific); + + for (int i=0; iphy_proc_rx[i]); // total UE rx + reset_meas(&UE->ue_front_end_stat[i]); + reset_meas(&UE->pdsch_procedures_stat[i]); + reset_meas(&UE->dlsch_procedures_stat[i]); + reset_meas(&UE->dlsch_decoding_stats[i]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]); } - for (l=2; l<12; l++) { - slot_fep_mbsfn(UE, - l, - subframe%10, - 0, - 0); - - if (UE->perfect_ce==1) { - // fill in perfect channel estimates - freq_channel(eNB2UE,UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); - - for(k=0; knb_antennas_tx; aa++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { - for (i=0; iN_RB_DL*12; i++) { - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+ - (aa*frame_parms->nb_antennas_rx)][i].x*AMP); - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+ - (aa*frame_parms->nb_antennas_rx)][i].y*AMP); - } + reset_meas(&UE->ofdm_demod_stats); + reset_meas(&UE->crnti_procedures_stats); + reset_meas(&UE->dlsch_channel_estimation_stats); + reset_meas(&UE->dlsch_freq_offset_estimation_stats); + reset_meas(&UE->rx_dft_stats); + reset_meas(&UE->dlsch_decoding_stats[0]); + reset_meas(&UE->dlsch_decoding_stats[1]); + reset_meas(&UE->dlsch_turbo_decoding_stats); + reset_meas(&UE->dlsch_deinterleaving_stats); + reset_meas(&UE->dlsch_rate_unmatching_stats); + reset_meas(&UE->dlsch_tc_init_stats); + reset_meas(&UE->dlsch_tc_alpha_stats); + reset_meas(&UE->dlsch_tc_beta_stats); + reset_meas(&UE->dlsch_tc_gamma_stats); + reset_meas(&UE->dlsch_tc_ext_stats); + reset_meas(&UE->dlsch_tc_intl1_stats); + reset_meas(&UE->dlsch_tc_intl2_stats); + // initialization + // initialization + varArray_t *table_tx=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_mod=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_enc=initVarArray(1000,sizeof(double)); + varArray_t *table_rx=initVarArray(1000,sizeof(double)); + time_stats_t phy_proc_rx_tot; + time_stats_t pdsch_procedures_tot; + time_stats_t dlsch_procedures_tot; + time_stats_t dlsch_decoding_tot; + time_stats_t dlsch_llr_tot; + time_stats_t ue_front_end_tot; + varArray_t *table_rx_fft=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_demod=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_dec=initVarArray(1000,sizeof(double)); + + for (trials = 0; trialsfirst_run = 1; + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0; + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0; + + while ((round < num_rounds) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 0)) { + // printf("Trial %d, round %d\n",trials,round); + round_trials[round]++; + + //if(transmission_mode>=5) + // pmi_feedback=1; + //else + // pmi_feedback=0; + + if (abstx) { + if (trials==0 && round==0 && SNR==snr0) //generate a new channel + hold_channel = 0; + else + hold_channel = 1; + } else + hold_channel = 0;//(round==0) ? 0 : 1; + + //PMI_FEEDBACK: + + // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + } + + if (input_fd==NULL) { + // Simulate HARQ procedures!!! + memset(CCE_table,0,800*sizeof(int)); + + if (/*common_flag == 0*/ 1) { + num_dci=0; + num_common_dci=0; + num_ue_spec_dci=0; + + if (round == 0) { // First round + TB0_active = 1; + eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); + } else { + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); + } + } + +//#ifdef ENABLE_MBMS_SIM +// eNB->frame_parms.Nid_cell_mbsfn=0; +// lte_gold_mbsfn (&eNB->frame_parms, eNB->lte_gold_mbsfn_table, eNB->frame_parms.Nid_cell_mbsfn); +//#endif + + UE->measurements.n0_power_tot_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR; + UE->measurements.n0_power_tot = pow(10,( 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR)/10); + + proc_eNB->subframe_tx = subframe; + sched_resp.subframe=subframe; + sched_resp.frame=proc_eNB->frame_tx; + eNB->abstraction_flag=0; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,1); + + if (uncoded_ber_bit == NULL) { + // this is for user 0 only + printf("nb_rb %d, rb_alloc %x, mcs %d\n", + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0], + eNB->dlsch[0][0]->harq_processes[0]->mcs); + coded_bits_per_codeword = get_G(&eNB->frame_parms, + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), + eNB->dlsch[0][0]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe, + transmission_mode>=7?transmission_mode:0); + uncoded_ber_bit = (short *) malloc(sizeof(short)*coded_bits_per_codeword); + printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); + } + + + + start_meas(&eNB->ofdm_mod_stats); + ru->proc.subframe_tx=subframe; + LOG_W(PHY,"eNB %d\n",eNB->frame_parms.num_MBSFN_config); + LOG_W(PHY,"eNB %d\n",eNB->frame_parms.NonMBSFN_config_flag); + memcpy((void *)&ru->frame_parms,(void *)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + LOG_W(PHY,"RU %d\n",ru->frame_parms.num_MBSFN_config); + LOG_W(PHY,"RU %d\n",ru->frame_parms.NonMBSFN_config_flag); + feptx_prec(ru); + feptx_ofdm(ru); + stop_meas(&eNB->ofdm_mod_stats); + // generate next subframe for channel estimation + DL_req.dl_config_request_body.number_dci=0; + DL_req.dl_config_request_body.number_pdu=0; + TX_req.tx_request_body.number_of_pdus=0; + proc_eNB->subframe_tx = subframe+1; + sched_resp.subframe=subframe+1; + schedule_response(&sched_resp); + + phy_procedures_eNB_TX(eNB,proc_eNB,0); + ru->proc.subframe_tx=(subframe+1)%10; + feptx_prec(ru); + feptx_ofdm(ru); + proc_eNB->frame_tx++; + tx_lev = 0; + + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + tx_lev += signal_energy(&ru->common.txdata[aa] + [subframe*eNB->frame_parms.samples_per_tti], + eNB->frame_parms.samples_per_tti); + } + + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + + if (n_frames==1) { + printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB); + LOG_M("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); + + if (transmission_mode<7) { + LOG_M("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + } else if (transmission_mode == 7) { + LOG_M("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + LOG_M("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1); } } } + + DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]]; + proc->subframe_rx = subframe; + UE->UE_mode[0] = PUSCH; + // first symbol has to be done separately in one-shot mode + slot_fep(UE, + 0, + (proc->subframe_rx<<1), + UE->rx_offset, + 0, + 0); + + if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); + + if (dci_flag==0) { + memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t)); + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; + + if (n_frames==1) + printf("bypassing PDCCH/DCI detection\n"); + + if (generate_ue_dlsch_params_from_dci(proc->frame_rx, + proc->subframe_rx, + (void *)&dci_alloc[0].dci_pdu, + common_flag == 0 ? n_rnti : SI_RNTI, + dci_alloc[0].format, + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], + UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], + UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], + &UE->frame_parms, + UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + UE->transmission_mode[eNB_id]<7?0:UE->transmission_mode[eNB_id], + 0)==0) { + dump_dci(&UE->frame_parms, &dci_alloc[0]); + //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1; + //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1; + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; + UE->dlsch_received[eNB_id]++; + } else { + LOG_E(PHY,"Problem in DCI!\n"); + } + } + + + UE->frame_parms.Nid_cell_mbsfn=0; + if(enable_fembms){ + lte_gold_mbsfn_khz_1dot25 (&UE->frame_parms, UE->lte_gold_mbsfn_khz_1dot25_table, UE->frame_parms.Nid_cell_mbsfn); + UE->frame_parms.NonMBSFN_config_flag=1; + }else{ + lte_gold_mbsfn (&UE->frame_parms, UE->lte_gold_mbsfn_table, UE->frame_parms.Nid_cell_mbsfn); + UE->frame_parms.num_MBSFN_config=1; + UE->frame_parms.MBSFN_config[0].radioframeAllocationPeriod=0; + UE->frame_parms.MBSFN_config[0].fourFrames_flag=0; + UE->frame_parms.MBSFN_config[0].radioframeAllocationOffset=0; + UE->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xC0; + } + + + + + dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; + phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx); + dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; + + if (dci_flag && (dci_received == 0)) { + printf("DCI not received\n"); + dci_errors[round]++; + LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); + LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + exit(-1); + } + + int bit_errors=0; + + if ((test_perf ==0 ) && (n_frames==1)) { + dlsch_unscrambling(&eNB->frame_parms, + 0, + UE->dlsch[UE->current_thread_id[subframe]][0][0], + coded_bits_per_codeword, + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], + 0, + subframe<<1); + + for (i=0; idlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| + (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { + uncoded_ber_bit[bit_errors++] = 1; + printf("error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + } else { + /* + printf("no error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + */ + } + + LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); + LOG_M("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + + if (eNB->frame_parms.nb_antennas_tx>1) + LOG_M("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8); + + //common vars + LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); + LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (UE->frame_parms.nb_antennas_rx>1) { + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1); + LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + } + + LOG_M("dlsch00_r0.m","dl00_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (UE->frame_parms.nb_antennas_rx>1) + LOG_M("dlsch01_r0.m","dl01_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (eNB->frame_parms.nb_antennas_tx>1) + LOG_M("dlsch10_r0.m","dl10_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) + LOG_M("dlsch11_r0.m","dl11_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + + //pdsch_vars + printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); + LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + //pdcch_vars + LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + } + + if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) { + avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt; + iter_trials++; + + if (n_frames==1) + printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); + + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS; + TB0_active = 0; + } // DLSCH received ok + else { + errs[round]++; + avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1; + iter_trials++; + + if (n_frames==1) { + //if ((n_frames==1) || (SNR>=30)) { + printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); + + for (s=0; sdlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus; + else + Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + printf("Decoded_output (Segment %d):\n",s); + + for (i=0; idlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i], + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + } + + sprintf(fname,"rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + LOG_M(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsigF0_r%d.m",round); + sprintf(vname,"rxs0F_r%d",round); + LOG_M(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (UE->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d.m",round); + LOG_M(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsigF1_r%d.m",round); + sprintf(vname,"rxs1F_r%d.m",round); + LOG_M(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + } + + sprintf(fname,"dlsch00_r%d.m",round); + sprintf(vname,"dl00_r%d",round); + LOG_M(fname,vname, + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (UE->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"dlsch01_r%d.m",round); + sprintf(vname,"dl01_r%d",round); + LOG_M(fname,vname, + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + } + + if (eNB->frame_parms.nb_antennas_tx>1) { + sprintf(fname,"dlsch10_r%d.m",round); + sprintf(vname,"dl10_r%d",round); + LOG_M(fname,vname, + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + } + + if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) { + sprintf(fname,"dlsch11_r%d.m",round); + sprintf(vname,"dl11_r%d",round); + LOG_M(fname,vname, + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + } + + //pdsch_vars + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); + //LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + //LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); + //LOG_M("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); + //LOG_M("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + //pdcch_vars + LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + + if (round == 3) exit(-1); + } + + // printf("round %d errors %d/%d\n",round,errs[round],trials); + round++; + // UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++; + } + + if (xforms==1) { + phy_scope_UE(form_ue, + UE, + eNB_id, + 0,// UE_id + subframe); + } + + UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++; + } //round + + // printf("\n"); + + if ((errs[0]>=n_frames/10) && (trials>(n_frames/2))) + break; + + //len = chbch_stats_read(stats_buffer,NULL,0,4096); + //printf("%s\n\n",stats_buffer); + + if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) { + UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10; + LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id], + UE->bitrate[eNB_id]/1000); + UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id]; } - if (l==6) - for (l2=2; l2<7; l2++) - rx_pmch(UE, - 0, - subframe%10, - l2); + /* calculate the total processing time for each packet, + * get the max, min, and number of packets that exceed t>2000us + */ + double t_tx = inMicroS(eNB->phy_proc_tx.p_time); + double t_tx_ifft = inMicroS(eNB->ofdm_mod_stats.p_time); + double t_rx = inMicroS(UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time); + sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]); + sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]); + sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]); + sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]); + double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time); + double t_rx_demod = inMicroS(UE->dlsch_rx_pdcch_stats.p_time); + double t_rx_dec = inMicroS(UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time); + + if (t_tx > 2000 )// 2ms is too much time for a subframe + n_tx_dropped++; + + if (t_rx > 2000 ) + n_rx_dropped++; + + appendVarArray(table_tx, &t_tx); + appendVarArray(table_tx_ifft, &t_tx_ifft); + appendVarArray(table_rx, &t_rx ); + appendVarArray(table_rx_fft, &t_rx_fft ); + appendVarArray(table_rx_demod, &t_rx_demod ); + appendVarArray(table_rx_dec, &t_rx_dec ); + } //trials + + // round_trials[0]: number of code word : goodput the protocol + // sort table + qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble); + qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble); + qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble); + qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble); + qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble); + qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble); + qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble); + qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble); + + if (dump_table == 1 ) { + set_component_filelog(SIM); // file located in /tmp/usim.txt + LOG_UDUMPMSG(SIM,table_tx,table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,table_rx,table_rx->size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n"); + } - if (l==6) - for (l2=2; l2<7; l2++) - rx_pmch(UE, - 0, - subframe%10, - l2); + effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); + printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n", + SNR, + (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12))); + printf("Errors (%u(%u)/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e), dci_errors %u/%u, Pe = %e => effective rate %f, normalized delay %f (%f)\n", + errs[0], + errs2[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + (double)errs[0]/(round_trials[0]), + (double)errs[1]/(round_trials[1]), + (double)errs[2]/(round_trials[2]), + (double)errs[3]/(round_trials[3]), + dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3], + round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3], + (double)(dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3])/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]), + //rate*effective_rate, + 100*effective_rate, + //rate, + //rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs), + (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ + (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + double timeBase=1/(1000*cpu_freq_GHz); + + if (print_perf==1) { + printf("\neNB TX function statistics (per 1ms subframe)\n"); + printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx"); + printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time"); + printStatIndent(&eNB->dlsch_ue_specific,"DL per ue part time"); + printStatIndent2(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); + printStatIndent3(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time"); + printStatIndent3(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time"); + printStatIndent3(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time"); + printStatIndent2(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); + printStatIndent2(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); + printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time"); + printf("\nUE RX function statistics (per 1ms subframe)\n"); + printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); + printStatIndent(&ue_front_end_tot,"Front end processing"); + printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); + printStatIndent2(&pdsch_procedures_tot,"pdsch processing"); + printStatIndent2(&dlsch_procedures_tot,"dlsch processing"); + printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing"); + printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); + printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); + printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); + printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time "); + printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); + printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching"); + printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, + UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials, + (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, + (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), + UE->dlsch_turbo_decoding_stats.trials); + printStatIndent2(&UE->dlsch_tc_init_stats,"init"); + printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha"); + printStatIndent2(&UE->dlsch_tc_beta_stats,"beta"); + printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma"); + printStatIndent2(&UE->dlsch_tc_ext_stats,"ext"); + printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver"); + printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC"); + } - if (l==11) - for (l2=7; l2<12; l2++) - rx_pmch(UE, - 0, - subframe%10, - l2); + if ((transmission_mode != 3) && (transmission_mode != 4)) { + fprintf(bler_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n", + SNR, + mcs1, + eNB->dlsch[0][0]->harq_processes[0]->TBS, + rate, + errs[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + dci_errors[0]); + } else { + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n", + SNR, + mcs1,mcs2, + eNB->dlsch[0][0]->harq_processes[0]->TBS, + eNB->dlsch[0][1]->harq_processes[0]->TBS, + rate, + errs[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + dci_errors[0]); } - UE->dlsch_MCH[0]->harq_processes[0]->G = get_G(&UE->frame_parms, - UE->dlsch_MCH[0]->harq_processes[0]->nb_rb, - UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, - get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs), - 1,2, - UE->proc.proc_rxtx[0].frame_tx,subframe,0); - UE->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs); - dlsch_unscrambling(&UE->frame_parms,1,UE->dlsch_MCH[0], - UE->dlsch_MCH[0]->harq_processes[0]->G, - UE->pdsch_vars_MCH[0]->llr[0],0,subframe<<1); - ret = dlsch_decoding(UE, - UE->pdsch_vars_MCH[0]->llr[0], - &UE->frame_parms, - UE->dlsch_MCH[0], - UE->dlsch_MCH[0]->harq_processes[0], - trials, - subframe, - 0,0,0); - - if (n_frames==1) - printf("MCH decoding returns %u\n",ret); - - if (ret == (1+UE->dlsch_MCH[0]->max_turbo_iterations)) - errs[0]++; - - UE->proc.proc_rxtx[0].frame_tx++; - eNB->proc.proc_rxtx[0].frame_tx++; - } + if(abstx) { //ABSTRACTION + blerr[0] = (double)errs[0]/(round_trials[0]); + + if(num_rounds>1) { + blerr[1] = (double)errs[1]/(round_trials[1]); + blerr[2] = (double)errs[2]/(round_trials[2]); + blerr[3] = (double)errs[3]/(round_trials[3]); + fprintf(csv_fd,"%e,%e,%e,%e;\n",blerr[0],blerr[1],blerr[2],blerr[3]); + } else { + fprintf(csv_fd,"%e;\n",blerr[0]); + } + } //ABStraction + + if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); + if ((transmission_mode != 3) && (transmission_mode != 4)) { + fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;", + SNR, + mcs1, + eNB->dlsch[0][0]->harq_processes[0]->TBS, + rate, + errs[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + dci_errors[0]); + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); + fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;", + SNR, + mcs1, + eNB->dlsch[0][0]->harq_processes[0]->TBS, + rate*effective_rate, + 100*effective_rate, + rate, + (double)avg_iter/iter_trials, + errs[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + (double)errs[0]/(round_trials[0]), + (double)errs[1]/(round_trials[0]), + (double)errs[2]/(round_trials[0]), + (double)errs[3]/(round_trials[0]), + dci_errors[0], + round_trials[0], + (double)dci_errors[0]/(round_trials[0]), + (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ + (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + } else { + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;", + SNR, + mcs1,mcs2, + eNB->dlsch[0][0]->harq_processes[0]->TBS, + eNB->dlsch[0][1]->harq_processes[0]->TBS, + rate, + errs[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + dci_errors[0]); + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;", + SNR, + mcs1,mcs2, + eNB->dlsch[0][0]->harq_processes[0]->TBS, + eNB->dlsch[0][1]->harq_processes[0]->TBS, + rate*effective_rate, + 100*effective_rate, + rate, + (double)avg_iter/iter_trials, + errs[0], + round_trials[0], + errs[1], + round_trials[1], + errs[2], + round_trials[2], + errs[3], + round_trials[3], + (double)errs[0]/(round_trials[0]), + (double)errs[1]/(round_trials[0]), + (double)errs[2]/(round_trials[0]), + (double)errs[3]/(round_trials[0]), + dci_errors[0], + round_trials[0], + (double)dci_errors[0]/(round_trials[0]), + (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ + (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + } - printf("errors %u/%u (Pe %e)\n",errs[round],trials,(double)errs[round]/trials); + //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", + fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", + eNB->phy_proc_tx.trials, + eNB->ofdm_mod_stats.trials, + eNB->dlsch_modulation_stats.trials, + eNB->dlsch_scrambling_stats.trials, + eNB->dlsch_encoding_stats.trials, + phy_proc_rx_tot.trials, + UE->ofdm_demod_stats.trials, + UE->dlsch_rx_pdcch_stats.trials, + UE->dlsch_llr_stats.trials, + UE->dlsch_unscrambling_stats.trials, + UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials + ); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;", + get_time_meas_us(&eNB->phy_proc_tx), + get_time_meas_us(&eNB->ofdm_mod_stats), + get_time_meas_us(&eNB->dlsch_modulation_stats), + get_time_meas_us(&eNB->dlsch_scrambling_stats), + get_time_meas_us(&eNB->dlsch_encoding_stats), + get_time_meas_us(&phy_proc_rx_tot), + nsymb*get_time_meas_us(&UE->ofdm_demod_stats), + get_time_meas_us(&UE->dlsch_rx_pdcch_stats), + 3*get_time_meas_us(&UE->dlsch_llr_stats), + get_time_meas_us(&UE->dlsch_unscrambling_stats), + get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]) + ); + //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); + //fprintf(time_meas_fd,"IFFT;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->ofdm_mod_stats), + median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft)); + //fprintf(time_meas_fd,"MOD;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->dlsch_modulation_stats), + median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod)); + //fprintf(time_meas_fd,"ENC;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->dlsch_encoding_stats), + median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc)); + //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min, + median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped); + //fprintf(time_meas_fd,"FFT;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->ofdm_demod_stats), + median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft)); + //fprintf(time_meas_fd,"DEMOD;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->dlsch_demodulation_stats), + median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod)); + //fprintf(time_meas_fd,"DEC;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f\n", + squareRoot(&UE->dlsch_decoding_stats[subframe]), + median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); + printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); + test_passed = 1; + break; + } else if (test_perf !=0 ) { + printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); + test_passed = 0; + } - if (awgn_flag==0) - fprintf(fd,"SNR_%d_%d = [SNR_%d_%d %f]; errs_mch_%d_%d =[errs_mch_%d_%d %u]; mch_trials_%d_%d =[mch_trials_%d_%d %u];\n", - mcs,N_RB_DL,mcs,N_RB_DL,SNR, - mcs,N_RB_DL,mcs,N_RB_DL,errs[0], - mcs,N_RB_DL,mcs,N_RB_DL,trials); - else - fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %f]; errs_mch_awgn_%d =[errs_mch_awgn_%d %u]; mch_trials_awgn_%d =[mch_trials_awgn_%d %u];\n", - N_RB_DL,N_RB_DL,SNR, - N_RB_DL,N_RB_DL,errs[0], - N_RB_DL,N_RB_DL,trials); + if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames)) + break; + }// SNR + } //ch_realization - fflush(fd); + fclose(bler_fd); - if (errs[0] == 0) - break; - } + if (test_perf !=0) + fclose (time_meas_fd); - if (n_frames==1) { - printf("Dumping PMCH files ( G %d)\n",UE->dlsch_MCH[0]->harq_processes[0]->G); - dump_mch(UE,0, - UE->dlsch_MCH[0]->harq_processes[0]->G, - subframe); + //fprintf(tikz_fd,"};\n"); + //fclose(tikz_fd); + + if (input_trch_file==1) + fclose(input_trch_fd); + + if (input_file==1) + fclose(input_fd); + + if(abstx) { // ABSTRACTION + fprintf(csv_fd,"];"); + fclose(csv_fd); } + if (uncoded_ber_bit) + free(uncoded_ber_bit); + + uncoded_ber_bit = NULL; printf("Freeing dlsch structures\n"); - free_eNB_dlsch(eNB->dlsch_MCH); - free_ue_dlsch(UE->dlsch_MCH[0]); - fclose(fd); - return(0); -} + for (i=0; i<2; i++) { + printf("eNB %d\n",i); + free_eNB_dlsch(eNB->dlsch[0][i]); + printf("UE %d\n",i); + free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]); + } + + if (test_perf && !test_passed) + return(-1); + else + return(0); +} +/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +uint64_t get_softmodem_optmask(void) { + return 0; +} -- GitLab From f1d51cc0be02f9e2f8a8d2520ba9f510333bf560 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 18:08:41 +0200 Subject: [PATCH 14/34] fembms: handle L2 eNB config in softmodem Signed-off-by: Javier Morgade --- openair2/COMMON/m2ap_messages_def.h | 1 + openair2/COMMON/m2ap_messages_types.h | 11 ++++++++++- openair2/ENB_APP/enb_app.c | 25 ++++++++++--------------- openair2/ENB_APP/enb_config.c | 3 ++- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/openair2/COMMON/m2ap_messages_def.h b/openair2/COMMON/m2ap_messages_def.h index adad70c9cc..743ca126fb 100644 --- a/openair2/COMMON/m2ap_messages_def.h +++ b/openair2/COMMON/m2ap_messages_def.h @@ -50,6 +50,7 @@ MESSAGE_DEF(M2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, m2ap_der /* M2AP -> SCTP */ MESSAGE_DEF(M2AP_MCE_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_mce_sctp_req_t , m2ap_mce_sctp_req) +MESSAGE_DEF(M2AP_ENB_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_enb_sctp_req_t , m2ap_enb_sctp_req) //MESSAGE_DEF(M2AP_ENB_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_enb_setup_req_t , f1ap_enb_setup_req) /* eNB_DU application layer -> M2AP messages or CU M2AP -> RRC*/ diff --git a/openair2/COMMON/m2ap_messages_types.h b/openair2/COMMON/m2ap_messages_types.h index 501414f296..c70c50fc64 100644 --- a/openair2/COMMON/m2ap_messages_types.h +++ b/openair2/COMMON/m2ap_messages_types.h @@ -480,7 +480,7 @@ typedef struct m2ap_mbms_scheduling_information_s { uint8_t common_sf_allocation_period; uint8_t mbms_area_id; struct{ - uint8_t allocated_sf_end; + uint16_t allocated_sf_end; uint8_t data_mcs; uint8_t mch_scheduling_period; struct{ @@ -533,6 +533,15 @@ typedef struct m2ap_mce_sctp_req_s { uint32_t mce_port_for_M2C; }m2ap_mce_sctp_req_t; +typedef struct m2ap_enb_sctp_req_s { + /* The local MCE IP address to bind */ + net_ip_address_t enb_m2_ip_address; + + /* eNB port for M2C*/ + uint32_t enb_port_for_M2C; +}m2ap_enb_sctp_req_t; + + typedef struct m2ap_mbms_scheduling_information_resp_s { } m2ap_mbms_scheduling_information_resp_t; typedef struct m2ap_session_start_req_s { diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 0e1c7e64bc..4b592f27cf 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -214,7 +214,7 @@ void *eNB_app_task(void *args_p) { long x2_enb_register_retry_timer_id; uint32_t m2_register_enb_pending = 0; uint32_t m2_registered_enb = 0; - long m2_enb_register_retry_timer_id; + //long m2_enb_register_retry_timer_id; MessageDef *msg_p = NULL; instance_t instance; int result; @@ -236,16 +236,11 @@ void *eNB_app_task(void *args_p) { /* Try to register each eNB with MCE each other */ if (is_m2ap_eNB_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) { //eNB_app_register_MBMS_STA(RC.rrc[0]->node_type, enb_id_start, enb_id_end); - //m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end); + m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end); - if (timer_setup (5, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, - NULL, &m2_enb_register_retry_timer_id) < 0) { - //LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); - //sleep(ENB_REGISTER_RETRY_DELAY); - /* Restart the registration process */ - //registered_enb = 0; - //register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end); - } + //if (timer_setup (5, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + // NULL, &m2_enb_register_retry_timer_id) < 0) { + //} } @@ -377,11 +372,11 @@ void *eNB_app_task(void *args_p) { } } /* if (EPC_MODE_ENABLED) */ - if(TIMER_HAS_EXPIRED (msg_p).timer_id == m2_enb_register_retry_timer_id) { - - LOG_I(ENB_APP, " Received %s: timer_id %ld M2 register\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); - m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end); - } +// if(TIMER_HAS_EXPIRED (msg_p).timer_id == m2_enb_register_retry_timer_id) { +// +// LOG_I(ENB_APP, " Received %s: timer_id %ld M2 register\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); +// m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end); +// } break; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 6dcc574746..df8238bf25 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -3041,7 +3041,8 @@ void configure_du_mac(int inst) { (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } -- GitLab From 1f034ab40453d562f1e0abcde441bfb72d1f5d9d Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 18:10:25 +0200 Subject: [PATCH 15/34] fembms: prototype overload (legacy code for F1AP) Signed-off-by: Javier Morgade --- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index fb9450728b..6953588818 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -306,7 +306,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); break; } // case @@ -480,7 +481,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } -- GitLab From e3cf9bcf1f473990d7e23fcd8cc34e0baccb765e Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 18:11:51 +0200 Subject: [PATCH 16/34] fembms: handle L2 eNB/UE config Signed-off-by: Javier Morgade --- openair2/LAYER2/MAC/config.c | 23 ++++++++++++++++++++--- openair2/LAYER2/MAC/config_ue.c | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 49949bd771..781347abaa 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -660,7 +660,7 @@ config_sib2_mbsfn_part( int Mod_idP, if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 0; phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); + LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] oneFrame pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 1; phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = @@ -668,7 +668,7 @@ config_sib2_mbsfn_part( int Mod_idP, (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, + LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] fourFrame pattern is %x\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]); } } @@ -777,7 +777,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo_fembms, struct LTE_NonMBSFN_SubframeConfig_r14 *nonMBSFN_SubframeConfig, LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms_r14_fembms, - LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms + LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms, + LTE_MBSFNAreaConfiguration_r9_t*mbms_AreaConfig ) { int i; int UE_id = -1; @@ -989,6 +990,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, cfg->num_tlv++; //We need to reuse current MCH scheduler //TOCHECK whether we can simply reuse current mbsfn_SubframeConfig stuff + RC.mac[Mod_idP]->common_channels[0].FeMBMS_flag = FeMBMS_Flag; } if (mbsfn_AreaInfoList != NULL) { @@ -1005,6 +1007,21 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, } } + if(mbms_AreaConfig != NULL) { + RC.mac[Mod_idP]->common_channels[0].commonSF_AllocPeriod_r9 = mbms_AreaConfig->commonSF_AllocPeriod_r9; + LOG_I(MAC, "[eNB %d][CONFIG] LTE_MBSFNAreaConfiguration_r9_t(%p) commonSF_AllocPeriod_r9(%d)\n",Mod_idP,mbms_AreaConfig, RC.mac[Mod_idP]->common_channels[0].commonSF_AllocPeriod_r9); + for(i=0; i < mbms_AreaConfig->commonSF_Alloc_r9.list.count; i++){ + RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = mbms_AreaConfig->commonSF_Alloc_r9.list.array[i]; + LOG_I(RRC,"[eNB %d][CONFIG] MBSFNArea[%d] commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x,%x,%x)\n" + ,Mod_idP,i + ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod + ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset + ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0] + ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1] + ,RC.mac[Mod_idP]->common_channels[0].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2]); + } + } + if (pmch_InfoList != NULL) { // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index 897afbf62b..1c5e706218 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -530,6 +530,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, LOG_I(MAC, "[UE %d] Configuring LTE_NonMBSFN \n", Mod_idP); phy_config_sib1_fembms_ue(Mod_idP, CC_idP, 0, nonMBSFN_SubframeConfig); + UE_mac_inst[Mod_idP].non_mbsfn_SubframeConfig = nonMBSFN_SubframeConfig; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME -- GitLab From 9b37dcecdb07fc90ef77674bdd48c78e68909068 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 18:14:44 +0200 Subject: [PATCH 17/34] fembms: handle MBMS in new RLC Signed-off-by: Javier Morgade --- openair2/LAYER2/RLC/rlc.c | 2 +- openair2/LAYER2/RLC/rlc_rrc.c | 3 ++- openair2/PHY_INTERFACE/phy_stub_UE.c | 32 +++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 2fb844f05a..98c8c3e252 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -519,7 +519,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, // LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id); if (sdu_pP != NULL) { if (sdu_sizeP > 0) { - LOG_I(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP); + LOG_D(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP); new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__); if (new_sdu_p != NULL) { diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 85ee4e0571..4313f379fe 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -640,7 +640,8 @@ rlc_union_t *rrc_rlc_add_rlc ( } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) { rlc_union_p = calloc(1, sizeof(rlc_union_t)); h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p); - h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); + if(MBMS_flagP != TRUE) + h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { if (MBMS_flagP == TRUE) { diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 41fb3ddc3a..de42d67624 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -800,7 +800,37 @@ void dl_config_req_UE_MAC_dci(int sfn, UE_mac_inst[ue_id].first_ULSCH_Tx = 1; } } - } else { + } + //else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) { + // // BCH case: Last parameter is 1 if first time synchronization and zero + // // otherwise. Not sure which value to put for our case. + // if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){ + // dl_phy_sync_success(Mod_id, sfn, 0, 1); + // LOG_E(MAC, + // "%s(): Received MIB: UE_mode: %d, sfn/sf: %d.%d\n", + // __func__, + // UE_mac_inst[Mod_id].UE_mode[0], + // sfn, + // sf); + // UE_mac_inst[Mod_id].UE_mode[0] = PRACH; + // } else { + // dl_phy_sync_success(Mod_id, sfn, 0, 0); + // } + //} else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_MCH_PDU_TYPE){ + // if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED) { + // /* this check is in the code before refactoring, but I don't know + // * why. Leave it in here for the moment */ + // continue; + // } + // nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp = &dl_config_pdu_list[i]; + // const int pdu_index = dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index; + // ue_send_mch_sdu(Mod_id, 0, sfn, + // tx_request_pdu_list[pdu_index].segments[0].segment_data, + // tx_request_pdu_list[pdu_index].segments[0].segment_length, + // 0,0); + + //} + else { LOG_W(MAC, "can not handle special RNTI %x\n", rnti); } } -- GitLab From 3aaa152e4e34f84a264e369f50457c83d4a20d80 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 18:16:46 +0200 Subject: [PATCH 18/34] fembms: new FeMBMS/eMBMS MCH eNB/UE scheduler implemented - MBMS scheduler re-worked to enable dedicated MBMS serving cells - added support for multiple eMBMS MCH sessions - added support for multiple FeMBMS MCH sessions Signed-off-by: Javier Morgade --- openair2/LAYER2/MAC/eNB_scheduler.c | 21 +- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 59 + openair2/LAYER2/MAC/eNB_scheduler_mch.c | 1303 ++++++++++++---------- openair2/LAYER2/MAC/mac.h | 9 +- openair2/LAYER2/MAC/mac_proto.h | 18 +- openair2/LAYER2/MAC/ue_procedures.c | 610 +++++++++- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 2 +- 7 files changed, 1415 insertions(+), 607 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index c46005ee2d..c36bd0d56a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -904,6 +904,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } #endif + int do_fembms_si=0; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { if (cc[CC_id].MBMS_flag > 0) { start_meas(&RC.mac[module_idP]->schedule_mch); @@ -914,6 +915,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } stop_meas(&RC.mac[module_idP]->schedule_mch); } + if (cc[CC_id].FeMBMS_flag > 0) { + do_fembms_si = 1; + } + } static int debug_flag = 0; @@ -935,12 +940,22 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* This schedules MIB */ - if ((subframeP == 0) && (frameP & 3) == 0) - schedule_mib(module_idP, frameP, subframeP); + if(!do_fembms_si/*get_softmodem_params()->fembms*/){ + if ((subframeP == 0) && (frameP & 3) == 0) + schedule_mib(module_idP, frameP, subframeP); + }else{ + if ((subframeP == 0) && (frameP & 15) == 0 ){ + schedule_fembms_mib(module_idP, frameP, subframeP); + //schedule_SI_MBMS(module_idP, frameP, subframeP); + } + } if (get_softmodem_params()->phy_test == 0) { /* This schedules SI for legacy LTE and eMTC starting in subframeP */ - schedule_SI(module_idP, frameP, subframeP); + if(!do_fembms_si/*get_softmodem_params()->fembms*/) + schedule_SI(module_idP, frameP, subframeP); + else + schedule_SI_MBMS(module_idP, frameP, subframeP); /* This schedules Paging in subframeP */ schedule_PCH(module_idP,frameP,subframeP); /* This schedules Random-Access for legacy LTE and eMTC starting in subframeP */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 5b99578d57..e4b9a7a65b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -731,6 +731,7 @@ schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, if (subframeP == 0) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { cc = &eNB->common_channels[CC_id]; + //printf("*cc->sib1_MBMS->si_WindowLength_r14 %d \n", *cc->sib1_MBMS->si_WindowLength_r14); vrb_map = (void *) &cc->vrb_map; N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); dl_config_request = &eNB->DL_req[CC_id]; @@ -911,6 +912,64 @@ schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, stop_meas(&eNB->schedule_si_mbms); } +void +schedule_fembms_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + int mib_sdu_length; + int CC_id; + nfapi_dl_config_request_t *dl_config_request; + nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; + AssertFatal(subframeP == 0, "Subframe must be 0\n"); + AssertFatal((frameP & 15) == 0, "Frame must be a multiple of 16\n"); + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &dl_config_request->dl_config_request_body; + cc = &eNB->common_channels[CC_id]; + mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH_MBMS, 0xFFFF, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case + LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length); + + if (mib_sdu_length > 0) { + LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); + + if ((frameP & 1023) < 40) + LOG_D(MAC, + "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n", + module_idP, frameP, CC_id, mib_sdu_length, + (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = + 2 + sizeof(nfapi_dl_config_bch_pdu); + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; + dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_req->number_pdu++; + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); + // DL request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 3; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 3; + TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + } + } +} void schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index eb5d78fd3f..cb90419d43 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -66,7 +66,11 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, "[eNB %d] CC_id %d MBSFN synchronization area %d out of range\n ", module_idP, CC_id, mbsfn_sync_area); return -1; - } else if (RC.mac[module_idP]-> + }else if (RC.mac[module_idP]-> + common_channels[CC_id].non_mbsfn_SubframeConfig + != NULL) { + return mbsfn_sync_area; + }else if (RC.mac[module_idP]-> common_channels[CC_id].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) { return mbsfn_sync_area; @@ -80,14 +84,30 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, static uint32_t bytes_in_buffer=0; static uint32_t msi_pmch_stop=0; -//static uint8_t msi_active=0; -//static uint8_t msi_pmch_stop2=0; -uint16_t mbms_rab_id = 2047; +uint16_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; static uint32_t msi_sfs=0; //MSI_ELEMENT * ptr =NULL; +static int check_CAS_sf(frame_t frameP,sub_frame_t subframeP){ + if( ((frameP&3)==0) && (subframeP == 0)) + return 1; + else + return 0; +} +static int check_nonMBSFN_sf(frame_t frameP,COMMON_channels_t *cc,int sf){ + uint32_t non_mbsfn_SubframeConfig = (cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7); + if( frameP % (4<non_mbsfn_SubframeConfig->radioFrameAllocationPeriod_r14) == cc->non_mbsfn_SubframeConfig->radioFrameAllocationOffset_r14 ){ + return (non_mbsfn_SubframeConfig & (0x200>>(sf)))==(0x200 >> (sf)); + } + return 0; +} + + +static int x=0; +static int mbms_mch_i=0; + int schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP) @@ -99,395 +119,571 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; int mbsfn_period = 0; // 1<<(RC.mac[module_idP]->mbsfn_SubframeConfig[0]->radioframeAllocationPeriod); int mcch_period = 0; //32<<(RC.mac[module_idP]->mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + //TOCHECK mtch index here if(RC.mac[module_idP]->common_channels[CC_id]. pmch_Config[0] == NULL ) - return 0; - - - + //TOCHECK mtch index here int mch_scheduling_period = 8 << (RC.mac[module_idP]->common_channels[CC_id]. pmch_Config[0]->mch_SchedulingPeriod_r9); - unsigned char mcch_sdu_length; - unsigned char header_len_mcch = 0, header_len_msi = - 0, header_len_mtch = 0, header_len_mtch_temp = - 0, header_len_mcch_temp = 0, header_len_msi_temp = 0; - int ii = 0, msi_pos = 0; - int mcch_mcs = -1; - uint16_t TBS, j = -1, padding = 0, post_padding = 0; - mac_rlc_status_resp_t rlc_status; - //mac_rlc_status_resp_t rlc_status2; - int num_mtch; - int msi_length=0, i, k; - //uint8_t l =0; - unsigned char sdu_lcids[11], num_sdus = 0, offset = 0; - uint16_t sdu_lengths[11], sdu_length_total = 0; - unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only - - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; - - cc->MCH_pdu.Pdu_size = 0; - - for (i = 0; i < cc->num_active_mbsfn_area; i++) { - // assume, that there is always a mapping - if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) { - return 0; - } - - mbsfn_period = - 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); - mcch_period = - 32 << (cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_RepetitionPeriod_r9); - msi_pos = 0; - ii = 0; - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n", - module_idP, CC_id, frameP, subframeP, i, - cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern, - mbsfn_period, mcch_period); - - - switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { - case 0: - mcch_mcs = 2; - break; - - case 1: - mcch_mcs = 7; - break; - - case 2: - mcch_mcs = 13; - break; - - case 3: - mcch_mcs = 19; - break; - } - - // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) - if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP - if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format - - // Find the first subframeP in this MCH to transmit MSI - if (frameP % mch_scheduling_period == - cc->mbsfn_SubframeConfig[j]-> - radioframeAllocationOffset) { - while (ii == 0) { - ii = cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & (0x80 >> msi_pos); - msi_pos++; - } - - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", - module_idP, CC_id, frameP, subframeP, i, j, - cc->mbsfn_SubframeConfig[j]-> - subframeAllocation.choice.oneFrame.buf[0], - msi_pos); - } - // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 - switch (subframeP) { - case 1: - if (cc->tdd_Config == NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == - MBSFN_FDD_SF1) { - if (msi_pos == 1) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF1) == - MBSFN_FDD_SF1)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 2: - if (cc->tdd_Config == NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == - MBSFN_FDD_SF2) { - if (msi_pos == 2) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF2) == - MBSFN_FDD_SF2)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 3: - if (cc->tdd_Config != NULL) { // TDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == - MBSFN_TDD_SF3) { - if (msi_pos == 1) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF3) == - MBSFN_TDD_SF3)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } else { // FDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == - MBSFN_FDD_SF3) { - if (msi_pos == 3) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF3) == - MBSFN_FDD_SF3)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 4: - if (cc->tdd_Config != NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == - MBSFN_TDD_SF4) { - if (msi_pos == 2) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF4) == - MBSFN_TDD_SF4)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 6: - if (cc->tdd_Config == NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == - MBSFN_FDD_SF6) { - if (msi_pos == 4) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF6) == - MBSFN_FDD_SF6)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 7: - if (cc->tdd_Config != NULL) { // TDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == - MBSFN_TDD_SF7) { - if (msi_pos == 3) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF7) == - MBSFN_TDD_SF7)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } else { // FDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == - MBSFN_FDD_SF7) { - if (msi_pos == 5) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF7) == - MBSFN_FDD_SF7)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 8: - if (cc->tdd_Config != NULL) { //TDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == - MBSFN_TDD_SF8) { - if (msi_pos == 4) { - msi_flag = 1; - } - - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF8) == - MBSFN_TDD_SF8)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } else { // FDD - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == - MBSFN_FDD_SF8) { - if (msi_pos == 6) { - msi_flag = 1; - } - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_FDD_SF8) == - MBSFN_FDD_SF8)) { - mcch_flag = 1; - } + unsigned char mcch_sdu_length; + unsigned char header_len_mcch = 0, header_len_msi = + 0, header_len_mtch = 0, header_len_mtch_temp = + 0, header_len_mcch_temp = 0, header_len_msi_temp = 0; + int ii = 0, msi_pos = -1; + int mcch_mcs = -1; + int shifted_sf = 0; + uint16_t TBS, j = -1, padding = 0, post_padding = 0; + mac_rlc_status_resp_t rlc_status; + int num_mtch=0; + int msi_length=0, i, k; - mtch_flag = 1; - } - } + unsigned char sdu_lcids[11], num_sdus = 0, offset = 0; + uint16_t sdu_lengths[11], sdu_length_total = 0; + unsigned char mch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; // check the max value, this is for dlsch only - break; + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; - case 9: - if (cc->tdd_Config != NULL) { - if ((cc-> - mbsfn_SubframeConfig[j]->subframeAllocation. - choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == - MBSFN_TDD_SF9) { - if (msi_pos == 5) { - msi_flag = 1; - } + cc->MCH_pdu.Pdu_size = 0; - if ((frameP % mcch_period == - cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_Offset_r9) - && - ((cc->mbsfn_AreaInfo[i]-> - mcch_Config_r9.sf_AllocInfo_r9. - buf[0] & MBSFN_TDD_SF9) == - MBSFN_TDD_SF9)) { - mcch_flag = 1; - } + for (i = 0; i < cc->num_active_mbsfn_area; i++) { + // assume, that there is always a mapping + if ((j = get_mbsfn_sf_alloction(module_idP, CC_id, i)) == -1) { + return 0; + } - mtch_flag = 1; - } - } + if(cc->non_mbsfn_SubframeConfig){ + int alloc_offset=0; + uint32_t period; + + uint32_t non_mbsfn_SubframeConfig = (cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | cc->non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7); + long mcch_offset = cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9; + + period = 4<non_mbsfn_SubframeConfig->radioFrameAllocationPeriod_r14; + alloc_offset = cc->non_mbsfn_SubframeConfig->radioFrameAllocationOffset_r14; + mcch_period = 32 << cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9; + + // get the real MCS value + switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; + + case 1: + mcch_mcs = 7; + break; + + case 2: + mcch_mcs = 13; + break; + + case 3: + mcch_mcs = 19; + break; + } + + if (cc->pmch_Config[0]) { + mch_scheduling_period = 8 << cc->pmch_Config[0]->mch_SchedulingPeriod_r9; + } + + LOG_D(MAC,"frameP %d subframe %d period %d alloc_offset %d mcch_mcs %d mcch_period %d mcch_offset %ld buf %x mch_scheduling_period %d\n",frameP, subframeP, period, alloc_offset,mcch_mcs, mcch_period, mcch_offset,(cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]),mch_scheduling_period); + //if( (frameP % (4 << cc->commonSF_AllocPeriod_r9) ) == 0 ){ + // if((subframeP==0)){ + // x=0; + // mbms_mch_i=0; + // } + //} + //if (frameP % (4 << cc->commonSF_AllocPeriod_r9 ) == 0) { + // if((subframeP==0)){ + // x=0; + // mbms_mch_i=0; + // } + //} + if (cc->pmch_Config[0]) { + // Find the first subframe in this MCH to transmit MSI + if (frameP % 1 == 0) { + if (frameP % mch_scheduling_period == 0) { + msi_pos=0; + if((frameP&3)==0) + msi_pos++; + while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos)) + msi_pos++; + mbms_mch_i=0; - break; - } // end switch + if((subframeP==0)){ + x=0; + mbms_mch_i=0; + } + + } + } + } - // sf allocation is non-overlapping - if ((msi_flag == 1) || (mcch_flag == 1) - || (mtch_flag == 1)) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", - module_idP, CC_id, frameP, subframeP, i, j, - msi_flag, mcch_flag, mtch_flag); - break; + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9+shifted_sf){ + + shifted_sf = check_nonMBSFN_sf(frameP,cc,subframeP)+check_CAS_sf(frameP,subframeP); + msi_pos=subframeP+shifted_sf; + if(shifted_sf==0) + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d shifted_sf %d\n",frameP, subframeP, msi_pos,mbms_mch_i,shifted_sf); } - } else { // four-frameP format } - } - } // end of for loop + + // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframeP) { + case 0: + if (msi_pos == 0) { + msi_flag = 1; + } + mtch_flag = 1; + break; + case 1: + if (msi_pos == 1) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + mtch_flag = 1; + break; + + case 2: + if (msi_pos == 2) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { + mcch_flag = 1; + } + mtch_flag = 1; + + break; + + case 3: + if (msi_pos == 3) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + mtch_flag = 1; + break; + + case 4: + if (msi_pos == 4) { + msi_flag = 1; + } + mtch_flag = 1; + break; + + case 5: + if (msi_pos == 5) { + msi_flag = 1; + } + mtch_flag = 1; + break; + + case 6: + if (msi_pos == 6) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { + mcch_flag = 1; + } + mtch_flag = 1; + break; + + case 7: + if (msi_pos == 7) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + mtch_flag = 1; + break; + + case 8: + if (msi_pos == 8) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + mtch_flag = 1; + break; + + case 9: + if (msi_pos == 9) { + msi_flag = 1; + } + mtch_flag = 1; + break; + }// end switch + + if ((msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1)) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + module_idP, CC_id, frameP, subframeP, i, j, + msi_flag, mcch_flag, mtch_flag); + } + + //TODO quitar la subframe 0 del otro switch ... está mal interpretado ? + // if((frameP&3) == 0){ + // mtch_flag=0;mcch_flag=0;msi_flag=0; + // } + + if((frameP % period ) == alloc_offset){ + LOG_D(MAC,"non_mbsfn_SubframeConfig %x\n",non_mbsfn_SubframeConfig); + switch(subframeP){ + case 0:{ + mtch_flag=0;mcch_flag=0;msi_flag=0; + } + break; + case 1:{ + if ((non_mbsfn_SubframeConfig & 0x100) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 2:{ + if ((non_mbsfn_SubframeConfig & 0x80) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 3:{ + if ((non_mbsfn_SubframeConfig & 0x40) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 4:{ + if ((non_mbsfn_SubframeConfig & 0x20) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 5:{ + if ((non_mbsfn_SubframeConfig & 0x10) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 6:{ + if ((non_mbsfn_SubframeConfig & 0x8) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 7:{ + if ((non_mbsfn_SubframeConfig & 0x4) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 8:{ + if ((non_mbsfn_SubframeConfig & 0x2) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + case 9:{ + if ((non_mbsfn_SubframeConfig & 0x1) > 0) + {mtch_flag=0;mcch_flag=0;msi_flag=0;} + } + break; + } + } + // sf allocation is non-overlapping + if ((msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1)) { + x++; + //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){ + //x++; + //} + + if(msi_flag==1){ + if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %( 4 << cc->commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 << cc->pmch_Config[mbms_mch_i]->mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){ + msi_flag=0; + LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframeP, mbms_mch_i); + } + + } + + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d, x %d\n", + module_idP, CC_id, frameP, subframeP, i, j, + msi_flag, mcch_flag, mtch_flag,x); + break; + } + + + }else if(cc->mbsfn_SubframeConfig[j]){ + + mbsfn_period = + 1 << (cc->mbsfn_SubframeConfig[j]->radioframeAllocationPeriod); + mcch_period = + 32 << (cc->mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_RepetitionPeriod_r9); + msi_pos = 0; + ii = 0; + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d)\n", + module_idP, CC_id, frameP, subframeP, i, + cc->num_active_mbsfn_area, j, cc->num_sf_allocation_pattern, + mbsfn_period, mcch_period); + + switch (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; + + case 1: + mcch_mcs = 7; + break; + + case 2: + mcch_mcs = 13; + break; + + case 3: + mcch_mcs = 19; + break; + } + + // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) + if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP + if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + // Find the first subframeP in this MCH to transmit MSI + if (frameP % mch_scheduling_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { + while (ii == 0) { + ii = cc-> + mbsfn_SubframeConfig[j]->subframeAllocation. + choice.oneFrame.buf[0] & (0x80 >> msi_pos); + msi_pos++; + } + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : sync area %d sf allocation pattern %d sf alloc %x msi pos is %d \n", + module_idP, CC_id, frameP, subframeP, i, j, + cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0], + msi_pos); + if((subframeP==1)){ + x=0; + mbms_mch_i=0; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + + // Check if the subframeP is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframeP) { + case 1: + if (cc->tdd_Config == NULL) { + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=1; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 1) { + msi_flag = 1; + } + if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + && ( (cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 2: + if (cc->tdd_Config == NULL) { + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=2; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + + if (msi_pos == 2) { + msi_flag = 1; + } + if ( (frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + && ((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 3: + if (cc->tdd_Config != NULL) { + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { + if (msi_pos == 1) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } else { // FDD + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=3; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 3) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 4: + if (cc->tdd_Config != NULL) { + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { + if (msi_pos == 2) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 6: + if (cc->tdd_Config == NULL) { + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=4; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 4) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 7: + if (cc->tdd_Config != NULL) { // TDD + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { + if (msi_pos == 3) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } else { // FDD + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=5; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + + if (msi_pos == 5) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 8: + if (cc->tdd_Config != NULL) { //TDD + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { + if (msi_pos == 4) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } else { // FDD + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { + if(cc->pmch_Config[mbms_mch_i+1]!=NULL){ + if( x == cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=6; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframeP, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 6) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + case 9: + if (cc->tdd_Config != NULL) { + if ((cc->mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { + if (msi_pos == 5) { + msi_flag = 1; + } + if ((frameP % mcch_period == cc->mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) + &&((cc->mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9)) { + mcch_flag = 1; + } + mtch_flag = 1; + } + } + break; + } // end switch + // sf allocation is non-overlapping + if ((msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1)) { + x++; + //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){ + //x++; + //} + if(msi_flag==1){ + if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %( 4 << cc->commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 << cc->pmch_Config[mbms_mch_i]->mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){ + msi_flag=0; + LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframeP, mbms_mch_i); + } + + } + + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d x %d\n", + module_idP, CC_id, frameP, subframeP, i, j, + msi_flag, mcch_flag, mtch_flag,x); + break; + } + } else {// four-frameP format + printf("Hola\n"); + AssertFatal(1==0,"four-frameP format: not implemented yet\n"); + } + } + } // MBMS format + }// end of for loop cc->msi_active = 0; cc->mcch_active = 0; @@ -497,7 +693,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, if ((msi_flag == 1) || (mcch_flag == 1)) { cc->MCH_pdu.mcs = mcch_mcs; } else if (mtch_flag == 1) { // only MTCH in this subframeP - cc->MCH_pdu.mcs = cc->pmch_Config[0]->dataMCS_r9; + cc->MCH_pdu.mcs = cc->pmch_Config[mbms_mch_i]->dataMCS_r9; } @@ -510,26 +706,14 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, // there is MSI (MCH Scheduling Info) uint16_t msi_control_element[29], *msi_ptr; + // MSI buffer pointer char *buffer_pointer=NULL; if (msi_flag == 1) { // Create MSI here - //uint16_t msi_control_element[29], *msi_ptr; - msi_ptr = &msi_control_element[0]; - //((MSI_ELEMENT *) msi_ptr)->lcid = MCCH_LCHANID; //MCCH - - //if (mcch_flag == 1) { - // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; - // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0; - //} else { // no mcch for this MSP - // ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // stop value is 2047 - // ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xff; - //} - - //msi_ptr += sizeof(MSI_ELEMENT); //Header for MTCHs - num_mtch = cc->mbms_SessionList[0]->list.count; + num_mtch = cc->mbms_SessionList[mbms_mch_i]->list.count; TBS = get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); @@ -537,7 +721,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment - ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[0]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; + ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; if( msi_sfs != 0 ) msi_pmch_stop = msi_sfs-1; @@ -546,22 +730,15 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, msi_pmch_stop = msi_sfs; - //if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9) - //LOG_W(MAC,"e-MBMS Buffer Overflow\n"); - if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) & stop_sf limited to 256 - //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); - msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = (((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) >> 8) & 0x7f); + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = ((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) & 0xff); + msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9); }else{ ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; msi_pmch_stop=0; } - - - msi_ptr += sizeof(MSI_ELEMENT); } @@ -573,15 +750,11 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, header_len_msi = 3; } - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes TBS %d, bytes in buffer %d stop_sf_LSB %d msi_sfs %d cc->pmch_Config[0]->sf_AllocEnd_r9 %ld\n", - module_idP, CC_id, frameP, msi_length,TBS, bytes_in_buffer,msi_pmch_stop,msi_sfs,cc->pmch_Config[0]->sf_AllocEnd_r9); + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : MSI->MCH, length of MSI is %d bytes TBS %d, bytes in buffer %d stop_sf_LSB %d msi_sfs %d cc->pmch_Config[0]->sf_AllocEnd_r9 %ld\n", + module_idP, CC_id, frameP, msi_length,TBS, bytes_in_buffer,msi_pmch_stop,msi_sfs,cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9); msi_sfs = 0; - //LOG_D(MAC,"Scheduler: MSI is transmitted in this subframeP \n" ); - - // LOG_D(MAC,"Scheduler: MSI length is %d bytes\n",msi_length); // Store MSI data to mch_buffer[0] memcpy((char *) &mch_buffer[sdu_length_total], msi_control_element, msi_length); @@ -598,75 +771,93 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } // there is MCCH if (mcch_flag == 1) { - - //LOG_E(MAC, - //"[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (mod %d)\n",module_idP, CC_id, frameP, subframeP,frameP%2==0); - if(1/*frameP%2==0*/){ - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", - module_idP, CC_id, frameP, subframeP, i, j); - - mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], - i); // this is the mbsfn sync area index - } - else{ - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (area %d, sfAlloc %d)\n", - module_idP, CC_id, frameP, subframeP, i, j); - -// -// mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH_COUNTING, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], -// i); // this is the mbsfn sync area index + //MCCH scheduling if !FeMBMS + if(!cc->non_mbsfn_SubframeConfig){ + mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH_COUNTING, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], + i); // this is the mbsfn sync area index + if(mcch_sdu_length>0) + LOG_I(MAC, "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE COUNTING (area %d, sfAlloc %d)\n", + module_idP, CC_id, frameP, subframeP, i, j); + + if (mcch_sdu_length > 0) { + mcch_sdu_length+=1; //RLC ? + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", + module_idP, CC_id, frameP, subframeP, mcch_sdu_length); + + header_len_mcch = 2; + + if (cc->tdd_Config != NULL) { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } else { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } + + cc->mcch_active = 1; + + memcpy((char *) &mch_buffer[sdu_length_total]+1, + &cc->MCCH_pdu.payload[0], mcch_sdu_length); + sdu_lcids[num_sdus] = MCCH_LCHANID; + sdu_lengths[num_sdus] = mcch_sdu_length; + + if (sdu_lengths[num_sdus] > 128) { + header_len_mcch = 3; + } + + sdu_length_total += sdu_lengths[num_sdus]; + LOG_D(MAC, + "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n", + module_idP, CC_id, sdu_lengths[num_sdus]); + num_sdus++; + } } - mcch_sdu_length+=1; //RLC ? - - if (mcch_sdu_length > 0) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", - module_idP, CC_id, frameP, subframeP, mcch_sdu_length); - - header_len_mcch = 2; - - if (cc->tdd_Config != NULL) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", - module_idP, CC_id, frameP, subframeP, - mcch_sdu_length, mcch_mcs); - } else { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", - module_idP, CC_id, frameP, subframeP, - mcch_sdu_length, mcch_mcs); - } - - cc->mcch_active = 1; + //MCCH scheduling ... do it anyway + { + LOG_I(MAC, "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", + module_idP, CC_id, frameP, subframeP, i, j); + + mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], + i); // this is the mbsfn sync area index + + if (mcch_sdu_length > 0) { + mcch_sdu_length+=1; //RLC ? + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d : MCCH->MCH, Received %d bytes from RRC \n", + module_idP, CC_id, frameP, subframeP, mcch_sdu_length); + + header_len_mcch = 2; + + if (cc->tdd_Config != NULL) { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } else { + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n", + module_idP, CC_id, frameP, subframeP, + mcch_sdu_length, mcch_mcs); + } - memcpy((char *) &mch_buffer[sdu_length_total]+1, - &cc->MCCH_pdu.payload[0], mcch_sdu_length); - sdu_lcids[num_sdus] = MCCH_LCHANID; - sdu_lengths[num_sdus] = mcch_sdu_length; + cc->mcch_active = 1; - // LOG_W(MAC,"MCCH RLC %x:",(unsigned char)mch_buffer[sdu_length_total]); - // for (int kk = 7; kk >= 0; kk--) - // { - // printf("%d",(((unsigned char)mch_buffer[sdu_length_total]) >> kk) & 1 ? '1' : '0'); - // } - // printf("\n"); - //mch_buffer[sdu_length_total] = (unsigned char)0; + memcpy((char *) &mch_buffer[sdu_length_total]+1, + &cc->MCCH_pdu.payload[0], mcch_sdu_length); + sdu_lcids[num_sdus] = MCCH_LCHANID; + sdu_lengths[num_sdus] = mcch_sdu_length; + if (sdu_lengths[num_sdus] > 128) { + header_len_mcch = 3; + } - if (sdu_lengths[num_sdus] > 128) { - header_len_mcch = 3; + sdu_length_total += sdu_lengths[num_sdus]; + LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n", + module_idP, CC_id, sdu_lengths[num_sdus]); + num_sdus++; } - - sdu_length_total += sdu_lengths[num_sdus]; - LOG_D(MAC, - "[eNB %d] CC_id %d Got %d bytes for MCCH from RRC \n", - module_idP, CC_id, sdu_lengths[num_sdus]); - num_sdus++; } - } + }// mcch_flag TBS = @@ -678,154 +869,108 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, // there is MTCHs, loop if there are more than 1 if (mtch_flag == 1 ) { // Calculate TBS - /* if ((msi_flag==1) || (mcch_flag==1)) { - TBS = mac_xface->get_TBS(mcch_mcs, mac_xface->frame_parms->N_RB_DL); - } - else { // only MTCH in this subframeP - TBS = mac_xface->get_TBS(RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9, mac_xface->frame_parms->N_RB_DL); - } - - // get MTCH data from RLC (like for DTCH) - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframe %d: Schedule MTCH (area %d, sfAlloc %d)\n",Mod_id,CC_id,frame,subframe,i,j); - - header_len_mtch = 3; - LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", - Mod_id,CC_id,frame,MTCH,TBS, - TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); - - rlc_status = mac_rlc_status_ind(Mod_id,frame,1,RLC_MBMS_YES,MTCH+ (maxDRB + 3) * MAX_MOBILES_PER_RG, - TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); - printf("frame %d, subframe %d, rlc_status.bytes_in_buffer is %d\n",frame,subframe, rlc_status.bytes_in_buffer); - - */ - // get MTCH data from RLC (like for DTCH) - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", module_idP, CC_id, frameP, subframeP, i, j); header_len_mtch = 3; - LOG_D(MAC, - "[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", + LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n", module_idP, CC_id, frameP, MTCH, TBS, TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch); - mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9; + //TODO + mbms_rab_id = cc->mbms_SessionList[0/*mbms_mch_i*/]->list.array[0]->logicalChannelIdentity_r9; rlc_status = mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP, module_idP, ENB_FLAG_YES, MBMS_FLAG_YES, - cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, + cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9, //MTCH, 0, 0 ); - bytes_in_buffer = rlc_status.bytes_in_buffer; + bytes_in_buffer = rlc_status.bytes_in_buffer; + //TOCHECK is this really neede? if( !(mcch_flag==1 || msi_flag==1) ) msi_sfs = rlc_status.bytes_in_buffer/(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)+(rlc_status.bytes_in_buffer%(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)?1:0); - //uint16_t msi_control_element[29], *msi_ptr; - // - // - uint16_t TBS_MTCH = - get_TBS_DL(cc->pmch_Config[0]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth)); - if(msi_flag==1 && buffer_pointer!=NULL){ - msi_ptr = &msi_control_element[0]; - //memcpy(buffer_pointer, - // msi_control_element, msi_length); + uint16_t TBS_MTCH = + get_TBS_DL(cc->pmch_Config[mbms_mch_i]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth)); + + if(msi_flag==1 && buffer_pointer!=NULL){ + // msi_ptr = &msi_control_element[0]; - // msi_pmch_stop = rlc_status.bytes_in_buffer/TBS+(rlc_status.bytes_in_buffer%TBS?1:0); msi_pmch_stop = (rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0); - if( msi_pmch_stop > cc->pmch_Config[0]->sf_AllocEnd_r9) - LOG_E(MAC,"e-MBMS Buffer Overflow\n"); - if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0; // last subframeP of this mtch (only one mtch now) & stop_sf limited to 256 - //((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = msi_pmch_stop; - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); - msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[0]->sf_AllocEnd_r9); - }else{ - ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) - ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; - msi_pmch_stop=0; - } - LOG_I(MAC,"frameP %d, subframeP %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d\n",frameP,subframeP,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB); - //LOG_W(MAC,"frameP %d, subframeP %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d msi_calc:%d remainder %d\n",frameP,subframeP,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,rlc_status.bytes_in_buffer/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0),((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0)); + for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment + msi_ptr = &msi_control_element[k]; - memcpy(buffer_pointer, - msi_control_element, msi_length); + ((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid; + + if( msi_pmch_stop > cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) + LOG_E(MAC,"e-MBMS Buffer Overflow\n"); + + if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) { + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = (((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) >> 8) & 0x7f); + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = ((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) & 0xff); + msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9); + }else{ + ((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = 0x7; // last subframeP of this mtch (only one mtch now) + ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; + msi_pmch_stop=0; + } + LOG_I(MAC,"frameP %d, subframeP %d LCID %ld rlc_status.bytes_in_buffer %d stop_sf_LSB %d stop_sf_MSB %d msi_pmch_stop %d sf_AllocEnd_r9 %ld, msi_length %d\n",frameP,subframeP,((MSI_ELEMENT *) msi_ptr)->lcid,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB, msi_pmch_stop,cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9, msi_length); + } + memcpy((char*)buffer_pointer, + msi_control_element, msi_length); } - LOG_D(MAC, - "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS_MTCH %d pmch_stop %d msi_sfs %d\n", + LOG_D(MAC, "e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d TBS_MTCH %d pmch_stop %d msi_sfs %d\n", MTCH, frameP, subframeP, rlc_status.bytes_in_buffer,TBS_MTCH,msi_pmch_stop,msi_sfs); - if ((rlc_status.bytes_in_buffer > 0 && msi_pmch_stop > 0) && ((msi_flag!=1 || mcch_flag!=1)) /*|| (rlc_status.bytes_in_buffer > 0 && (msi_flag==1 || mcch_flag==1))*//*|| msi_sfs > cc->pmch_Config[0]->sf_AllocEnd_r9 */ /*msi_pmch_stop>=num_sf_alloc*/ ) { - //if(rlc_status.bytes_in_buffer > 0){ - LOG_D(MAC, - "[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d) rlc_status.bytes_in_buffer %d\n", - module_idP, CC_id, frameP, + //TODO not sure whether msi and mch MCH should be precluded ... keep in mind this konditions just in case if ((rlc_status.bytes_in_buffer > 0 && msi_pmch_stop > 0) && ((msi_flag!=1 || mcch_flag!=1)) + if ((rlc_status.bytes_in_buffer > 0 && msi_pmch_stop > 0) /*&& ((msi_flag!=1 || mcch_flag!=1))*/ /*|| (rlc_status.bytes_in_buffer > 0 && (msi_flag==1 || mcch_flag==1))*//*|| msi_sfs > cc->pmch_Config[0]->sf_AllocEnd_r9 */ /*msi_pmch_stop>=num_sf_alloc*/ ) { + LOG_I(MAC,"[eNB %d][MBMS USER-PLANE], CC_id %d, Frame %d, Subframe %d MTCH->MCH, Requesting %d bytes from RLC (header len mtch %d) rlc_status.bytes_in_buffer %d, LCID %ld\n", + module_idP, CC_id, frameP, subframeP, TBS - header_len_mcch - header_len_msi - - sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer); + sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer,cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9, TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch, (char *) &mch_buffer[sdu_length_total] ,0, 0 ); - - // LOG_I(MAC,"RLC %x:",(unsigned char)mch_buffer[sdu_length_total]); - // for (int kk = 7; kk >= 0; kk--) - // { - // printf("%d",(((unsigned char)mch_buffer[sdu_length_total]) >> kk) & 1 ? '1' : '0'); - // } - // printf("\n"); - - //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(MAX_MOBILES_PER_ENB+1)), (char*)&mch_buffer[sdu_length_total]); - LOG_D(MAC, - "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_sfs %d sdu_lengths[num_sdus] %d\n", + LOG_D(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_sfs %d sdu_lengths[num_sdus] %d\n", module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs, sdu_lengths[num_sdus]); + cc->mtch_active = 1; - sdu_lcids[num_sdus] = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9/*MTCH*/; + + sdu_lcids[num_sdus] = cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9/*MTCH*/; sdu_length_total += sdu_lengths[num_sdus]; if (msi_pmch_stop != 0 && msi_flag !=1) msi_pmch_stop--; - if (sdu_lengths[num_sdus] < 128) { header_len_mtch = 2; } num_sdus++; - //} } else { - // LOG_E(MAC, - // "[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d msi_pmch_stop %d msi_buffer %d msi_sfs %ld msi_buffer_act %ld sdu_lengths[num_sdus] %d\n", - // module_idP, CC_id, sdu_lengths[num_sdus], MTCH,msi_pmch_stop,msi_sfs,msi_buffer_act, sdu_lengths[num_sdus]); - header_len_mtch = 0; } } - // } // FINAL STEP: Prepare and multiplexe MSI, MCCH and MTCHs - if ((sdu_length_total + header_len_msi + header_len_mcch + - header_len_mtch) > 0) { + if ((sdu_length_total + header_len_msi + header_len_mcch + header_len_mtch) > 0) { + // Adjust the last subheader - /* if ((msi_flag==1) || (mcch_flag==1)) { - RC.mac[module_idP]->MCH_pdu.mcs = mcch_mcs; - } - else if (mtch_flag == 1) { // only MTCH in this subframeP - RC.mac[module_idP]->MCH_pdu.mcs = RC.mac[module_idP]->pmch_Config[0]->dataMCS_r9; - } - */ header_len_mtch_temp = header_len_mtch; header_len_mcch_temp = header_len_mcch; header_len_msi_temp = header_len_msi; @@ -881,12 +1026,10 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, cc->MCH_pdu.msi_active = cc->msi_active; cc->MCH_pdu.mcch_active = cc->mcch_active; cc->MCH_pdu.mtch_active = cc->mtch_active; - LOG_D(MAC, - " MCS for this sf is %d (mcch active %d, mtch active %d)\n", + LOG_D(MAC, " MCS for this sf is %d (mcch active %d, mtch active %d)\n", cc->MCH_pdu.mcs, cc->MCH_pdu.mcch_active, cc->MCH_pdu.mtch_active); - LOG_D(MAC, - "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", + LOG_D(MAC, "[eNB %d][MBMS USER-PLANE ] CC_id %d Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,padding %d,post_padding %d (mcs %d, TBS %d), header MTCH %d, header MCCH %d, header MSI %d\n", module_idP, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], sdu_lcids[0], offset, padding, post_padding, cc->MCH_pdu.mcs, TBS, header_len_mtch, header_len_mcch, @@ -902,20 +1045,15 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, /* Tracing of PDU is done on UE side */ //if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xfffd, // M_RNTI = 6 in wirehsark - RC.mac[module_idP]->frame, - RC.mac[module_idP]->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n", + trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) cc->MCH_pdu.payload, TBS, module_idP, WS_M_RNTI , 0xfffd, // M_RNTI = 6 in wirehsark + RC.mac[module_idP]->frame, + RC.mac[module_idP]->subframe, 0, 0); + LOG_D(OPT, "[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n", module_idP, CC_id, frameP, TBS); //} eNB_MAC_INST *eNB = RC.mac[module_idP]; dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - // dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - // memset((void *) dl_config_pdu, - // 0, - // sizeof(nfapi_dl_config_request_pdu_t)); dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; fill_nfapi_mch_config( dl_req, @@ -934,12 +1072,6 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, TBS, eNB->pdu_index[CC_id], (uint8_t*)cc->MCH_pdu.payload); - - - /* - for (j=0;jMCH_pdu.payload[j+offset]); - printf(" \n"); */ return 1; } else { cc->MCH_pdu.Pdu_size = 0; @@ -947,21 +1079,8 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, cc->MCH_pdu.msi_active = 0; cc->MCH_pdu.mcch_active = 0; cc->MCH_pdu.mtch_active = 0; - // for testing purpose, fill with random data - //for (j=0;j<(TBS-sdu_length_total-offset);j++) - // RC.mac[module_idP]->MCH_pdu.payload[offset+sdu_length_total+j] = (char)(taus()&0xff); return 0; } - - //this is for testing - /* - if (mtch_flag == 1) { - // LOG_D(MAC,"DUY: mch_buffer length so far is : %ld\n", &mch_buffer[sdu_length_total]-&mch_buffer[0]); - return 1; - } - else - return 0; - */ } int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 329e262c82..d3bf40afa4 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -56,6 +56,7 @@ #include "LTE_MobilityControlInfo.h" #include "LTE_MBSFN-AreaInfoList-r9.h" #include "LTE_MBSFN-SubframeConfigList.h" +#include "LTE_MBSFNAreaConfiguration-r9.h" #include "LTE_PMCH-InfoList-r9.h" #include "LTE_SCellToAddMod-r10.h" #include "LTE_SystemInformationBlockType1-v1310-IEs.h" @@ -412,9 +413,11 @@ typedef struct { /*!\brief Values of BCCH SIB_BR logical channel (fake) */ #define BCCH_SI_BR 7 // SI-BR /*!\brief Values of BCCH SIB1_MBMS logical channel (fake) */ -#define BCCH_SIB1_MBMS 60 // SIB1_MBMS //TODO better armonize index +#define MIBCH_MBMS 10 // SIB1_MBMS //TODO better armonize index +#define BCCH_SIB1_MBMS 12 // SIB1_MBMS //TODO better armonize index /*!\brief Values of BCCH SI_MBMS logical channel (fake) */ -#define BCCH_SI_MBMS 61 // SIB_MBMS //TODO better armonize index +#define BCCH_SI_MBMS 13 // SIB_MBMS //TODO better armonize index +#define MCCH_COUNTING 14 /*!\brief Value of CCCH / SRB0 logical channel */ #define CCCH 0 // srb0 /*!\brief DCCH / SRB1 logical channel */ @@ -1312,6 +1315,8 @@ typedef struct { /// MBSFN SubframeConfig struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; struct LTE_NonMBSFN_SubframeConfig_r14 *non_mbsfn_SubframeConfig; + struct LTE_MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? + uint8_t commonSF_AllocPeriod_r9; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; /// MBMS Flag diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 2cb86c25af..d3bf1bd2ac 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -33,6 +33,16 @@ #include "PHY/defs_common.h" // for PRACH_RESOURCES_t and lte_subframe_t #include "openair2/COMMON/mac_messages_types.h" +/** \fn void schedule_fembms_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); +\brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1. +@param Mod_id Instance ID of eNB +@param frame Frame index +@param subframe Subframe number on which to act + +*/ + +void schedule_fembms_mib(module_id_t module_idP, + frame_t frameP, sub_frame_t subframeP); /** \addtogroup _mac * @{ @@ -534,6 +544,10 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, sub_frame_t subframe, uint8_t eNB_index, uint8_t *sync_area, uint8_t *mcch_active); +int ue_query_mch_fembms(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * sync_area, uint8_t * mcch_active); + /* \brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU. @param Mod_id Instance id of UE in machine @@ -900,6 +914,7 @@ int generate_dlsch_header(unsigned char *mac_header, @param non_MBSFN_SubframeConfig pointer to FeMBMS Non MBSFN Subframe Config @param sib1_mbms_r14_fembms pointer SI Scheduling infomration for SI-MBMS @param mbsfn_AreaInfoList_fembms pointer to FeMBMS MBSFN Area Info list from SIB1-MBMS +@param mbms_AreaConfiguration pointer to eMBMS MBSFN Area Configuration */ int rrc_mac_config_req_eNB(module_id_t module_idP, @@ -936,7 +951,8 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo_fembms, struct LTE_NonMBSFN_SubframeConfig_r14 *nonMBSFN_SubframeConfig, LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms_r14_fembms, - LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms + LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList_fembms, + LTE_MBSFNAreaConfiguration_r9_t * mbms_AreaConfiguration ); /** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages. diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 24630c0fe2..54d9f687e1 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -72,7 +72,10 @@ extern UL_IND_t *UL_INFO; extern int next_ra_frame; extern module_id_t next_Mod_id; -int mbms_rab_id = 2047; +int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; +static int mbms_mch_i=0; +static int num_msi_per_CSA[28]; + /* * @@ -753,13 +756,14 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n"); } - LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]); + LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]); + for (j=0; j> 3; UE_mac_inst[module_idP].pmch_stop_mtch[j] = stop_mtch_val; - LOG_D(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP); + LOG_I(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP); if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) { LOG_D(MAC,"(reserved)\n"); @@ -768,7 +772,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, UE_mac_inst[module_idP].msi_status_v[j] = 0; if (UE_mac_inst[module_idP].mcch_status==1) { - LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]); + LOG_I(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), LCID(%d)(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_lcids[j] , UE_mac_inst[module_idP].pmch_stop_mtch[j]); if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) { UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc; @@ -777,7 +781,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } } } else if (rx_lcids[i] == MCCH_LCHANID) { - LOG_D(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]); + LOG_I(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]); mac_rrc_data_ind_ue(module_idP, CC_id, frameP,0, // unknown subframe @@ -794,7 +798,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, } if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) { - LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j); + LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d lcid %d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j,rx_lcids[i]); //This sucks I know ... workaround ! mbms_rab_id = rx_lcids[i]; //end sucks :-( @@ -951,7 +955,9 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra } } else { //more that one MCH ?? check better this condition //msi and mtch are mutally excluded then the break is safe + //TODO if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9 + 1) && (sf_AllocEnd_r9 >= (num_sf_alloc+1))) { + //if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9) && (sf_AllocEnd_r9 >= (num_sf_alloc))) { //msi should be just after msi_flag = 1; LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9, @@ -986,6 +992,458 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra return mtch_mcs; } +//static int common_num_sf_alloc=0; +//static int x=0; +int ue_query_mch_fembms(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) { + int i = 0, j = 0,/* ii = 0,*/ msi_pos = -1, mcch_mcs = -1, mtch_mcs = -1, l=0,ii=0; + int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; + int alloc_offset=0; + uint32_t period; + //uint16_t num_non_mbsfn_SubframeConfig=0; + long mch_scheduling_period = -1; + uint8_t mch_lcid = 0; + int first_pos=0; + + if(UE_mac_inst[module_idP].non_mbsfn_SubframeConfig == NULL ) + return -1; + + int non_mbsfn_SubframeConfig = (UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7); + + period = 4<radioFrameAllocationPeriod_r14; + alloc_offset = UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->radioFrameAllocationOffset_r14; + + long mcch_period = 32 << UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9; + long mcch_offset = UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9; + + if (UE_mac_inst[module_idP].pmch_Config[0]) { + mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9; + } + + +// for(l=0;l<8;l++){ +// if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]!=NULL){ +// if(frameP%(4<> msi_pos)) == (0x100>>msi_pos)) +// first_pos++; +// if(first_pos == subframe){ +// ii=0; +// while(UE_mac_inst[module_idP].pmch_Config[ii]!=NULL){ +// num_msi_per_CSA[ii]= ( ( 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9) / (8 << UE_mac_inst[module_idP].pmch_Config[ii]->mch_SchedulingPeriod_r9) ); +// ii++; +// LOG_D(MAC,"frameP %d subframe %d num_msi_per_CSA[%d] %d\n",frameP,subframe,ii,num_msi_per_CSA[ii]); +// } +// } +// +// } +// } +// } +// + + // get the real MCS value + switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { + case 0: + mcch_mcs = 2; + break; + + case 1: + mcch_mcs = 7; + break; + + case 2: + mcch_mcs = 13; + break; + + case 3: + mcch_mcs = 19; + break; + } + LOG_D(MAC,"frameP %d subframe %d period %d alloc_offset %d mcch_mcs %d mcch_period %ld mcch_offset %ld buf %x mch_scheduling_period %ld\n",frameP, subframe, period, alloc_offset,mcch_mcs, mcch_period, mcch_offset,(UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]),mch_scheduling_period); + + if((frameP % period ) == alloc_offset){ + switch(subframe){ + case 0: + return (-1); + break; + case 1: + if ((non_mbsfn_SubframeConfig & 0x100) > 0) + return (-1); + break; + case 2: + if ((non_mbsfn_SubframeConfig & 0x80) > 0) + return (-1); + break; + case 3: + if ((non_mbsfn_SubframeConfig & 0x40) > 0) + return (-1); + break; + case 4: + if ((non_mbsfn_SubframeConfig & 0x20) > 0) + return (-1); + break; + case 5: + if ((non_mbsfn_SubframeConfig & 0x10) > 0) + return (-1); + break; + case 6: + if ((non_mbsfn_SubframeConfig & 0x8) > 0) + return (-1); + break; + case 7: + if ((non_mbsfn_SubframeConfig & 0x4) > 0) + return (-1); + break; + case 8: + if ((non_mbsfn_SubframeConfig & 0x2) > 0) + return (-1); + break; + case 9: + if ((non_mbsfn_SubframeConfig & 0x1) > 0) + return (-1); + break; + } + } + + if (UE_mac_inst[module_idP].pmch_Config[0]) { + // Find the first subframe in this MCH to transmit MSI + if (frameP % 1 == 0) { + if (frameP % mch_scheduling_period == 0) { + msi_pos=0; + if((frameP&3)==0) + msi_pos++; + while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos)) + msi_pos++; + if(msi_pos == subframe){ + UE_mac_inst[module_idP].common_num_sf_alloc=0; + mbms_mch_i=0; + //LOG_W(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + } + } + + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=subframe; + mbms_mch_i++; + // LOG_W(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + + + // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 + switch (subframe) { + case 0: + if (msi_pos == 0) { + msi_flag = 1; + } + mtch_flag = 1; + break; + case 1: + if (msi_pos == 1) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + + mtch_flag = 1; + break; + + case 2: + if (msi_pos == 2) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { + mcch_flag = 1; + } + + mtch_flag = 1; + + break; + + case 3: + if (msi_pos == 3) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; + + break; + case 4: + if (msi_pos == 4) { + msi_flag = 1; + } + mtch_flag = 1; + break; + case 5: + if (msi_pos == 5) { + msi_flag = 1; + } + mtch_flag = 1; + break; + + case 6: + if (msi_pos == 6) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { + mcch_flag = 1; + } + + mtch_flag = 1; + + break; + + case 7: + if (msi_pos == 7) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; + + break; + + case 8: + if (msi_pos == 8) { + msi_flag = 1; + } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; + break; + + case 9: + if (msi_pos == 9) { + msi_flag = 1; + } + mtch_flag = 1; + break; + }// end switch + + if( (msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1) ){ + UE_mac_inst[module_idP].common_num_sf_alloc++; + //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){ + //UE_mac_inst[module_idP].common_num_sf_alloc++; + //if(msi_flag == 1) + // if((num_msi_per_CSA[mbms_mch_i]--)==0){ + // LOG_E(MAC,"Both MSI and MTCH Should be reset?\n"); + // msi_flag=0; + //} + //} + + } + + + + +#ifdef OLD + // Acount for sf_allocable in CSA + int num_sf_alloc = 0; + + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + continue; + + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0]; + + + for (j = 0; j < 6; j++) + num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j)); + //num_sf_alloc=1; + } + + num_sf_alloc = 10; + + num_non_mbsfn_SubframeConfig = (UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7); + int ones=0; + for(j=0; j < 16; j++){ + if(num_non_mbsfn_SubframeConfig & 1) + ones++; + num_non_mbsfn_SubframeConfig>>=1; + } + + for (l = 0; l < 28; l++) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= 1/*num_sf_alloc*/) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[l] != 2047) { + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL){ + mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationOffset; + long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationPeriod; + long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + if(UE_mac_inst[module_idP].common_num_sf_alloc >= UE_mac_inst[module_idP].pmch_stop_mtch[l]){ + //LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc); + + mtch_mcs = -1; + }/*else + OG_W(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);*/ + LOG_D(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d num_sf_alloc %d commonSF_AllocPeriod %ld, common_mbsfn_period %ld num_non_mbsfn_SubframeConfig %x ones %d\n",UE_mac_inst[module_idP].common_num_sf_alloc,num_sf_alloc, commonSF_AllocPeriod,common_mbsfn_period,num_non_mbsfn_SubframeConfig,ones); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period-(1+ones)*(commonSF_AllocPeriod/4)); //TODO + } + else + mtch_mcs = -1; + + mch_lcid = (uint8_t)l; + break; + } + } + } +#endif + +{ + // Acount for sf_allocable in Common SF Allocation + int num_sf_alloc = 0; + + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + continue; + + //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset; + long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod; + long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + + + num_sf_alloc =10*commonSF_AllocPeriod/common_mbsfn_period; + num_sf_alloc -=1*((commonSF_AllocPeriod/common_mbsfn_period)/4); //CAS sfs + uint32_t num_non_mbsfn_SubframeConfig2 = (UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | UE_mac_inst[module_idP].non_mbsfn_SubframeConfig->subframeAllocation_r14.buf[0]>>7); + for (j = 0; j < 10; j++) + num_sf_alloc -= ((num_non_mbsfn_SubframeConfig2 & (0x200 >> j)) == (0x200 >> j))*((commonSF_AllocPeriod/common_mbsfn_period)/period); + + } + + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + continue; + + //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset; + long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod; + //long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + + + if(msi_flag==1 && UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){ + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%ld),common_num_sf_alloc(%d)\n",mbms_mch_i,frameP,subframe,num_sf_alloc,UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9, + UE_mac_inst[module_idP].common_num_sf_alloc); + UE_mac_inst[module_idP].msi_current_alloc = UE_mac_inst[module_idP].common_num_sf_alloc;//num_sf_alloc; + UE_mac_inst[module_idP].msi_pmch = mbms_mch_i; + }else if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){ + if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] >= UE_mac_inst[module_idP].common_num_sf_alloc/*num_sf_alloc*/) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] != 2047) { + mtch_flag = 1; + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL) + mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + else + mtch_mcs = -1; + mch_lcid = (uint8_t)mbms_mch_i; + LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs, + UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i],UE_mac_inst[module_idP].pmch_lcids[mbms_mch_i],UE_mac_inst[module_idP].msi_pmch); + } + } + } + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % ((num_sf_alloc-mbms_mch_i) /** commonSF_AllocPeriod *// common_mbsfn_period);//48; + + if(mtch_flag) + break; + } + if(msi_flag==1){ + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %(4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 <mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){ + msi_flag=0; + LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframe, mbms_mch_i); + } + } + } +} + + // sf allocation is non-overlapping + if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", + module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag); + *sync_area=i; + } + + //if(msi_flag == 1) + // if((num_msi_per_CSA[mbms_mch_i]--)==0){ + // LOG_E(MAC,"Both MSI and MTCH Should be reset?\n"); + // msi_flag=mtch_flag=0; + //} + + + if ((mcch_flag == 1)) { // || (msi_flag==1)) + *mcch_active = 1; + } + + if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ) { + if (msi_flag!=1) { + for (i=0; i<8; i++) + UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = NULL; + + for (i=0; i<15; i++) + UE_mac_inst[module_idP].pmch_Config[i] = NULL; + + for (i=0; i<28 ; i++) { + UE_mac_inst[module_idP].pmch_lcids[i] = -1; + UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; + UE_mac_inst[module_idP].msi_status_v[i] = 0; + } + } else { + for (i=0; i<28; i++) { + UE_mac_inst[module_idP].pmch_lcids[i] = -1; + UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; + UE_mac_inst[module_idP].msi_status_v[i] = 0; + } + } + + return mcch_mcs; + } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status_v[(mch_lcid > 27) ? 27 : mch_lcid] == 1)) { + return mtch_mcs; + } else { + return -1; + } + + + + // if(mcch_flag == 1 || msi_flag == 1 ){ + // *mcch_active = 1; + // return (mcch_mcs); + // }else if(mtch_flag == 1){ + // mtch_mcs=-1; + // return (mtch_mcs); + // } + + // return -1; + +} + + int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid) { int i, j, mtch_mcs = -1; int mtch_flag = 0; @@ -1100,6 +1558,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i return mtch_mcs; } + int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) { int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1; int l =0; @@ -1162,6 +1621,11 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ ii = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80 >> msi_pos); msi_pos++; } + if(msi_pos == subframe){ + UE_mac_inst[module_idP].common_num_sf_alloc=0; + mbms_mch_i=0; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } } } @@ -1170,6 +1634,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ case 1: if (UE_mac_inst[module_idP].tdd_Config == NULL) { if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=1; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 1) { msi_flag = 1; } @@ -1188,6 +1660,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ case 2: if (UE_mac_inst[module_idP].tdd_Config == NULL) { if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=2; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 2) { msi_flag = 1; } @@ -1219,6 +1699,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ } } else { // FDD if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=3; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 3) { msi_flag = 1; } @@ -1255,6 +1743,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ case 6: if (UE_mac_inst[module_idP].tdd_Config == NULL) { if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=6; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 4) { msi_flag = 1; } @@ -1286,6 +1782,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ } } else { // FDD if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=5; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } + if (msi_pos == 5) { msi_flag = 1; } @@ -1317,6 +1821,13 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ } } else { // FDD if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { + if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i+1]!=NULL){ + if( UE_mac_inst[module_idP].common_num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9){ + msi_pos=6; + mbms_mch_i++; + LOG_D(MAC,"MSP, frameP %d subframeP %d msi_pos(%d) mbms_mch_i %d\n",frameP, subframe, msi_pos,mbms_mch_i); + } + } if (msi_pos == 6) { msi_flag = 1; } @@ -1351,6 +1862,14 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ break; }// end switch + if( (msi_flag == 1) || (mcch_flag == 1) || (mtch_flag == 1) ){ + UE_mac_inst[module_idP].common_num_sf_alloc++; + //if( (msi_flag!=1 && mcch_flag!=1) || (msi_flag!=1 && mcch_flag!=1 && mtch_flag!=1) ){ + //UE_mac_inst[module_idP].common_num_sf_alloc++; + //} + } + +#ifdef OLD // Acount for sf_allocable in CSA int num_sf_alloc = 0; @@ -1392,11 +1911,86 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ } } } +#endif + +{ + // Acount for sf_allocable in Common SF Allocation + int num_sf_alloc = 0; + + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + continue; + + //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset; + //long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod; + //long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + + uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0]; + + for (j = 0; j < 6; j++) + num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j)); + } + + + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + continue; + + //int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationOffset; + long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->radioframeAllocationPeriod; + long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; + + + if(msi_flag==1 && UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){ + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%ld),common_num_sf_alloc(%d)\n",mbms_mch_i,frameP,subframe,num_sf_alloc,UE_mac_inst[module_idP].pmch_Config[mbms_mch_i]->sf_AllocEnd_r9, + UE_mac_inst[module_idP].common_num_sf_alloc); + UE_mac_inst[module_idP].msi_current_alloc = UE_mac_inst[module_idP].common_num_sf_alloc;//num_sf_alloc; + UE_mac_inst[module_idP].msi_pmch = mbms_mch_i; + }else if(UE_mac_inst[module_idP].pmch_Config[mbms_mch_i] != NULL){ + if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] >= UE_mac_inst[module_idP].common_num_sf_alloc/*num_sf_alloc*/) { + if (UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i] != 2047) { + mtch_flag = 1; + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL) + mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; + else + mtch_mcs = -1; + mch_lcid = (uint8_t)mbms_mch_i; + LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs, + UE_mac_inst[module_idP].pmch_stop_mtch[mbms_mch_i],UE_mac_inst[module_idP].pmch_lcids[mbms_mch_i],UE_mac_inst[module_idP].msi_pmch); + } + } + } + //LOG_D(MAC,"UE_mac_inst[module_idP].common_num_sf_alloc: %d num_sf_alloc %d mbms_mch_i %d commonSF_AllocPeriod %d common_mbsfn_period %d\n",UE_mac_inst[module_idP].common_num_sf_alloc,num_sf_alloc,mbms_mch_i,commonSF_AllocPeriod,common_mbsfn_period); + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % ((num_sf_alloc* commonSF_AllocPeriod-mbms_mch_i) / common_mbsfn_period);//48; + + + if(mtch_flag) + break; + } + if(msi_flag==1){ + for (l = 0; l < 8; l++) { + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL) + continue; + + if ( (/*AJ*/ (/*V*/ ( /*U*/ (frameP %(4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9)) ) / 8 ) % ((8 <mch_SchedulingPeriod_r9) / 8 ) ) != 0 ){ + msi_flag=0; + LOG_D(MAC,"frameP %d subframeP %d reset(%d)\n",frameP, subframe, mbms_mch_i); + } + } + } + +} // sf allocation is non-overlapping if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { - LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", - module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag); + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d x %d\n", + module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag,UE_mac_inst[module_idP].common_num_sf_alloc); *sync_area=i; break; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 6c23332687..7286aad455 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -308,7 +308,7 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p ctxt.module_id, ctxt.rnti, ctxt.enb_flag); if (h_rc == HASH_TABLE_OK) { - LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", ctxt.frame, ctxt.instance, len, rab_id); LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, -- GitLab From 6db9fca1b77aa2dd8972d24e2c7370a021522c3a Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Tue, 21 Jul 2020 21:07:42 +0200 Subject: [PATCH 19/34] fembms: code cleanup Signed-off-by: Javier Morgade --- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 2 +- openair2/LAYER2/MAC/ue_procedures.c | 6 +- openair2/M2AP/m2ap_MCE_interface_management.c | 143 ++++++++++++- openair2/M2AP/m2ap_MCE_interface_management.h | 10 +- openair2/M2AP/m2ap_eNB.c | 18 ++ openair2/M2AP/m2ap_eNB_interface_management.c | 198 +++++++++++++++++- openair2/MCE_APP/mce_app.c | 5 +- 7 files changed, 351 insertions(+), 31 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index cb90419d43..0c686a6475 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -921,7 +921,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, ((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = 0xFF; msi_pmch_stop=0; } - LOG_I(MAC,"frameP %d, subframeP %d LCID %ld rlc_status.bytes_in_buffer %d stop_sf_LSB %d stop_sf_MSB %d msi_pmch_stop %d sf_AllocEnd_r9 %ld, msi_length %d\n",frameP,subframeP,((MSI_ELEMENT *) msi_ptr)->lcid,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB, msi_pmch_stop,cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9, msi_length); + LOG_I(MAC,"frameP %d, subframeP %d LCID %d rlc_status.bytes_in_buffer %d stop_sf_LSB %d stop_sf_MSB %d msi_pmch_stop %d sf_AllocEnd_r9 %ld, msi_length %d\n",frameP,subframeP,((MSI_ELEMENT *) msi_ptr)->lcid,rlc_status.bytes_in_buffer,((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB,((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB, msi_pmch_stop,cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9, msi_length); } memcpy((char*)buffer_pointer, diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 54d9f687e1..f81c66e269 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -74,7 +74,7 @@ extern module_id_t next_Mod_id; int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; static int mbms_mch_i=0; -static int num_msi_per_CSA[28]; +//static int num_msi_per_CSA[28]; /* @@ -995,14 +995,14 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra //static int common_num_sf_alloc=0; //static int x=0; int ue_query_mch_fembms(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) { - int i = 0, j = 0,/* ii = 0,*/ msi_pos = -1, mcch_mcs = -1, mtch_mcs = -1, l=0,ii=0; + int i = 0, j = 0,/* ii = 0,*/ msi_pos = -1, mcch_mcs = -1, mtch_mcs = -1, l=0/*,ii=0*/; int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; int alloc_offset=0; uint32_t period; //uint16_t num_non_mbsfn_SubframeConfig=0; long mch_scheduling_period = -1; uint8_t mch_lcid = 0; - int first_pos=0; + //int first_pos=0; if(UE_mac_inst[module_idP].non_mbsfn_SubframeConfig == NULL ) return -1; diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c index 1bef834179..e162c9a5de 100644 --- a/openair2/M2AP/m2ap_MCE_interface_management.c +++ b/openair2/M2AP/m2ap_MCE_interface_management.c @@ -521,6 +521,7 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i mbsfn_subframe_configuration->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period; mbsfn_subframe_configuration->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset; if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){ + LOG_I(M2AP,"is_four_sf\n"); mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames; mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(3); mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF); @@ -530,6 +531,7 @@ int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance, /*uint32_t assoc_i mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.bits_unused = 0; }else{ + LOG_I(M2AP,"is_one_sf\n"); mbsfn_subframe_configuration->subframeAllocation.present = M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_oneFrame; mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.buf = MALLOC(1); mbsfn_subframe_configuration->subframeAllocation.choice.oneFrame.size = 1; @@ -1357,11 +1359,10 @@ int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, -int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M2AP_M2AP_PDU_t *pdu){ +int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,module_id_t du_mod_idP){ + AssertFatal(1==0,"Not implemented yet\n"); + } /* @@ -1378,16 +1379,138 @@ int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, M2AP_M2AP_PDU_t *pdu){ - AssertFatal(1==0,"Not implemented yet\n"); + //int i; + //AssertFatal(1==0,"Not implemented yet\n"); + LOG_D(M2AP, "MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE\n"); + + AssertFatal(pdu->present == M2AP_M2AP_PDU_PR_successfulOutcome, + "pdu->present != M2AP_M2AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome.procedureCode == M2AP_ProcedureCode_id_mbmsServiceCounting, + "pdu->choice.successfulOutcome->procedureCode != M2AP_ProcedureCode_id_mbmsServiceCounting\n"); + AssertFatal(pdu->choice.successfulOutcome.criticality == M2AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != M2AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome.value.present == M2AP_SuccessfulOutcome__value_PR_MbmsServiceCountingResponse, + "pdu->choice.successfulOutcome.value.present != M2AP_SuccessfulOutcome__value_PR_MbmsServiceCountingResponse\n"); + + + M2AP_MbmsServiceCountingResponse_t *in = &pdu->choice.successfulOutcome.value.choice.MbmsServiceCountingResponse; + //M2AP_MbmsServiceCountingResponse_Ies_t *ie; + //int MCE_MBMS_M2AP_ID=-1; + //int ENB_MBMS_M2AP_ID=-1; + + + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SERVICE_COUNTING_RESP); //TODO + + LOG_D(M2AP, "M2AP: MbmsServiceCounting-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + //ie = in->protocolIEs.list.array[i]; + // switch (ie->id) { + // case M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID: + // AssertFatal(ie->criticality == M2AP_Criticality_reject, + // "ie->criticality != M2AP_Criticality_reject\n"); + // AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_MCE_MBMS_M2AP_ID, + // "ie->value.present != M2AP_sessionStartResponse_IEs__value_PR_MCE_MBMS_M2AP_ID\n"); + // MCE_MBMS_M2AP_ID=ie->value.choice.MCE_MBMS_M2AP_ID; + // LOG_D(M2AP, "M2AP: SessionStart-Resp: MCE_MBMS_M2AP_ID %d\n", + // MCE_MBMS_M2AP_ID); + // break; + // case M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID: + // AssertFatal(ie->criticality == M2AP_Criticality_reject, + // "ie->criticality != M2AP_Criticality_reject\n"); + // AssertFatal(ie->value.present == M2AP_SessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID, + // "ie->value.present != M2AP_sessionStartResponse_Ies__value_PR_ENB_MBMS_M2AP_ID\n"); + // ENB_MBMS_M2AP_ID=ie->value.choice.ENB_MBMS_M2AP_ID; + // LOG_D(M2AP, "M2AP: SessionStart-Resp: ENB_MBMS_M2AP_ID %d\n", + // ENB_MBMS_M2AP_ID); + // break; + // } + } + + //AssertFatal(MCE_MBMS_M2AP_ID!=-1,"MCE_MBMS_M2AP_ID was not sent\n"); + //AssertFatal(ENB_MBMS_M2AP_ID!=-1,"ENB_MBMS_M2AP_ID was not sent\n"); + //M2AP_SESSION_START_RESP(msg_p). +// MSC_LOG_RX_MESSAGE( +// MSC_M2AP_MCE, +// MSC_M2AP_ENB, + //return 0; +// 0, +// 0, +// MSC_AS_TIME_FMT" MCE_handle_M2_SESSION_START_RESPONSE successfulOutcome assoc_id %d", +// 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), +// assoc_id); +// + //LOG_D(M2AP, "Sending ITTI message to ENB_APP with assoc_id (%d->%d)\n", + //assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); + + itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_g); + return 0; + } -int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M2AP_M2AP_PDU_t *pdu){ - AssertFatal(1==0,"Not implemented yet\n"); +int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, module_id_t du_mod_idP){ + + M2AP_M2AP_PDU_t pdu; + M2AP_MbmsServiceCountingRequest_t *out; + M2AP_MbmsServiceCountingRequest_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i=0; + //int j=0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCounting; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsServiceCountingRequest; + out = &pdu.choice.initiatingMessage.value.choice.MbmsServiceCountingRequest; + + /* mandatory */ + /* c1. MCCH_Update_Time */ //long + ie=(M2AP_MbmsServiceCountingRequest_Ies_t *)calloc(1,sizeof(M2AP_MbmsSchedulingInformation_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCCH_Update_Time; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingRequest_Ies__value_PR_MCCH_Update_Time; + //ie->value.choice.MCCH_Update_Time = ; + //ie->value.choice.MCCH_Update_Time = m2ap_mbms_scheduling_information->mcch_update_time; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_MbmsServiceCountingRequest_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingRequest_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBSFN_Area_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. TMGI (integrer value) */ + ie = (M2AP_MbmsServiceCountingRequest_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingRequest_Ies_t )); + ie->id = M2AP_ProtocolIE_ID_id_MBMS_Counting_Request_Session; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBMS_Counting_Request_Session; + + //M2AP_MBMS_Counting_Request_Session_t * m2ap_mbms_counting_request_session = &ie->value.choice.MBMS_Counting_Request_Session; + + //&ie->choice.TMGI.pLMN_Identity); + //INT16_TO_OCTET_STRING(0,&ie->choice.TMGI.serviceId); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n"); + return -1; + } + + return 0; } diff --git a/openair2/M2AP/m2ap_MCE_interface_management.h b/openair2/M2AP/m2ap_MCE_interface_management.h index 6b899e9ea2..2b1d5824af 100644 --- a/openair2/M2AP/m2ap_MCE_interface_management.h +++ b/openair2/M2AP/m2ap_MCE_interface_management.h @@ -150,10 +150,7 @@ int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, uint32_t stream, M2AP_M2AP_PDU_t *pdu); -int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M2AP_M2AP_PDU_t *pdu); +int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,module_id_t du_mod_idP); /* * Service Counting Request @@ -165,10 +162,7 @@ int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance, uint32_t stream, M2AP_M2AP_PDU_t *pdu); -int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - M2AP_M2AP_PDU_t *pdu); +int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance, module_id_t du_mod_idP); /* * Service Counting Results Report */ diff --git a/openair2/M2AP/m2ap_eNB.c b/openair2/M2AP/m2ap_eNB.c index 206b7cf8ca..39c769a43d 100644 --- a/openair2/M2AP/m2ap_eNB.c +++ b/openair2/M2AP/m2ap_eNB.c @@ -142,6 +142,22 @@ void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->ulp_cnx_id); //m2ap_handle_m2_setup_message(instance_p, m2ap_enb_data_p, // sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + + sleep(4); + int index; + /* Trying to connect to the provided list of eNB ip address */ + for (index = 0; index < instance_p->nb_m2; index++) { + //M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n", + // instance_id, instance->eNB_id); + m2ap_eNB_register_eNB(instance_p, + &instance_p->target_mce_m2_ip_address[index], + &instance_p->enb_m2_ip_address, + instance_p->sctp_in_streams, + instance_p->sctp_out_streams, + instance_p->enb_port_for_M2C, + instance_p->multi_sd); + } + return; } @@ -304,6 +320,8 @@ void m2ap_eNB_handle_register_eNB(instance_t instance, DevCheck(new_instance->mcc == m2ap_register_eNB->mcc, new_instance->mcc, m2ap_register_eNB->mcc, 0); DevCheck(new_instance->mnc == m2ap_register_eNB->mnc, new_instance->mnc, m2ap_register_eNB->mnc, 0); M2AP_WARN("eNB[%d] already registered\n", instance); + + } else { new_instance = calloc(1, sizeof(m2ap_eNB_instance_t)); DevAssert(new_instance != NULL); diff --git a/openair2/M2AP/m2ap_eNB_interface_management.c b/openair2/M2AP/m2ap_eNB_interface_management.c index 95b8372025..9649d919c3 100644 --- a/openair2/M2AP/m2ap_eNB_interface_management.c +++ b/openair2/M2AP/m2ap_eNB_interface_management.c @@ -163,8 +163,12 @@ int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance, M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period = m2ap_mbsfn_sf_configuration->radioframeAllocationPeriod; M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset = m2ap_mbsfn_sf_configuration->radioframeAllocationOffset; if( m2ap_mbsfn_sf_configuration->subframeAllocation.present == M2AP_MBSFN_Subframe_Configuration__subframeAllocation_PR_fourFrames ) { + LOG_I(RRC,"is_four_sf\n"); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf = 1; M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[1]<<8) | (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0]<<16); }else{ + LOG_I(RRC,"is_one_sf\n"); + M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf = 0; M2AP_MBMS_SCHEDULING_INFORMATION(message_p).mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation = (m2ap_mbsfn_sf_configuration->subframeAllocation.choice.oneFrame.buf[0] >> 2) & 0x3F; } } @@ -1262,46 +1266,226 @@ int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance, uint32_t stream, M2AP_M2AP_PDU_t *pdu) { - LOG_D(M2AP, "eNB_handle_MBMS_SERVICE_COUNTING_REQUEST assoc_id %d\n",assoc_id); - MessageDef *message_p; + LOG_D(M2AP, "eNB_handle_MBMS_SERVICE_COUNTING_REQUEST assoc_id %d\n",assoc_id); + + //MessageDef *message_p; //M2AP_MbmsServiceCountingRequest_t *container; //M2AP_MbmsServiceCountingRequest_Ies_t *ie; + M2AP_MbmsServiceCountingRequest_t *in; + M2AP_MbmsServiceCountingRequest_Ies_t *ie; //int i = 0; + int j; DevAssert(pdu != NULL); // container = &pdu->choice.initiatingMessage.value.choice.MbmsServiceCountingRequest; + in = &pdu->choice.initiatingMessage.value.choice.MbmsServiceCountingRequest; /* M2 Setup Request == Non UE-related procedure -> stream 0 */ if (stream != 0) { - LOG_D(M2AP, "[SCTP %d] Received MMBS session start request on stream != 0 (%d)\n", + LOG_D(M2AP, "[SCTP %d] Received MMBS service Counting Request on stream != 0 (%d)\n", assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ); + for (j=0;j < in->protocolIEs.list.count; j++) { + ie = in->protocolIEs.list.array[j]; + switch (ie->id) { + case M2AP_ProtocolIE_ID_id_MCCH_Update_Time: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_MbmsServiceCountingRequest_Ies__value_PR_MCCH_Update_Time, + "ie->value.present != M2AP_MbmsServiceCountingRequest_Ies__value_PR_MCCH_Update_Time\n"); + LOG_D(M2AP, "M2AP: : MCCH_Update_Time \n"); + break; + case M2AP_ProtocolIE_ID_id_MBSFN_Area_ID: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBSFN_Area_ID, + "ie->value.present != M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBSFN_Area_ID\n"); + LOG_D(M2AP, "M2AP: : MBSFN_Area_ID \n"); + break; + case M2AP_ProtocolIE_ID_id_MBMS_Counting_Request_Session: + AssertFatal(ie->criticality == M2AP_Criticality_reject, + "ie->criticality != M2AP_Criticality_reject\n"); + AssertFatal(ie->value.present == M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBMS_Counting_Request_Session, + "ie->value.present != M2AP_MbmsServiceCountingRequest_Ies__value_PR_MBMS_Counting_Request_Session\n"); + LOG_D(M2AP, "M2AP: : MBMS_Counting_Request_Session \n"); + //ie->value.choice.MBMS_Counting_Request_Session.list.count; - itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + break; + + } + } + //message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ); + return 0; } int eNB_send_MBMS_SERVICE_COUNTING_REPORT(instance_t instance, m2ap_mbms_service_counting_report_t * m2ap_mbms_service_counting_report) { - AssertFatal(1==0,"Not implemented yet\n"); + M2AP_M2AP_PDU_t pdu; + M2AP_MbmsServiceCountingResultsReport_t *out; + M2AP_MbmsServiceCountingResultsReport_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + // + // memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCountingResultsReport; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsServiceCountingResultsReport; + out = &pdu.choice.initiatingMessage.value.choice.MbmsServiceCountingResultsReport; + + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCountingResultsReport; + pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_MbmsServiceCountingResultsReport; + out = &pdu.choice.initiatingMessage.value.choice.MbmsServiceCountingResultsReport; + + /* mandatory */ + /* c1. MBSFN_Area_ID (integer value) */ //long + ie = (M2AP_MbmsServiceCountingResultsReport_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingResultsReport_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MBSFN_Area_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingResultsReport_Ies__value_PR_MBSFN_Area_ID; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c1. MBSFN_Area_ID (integer value) */ //long + ie = (M2AP_MbmsServiceCountingResultsReport_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingResultsReport_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MBMS_Counting_Result_List; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingResultsReport_Ies__value_PR_MBMS_Counting_Result_List; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + M2AP_MBMS_Counting_Result_List_t * m2ap_mbms_counting_result_list = &ie->value.choice.MBMS_Counting_Result_List; + + M2AP_MBMS_Counting_Result_Item_t * m2ap_mbms_counting_result_item = (M2AP_MBMS_Counting_Result_Item_t*)calloc(1,sizeof(M2AP_MBMS_Counting_Result_Item_t)); + m2ap_mbms_counting_result_item->id = M2AP_ProtocolIE_ID_id_MBMS_Counting_Result_Item; + m2ap_mbms_counting_result_item->criticality = M2AP_Criticality_reject; + m2ap_mbms_counting_result_item->value.present = M2AP_MBMS_Counting_Result_Item__value_PR_MBMS_Counting_Result; + M2AP_MBMS_Counting_Result_t * m2ap_mbms_counting_result = &m2ap_mbms_counting_result_item->value.choice.MBMS_Counting_Result; + + M2AP_TMGI_t * tmgi = &m2ap_mbms_counting_result->tmgi; + MCC_MNC_TO_PLMNID(0,0,3,&tmgi->pLMNidentity);/*instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,*/ + uint8_t TMGI[5] = {4,3,2,1,0}; + OCTET_STRING_fromBuf(&tmgi->serviceID,(const char*)&TMGI[2],3); + + //M2AP_CountingResult_t * m2ap_counting_result = &m2ap_mbms_counting_result->countingResult; + + ASN_SEQUENCE_ADD(&m2ap_mbms_counting_result_list->list,m2ap_mbms_counting_result_item); + + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n"); + return -1; + } return 0; } + int eNB_send_MBMS_SERVICE_COUNTING_RESP(instance_t instance, m2ap_mbms_service_counting_resp_t * m2ap_mbms_service_counting_resp) { AssertFatal(1==0,"Not implemented yet\n"); + M2AP_M2AP_PDU_t pdu; + M2AP_MbmsServiceCountingResponse_t *out; + M2AP_MbmsServiceCountingResponse_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCounting; + pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_MbmsServiceCountingResponse; + out = &pdu.choice.successfulOutcome.value.choice.MbmsServiceCountingResponse; + + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_MbmsServiceCountingResponse_Ies_t*)calloc(1, sizeof(M2AP_MbmsServiceCountingResponse_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_MCE_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingResponse_Ies__value_PR_CriticalityDiagnostics; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n"); + return -1; + } + + return 0; return 0; } + int eNB_send_MBMS_SERVICE_COUNTING_FAILURE(instance_t instance, m2ap_mbms_service_counting_failure_t * m2ap_mbms_service_counting_failure) { - AssertFatal(1==0,"Not implemented yet\n"); + M2AP_M2AP_PDU_t pdu; + M2AP_MbmsServiceCountingFailure_t *out; + M2AP_MbmsServiceCountingFailure_Ies_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome; + //pdu.choice.successfulOutcome = (M2AP_SuccessfulOutcome_t *)calloc(1, sizeof(M2AP_SuccessfulOutcome_t)); + pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_mbmsServiceCounting; + pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_MbmsServiceCountingFailure; + out = &pdu.choice.unsuccessfulOutcome.value.choice.MbmsServiceCountingFailure; + + + /* mandatory */ + /* c1. MCE_MBMS_M2AP_ID (integer value) */ //long + ie = (M2AP_MbmsServiceCountingFailure_Ies_t*)calloc(1, sizeof(M2AP_MbmsServiceCountingFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_M2AP_ID; + ie->criticality = M2AP_Criticality_reject; + ie->value.present = M2AP_MbmsServiceCountingFailure_Ies__value_PR_CriticalityDiagnostics; + //ie->value.choice.MCE_MBMS_M2AP_ID = /*F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);*/ //? + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. Cause */ + ie = (M2AP_MbmsServiceCountingFailure_Ies_t *)calloc(1, sizeof(M2AP_MbmsServiceCountingFailure_Ies_t)); + ie->id = M2AP_ProtocolIE_ID_id_Cause; + ie->criticality = M2AP_Criticality_ignore; + ie->value.present = M2AP_MbmsServiceCountingFailure_Ies__value_PR_Cause; + ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_unspecified; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(M2AP, "Failed to encode MBMS Service Counting Results Report\n"); + return -1; + } + + return 0; } diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c index 6f7454c321..817c863f7b 100644 --- a/openair2/MCE_APP/mce_app.c +++ b/openair2/MCE_APP/mce_app.c @@ -372,7 +372,8 @@ void *MCE_app_task(void *args_p) { // /* Try to register each MCE with MCE each other */ if (is_m3ap_MCE_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) { - ///*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end); + ///*m3_register_mce_pending =*/ + MCE_app_register_m3 (mce_id_start, mce_id_end); } do { @@ -627,7 +628,7 @@ void *MCE_app_task(void *args_p) { //} - /*m3_register_mce_pending =*/ MCE_app_register_m3 (mce_id_start, mce_id_end); + /*m3_register_mce_pending =*/ //MCE_app_register_m3 (mce_id_start, mce_id_end); //MCE_app_send_m2ap_session_start_req(0); break; -- GitLab From 9e789c84be0cd6576a32215ab53039fe0b92de7c Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Wed, 22 Jul 2020 07:34:09 +0200 Subject: [PATCH 20/34] fembms: - added suppor for FeMBMS RRC sublayer / l2 interface - added primitives to build asn1 messages for FeMBMS eNB Signed-off-by: Javier Morgade --- openair2/RRC/LTE/L2_interface.c | 57 +++++++++++++++++++++++++++- openair2/RRC/LTE/L2_interface_ue.c | 17 ++++++++- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 40 +++++++++++++------ 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 68017be85b..3917b4b5a8 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -28,6 +28,15 @@ * \email: raymond.knopp@eurecom.fr */ +/*! \file l2_interface.c + * \brief layer 2 interface, added support for FeMBMS RRC sublayer + * \author J. Morgade + * \date 2020 + * \version 1.0 + * \email: javier.morgade@ieee.org + */ + + #include "platform_types.h" #include "rrc_defs.h" #include "rrc_extern.h" @@ -65,6 +74,9 @@ mac_rrc_data_req( uint8_t Sdu_size = 0; uint8_t sfn = (uint8_t)((frameP>>2)&0xff); + uint8_t sfn_fembms = (uint8_t)((frameP>>4)&0xff); + sfn_fembms = sfn_fembms<<2; + if (LOG_DEBUGFLAG(DEBUG_RRC)) { LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); } @@ -72,12 +84,14 @@ mac_rrc_data_req( eNB_RRC_INST *rrc; rrc_eNB_carrier_data_t *carrier; LTE_BCCH_BCH_Message_t *mib; + LTE_BCCH_BCH_Message_MBMS_t *mib_fembms; rrc = RC.rrc[Mod_idP]; carrier = &rrc->carrier[0]; mib = &carrier->mib; + mib_fembms = &carrier->mib_fembms; if((Srb_id & RAB_OFFSET) == BCCH_SI_MBMS){ - if (frameP%4 == 0) { + if (frameP%8 == 0) { memcpy(&buffer_pP[0], RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS, RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS); @@ -159,6 +173,22 @@ mac_rrc_data_req( return(3); } + if( (Srb_id & RAB_OFFSET ) == MIBCH_MBMS) { + mib_fembms->message.systemFrameNumber_r14.buf = &sfn_fembms; + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message_MBMS, + NULL, + (void *)mib_fembms, + carrier->MIB_FeMBMS, + 24); + LOG_I(RRC,"Encoded MIB MBMS for frame %d (%p), bits %lu %x,%x,%x %x bits_unused %d\n",sfn_fembms>>2,carrier->MIB_FeMBMS,enc_rval.encoded,carrier->MIB_FeMBMS[0],carrier->MIB_FeMBMS[1],carrier->MIB_FeMBMS[2],mib_fembms->message.systemFrameNumber_r14.buf[0],mib_fembms->message.systemFrameNumber_r14.bits_unused); + buffer_pP[0]=carrier->MIB_FeMBMS[0]; + buffer_pP[1]=carrier->MIB_FeMBMS[1]; + buffer_pP[2]=carrier->MIB_FeMBMS[2]; + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return(3); + } + if( (Srb_id & RAB_OFFSET ) == CCCH) { struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti); @@ -203,6 +233,8 @@ mac_rrc_data_req( RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); + LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); + if (LOG_DEBUGFLAG(DEBUG_RRC)) { LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); @@ -216,6 +248,29 @@ mac_rrc_data_req( return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); } + if((Srb_id & RAB_OFFSET) == MCCH_COUNTING) { + if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS_COUNTING[mbsfn_sync_area].Active==0) { + return 0; // this parameter is set in function init_mcch in rrc_eNB.c + } + + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[mbsfn_sync_area], + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[mbsfn_sync_area]); + + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE_COUNTING \n",Mod_idP,frameP); + + for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[mbsfn_sync_area]; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); + } + + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ + + return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[mbsfn_sync_area]); + } + + if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR) { memcpy(&buffer_pP[0], RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR, diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 61ab63955d..c413df49bb 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file l2_interface.c +/*! \file l2_interface_ue.c * \brief layer 2 interface, used to support different RRC sublayer * \author Raymond Knopp and Navid Nikaein * \date 2010-2014 @@ -28,6 +28,16 @@ * \email: raymond.knopp@eurecom.fr */ + +/*! \file l2_interface_ue.c + * \brief layer 2 interface, added support for FeMBMS RRC sublayer + * \author J. Morgade + * \date 2020 + * \version 1.0 + * \email: javier.morgade@ieee.org + */ + + #include "platform_types.h" #include "rrc_defs.h" #include "rrc_extern.h" @@ -217,7 +227,10 @@ mac_rrc_data_ind_ue( } if ((srb_idP & RAB_OFFSET) == MCCH) { - LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", + //LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", + //module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); + + LOG_W(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); { MessageDef *message_p; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 583e10da94..5c5a5575fe 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -28,6 +28,14 @@ * \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr */ +/*! \file asn1_msg.c + * \brief added primitives to build the asn1 messages for FeMBMS + * \author Javier Morgade + * \date 2019-2020 + * \version 1.0 + * \email: javier.morgade@ieee.org + */ + #include #include #include /* for atoi(3) */ @@ -185,7 +193,8 @@ uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) { uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFN, uint32_t frame) { asn_enc_rval_t enc_rval; LTE_BCCH_BCH_Message_MBMS_t *mib_fembms=&carrier->mib_fembms; - uint8_t sfn = (uint8_t)((frame>>2)&0xff); + frame=198; + uint8_t sfn = (uint8_t)((frame>>4)&0xff); uint16_t *spare = calloc(1,sizeof(uint16_t)); if( spare == NULL ) abort(); @@ -223,15 +232,16 @@ uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_ (uint32_t)mib_fembms->message.dl_Bandwidth_MBMS_r14, (uint32_t)additionalNonMBSFN, (uint32_t)sfn); + sfn = sfn<<2; mib_fembms->message.systemFrameNumber_r14.buf = &sfn; mib_fembms->message.systemFrameNumber_r14.size = 1; - mib_fembms->message.systemFrameNumber_r14.bits_unused=0; + mib_fembms->message.systemFrameNumber_r14.bits_unused=2; mib_fembms->message.spare.buf = (uint8_t *)spare; mib_fembms->message.spare.size = 2; - mib_fembms->message.spare.bits_unused = 6; // This makes a spare of 10 bits + mib_fembms->message.spare.bits_unused = 3; // This makes a spare of 10 bits //TODO additionalNonBMSFNSubframes-r14 INTEGER (0..3) ? //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - //xer_fprint(stdout, &asn_DEF_LTE_BCCH_BCH_Message_MBMS, (void *)mib_fembms); + xer_fprint(stdout, &asn_DEF_LTE_BCCH_BCH_Message_MBMS, (void *)mib_fembms); //} enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message_MBMS, NULL, @@ -387,7 +397,11 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, // SystemInformation_t systemInformation; int num_plmn = configuration->num_plmn; - LTE_PLMN_IdentityInfo_t *PLMN_identity_info; + //LTE_PLMN_IdentityInfo_t *PLMN_identity_info; + LTE_PLMN_IdentityInfo_t * PLMN_identity_info = &carrier->PLMN_identity_info_MBMS[0]; + //LTE_MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; + //LTE_MCC_MNC_Digit_t *dummy_mcc = &carrier->dummy_mcc_MBMS[0][0]; + //LTE_MCC_MNC_Digit_t *dummy_mnc = &carrier->dummy_mnc_MBMS[0][0]; LTE_MCC_MNC_Digit_t *dummy_mcc_0; LTE_MCC_MNC_Digit_t *dummy_mcc_1; LTE_MCC_MNC_Digit_t *dummy_mcc_2; @@ -395,7 +409,9 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, LTE_MCC_MNC_Digit_t *dummy_mnc_1; LTE_MCC_MNC_Digit_t *dummy_mnc_2; asn_enc_rval_t enc_rval; - LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo; + //LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo; + //LTE_SchedulingInfo_MBMS_r14_t schedulingInfo; + LTE_SchedulingInfo_MBMS_r14_t *schedulingInfo = &carrier->schedulingInfo_MBMS; LTE_SIB_Type_t *sib_type; uint8_t *buffer = carrier->SIB1_MBMS; LTE_BCCH_DL_SCH_Message_MBMS_t *bcch_message = &carrier->siblock1_MBMS; @@ -408,6 +424,8 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, // memcpy(&bcch_message.message.choice.c1.choice.systemInformationBlockType1,sib1,sizeof(SystemInformationBlockType1_t)); *sib1_MBMS = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14; PLMN_identity_info = CALLOC(1, sizeof(LTE_PLMN_IdentityInfo_t) * num_plmn); + //memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_MBMS_r14_t)); + memset(schedulingInfo,0,sizeof(LTE_SchedulingInfo_MBMS_r14_t)); if (PLMN_identity_info == NULL) exit(1); @@ -528,7 +546,7 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=0x20<<2; // FDD: SF1 MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; - MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n2; (MBSFN_Area1)->ext1 = CALLOC (1, sizeof(*(MBSFN_Area1)->ext1)); memset((MBSFN_Area1)->ext1,0,sizeof(*(MBSFN_Area1)->ext1)); MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14 = CALLOC(1,sizeof(*( MBSFN_Area1->ext1)->subcarrierSpacingMBMS_r14)); @@ -541,18 +559,18 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, if(1) { (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14 = CALLOC(1,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14)); memset((*sib1_MBMS)->nonMBSFN_SubframeConfig_r14,0,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14)); - (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14 = LTE_NonMBSFN_SubframeConfig_r14__radioFrameAllocationPeriod_r14_rf8; + (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14 = LTE_NonMBSFN_SubframeConfig_r14__radioFrameAllocationPeriod_r14_rf4; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->radioFrameAllocationOffset_r14 = 0; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf = MALLOC(2); //100000001 byte(0)=10000000 byte(1)=xxxxxxx1 - (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[0] = 0x80<<0; - (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[1] = 0x1<<7; + (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[0] = 0x8<<0; + (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf[1] = 0; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.size = 2; (*sib1_MBMS)->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.bits_unused = 7; } //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message); + xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message); //} enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, NULL, -- GitLab From 8f8b16a84ee2b15faec4ea13d72cfee640238ee2 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Wed, 22 Jul 2020 07:40:32 +0200 Subject: [PATCH 21/34] embms: Experimental MBMS Couting support added / 3GPP TS 36.44 (*) (*) The MBMS Counting function allows the MCE to request the eNB(s) to count and report per MBSFN area for one or more MBMS services the number of connected UEs receiving the MBMS Service or interested in receiving it. Signed-off-by: Javier Morgade --- openair2/RRC/LTE/L2_interface.c | 2 +- openair2/RRC/LTE/rrc_UE.c | 121 ++++++++- openair2/RRC/LTE/rrc_defs.h | 9 + openair2/RRC/LTE/rrc_eNB.c | 38 ++- openair2/RRC/LTE/rrc_eNB_M2AP.c | 459 ++++++++++++++++++++++++++++++-- openair3/M3AP/m3ap_MCE.c | 14 + targets/RT/USER/lte-softmodem.c | 5 +- 7 files changed, 606 insertions(+), 42 deletions(-) diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 3917b4b5a8..fe1cbd32ef 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -30,7 +30,7 @@ /*! \file l2_interface.c * \brief layer 2 interface, added support for FeMBMS RRC sublayer - * \author J. Morgade + * \author Javier Morgade * \date 2020 * \version 1.0 * \email: javier.morgade@ieee.org diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 4116f5367e..5955c2221c 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -150,14 +150,19 @@ static uint8_t check_trigger_meas_event( LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt); static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); +static void decode_MBMSCountingRequest(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); + uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); - - - - - +void +rrc_ue_process_MBMSCountingRequest( + const protocol_ctxt_t *const ctxt_pP, + LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest, + uint8_t eNB_index + ); + +protocol_ctxt_t ctxt_pP_local; /*------------------------------------------------------------------------------*/ @@ -510,6 +515,7 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *c LOG_D(RLC, "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to eNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", ctxt_pP->frame, ctxt_pP->module_id+NB_eNB_INST, size, eNB_index, rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH); + ctxt_pP_local.rnti = ctxt_pP->rnti; rrc_data_req_ue ( ctxt_pP, DCCH, @@ -1561,6 +1567,65 @@ rrc_ue_process_securityModeCommand( securityModeCommand->criticalExtensions.present); } +void +rrc_ue_process_MBMSCountingRequest( + const protocol_ctxt_t *const ctxt_pP, + LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest, + uint8_t eNB_index +) +{ + asn_enc_rval_t enc_rval; + LTE_UL_DCCH_Message_t ul_dcch_msg; + struct LTE_CountingResponseInfo_r10 CountingResponse; + uint8_t buffer[200]; + //int i; + LOG_I(RRC,"[UE %d] Frame %d: Receiving from (MCCH), Processing MBMSCoutingRequest (eNB %d)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + eNB_index); + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); + memset((void *)&CountingResponse,0,sizeof(struct LTE_CountingResponseInfo_r10)); + + + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10; + LTE_MBMSCountingResponse_r10_t *MBMSCountingResponse = &ul_dcch_msg.message.choice.c1.choice.mbmsCountingResponse_r10; + + MBMSCountingResponse->criticalExtensions.present = LTE_MBMSCountingResponse_r10__criticalExtensions_PR_c1; + MBMSCountingResponse->criticalExtensions.choice.c1.present = LTE_MBMSCountingResponse_r10__criticalExtensions__c1_PR_countingResponse_r10; + LTE_MBMSCountingResponse_r10_IEs_t *MBMSCountingResponse_r10_IEs = &MBMSCountingResponse->criticalExtensions.choice.c1.choice.countingResponse_r10; + + MBMSCountingResponse_r10_IEs->mbsfn_AreaIndex_r10 = calloc(1,sizeof(long)); + // MBMSCountingResponse_r10_IEs->countingResponseList_r10 = calloc(1,sizeof(struct LTE_CountingResponseList_r10)); +// +// ASN_SEQUENCE_ADD( +// &MBMSCountingResponse->criticalExtensions.choice.c1.choice.countingResponse_r10.countingResponseList_r10.list, +// &CountingResponse); +// + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); + } + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); + + + LOG_I(RRC,"MBMSCountingResponse Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + rrc_data_req_ue ( + &ctxt_pP_local, + DCCH, + rrc_mui++, + SDU_CONFIRM_NO, + (enc_rval.encoded + 7) / 8, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + +} + + //----------------------------------------------------------------------------- void rrc_ue_process_ueCapabilityEnquiry( @@ -2178,8 +2243,8 @@ rrc_ue_decode_dcch( #endif } -const char siWindowLength[8][5] = {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","ERR"}; -const char siWindowLength_int[7] = {1,2,5,10,15,20,40}; +const char siWindowLength[9][5] = {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","80ms","ERR"}; +const char siWindowLength_int[8] = {1,2,5,10,15,20,40,80}; const char SIBType[12][6] = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","SIB10","SIB11","SIB12","SIB13","Spare"}; const char SIBPeriod[8][6]= {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"}; @@ -2689,7 +2754,7 @@ int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_in //LOG_I( RRC, "TDD subframeAssignment : %ld\n", sib1_MBMS->tdd_Config->subframeAssignment ); //LOG_I( RRC, "TDD specialSubframePatterns : %ld\n", sib1_MBMS->tdd_Config->specialSubframePatterns ); //} - LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1_MBMS->si_WindowLength_r14,7)] ); + LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1_MBMS->si_WindowLength_r14,8)] ); LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1_MBMS->systemInfoValueTag_r14 ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod_MBMS = siPeriod_int[sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[0]->si_Periodicity_r14]; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize_MBMS = siWindowLength_int[sib1_MBMS->si_WindowLength_r14]; @@ -2888,7 +2953,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LOG_I( RRC, "TDD specialSubframePatterns : %ld\n", sib1->tdd_Config->specialSubframePatterns ); } - LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_WindowLength,7)] ); + LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_WindowLength,8)] ); LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod = siPeriod_int[sib1->schedulingInfoList.list.array[0]->si_Periodicity]; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize = siWindowLength_int[sib1->si_WindowLength]; @@ -4205,12 +4270,12 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB asn_dec_rval_t dec_rval; if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] == 1) { - LOG_D(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n", + LOG_W(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n", ctxt_pP->module_id, ctxt_pP->frame, mbsfn_sync_area); return 0; // avoid decoding to prevent memory bloating - } else if(UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State >= RRC_CONNECTED /*|| UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_RECONFIGURED*/){ + } else if(1/*UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State >= RRC_CONNECTED*/ /*|| UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_RECONFIGURED*/){ dec_rval = uper_decode_complete(NULL, &asn_DEF_LTE_MCCH_Message, (void **)&mcch, @@ -4229,6 +4294,7 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_MCCH_Message, (void *)mcch); } + xer_fprint(stdout, &asn_DEF_LTE_MCCH_Message, (void *)mcch); if (mcch->message.present == LTE_MCCH_MessageType_PR_c1) { LOG_D(RRC,"[UE %d] Found mcch message \n", @@ -4250,7 +4316,29 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB ctxt_pP->frame, mbsfn_sync_area); } + }else if(mcch->message.present == LTE_MCCH_MessageType_PR_later){ + LOG_D(RRC,"[UE %d] Found mcch message \n", + ctxt_pP->module_id); + if(mcch->message.choice.later.present == LTE_MCCH_MessageType__later_PR_c2){ + if(mcch->message.choice.later.choice.c2.present == LTE_MCCH_MessageType__later__c2_PR_mbmsCountingRequest_r10){ + LOG_I(RRC,"[UE %d] Frame %d : Found MBMSCountingRequest from eNB %d %p\n", + ctxt_pP->module_id, + ctxt_pP->frame, + eNB_index,&mcch->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10); + + rrc_ue_process_MBMSCountingRequest(ctxt_pP,&mcch->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10,eNB_index); + + decode_MBMSCountingRequest( + ctxt_pP->module_id, + eNB_index, + ctxt_pP->frame, + mbsfn_sync_area); + + + } + } } + } return 0; @@ -4308,7 +4396,7 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, (LTE_MBSFN_AreaInfoList_r9_t *)NULL ); - if(UE_rrc_inst[ue_mod_idP].Info[eNB_index].State >= RRC_CONNECTED /*|| UE_rrc_inst[ue_mod_idP].Info[eNB_index].State == RRC_RECONFIGURED*/) + if(1/*UE_rrc_inst[ue_mod_idP].Info[eNB_index].State >= RRC_CONNECTED*/ /*|| UE_rrc_inst[ue_mod_idP].Info[eNB_index].State == RRC_RECONFIGURED*/) UE_rrc_inst[ue_mod_idP].Info[eNB_index].MCCHStatus[mbsfn_sync_area] = 1; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_idP, ENB_FLAG_NO, UE_rrc_inst[ue_mod_idP].Info[eNB_index].rnti, frameP, 0,eNB_index); // Config Radio Bearer for MBMS user data (similar way to configure for eNB side in init_MBMS function) @@ -4332,6 +4420,13 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f // */ } +void decode_MBMSCountingRequest( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area ) { + //uint8_t i; + //protocol_ctxt_t ctxt; + + + +} //----------------------------------------------------------------------------- void *rrc_ue_task( void *args_p ) { @@ -4429,7 +4524,7 @@ void *rrc_ue_task( void *args_p ) { break; case RRC_MAC_MCCH_DATA_IND: - LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), + LOG_W(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_MCCH_DATA_IND (msg_p).frame, RRC_MAC_MCCH_DATA_IND (msg_p).enb_index, RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area); //PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0,RRC_MAC_MCCH_DATA_IND (msg_p).enb_index); diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 42fa5f6de1..f3380a054e 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -715,6 +715,9 @@ typedef struct { LTE_BCCH_BCH_Message_MBMS_t mib_fembms; LTE_BCCH_DL_SCH_Message_MBMS_t siblock1_MBMS; LTE_BCCH_DL_SCH_Message_MBMS_t systemInformation_MBMS; + LTE_SchedulingInfo_MBMS_r14_t schedulingInfo_MBMS; + LTE_PLMN_IdentityInfo_t PLMN_identity_info_MBMS[6]; + LTE_MCC_MNC_Digit_t dummy_mcc_MBMS[6][3], dummy_mnc_MBMS[6][3]; LTE_SystemInformationBlockType1_t *sib1; LTE_SystemInformationBlockType2_t *sib2; LTE_SystemInformationBlockType3_t *sib3; @@ -731,6 +734,12 @@ typedef struct { LTE_MCCH_Message_t mcch; LTE_MBSFNAreaConfiguration_r9_t *mcch_message; SRB_INFO MCCH_MESS[8];// MAX_MBSFN_AREA + uint8_t **MCCH_MESSAGE_COUNTING; // MAX_MBSFN_AREA + uint8_t sizeof_MCCH_MESSAGE_COUNTING[8];// MAX_MBSFN_AREA + LTE_MCCH_Message_t mcch_counting; + LTE_MBMSCountingRequest_r10_t *mcch_message_counting; + SRB_INFO MCCH_MESS_COUNTING[8];// MAX_MBSFN_AREA + //TTN - SIB 18,19,21 for D2D LTE_SystemInformationBlockType18_r12_t *sib18; LTE_SystemInformationBlockType19_r12_t *sib19; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 08c322f9b8..b665555b5d 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -155,6 +155,7 @@ init_SI( LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { + LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); @@ -231,6 +232,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf); } + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag=1; //AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255"); } @@ -496,12 +498,15 @@ init_SI( (LTE_PMCH_InfoList_r9_t *) NULL, sib1_v13ext, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag, - (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (carrier->sib1_MBMS==NULL?(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL:(LTE_BCCH_DL_SCH_Message_MBMS_t *)carrier->sib1_MBMS),//(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL - ); + (carrier->sib1_MBMS==NULL?(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL:(struct LTE_NonMBSFN_SubframeConfig_r14 *)carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (carrier->sib1_MBMS==NULL?(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL:(LTE_SystemInformationBlockType1_MBMS_r14_t *)carrier->sib1_MBMS->systemInformationBlockType13_r14),//(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (carrier->sib1_MBMS==NULL?(LTE_MBSFN_AreaInfoList_r9_t *) NULL:(LTE_MBSFN_AreaInfoList_r9_t *)&carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9)//(LTE_MBSFN_AreaInfoList_r9_t *) NULL + + ,(LTE_MBSFNAreaConfiguration_r9_t*) NULL + + ); } /* set flag to indicate that cell information is configured. This is required @@ -584,7 +589,8 @@ init_MCCH( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } @@ -1458,7 +1464,8 @@ rrc_eNB_generate_RRCConnectionReestablishment( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); break; } @@ -5759,7 +5766,8 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); // Configure target eNB SRB2 /// SRB2 @@ -6439,7 +6447,8 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } @@ -6655,7 +6664,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } } else { // remove LCHAN from MAC/PHY @@ -6714,7 +6724,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) @@ -6876,7 +6887,8 @@ rrc_eNB_generate_RRCConnectionSetup( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); break; } @@ -8352,6 +8364,8 @@ rrc_eNB_decode_dcch( case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n"); + break; case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.c b/openair2/RRC/LTE/rrc_eNB_M2AP.c index bd586dfc71..98a72895a0 100644 --- a/openair2/RRC/LTE/rrc_eNB_M2AP.c +++ b/openair2/RRC/LTE/rrc_eNB_M2AP.c @@ -63,6 +63,71 @@ rrc_M2AP_openair_rrc_top_init_MBMS(int eMBMS_active){ } +static uint8_t rrc_M2AP_do_MBSFNCountingRequest( + uint8_t Mod_id, + uint8_t sync_area, + uint8_t *buffer, + LTE_MCCH_Message_t *mcch_message, + LTE_MBMSCountingRequest_r10_t **mbsfnCoutingRequest, + const m2ap_mbms_service_counting_req_t *const m2ap_mbms_service_counting_req +) { + //int i,j,k; + + asn_enc_rval_t enc_rval; + //LTE_MBSFN_SubframeConfig_t *mbsfn_SubframeConfig1; + //LTE_PMCH_Info_r9_t *pmch_Info_1; + //LTE_MBMS_SessionInfo_r9_t *mbms_Session_1; + // MBMS_SessionInfo_r9_t *mbms_Session_2; + //eNB_RRC_INST *rrc = RC.rrc[Mod_id]; + //rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0]; + memset(mcch_message,0,sizeof(LTE_MCCH_Message_t)); + //mcch_message->message.present = LTE_MCCH_MessageType_PR_c1; + mcch_message->message.present = LTE_MCCH_MessageType_PR_later; + //mcch_message->message.choice.c1.present = LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9; + mcch_message->message.choice.later.present = LTE_MCCH_MessageType__later_PR_c2; + mcch_message->message.choice.later.choice.c2.present = LTE_MCCH_MessageType__later__c2_PR_mbmsCountingRequest_r10; + *mbsfnCoutingRequest = &mcch_message->message.choice.later.choice.c2.choice.mbmsCountingRequest_r10; + + + //LTE_CountingRequestList_r10_t countingRequestList_r10; // A_SEQUENCE_OF(struct LTE_CountingRequestInfo_r10) list; + struct LTE_CountingRequestInfo_r10 *lte_counting_request_info; //LTE_TMGI_r9_t tmgi_r10; + lte_counting_request_info = CALLOC(1,sizeof(struct LTE_CountingRequestInfo_r10)); + uint8_t TMGI[5] = {4,3,2,1,0}; + lte_counting_request_info->tmgi_r10.plmn_Id_r9.present = LTE_TMGI_r9__plmn_Id_r9_PR_plmn_Index_r9; + lte_counting_request_info->tmgi_r10.plmn_Id_r9.choice.plmn_Index_r9= 1; + memset(<e_counting_request_info->tmgi_r10.serviceId_r9,0,sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(<e_counting_request_info->tmgi_r10.serviceId_r9,(const char*)&TMGI[2],3); + ASN_SEQUENCE_ADD(&(*mbsfnCoutingRequest)->countingRequestList_r10.list,lte_counting_request_info); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void *)mcch_message); + } + + xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void *)mcch_message); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_MCCH_Message, + NULL, + (void *)mcch_message, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_I(RRC,"[eNB] MCCH Message Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : MCCH encoding failed for MBSFNAreaConfiguration\n"); + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} + static uint8_t rrc_M2AP_do_MBSFNAreaConfig( uint8_t Mod_id, @@ -96,6 +161,7 @@ static uint8_t rrc_M2AP_do_MBSFNAreaConfig( mbsfn_SubframeConfig1->radioframeAllocationPeriod= m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_period;//LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; mbsfn_SubframeConfig1->radioframeAllocationOffset= m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].radioframe_allocation_offset; if(m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].is_four_sf){ + LOG_I(RRC,"is_four_sf\n"); mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[i].mbms_sf_config_list[j].subframe_allocation) & 0xFF); @@ -106,6 +172,7 @@ static uint8_t rrc_M2AP_do_MBSFNAreaConfig( }else { + LOG_I(RRC,"is_one_sf\n"); mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; @@ -128,7 +195,8 @@ static uint8_t rrc_M2AP_do_MBSFNAreaConfig( */ pmch_Info_1->pmch_Config_r9.sf_AllocEnd_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].allocated_sf_end; pmch_Info_1->pmch_Config_r9.dataMCS_r9= m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].data_mcs; - pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; + //pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; + pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9 = m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].mch_scheduling_period; // MBMSs-SessionInfoList-r9 for(k=0; k < m2ap_mbms_scheduling_information->mbms_area_config_list[i].pmch_config_list[j].num_mbms_session_list; k++){ // pmch_Info_1->mbms_SessionInfoList_r9 = CALLOC(1,sizeof(struct MBMS_SessionInfoList_r9)); @@ -240,6 +308,9 @@ static void rrc_M2AP_init_MCCH( RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE = malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *)); + + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING = + malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *)); for (sync_area = 0; sync_area < RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area; sync_area++) { RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = 0; @@ -253,6 +324,20 @@ static void rrc_M2AP_init_MCCH( &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message, m2ap_mbms_scheduling_information ); + + RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[sync_area] = 0; + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[sync_area] = (uint8_t *) malloc16(32); + AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[sync_area] != NULL, + "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP); + + RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE_COUNTING[sync_area] = rrc_M2AP_do_MBSFNCountingRequest(enb_mod_idP, + sync_area, + (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE_COUNTING[sync_area], + &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_counting, + &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message_counting, + NULL//m2ap_mbms_scheduling_information + ); + LOG_I(RRC, "mcch message pointer %p for sync area %d \n", RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], sync_area); @@ -269,6 +354,8 @@ static void rrc_M2AP_init_MCCH( AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255, "RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255"); RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1; + + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS_COUNTING[sync_area].Active = 1; } @@ -297,16 +384,347 @@ static void rrc_M2AP_init_MCCH( (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9), (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL, - 0, + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*)(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message) + ); + } + + return; +} + + +static uint8_t rrc_M2AP_do_SIB1_MBMS_SIB13( + const protocol_ctxt_t *const ctxt_pP, + uint8_t Mod_id, + int CC_id, + const m2ap_setup_resp_t *const m2ap_setup_resp, + const m2ap_mbms_scheduling_information_t *const m2ap_mbms_scheduling_information +){ + + int i,j,l; + + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; + rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; + + + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part=NULL; + LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList/*,*MBSFNSubframeConfigList_copy*/; + + asn_enc_rval_t enc_rval; + + LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; + LTE_BCCH_DL_SCH_Message_MBMS_t *bcch_message_fembms = &RC.rrc[Mod_id]->carrier[CC_id].siblock1_MBMS; + uint8_t *buffer; + uint8_t *buffer_fembms; + LTE_SystemInformationBlockType2_t **sib2; + + + LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list/*,*MBSFNArea_list_copy*/; + LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; + struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1; + + LTE_SystemInformationBlockType1_MBMS_r14_t **sib1_MBMS = &RC.rrc[Mod_id]->carrier[CC_id].sib1_MBMS; + + + + if(ctxt_pP->brOption){ + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23_BR; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2_BR; + LOG_I(RRC,"Running SIB2/3 Encoding for eMTC\n"); + + + }else + { + buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; + sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; + } + + buffer_fembms = RC.rrc[Mod_id]->carrier[CC_id].SIB1_MBMS; + + + if (bcch_message) { + //memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); + } else { + LOG_E(RRC,"[eNB %d] BCCH_MESSAGE is null, exiting\n", Mod_id); + exit(-1); + } + + if (!sib2) { + LOG_E(RRC,"[eNB %d] sib2 is null, exiting\n", Mod_id); + exit(-1); + } + + if(!sib13){ + LOG_I(RRC,"[eNB %d] sib13 is null, it should get created\n",Mod_id); + } + + + if(!sib1_MBMS){ + LOG_I(RRC,"[eNB %d] sib1_MBMS is null, it should get created\n",Mod_id); + } + + //if (!sib3) { + // LOG_E(RRC,"[eNB %d] sib3 is null, exiting\n", Mod_id); + // exit(-1); + //} + + for (i=0; i < bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; + switch(typeandinfo->present) { + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_NOTHING: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: + *sib13=&typeandinfo->choice.sib13_v920; + (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + (*sib13)->notificationConfig_r9.notificationOffset_r9=0; + (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; + // MBSFN-AreaInfoList + MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list)); + memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); + + for( j=0; j < m2ap_setup_resp->num_mcch_config_per_mbsfn; j++){ + // MBSFN Area 1 + MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); + MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mbsfn_area; + MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[j].pdcch_length; + MBSFN_Area1->notificationIndicator_r9= 0; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].offset; // in accordance with mbsfn subframe configuration in sib2 + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].modification_period; + + // Subframe Allocation Info + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[j].subframe_allocation_info<<2; // FDD: SF1 + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[j].mcs; + ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); + } + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib14_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib15_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib16_v1130: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib17_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib20_v1310: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib24_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib25_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530: + break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + + LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2); + + for(j=0; j < m2ap_mbms_scheduling_information->num_mbms_area_config_list ; j++) { + + (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList)); + MBSFNSubframeConfigList = (&typeandinfo->choice.sib2)->mbsfn_SubframeConfigList; + + for(l=0; l < m2ap_mbms_scheduling_information->mbms_area_config_list[j].num_mbms_sf_config_list; l++){ + LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; + sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1)); + memset((void *)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); + + sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_period; + sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset = m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].radioframe_allocation_offset; + + + if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){ + LOG_I(RRC,"is_four_sf\n"); + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; + + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>8) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF); + + }else{ + LOG_I(RRC,"is_one_sf\n"); + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation<<2); + + + } + + ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1); + } + } + + break; + + } + } + + + if(*sib13==NULL){ + sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; + + *sib13 = &sib13_part->choice.sib13_v920; + + (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9=LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + (*sib13)->notificationConfig_r9.notificationOffset_r9=0; + (*sib13)->notificationConfig_r9.notificationSF_Index_r9=1; + + // MBSFN-AreaInfoList + MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list)); + memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); + + for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ + // MBSFN Area 1 + MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); + MBSFN_Area1->mbsfn_AreaId_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mbsfn_area; + MBSFN_Area1->non_MBSFNregionLength= m2ap_setup_resp->mcch_config_per_mbsfn[i].pdcch_length; + MBSFN_Area1->notificationIndicator_r9= 0; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].repetition_period;//LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].offset; // in accordance with mbsfn subframe configuration in sib2 + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].modification_period; + + // Subframe Allocation Info + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=m2ap_setup_resp->mcch_config_per_mbsfn[i].subframe_allocation_info<<2; // FDD: SF1 + MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= m2ap_setup_resp->mcch_config_per_mbsfn[i].mcs; + ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); + } + + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib13_part); + + } + + *sib1_MBMS = &bcch_message_fembms->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14; + + + if((*sib1_MBMS)->systemInformationBlockType13_r14==NULL){ + (*sib1_MBMS)->systemInformationBlockType13_r14 = CALLOC(1,sizeof(struct LTE_SystemInformationBlockType13_r9)); + memset((*sib1_MBMS)->systemInformationBlockType13_r14,0,sizeof(struct LTE_SystemInformationBlockType13_r9)); + } + + + memcpy((*sib1_MBMS)->systemInformationBlockType13_r14,*sib13,sizeof(struct LTE_SystemInformationBlockType13_r9)); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, + NULL, + (void *)bcch_message_fembms, + buffer_fembms, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + LOG_I(RRC,"[eNB] MBMS SIB1_MBMS SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI encoding failed for SIB23\n"); + return(-1); + } + + + + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, + NULL, + (void *)bcch_message, + buffer, + 900); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + LOG_I(RRC,"[eNB] MBMS SIB2 SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI encoding failed for SIB23\n"); + return(-1); + } + + carrier->MBMS_flag =1; + + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, + 0,0,0,0,0, + 0, + 0xfffd,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, + (LTE_AdditionalSpectrumEmission_t *)NULL, + (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList, + carrier->MBMS_flag, + (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + carrier->FeMBMS_flag, (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } - - return; + + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = ((enc_rval.encoded+7)/8); + + return 0; } //static uint8_t rrc_M2AP_do_SIB1( // const protocol_ctxt_t *const ctxt_pP, @@ -501,21 +919,23 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){ + LOG_I(RRC,"is_four_sf\n"); sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0; - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation) & 0xFF); - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>8) & 0xFF); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF); }else{ + LOG_I(RRC,"is_one_sf\n"); sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation<<2); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation<<2); } @@ -580,7 +1000,8 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } @@ -752,7 +1173,8 @@ for( i=0; i < m2ap_setup_resp->num_mcch_config_per_mbsfn; i++){ (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } @@ -917,20 +1339,22 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( if(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].is_four_sf){ sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames; + LOG_I(RRC,"rrc_M2AP_do_SIB23_SIB2_SIB13 is_four_sf\n"); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(3); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 3; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 0; - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation) & 0xFF); - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation>>8) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[2] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation) & 0xFF); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[1] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>8) & 0xFF); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0] = ((m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation>>16) & 0xFF); }else{ + LOG_I(RRC,"rrc_M2AP_do_SIB23_SIB2_SIB13 rs_one_sf\n"); sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[j].subframe_allocation<<2); + sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=(m2ap_mbms_scheduling_information->mbms_area_config_list[j].mbms_sf_config_list[l].subframe_allocation<<2); } @@ -1030,7 +1454,8 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13( (LTE_SchedulingInfo_MBMS_r14_t *) NULL, (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t*) NULL ); } @@ -1122,7 +1547,11 @@ rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ( rrc_M2AP_do_SIB23_SIB2(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information_g); rrc_M2AP_do_SIB23_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g); }else{ - rrc_M2AP_do_SIB23_SIB2_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g); + if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag){ + rrc_M2AP_do_SIB1_MBMS_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g); + }else{ + rrc_M2AP_do_SIB23_SIB2_SIB13(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_setup_resp_g,m2ap_mbms_scheduling_information_g); + } } rrc_M2AP_init_MCCH(ctxt_pP,ctxt_pP->module_id,CC_id,m2ap_mbms_scheduling_information_g); rrc_M2AP_init_MBMS(ctxt_pP->module_id, CC_id, 0); diff --git a/openair3/M3AP/m3ap_MCE.c b/openair3/M3AP/m3ap_MCE.c index 232b0c0ece..dec9b96897 100644 --- a/openair3/M3AP/m3ap_MCE.c +++ b/openair3/M3AP/m3ap_MCE.c @@ -142,6 +142,20 @@ void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->ulp_cnx_id); //m3ap_handle_m3_setup_message(instance_p, m3ap_enb_data_p, //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + sleep(4); + int index; + /* Trying to connect to the provided list of eNB ip address */ + for (index = 0; index < instance_p->nb_m3; index++) { + //M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n", + // instance_id, instance->eNB_id); + m3ap_MCE_register_MCE(instance_p, + &instance_p->target_mme_m3_ip_address[index], + &instance_p->mme_m3_ip_address, + instance_p->sctp_in_streams, + instance_p->sctp_out_streams, + instance_p->mce_port_for_M3C, + instance_p->multi_sd); + } return; } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 4715a4e995..faeed94c06 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -713,9 +713,12 @@ int main ( int argc, char **argv ) sync_var=0; pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); + create_tasks_mbms(1); config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); } - create_tasks_mbms(1); + else + create_tasks_mbms(1); + //create_tasks_mbms(1); // wait for end of program LOG_UI(ENB_APP,"TYPE TO TERMINATE\n"); -- GitLab From 543457f377be4eec6affaa95f714e92c1a946752 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Wed, 22 Jul 2020 08:09:51 +0200 Subject: [PATCH 22/34] fembms: removing debug log Signed-off-by: Javier Morgade --- openair1/SCHED_UE/phy_procedures_lte_ue.c | 3 +-- openair2/RRC/LTE/L2_interface.c | 4 ++-- openair2/RRC/LTE/L2_interface_ue.c | 6 ++---- openair2/RRC/LTE/rrc_UE.c | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 9f0b965e0c..35631c4ac3 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2707,7 +2707,6 @@ int ue_pdcch_procedures(uint8_t eNB_id, if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); } - LOG_W(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); if (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, @@ -2726,7 +2725,7 @@ int ue_pdcch_procedures(uint8_t eNB_id, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], 0)==0) { ue->dlsch_SI_received[eNB_id]++; - LOG_W(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); + LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } } else if ((dci_alloc_rx[i].rnti == P_RNTI) && diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index fe1cbd32ef..d9682b466f 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -233,10 +233,10 @@ mac_rrc_data_req( RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); - LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); + LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); if (LOG_DEBUGFLAG(DEBUG_RRC)) { - LOG_W(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); + LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) { LOG_T(RRC,"%x.",buffer_pP[i]); diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index c413df49bb..8c55dbaeb5 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -227,11 +227,9 @@ mac_rrc_data_ind_ue( } if ((srb_idP & RAB_OFFSET) == MCCH) { - //LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", - //module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); - - LOG_W(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", + LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); + { MessageDef *message_p; int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 5955c2221c..1e788a1762 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -4270,7 +4270,7 @@ int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB asn_dec_rval_t dec_rval; if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].MCCHStatus[mbsfn_sync_area] == 1) { - LOG_W(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n", + LOG_D(RRC,"[UE %d] Frame %d: MCCH MESSAGE for MBSFN sync area %d has been already received!\n", ctxt_pP->module_id, ctxt_pP->frame, mbsfn_sync_area); @@ -4524,7 +4524,7 @@ void *rrc_ue_task( void *args_p ) { break; case RRC_MAC_MCCH_DATA_IND: - LOG_W(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), + LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_MCCH_DATA_IND (msg_p).frame, RRC_MAC_MCCH_DATA_IND (msg_p).enb_index, RRC_MAC_MCCH_DATA_IND (msg_p).mbsfn_sync_area); //PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, M_RNTI, RRC_MAC_MCCH_DATA_IND (msg_p).frame, 0,RRC_MAC_MCCH_DATA_IND (msg_p).enb_index); -- GitLab From df58e251d81083f083134b2e7d4749380374c23b Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Wed, 22 Jul 2020 10:35:22 +0200 Subject: [PATCH 23/34] fembms: -FIX phy_simulators compiling error - adding missing dummy functions Signed-off-by: Javier Morgade --- openair1/SIMULATION/LTE_PHY/dummy_functions.c | 5 +++++ .../SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c index 5ec0f6e696..120e4845d9 100644 --- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -67,6 +67,11 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, sub_frame_t subframe, uint8_t eNB_index, uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + +int ue_query_mch_fembms(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync){} diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c index a93f0d48f3..cc8c62a36d 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c @@ -115,6 +115,11 @@ int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, sub_frame_t subframe, uint8_t eNB_index, uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + +int ue_query_mch_fembms(module_id_t Mod_id, uint8_t CC_id, uint32_t frame, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync){} -- GitLab From 5a68767d6a69765d24ed63ed9e1b0011b09c5305 Mon Sep 17 00:00:00 2001 From: "Dr.-Ing. Javier Morgade" Date: Wed, 22 Jul 2020 16:57:51 +0200 Subject: [PATCH 24/34] Update enb.band17.tm1.mbms.25PRB.usrpb210.conf --- ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf index e36d970b5b..a9ccb9f783 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf @@ -249,7 +249,6 @@ MCEs = ( ); - NETWORK_INTERFACES : { MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; -- GitLab From 63ed400e28fc54a7413855ef298565be78f0eba1 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Fri, 24 Jul 2020 09:44:13 +0200 Subject: [PATCH 25/34] fembms: CI/CD Adding FeMBMS RFSIM coverage test Signed-off-by: Javier Morgade --- .../conf_files/lte-fdd-fmbms-basic-sim.conf | 426 ++++++++++++++++++ 1 file changed, 426 insertions(+) create mode 100644 ci-scripts/conf_files/lte-fdd-fmbms-basic-sim.conf diff --git a/ci-scripts/conf_files/lte-fdd-fmbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-fmbms-basic-sim.conf new file mode 100644 index 0000000000..e3adedbf4a --- /dev/null +++ b/ci-scripts/conf_files/lte-fdd-fmbms-basic-sim.conf @@ -0,0 +1,426 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "ENABLE" + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + ////////// MCE parameters: + target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///M2 + enable_enb_m2 = "yes"; + + + mbms_configuration_data_list = ( + { + mbsfn_sync_area = 0x0001; + mbms_service_area_list=( + { + mbms_service_area=0x0001; + } + ); + } + + ); + + + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24"; + ENB_PORT_FOR_M2C = 36443; # Spec 36443 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +MCEs = ( + { + MCE_ID = 0xe00; + + MCE_name = "MCE-Vicomtech-LTEBox"; + + //M2 + enable_mce_m2 = "yes"; + + //M3 + enable_mce_m3 = "yes"; + + target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + + NETWORK_INTERFACES : + { + MCE_INTERFACE_NAME_FOR_M2_ENB = "lo"; + MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24"; + MCE_PORT_FOR_M2C = 36443; # Spec 36443 + + MCE_INTERFACE_NAME_FOR_M3_MME = "lo"; + MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24"; + MCE_PORT_FOR_M3C = 36444; # Spec 36444 + }; + + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + }; + + mbms_sched_info : + { + mcch_update_time = 10; + mbms_area_config_list = ( + { + common_sf_allocation_period = 1; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6) + mbms_area_id = 0; + pmch_config_list = ( + { + allocated_sf_end=512; + data_mcs=15; + mch_scheduling_period = 0; #rf8(0) rf16(1) rf32(2) rf64(3) rf128(4) rf256(5) rf512(6) rf1024(7) + mbms_session_list = ( + { + #plnm + service_id ->tmgi + plnm: + { + mcc = 208; + mnc = 93; + mnc_length = 2; + } + service_id=0; #keep this allways as 0 (workaround for TUN if) + lcid=5; #this must be properly defined lcid:6+service:0 -> rab_id:5 //with new RLC set lcid either 4 or 5 + } + ); + } + ); + + mbms_sf_config_list = ( + { + radioframe_allocation_period=0; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5) + radioframe_alloocation_offset=0; + num_frame="oneFrame"; + subframe_allocation=57; #xx111001 + //num_frame="fourFrame"; + //subframe_allocation=14548987; # + } + ); + + } + ); + }; + + + mcch_config_per_mbsfn_area = ( + { + mbsfn_area = 0; + pdcch_length = 1; #s1(0), s2(1) + repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3) + offset = 0; + modification_period = 0; #rf512(0; rf1024(1) + subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000 + mcs = 0; #n2(0), n7(1), n13(2), n19(3) + } + ); + + #); #end mbms_scheduling_info + + } +); + +MMEs = ( + { + MME_ID = 0xe00; + + MME_name = "MME-MBMS-Vicomtech-LTEBox"; + + //M3 + enable_mme_m3 = "yes"; + NETWORK_INTERFACES : + { + MME_INTERFACE_NAME_FOR_M3_MCE = "lo"; + MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24"; + MME_PORT_FOR_M3C = 36444; # Spec 36444 + + }; + } +); + + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "ens3"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + +//rfsimulator : +//{ + //options = ("chanmod"); + //modelname = "AWGN"; +//}; + -- GitLab From 27b9fa6935cecbef130121499d5c278ec21871ab Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Fri, 24 Jul 2020 09:46:02 +0200 Subject: [PATCH 26/34] fembms: CI/DC adding missing commit Signed-off-by: Javier Morgade --- ci-scripts/reportTestLocally.sh | 95 +++++++++++++++++++++++++++++++++ ci-scripts/runTestOnVM.sh | 89 ++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 897f9285e9..b05ccf39db 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -620,6 +620,101 @@ function report_test { #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul*client*txt | grep -v mbms 2> /dev/null` #analyzeIperfFiles done + + # FeMBMS Case + CN_CONFIG="noS1" + TMODE="fdd" + BW_CASES=(05) + for BW in ${BW_CASES[@]} + do + echo " " >> ./test_simulator_results.html + echo " Test FeMBMS without EPC (aka noS1): ${TMODE} -- ${BW}MHz " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_enb_fembms.log + UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"` + if [ -f $ENB_LOG ] && [ -f $UE_LOG ] + then + NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " $NAME_ENB --- $NAME_UE" >> ./test_simulator_results.html + echo " N/A" >> ./test_simulator_results.html + #NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfully configured" $ENB_LOG` + NB_ENB_MTUNNEL_UP=`egrep -c "Interface oaitun_enm1 successfully configured" $ENB_LOG` + #NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` + #NB_ENB_SYNCED_WITH_UE=`egrep -c "Generating RRCConnectionReconfigurationComplete" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG` + NB_UE_MTUNNEL_UP=`egrep -c "Interface oaitun_uem1 successfully configured" $UE_LOG` + NB_UE_MBMS_PUSH_MSG=`egrep -c "TRIED TO PUSH MBMS DATA TO" $UE_LOG` + #if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] && [ $NB_UE_MBMS_PUSH_MSG -gt 0 ] + if [ $NB_UE_MBMS_PUSH_MSG -gt 0 ] + then + echo " OK" >> ./test_simulator_results.html + else + echo " KO" >> ./test_simulator_results.html + fi + echo "
" >> ./test_simulator_results.html
+                #if [ $NB_ENB_GOT_SYNC -gt 0 ]
+                #then
+                #    echo "- eNB --> got sync" >> ./test_simulator_results.html
+                #else
+                #    echo "- eNB NEVER got sync" >> ./test_simulator_results.html
+                #fi
+                if [ $NB_ENB_TUNNEL_UP -gt 0 ]
+                then
+                    echo "- eNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- eNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_ENB_MTUNNEL_UP -gt 0 ]
+                then
+                    echo "- eNB mounted oaitun_enm1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- eNB NEVER mounted oaitun_enm1 interface" >> ./test_simulator_results.html
+                fi
+                #if [ $NB_UE_GOT_SYNC -gt 0 ]
+                #then
+                #    echo "- LTE UE --> got sync" >> ./test_simulator_results.html
+                #else
+                #    echo "- LTE UE NEVER got sync" >> ./test_simulator_results.html
+                #fi
+                #if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
+                #then
+                #    echo "- LTE UE attached to eNB" >> ./test_simulator_results.html
+                #else
+                #    echo "- LTE UE NEVER attached to eNB" >> ./test_simulator_results.html
+                #fi
+                if [ $NB_UE_TUNNEL_UP -gt 0 ]
+                then
+                    echo "- LTE UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_UE_MTUNNEL_UP -gt 0 ]
+                then
+                    echo "- LTE UE mounted oaitun_uem1 interface" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER mounted oaitun_uem1 interface" >> ./test_simulator_results.html
+                fi
+                if [ $NB_UE_MBMS_PUSH_MSG -gt 0 ]
+                then
+                    echo "- LTE UE tried to push ${NB_UE_MBMS_PUSH_MSG} MBMS DATA" >> ./test_simulator_results.html
+                else
+                    echo "- LTE UE NEVER pushed MBMS DATA" >> ./test_simulator_results.html
+                fi
+                echo "        
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + #PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_ping*.log 2> /dev/null` + #analyzePingFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl*client*txt | grep -v mbms 2> /dev/null` + #analyzeIperfFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul*client*txt | grep -v mbms 2> /dev/null` + #analyzeIperfFiles + done echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 0db2264c76..1ac5e3a920 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -2050,6 +2050,95 @@ function run_test_on_vm { echo "LTE RFSIM seems to FAIL" echo "LTE: TEST_KO" > $ARCHIVES_LOC/test_final_status.log fi + + #################### + ## FeMSMS CASE noS1 ## + #################### + CONF_FILE=lte-fdd-fembms-basic-sim.conf + CN_CONFIG="noS1" + S1_NOS1_CFG=0 + LTEBOX=0 + TMODE="fdd" + FREQUENCY=2680 + BW_CASES=(05) + FeMBMS_STATUS=0 + + for BW in ${BW_CASES[@]} + do + if [[ $BW =~ .*05.* ]]; then PRB=25; fi + if [[ $BW =~ .*10.* ]]; then PRB=50; fi + if [[ $BW =~ .*20.* ]]; then PRB=100; fi + + echo "############################################################" + echo "${CN_CONFIG} : Starting the eNB with MSMS in ${TMODE}-${BW}MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_enb_fembms.log + start_rf_sim_enb $ENB_VM_CMDS "$ENB_VM_IP_ADDR" "$EPC_VM_IP_ADDR" $CURRENT_ENB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG + + echo "############################################################" + echo "${CN_CONFIG} : Starting the UE" + echo "############################################################" + CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ue_fembms.log + start_rf_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + STATUS=-1 + break + fi + + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + get_enb_mbms_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl_fembms + get_ue_mbms_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + THROUGHPUT=2 + generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + #check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + NB_UE_FeMBMS_MESSAGES=`egrep -c "TRIED TO PUSH MBMS DATA TO" $ARCHIVES_LOC/$CURRENT_UE_LOG_FILE` + if [ $NB_UE_FeMBMS_MESSAGES -eq 0 ]; then FeMBMS_STATUS=-1; fi + + done + + full_l2_sim_destroy + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $FeMBMS_STATUS -eq 0 ] + then + echo "LTE FeMBMS RFSIM seems OK" + else + echo "LTE FeMBMS RFSIM seems to FAIL" + STATUS=-1 + fi + if [ $STATUS -eq 0 ] + then + echo "LTE RFSIM seems OK" + echo "LTE: TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else + echo "LTE RFSIM seems to FAIL" + echo "LTE: TEST_KO" > $ARCHIVES_LOC/test_final_status.log + fi + fi if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] -- GitLab From c681e800bacc9e03df36aa969f24a3c27ff32540 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Fri, 24 Jul 2020 14:45:28 +0200 Subject: [PATCH 27/34] fembms: CI/CD Adding USRP coverage tests for FeMBMS Signed-off-by: Javier Morgade --- ...p210_band7_test_05mhz_tm1_fembms_no_s1.xml | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml new file mode 100644 index 0000000000..02a62561a5 --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml @@ -0,0 +1,82 @@ + + + test-05-tm1-fembms-nos1-tunnel + Test-05MHz-FeMBMS-TM1-noS1-tunnel + tasks + 2 + + 030201 090109 + 030103 000001 090103 000002 040605 000001 090109 030201 + + + + + IdleSleep + Sleep + 10 + + + + IdleSleep + Sleep + 15 + + + + IdleSleep + Sleep + 60 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz/MBMS) + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_OAI_UE + Initialize OAI UE (FDD/Band7/5MHz/MBMS) + -C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1 + + + + Terminate_OAI_UE + Terminate OAI UE + + + + Iperf + iperf (5MHz - DL/1.5Mbps/UDP/MBMS-sink)(20 sec) + -c 10.0.2.2 -u -b 1.5M -t 20 -i 1 -fm -B 10.0.2.1 + 50 + sink + + + -- GitLab From 8e9a989aa53dfc36c5d0a2a907952170acb66f83 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Fri, 24 Jul 2020 17:48:51 +0200 Subject: [PATCH 28/34] fembms: FIX filename typo Signed-off-by: Javier Morgade --- ...lte-fdd-fmbms-basic-sim.conf => lte-fdd-fembms-basic-sim.conf} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ci-scripts/conf_files/{lte-fdd-fmbms-basic-sim.conf => lte-fdd-fembms-basic-sim.conf} (100%) diff --git a/ci-scripts/conf_files/lte-fdd-fmbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf similarity index 100% rename from ci-scripts/conf_files/lte-fdd-fmbms-basic-sim.conf rename to ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf -- GitLab From 7f9dbdd3f4c8c3f0ec7e37a6aaec1f2e375e2034 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 25 Jul 2020 08:06:04 +0200 Subject: [PATCH 29/34] fembms: CI/CD Test Signed-off-by: Javier Morgade --- ci-scripts/runTestOnVM.sh | 2 +- .../enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 1ac5e3a920..b9b9a2bafa 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -2052,7 +2052,7 @@ function run_test_on_vm { fi #################### - ## FeMSMS CASE noS1 ## + ## FeMBMS CASE noS1 ## #################### CONF_FILE=lte-fdd-fembms-basic-sim.conf CN_CONFIG="noS1" diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml index 02a62561a5..49aa516e8c 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml @@ -27,7 +27,7 @@ 2 030201 090109 - 030103 000001 090103 000002 040605 000001 090109 030201 + 030104 000001 090104 000002 040606 000001 090109 030201 @@ -49,7 +49,7 @@ 60 - + Initialize_eNB Initialize eNB (FDD/Band7/5MHz/MBMS) -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 @@ -60,7 +60,7 @@ Terminate eNB - + Initialize_OAI_UE Initialize OAI UE (FDD/Band7/5MHz/MBMS) -C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1 @@ -71,7 +71,7 @@ Terminate OAI UE - + Iperf iperf (5MHz - DL/1.5Mbps/UDP/MBMS-sink)(20 sec) -c 10.0.2.2 -u -b 1.5M -t 20 -i 1 -fm -B 10.0.2.1 -- GitLab From 1d4bd3358a35b37d426153cb4e6287abc93e3e3e Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 25 Jul 2020 11:42:23 +0200 Subject: [PATCH 30/34] fembms: CI/CD fixing USRP Test Signed-off-by: Javier Morgade --- .../enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml index 49aa516e8c..8736ab2082 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml @@ -27,7 +27,7 @@ 2 030201 090109 - 030104 000001 090104 000002 040606 000001 090109 030201 + 030104 000001 090104 000002 040605 000001 090109 030201 @@ -71,7 +71,7 @@ Terminate OAI UE - + Iperf iperf (5MHz - DL/1.5Mbps/UDP/MBMS-sink)(20 sec) -c 10.0.2.2 -u -b 1.5M -t 20 -i 1 -fm -B 10.0.2.1 -- GitLab From 0c31b449caec54eadf1a9c7b4e7499a22e12e578 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sat, 25 Jul 2020 15:48:05 +0200 Subject: [PATCH 31/34] fembms: CI/CD fixing USRP Test Signed-off-by: Javier Morgade --- .../enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml index b841d3bab4..3780c52bb7 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml @@ -52,7 +52,7 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz/MBMS) - -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 -- GitLab From e10b0646e48579aedd28f9a8c6560718ab644ac6 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Sun, 26 Jul 2020 08:41:42 +0200 Subject: [PATCH 32/34] fembms: CI/CD fallback USRP tests Signed-off-by: Javier Morgade --- ..._ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml | 12 ++++++------ ...nb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml index 8736ab2082..3780c52bb7 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_fembms_no_s1.xml @@ -21,13 +21,13 @@ --> - test-05-tm1-fembms-nos1-tunnel - Test-05MHz-FeMBMS-TM1-noS1-tunnel + test-05-tm1-mbms-nos1-tunnel + Test-05MHz-MBMS-TM1-noS1-tunnel tasks 2 030201 090109 - 030104 000001 090104 000002 040605 000001 090109 030201 + 030103 000001 090103 000002 040605 000001 090109 030201 @@ -49,10 +49,10 @@ 60 - + Initialize_eNB Initialize eNB (FDD/Band7/5MHz/MBMS) - -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 @@ -60,7 +60,7 @@ Terminate eNB - + Initialize_OAI_UE Initialize OAI UE (FDD/Band7/5MHz/MBMS) -C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1 diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml index 3780c52bb7..b841d3bab4 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml @@ -52,7 +52,7 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz/MBMS) - -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 -- GitLab From 73dd4715944f36446977850a7915f4a2b5f300fa Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 27 Jul 2020 10:34:43 +0200 Subject: [PATCH 33/34] fembms: CI/CD using MBMS config to lauch FeMBMS test Signed-off-by: Javier Morgade --- .../enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml index b841d3bab4..3780c52bb7 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml @@ -52,7 +52,7 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz/MBMS) - -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 -- GitLab From a061c8acc58097564f4152223aa1b0dbf19bb3ee Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 27 Jul 2020 14:17:58 +0200 Subject: [PATCH 34/34] fembms: CI/CD fallback to original MBMS settings Signed-off-by: Javier Morgade --- .../enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml index 3780c52bb7..b841d3bab4 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_mbms_no_s1.xml @@ -52,7 +52,7 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz/MBMS) - -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 --eNBs.[0].component_carriers.[0].mbms_dedicated_serving_cell ENABLE --MCEs.[0].mbms_sched_info.mbms_area_config_list.[0].pmch_config_list.[0].allocated_sf_end 512 + -O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000 -- GitLab