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 = &lte_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();