diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 90f9d5bbfaba26a0bc01f3d9ff29d1dfa808f46d..cc0296cb441ac51669ff92cf396aadaecbfe62ae 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -290,6 +290,8 @@ const char* eurecomFunctionsNames[] = { /* PHY signals */ "ue_synch", "ue_slot_fep", + "ue_slot_fep_mbsfn", + "ue_slot_fep_mbsfn_khz_1dot25", "ue_rrc_measurements", "ue_gain_control", "ue_adjust_synch", @@ -356,9 +358,12 @@ const char* eurecomFunctionsNames[] = { "dlsch_decoding5", "dlsch_decoding6", "dlsch_decoding7", + "dlsch_pmch_decoding", "rx_pdcch", "dci_decoding", "rx_phich", + "rx_pmch", + "rx_pmch_khz_1dot25", "pdsch_procedures", "pdsch_procedures_si", "pdsch_procedures_p", diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 2088fb17d7aa7e1f4f0a53f3d93d27883fcedfc5..45525f85435ff994a4899f1f69264db6705db2ff 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -268,6 +268,8 @@ typedef enum { /* PHY signals */ VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, @@ -334,9 +336,12 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING5, VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING6, VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING7, + VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, + VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, + VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 907b871efe8a4b198873192134685b4bce74df7d..348d4837b7ca5ddb9040060d9c10b04e13b69dd9 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -2138,6 +2138,16 @@ ID = VCD_FUNCTION_UE_SLOT_FEP GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value VCD_NAME = ue_slot_fep +ID = VCD_FUNCTION_UE_SLOT_FEP_MBSFN + DESC = VCD function UE_SLOT_FEP_MBSFN + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_mbsfn +ID = VCD_FUNCTION_UE_SLOT_FEP_MBSFN_KHZ_1DOT25 + DESC = VCD function UE_SLOT_FEP_MBSFN_KHZ_1DOT25 + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_mbsfn_khz_1dot25 ID = VCD_FUNCTION_UE_RRC_MEASUREMENTS DESC = VCD function UE_RRC_MEASUREMENTS GROUP = ALL:VCD:UE:VCD_FUNCTION @@ -2468,6 +2478,11 @@ ID = VCD_FUNCTION_DLSCH_DECODING7 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = dlsch_decoding7 +ID = VCD_FUNCTION_DLSCH_PMCH_DECODING + DESC = VCD function DLSCH_PMCH_DECODING + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = dlsch_pmch_decoding ID = VCD_FUNCTION_RX_PDCCH DESC = VCD function RX_PDCCH GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -2483,6 +2498,16 @@ ID = VCD_FUNCTION_RX_PHICH GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = rx_phich +ID = VCD_FUNCTION_RX_PMCH + DESC = VCD function RX_PMCH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = rx_pmch +ID = VCD_FUNCTION_RX_PMCH_KHZ_1DOT25 + DESC = VCD function RX_PMCH_KHZ_1DOT25 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = rx_pmch_khz_1dot25 ID = VCD_FUNCTION_PDSCH_PROC DESC = VCD function PDSCH_PROC GROUP = ALL:VCD:UE:VCD_FUNCTION diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 282739e31597782fd46a1e5e50f154d01c801708..6a70e1f10afae444929d0ec07807318ee9f8f261 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -702,6 +702,18 @@ typedef struct { #define NFAPI_PUCCH_CONFIG_N_AN_CS_TAG 0x003E #define NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG 0x003F +typedef struct { + nfapi_uint8_tlv_t radioframe_allocation_period; + nfapi_uint8_tlv_t radioframe_allocation_offset; + nfapi_uint8_tlv_t non_mbsfn_config_flag; + nfapi_uint16_tlv_t non_mbsfn_subframeconfig; +} nfapi_fembms_config_t; + +#define NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG 0x0042 +#define NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG 0x0043 +#define NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG 0x0044 +#define NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG 0x0045 + typedef struct { nfapi_uint16_tlv_t bandwidth_configuration; nfapi_uint16_tlv_t max_up_pts; @@ -1097,6 +1109,7 @@ typedef struct { nfapi_prach_config_t prach_config; nfapi_pusch_config_t pusch_config; nfapi_pucch_config_t pucch_config; + nfapi_fembms_config_t fembms_config; nfapi_srs_config_t srs_config; nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; nfapi_tdd_frame_structure_t tdd_frame_structure_config; @@ -1118,6 +1131,7 @@ typedef struct { nfapi_prach_config_t prach_config; nfapi_pusch_config_t pusch_config; nfapi_pucch_config_t pucch_config; + nfapi_fembms_config_t fembms_config; nfapi_srs_config_t srs_config; nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; nfapi_laa_config_t laa_config; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c index c78b8291358c2a611763649d024bb86acf2b9fba..54e27123d995ea1ec3088e0daa7a48c74574d64d 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -461,6 +461,12 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_subframeconfig), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 475da1e860aca86298e8101dda899867dc11990a..fad4311714bfdb11bd2703e409c4c4629118dc77 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -310,6 +310,12 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->num_MBSFN_config = 0; + fp->NonMBSFN_config_flag =cfg->fembms_config.non_mbsfn_config_flag.value; + 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; + LOG_D(PHY,"eNB %d/%d frame NonMBSFN configured: %d (%x) %d/%d\n",Mod_id,CC_id,fp->NonMBSFN_config_flag,fp->NonMBSFN_config.non_mbsfn_SubframeConfig,fp->NonMBSFN_config.radioframeAllocationPeriod,fp->NonMBSFN_config.radioframeAllocationOffset); + init_ncs_cell (fp, RC.eNB[Mod_id][CC_id]->ncs_cell); @@ -335,6 +341,10 @@ void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx, } lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn); +#endif } diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 99d4f89ace42db62ca526e50ffcdcf8bd9098bd2..f7ab91c86ea6d68f53556fd46c7b1a91f7dd3148 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -165,8 +165,29 @@ void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_A } lte_gold_mbsfn(fp,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_mbsfn_table,fp->Nid_cell_mbsfn); + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + lte_gold_mbsfn_khz_1dot25(fp,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table,fp->Nid_cell_mbsfn); +#endif + } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void phy_config_sib1_fembms_ue(module_id_t Mod_id,int CC_id, + uint8_t eNB_id, + struct LTE_NonMBSFN_SubframeConfig_r14 *nonMBSFN_SubframeConfig){ + PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + LTE_DL_FRAME_PARMS *fp = &ue->frame_parms; + if (nonMBSFN_SubframeConfig != NULL) { + fp->NonMBSFN_config_flag = 0; + 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); + } +} +#endif + /* * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover @@ -872,4 +893,4 @@ void init_lte_ue_transport(PHY_VARS_UE *ue,int abstraction_flag) { ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; ue->dlsch_MCH[0] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0); -} \ No newline at end of file +} diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c index 4d149c0026be929c51e209bbceec6849dd6c2da9..c87c3b44b0e65d7fc128738ca3e260ea3a213adc 100644 --- a/openair1/PHY/INIT/lte_parms.c +++ b/openair1/PHY/INIT/lte_parms.c @@ -125,6 +125,12 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf) { frame_parms->nb_prefix_samples0>>=(2-log2_osf); frame_parms->N_RBGS = 2; frame_parms->N_RBG = 13; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + frame_parms->ofdm_symbol_size_khz_1dot25 = 6144*osf; + frame_parms->first_carrier_offset_khz_1dot25 = frame_parms->ofdm_symbol_size_khz_1dot25 - 1800; //4344 + frame_parms->nb_prefix_samples_khz_1dot25>>=(2-log2_osf); + frame_parms->nb_prefix_samples0_khz_1dot25>>=(2-log2_osf); +#endif break; case 15: diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index 9e08dabba236e30089c28e4f43d036b021dfee31..ac03ec7ded6bb509a623fa26847ce0f550ac18e1 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -35,6 +35,9 @@ #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "LTE_SCellToAddMod-r10.h" #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#include "LTE_NonMBSFN-SubframeConfig-r14.h" +#endif /** @addtogroup _PHY_STRUCTURES_ * @{ */ @@ -147,7 +150,6 @@ void phy_config_sib1_ue(module_id_t Mod_id, uint8_t SIwindowsize, uint16_t SIperiod); - /*! \fn void phy_config_sib2_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t CH_index, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, @@ -258,6 +260,10 @@ void phy_config_sib13_ue(module_id_t Mod_id, int CC_id,uint8_t CH_index,int mbsfn_Area_idx, long mbsfn_AreaId_r9); +void phy_config_sib1_fembms_ue(module_id_t Mod_id,int CC_id, + uint8_t eNB_id, + struct LTE_NonMBSFN_SubframeConfig_r14 *nonMBSFN_SubframeConfig); + /** \brief Configure eNB MBSFN common parameters. \details Invoked upon transmission of SIB13 from eNB. diff --git a/openair1/PHY/LTE_ESTIMATION/filt96_32_khz_1dot25.h b/openair1/PHY/LTE_ESTIMATION/filt96_32_khz_1dot25.h new file mode 100644 index 0000000000000000000000000000000000000000..876aef6d58f38553181db3c90610ab1c5f67b6fb --- /dev/null +++ b/openair1/PHY/LTE_ESTIMATION/filt96_32_khz_1dot25.h @@ -0,0 +1,205 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +short filt24_0_khz_1dot25[24] __attribute__((aligned(32))) ={ + 2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_0_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 2341,4681,7022,9362,11703,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_0_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +short filt24_1_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_1_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,4681,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_1_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0,0,0,0,0,0,0 +}; + + +short filt24_2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_2_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,2341,4681,7022,9362, 11703,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_2_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,2730,5461,8192,10922,13653,16384,14043,11703,9362,4681,2341,0,0,0,0,0,0,0,0,0,0,0 +}; + +// X X X Y | X X X X | X Y X X +short filt24_3_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_3_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,2341,4681,7022,9362,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0 +}; +// X X X Y | X X DC X X | X Y X X +short filt24_3_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,7022,4681,2341,0,0,0,0,0,0,0,0,0,0 +}; + + +short filt24_4_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0 +}; +short filt24_4_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,2341,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0 +}; +short filt24_4_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,7022,4681,2341,0,0,0,0,0,0,0,0,0 +}; + +short filt24_5_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0 +}; +// X X X Y | X X DC X X | X Y X X +short filt24_5_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,2341,4681,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0 +}; +short filt24_5_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,2730,5461,8192,10922,13653,16384,11703,9362,7022,4681,2730,0,0,0,0,0,0,0,0 +}; + + +short filt24_6_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0 +}; +short filt24_6_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,4681,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0 +}; +short filt24_6_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0,0 +}; + + +short filt24_7_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0 +}; +short filt24_7_dcl_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,0,4681,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0 +}; +short filt24_7_dcr_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0 +}; + +short filt24_0l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_1l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_2l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_3l_khz_1dot25[24] __attribute__((aligned(32))) ={ + //0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0}; + 0,0,0,0,0,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_4l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0 +}; +short filt24_5l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0 +}; +short filt24_6l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0 +}; +short filt24_7l_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0 +}; +short filt24_0l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_1l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_2l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + -2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_3l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + -5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_4l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + -8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0 +}; +short filt24_5l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0 +}; +short filt24_6l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + -13653,-10922,-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0 +}; +short filt24_7l2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,-13653,-10922,-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0 +}; +short filt24_0r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_1r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_2r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_3r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0 +}; +short filt24_4r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0 +}; +short filt24_5r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0 +}; +short filt24_6r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0 +}; +short filt24_7r_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0 +}; +short filt24_0r2_khz_1dot25[24] __attribute__((aligned(32))) ={ /****/ + 2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0,0,0,0 +}; +short filt24_1r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0,0,0 +}; +short filt24_2r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0,0 +}; +short filt24_3r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0 +}; +short filt24_4r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0 +}; +short filt24_5r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0 +}; +short filt24_6r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0 +}; +short filt24_7r2_khz_1dot25[24] __attribute__((aligned(32))) ={ + 0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653 +}; 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 1a0611b9626ac960b6c228d798b72c4c8369b543..0d45a472eb7d2a3def68ff0b9b52fe1242e52d64 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c @@ -19,11 +19,24 @@ * contact@openairinterface.org */ +/*! \file config_ue.c + * \brief This includes FeMBMS UE Channel Estimation Procedures for FeMBMS 1.25KHz Carrier Spacing + * \author Javier Morgade + * \date 2019 + * \version 0.1 + * \email: javier.morgade@ieee.org + * @ingroup _phy + + */ + + #include <string.h> #include "PHY/defs_UE.h" #include "lte_estimation.h" #include "PHY/LTE_REFSIG/lte_refsig.h" +#include "filt96_32_khz_1dot25.h" + //#define DEBUG_CH int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue, module_id_t eNB_id, @@ -769,3 +782,180 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue, return(0); } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +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*/; + //unsigned int rb; + int16_t ch[2]; + short *pil,*rxF,*dl_ch/*,*ch0,*ch1,*ch11,*chp,*ch_prev*/; + int ch_offset,symbol_offset; + int pilot_cnt; + + int16_t *f,*f2,*fl,*f2l2,*fr,*f2r2/*,*f2_dc,*f_dc*/; + + unsigned int k; + + // unsigned int n; + // int i; + + int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0]; + 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); + + if( (subframe&0x1) == 0){ + f=filt24_0_khz_1dot25; + f2=filt24_2_khz_1dot25; + fl=filt24_0_khz_1dot25; + f2l2=filt24_2_khz_1dot25; + fr=filt24_0r2_khz_1dot25; + f2r2=filt24_2r_khz_1dot25; + //f_dc=filt24_0_dcr_khz_1dot25; + //f2_dc=filt24_2_dcl_khz_1dot25; + }else{ + f=filt24_0_khz_1dot25; + f2=filt24_2_khz_1dot25; + fl=filt24_0_khz_1dot25; + f2l2=filt24_2_khz_1dot25; + fr=filt24_0r2_khz_1dot25; + f2r2=filt24_2r_khz_1dot25; + //f_dc=filt24_0_dcr_khz_1dot25; + //f2_dc=filt24_2_dcl_khz_1dot25; + } + + + for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { + // generate pilot + lte_dl_mbsfn_khz_1dot25_rx(ue, + &pilot_khz_1dot25[0], + subframe); + + + pil = (short *)&pilot_khz_1dot25[0]; + rxF = (short *)&rxdataF[aarx][((ue->frame_parms.first_carrier_offset_khz_1dot25))]; + dl_ch = (short *)&dl_ch_estimates[aarx][ch_offset]; + + memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size_khz_1dot25)); + + if( (subframe&0x1) == 0){ + rxF+=0; + k=0; + }else{ + rxF+=6;//2*3; + k=3; + } + + if(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, + ch, + dl_ch, + 24); + pil+=2; // Re Im + rxF+=12; + dl_ch+=8; + + 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(f2l2, + ch, + dl_ch, + 24); + pil+=2; // Re Im + rxF+=12; + dl_ch+=16; + + for(pilot_cnt=2;pilot_cnt<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, + ch, + dl_ch, + 24); + pil+=2; // Re Im + rxF+=12; + dl_ch+=8; + + 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(f2, + ch, + dl_ch, + 24); + pil+=2; + rxF+=12; + dl_ch+=16; + + } + + rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))]; //Skip DC offset + + for(pilot_cnt=0; pilot_cnt<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, + ch, + dl_ch, + 24); + pil+=2; + rxF+=12; + dl_ch+=8; + + 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(f2, + ch, + dl_ch, + 24); + pil+=2; + rxF+=12; + dl_ch+=16; + } + + 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(fr, + ch, + dl_ch, + 24); + pil+=2; // Re Im + rxF+=12; + dl_ch+=8; + + 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(f2r2, + ch, + dl_ch, + 24); + } + } + + return(0); +} +#endif + + diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h index 53d874a8fc0f3203fb93d88d140145acfce012c3..a155d68d26ca3c75996be553fa9d68f93584249b 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h +++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h @@ -141,6 +141,11 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *phy_vars_ue, int subframe, unsigned char l); +int lte_dl_mbsfn_khz_1dot25_channel_estimation(PHY_VARS_UE *ue, + module_id_t eNB_id, + uint8_t eNB_offset, + int subframe); + /*! \brief Frequency offset estimation for LTE We estimate the frequency offset by calculating the phase difference between channel estimates for symbols carrying pilots (l==0 or l==3/4). We take a moving average of the phase difference. diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index bc841744f4b56e0816047e4ca8cfbafb67ee74f8..7b05972f8266c45257565a5deca4ffde3a38369a 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -341,7 +341,6 @@ int lte_sync_time(int **rxdata, ///rx data in time domain { - // perform a time domain correlation using the oversampled sync sequence unsigned int n, ar, s, peak_pos, peak_val, sync_source; diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c index b0af8f6b0b0489de8b91a6bccf350e9aa7148079..f78da483de8e7a2dc6aca37c07877a48d0d67da1 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c @@ -131,3 +131,92 @@ int lte_dl_mbsfn_rx(PHY_VARS_UE *ue, return(0); } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int lte_dl_mbsfn_khz_1dot25(PHY_VARS_eNB *eNB, int32_t *output, + short amp, + int subframe) +{ + + unsigned int mprime,mprime_dword,mprime_qpsk_symb,m; + unsigned short k=0,a; + int32_t qpsk[4]; + + a = (amp*ONE_OVER_SQRT2_Q15)>>15; + ((short *)&qpsk[0])[0] = a; + ((short *)&qpsk[0])[1] = a; + + ((short *)&qpsk[1])[0] = -a; + ((short *)&qpsk[1])[1] = a; + ((short *)&qpsk[2])[0] = a; + ((short *)&qpsk[2])[1] = -a; + + ((short *)&qpsk[3])[0] = -a; + ((short *)&qpsk[3])[1] = -a; + + + mprime = 3*(110 - eNB->frame_parms.N_RB_DL); + + for (m=0; m<eNB->frame_parms.N_RB_DL*24; m++) // m = 0:24*N_RB_DL-1 + { + if ((subframe&0x1)==0) // n_sf mod 2 == 0: even + k = 6*m; + else + k = 6*m + 3; + + + k+=eNB->frame_parms.first_carrier_offset_khz_1dot25; + + mprime_dword = mprime>>4; + mprime_qpsk_symb = mprime&0xf; + + if (k >= eNB->frame_parms.ofdm_symbol_size_khz_1dot25) { + k++; // skip DC carrier + k-=eNB->frame_parms.ofdm_symbol_size_khz_1dot25; + } + output[k] = qpsk[(eNB->lte_gold_mbsfn_khz_1dot25_table[subframe][mprime_dword]>>(2*mprime_qpsk_symb))&3]; + mprime++; + } + + return(0); +} + + +int lte_dl_mbsfn_khz_1dot25_rx(PHY_VARS_UE *ue, + int *output, + int subframe) +{ + + unsigned int mprime,mprime_dword,mprime_qpsk_symb,m; + unsigned short k=0; + unsigned int qpsk[4]; + + // This includes complex conjugate for channel estimation + + ((short *)&qpsk[0])[0] = ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[0])[1] = -ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[1])[0] = -ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[1])[1] = -ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[2])[0] = ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[2])[1] = ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[3])[0] = -ONE_OVER_SQRT2_Q15; + ((short *)&qpsk[3])[1] = ONE_OVER_SQRT2_Q15; + + mprime = 3*(110 - ue->frame_parms.N_RB_DL); + + for (m=0; m<ue->frame_parms.N_RB_DL*24; m++) // m = 0:24*N_RB_DL-1 + { mprime_dword = mprime>>4; + mprime_qpsk_symb = mprime&0xf; + + // this is r_mprime from 3GPP 36-211 6.10.1.2 + output[k] = qpsk[(ue->lte_gold_mbsfn_khz_1dot25_table[subframe][mprime_dword]>>(2*mprime_qpsk_symb))&3]; + + mprime++; + k++; + + } + + return(0); +} + +#endif // MAKE Rel14 + diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c index 69dbb705db8fd4cd85f215f50a63949f5fb88ed1..a260a50dbe9c6558d677a68deab0466fc2b96806 100644 --- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c @@ -95,6 +95,34 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void lte_gold_mbsfn_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_khz_1dot25_table[10][150],uint16_t Nid_mbsfn){ + unsigned char sfn; + unsigned int n,x1,x2;//,x1tmp,x2tmp; + + for (sfn=0; sfn<10; sfn++) { + x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + (7*(1+sfn))))<<9); //cinit + x1 = 1+ (1<<31); + x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31); + for (n=1; n<50; n++) { + x1 = (x1>>1) ^ (x1>>4); + x1 = x1 ^ (x1<<31) ^ (x1<<28); + x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); + x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); + } + for (n=0; n<150; n++) { + x1 = (x1>>1) ^ (x1>>4); + x1 = x1 ^ (x1<<31) ^ (x1<<28); + x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); + x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); + lte_gold_mbsfn_khz_1dot25_table[sfn][n] = x1^x2; + } + } +} +#endif + + + #ifdef LTE_GOLD_MAIN main() { diff --git a/openair1/PHY/LTE_REFSIG/lte_refsig.h b/openair1/PHY/LTE_REFSIG/lte_refsig.h index 1bac0d14fc8322e26bf8ca519e28e653685b1554..45402436f70abbc6756682b999fe1532f5c74c6e 100644 --- a/openair1/PHY/LTE_REFSIG/lte_refsig.h +++ b/openair1/PHY/LTE_REFSIG/lte_refsig.h @@ -57,6 +57,8 @@ void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_table[10][3][42],uint16_t Nid_MBSFN); +void lte_gold_mbsfn_khz_1dot25 (LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_1khz_1dot25_table[10][150],uint16_t Nid_MBSFN); + /*! \brief This function generates the cell-specific reference signal sequence (36-211, Sec 6.10.1.1) @param phy_vars_eNB Pointer to eNB variables @@ -144,6 +146,10 @@ int lte_dl_mbsfn_rx(PHY_VARS_UE *phy_vars_ue, int subframe, unsigned char l); +int lte_dl_mbsfn_khz_1dot25_rx(PHY_VARS_UE *ue, + int *output, + int subframe); + diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c index a66344611b8c61921472f70b3a2766d9e6586cfe..95371d03d944e12b44a8fb48b9d1f9e9a454ad3a 100644 --- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c +++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c @@ -349,6 +349,43 @@ int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint } } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe,uint8_t beamforming_mode) +{ + //int G_adj; + + /*if (is_pmch_subframe(frame,subframe,frame_parms) == 0) { + G_adj= adjust_G(frame_parms,rb_alloc,mod_order,subframe); + + //printf("get_G subframe %d mod_order %d, nb_rb %d: rb_alloc %x,%x,%x,%x, G_adj %d\n",subframe,mod_order,nb_rb,rb_alloc[3],rb_alloc[2],rb_alloc[1],rb_alloc[0], G_adj); + if (frame_parms->Ncp==NORMAL) { // normal prefix + // PDDDPDD PDDDPDD - 13 PDSCH symbols, 10 full, 3 w/ pilots = 10*12 + 3*8 + // PCDDPDD PDDDPDD - 12 PDSCH symbols, 9 full, 3 w/ pilots = 9*12 + 3*8 + // PCCDPDD PDDDPDD - 11 PDSCH symbols, 8 full, 3 w/pilots = 8*12 + 3*8 + if (beamforming_mode==0 && frame_parms->nb_antenna_ports_eNB!=1) + return((((int)nb_rb * mod_order * ((11-num_pdcch_symbols)*12 + 3*8)) - G_adj)*Nl); + else if(beamforming_mode==7) + return(((int)nb_rb * mod_order * ((7-num_pdcch_symbols)*12 + 3*10 + 4*9)) - G_adj); + else //SISO + return(((int)nb_rb * mod_order * ((11-num_pdcch_symbols)*12 + 3*10)) - G_adj); + } else { + // PDDPDD PDDPDD - 11 PDSCH symbols, 8 full, 3 w/ pilots = 8*12 + 3*8 + // PCDPDD PDDPDD - 10 PDSCH symbols, 7 full, 3 w/ pilots = 7*12 + 3*8 + // PCCPDD PDDPDD - 9 PDSCH symbols, 6 full, 3 w/pilots = 6*12 + 3*8 + if (frame_parms->nb_antenna_ports_eNB!=1) + return((((int)nb_rb * mod_order * ((9-num_pdcch_symbols)*12 + 3*8)) - G_adj)*Nl); + else if(beamforming_mode==7) + return(((int)nb_rb * mod_order * ((5-num_pdcch_symbols)*12 + 3*8 + 4*9)) - G_adj); + else //SISO + return(((int)nb_rb * mod_order * ((9-num_pdcch_symbols)*12 + 3*10)) - G_adj); + } + } else { // This is an MBSFN subframe + return((int)frame_parms->N_RB_DL * mod_order * 102); + }*/ + return((int)frame_parms->N_RB_DL * mod_order * 120); +} +#endif + // following function requires dlsch_tbs_full.h #include "PHY/LTE_TRANSPORT/dlsch_tbs_full.h" diff --git a/openair1/PHY/LTE_TRANSPORT/phich_common.c b/openair1/PHY/LTE_TRANSPORT/phich_common.c index 72e9ad134ab60a1eb0b52e88140769783a8d90a9..89c826be66db08e69a8310417a8ea6758b4db3bd 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich_common.c +++ b/openair1/PHY/LTE_TRANSPORT/phich_common.c @@ -33,7 +33,13 @@ #include "PHY/defs_eNB.h" -uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { +uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) +{ + // for FeMBMS + if(frame_parms->FeMBMS_active!=0){ + return(0); + } + // for FDD if (frame_parms->frame_type == FDD) return 1; diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c index a4821a420ff27f87731c6b737d515598e5758343..fb9b4ea1e9e6fd33901ecc541f5e266e4034d37c 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c @@ -22,6 +22,88 @@ #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" +/*! \file PHY/LTE_TRANSPORT/pmch_common.c +* \brief This includes routines for decoding the UE FeMBMS/PMCH physical/multicast/transport channel 3GPP TS 36.211 version 14.2.0 Release 14 Sections 6.5/6.10.2 +* \author J. Morgade +* \date 2019 +* \version 0.1 +* \company Vicomtech +* \email: javier.morgade@ieee.org +* \note +* \warning +*/ + + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +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<<frame_parms->NonMBSFN_config.radioframeAllocationPeriod; + if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + switch (subframe) { + case 0: + return(1); //This should be CAS + break; + } + } + } + return (0); +} + +int is_fembms_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) +{ + uint32_t period; + + if(frame_parms->NonMBSFN_config_flag ) { + period = 4<<frame_parms->NonMBSFN_config.radioframeAllocationPeriod; + if ((frame % period) == frame_parms->NonMBSFN_config.radioframeAllocationOffset) { + switch (subframe) { + 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; + } + } else { //Then regular MBSFN FeMBMS subframe + return(1); + } + } + return(0); +} +#endif + int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms) { diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h index 0cc59360b612c57a7846abe5d4378a0517b791a7..5bccca25b7351e5963f8273a680b566e14d2466f 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h @@ -96,6 +96,8 @@ uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL); int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode); +int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode); + int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe); int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol); @@ -256,6 +258,27 @@ void init_prach_tables(int N_ZC); */ int is_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +/*! + \brief Return the status of CAS in this frame/subframe + @param frame Frame index + @param subframe Subframe index + @param frame_parms Pointer to frame parameters + @returns 1 if subframe is for CAS +*/ +int is_fembms_cas_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 + @param subframe Subframe index + @param frame_parms Pointer to frame parameters + @returns 1 if subframe is for MBSFN +*/ +int is_fembms_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parms); +#endif + + /** \brief This routine expands a single (wideband) PMI to subband PMI bitmap similar to the one used in the UCI and in the dlsch_modulation routine @param frame_parms Pointer to DL frame configuration parameters diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c index 2c6f31e24461b3b88e32955be531849761b31546..3c7e3f986b633aa7004149c8a0fb798fa318f755 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c @@ -1930,7 +1930,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, if (((L>1) && ((crc == si_rnti)|| (crc == p_rnti)|| - (crc == ra_rnti)))|| + (crc == ra_rnti)/*||(crc == 0xfff9)*/))|| (crc == pdcch_vars[eNB_id]->crnti)) { dci_alloc[*dci_cnt].dci_length = sizeof_bits; dci_alloc[*dci_cnt].rnti = crc; @@ -1965,7 +1965,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, #endif } - if (crc==si_rnti) { + if (crc==si_rnti /*|| crc==0xfff9*/) { dci_alloc[*dci_cnt].format = format_si; *dci_cnt = *dci_cnt+1; } else if (crc==p_rnti) { diff --git a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c index 9cdecd7493352bae2c4539217094b4cabfa0b079..968597bfb8fdc5ada6342b9f497ab3b12be3ba31 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c @@ -120,26 +120,54 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { pbch_decoded = 0; for (frame_mod4=0; frame_mod4<4; frame_mod4++) { - pbch_tx_ant = rx_pbch(&ue->common_vars, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (ue->FeMBMS_active != 2){ +#endif + pbch_tx_ant = rx_pbch(&ue->common_vars, ue->pbch_vars[0], frame_parms, 0, SISO, ue->high_speed_flag, frame_mod4); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + }else{ + pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, + ue->pbch_vars[0], + frame_parms, + 0, + SISO, + ue->high_speed_flag, + frame_mod4); + } +#endif - if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) { - pbch_decoded = 1; - break; + if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) { + pbch_decoded = 1; + break; } - pbch_tx_ant = rx_pbch(&ue->common_vars, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (ue->FeMBMS_active != 2){ +#endif + pbch_tx_ant = rx_pbch(&ue->common_vars, + ue->pbch_vars[0], + frame_parms, + 0, + ALAMOUTI, + ue->high_speed_flag, + frame_mod4); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + }else{ + pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, ue->pbch_vars[0], frame_parms, 0, ALAMOUTI, ue->high_speed_flag, frame_mod4); + } +#endif if ((pbch_tx_ant>0) && (pbch_tx_ant<=2)) { pbch_decoded = 1; @@ -189,6 +217,9 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { break; } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(ue->FeMBMS_active != 2) { +#endif // now check for PHICH parameters frame_parms->phich_config_common.phich_duration = (PHICH_DURATION_t)((ue->pbch_vars[0]->decoded_output[2]>>4)&1); dummy = (ue->pbch_vars[0]->decoded_output[2]>>2)&3; @@ -235,6 +266,26 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) { frame_parms->N_RB_DL, frame_parms->phich_config_common.phich_duration, phich_resource); //frame_parms->phich_config_common.phich_resource); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + }else{ + for(int i=0; i<RX_NB_TH;i++) + { + ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&31)<<1) + (ue->pbch_vars[0]->decoded_output[1]>>7))<<4; + ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; + } + LOG_D(PHY,"[UE%d] Initial sync: FeMBMS pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, AdditionalNonMBSFN_SF %d, frame_mod4 %d\n", + ue->Mod_id, + frame_parms->nb_antenna_ports_eNB, + pbch_tx_ant, + ue->proc.proc_rxtx[0].frame_rx, + frame_parms->N_RB_DL, + 0, + frame_mod4 + ); + + } +#endif return(0); } else { return(-1); @@ -301,8 +352,21 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { // LOG_M("rxdata2.m","rxd2",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); LOG_D(PHY,"FDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", + frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (ret==-1){ + ue->FeMBMS_active = 2; + ret = pbch_detection(ue,mode); + if (ret==-1){ + ue->FeMBMS_active = 0; + frame_parms->FeMBMS_active = 0; + } + else frame_parms->FeMBMS_active = 1; + LOG_D(PHY,"FeMBMS Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", frame_parms->Nid_cell,metric_fdd_ncp,phase_fdd_ncp,flip_fdd_ncp,ret); + } +#endif } else { LOG_D(PHY,"FDD Normal prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot); } @@ -342,6 +406,23 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode) { // LOG_M("rxdata3.m","rxd3",ue->common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1); LOG_D(PHY,"FDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (ret==-1){ + ue->FeMBMS_active = 2; + ret = pbch_detection(ue,mode); + if (ret==-1){ + ue->FeMBMS_active = 0; + frame_parms->FeMBMS_active = 0; + } + else frame_parms->FeMBMS_active = 1; + LOG_I(PHY,"FeMBMS CAS Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n", + frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret); + + } +#endif + + } else { LOG_D(PHY,"FDD Extended prefix: SSS error condition: sync_pos %d, sync_pos_slot %d\n", sync_pos, sync_pos_slot); } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c index a6acec9ca3762499a8c7fbed3032f253c3f1a7cf..5884a159ac54e40399f1edd74d2037b72e3cb6bd 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pbch_ue.c @@ -29,6 +29,8 @@ * \note * \warning */ + + #include "PHY/defs_UE.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_extern.h" @@ -630,3 +632,201 @@ uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars, } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void pbch_unscrambling_fembms(LTE_DL_FRAME_PARMS *frame_parms, + int8_t* llr, + uint32_t length, + uint8_t frame_mod4) +{ + int i; + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in first call to 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_unscrambling: Nid_cell = %d, x2 = %d, frame_mod4 %d length %d\n",frame_parms->Nid_cell,x2,frame_mod4,length); + for (i=0; i<length; i++) { + if (i%32==0) { + s = lte_gold_generic(&x1, &x2, reset); + // printf("lte_gold[%d]=%x\n",i,s); + reset = 0; + } + // take the quarter of the PBCH that corresponds to this frame + if ((i>=(frame_mod4*(length>>2))) && (i<((1+frame_mod4)*(length>>2)))) { + + if (((s>>(i%32))&1)==0) + llr[i] = -llr[i]; + } + } +} + +uint16_t rx_pbch_fembms(LTE_UE_COMMON *lte_ue_common_vars, + LTE_UE_PBCH *lte_ue_pbch_vars, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t eNB_id, + MIMO_mode_t mimo_mode, + uint32_t high_speed_flag, + uint8_t frame_mod4) +{ + + uint8_t log2_maxh;//,aatx,aarx; + int max_h=0; + + int symbol,i; + uint32_t nsymb = (frame_parms->Ncp==0) ? 14:12; + uint16_t pbch_E; + uint8_t pbch_a[8]; + uint8_t RCC; + + int8_t *pbch_e_rx; + uint8_t *decoded_output = lte_ue_pbch_vars->decoded_output; + uint16_t crc; + + + // pbch_D = 16+PBCH_A; + + pbch_E = (frame_parms->Ncp==0) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) + pbch_e_rx = <e_ue_pbch_vars->llr[frame_mod4*(pbch_E>>2)]; +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] starting symbol loop (Ncp %d, frame_mod4 %d,mimo_mode %d\n",frame_parms->Ncp,frame_mod4,mimo_mode); +#endif + + // clear LLR buffer + memset(lte_ue_pbch_vars->llr,0,pbch_E); + + for (symbol=(nsymb>>1); symbol<(nsymb>>1)+4; symbol++) { + +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] starting extract\n"); +#endif + pbch_extract(lte_ue_common_vars->common_vars_rx_data_per_thread[0].rxdataF, + lte_ue_common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id], + lte_ue_pbch_vars->rxdataF_ext, + lte_ue_pbch_vars->dl_ch_estimates_ext, + symbol, + high_speed_flag, + frame_parms); +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PHY] PBCH Symbol %d\n",symbol); + LOG_D(PHY,"[PHY] PBCH starting channel_level\n"); +#endif + + max_h = pbch_channel_level(lte_ue_pbch_vars->dl_ch_estimates_ext, + frame_parms, + symbol); + log2_maxh = 3+(log2_approx(max_h)/2); + +#ifdef DEBUG_PBCH + + LOG_D(PHY,"[PHY] PBCH log2_maxh = %d (%d)\n",log2_maxh,max_h); +#endif + + pbch_channel_compensation(lte_ue_pbch_vars->rxdataF_ext, + lte_ue_pbch_vars->dl_ch_estimates_ext, + lte_ue_pbch_vars->rxdataF_comp, + frame_parms, + symbol, + log2_maxh); // log2_maxh+I0_shift + + if (frame_parms->nb_antennas_rx > 1) + pbch_detection_mrc(frame_parms, + lte_ue_pbch_vars->rxdataF_comp, + symbol); + + + if (mimo_mode == ALAMOUTI) { + pbch_alamouti(frame_parms,lte_ue_pbch_vars->rxdataF_comp,symbol); + } else if (mimo_mode != SISO) { + LOG_D(PHY,"[PBCH][RX] Unsupported MIMO mode\n"); + return(-1); + } + + if (symbol>(nsymb>>1)+1) { + pbch_quantize(pbch_e_rx, + (short*)&(lte_ue_pbch_vars->rxdataF_comp[0][(symbol%(nsymb>>1))*72]), + 144); + + pbch_e_rx+=144; + } else { + pbch_quantize(pbch_e_rx, + (short*)&(lte_ue_pbch_vars->rxdataF_comp[0][(symbol%(nsymb>>1))*72]), + 96); + + pbch_e_rx+=96; + } + + + } + + pbch_e_rx = lte_ue_pbch_vars->llr; + + + + //un-scrambling +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] doing unscrambling\n"); +#endif + +pbch_unscrambling_fembms(frame_parms, + pbch_e_rx, + pbch_E, + frame_mod4); + + + //un-rate matching +#ifdef DEBUG_PBCH + LOG_D(PHY,"[PBCH] doing un-rate-matching\n"); +#endif + + + memset(dummy_w_rx,0,3*3*(16+PBCH_A)); + RCC = generate_dummy_w_cc(16+PBCH_A, + dummy_w_rx); + + + lte_rate_matching_cc_rx(RCC,pbch_E,pbch_w_rx,dummy_w_rx,pbch_e_rx); + + sub_block_deinterleaving_cc((unsigned int)(PBCH_A+16), + &pbch_d_rx[96], + &pbch_w_rx[0]); + + memset(pbch_a,0,((16+PBCH_A)>>3)); + + + + + phy_viterbi_lte_sse2(pbch_d_rx+96,pbch_a,16+PBCH_A); + + // Fix byte endian of PBCH (bit 23 goes in first) + for (i=0; i<(PBCH_A>>3); i++) + decoded_output[(PBCH_A>>3)-i-1] = pbch_a[i]; + +#ifdef DEBUG_PBCH + + for (i=0; i<(PBCH_A>>3); i++) + LOG_I(PHY,"[PBCH] pbch_a[%d] = %x\n",i,decoded_output[i]); + +#endif //DEBUG_PBCH + +#ifdef DEBUG_PBCH + LOG_I(PHY,"PBCH CRC %x : %x\n", + crc16(pbch_a,PBCH_A), + ((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]); +#endif + + crc = (crc16(pbch_a,PBCH_A)>>16) ^ + (((uint16_t)pbch_a[PBCH_A>>3]<<8)+pbch_a[(PBCH_A>>3)+1]); + + if (crc == 0x0000) + return(1); + else if (crc == 0xffff) + return(2); + else if (crc == 0x5555) + return(4); + else + return(-1); +} +#endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c index 0a12d393d46954f1639a56917d8e53647f98bbe3..362c1bf77342952ab9b5ca40bcf5af4404e3ded8 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c @@ -19,6 +19,18 @@ * contact@openairinterface.org */ +/*! \file PHY/LTE_UE_TRANSPORT/pmch_ue.c +* \brief This includes routines for decoding the UE FeMBMS/PMCH physical/multicast/transport channel 3GPP TS 36.211 version 14.2.0 Release 14 Sections 6.5/6.10.2 +* \author J. Morgade +* \date 2019 +* \version 0.1 +* \company Vicomtech +* \email: javier.morgade@ieee.org +* \note +* \warning +*/ + + #include "PHY/defs_UE.h" #include "PHY/phy_extern_ue.h" #include "PHY/sse_intrin.h" @@ -132,6 +144,39 @@ void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) } } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void mch_extract_rbs_khz_1dot25(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + /*unsigned char symbol,*/ + unsigned char subframe, + LTE_DL_FRAME_PARMS *frame_parms) +{ + + int i,j,offset,aarx,numext; + + if( (subframe&0x1) == 0){ + offset=0; + }else{ + offset=3; + } + numext=0; + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + for (i=0,j=0; i<frame_parms->N_RB_DL*72; i++) { + if( ((i-offset)%6) != 0 ){ + //rxdataF_ext[aarx][j+0] = rxdataF[aarx][i+4344 +0]; + rxdataF_ext[aarx][j+0] = rxdataF[aarx][i+frame_parms->first_carrier_offset_khz_1dot25 +0]; + rxdataF_ext[aarx][(frame_parms->N_RB_DL*60)+j+0] = rxdataF[aarx][i+1+0]; //DC + dl_ch_estimates_ext[aarx][j+0] = dl_ch_estimates[aarx][i+0]; + dl_ch_estimates_ext[aarx][(frame_parms->N_RB_DL*60)+j+0] = dl_ch_estimates[aarx][i+(frame_parms->N_RB_DL*72)+0]; + numext+=2; + j++; + } + } + } +} +#endif void mch_extract_rbs(int **rxdataF, @@ -145,7 +190,6 @@ void mch_extract_rbs(int **rxdataF, int pilots=0,i,j,offset,aarx; - // printf("Extracting PMCH: symbol %d\n",symbol); if ((symbol==2)|| (symbol==10)) { pilots = 1; @@ -240,6 +284,62 @@ void mch_channel_level(int **dl_ch_estimates_ext, #endif } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void mch_channel_level_khz_1dot25(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + int *avg, + /*uint8_t symbol,*/ + unsigned short nb_rb) +{ + + int i,aarx,nre; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128,avg128; +#elif defined(__arm__) + int32x4_t avg128; +#endif + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { +#if defined(__x86_64__) || defined(__i386__) + //clear average level + avg128 = _mm_setzero_si128(); + // 5 is always a symbol with no pilots for both normal and extended prefix + + dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][0/*symbol*frame_parms->N_RB_DL*12*/]; +#elif defined(__arm__) + + +#endif + /*if ((symbol == 2) || (symbol == 6) || (symbol == 10)) + nre = (frame_parms->N_RB_DL*6); + else + nre = (frame_parms->N_RB_DL*12);*/ + nre = frame_parms->N_RB_DL*12*10; + //nre = frame_parms->N_RB_DL*12; + + for (i=0; i<(nre>>2); i++) { +#if defined(__x86_64__) || defined(__i386__) + avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); +#elif defined(__arm__) + +#endif + } + + avg[aarx] = (((int*)&avg128)[0] + + ((int*)&avg128)[1] + + ((int*)&avg128)[2] + + ((int*)&avg128)[3])/nre; + + //printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} +#endif + + void mch_channel_compensation(int **rxdataF_ext, int **dl_ch_estimates_ext, int **dl_ch_mag, @@ -389,6 +489,164 @@ void mch_channel_compensation(int **rxdataF_ext, } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void mch_channel_compensation_khz_1dot25(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + LTE_DL_FRAME_PARMS *frame_parms, + /*unsigned char symbol,*/ + unsigned char mod_order, + unsigned char output_shift) +{ + + int aarx,nre,i; +#if defined(__x86_64__) || defined(__i386__) + __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; +#elif defined(__arm__) + +#endif + /*if ((symbol == 2) || (symbol == 6) || (symbol == 10)) + nre = frame_parms->N_RB_DL*6; + else + nre = frame_parms->N_RB_DL*12;*/ + + nre = frame_parms->N_RB_DL*12*10; + + +#if defined(__x86_64__) || defined(__i386__) + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128b = _mm_set1_epi16(QAM64_n2); + } +#elif defined(__arm__) + +#endif + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + +#if defined(__x86_64__) || defined(__i386__) + + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][0]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[aarx][0]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[aarx][0]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][0]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][0]; + + #elif defined(__arm__) + +#endif + + for (i=0; i<(nre>>2); i+=2) { + if (mod_order>2) { + // get channel amplitude if not QPSK +#if defined(__x86_64__) || defined(__i386__) + + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + // store channel magnitude here in a new field of dlsch + + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + + + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + + + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + +#elif defined(__arm__) + +#endif + } + +#if defined(__x86_64__) || defined(__i386__) + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + + dl_ch128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + +#elif defined(__arm__) + +#endif + } + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + +} +#endif + + void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, int **dl_ch_mag, @@ -442,6 +700,65 @@ void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, #endif } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void mch_detection_mrc_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + int **dl_ch_mag, + int **dl_ch_magb/*, + unsigned char symbol*/) +{ + + + int i; +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; +#elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; +#endif + if (frame_parms->nb_antennas_rx>1) { + +#if defined(__x86_64__) || defined(__i386__) + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][0]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][0]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][0]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[1][0]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][0]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[1][0]; + +#elif defined(__arm__) + rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][0]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][0]; + dl_ch_mag128_0 = (int16x8_t *)&dl_ch_mag[0][0]; + dl_ch_mag128_1 = (int16x8_t *)&dl_ch_mag[1][0]; + dl_ch_mag128_0b = (int16x8_t *)&dl_ch_magb[0][0]; + dl_ch_mag128_1b = (int16x8_t *)&dl_ch_magb[1][0]; + +#endif + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; i<frame_parms->N_RB_DL*30; i++) { +#if defined(__x86_64__) || defined(__i386__) + rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); + dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); + dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); +#elif defined(__arm__) + rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); + dl_ch_mag128_0[i] = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]); + dl_ch_mag128_0b[i] = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]); +#endif + } + } +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} +#endif + + + + + int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, short *dlsch_llr, @@ -468,7 +785,6 @@ int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, len = frame_parms->N_RB_DL*12; } - // printf("dlsch_qpsk_llr: symbol %d,len %d,pbch_pss_sss_adjust %d\n",symbol,len,pbch_pss_sss_adjust); for (i=0; i<len; i++) { *llr32 = *rxF; rxF++; @@ -485,13 +801,55 @@ int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, return(0); } -//---------------------------------------------------------------------------------------------- -// 16-QAM -//---------------------------------------------------------------------------------------------- +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int mch_qpsk_llr_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, + /*unsigned char symbol,*/ + short **llr32p) +{ -void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, - int **rxdataF_comp, - short *dlsch_llr, + uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][0/*(symbol*frame_parms->N_RB_DL*12)*/]; + //uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + uint32_t *llr32; + int i,len; + + //if (symbol==0) { + llr32 = (uint32_t*)dlsch_llr; + //} else { + //llr32 = (uint32_t*)(*llr32p); + //} + + //AssertFatal(llr32!=NULL,"dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32); + AssertFatal(llr32!=NULL,"dlsch_qpsk_llr: llr is null, llr32=%p\n",llr32); + + len = frame_parms->N_RB_DL*12*10; + + for (i=0; i<len; i++) { + *llr32 = *rxF; + rxF++; + llr32++; + } + + *llr32p = (short *)llr32; + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif + + return(0); +} +#endif + + +//---------------------------------------------------------------------------------------------- +// 16-QAM +//---------------------------------------------------------------------------------------------- + +void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, int **dl_ch_mag, unsigned char symbol, int16_t **llr32p) @@ -599,6 +957,114 @@ void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, #endif } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void mch_16qam_llr_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, + int **dl_ch_mag, + /*unsigned char symbol,*/ + int16_t **llr32p) +{ + +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxF = (__m128i*)&rxdataF_comp[0][0]; + __m128i *ch_mag; + __m128i llr128[2],xmm0; + uint32_t *llr32; +#elif defined(__arm__) + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][0]; + int16x8_t *ch_mag; + int16x8_t llr128[2],xmm0; + int16_t *llr16; +#endif + int i,len; + unsigned char len_mod4=0; + +#if defined(__x86_64__) || defined(__i386__) + //if (symbol==2) { + llr32 = (uint32_t*)dlsch_llr; + //} else { + //llr32 = (uint32_t*)*llr32p; + //} +#elif defined(__arm__) + //if (symbol==2) { + llr16 = (int16_t*)dlsch_llr; + //} else { + // llr16 = (int16_t*)*llr32p; + //} +#endif +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&dl_ch_mag[0][0]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&dl_ch_mag[0][0]; +#endif + len = frame_parms->N_RB_DL*12*10; + + + + // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE) + //if (symbol==2) + *llr32p = dlsch_llr + (len<<2); + //else + //*llr32p += (len<<2); + + len_mod4 = len&3; + len>>=2; // length in quad words (4 REs) + len+=(len_mod4==0 ? 0 : 1); + + for (i=0; i<len; i++) { + +#if defined(__x86_64__) || defined(__i386__) + xmm0 = _mm_abs_epi16(rxF[i]); + xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); + + // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 + llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); + llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); + llr32[0] = ((uint32_t *)&llr128[0])[0]; + llr32[1] = ((uint32_t *)&llr128[0])[1]; + llr32[2] = ((uint32_t *)&llr128[0])[2]; + llr32[3] = ((uint32_t *)&llr128[0])[3]; + llr32[4] = ((uint32_t *)&llr128[1])[0]; + llr32[5] = ((uint32_t *)&llr128[1])[1]; + llr32[6] = ((uint32_t *)&llr128[1])[2]; + llr32[7] = ((uint32_t *)&llr128[1])[3]; + llr32+=8; + +#elif defined(__arm__) + xmm0 = vabsq_s16(rxF[i]); + xmm0 = vsubq_s16(ch_mag[i],xmm0); + + // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2 + + llr16[0] = vgetq_lane_s16(rxF[i],0); + llr16[1] = vgetq_lane_s16(xmm0,0); + llr16[2] = vgetq_lane_s16(rxF[i],1); + llr16[3] = vgetq_lane_s16(xmm0,1); + llr16[4] = vgetq_lane_s16(rxF[i],2); + llr16[5] = vgetq_lane_s16(xmm0,2); + llr16[6] = vgetq_lane_s16(rxF[i],2); + llr16[7] = vgetq_lane_s16(xmm0,3); + llr16[8] = vgetq_lane_s16(rxF[i],4); + llr16[9] = vgetq_lane_s16(xmm0,4); + llr16[10] = vgetq_lane_s16(rxF[i],5); + llr16[11] = vgetq_lane_s16(xmm0,5); + llr16[12] = vgetq_lane_s16(rxF[i],6); + llr16[13] = vgetq_lane_s16(xmm0,6); + llr16[14] = vgetq_lane_s16(rxF[i],7); + llr16[15] = vgetq_lane_s16(xmm0,7); + llr16+=16; +#endif + + } + +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} +#endif + //---------------------------------------------------------------------------------------------- // 64-QAM //---------------------------------------------------------------------------------------------- @@ -666,10 +1132,147 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, xmm2 = vsubq_s16(ch_magb[i],xmm2); #endif + // loop over all LLRs in quad word (24 coded bits) /* - printf("pmch i: %d => mag (%d,%d) (%d,%d)\n",i,((short *)&ch_mag[i])[0],((short *)&ch_magb[i])[0], - ((short *)&rxF[i])[0],((short *)&rxF[i])[1]); + for (j=0;j<8;j+=2) { + llr2[0] = ((short *)&rxF[i])[j]; + llr2[1] = ((short *)&rxF[i])[j+1]; + llr2[2] = _mm_extract_epi16(xmm1,j); + llr2[3] = _mm_extract_epi16(xmm1,j+1);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,j);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,j+1);//((short *)&xmm2)[j+1]; + + llr2+=6; + } */ + llr2[0] = ((short *)&rxF[i])[0]; + llr2[1] = ((short *)&rxF[i])[1]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,0); + llr2[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,0); + llr2[3] = vgetq_lane_s16(xmm1,1);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,0);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,1);//((short *)&xmm2)[j+1]; +#endif + + llr2+=6; + llr2[0] = ((short *)&rxF[i])[2]; + llr2[1] = ((short *)&rxF[i])[3]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,2); + llr2[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,2); + llr2[3] = vgetq_lane_s16(xmm1,3);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,2);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,3);//((short *)&xmm2)[j+1]; +#endif + llr2+=6; + llr2[0] = ((short *)&rxF[i])[4]; + llr2[1] = ((short *)&rxF[i])[5]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,4); + llr2[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,4); + llr2[3] = vgetq_lane_s16(xmm1,5);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,4);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,5);//((short *)&xmm2)[j+1]; +#endif + llr2+=6; + llr2[0] = ((short *)&rxF[i])[6]; + llr2[1] = ((short *)&rxF[i])[7]; +#if defined(__x86_64__) || defined(__i386__) + llr2[2] = _mm_extract_epi16(xmm1,6); + llr2[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1]; + llr2[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j]; + llr2[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1]; +#elif defined(__arm__) + llr2[2] = vgetq_lane_s16(xmm1,6); + llr2[3] = vgetq_lane_s16(xmm1,7);//((short *)&xmm1)[j+1]; + llr2[4] = vgetq_lane_s16(xmm2,6);//((short *)&xmm2)[j]; + llr2[5] = vgetq_lane_s16(xmm2,7);//((short *)&xmm2)[j+1]; +#endif + llr2+=6; + } + + *llr_save = llr; +#if defined(__x86_64__) || defined(__i386__) + _mm_empty(); + _m_empty(); +#endif +} + + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void mch_64qam_llr_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + short *dlsch_llr, + int **dl_ch_mag, + int **dl_ch_magb, + /*unsigned char symbol,*/ + short **llr_save) +{ + +#if defined(__x86_64__) || defined(__i386__) + __m128i xmm1,xmm2,*ch_mag,*ch_magb; + __m128i *rxF = (__m128i*)&rxdataF_comp[0][0]; +#elif defined(__arm__) + int16x8_t xmm1,xmm2,*ch_mag,*ch_magb; + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][0]; +#endif + + int i,len,len2; + // int j=0; + unsigned char len_mod4; + short *llr; + int16_t *llr2; + + //if (symbol==2) + llr = dlsch_llr; + //else + //llr = *llr_save; + +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&dl_ch_mag[0][0]; + ch_magb = (__m128i*)&dl_ch_magb[0][0]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&dl_ch_mag[0][0]; + ch_magb = (int16x8_t*)&dl_ch_magb[0][0]; +#endif + + len = frame_parms->N_RB_DL*12*10; + + + llr2 = llr; + llr += (len*6); + + len_mod4 =len&3; + len2=len>>2; // length in quad words (4 REs) + len2+=(len_mod4?0:1); + + + for (i=0; i<len2; i++) { +#if defined(__x86_64__) || defined(__i386__) + xmm1 = _mm_abs_epi16(rxF[i]); + xmm1 = _mm_subs_epi16(ch_mag[i],xmm1); + xmm2 = _mm_abs_epi16(xmm1); + xmm2 = _mm_subs_epi16(ch_magb[i],xmm2); +#elif defined(__arm__) + xmm1 = vabsq_s16(rxF[i]); + xmm1 = vsubq_s16(ch_mag[i],xmm1); + xmm2 = vabsq_s16(xmm1); + xmm2 = vsubq_s16(ch_magb[i],xmm2); +#endif + // loop over all LLRs in quad word (24 coded bits) /* for (j=0;j<8;j+=2) { @@ -748,6 +1351,8 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, _m_empty(); #endif } +#endif + int avg_pmch[4]; int rx_pmch(PHY_VARS_UE *ue, @@ -762,7 +1367,6 @@ int rx_pmch(PHY_VARS_UE *ue, LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id]; int avgs,aarx; - //printf("*********************mch: symbol %d\n",symbol); mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], @@ -839,4 +1443,99 @@ int rx_pmch(PHY_VARS_UE *ue, return(0); } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int rx_pmch_khz_1dot25(PHY_VARS_UE *ue, + unsigned char eNB_id, + uint8_t subframe/*, + unsigned char symbol*/ + ,int mcs) // currently work around TOFIX +{ + //unsigned int symbol; + + LTE_UE_COMMON *common_vars = &ue->common_vars; + LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id]; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + //LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id]; + int avgs,aarx; + + + mch_extract_rbs_khz_1dot25(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id], + pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + /*symbol,*/ + subframe, + frame_parms); + + mch_channel_level_khz_1dot25(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg_pmch, + /*symbol,*/ + frame_parms->N_RB_DL); + + avgs = 0; + + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++){ + avgs = cmax(avgs,avg_pmch[aarx]); + } + + + if (get_Qm(mcs/*dlsch[0]->harq_processes[0]->mcs)==2*/)==2) + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) ;// + 2 + else + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); // + 5;// + 2*/ + + + + + mch_channel_compensation_khz_1dot25(pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->rxdataF_comp0, + frame_parms, + /*symbol,*/ + get_Qm(mcs/*dlsch[0]->harq_processes[0]->mcs*/), + pdsch_vars[eNB_id]->log2_maxh); + + if (frame_parms->nb_antennas_rx > 1){ + mch_detection_mrc_khz_1dot25(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0/*, + symbol*/); + } + + switch (get_Qm(mcs/*dlsch[0]->harq_processes[0]->mcs*/)) { + case 2 : + mch_qpsk_llr_khz_1dot25(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + /*symbol,*/ + pdsch_vars[eNB_id]->llr128); + break; + + case 4: + mch_16qam_llr_khz_1dot25(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + pdsch_vars[eNB_id]->dl_ch_mag0, + /*symbol,*/ + pdsch_vars[eNB_id]->llr128); + break; + + case 6: + mch_64qam_llr_khz_1dot25(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + /*symbol,*/ + pdsch_vars[eNB_id]->llr128); + break; + } + + return(0); +} +#endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index 6e48e29e235feafd5cc3b4f25365a4d653e82979..844f738d8829072948a2fcd9d552aad9539cd63e 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -72,6 +72,12 @@ int rx_pmch(PHY_VARS_UE *phy_vars_ue, uint8_t subframe, unsigned char symbol); +int rx_pmch_khz_1dot25(PHY_VARS_UE *ue, + unsigned char eNB_id, + uint8_t subframe/*, + unsigned char symbol*/ + ,int mcs); + /** \brief Dump OCTAVE/MATLAB files for PMCH debugging @param phy_vars_ue Pointer to UE variables @param eNB_id index of eNB in ue variables @@ -1125,6 +1131,20 @@ uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars, uint32_t high_speed_flag, uint8_t frame_mod4); +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +/*! \brief receiver for the PBCH FeMBMS + \returns number of tx antennas or -1 if error +*/ +uint16_t rx_pbch_fembms(LTE_UE_COMMON *lte_ue_common_vars, + LTE_UE_PBCH *lte_ue_pbch_vars, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t eNB_id, + MIMO_mode_t mimo_mode, + uint32_t high_speed_flag, + uint8_t frame_mod4); +#endif + + uint16_t rx_pbch_emul(PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t pbch_phase); diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 7e2a3c8a27778f75b59866ea60392916baf9c684..e545f368484ff5ba87d90a63a154dc87573738b2 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -52,6 +52,10 @@ int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, int sample_offset, int no_prefix); +int slot_fep_mbsfn_khz_1dot25(PHY_VARS_UE *phy_vars_ue, + int subframe, + int sample_offset); + int front_end_fft(PHY_VARS_UE *ue, unsigned char l, unsigned char Ns, diff --git a/openair1/PHY/MODULATION/slot_fep_mbsfn.c b/openair1/PHY/MODULATION/slot_fep_mbsfn.c index 272cbc5d60b0566562fb9d838c54f3396ac37b7e..d34570f41245e27f40a098588705c43220ef1640 100644 --- a/openair1/PHY/MODULATION/slot_fep_mbsfn.c +++ b/openair1/PHY/MODULATION/slot_fep_mbsfn.c @@ -204,3 +204,112 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue, #endif return(0); } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int slot_fep_mbsfn_khz_1dot25(PHY_VARS_UE *ue, + int subframe, + int sample_offset) +{ + + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + LTE_UE_COMMON *common_vars = &ue->common_vars; + uint8_t eNB_id = 0;//ue_common_vars->eNb_id; + + unsigned char aa; + //unsigned char frame_type = frame_parms->frame_type; // Frame Type: 0 - FDD, 1 - TDD; + unsigned int nb_prefix_samples; + int ofdm_symbol_size; + unsigned int subframe_offset; + unsigned int frame_length_samples = frame_parms->samples_per_tti * 10; + +void (*dft)(int16_t *,int16_t *, int); + + AssertFatal(frame_parms->frame_type == FDD, "Frame is TDD!\n"); + + switch (frame_parms->ofdm_symbol_size) { + + case 128: + dft = dft1536; + ofdm_symbol_size=1536; + nb_prefix_samples=384; + break; + case 256: + AssertFatal(1==0,"FeMBMS dft3072 not implemented\n"); + dft = dft3072; + ofdm_symbol_size=3072; + nb_prefix_samples=768; + break; + + case 512: + dft = dft6144; + nb_prefix_samples=1536; + ofdm_symbol_size=6144; + break; + + case 1024: + dft = dft12288; + nb_prefix_samples=3072; + ofdm_symbol_size=12288; + break; + + case 1536: + dft = dft18432; + nb_prefix_samples=4608; + ofdm_symbol_size=18432; + break; + + case 2048: + dft = dft24576; + nb_prefix_samples=6144; + ofdm_symbol_size=24576; + break; + + default: + AssertFatal(1==0,"Illegal ofdm symbol size %d\n",frame_parms->ofdm_symbol_size); + break; + } + + subframe_offset = frame_parms->samples_per_tti * subframe; + +#ifdef DEBUG_FEP + LOG_D(PHY,"slot_fep_mbsfn125: subframe %d, nb_prefix_samples %d, subframe_offset %d, sample_offset %d\n", subframe, nb_prefix_samples,subframe_offset, + sample_offset); +#endif + + for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { + memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][0],0,ofdm_symbol_size*sizeof(int)); +#if UE_TIMING_TRACE + start_meas(&ue->rx_dft_stats); +#endif + dft((int16_t *)&common_vars->rxdata[aa][(sample_offset + + nb_prefix_samples + + subframe_offset - + SOFFSET) % frame_length_samples], + (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][0],1); + +#if UE_TIMING_TRACE + stop_meas(&ue->rx_dft_stats); +#endif + } + + + for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { + if (ue->perfect_ce == 0) { +#ifdef DEBUG_FEP + LOG_D(PHY,"Channel estimation eNB %d, aatx %d, subframe %d\n",eNB_id,aa,subframe); +#endif + lte_dl_mbsfn_khz_1dot25_channel_estimation(ue, + eNB_id, + 0, + subframe); + } + } + +#ifdef DEBUG_FEP + LOG_D(PHY,"slot_fep_mbsfn: done\n"); +#endif + + return(0); +} +#endif + diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index 0a34d9f12bb9420b285b1adb387a6d3b73ac77c7..1c40314fd4d2ab127cc93da73942982e12a9f87c 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -569,6 +569,10 @@ typedef struct PHY_VARS_eNB_NB_IoT_s { uint32_t lte_gold_uespec_table[2][20][2][21]; /// mbsfn reference symbols uint32_t lte_gold_mbsfn_table[10][3][42]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_khz_1dot25_table[10][150]; //Not sure whether we need this here +#endif /// uint32_t X_u[64][839]; /// @@ -841,6 +845,10 @@ typedef struct { uint32_t lte_gold_uespec_table[2][20][2][21]; //mbsfn reference symbols uint32_t lte_gold_mbsfn_table[10][3][42]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_khz_1dot25_table[10][150]; //Not sure whether we need this here +#endif /// uint32_t X_u[64][839]; /// diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 5beb6e3ba0e524cfa39d232110b66bfa48ce26da..294afb7bb012ad6b850371a312562b1368619c5a 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -621,6 +621,11 @@ typedef struct { //uint8_t local_flag; /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) runmode_t mode; + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// \brief Indicator that UE is configured for FeMBMS functionality (This flag should be avoided) ... just kept for PBCH initical scan (TODO) + int FeMBMS_active; +#endif /// \brief Indicator that UE should perform band scanning int UE_scan; /// \brief Indicator that UE should perform coarse scanning around carrier @@ -703,6 +708,10 @@ typedef struct { /// mbsfn reference symbols uint32_t lte_gold_mbsfn_table[10][3][42]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_khz_1dot25_table[10][150]; +#endif uint32_t X_u[64][839]; diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 697067b577277ffd3d1eea7029a07afeeffbe7cd..cf596a60e09fa29e0789afb686d4db7ce6d9aade 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -583,6 +583,15 @@ typedef struct { int mbsfn_SubframeConfig; } MBSFN_config_t; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +typedef struct { + int radioframeAllocationPeriod; + int radioframeAllocationOffset; + int non_mbsfn_SubframeConfig; +} NonMBSFN_config_t; +#endif + + typedef struct { /// Number of resource blocks (RB) in DL uint8_t N_RB_DL; @@ -626,12 +635,29 @@ typedef struct { uint8_t threequarter_fs; /// Size of FFT uint16_t ofdm_symbol_size; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t FeMBMS_active; +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// Size of FFT + uint16_t ofdm_symbol_size_khz_1dot25; +#endif /// Number of prefix samples in all but first symbol of slot uint16_t nb_prefix_samples; /// Number of prefix samples in first symbol of slot uint16_t nb_prefix_samples0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// Number of prefix samples in all but first symbol of slot + uint16_t nb_prefix_samples_khz_1dot25; + /// Number of prefix samples in first symbol of slot + uint16_t nb_prefix_samples0_khz_1dot25; +#endif /// Carrier offset in FFT buffer for first RE in PRB0 uint16_t first_carrier_offset; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// Carrier offset in FFT buffer for first RE in PRB0 (FeMBMS + uint16_t first_carrier_offset_khz_1dot25; +#endif /// Number of samples in a subframe uint32_t samples_per_tti; /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) @@ -668,6 +694,10 @@ typedef struct { int num_MBSFN_config; /// Array of MBSFN Configurations (max 8 (maxMBSFN-Allocations) elements as per 36.331) MBSFN_config_t MBSFN_config[8]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t NonMBSFN_config_flag; + NonMBSFN_config_t NonMBSFN_config; +#endif /// Maximum Number of Retransmissions of RRCConnectionRequest (from 36-331 RRC Spec) uint8_t maxHARQ_Msg3Tx; /// Size of SI windows used for repetition of one SI message (in frames) @@ -682,6 +712,9 @@ typedef struct { uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[MAX_MBSFN_AREA]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct NonMBSFN_SubframeConfig *non_mbsfn_SubframeConfig; +#endif /// for fair RR scheduler uint32_t ue_multiple_max; } LTE_DL_FRAME_PARMS; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 25aa83404b3e708a247baa3c82df37c5191041ec..1f2c44ca5b0a39c1103e7bac2ea20ebad049d4c6 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -1071,6 +1071,10 @@ typedef struct PHY_VARS_eNB_s { /// mbsfn reference symbols uint32_t lte_gold_mbsfn_table[10][3][42]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_khz_1dot25_table[10][150]; +#endif // PRACH energy detection parameters /// Detection threshold for LTE PRACH diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 1ad9296613626b3676e6b223013b1020e1e753fb..5da97b3a1aff2c19b1b305bf79bf4a8b56ac8b35 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -19,16 +19,17 @@ * contact@openairinterface.org */ -/*! \file phy_procedures_lte_ue.c - * \brief Implementation of UE procedures from 36.213 LTE specifications - * \author R. Knopp, F. Kaltenberger, N. Nikaein - * \date 2011 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr - * \note - * \warning - */ + /*! \file phy_procedures_lte_ue.c + * \brief Implementation of UE procedures from 36.213 LTE specifications / This includes FeMBMS UE procedures from 36.213 v14.2.0 specification + * \author R. Knopp, F. Kaltenberger, N. Nikaein, J. Morgade + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr, javier.morgad +e@ieee.org + * \note + * \warning + */ #define _GNU_SOURCE @@ -2307,7 +2308,19 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin 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); - pbch_tx_ant = rx_pbch(&ue->common_vars, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)){ + pbch_tx_ant = rx_pbch_fembms(&ue->common_vars, + ue->pbch_vars[eNB_id], + &ue->frame_parms, + eNB_id, + ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, + ue->high_speed_flag, + pbch_phase); + + }else +#endif + pbch_tx_ant = rx_pbch(&ue->common_vars, ue->pbch_vars[eNB_id], &ue->frame_parms, eNB_id, @@ -2343,10 +2356,22 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin return; } + ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; - frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8); - frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc)); - frame_tx += pbch_phase; + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(is_fembms_cas_subframe(frame_rx,subframe_rx,&ue->frame_parms)){ + 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 +=4*pbch_phase; + }else{ +#endif + frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8); + frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc)); + frame_tx += pbch_phase; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + } +#endif if (ue->mac_enabled==1) { dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id, @@ -2590,7 +2615,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx); dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } - } else if ((dci_alloc_rx[i].rnti == SI_RNTI) && + } else if ((dci_alloc_rx[i].rnti == SI_RNTI /*|| dci_alloc_rx[i].rnti == 0xfff9*/) && ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { 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); @@ -2599,6 +2624,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint if (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, (void *)&dci_alloc_rx[i].dci_pdu, + //dci_alloc_rx[i].rnti,//SI_RNTI (to enable MBMS dedicated SI-RNTI = 0xfff9 SI_RNTI, dci_alloc_rx[i].format, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], @@ -2766,7 +2792,11 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint } -void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) { +void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +, uint8_t fembms_flag +#endif +) { int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; @@ -2798,30 +2828,72 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs); fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/){ +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_FUNCTION_IN); + slot_fep_mbsfn_khz_1dot25(ue,subframe_rx,0); +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_FUNCTION_OUT); + } + else{ +#endif +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_FUNCTION_IN); for (l=2; l<12; l++) { slot_fep_mbsfn(ue, l, subframe_rx, 0,0);//ue->rx_offset,0); } +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_FUNCTION_OUT); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + } +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/){ +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_FUNCTION_IN); + rx_pmch_khz_1dot25(ue,0,subframe_rx,pmch_mcs); +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_FUNCTION_OUT); + } + else{ +#endif +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_FUNCTION_IN); for (l=2; l<12; l++) { rx_pmch(ue, 0, subframe_rx, l); } +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_FUNCTION_OUT); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + } +#endif +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_FUNCTION_IN); ue->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(pmch_mcs); - 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, - ue->dlsch_MCH[0]->harq_processes[0]->Qm, - 1, - 2, - frame_rx, - subframe_rx, - 0); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(fembms_flag /*subframe_rx == 3 || subframe_rx == 2*/) + ue->dlsch_MCH[0]->harq_processes[0]->G = get_G_khz_1dot25(&ue->frame_parms, + ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, + ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, + ue->dlsch_MCH[0]->harq_processes[0]->Qm, + 1, + 2, + frame_rx, + subframe_rx, + 0); + else +#endif + 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, + ue->dlsch_MCH[0]->harq_processes[0]->Qm, + 1, + 2, + frame_rx, + subframe_rx, + 0); + 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_rx<<1); @@ -2840,6 +2912,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs subframe_rx, 0, 0,1); +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PMCH_DECODING, VCD_FUNCTION_OUT); if (mcch_active == 1) ue->dlsch_mcch_trials[sync_area][0]++; @@ -2852,7 +2925,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs else ue->dlsch_mtch_errors[sync_area][0]++; - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n", + LOG_E(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n", ue->Mod_id, frame_rx,subframe_rx, ue->dlsch_mcch_errors[sync_area][0], @@ -2861,6 +2934,10 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs ue->dlsch_MCH[0]->max_turbo_iterations, ue->dlsch_MCH[0]->harq_processes[0]->G); // dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); + //if(subframe_rx == 3){ + //dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); + //exit_fun("nothing to add"); + //} if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) { @@ -2874,6 +2951,15 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs // mac_xface->macphy_exit("Why are we exiting here?"); } else { // decoding successful #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH OK (%d,%d), passing to L2 (TBS %d, iter %d,G %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_send_mch_sdu(ue->Mod_id, CC_id, frame_rx, @@ -3360,12 +3446,31 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, break; case SI_PDSCH: - ue_decode_si(ue->Mod_id, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(subframe_rx == 0) { + ue_decode_si_mbms(ue->Mod_id, CC_id, frame_rx, eNB_id, ue->dlsch_SI[eNB_id]->harq_processes[0]->b, ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + + } else { + ue_decode_si(ue->Mod_id, + CC_id, + frame_rx, + eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->b, + ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + } +#else + ue_decode_si(ue->Mod_id, + CC_id, + frame_rx, + eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->b, + ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); +#endif break; case P_PDSCH: @@ -4247,7 +4352,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, // start timers if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + LOG_I(PHY," ****** start RX-Chain for AbsSubframe->0 %d.%d ****** \n", frame_rx%1024, subframe_rx); } if(LOG_DEBUGFLAG(UE_TIMING)) { @@ -4255,6 +4360,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(is_fembms_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)){ + ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag,1); + return 0; + }else{ // this gets closed at end +#endif + + pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; if (do_pdcch_flag) { @@ -4358,7 +4472,11 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, // If this is PMCH, call procedures, do channel estimation for first symbol of next DL subframe and return if (pmch_flag == 1) { - ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag); + ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +,0 +#endif +); int next_subframe_rx = (1+subframe_rx)%10; if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { @@ -4647,6 +4765,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, ue->dlsch_ra[eNB_id]->active = 0; } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + } // This commes from feMBMS subframe filtering ! +#endif + // duplicate harq structure uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid; LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid]; diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c index 586193484dd968d8564ad82c9f710c6a252fc246..7f5fa1fb75f42609e973948fb4805d122acbdf75 100644 --- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -34,6 +34,9 @@ void ue_decode_p(module_id_t module_idP, int CC_id, frame_t frame, void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frame, uint8_t CH_index, void *pdu, uint16_t len){} +void ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + void ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frame, sub_frame_t subframe, uint8_t * sdu, uint16_t sdu_len, uint8_t CH_index){} diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h index fcb45431491b940a8646600b2bccec82626b4951..f69186e4b86a60f7b1f8ba814801988faa00e1d0 100644 --- a/openair2/COMMON/mac_messages_def.h +++ b/openair2/COMMON/mac_messages_def.h @@ -34,6 +34,9 @@ MESSAGE_DEF(RRC_MAC_OUT_OF_SYNC_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacOutOfSy MESSAGE_DEF(RRC_MAC_BCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataReq, rrc_mac_bcch_data_req) MESSAGE_DEF(RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchDataInd, rrc_mac_bcch_data_ind) +MESSAGE_DEF(RRC_MAC_BCCH_MBMS_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchMbmsDataReq, rrc_mac_bcch_mbms_data_req) +MESSAGE_DEF(RRC_MAC_BCCH_MBMS_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacBcchMbmsDataInd, rrc_mac_bcch_mbms_data_ind) + MESSAGE_DEF(RRC_MAC_CCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataReq, rrc_mac_ccch_data_req) MESSAGE_DEF(RRC_MAC_CCCH_DATA_CNF, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataCnf, rrc_mac_ccch_data_cnf) MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataInd, rrc_mac_ccch_data_ind) diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index d7fd44f072a35d0de25c04777ba62e7b7d6ca96e..3bbea66d0d649d7b2463ede95787e99c44c7d78b 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -37,6 +37,9 @@ #define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_req #define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_ind +#define RRC_MAC_BCCH_MBMS_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_req +#define RRC_MAC_BCCH_MBMS_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_ind + #define RRC_MAC_CCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_req #define RRC_MAC_CCCH_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_cnf #define RRC_MAC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_ind @@ -47,6 +50,7 @@ // Some constants from "LAYER2/MAC/defs.h" #define BCCH_SDU_SIZE (512) +#define BCCH_SDU_MBMS_SIZE (512) #define CCCH_SDU_SIZE (512) #define MCCH_SDU_SIZE (512) #define PCCH_SDU_SIZE (512) @@ -78,6 +82,25 @@ typedef struct RrcMacBcchDataInd_s { uint8_t rsrp; } RrcMacBcchDataInd; + +typedef struct RrcMacBcchMbmsDataReq_s { + uint32_t frame; + uint32_t sdu_size; + uint8_t sdu[BCCH_SDU_MBMS_SIZE]; + uint8_t enb_index; +} RrcMacBcchMbmsDataReq; + +typedef struct RrcMacBcchMbmsDataInd_s { + uint32_t frame; + uint8_t sub_frame; + uint32_t sdu_size; + uint8_t sdu[BCCH_SDU_MBMS_SIZE]; + uint8_t enb_index; + uint8_t rsrq; + uint8_t rsrp; +} RrcMacBcchMbmsDataInd; + + typedef struct RrcMacCcchDataReq_s { uint32_t frame; uint32_t sdu_size; diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index cac6056aa21cf0aa529669db12605b5061324743..d50436c03026a66f7b4e4231d95d9cb3c2c8b3a5 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -166,6 +166,7 @@ typedef struct RadioResourceConfig_s { long mpdcch_startSF_CSS_RA_r13_val; long* prach_HoppingOffset_r13; #endif + BOOLEAN_t mbms_dedicated_serving_cell; } RadioResourceConfig; // eNB: ENB_APP -> RRC messages diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 429ffa191823c9ed43939d3fbc02bcec6cec6584..1030b3d3770811d773b860de50d26ca1a7777ff1 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -1310,6 +1310,62 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { break; } + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_multiple_max= ccparams_lte.ue_multiple_max; + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + + if (!ccparams_lte.mbms_dedicated_serving_cell) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL); + else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = TRUE; + } else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = FALSE; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for mbms_dedicated_serving_cell choice: TRUE or FALSE !\n", + RC.config_file_name, i, ccparams_lte.mbms_dedicated_serving_cell); + } + +#endif + + + switch (ccparams_lte.N_RB_DL) { + case 25: + if ((ccparams_lte.ue_multiple_max < 1) || + (ccparams_lte.ue_multiple_max > 4)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", + RC.config_file_name, i, ccparams_lte.ue_multiple_max); + + break; + + case 50: + if ((ccparams_lte.ue_multiple_max < 1) || + (ccparams_lte.ue_multiple_max > 8)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", + RC.config_file_name, i, ccparams_lte.ue_multiple_max); + + break; + + case 100: + if ((ccparams_lte.ue_multiple_max < 1) || + (ccparams_lte.ue_multiple_max > 16)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", + RC.config_file_name, i, ccparams_lte.ue_multiple_max); + + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", + RC.config_file_name, i, ccparams_lte.N_RB_DL); + break; + } + if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf1") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf1; } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf2") == 0) { @@ -2825,6 +2881,15 @@ void configure_du_mac(int inst) { #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 #endif ); } diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 151b029613ed9ec4e4e41e9a1be7da83ce3d990b..63aeee09e45afa8a0b00a4b58204d4ad1a6c734c 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -394,6 +394,10 @@ typedef enum { #define ENB_CONFIG_STRING_UETIMERS_N311 "ue_TimersAndConstants_n311" #define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE "ue_TransmissionMode" #define ENB_CONFIG_STRING_UE_MULTIPLE_MAX "ue_multiple_max" +//SIB1-MBMS +#define ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL "mbms_dedicated_serving_cell" + + #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13" #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13" @@ -447,7 +451,6 @@ typedef enum { #define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_SIZE "DISCRXPOOLPS_ResourceConfig_subframeBitmap_choice_bs_size" #define ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED "DISCRXPOOLPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused" - /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* component carriers configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -534,6 +537,7 @@ typedef struct ccparams_lte_s { int32_t ue_TimersAndConstants_n311; int32_t ue_TransmissionMode; int32_t ue_multiple_max; + char *mbms_dedicated_serving_cell; int32_t srb1_timer_poll_retransmit; int32_t srb1_timer_reordering; int32_t srb1_timer_status_prohibit; @@ -657,6 +661,7 @@ typedef struct ccparams_lte_s { { .s5= {NULL }} , \ { .s5= {NULL }} , \ { .s5= {NULL }} , \ + { .s5= {NULL }} , \ { .s5= {NULL }} \ } /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -741,7 +746,8 @@ typedef struct ccparams_lte_s { {ENB_CONFIG_STRING_UETIMERS_N310, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n310, defintval:20, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ccparams.ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \ -{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0} \ +{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0} \ } @@ -822,6 +828,7 @@ typedef struct ccparams_lte_s { #define ENB_CONFIG_UETIMERS_N310_IDX 73 #define ENB_CONFIG_UETIMERS_N311_IDX 74 #define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 75 +#define ENB_CONFIG_MBMS_DEDICATED_SERVING_CELL_IDX 76 /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 6ece2d53a50e0ec2834019fd3a82ec133d76c6b1..fbc146f1a56e1b0e8ea83fc76c824879336f74df 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -311,6 +311,15 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 #endif ); break; @@ -470,6 +479,15 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + #endif + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 #endif ); } diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 669f3cf1fe23b2bfc8cdf7d151afd14f46ac66ea..62c6c436308fbe17ee449def340224b17f23061d 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -685,7 +685,17 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, LTE_SystemInformationBlockType1_v1310_IEs_t * sib1_v13ext #endif - ) { +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + uint8_t FeMBMS_Flag, + LTE_BCCH_DL_SCH_Message_MBMS_t * mib_fembms, + 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 +#endif + ) { + int i; int UE_id = -1; eNB_MAC_INST *eNB = RC.mac[Mod_idP]; @@ -736,6 +746,13 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, config_sib1(Mod_idP,CC_idP,tdd_Config); } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //TODO MBMS this must be passed through function + /*if (schedulingInfoList_MBMS!=NULL) { + RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList_MBMS = schedulingInfoList_MBMS; + config_sib1_mbms(Mod_idP,CC_idP,tdd_Config); + }*/ +#endif + #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if (sib1_v13ext != NULL) { @@ -855,6 +872,39 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, #endif } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (nonMBSFN_SubframeConfig != NULL){ + LOG_D(MAC, + "[eNB %d][CONFIG] Received a non MBSFN subframe allocation pattern (%x,%x):%x for FeMBMS-CAS\n", + Mod_idP, nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0],nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1],nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7 ); + //RC.mac[Mod_idP]->common_channels[0].non_mbsfn_SubframeConfig = (int)(nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1) | (int)(nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7); + RC.mac[Mod_idP]->common_channels[0].non_mbsfn_SubframeConfig = nonMBSFN_SubframeConfig; + + nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + cfg->fembms_config.non_mbsfn_config_flag.value = 1; + cfg->fembms_config.non_mbsfn_config_flag.tl.tag = NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG; + cfg->num_tlv++; + + cfg->fembms_config.non_mbsfn_subframeconfig.value = (nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[0]<<1 | nonMBSFN_SubframeConfig->subframeAllocation_r14.buf[1]>>7); + cfg->fembms_config.non_mbsfn_subframeconfig.tl.tag = NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG; + cfg->num_tlv++; + + cfg->fembms_config.radioframe_allocation_period.value = nonMBSFN_SubframeConfig->radioFrameAllocationPeriod_r14; + cfg->fembms_config.radioframe_allocation_period.tl.tag = NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG; + cfg->num_tlv++; + + cfg->fembms_config.radioframe_allocation_offset.value = nonMBSFN_SubframeConfig->radioFrameAllocationOffset_r14; + cfg->fembms_config.radioframe_allocation_offset.tl.tag = NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG; + cfg->num_tlv++; + + + + //We need to reuse current MCH scheduler + //TOCHECK whether we can simply reuse current mbsfn_SubframeConfig stuff + } +#endif + + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbsfn_AreaInfoList != NULL) { @@ -1283,4 +1333,4 @@ void eNB_Config_Local_DRX( LOG_E(MAC, "Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); break; } -} \ No newline at end of file +} diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index ab66aebab8fff385c29b78688c54d6f7819066e1..50586c37e30c7bcb81b3829a1144f6dedea588e5 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -20,16 +20,18 @@ * contact@openairinterface.org */ -/*! \file config.c - * \brief UE and eNB configuration performed by RRC or as a consequence of RRC procedures - * \author Navid Nikaein and Raymond Knopp - * \date 2010 - 2014 + +/*! \file config_ue.c + * \brief UE configuration performed by RRC or as a consequence of RRC procedures / This includes FeMBMS UE procedures + * \author Navid Nikaein, Raymond Knopp and Javier Morgade + * \date 2010 - 2014 / 2019 * \version 0.1 - * \email: navid.nikaein@eurecom.fr + * \email: navid.nikaein@eurecom.fr, javier.morgade@ieee.org * @ingroup _mac */ + #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" #include "nfapi/oai_integration/vendor_ext.h" @@ -130,7 +132,15 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, ,const uint32_t *const sourceL2Id ,const uint32_t *const destinationL2Id #endif - ) { +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + uint8_t FeMBMS_Flag, + struct LTE_NonMBSFN_SubframeConfig_r14 * nonMBSFN_SubframeConfig, + LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList_fembms +#endif + ) +{ + int i; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); @@ -560,6 +570,15 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, } #endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(nonMBSFN_SubframeConfig!=NULL) { + LOG_I(MAC, "[UE %d] Configuring LTE_NonMBSFN \n", + Mod_idP); + phy_config_sib1_fembms_ue(Mod_idP, CC_idP, 0, nonMBSFN_SubframeConfig); + } +#endif + #ifdef CBA if (cba_rnti) { diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h index 02f9c47ea5cdc7d0443cd13c64492460014d4adb..0d7dd7d2c06788e6af8089cb9b5e277c434f3412 100644 --- a/openair2/LAYER2/MAC/defs_NB_IoT.h +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -63,7 +63,8 @@ /*!\brief DTCH DRB1 logical channel */ #define DTCH 3 // LCID /*!\brief MCCH logical channel */ -#define MCCH 4 +//#define MCCH 4 +#define MCCH 62 /*!\brief MTCH logical channel */ #define MTCH 1 // DLSCH LCHAN ID diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index d5bab36f609ceba9882f0b733a3f8de2cb1031be..bb051dcd1ece3049c264cf0c4385cb1f95190858 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -955,7 +955,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* This schedules MIB */ - if ((subframeP == 0) && (frameP & 3) == 0) + if ((subframeP == 0) && (frameP & 3) == 0) schedule_mib(module_idP, frameP, subframeP); if (get_softmodem_params()->phy_test == 0) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 38195676d779a43c9be94961b8ef9387d43bc6b7..fb80c9e1d6058a9c50b33c869063c4cb6da40929 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -75,6 +75,235 @@ int Sj100[size_Sj100] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15 }; int SIB1_BR_TBS_table[6] = { 208, 256, 328, 504, 712, 936 }; +//------------------------------------------------------------------------------ +void +schedule_SIB1_MBMS(module_id_t module_idP, + frame_t frameP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ +#ifdef SCHEDULE_SIB1_MBMS + int8_t bcch_sdu_length; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int first_rb = -1; + int N_RB_DL; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + int m, i, N_S_NB; + int *Sj; + int n_NB = 0; + int TBS; + int k = 0, rvidx; + uint16_t sfn_sf = frameP<<4|subframeP; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + + cc = &eNB->common_channels[CC_id]; + vrb_map = (void *) &cc->vrb_map; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + + int foffset = cc->physCellId & 1; + int sfoffset = (cc->tdd_Config == NULL) ? 0 : 1; + + // Time-domain scheduling + if (cc->mib->message.schedulingInfoSIB1_BR_r13 == 0) + continue; + else + switch ((cc->mib->message.schedulingInfoSIB1_BR_r13 - 1) % 3) { + case 0: // repetition 4 + k = (frameP >> 1) & 3; + if ((subframeP != (4 + sfoffset)) + || ((frameP & 1) != foffset)) + continue; + break; + case 1: // repetition 8 + k = frameP & 3; + AssertFatal(N_RB_DL > 15, + "SIB1-BR repetition 8 not allowed for N_RB_DL= %d\n", + N_RB_DL); + if ((foffset == 0) && (subframeP != (4 + sfoffset))) + continue; + else if ((foffset == 1) + && (subframeP != ((9 + sfoffset) % 10))) + continue; + break; + case 2: // repetition 16 + k = ((10 * frameP) + subframeP) & 3; + AssertFatal(N_RB_DL > 15, + "SIB1-BR repetition 16 not allowed for N_RB_DL= %d\n", + N_RB_DL); + if ((sfoffset == 1) + && ((subframeP != 0) || (subframeP != 5))) + continue; + else if ((sfoffset == 0) && (foffset == 0) + && (subframeP != 4) && (subframeP != 9)) + continue; + else if ((sfoffset == 0) && (foffset == 1) + && (subframeP != 0) && (subframeP != 9)) + continue; + break; + } + // if we get here we have to schedule SIB1_BR in this frame/subframe + + // keep counter of SIB1_BR repetitions in 8 frame period to choose narrowband on which to transmit + if ((frameP & 7) == 0) + cc->SIB1_BR_cnt = 0; + else + cc->SIB1_BR_cnt++; + + // Frequency-domain scheduling + switch (N_RB_DL) { + case 6: + case 15: + default: + m = 1; + n_NB = 0; + N_S_NB = 0; + Sj = NULL; + break; + case 25: + m = 2; + N_S_NB = 2; + Sj = Sj25; + break; + case 50: + m = 2; + N_S_NB = 6; + Sj = Sj50; + break; + case 75: + m = 4; + N_S_NB = 10; + Sj = Sj75; + break; + case 100: + m = 4; + N_S_NB = 14; + Sj = Sj100; + break; + } + // Note: definition of k above and rvidx from 36.321 section 5.3.1 + rvidx = (((3 * k) >> 1) + (k & 1)) & 3; + + i = cc->SIB1_BR_cnt & (m - 1); + + n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + + + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case + + AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, + "schedulingInfoSIB1_BR_r13 %d > 18\n", + (int) cc->mib->message.schedulingInfoSIB1_BR_r13); + + AssertFatal(bcch_sdu_length > 0, + "RRC returned 0 bytes for SIB1-BR\n"); + + TBS = + SIB1_BR_TBS_table[(cc->mib->message.schedulingInfoSIB1_BR_r13 - + 1) / 3] >> 3; + + AssertFatal(bcch_sdu_length <= TBS, + "length returned by RRC %d is not compatible with the TBS %d from MIB\n", + bcch_sdu_length, TBS); + + if ((frameP & 1023) < 200) + LOG_D(MAC, + "[eNB %d] Frame %d Subframe %d: SIB1_BR->DLSCH CC_id %d, Received %d bytes, scheduling on NB %d (i %d,m %d,N_S_NB %d) rvidx %d\n", + module_idP, frameP, subframeP, CC_id, bcch_sdu_length, + n_NB, i, m, N_S_NB, rvidx); + + // allocate all 6 PRBs in narrowband for SIB1_BR + + first_rb = narrowband_to_first_rb(cc, n_NB); + + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + vrb_map[first_rb + 4] = 1; + vrb_map[first_rb + 5] = 1; + + 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 = TBS; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx + + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + // Program TX 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 = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; + 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].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_BR_pdu[0].payload[0], + bcch_sdu_length, + 0xffff, WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); + } + if (cc->tdd_Config != NULL) { //TDD + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (TDD) for CC_id %d SIB1-BR %d bytes\n", + frameP, CC_id, bcch_sdu_length); + } else { + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", + frameP, CC_id, bcch_sdu_length); + } + } +#endif +} + + //------------------------------------------------------------------------------ void schedule_SIB1_BR(module_id_t module_idP, @@ -304,6 +533,8 @@ schedule_SIB1_BR(module_id_t module_idP, int si_WindowLength_BR_r13tab[LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 20, 40, 60, 80, 120, 160, 200 }; int si_TBS_r13tab[LTE_SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; +int si_WindowLength_MBMS_r14tab[8] = { 1, 2, 5, 10, 15, 20, 40, 80 }; + //------------------------------------------------------------------------------ void schedule_SI_BR(module_id_t module_idP, frame_t frameP, @@ -503,6 +734,231 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, } // CC_id return; } + + +//------------------------------------------------------------------------------ +void +schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + int8_t bcch_sdu_length; + int mcs = -1; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int first_rb = -1; + int N_RB_DL; + nfapi_dl_config_request_t *dl_config_request; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; + + start_meas(&eNB->schedule_si_mbms); + + // Only schedule LTE System Information in subframe 0 + if (subframeP == 0) { + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + + cc = &eNB->common_channels[CC_id]; + vrb_map = (void *) &cc->vrb_map; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + + + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_MBMS,0xFFFF, 1, &cc->BCCH_MBMS_pdu.payload[0], 0); // not used in this case + + if (bcch_sdu_length > 0) { + LOG_D(MAC, "[eNB %d] Frame %d : BCCH-MBMS->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); + + // Allocate 4 PRBs in a random location + /* + while (1) { + first_rb = (unsigned char)(taus()%(PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL-4)); + if ((vrb_map[first_rb] != 1) && + (vrb_map[first_rb+1] != 1) && + (vrb_map[first_rb+2] != 1) && + (vrb_map[first_rb+3] != 1)) + break; + } + */ + switch (N_RB_DL) { + case 6: + first_rb = 0; + break; + case 15: + first_rb = 6; + break; + case 25: + first_rb = 11; + break; + case 50: + first_rb = 23; + break; + case 100: + first_rb = 48; + break; + } + + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + + // Get MCS for length of SI, 3 PRBs + if (bcch_sdu_length <= 7) { + mcs = 0; + } else if (bcch_sdu_length <= 11) { + mcs = 1; + } else if (bcch_sdu_length <= 18) { + mcs = 2; + } else if (bcch_sdu_length <= 22) { + mcs = 3; + } else if (bcch_sdu_length <= 26) { + mcs = 4; + } else if (bcch_sdu_length <= 28) { + mcs = 5; + } else if (bcch_sdu_length <= 32) { + mcs = 6; + } else if (bcch_sdu_length <= 41) { + mcs = 7; + } else if (bcch_sdu_length <= 49) { + mcs = 8; + } + + + 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_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.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = 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.rnti = 0xFFFF; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // S-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_request->sfn_sf = sfn_sf; + + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { + LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI MBMS\n", frameP, subframeP); + dl_req->number_dci++; + dl_req->number_pdu++; + 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.pdu_index = eNB->pdu_index[CC_id]; + 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 = bcch_sdu_length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + + // Program TX 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 = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_MBMS_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; + + } else { + LOG_E(MAC, + "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI MBMS\n", + module_idP, CC_id, frameP, subframeP); + } + + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), + T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_MBMS_pdu.payload, bcch_sdu_length)); + + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_MBMS_pdu.payload[0], + bcch_sdu_length, + 0xffff, + WS_SI_RNTI, 0xffff, eNB->frame, eNB->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][BCH-MBMS] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, + bcch_sdu_length); + } + if (0/*cc->tdd_Config != NULL*/) { //TDD not for FeMBMS + LOG_D(MAC, + "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", + frameP, CC_id, bcch_sdu_length, mcs); + } else { + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-MBMS->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); + } + + + eNB->eNB_stats[CC_id].total_num_bcch_pdu += 1; + eNB->eNB_stats[CC_id].bcch_buffer = bcch_sdu_length; + eNB->eNB_stats[CC_id].total_bcch_buffer += bcch_sdu_length; + eNB->eNB_stats[CC_id].bcch_mcs = mcs; +//printf("SI %d.%d\n", frameP, subframeP);/////////////////////////////////////////****************************** + } else { + + //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); + } + } + } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + //schedule_SIB1_BR(module_idP, frameP, subframeP); + //schedule_SI_BR(module_idP, frameP, subframeP); +#endif + + stop_meas(&eNB->schedule_si_mbms); + + +} #endif void diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 0ac3a32fa8b82bee1eba86369121edc97f5f6d65..8f9a1b94f61014c339ffba776d7cf6d40cb13029 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -66,6 +66,12 @@ #include "LTE_SystemInformationBlockType1-v1310-IEs.h" #include "LTE_SystemInformationBlockType18-r12.h" #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#include "LTE_BCCH-BCH-Message-MBMS.h" +#include "LTE_BCCH-DL-SCH-Message-MBMS.h" +#include "LTE_SystemInformationBlockType1-MBMS-r14.h" +#include "LTE_NonMBSFN-SubframeConfig-r14.h" +#endif #include "LTE_RadioResourceConfigCommonSIB.h" #include "nfapi_interface.h" #include "PHY_INTERFACE/IF_Module.h" @@ -416,6 +422,11 @@ typedef struct { #define BCCH_SIB1_BR 6 // SIB1_BR /*!\brief Values of BCCH SIB_BR logical channel (fake) */ #define BCCH_SI_BR 7 // SI-BR +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +/*!\brief Values of BCCH SIB1_BR logical channel (fake) */ +#define BCCH_SIB1_MBMS 60 // SIB1_MBMS //TODO better armonize index +#define BCCH_SI_MBMS 61 // SIB_MBMS //TODO better armonize index +#endif /*!\brief Value of CCCH / SRB0 logical channel */ #define CCCH 0 // srb0 /*!\brief DCCH / SRB1 logical channel */ @@ -425,7 +436,8 @@ typedef struct { /*!\brief DTCH DRB1 logical channel */ #define DTCH 3 // LCID /*!\brief MCCH logical channel */ -#define MCCH 4 +//#define MCCH 4 +#define MCCH 62 /*!\brief MTCH logical channel */ #define MTCH 1 // DLSCH LCHAN ID @@ -1311,6 +1323,7 @@ typedef struct { LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR; + LTE_SchedulingInfoList_MBMS_r14_t *schedulingInfoList_MBMS; #endif LTE_TDD_Config_t *tdd_Config; LTE_SchedulingInfoList_t *schedulingInfoList; @@ -1338,6 +1351,9 @@ typedef struct { uint8_t vrb_map_UL[100]; /// MBSFN SubframeConfig struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct LTE_NonMBSFN_SubframeConfig_r14 *non_mbsfn_SubframeConfig; +#endif /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -1370,6 +1386,11 @@ typedef struct { /// Outgoing BCCH-BR pdu for PHY BCCH_PDU BCCH_BR_pdu[20]; #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + BCCH_PDU BCCH_MBMS_pdu; + uint8_t FeMBMS_flag; +#endif + } COMMON_channels_t; /*! \brief top level eNB MAC structure */ typedef struct eNB_MAC_INST_s { @@ -1437,6 +1458,9 @@ typedef struct eNB_MAC_INST_s { time_stats_t eNB_scheduler; /// processing time of eNB scheduler for SI time_stats_t schedule_si; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + time_stats_t schedule_si_mbms; +#endif /// processing time of eNB scheduler for Random access time_stats_t schedule_ra; /// processing time of eNB ULSCH scheduler @@ -1676,6 +1700,9 @@ typedef struct { /// MBSFN_Subframe Configuration struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + struct LTE_NonMBSFN_SubframeConfig_r14 *non_mbsfn_SubframeConfig; +#endif /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index f97531698de14c4c798edf68b398156c11fa9b3c..f5762cb14ec486f48030981786cd2c1af534a959 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -67,6 +67,17 @@ void schedule_RA(module_id_t module_idP, frame_t frameP, void schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +/** \brief First stage of SI Scheduling. Gets a SI SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs). +@param Mod_id Instance ID of eNB +@param frame Frame index +@param subframe Subframe number on which to act +*/ +void schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, + sub_frame_t subframeP); +#endif + + /** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0; @param Mod_id Instance ID of eNB @param frame Frame index @@ -539,6 +550,11 @@ void mac_out_of_sync_ind(module_id_t module_idP, frame_t frameP, void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frame, uint8_t CH_index, void *pdu, uint16_t len); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len); +#endif + void ue_decode_p(module_id_t module_idP, int CC_id, frame_t frame, uint8_t CH_index, void *pdu, uint16_t len); @@ -954,6 +970,12 @@ int generate_dlsch_header(unsigned char *mac_header, @param mbsfn_AreaInfoList pointer to MBSFN Area Info list from SIB13 @param pmch_InfoList pointer to PMCH_InfoList from MBSFNAreaConfiguration Message (MCCH Message) @param sib1_ext_r13 SI Scheduling information for SI-BR UEs +@param mib_fembms pointer to FeMBMS MIB +@param FeMBMS_Flag indicates FeMBMS transmission +@param schedulingInfo_fembms pointer to FeMBMS SI Scheduling Information +@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 */ int rrc_mac_config_req_eNB(module_id_t module_idP, @@ -1003,6 +1025,15 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, , LTE_SystemInformationBlockType1_v1310_IEs_t * sib1_ext_r13 +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + uint8_t FeMBMS_Flag, + LTE_BCCH_DL_SCH_Message_MBMS_t * mib_fembms, + 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 #endif ); @@ -1066,6 +1097,12 @@ int rrc_mac_config_req_ue(module_id_t module_idP, ,config_action_t config_action ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + uint8_t FeMBMS_Flag, + struct LTE_NonMBSFN_SubframeConfig_r14 * nonMBSFN_SubframeConfig, + LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList_fembms #endif ); diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 4be98d590a8ec97cdbffa2b78024abc17b78117e..f001c5f2ae064966fd2a4df46fd72efd412c92a6 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -19,14 +19,14 @@ * contact@openairinterface.org */ -/*! \file ue_procedures.c - * \brief procedures related to UE - * \author Navid Nikaein and Raymond Knopp - * \date 2010 - 2014 - * \version 1 - * \email: navid.nikaein@eurecom.fr - * @ingroup _mac +/*! \file asn1_msg.c + * \brief primitives to build the asn1 messages / primitives to build FeMBMS asn1 messages + * \author Raymond Knopp, Navid Nikaein and Javier Morgade + * \date 2011 / 2019 + * \version 1.0 + * \company Eurecom + * \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr javier.morgade@ieee.org */ #ifdef EXMIMO @@ -594,6 +594,45 @@ ue_send_sdu(module_id_t module_idP, #endif } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +void +ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frameP, + uint8_t eNB_index, void *pdu, uint16_t len) +{ +#if UE_TIMING_TRACE + start_meas(&UE_mac_inst[module_idP].rx_si); +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN); + + LOG_D(MAC, "[UE %d] Frame %d Sending SI MBMS to RRC (LCID Id %d,len %d)\n", + module_idP, frameP, BCCH, len); + + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe + SI_RNTI, + BCCH_SI_MBMS, (uint8_t *) pdu, len, eNB_index, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); +#if UE_TIMING_TRACE + stop_meas(&UE_mac_inst[module_idP].rx_si); +#endif + if (opt_enabled == 1) { + trace_pdu(DIRECTION_UPLINK, + (uint8_t *) pdu, + len, + module_idP, + WS_SI_RNTI, + 0xffff, + UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); + LOG_D(OPT, + "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, len); + } +} +#endif + void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_index, void *pdu, uint16_t len) { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index d1252c8d5afabc1643783df07ad9b9da2dc03fe3..41688a62cfd5e1f1f71d83eb2b0e59e69c018010 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -972,8 +972,10 @@ pdcp_data_ind( dest_addr.sin_family = AF_INET; dest_addr.sin_port = udp_header->dest; dest_addr.sin_addr.s_addr = ip_header->daddr; - sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); - packet_forwarded = TRUE; + + sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); + //packet_forwarded = TRUE; + } #endif diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index 6cb849091a5a8ef4a9a68226b8e8f3b4cf617cf5..b7bc34db54674c92e1b471247575b3b19d4745d4 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -137,7 +137,7 @@ void config_req_rlc_um_asn1 ( } rlc_p = &rlc_union_p->rlc.um; - } + }else if ((sourceL2Id >0 ) && (destinationL2Id >0)){ key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP); } else diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 70e0ecd20a5f0c30fd470b552690546acd136098..3cde5977ff0eac3f9e4c7cd56654a2107695ac80 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -398,7 +398,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, } key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); - } + }else if (sourceL2Id && destinationL2Id) { LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 7bfeb43b53d333249b812a88f6ea4801423a34e2..6478641438c060bd88fd09331123fc4faea6c5ef 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -77,6 +77,26 @@ mac_rrc_data_req( carrier = &rrc->carrier[0]; mib = &carrier->mib; + if(Srb_id == BCCH_SI_MBMS){ + if (frameP%4 == 0){ + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS, + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS); + + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1 MBMS\n",Mod_idP,frameP); + + for (int i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS; 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_SIB1_MBMS); + } + } + if((Srb_id & RAB_OFFSET) == BCCH) { if(RC.rrc[Mod_idP]->carrier[CC_id].SI.Active==0) { return 0; diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 94a0f175d0078917b2044c259b12eeba3aec22ec..d8b6974501622383f7eb77985dcf699428780f31 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -138,6 +138,40 @@ mac_rrc_data_ind_ue( */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, 0, rntiP, frameP, sub_frameP,eNB_indexP); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if(srb_idP == BCCH_SI_MBMS) { + LOG_D(RRC,"[UE %d] Received SDU for BCCH on MBMS SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sdu); + + if (sdu_lenP > msg_sdu_size) { + LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = sdu_lenP; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_MBMS_DATA_IND); + memset (RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sdu, 0, BCCH_SDU_MBMS_SIZE); + RRC_MAC_BCCH_MBMS_DATA_IND (message_p).frame = frameP; + RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sdu_size = sdu_size; + memcpy (RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_BCCH_MBMS_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_BCCH_MBMS_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; + RRC_MAC_BCCH_MBMS_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; + + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } +#else + decode_BCCH_MBMS_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0); +#endif + } +#endif + if(srb_idP == BCCH) { LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); #if defined(ENABLE_ITTI) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9f12e99d9c80ebf42ca52ad6d15250d5509908d0..b28a3cee50fdd0a02d2a3625ed8a7e9a867ca0b7 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -78,6 +78,13 @@ #include "LTE_SBCCH-SL-BCH-MessageType.h" #include "LTE_SBCCH-SL-BCH-Message.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + #include "LTE_BCCH-BCH-Message-MBMS.h" + #include "LTE_BCCH-DL-SCH-Message-MBMS.h" + #include "LTE_SystemInformationBlockType1-MBMS-r14.h" + #include "LTE_NonMBSFN-SubframeConfig-r14.h" +#endif + //#include "PHY/defs.h" #include "LTE_MeasObjectToAddModList.h" @@ -177,6 +184,88 @@ uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) { return 0xFF; //error! } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +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); + uint16_t *spare = calloc(1,sizeof(uint16_t)); + uint16_t *additionalNonMBSFNSubframes = calloc(1,sizeof(uint16_t)); + + if( spare == NULL || additionalNonMBSFNSubframes == NULL ) abort(); + + switch (N_RB_DL) { + case 6: + mib_fembms->message.dl_Bandwidth_MBMS_r14 = LTE_MasterInformationBlock_MBMS_r14__dl_Bandwidth_MBMS_r14_n6; + break; + + case 15: + mib_fembms->message.dl_Bandwidth_MBMS_r14 = LTE_MasterInformationBlock_MBMS_r14__dl_Bandwidth_MBMS_r14_n15; + break; + + case 25: + mib_fembms->message.dl_Bandwidth_MBMS_r14 = LTE_MasterInformationBlock_MBMS_r14__dl_Bandwidth_MBMS_r14_n25; + break; + + case 50: + mib_fembms->message.dl_Bandwidth_MBMS_r14 = LTE_MasterInformationBlock_MBMS_r14__dl_Bandwidth_MBMS_r14_n50; + break; + + case 75: + mib_fembms->message.dl_Bandwidth_MBMS_r14 = LTE_MasterInformationBlock_MBMS_r14__dl_Bandwidth_MBMS_r14_n75; + break; + + case 100: + mib_fembms->message.dl_Bandwidth_MBMS_r14 = LTE_MasterInformationBlock_MBMS_r14__dl_Bandwidth_MBMS_r14_n100; + break; + + default: + AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); + } + LOG_I(RRC,"[MIB] systemBandwidth %x, additional non MBMS subframes %x, sfn %x\n", + (uint32_t)mib_fembms->message.dl_Bandwidth_MBMS_r14, + (uint32_t)additionalNonMBSFN, + (uint32_t)sfn); + + + 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.spare.buf = (uint8_t *)spare; +//#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) + mib_fembms->message.spare.size = 2; + mib_fembms->message.spare.bits_unused = 6; // This makes a spare of 10 bits +//#else + //mib->message.spare.size = 1; + //mib->message.spare.bits_unused = 3; // This makes a spare of 5 bits + //mib->message.schedulingInfoSIB1_BR_r13 = 0; // turn off eMTC +//#endif + + //TODO additionalNonBMSFNSubframes-r14 INTEGER (0..3) ? + + //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + 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, + (void *)mib_fembms, + carrier->MIB_FeMBMS, + 24); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} +#endif + uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich_Resource, uint32_t phich_duration, uint32_t frame #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -317,6 +406,221 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, return((enc_rval.encoded+7)/8); } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, + int Mod_id,int CC_id +#if defined(ENABLE_ITTI) + , RrcConfigurationReq *configuration +#endif + ) { + // SystemInformation_t systemInformation; +#if defined(ENABLE_ITTI) + int num_plmn = configuration->num_plmn; +#else + int num_plmn = 1; +#endif + LTE_PLMN_IdentityInfo_t PLMN_identity_info[num_plmn]; + LTE_MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; + asn_enc_rval_t enc_rval; + LTE_SchedulingInfo_MBMS_r14_t schedulingInfo; + LTE_SIB_Type_t sib_type; + uint8_t *buffer = carrier->SIB1_MBMS; + LTE_BCCH_DL_SCH_Message_MBMS_t *bcch_message = &carrier->siblock1_MBMS; + LTE_SystemInformationBlockType1_MBMS_r14_t **sib1_MBMS = &carrier->sib1_MBMS; + + int i; + //LTE_NonMBSFN_SubframeConfig_r14 nonMBSFN_SubframeConfig_r14; + + struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1/*, *MBSFN_Area2*/; + struct LTE_NonMBSFN_SubframeConfig_r14 nonMBSFN_SubframeConfig_r14; + + memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_MBMS_t)); + bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_MBMS_r14_PR_c1; + bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType_MBMS_r14__c1_PR_systemInformationBlockType1_MBMS_r14; + // memcpy(&bcch_message.message.choice.c1.choice.systemInformationBlockType1,sib1,sizeof(SystemInformationBlockType1_t)); + *sib1_MBMS = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14; + memset(PLMN_identity_info,0,num_plmn * sizeof(LTE_PLMN_IdentityInfo_t)); + memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_MBMS_r14_t)); + memset(&sib_type,0,sizeof(LTE_SIB_Type_t)); + memset(&nonMBSFN_SubframeConfig_r14,0,sizeof(struct LTE_NonMBSFN_SubframeConfig_r14)); + + /* as per TS 36.311, up to 6 PLMN_identity_info are allowed in list -> add one by one */ + for (i = 0; i < configuration->num_plmn; ++i) { + PLMN_identity_info[i].plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); + memset(PLMN_identity_info[i].plmn_Identity.mcc,0,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); + asn_set_empty(&PLMN_identity_info[i].plmn_Identity.mcc->list);//.size=0; +#if defined(ENABLE_ITTI) + dummy_mcc[i][0] = (configuration->mcc[i] / 100) % 10; + dummy_mcc[i][1] = (configuration->mcc[i] / 10) % 10; + dummy_mcc[i][2] = (configuration->mcc[i] / 1) % 10; +#else + dummy_mcc[i][0] = 0; + dummy_mcc[i][1] = 0; + dummy_mcc[i][2] = 1; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][2]); + PLMN_identity_info[i].plmn_Identity.mnc.list.size=0; + PLMN_identity_info[i].plmn_Identity.mnc.list.count=0; +#if defined(ENABLE_ITTI) + + if (configuration->mnc[i] >= 100) { + dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 10; + dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10; + } else { + if (configuration->mnc_digit_length[i] == 2) { + dummy_mnc[i][0] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][1] = (configuration->mnc[i] / 1) % 10; + dummy_mnc[i][2] = 0xf; + } else { + dummy_mnc[i][0] = (configuration->mnc[i] / 100) % 100; + dummy_mnc[i][1] = (configuration->mnc[i] / 10) % 10; + dummy_mnc[i][2] = (configuration->mnc[i] / 1) % 10; + } + } + +#else + dummy_mnc[i][0] = 0; + dummy_mnc[i][1] = 1; + dummy_mnc[i][2] = 0xf; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][1]); + + if (dummy_mnc[i][2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mnc.list,&dummy_mnc[i][2]); + } + + //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); + PLMN_identity_info[i].cellReservedForOperatorUse=LTE_PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; + ASN_SEQUENCE_ADD(&(*sib1_MBMS)->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.list,&PLMN_identity_info[i]); + } + + // 16 bits + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf = MALLOC(2); +#if defined(ENABLE_ITTI) + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[0] = (configuration->tac >> 8) & 0xff; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[1] = (configuration->tac >> 0) & 0xff; +#else + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[0] = 0x00; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[1] = 0x01; +#endif + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.size=2; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.trackingAreaCode_r14.bits_unused=0; + // 28 bits + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf = MALLOC(8); +#if defined(ENABLE_ITTI) + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[0] = (configuration->cell_identity >> 20) & 0xff; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[1] = (configuration->cell_identity >> 12) & 0xff; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[2] = (configuration->cell_identity >> 4) & 0xff; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[3] = (configuration->cell_identity << 4) & 0xf0; +#else + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[0] = 0x00; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[1] = 0x00; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[2] = 0x00; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[3] = 0x10; +#endif + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.size=4; + (*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.bits_unused=4; + (*sib1_MBMS)->freqBandIndicator_r14 = +#if defined(ENABLE_ITTI) + configuration->eutra_band[CC_id]; +#else + 7; +#endif + schedulingInfo.si_Periodicity_r14=LTE_SchedulingInfo__si_Periodicity_rf16; + sib_type=LTE_SIB_Type_MBMS_r14_sibType13_v920; + ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo_r14.list,&sib_type); + ASN_SEQUENCE_ADD(&(*sib1_MBMS)->schedulingInfoList_MBMS_r14.list,&schedulingInfo); + + (*sib1_MBMS)->si_WindowLength_r14=LTE_SystemInformationBlockType1_MBMS_r14__si_WindowLength_r14_ms20; + (*sib1_MBMS)->systemInfoValueTag_r14=0; + // (*sib1).nonCriticalExtension = calloc(1,sizeof(*(*sib1).nonCriticalExtension)); + + + //sib13 optional + if (1) + { + (*sib1_MBMS)->systemInformationBlockType13_r14 = CALLOC(1,sizeof(struct LTE_SystemInformationBlockType13_r9)); + memset((*sib1_MBMS)->systemInformationBlockType13_r14,0,sizeof(struct LTE_SystemInformationBlockType13_r9)); + + ((*sib1_MBMS)->systemInformationBlockType13_r14)->notificationConfig_r9.notificationRepetitionCoeff_r9= LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + ((*sib1_MBMS)->systemInformationBlockType13_r14)->notificationConfig_r9.notificationOffset_r9= 0; + ((*sib1_MBMS)->systemInformationBlockType13_r14)->notificationConfig_r9.notificationSF_Index_r9= 1; + + //((*sib1_MBMS)->systemInformationBlockType13_r14)->mbsfn_AreaInfoList_r9= CALLOC(1,sizeof(LTE_MBSFN_AreaInfoList_r9_t)); + //memset(((*sib1_MBMS)->systemInformationBlockType13_r14)->mbsfn_AreaInfoList_r9,0,sizeof(LTE_MBSFN_AreaInfoList_r9_t)); + LTE_MBSFN_AreaInfoList_r9_t * MBSFNArea_list= &((*sib1_MBMS)->systemInformationBlockType13_r14)->mbsfn_AreaInfoList_r9; + // MBSFN-AreaInfoList + memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); + // MBSFN Area 1 + MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); + MBSFN_Area1->mbsfn_AreaId_r9= 1; + MBSFN_Area1->non_MBSFNregionLength= LTE_MBSFN_AreaInfo_r9__non_MBSFNregionLength_s2; + MBSFN_Area1->notificationIndicator_r9= 0; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= 1; // in accordance with mbsfn subframe configuration in sib2 + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_ModificationPeriod_r9_rf512; + // 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]=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)->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)); + + memset(MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14,0,sizeof(*((MBSFN_Area1)->ext1)->subcarrierSpacingMBMS_r14)); + + + *(MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14) = LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_khz_1dot25; + + ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); + } + + //nonMBSFN_SubframeConfig_r14 optional + 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->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.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); + //} + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, + NULL, + (void *)bcch_message, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + LOG_D(RRC,"[eNB] SystemInformationBlockType1_MBMS Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); +} +#endif //----------------------------------------------------------------------------- /* * Generate the configuration structure for CDRX feature diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 6e3fa6dd6076213e42e28fbaadb8f2cca4aaeadb..7ddf939e6de36868e08ce1f85249722f7ce8973d 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -70,6 +70,15 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich #endif ); +/** +<<<<<<< HEAD +\brief Generate configuration for MIB (eNB). +@param carrier pointer to Carrier information +@param N_RB_DL Number of downlink PRBs +@param additional Non MBSFN Subframes parameter +@param frame radio frame number +@return size of encoded bit stream in bytes*/ +uint8_t do_MIB_FeMBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFNSubframes, uint32_t frame); /** \brief Generate configuration structure for DRX_Config @param Mod_id Instance of eNB @@ -97,6 +106,17 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id #endif ); +/** +\brief Generate configuration for SIB1 MBMS (eNB). +@param carrier pointer to Carrier information +@param Mod_id Instance of eNB +@param Component carrier Component carrier to configure +@param configuration Pointer Configuration Request structure +@return size of encoded bit stream in bytes*/ +uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id, RrcConfigurationReq *configuration + ); + + /** \brief Generate a default configuration for SIB2/SIB3 in one System Information PDU (eNB). diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 50ae0193238778e3864c0ee3c0b0d577f1a15772..85bad0789d0d8991c7814a784e639d78cd098b76 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -20,12 +20,12 @@ */ /*! \file rrc_UE.c - * \brief rrc procedures for UE - * \author Navid Nikaein and Raymond Knopp - * \date 2011 - 2014 + * \brief rrc procedures for UE / rrc procedures for FeMBMS UE + * \author Navid Nikaein, Raymond Knopp and Javier Morgade + * \date 2011 - 2014 / FeMBMS 2019 * \version 1.0 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr + * \company Eurecom, Vicomtech + * \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr and javier.morgade@ieee.org */ #define RRC_UE @@ -82,6 +82,14 @@ #include "openair2/LAYER2/MAC/mac_extern.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + #include "LTE_BCCH-BCH-Message-MBMS.h" + #include "LTE_BCCH-DL-SCH-Message-MBMS.h" + #include "LTE_SystemInformation-MBMS-r14.h" + #include "LTE_SystemInformationBlockType1-MBMS-r14.h" + #include "LTE_NonMBSFN-SubframeConfig-r14.h" +#endif + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #include "LTE_SL-Preconfiguration-r12.h" @@ -111,9 +119,16 @@ extern void pdcp_config_set_security( void rrc_ue_process_securityModeCommand( const protocol_ctxt_t *const ctxt_pP, LTE_SecurityModeCommand_t *const securityModeCommand, const uint8_t eNB_index ); static int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +static int decode_SI_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ); +#endif static int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +static int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ); +#endif + /** \brief Generates/Encodes RRCConnnectionSetupComplete message at UE * \param ctxt_pP Running context * \param eNB_index Index of corresponding eNB/CH @@ -232,6 +247,12 @@ static void init_SI_UE( protocol_ctxt_t const *ctxt_pP, const uint8_t eNB_index UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].SIB1[eNB_index] = (uint8_t *)malloc16_clear( 32 ); UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType1_t) ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1_MBMS[eNB_index] = 0; + UE_rrc_inst[ctxt_pP->module_id].sizeof_SI_MBMS[eNB_index] = 0; + UE_rrc_inst[ctxt_pP->module_id].SIB1_MBMS[eNB_index] = (uint8_t *)malloc16_clear( 32 ); + UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType1_MBMS_r14_t) ); +#endif UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType2_t) ); UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType3_t) ); UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType4_t) ); @@ -253,6 +274,12 @@ static void init_SI_UE( protocol_ctxt_t const *ctxt_pP, const uint8_t eNB_index UE_rrc_inst[ctxt_pP->module_id].si[eNB_index] = (LTE_SystemInformation_t *)malloc16_clear( sizeof(LTE_SystemInformation_t) ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt = 0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + UE_rrc_inst[ctxt_pP->module_id].SI_MBMS[eNB_index] = (uint8_t *)malloc16_clear( 64 ); + UE_rrc_inst[ctxt_pP->module_id].si_MBMS[eNB_index] = (LTE_SystemInformation_MBMS_r14_t *)malloc16_clear( sizeof(LTE_SystemInformation_MBMS_r14_t) ); + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS = 0; + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt_MBMS = 0; +#endif } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -915,6 +942,12 @@ rrc_ue_process_measConfig( 0, NULL, NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); } @@ -1388,6 +1421,13 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); } } else { @@ -1452,6 +1492,13 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); } } @@ -1559,6 +1606,13 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); } } @@ -2071,6 +2125,13 @@ rrc_ue_process_mobilityControlInfo( NULL, NULL #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); // Re-establish PDCP for all RBs that are established // rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, ue_mod_idP+DCCH); @@ -2562,6 +2623,152 @@ const char *SIB2nB( long value ) { } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int decode_BCCH_MBMS_DLSCH_Message( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + uint8_t *const Sdu, + const uint8_t Sdu_len, + const uint8_t rsrq, + const uint8_t rsrp ) { + LTE_BCCH_DL_SCH_Message_MBMS_t *bcch_message = NULL; + //LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN ); + + /*if (((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS&1) == 1) && // SIB1 received + (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt_MBMS == sib1->schedulingInfoList_MBMS_r14.list.count)) { + // Avoid decoding SystemInformationBlockType1_t* sib1_MBMS = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index]; + // to prevent memory bloating + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + return 0; + }*/ + + rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB ); + + //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS,(void *)bcch_message ); + //} + + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, + (void **)&bcch_message, + (const void *)Sdu, + Sdu_len ); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MBMS_MESSAGE (%zu bits)\n", + ctxt_pP->module_id, + dec_rval.consumed ); + log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); + // free the memory + SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS, (void *)bcch_message, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + return -1; + } + + //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + //xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_MBMS,(void *)bcch_message ); + //} + + if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_MBMS_r14_PR_c1) { + switch (bcch_message->message.choice.c1.present) { + case LTE_BCCH_DL_SCH_MessageType_MBMS_r14__c1_PR_systemInformationBlockType1_MBMS_r14: + if ((ctxt_pP->frame % 4) == 0) { + // every 4 frame + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS&1) == 0) { + LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_mbms = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index]; + memcpy( (void *)sib1_mbms, + (void *)&bcch_message->message.choice.c1.choice.systemInformationBlockType1_MBMS_r14, + sizeof(LTE_SystemInformationBlockType1_MBMS_r14_t) ); + LOG_D( RRC, "[UE %"PRIu8"] Decoding \"First\" SIB1-MBMS\n", ctxt_pP->module_id ); + decode_SIB1_MBMS( ctxt_pP, eNB_index, rsrq, rsrp ); + } + } + + break; + + case LTE_BCCH_DL_SCH_MessageType_MBMS_r14__c1_PR_systemInformation_MBMS_r14: + if ((ctxt_pP->frame % 4) == 0) { + //if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 1) { + // SIB1 with schedulingInfoList is available + // you miss this on the eNB!!!! + LTE_SystemInformation_MBMS_r14_t *si_mbms = UE_rrc_inst[ctxt_pP->module_id].si_MBMS[eNB_index]; + memcpy( si_mbms, + &bcch_message->message.choice.c1.choice.systemInformation_MBMS_r14, + sizeof(LTE_SystemInformation_MBMS_r14_t) ); + LOG_W( RRC, "[UE %"PRIu8"] Decoding MBMS SI for frameP %"PRIu32"\n", + ctxt_pP->module_id, + ctxt_pP->frame ); + decode_SI_MBMS( ctxt_pP, eNB_index ); //TODO + //UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; + //} + } + + break; + + case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: + default: + break; + } + } + + + + /*if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1) { + switch (bcch_message->message.choice.c1.present) { + case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: + if ((ctxt_pP->frame % 2) == 0) { + // even frame + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 0) { + LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + memcpy( (void *)sib1, + (void *)&bcch_message->message.choice.c1.choice.systemInformationBlockType1, + sizeof(LTE_SystemInformationBlockType1_t) ); + LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id ); + decode_SIB1( ctxt_pP, eNB_index, rsrq, rsrp ); + } + } + + break; + + case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 1) { + // SIB1 with schedulingInfoList is available + LTE_SystemInformation_t *si = UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; + memcpy( si, + &bcch_message->message.choice.c1.choice.systemInformation, + sizeof(LTE_SystemInformation_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n", + ctxt_pP->module_id, + ctxt_pP->frame ); + decode_SI( ctxt_pP, eNB_index ); + //if (nfapi_mode == 3) + UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; + } + + break; + + case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: + default: + break; + } + }*/ + + /*if ((rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) +#if defined(ENABLE_USE_MME) + && (UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) +#endif + ) { + rrc_ue_generate_RRCConnectionRequest(ctxt_pP, 0); + rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); + }*/ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + return 0; +} + +#endif + //----------------------------------------------------------------------------- @@ -2691,12 +2898,14 @@ int decode_PCCH_DLSCH_Message( return(0); } -//----------------------------------------------------------------------------- -int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) { - LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) { + LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_MBMS = UE_rrc_inst[ctxt_pP->module_id].sib1_MBMS[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); - LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); - LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; + LOG_I( RRC, "[UE %d] : Dumping SIB 1 SIB1-MBMS\n", ctxt_pP->module_id ); + + //cannot parse ! ... TODO + /*LTE_PLMN_Identity_t *PLMN_identity = ((LTE_PLMN_Identity_t*)(&sib1_MBMS->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.list.array[0]))->plmn_Identity; int mccdigits = PLMN_identity->mcc->list.count; int mncdigits = PLMN_identity->mnc.list.count; int mcc; @@ -2716,9 +2925,9 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, } LOG_I( RRC, "PLMN MCC %0*d, MNC %0*d, TAC 0x%04x\n", mccdigits, mcc, mncdigits, mnc, - ((sib1->cellAccessRelatedInfo.trackingAreaCode.size == 2)?((sib1->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8) + sib1->cellAccessRelatedInfo.trackingAreaCode.buf[1]):0)); - LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, - SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); + ((sib1_MBMS->cellAccessRelatedInfo_r14.trackingAreaCode_r14.size == 2)?((sib1_MBMS->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[0]<<8) + sib1_MBMS->cellAccessRelatedInfo_r14.trackingAreaCode_r14.buf[1]):0)); + LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", ((LTE_PLMN_IndentityInfo_t*)sib1_MBMS->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.list.array[0])->cellReservedForOperatorUse, + SIBreserved(((LTE_PLMN_IdentityInfo_t*)sib1_MBMS->cellAccessRelatedInfo_r14.plmn_IdentityList_r14.list.array[0])->cellReservedForOperatorUse) ); // search internal table for provider name int plmn_ind = 0; @@ -2734,45 +2943,45 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, if (plmn_data[plmn_ind].mcc < 0) { LOG_I( RRC, "Found Unknown operator (no entry in internal table)\n" ); } - +*/ LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", - BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.cellIdentity ), - sib1->cellAccessRelatedInfo.cellIdentity.buf[0], - sib1->cellAccessRelatedInfo.cellIdentity.buf[1], - sib1->cellAccessRelatedInfo.cellIdentity.buf[2], - sib1->cellAccessRelatedInfo.cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.cellIdentity.bits_unused); - LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) ); - LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) ); - LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication ); - - if (sib1->cellAccessRelatedInfo.csg_Identity) - LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) ); - else - LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" ); - - LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo.q_RxLevMin ); - - if (sib1->cellSelectionInfo.q_RxLevMinOffset) - LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo.q_RxLevMinOffset ); - else - LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" ); - - if (sib1->p_Max) - LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max ); - else - LOG_I( RRC, "p_Max : not defined\n" ); - - LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator ); - - if (sib1->schedulingInfoList.list.count > 0) { - for (int i=0; i<sib1->schedulingInfoList.list.count; i++) { - LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->schedulingInfoList.list.array[i]->si_Periodicity,7)]); - - if (sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) { + BIT_STRING_to_uint32( &sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14 ), + sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[0], + sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[1], + sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[2], + sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.buf[3] >> sib1_MBMS->cellAccessRelatedInfo_r14.cellIdentity_r14.bits_unused); + //LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1_MBMS->cellAccessRelatedInfo_r14.cellBarred, SIBbarred(sib1_MBMS->cellAccessRelatedInfo_r14.cellBarred) ); + //LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) ); + //LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication ); + + //if (sib1->cellAccessRelatedInfo.csg_Identity) + //LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) ); + //else + //LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" ); +// + //LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo.q_RxLevMin ); + + //if (sib1->cellSelectionInfo.q_RxLevMinOffset) + //LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo.q_RxLevMinOffset ); + //else + //LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" ); + + //if (sib1->p_Max) + //LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max ); + //else + //LOG_I( RRC, "p_Max : not defined\n" ); + + LOG_I( RRC, "freqBandIndicator : %ld\n", sib1_MBMS->freqBandIndicator_r14 ); + + if (sib1_MBMS->schedulingInfoList_MBMS_r14.list.count > 0) { + for (int i=0; i<sib1_MBMS->schedulingInfoList_MBMS_r14.list.count; i++) { + LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->si_Periodicity_r14,7)]); + + if (sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->sib_MappingInfo_r14.list.count > 0) { char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32 - for (int j=0; j<sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) { - sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(*sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0],11)] ); + for (int j=0; j<sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->sib_MappingInfo_r14.list.count; j++) { + sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(*sib1_MBMS->schedulingInfoList_MBMS_r14.list.array[i]->sib_MappingInfo_r14.list.array[0],11)] ); } LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp ); @@ -2785,16 +2994,18 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, return -1; } - if (sib1->tdd_Config) { - LOG_I( RRC, "TDD subframeAssignment : %ld\n", sib1->tdd_Config->subframeAssignment ); - 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, "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]; - LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + //if (sib1_MBMS->tdd_Config) { + //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, "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]; + + + LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1-MBMS params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, @@ -2808,17 +3019,17 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, 0, (struct LTE_LogicalChannelConfig *)NULL, (LTE_MeasGapConfig_t *)NULL, - UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config, + (LTE_TDD_Config_t *)NULL,//UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config, (LTE_MobilityControlInfo_t *) NULL, - &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize, - &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod, + NULL,//&UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize, + NULL,//&UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod, NULL, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, - (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (sib1_MBMS->systemInformationBlockType13_r14==NULL?(LTE_MBSFN_AreaInfoList_r9_t *)NULL:&(sib1_MBMS->systemInformationBlockType13_r14)->mbsfn_AreaInfoList_r9),//(LTE_MBSFN_AreaInfoList_r9_t *)NULL, (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -2831,23 +3042,27 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, 0, NULL, NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (sib1_MBMS->nonMBSFN_SubframeConfig_r14==NULL?(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL:sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1; - UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; - - //#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - if (EPC_MODE_ENABLED) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus_MBMS = 1; + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag_MBMS = sib1_MBMS->systemInfoValueTag_r14; +#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) +/* + { int cell_valid = 0; if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { - /* Cell is not barred */ int plmn; int plmn_number; plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; - /* Compare requested PLMN and PLMNs from SIB1*/ for (plmn = 0; plmn < plmn_number; plmn++) { LTE_PLMN_Identity_t *plmn_Identity; plmn_Identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_Identity; @@ -2873,7 +3088,6 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2])) ) ) { - /* PLMN match, send a confirmation to NAS */ MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CELL_SELECTION_CNF); NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; @@ -2886,69 +3100,290 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, cell_valid = 1; break; } - } /* for plmn = 0;... */ + } } if (cell_valid == 0) { - /* Cell can not be used, ask PHY to try the next one */ MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); } - }/* EPC_MODE_ENABLED */ - + } +*/ +#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); return 0; } -//----------------------------------------------------------------------------- -void dump_sib2( LTE_SystemInformationBlockType2_t *sib2 ) { - // ac_BarringInfo - if (sib2->ac_BarringInfo) { - LOG_I( RRC, "ac_BarringInfo->ac_BarringForEmergency : %d\n", - sib2->ac_BarringInfo->ac_BarringForEmergency ); - if (sib2->ac_BarringInfo->ac_BarringForMO_Signalling) { - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringFactor : %ld\n", - sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringFactor ); - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringTime : %ld\n", - sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringTime ); - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringForSpecialAC : %"PRIu32"\n", - BIT_STRING_to_uint32(&sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringForSpecialAC) ); - } else - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling : not defined\n" ); +#endif - if (sib2->ac_BarringInfo->ac_BarringForMO_Data) { - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringFactor : %ld\n", - sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringFactor ); - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringTime : %ld\n", - sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringTime ); - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringForSpecialAC : %"PRIu32"\n", - BIT_STRING_to_uint32(&sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringForSpecialAC) ); - } else - LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data : not defined\n" ); - } else - LOG_I( RRC, "ac_BarringInfo : not defined\n" ); +//----------------------------------------------------------------------------- +int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) { + LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); + LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); + LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; + int mccdigits = PLMN_identity->mcc->list.count; + int mncdigits = PLMN_identity->mnc.list.count; + int mcc; - // RACH - LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles : raw:%ld decoded:%s\n", - sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles, - SIB2numberOfRA_Preambles(sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles) ); + if (mccdigits == 2) { + mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; + } else { + mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + } - if (sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig) { - LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA : %ld\n", - sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA ); - LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA : %ld\n", - sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA ); - LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB : %ld\n", - sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB ); + int mnc; + + if (mncdigits == 2) { + mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; } else { - LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig : not defined\n" ); + mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; } - LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep : raw:%ld decoded:%s\n", + LOG_I( RRC, "PLMN MCC %0*d, MNC %0*d, TAC 0x%04x\n", mccdigits, mcc, mncdigits, mnc, + ((sib1->cellAccessRelatedInfo.trackingAreaCode.size == 2)?((sib1->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8) + sib1->cellAccessRelatedInfo.trackingAreaCode.buf[1]):0)); + LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, + SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); + // search internal table for provider name + int plmn_ind = 0; + + while (plmn_data[plmn_ind].mcc > 0) { + if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { + LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); + break; + } + + plmn_ind++; + } + + if (plmn_data[plmn_ind].mcc < 0) { + LOG_I( RRC, "Found Unknown operator (no entry in internal table)\n" ); + } + + LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", + BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.cellIdentity ), + sib1->cellAccessRelatedInfo.cellIdentity.buf[0], + sib1->cellAccessRelatedInfo.cellIdentity.buf[1], + sib1->cellAccessRelatedInfo.cellIdentity.buf[2], + sib1->cellAccessRelatedInfo.cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.cellIdentity.bits_unused); + LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) ); + LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) ); + LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication ); + + if (sib1->cellAccessRelatedInfo.csg_Identity) + LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) ); + else + LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" ); + + LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo.q_RxLevMin ); + + if (sib1->cellSelectionInfo.q_RxLevMinOffset) + LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo.q_RxLevMinOffset ); + else + LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" ); + + if (sib1->p_Max) + LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max ); + else + LOG_I( RRC, "p_Max : not defined\n" ); + + LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator ); + + if (sib1->schedulingInfoList.list.count > 0) { + for (int i=0; i<sib1->schedulingInfoList.list.count; i++) { + LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->schedulingInfoList.list.array[i]->si_Periodicity,7)]); + + if (sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) { + char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32 + + for (int j=0; j<sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) { + sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(*sib1->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0],11)] ); + } + + LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp ); + } else { + LOG_I( RRC, "mapping list %d is null\n", i ); + } + } + } else { + LOG_E( RRC, "siSchedulingInfoPeriod[0] : PROBLEM!!!\n" ); + return -1; + } + + if (sib1->tdd_Config) { + LOG_I( RRC, "TDD subframeAssignment : %ld\n", sib1->tdd_Config->subframeAssignment ); + 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, "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]; + LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); + rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config, + (LTE_MobilityControlInfo_t *) NULL, + &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize, + &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod, + NULL, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,0, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL +#endif +#ifdef CBA + , + 0, + 0 +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + NULL, + NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + + ); + LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1; + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; +#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) + { + int cell_valid = 0; + + if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { + /* Cell is not barred */ + int plmn; + int plmn_number; + plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; + + /* Compare requested PLMN and PLMNs from SIB1*/ + for (plmn = 0; plmn < plmn_number; plmn++) { + LTE_PLMN_Identity_t *plmn_Identity; + plmn_Identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_Identity; + + if ( + ( + (plmn_Identity->mcc == NULL) + || + ( + (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) && + (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) && + (UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2])) + ) + ) + && + (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0])) + && + (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1])) + && + ( + ((UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2)) + || + (UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2])) + ) + ) { + /* PLMN match, send a confirmation to NAS */ + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CELL_SELECTION_CNF); + NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; + NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.cellIdentity); + NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(&sib1->cellAccessRelatedInfo.trackingAreaCode); + NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF; + NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq; + NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp; + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); + cell_valid = 1; + break; + } + } + } + + if (cell_valid == 0) { + /* Cell can not be used, ask PHY to try the next one */ + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); + itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); + LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); + } + } +#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); + return 0; +} + + +//----------------------------------------------------------------------------- +void dump_sib2( LTE_SystemInformationBlockType2_t *sib2 ) { + // ac_BarringInfo + if (sib2->ac_BarringInfo) { + LOG_I( RRC, "ac_BarringInfo->ac_BarringForEmergency : %d\n", + sib2->ac_BarringInfo->ac_BarringForEmergency ); + + if (sib2->ac_BarringInfo->ac_BarringForMO_Signalling) { + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringFactor : %ld\n", + sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringFactor ); + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringTime : %ld\n", + sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringTime ); + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringForSpecialAC : %"PRIu32"\n", + BIT_STRING_to_uint32(&sib2->ac_BarringInfo->ac_BarringForMO_Signalling->ac_BarringForSpecialAC) ); + } else + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Signalling : not defined\n" ); + + if (sib2->ac_BarringInfo->ac_BarringForMO_Data) { + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringFactor : %ld\n", + sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringFactor ); + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringTime : %ld\n", + sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringTime ); + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data->ac_BarringForSpecialAC : %"PRIu32"\n", + BIT_STRING_to_uint32(&sib2->ac_BarringInfo->ac_BarringForMO_Data->ac_BarringForSpecialAC) ); + } else + LOG_I( RRC, "ac_BarringInfo->ac_BarringForMO_Data : not defined\n" ); + } else + LOG_I( RRC, "ac_BarringInfo : not defined\n" ); + + // RACH + LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles : raw:%ld decoded:%s\n", + sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles, + SIB2numberOfRA_Preambles(sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles) ); + + if (sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig) { + LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA : %ld\n", + sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA ); + LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA : %ld\n", + sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA ); + LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB : %ld\n", + sib2->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messagePowerOffsetGroupB ); + } else { + LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig : not defined\n" ); + } + + LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep : raw:%ld decoded:%s\n", sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep, SIB2powerRampingStep(sib2->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep) ); LOG_I( RRC, "radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower : raw:%ld decoded:%s\n", @@ -3320,134 +3755,499 @@ void dump_sib5( LTE_SystemInformationBlockType5_t *sib5 ) { LOG_I(RRC," AllowedMeasBandwidth : 25\n"); break; - case LTE_AllowedMeasBandwidth_mbw50: - LOG_I(RRC," AllowedMeasBandwidth : 50\n"); + case LTE_AllowedMeasBandwidth_mbw50: + LOG_I(RRC," AllowedMeasBandwidth : 50\n"); + break; + + case LTE_AllowedMeasBandwidth_mbw75: + LOG_I(RRC," AllowedMeasBandwidth : 75\n"); + break; + + case LTE_AllowedMeasBandwidth_mbw100: + LOG_I(RRC," AllowedMeasBandwidth : 100\n"); + break; + } + + if (ifcfInfo->presenceAntennaPort1) + LOG_I(RRC," PresenceAntennaPort1 : True\n"); + else + LOG_I(RRC," PresenceAntennaPort1 : False\n"); + + if (ifcfInfo->cellReselectionPriority) { + LOG_I(RRC," CellReselectionPriority : %ld\n", + *ifcfInfo->cellReselectionPriority); + } + + LOG_I(RRC," NeighCellConfig : "); + + for (j=0; j<ifcfInfo->neighCellConfig.size; j++) { + printf("%2x ",ifcfInfo->neighCellConfig.buf[j]); + } + + printf("\n"); + + if (ifcfInfo->q_OffsetFreq) + LOG_I(RRC," Q_OffsetFreq : %d\n",Qoffsettab[*ifcfInfo->q_OffsetFreq]); + + if (ifcfInfo->interFreqNeighCellList) { + for (j=0; j<ifcfInfo->interFreqNeighCellList->list.count; j++) { + LOG_I(RRC," Cell %d\n", j); + LOG_I(RRC," PhysCellId : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->physCellId); + LOG_I(RRC," Q_OffsetRange : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->q_OffsetCell); + } + } + + if (ifcfInfo->interFreqBlackCellList) { + for (j=0; j<ifcfInfo->interFreqBlackCellList->list.count; j++) { + LOG_I(RRC," Cell %d\n", j); + LOG_I(RRC," PhysCellId start: %ld\n",ifcfInfo->interFreqBlackCellList->list.array[j]->start); + + if (ifcfInfo->interFreqBlackCellList->list.array[i]->range) { + LOG_I(RRC," PhysCellId Range : %ld\n",*ifcfInfo->interFreqBlackCellList->list.array[j]->range); + } + } + } + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + + if (ifcfInfo->ext1 && ifcfInfo->ext1->q_QualMin_r9) + LOG_I(RRC," Q_QualMin_r9 : %ld\n",*ifcfInfo->ext1->q_QualMin_r9); + + if (ifcfInfo->ext1 && ifcfInfo->ext1->threshX_Q_r9) { + LOG_I(RRC," threshX_HighQ_r9 : %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_HighQ_r9); + LOG_I(RRC," threshX_LowQ_r9: %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_LowQ_r9); + } + +#endif + } +} + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +void dump_sib13( LTE_SystemInformationBlockType13_r9_t *sib13 ) { + LOG_I( RRC, "[UE] Dumping SIB13\n" ); + LOG_I( RRC, "[UE] dumping sib13 second time\n" ); + LOG_I( RRC, "[UE] NotificationRepetitionCoeff-r9 : %ld\n", sib13->notificationConfig_r9.notificationRepetitionCoeff_r9 ); + LOG_I( RRC, "[UE] NotificationOffset-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationOffset_r9 ); + LOG_I( RRC, "[UE] NotificationSF-Index-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationSF_Index_r9 ); +} + + +//TTN - SIB18 +//----------------------------------------------------------------------------- +void dump_sib18(LTE_SystemInformationBlockType18_r12_t *sib18) { + LOG_I( RRC, "[UE] Dumping SIB18\n" ); + + for (int i = 0; i < sib18->commConfig_r12->commRxPool_r12.list.count; i++) { + LOG_I(RRC, " Contents of SIB18 %d/%d \n", i+1, sib18->commConfig_r12->commRxPool_r12.list.count); + LOG_I(RRC, " SIB18 rxPool_sc_CP_Len: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_CP_Len_r12); + LOG_I(RRC, " SIB18 sc_Period_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_Period_r12); + LOG_I(RRC, " SIB18 data_CP_Len_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->data_CP_Len_r12); + LOG_I(RRC, " SIB18 prb_Num_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, " SIB18 prb_Start_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, " SIB18 prb_End_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_End_r12); + //to add more log + } +} + +//TTN - SIB19 +//----------------------------------------------------------------------------- +void dump_sib19(LTE_SystemInformationBlockType19_r12_t *sib19) { + LOG_I( RRC, "[UE] Dumping SIB19\n" ); + + for (int i = 0; i < sib19->discConfig_r12->discRxPool_r12.list.count; i++) { + LOG_I(RRC, " Contents of SIB19 %d/%d \n", i+1, sib19->discConfig_r12->discRxPool_r12.list.count); + LOG_I(RRC, " SIB19 cp_Len_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->cp_Len_r12); + LOG_I(RRC, " SIB19 discPeriod_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->discPeriod_r12); + LOG_I(RRC, " SIB19 numRetx_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRetx_r12); + LOG_I(RRC, " SIB19 numRepetition_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRepetition_r12); + LOG_I(RRC, " SIB19 prb_Num_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, " SIB19 prb_Start_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, " SIB19 prb_End_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_End_r12); + //to add more log + } +} + +void dump_sib21(LTE_SystemInformationBlockType21_r14_t *sib21) { + if ((sib21->sl_V2X_ConfigCommon_r14 != NULL) && (sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 !=NULL) ) { + for (int i = 0; i < sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count; i++) { + LOG_I(RRC, " Contents of SIB21 %d/%d \n", i+1, sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count); + LOG_I(RRC, " SIB21 sl_Subframe_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sl_Subframe_r14.present); + LOG_I(RRC, " SIB21 adjacencyPSCCH_PSSCH_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->adjacencyPSCCH_PSSCH_r14); + LOG_I(RRC, " SIB21 sizeSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sizeSubchannel_r14); + LOG_I(RRC, " SIB21 numSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->numSubchannel_r14); + LOG_I(RRC, " SIB21 startRB_Subchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->startRB_Subchannel_r14); + //to add more log + } + } +} + + +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +//----------------------------------------------------------------------------- +int decode_SI_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { + /*LTE_SystemInformation_t **si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; + int new_sib = 0; + LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); + + // Dump contents + if ((*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_systemInformation_r8 || +#if (LTE_RRC_VERSION >= MAKE_VERSION(15, 3, 0)) + (*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r15) { +#else + (*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture) { +#endif + LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n", + (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count ); + } + else { + LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel8)\n" ); + return -1; + } + + for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; + + switch(typeandinfo->present) { + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(LTE_SystemInformationBlockType2_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib2( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] ); + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); + rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, + &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->radioResourceConfigCommon, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, +#endif + (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, + NULL, + NULL, + UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_CarrierFreq, + UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth, + &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission, + UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,0, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL +#endif +#ifdef CBA + ,0, + 0 +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + NULL, + NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + + ); + // After SI is received, prepare RRCConnectionRequest +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option +#endif +#if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) + rrc_ue_generate_RRCConnectionRequest( ctxt_pP, eNB_index ); + +#endif + + if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_IDLE) { + LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id ); + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_SI_RECEIVED; +#if ENABLE_RAL + { + MessageDef *message_ral_p = NULL; + rrc_ral_system_information_ind_t ral_si_ind; + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_SYSTEM_INFORMATION_IND); + memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t)); + ral_si_ind.plmn_id.MCCdigit2 = '0'; + ral_si_ind.plmn_id.MCCdigit1 = '2'; + ral_si_ind.plmn_id.MNCdigit3 = '0'; + ral_si_ind.plmn_id.MCCdigit3 = '8'; + ral_si_ind.plmn_id.MNCdigit2 = '9'; + ral_si_ind.plmn_id.MNCdigit1 = '9'; + ral_si_ind.cell_id = 1; + ral_si_ind.dbm = 0; + //ral_si_ind.dbm = fifo_dump_emos_UE.PHY_measurements->rx_rssi_dBm[eNB_index]; + // TO DO + ral_si_ind.sinr = 0; + //ral_si_ind.sinr = fifo_dump_emos_UE.PHY_measurements->subband_cqi_dB[eNB_index][phy_vars_ue->lte_frame_parms.nb_antennas_rx][0]; + // TO DO + ral_si_ind.link_data_rate = 0; + memcpy (&message_ral_p->ittiMsg, (void *) &ral_si_ind, sizeof(rrc_ral_system_information_ind_t)); +#warning "ue_mod_idP ? for instance ?" + itti_send_msg_to_task (TASK_RAL_UE, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), message_ral_p); + } +#endif + } + } + + break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index], &typeandinfo->choice.sib3, sizeof(LTE_SystemInformationBlockType3_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB3 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib3( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] ); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index], &typeandinfo->choice.sib4, sizeof(LTE_SystemInformationBlockType4_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB4 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index], &typeandinfo->choice.sib5, sizeof(LTE_SystemInformationBlockType5_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib5(UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index]); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index], &typeandinfo->choice.sib6, sizeof(LTE_SystemInformationBlockType6_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&64) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=64; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index], &typeandinfo->choice.sib7, sizeof(LTE_SystemInformationBlockType7_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB7 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&128) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=128; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index], &typeandinfo->choice.sib8, sizeof(LTE_SystemInformationBlockType8_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB8 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&256) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=256; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index], &typeandinfo->choice.sib9, sizeof(LTE_SystemInformationBlockType9_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } + + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&512) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=512; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index], &typeandinfo->choice.sib10, sizeof(LTE_SystemInformationBlockType10_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB10 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } + break; - case LTE_AllowedMeasBandwidth_mbw75: - LOG_I(RRC," AllowedMeasBandwidth : 75\n"); - break; + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1024) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=1024; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index], &typeandinfo->choice.sib11, sizeof(LTE_SystemInformationBlockType11_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB11 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } - case LTE_AllowedMeasBandwidth_mbw100: - LOG_I(RRC," AllowedMeasBandwidth : 100\n"); break; - } +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) - if (ifcfInfo->presenceAntennaPort1) - LOG_I(RRC," PresenceAntennaPort1 : True\n"); - else - LOG_I(RRC," PresenceAntennaPort1 : False\n"); + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2048) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2048; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index], &typeandinfo->choice.sib12_v920, sizeof(LTE_SystemInformationBlockType12_r9_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + } - if (ifcfInfo->cellReselectionPriority) { - LOG_I(RRC," CellReselectionPriority : %ld\n", - *ifcfInfo->cellReselectionPriority); - } + break; - LOG_I(RRC," NeighCellConfig : "); + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4096) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4096; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index], &typeandinfo->choice.sib13_v920, sizeof(LTE_SystemInformationBlockType13_r9_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib13( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] ); + // adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)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, + NULL, + NULL, + NULL, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *)NULL, + 0, + &UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index]->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *)NULL +#ifdef CBA + ,0, + 0 +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + NULL, + NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); + break; + } - for (j=0; j<ifcfInfo->neighCellConfig.size; j++) { - printf("%2x ",ifcfInfo->neighCellConfig.buf[j]); - } +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - printf("\n"); + //SIB18 + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8192; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], &typeandinfo->choice.sib18_v1250, sizeof(LTE_SystemInformationBlockType18_r12_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB18 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib18( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] ); + // adding here function to store necessary parameters to transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB18 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + //process SIB18 to transfer SL-related parameters to PHY + rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, + UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], + (LTE_SystemInformationBlockType19_r12_t *)NULL, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL + ); + } - if (ifcfInfo->q_OffsetFreq) - LOG_I(RRC," Q_OffsetFreq : %d\n",Qoffsettab[*ifcfInfo->q_OffsetFreq]); + break; - if (ifcfInfo->interFreqNeighCellList) { - for (j=0; j<ifcfInfo->interFreqNeighCellList->list.count; j++) { - LOG_I(RRC," Cell %d\n", j); - LOG_I(RRC," PhysCellId : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->physCellId); - LOG_I(RRC," Q_OffsetRange : %ld\n",ifcfInfo->interFreqNeighCellList->list.array[j]->q_OffsetCell); - } - } + //SIB19 + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16384) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16384; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], &typeandinfo->choice.sib19_v1250, sizeof(LTE_SystemInformationBlockType19_r12_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB19 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib19( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] ); + // adding here function to store necessary parameters to transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB19 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + //process SIB19 to transfer SL-related parameters to PHY + rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, + (LTE_SystemInformationBlockType18_r12_t *)NULL, + UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL + ); + } - if (ifcfInfo->interFreqBlackCellList) { - for (j=0; j<ifcfInfo->interFreqBlackCellList->list.count; j++) { - LOG_I(RRC," Cell %d\n", j); - LOG_I(RRC," PhysCellId start: %ld\n",ifcfInfo->interFreqBlackCellList->list.array[j]->start); + break; - if (ifcfInfo->interFreqBlackCellList->list.array[i]->range) { - LOG_I(RRC," PhysCellId Range : %ld\n",*ifcfInfo->interFreqBlackCellList->list.array[j]->range); + //SIB21 + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32768) == 0) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32768; + new_sib=1; + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index], &typeandinfo->choice.sib21_v1430, sizeof(LTE_SystemInformationBlockType21_r14_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB21 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); + dump_sib21( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] ); + // adding here function to store necessary parameters to transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB21 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); + //process SIB21 + //TODO } - } - } - -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - if (ifcfInfo->ext1 && ifcfInfo->ext1->q_QualMin_r9) - LOG_I(RRC," Q_QualMin_r9 : %ld\n",*ifcfInfo->ext1->q_QualMin_r9); + break; +#endif - if (ifcfInfo->ext1 && ifcfInfo->ext1->threshX_Q_r9) { - LOG_I(RRC," threshX_HighQ_r9 : %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_HighQ_r9); - LOG_I(RRC," threshX_LowQ_r9: %ld\n",ifcfInfo->ext1->threshX_Q_r9->threshX_LowQ_r9); + default: + break; } - -#endif } -} - -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -void dump_sib13( LTE_SystemInformationBlockType13_r9_t *sib13 ) { - LOG_I( RRC, "[UE] Dumping SIB13\n" ); - LOG_I( RRC, "[UE] dumping sib13 second time\n" ); - LOG_I( RRC, "[UE] NotificationRepetitionCoeff-r9 : %ld\n", sib13->notificationConfig_r9.notificationRepetitionCoeff_r9 ); - LOG_I( RRC, "[UE] NotificationOffset-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationOffset_r9 ); - LOG_I( RRC, "[UE] NotificationSF-Index-r9 : %d\n", (int)sib13->notificationConfig_r9.notificationSF_Index_r9 ); -} - - -//TTN - SIB18 -//----------------------------------------------------------------------------- -void dump_sib18(LTE_SystemInformationBlockType18_r12_t *sib18) { - LOG_I( RRC, "[UE] Dumping SIB18\n" ); - for (int i = 0; i < sib18->commConfig_r12->commRxPool_r12.list.count; i++) { - LOG_I(RRC, " Contents of SIB18 %d/%d \n", i+1, sib18->commConfig_r12->commRxPool_r12.list.count); - LOG_I(RRC, " SIB18 rxPool_sc_CP_Len: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_CP_Len_r12); - LOG_I(RRC, " SIB18 sc_Period_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_Period_r12); - LOG_I(RRC, " SIB18 data_CP_Len_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->data_CP_Len_r12); - LOG_I(RRC, " SIB18 prb_Num_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Num_r12); - LOG_I(RRC, " SIB18 prb_Start_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_Start_r12); - LOG_I(RRC, " SIB18 prb_End_r12: %ld \n", sib18->commConfig_r12->commRxPool_r12.list.array[i]->sc_TF_ResourceConfig_r12.prb_End_r12); - //to add more log - } -} + if (new_sib == 1) { + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt++; -//TTN - SIB19 -//----------------------------------------------------------------------------- -void dump_sib19(LTE_SystemInformationBlockType19_r12_t *sib19) { - LOG_I( RRC, "[UE] Dumping SIB19\n" ); + if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt == sib1->schedulingInfoList.list.count) + rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); - for (int i = 0; i < sib19->discConfig_r12->discRxPool_r12.list.count; i++) { - LOG_I(RRC, " Contents of SIB19 %d/%d \n", i+1, sib19->discConfig_r12->discRxPool_r12.list.count); - LOG_I(RRC, " SIB19 cp_Len_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->cp_Len_r12); - LOG_I(RRC, " SIB19 discPeriod_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->discPeriod_r12); - LOG_I(RRC, " SIB19 numRetx_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRetx_r12); - LOG_I(RRC, " SIB19 numRepetition_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->numRepetition_r12); - LOG_I(RRC, " SIB19 prb_Num_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Num_r12); - LOG_I(RRC, " SIB19 prb_Start_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_Start_r12); - LOG_I(RRC, " SIB19 prb_End_r12: %ld \n", sib19->discConfig_r12->discRxPool_r12.list.array[i]->tf_ResourceConfig_r12.prb_End_r12); - //to add more log + LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus, + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt, + sib1->schedulingInfoList.list.count); } -} -void dump_sib21(LTE_SystemInformationBlockType21_r14_t *sib21) { - if ((sib21->sl_V2X_ConfigCommon_r14 != NULL) && (sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 !=NULL) ) { - for (int i = 0; i < sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count; i++) { - LOG_I(RRC, " Contents of SIB21 %d/%d \n", i+1, sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count); - LOG_I(RRC, " SIB21 sl_Subframe_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sl_Subframe_r14.present); - LOG_I(RRC, " SIB21 adjacencyPSCCH_PSSCH_r14: %d \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->adjacencyPSCCH_PSSCH_r14); - LOG_I(RRC, " SIB21 sizeSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->sizeSubchannel_r14); - LOG_I(RRC, " SIB21 numSubchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->numSubchannel_r14); - LOG_I(RRC, " SIB21 startRB_Subchannel_r14: %ld \n", sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.array[i]->startRB_Subchannel_r14); - //to add more log - } - } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI , VCD_FUNCTION_OUT);*/ + return 0; } #endif + //----------------------------------------------------------------------------- int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { LTE_SystemInformation_t **si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; @@ -3516,6 +4316,12 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { 0, NULL, NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); // After SI is received, prepare RRCConnectionRequest @@ -3702,6 +4508,12 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { 0, NULL, NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); break; @@ -4223,6 +5035,13 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f NULL, NULL #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL +#endif + ); 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); @@ -4310,6 +5129,22 @@ void *rrc_ue_task( void *args_p ) { RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); break; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + case RRC_MAC_BCCH_MBMS_DATA_IND: + LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), + RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).frame, RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).enb_index); + // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).frame, 0,RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).enb_index); + decode_BCCH_MBMS_DLSCH_Message (&ctxt, + RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).enb_index, + RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).sdu, + RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).sdu_size, + RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).rsrq, + RRC_MAC_BCCH_MBMS_DATA_IND (msg_p).rsrp); + break; +#endif + + case RRC_MAC_CCCH_DATA_CNF: LOG_D(RRC, "[UE %d] Received %s: eNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), RRC_MAC_CCCH_DATA_CNF (msg_p).enb_index); @@ -5241,6 +6076,12 @@ void *rrc_control_socket_thread_fct(void *arg) { ,CONFIG_ACTION_ADD, &sourceL2Id, &groupL2Id +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); LOG_I(RRC,"Send GroupCommunicationEstablishResp to ProSe App\n"); @@ -5312,6 +6153,12 @@ void *rrc_control_socket_thread_fct(void *arg) { ,CONFIG_ACTION_REMOVE, &sourceL2Id, &destinationL2Id +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); LOG_I(RRC,"Send GroupCommunicationReleaseResponse to ProSe App \n"); @@ -5472,6 +6319,12 @@ void *rrc_control_socket_thread_fct(void *arg) { ,CONFIG_ACTION_ADD, &sourceL2Id, &destinationL2Id +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); LOG_I(RRC,"Send DirectCommunicationEstablishResp to ProSe App\n"); @@ -5646,6 +6499,12 @@ void *rrc_control_socket_thread_fct(void *arg) { ,CONFIG_ACTION_ADD, &sourceL2Id, &destinationL2Id +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); } else {//RX @@ -5684,6 +6543,12 @@ void *rrc_control_socket_thread_fct(void *arg) { ,CONFIG_ACTION_ADD, &sourceL2Id, NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL #endif ); } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 1da374dd4278d379a26ea04ad132f8ba56e36bd3..2f3f6799355b6f69e024c3338a5395b0dccdb2e4 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -404,13 +404,25 @@ typedef struct UE_RRC_INFO_s { uint8_t SIB1systemInfoValueTag; uint32_t SIStatus; uint32_t SIcnt; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t SIB1systemInfoValueTag_MBMS; + uint32_t SIStatus_MBMS; + uint32_t SIcnt_MBMS; +#endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA #endif uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t SIwindowsize_MBMS; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 +#endif + uint8_t handoverTarget; HO_STATE_t ho_state; uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint16_t SIperiod_MBMS; //!< Corresponds to the SIB1-MBMS si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 TODO +#endif unsigned short UE_index; uint32_t T300_active; uint32_t T300_cnt; @@ -656,6 +668,10 @@ typedef struct { uint8_t sizeof_SIB1_BR; uint8_t *SIB23_BR; uint8_t sizeof_SIB23_BR; + uint8_t *MIB_FeMBMS; + uint8_t sizeof_MIB_FeMBMS; + uint8_t *SIB1_MBMS; + uint8_t sizeof_SIB1_MBMS; #endif int physCellId; int Ncp; @@ -673,12 +689,20 @@ typedef struct { LTE_BCCH_DL_SCH_Message_t systemInformation; LTE_BCCH_DL_SCH_Message_t systemInformation_BR; // SystemInformation_t systemInformation; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 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; +#endif LTE_SystemInformationBlockType1_t *sib1; LTE_SystemInformationBlockType2_t *sib2; LTE_SystemInformationBlockType3_t *sib3; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_SystemInformationBlockType1_t *sib1_BR; LTE_SystemInformationBlockType2_t *sib2_BR; + LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_MBMS; + LTE_SystemInformationBlockType13_r9_t *sib13_MBMS; + uint8_t FeMBMS_flag; #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) LTE_SystemInformationBlockType13_r9_t *sib13; @@ -774,8 +798,22 @@ typedef struct UE_RRC_INST_s { uint8_t sizeof_SI[NB_CNX_UE]; uint8_t SIB1Status[NB_CNX_UE]; uint8_t SIStatus[NB_CNX_UE]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint8_t *SIB1_MBMS[NB_CNX_UE]; + uint8_t sizeof_SIB1_MBMS[NB_CNX_UE]; + uint8_t *SI_MBMS[NB_CNX_UE]; + uint8_t sizeof_SI_MBMS[NB_CNX_UE]; + uint8_t SIB1Status_MBMS[NB_CNX_UE]; + uint8_t SIStatus_MBMS[NB_CNX_UE]; +#endif LTE_SystemInformationBlockType1_t *sib1[NB_CNX_UE]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_SystemInformationBlockType1_MBMS_r14_t *sib1_MBMS[NB_CNX_UE]; +#endif LTE_SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_SystemInformation_MBMS_r14_t *si_MBMS[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). +#endif LTE_SystemInformationBlockType2_t *sib2[NB_CNX_UE]; LTE_SystemInformationBlockType3_t *sib3[NB_CNX_UE]; LTE_SystemInformationBlockType4_t *sib4[NB_CNX_UE]; @@ -817,6 +855,10 @@ typedef struct UE_RRC_INST_s { LTE_SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; LTE_SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; #endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_SystemInformationBlockType13_r9_t *sib13_MBMS[NB_CNX_UE]; + uint8_t FeMBMS_flag; +#endif #ifdef CBA uint8_t num_active_cba_groups; uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 1dd3a26053a34c2fa39f7b009d8203b67eaa70ef..15771a766a6cdd630d345600afcb01c5c860e6ec 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -62,6 +62,12 @@ #include "LTE_SL-CommConfig-r12.h" #include "LTE_PeriodicBSR-Timer-r12.h" #include "LTE_RetxBSR-Timer-r12.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + #include "LTE_BCCH-BCH-Message-MBMS.h" + #include "LTE_BCCH-DL-SCH-Message-MBMS.h" + #include "LTE_SystemInformationBlockType1-MBMS-r14.h" + #include "LTE_NonMBSFN-SubframeConfig-r14.h" +#endif #include "common/utils/LOG/vcd_signal_dumper.h" #include "x2ap_eNB.h" @@ -142,6 +148,100 @@ init_SI( LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL; #endif LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +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); + do_MIB_FeMBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], +#ifdef ENABLE_ITTI + configuration->N_RB_DL[CC_id], + 0 //additionalNonMBSFN +#else + 50,0 +#endif + ,0); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = 0; + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_MBMS = (uint8_t *) malloc16(32); + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_MBMS!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1_MBMS allocated\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_MBMS = do_SIB1_MBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id +#if defined(ENABLE_ITTI) + , configuration +#endif + ); + + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB1-MBMS\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP) + ); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS freqBandIndicator_r14 %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->freqBandIndicator_r14 + ); + + for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->schedulingInfoList_MBMS_r14.list.count; i++) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS contents for Scheduling Info List %d/%d(partial)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + i, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->schedulingInfoList_MBMS_r14.list.count); + } + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13-r14 contents for MBSFN subframe allocation (partial)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP) + ); + + for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.count; i++) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13-r14 contents for MBSFN sync area %d/%d (partial)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + i, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Repetition Period: %ld (just index number, not real value)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Offset: %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Modification Period: %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_ModificationPeriod_r9); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS MCCH Signalling MCS: %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.signallingMCS_r9); + //LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS SIB13 sf_AllocInfo is = %x\n", + // PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + // RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.sf_AllocInfo_r9.buf); + + if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->ext1) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS Subcarrier Spacing MBMS: %s\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (*RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->ext1->subcarrierSpacingMBMS_r14 == LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_khz_1dot25 ? "khz_1dot25": "khz_7dot5")); + } + } + + + + if(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config radioFrameAllocationPeriod-r14 %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->radioFrameAllocationPeriod_r14 + ); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config radioFrameAllocationOffset-r14 %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->radioFrameAllocationOffset_r14 + ); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS non MBSFN Subframe Config subframeAllocation-r14 is = %s\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->nonMBSFN_SubframeConfig_r14->subframeAllocation_r14.buf); + + + + } + + + //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"); +} +#endif + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; @@ -496,9 +596,17 @@ init_SI( , sib1_v13ext #endif - ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].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 +#endif + ); } - /* set flag to indicate that cell information is configured. This is required * in DU to trigger F1AP_SETUP procedure */ pthread_mutex_lock(&rrc->cell_info_mutex); @@ -587,7 +695,16 @@ init_MCCH( , (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 +#endif + ); } //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9); } @@ -1378,6 +1495,15 @@ rrc_eNB_generate_RRCConnectionReestablishment( #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) ,(LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 #endif ); break; @@ -4931,10 +5057,149 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct // assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4; physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4; - //} - //else { - //LOG_E(RRC,"physical_config_dedicated not present in RRCConnectionReconfiguration. Not reconfiguring!\n"); - //} + LOG_D(RRC, + "handover_config [FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 UE %x) --->][MAC_eNB][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ctxt_pP->module_id); + rrc_mac_config_req_eNB( + ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + ue_context_pP->ue_context.physicalConfigDedicated, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + NULL,//SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *) NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 +#endif + ); + // Configure target eNB SRB2 + /// SRB2 + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB_configList2 = CALLOC(1, sizeof(*SRB_configList2)); + memset(SRB_configList2, 0, sizeof(*SRB_configList2)); + SRB2_config->srb_Identity = 2; + SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config)); + SRB2_config->rlc_Config = SRB2_rlc_config; + SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10; + SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); + SRB2_config->logicalChannelConfig = SRB2_lchan_config; + SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); + SRB2_ul_SpecificParameters->priority = 1; + SRB2_ul_SpecificParameters->prioritisedBitRate = + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + // LCG for CCCH and DCCH is 0 as defined in 36331 + logicalchannelgroup = CALLOC(1, sizeof(long)); + *logicalchannelgroup = 0; + SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; + SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + // Configure target eNB DRB + DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2)); + /// DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); + //DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32 + // NN: this is the 1st DRB for this ue, so set it to 1 + DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32 + DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->logicalChannelIdentity) = (long)3; + DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = NULL; + DRB_pdcp_config->rlc_AM = NULL; + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; + DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + DRB_ul_SpecificParameters->priority = 2; // lower priority than srb1, srb2 + DRB_ul_SpecificParameters->prioritisedBitRate = + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); + mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); + ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; + mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); + maxHARQ_Tx = CALLOC(1, sizeof(long)); + *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + periodicBSR_Timer = CALLOC(1, sizeof(long)); + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->drx_Config = NULL; + mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); + mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); + mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; + //sps_RA_ConfigList_rlola = NULL; +#endif // Measurement ID list MeasId_list = CALLOC(1, sizeof(*MeasId_list)); memset((void *)MeasId_list, 0, sizeof(*MeasId_list)); @@ -5461,6 +5726,15 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 #endif ); //#if 0 @@ -5688,9 +5962,18 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( , (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif - ); - } - } else { // end if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) // remove LCHAN from MAC/PHY +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 +#endif + ); + } + } else { // remove LCHAN from MAC/PHY if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, @@ -5752,6 +6035,15 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 #endif ); } @@ -5920,8 +6212,18 @@ rrc_eNB_generate_RRCConnectionSetup( , (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); - } +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 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 +#endif + ); + break; + } } } diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index 99b77b6b61dbc05ab57be000e0e7382be85a33d9..34439753d8f5ab796267940e159a62ca04beee75 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -542,6 +542,16 @@ int decode_BCCH_DLSCH_Message( const uint8_t rsrq, const uint8_t rsrp ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +int decode_BCCH_MBMS_DLSCH_Message( + const protocol_ctxt_t* const ctxt_pP, + const uint8_t eNB_index, + uint8_t* const Sdu, + const uint8_t Sdu_len, + const uint8_t rsrq, + const uint8_t rsrp ); +#endif + int decode_PCCH_DLSCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index 14d762da132633fd51211085eb02379f33a8087e..b72e4c59d7b538d20af3e7bf159e9adfda7093f2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -105,7 +105,8 @@ eNBs = ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; - ue_TransmissionMode = 2; + ue_TransmissionMode = 1; + mbms_dedicated_serving_cell = "ENABLE" } ); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index c923b2a16f17e6b8d6554ab296f6665ca6a05b87..eb510e5ff21c996b56e2d5c9855152e3a415e0f0 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -618,7 +618,7 @@ int main( int argc, char **argv ) { if (config_mod == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } - + mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); set_latency_target();