diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index cbae84f56b6c1643884468f09fbc52db0df62694..bec08732769d0758332f4231fd3b7b4a2f9da721 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -450,11 +450,11 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
       } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
         fp->MBSFN_config[i].fourFrames_flag = 1;
         fp->MBSFN_config[i].mbsfn_SubframeConfig =
-          mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]|
+          mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
           (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
-          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16);
+          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
 
-        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
+        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %x\n", i,
               fp->MBSFN_config[i].mbsfn_SubframeConfig);
       }
     }
diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c
index 62d768a50aeee992662826aff4928d8c5d1e5e08..1ed9e20d602ecc39f4f573f37b83142a5fa60d2d 100644
--- a/openair1/PHY/INIT/lte_init_ue.c
+++ b/openair1/PHY/INIT/lte_init_ue.c
@@ -165,11 +165,11 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id,
       } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
         fp->MBSFN_config[i].fourFrames_flag = 1;
         fp->MBSFN_config[i].mbsfn_SubframeConfig =
-          mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]|
+          mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
           (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
-          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16);
+          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
 
-        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
+        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %x\n", i,
               fp->MBSFN_config[i].mbsfn_SubframeConfig);
       }
     }
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
index e268a5b061c0e06031681909be23cfbb4acc87cd..516cb32999b505aa08f1e36c2c23a1d08c747288 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
@@ -61,8 +61,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
     temp = 0;
 
     for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
-      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
+      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)];
+      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)];
       temp += (Re*Re/2) + (Im*Im/2);
     }
 
@@ -81,7 +81,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
   // do not filter to have proactive timing adjustment
   max_pos_fil = max_pos;
 
-  if(subframe == 6)
+  if(subframe == 5)
   {
       diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
index 732db1fa4e533998a83ede51735111520df19042..c912c8893482c1c00c47b73128a0e7de5b73a052 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
@@ -62,8 +62,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
     temp = 0;
 
     for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
-      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
+      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)];
+      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)];
       temp += (Re*Re/2) + (Im*Im/2);
     }
 
@@ -82,7 +82,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
   // do not filter to have proactive timing adjustment
   max_pos_fil = max_pos;
 
-  if(subframe == 6)
+  if(subframe == 5)
   {
       diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
 
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
index 14def309b7bdb11043ef66712b0828d5546898d6..69dbb705db8fd4cd85f215f50a63949f5fb88ed1 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
@@ -54,9 +54,9 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl
     for (l=0; l<3; l++) {
 
       if (l==0)
-        x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + 2 + (7*(1+(sfn>>1)))))<<9); //cinit
+        x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + 2 + (7*(1+(sfn<<1)))))<<9); //cinit
       else
-        x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + ((l-1)<<2) + (7*(2+(sfn>>1)))))<<9); //cinit
+        x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + ((l-1)<<2) + (7*(2+(sfn<<1)))))<<9); //cinit
 
       //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
       //n = 0
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch_common.c b/openair1/PHY/LTE_TRANSPORT/pmch_common.c
index 1d12c79621ea403c93c1eaa6389da0fa5065aa8c..a4821a420ff27f87731c6b737d515598e5758343 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch_common.c
@@ -27,6 +27,7 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par
 
   uint32_t period;
   uint8_t i;
+  uint8_t j;
 
   //  LOG_D(PHY,"is_pmch_subframe: frame %d, subframe %d, num_MBSFN_config %d\n",
   //  frame,subframe,frame_parms->num_MBSFN_config);
@@ -34,8 +35,8 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par
   for (i=0; i<frame_parms->num_MBSFN_config; i++) {  // we have at least one MBSFN configuration
     period = 1<<frame_parms->MBSFN_config[i].radioframeAllocationPeriod;
 
-    if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) {
-      if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) {
+    if (frame_parms->MBSFN_config[i].fourFrames_flag == 0) {
+      if ((frame % period) == frame_parms->MBSFN_config[i].radioframeAllocationOffset) {
         if (frame_parms->frame_type == FDD) {
           switch (subframe) {
 
@@ -108,9 +109,96 @@ int is_pmch_subframe(uint32_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_par
             break;
           }
         }
+      }
+
+    } else { // handle 4 frames case
+
+      for(j=0;j<4;j++) {
+        if ((frame % period) == (frame_parms->MBSFN_config[i].radioframeAllocationOffset + j)) {
+          if (frame_parms->frame_type == FDD) {
+            switch (subframe) {
+            case 1:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig)  & (0x800000>>(j*6))) > 0) {
+                //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x800000>>(j*6));
+                return(1);
+              }
+
+              break;
+
+            case 2:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x400000>>(j*6))) > 0) {
+                //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x400000>>(j*6));
+                return(1);
+              }
+
+              break;
+
+            case 3:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x200000>>(j*6))) > 0) {
+                //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x200000>>(j*6));
+                return(1);
+              }
+
+              break;
+
+            case 6:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x100000>>(j*6))) > 0) {
+                //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x100000>>(j*6));
+                return(1);
+              }
+
+              break;
+
+            case 7:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x80000>>(j*6))) > 0) {
+                //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x80000>>(j*6));
+                return(1);
+              }
+
+              break;
 
-      } else { // handle 4 frames case
+            case 8:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig) & (0x40000>>(j*6))) > 0) {
+                //LOG_E(PHY,"SubframeConfig<<6(%x),MBSFN_FDD_SF1(%x)\n",frame_parms->MBSFN_config[i].mbsfn_SubframeConfig,0x40000>>(j*6));
+                return(1);
+              }
 
+              break;
+            }
+          } else {
+            switch (subframe) {
+            case 3:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF3) > 0)
+                return(1);
+
+              break;
+
+            case 4:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF4) > 0)
+                return(1);
+
+              break;
+
+            case 7:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF7) > 0)
+                return(1);
+
+              break;
+
+            case 8:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF8) > 0)
+                return(1);
+
+              break;
+
+            case 9:
+              if (((frame_parms->MBSFN_config[i].mbsfn_SubframeConfig>>j*6) & MBSFN_TDD_SF9) > 0)
+                return(1);
+
+              break;
+            }
+          }
+        }
       }
     }
   }
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
index b9fbcad9c9349cbec14cd23f4c75e4ddbab6b6e4..e0ea796a826fb6b05357f5624942a954706cb389 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
@@ -179,29 +179,29 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_
 
     uint32_t rballoc=0;
     uint8_t mcs=0;
+    uint8_t Ngap=0;
 
     switch (N_RB_DL) {
         case 6:
-          mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
-          rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6);
-
+          mcs             = ((DCI1C_1_5MHz_t *)dci_pdu)->mcs;
+          rballoc         = conv_1C_RIV(((DCI1C_1_5MHz_t *)dci_pdu)->rballoc, 6);
           break;
 
         case 25:
-            mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
-            rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6);
-
+          mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
+          rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc, 25);
           break;
 
         case 50:
-            mcs             = ((DCI1C_10MHz_t *)dci_pdu)->mcs;
-            rballoc         = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6);
-
+          mcs             = ((DCI1C_10MHz_t *)dci_pdu)->mcs;
+          rballoc         = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc, 50);
+          Ngap            = ((DCI1C_10MHz_t *)dci_pdu)->Ngap;
           break;
 
         case 100:
-            mcs             = ((DCI1C_20MHz_t *)dci_pdu)->mcs;
-            rballoc         = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6);
+          mcs             = ((DCI1C_20MHz_t *)dci_pdu)->mcs;
+          rballoc         = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc, 100);
+          Ngap            = ((DCI1C_20MHz_t *)dci_pdu)->Ngap;
           break;
 
         default:
@@ -211,6 +211,7 @@ void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_
 
     pdci_info_extarcted->mcs1     = mcs;
     pdci_info_extarcted->rballoc  = rballoc;
+    pdci_info_extarcted->Ngap     = Ngap;
 }
 
 void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c
index ed258ed47c6f0ab6875d15582d5b8879c4b29395..02f3e5aaace3931d380d3fb70551520050bb838b 100644
--- a/openair1/SCHED_UE/phy_procedures_lte_ue.c
+++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c
@@ -2516,7 +2516,7 @@ void ue_measurement_procedures(
 	  T_INT((int)ue->common_vars.freq_offset));
   }
 
-  if (l==(6-ue->frame_parms.Ncp)) {
+  if (( (slot%2) == 0) && (l==(6-ue->frame_parms.Ncp))) {
 
     // make sure we have signal from PSS/SSS for N0 measurement
          // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
@@ -2982,18 +2982,18 @@ LOG_DEBUG_END
 
     else if ((ue->prach_resources[eNB_id]) &&
        (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
-       (dci_alloc_rx[i].format == format1A)) {
+       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
 
 LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
-      LOG_D(PHY,"[UE  %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i);
+      LOG_D(PHY,"[UE  %d][RAPROC] subframe %d: Found RA rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
 LOG_DEBUG_END
 
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
 					    subframe_rx,
-					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
+					    (void *)&dci_alloc_rx[i].dci_pdu,
 					    ue->prach_resources[eNB_id]->ra_RNTI,
-					    format1A,
+					    dci_alloc_rx[i].format,
 					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
 					    ue->pdsch_vars_ra[eNB_id],
 					    &ue->dlsch_ra[eNB_id],
@@ -3128,7 +3128,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
     // LOG_D(PHY,"ue calling pmch subframe ..\n ");
 
     LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
-    ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
+    ue->Mod_id,frame_rx,subframe_rx);
 #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
 
     pmch_mcs = ue_query_mch(ue->Mod_id,
@@ -3147,9 +3147,7 @@ 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);
 
-      
       for (l=2; l<12; l++) {
-	
 	slot_fep_mbsfn(ue,
 		       l,
 		       subframe_rx,
@@ -3164,6 +3162,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
       }
       
       
+      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,
@@ -3177,7 +3177,14 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
       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);
-      
+
+      LOG_D(PHY,"start turbo decode for MCH %d.%d --> nb_rb %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb);
+      LOG_D(PHY,"start turbo decode for MCH %d.%d --> rb_alloc_even %x \n", frame_rx, subframe_rx, (unsigned int)((intptr_t)ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even));
+      LOG_D(PHY,"start turbo decode for MCH %d.%d --> Qm %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Qm);
+      LOG_D(PHY,"start turbo decode for MCH %d.%d --> Nl %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Nl);
+      LOG_D(PHY,"start turbo decode for MCH %d.%d --> G  %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G);
+      LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo  %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo);
+
       ret = dlsch_decoding(ue,
 			   ue->pdsch_vars_MCH[0]->llr[0],
 			   &ue->frame_parms,
@@ -3206,7 +3213,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 	      ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
 	      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);
+	// dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
 LOG_DEBUG_BEGIN(DEBUG_UE_PHYPROC)
 	
 	for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
@@ -3222,25 +3229,24 @@ LOG_DEBUG_END
       } else { // decoding successful
 #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
 	
-	if (mcch_active == 1) {
-	  ue_send_mch_sdu(ue->Mod_id,
-			  CC_id,
-			  frame_rx,
-			  ue->dlsch_MCH[0]->harq_processes[0]->b,
-			  ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
-			  eNB_id,// not relevant in eMBMS context
-			  sync_area);
+	ue_send_mch_sdu(ue->Mod_id,
+			CC_id,
+			frame_rx,
+			ue->dlsch_MCH[0]->harq_processes[0]->b,
+			ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+			eNB_id,// not relevant in eMBMS context
+			sync_area);
+
+	if (mcch_active == 1)
 	  ue->dlsch_mcch_received[sync_area][0]++;
-	  
-	  
-	  if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
-	    ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
-	  } else {
-	    ue->dlsch_mch_received[0]+=1;
-	    ue->dlsch_mch_received_sf[subframe_rx][0]=1;
-	  }
-	  
-	  
+	else
+	  ue->dlsch_mtch_received[sync_area][0]++;
+
+	if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
+	  ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
+	} else {
+	  ue->dlsch_mch_received[0]+=1;
+	  ue->dlsch_mch_received_sf[subframe_rx][0]=1;
 	}
 
 #endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
@@ -4179,7 +4185,7 @@ LOG_DEBUG_END
 
 
     if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
-        l2 = 5;
+        l2 = 4;
     } else if (pmch_flag == 1) { // do first 2 symbols only
         l2 = 1;
     } else { // normal subframe, last symbol to be processed is the first of the second slot
@@ -4665,7 +4671,7 @@ LOG_DEBUG_END
 
 
   if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
-    l2 = 5;
+    l2 = 4;
   } else if (pmch_flag == 1) { // do first 2 symbols only
     l2 = 1;
   } else { // normal subframe, last symbol to be processed is the first of the second slot
@@ -4709,7 +4715,7 @@ LOG_DEBUG_END
 
     if (do_pdcch_flag) {
       if ((l==pilot1) ||
-	  ((pmch_flag==1)&(l==l2)))  {
+	  ((pmch_flag==1)&&(l==l2)))  {
 	LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
 
 	//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
@@ -4729,9 +4735,22 @@ LOG_DEBUG_END
   ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
 
   LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
-    // If this is PMCH, call procedures and return
+
+  // 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);
+
+    int next_subframe_rx = (1+subframe_rx)%10;
+    if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
+    {
+      slot_fep(ue,
+         0,
+         (next_subframe_rx<<1),
+         0,
+         0,
+         0);
+    }
+
     return 0;
   }
 
@@ -4841,6 +4860,7 @@ LOG_DEBUG_END
       ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
 
     } // for l=1..l2
+    ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
 
     // do first symbol of next downlink subframe for channel estimation
     int next_subframe_rx = (1+subframe_rx)%10;
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index d9e914f087009858a77e323fb2c3597609ca3d38..f8121310b1e413496d6663701662051d256f95ed 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -442,7 +442,7 @@ typedef struct {
 /*!\brief LCID of MCCH for DL */
 #define MCCH_LCHANID 0
 /*!\brief LCID of MCH scheduling info for DL */
-#define MCH_SCHDL_INFO 3
+#define MCH_SCHDL_INFO 30
 /*!\brief LCID of Carrier component activation/deactivation */
 #define CC_ACT_DEACT 27
 //TTN (for D2D)
@@ -1502,7 +1502,16 @@ typedef struct {
     /// MCCH status
     uint8_t mcch_status;
     /// MSI status
-    uint8_t msi_status;		// could be an array if there are >1 MCH in one MBSFN area
+    uint8_t msi_status_v[28];
+    uint8_t msi_current_alloc;
+    uint8_t msi_pmch;
+
+    struct MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA?
+    uint8_t commonSF_AllocPeriod_r9;
+    int common_num_sf_alloc;
+
+    uint8_t pmch_lcids[28];
+    uint16_t pmch_stop_mtch[28];
 #endif
   //#ifdef CBA
   /// CBA RNTI for each group
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index dd78da72751db65b3ae551d921b25353e9fcc33f..581fe9587dd024a236995f73e74544bf1a8c38b4 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -750,7 +750,7 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 		uint8_t sync_area)
 {
 
-    unsigned char num_sdu, i, *payload_ptr;
+    unsigned char num_sdu, i, j, *payload_ptr;
     unsigned char rx_lcids[NB_RB_MAX];
     unsigned short rx_lengths[NB_RB_MAX];
 #if UE_TIMING_TRACE
@@ -771,47 +771,76 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 	  num_sdu);
 
     for (i = 0; i < num_sdu; i++) {
-	if (rx_lcids[i] == MCH_SCHDL_INFO) {
-	    if (UE_mac_inst[module_idP].mcch_status == 1) {
-		LOG_I(MAC,
-		      "[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes)\n",
-		      module_idP, frameP, sync_area, eNB_index,
-		      rx_lengths[i]);
-		// ??store necessary scheduling info to ue_mac_inst in order to
-		// calculate exact position of interested service (for the complex case has >1 mtch)
-		// set msi_status to 1
-		UE_mac_inst[module_idP].msi_status = 1;
-	    }
-	} else if (rx_lcids[i] == MCCH_LCHANID) {
-	    LOG_I(MAC,
-		  "[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",
-		  module_idP, frameP, i, sync_area, eNB_index,
-		  rx_lengths[i]);
-	    mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0,	// unknown subframe
-			     M_RNTI,
-			     MCCH,
-			     payload_ptr, rx_lengths[i], eNB_index,
-			     sync_area);
-	} else if (rx_lcids[i] == MTCH) {
-	    if (UE_mac_inst[module_idP].msi_status == 1) {
-		LOG_I(MAC,
-		      "[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes)\n",
-		      module_idP, frameP, sync_area, eNB_index,
-		      rx_lengths[i]);
+      if (rx_lcids[i] == MCH_SCHDL_INFO) {
+        if (rx_lengths[i] & 0x01) {
+          LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n");
+        }
 
-		mac_rlc_data_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP, ENB_FLAG_NO, MBMS_FLAG_YES, MTCH,	/*+ (maxDRB + 3), */
-				 (char *) payload_ptr, rx_lengths[i], 1,
-				 NULL);
+        LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]);
 
-	    }
-	} else {
-	    LOG_W(MAC,
-		  "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n",
-		  module_idP, frameP, rx_lengths[i], i, rx_lcids[i],
-		  UE_mac_inst[module_idP].mcch_status, eNB_index);
-	}
+        for (j=0; j<rx_lengths[i]/2; j++) {
+          uint16_t stop_mtch_val = ((uint16_t)(payload_ptr[2*j] & 0x07) << 8) | (uint16_t)payload_ptr[2*j+1];
+
+          UE_mac_inst[module_idP].pmch_lcids[j] = (payload_ptr[2*j] & 0xF8) >> 3;
+          UE_mac_inst[module_idP].pmch_stop_mtch[j] = stop_mtch_val;
+          LOG_D(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP);
+
+          if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) {
+            LOG_D(MAC,"(reserved)\n");
+          }
+
+          UE_mac_inst[module_idP].msi_status_v[j] = 0;
 
-	payload_ptr += rx_lengths[i];
+          if (UE_mac_inst[module_idP].mcch_status==1) {
+            LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]);
+            if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) {
+              UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc;
+              UE_mac_inst[module_idP].msi_status_v[j] = 1;
+            }
+          }
+        }
+      } else if (rx_lcids[i] == MCCH_LCHANID) {
+        LOG_D(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]);
+        mac_rrc_data_ind_ue(module_idP,
+                         CC_id,
+                         frameP,0, // unknown subframe
+                         M_RNTI,
+                         MCCH,
+                         payload_ptr + 1, // Skip RLC layer 1st byte
+                         rx_lengths[i] - 1,
+                         eNB_index,
+                         sync_area);
+      } else if (rx_lcids[i] <= 28) {
+        for (j=0; j<28; j++) {
+          if (rx_lcids[i] == UE_mac_inst[module_idP].pmch_lcids[j])
+            break;
+        }
+
+        if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) {
+          LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j);
+
+          mac_rlc_data_ind(
+            module_idP,
+            UE_mac_inst[module_idP].crnti,
+            eNB_index,
+            frameP,
+            ENB_FLAG_NO,
+            MBMS_FLAG_YES,
+            rx_lcids[i], /*+ (maxDRB + 3),*/
+            (char *)payload_ptr,
+            rx_lengths[i],
+            1,
+            NULL);
+
+        }
+      } else {
+        LOG_W(MAC,
+              "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n",
+              module_idP, frameP, rx_lengths[i], i, rx_lcids[i],
+              UE_mac_inst[module_idP].mcch_status, eNB_index);
+      }
+
+      payload_ptr += rx_lengths[i];
     }
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
@@ -916,406 +945,591 @@ int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_are
     }
 }
 
-int
-ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP,
-	     uint32_t subframe, uint8_t eNB_index, uint8_t * sync_area,
-	     uint8_t * mcch_active)
+int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int commonSFAlloc_period, int commonSFAlloc_offset, int num_sf_alloc, int *mtch_active, int *msi_active, uint8_t *mch_lcid)
 {
+  int i, mtch_mcs = -1;
+  int mtch_flag = 0;
+  int msi_flag = 0;
 
-    int i = 0, j = 0, ii = 0, msi_pos = 0, mcch_mcs = -1;
-    int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
-    int mbsfn_period = 0;	// 1<<(UE_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
-    int mcch_period = 0;	// 32<<(UE_mac_inst[module_idP].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
-    int mch_scheduling_period = -1;
+  for (i = 0; i < 4; i++) {
+    if (UE_mac_inst[module_idP].pmch_Config[i] == NULL)
+      continue;
 
-    int frame_FDD = 1;
+    int mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[i]->mch_SchedulingPeriod_r9;
+    uint8_t  sf_AllocEnd_r9   = UE_mac_inst[module_idP].pmch_Config[i]->sf_AllocEnd_r9;
 
+    if (sf_AllocEnd_r9 == 2047) {
+      msi_flag = 1;
+      break;
+    }
 
-#if UE_TIMING_TRACE
-    start_meas(&UE_mac_inst[module_idP].ue_query_mch);
-#endif
+    if ((frameP % mch_scheduling_period) == (commonSFAlloc_offset + (frameP % 4))) {
+      if (i == 0) {
+        //msi and mtch are mutally excluded then the break is safe
+        if ((num_sf_alloc == 0) && (sf_AllocEnd_r9 >= 1)) {
+          msi_flag = 1;
+          LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc);
+          UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc;
+          UE_mac_inst[module_idP].msi_pmch = i;
+        }
+      } else { //more that one MCH ?? check better this condition
+        //msi and mtch are mutally excluded then the break is safe
+        if ((num_sf_alloc ==  UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9 + 1) && (sf_AllocEnd_r9 >= (num_sf_alloc+1))) {
+          //msi should be just after 
+          msi_flag = 1;
+          LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc);
+          UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc;
+          UE_mac_inst[module_idP].msi_pmch = i;
+        }
+      }
+    }
+  }
 
-    if (UE_mac_inst[module_idP].pmch_Config[0]) {
-	mch_scheduling_period =
-	    8 << (UE_mac_inst[module_idP].
-		  pmch_Config[0]->mch_SchedulingPeriod_r9);
+  for (i = 0; i < 28; i++) {
+    if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) {
+      if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) {
+        mtch_flag = 1;
+        if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL)
+          mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
+        else
+          mtch_mcs = -1;
+        *mch_lcid = (uint8_t)i;
+        LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs,UE_mac_inst[module_idP].pmch_stop_mtch[i],UE_mac_inst[module_idP].pmch_lcids[i],UE_mac_inst[module_idP].msi_pmch);
+        break;
+      }
     }
+  }
 
-    for (i = 0; i < UE_mac_inst[module_idP].num_active_mbsfn_area; i++) {
-	// assume, that there is always a mapping
-	if ((j =
-	     ue_get_mbsfn_sf_alloction(module_idP, i, eNB_index)) == -1) {
-	    return -1;		// continue;
-	}
+  *mtch_active = mtch_flag;
+  *msi_active = msi_flag;
 
-	ii = 0;
-	msi_pos = 0;
-	mbsfn_period =
-	    1 << (UE_mac_inst[module_idP].
-		  mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
-	mcch_period =
-	    32 << (UE_mac_inst[module_idP].
-		   mbsfn_AreaInfo[0]->mcch_Config_r9.
-		   mcch_RepetitionPeriod_r9);
+  return mtch_mcs;
+}
 
-	LOG_D(MAC,
-	      "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d,mac sched period (%d,%ld))\n",
-	      module_idP, frameP, subframe, i,
-	      UE_mac_inst[module_idP].num_active_mbsfn_area, j,
-	      UE_mac_inst[module_idP].num_sf_allocation_pattern,
-	      mbsfn_period, mcch_period, mch_scheduling_period,
-	      UE_mac_inst[module_idP].
-	      mbsfn_SubframeConfig[j]->radioframeAllocationOffset);
-
-	// get the real MCS value
-	switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->
-		mcch_Config_r9.signallingMCS_r9) {
-	case 0:
-	    mcch_mcs = 2;
-	    break;
-
-	case 1:
-	    mcch_mcs = 7;
-	    break;
-
-	case 2:
-	    mcch_mcs = 13;
-	    break;
-
-	case 3:
-	    mcch_mcs = 19;
-	    break;
-	}
+int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid)
+{
+  int i, j, mtch_mcs = -1;
+  int mtch_flag = 0;
+
+  // Acount for sf_allocable in CSA
+  int num_sf_alloc = 0;
+  for (i = 0; i < 8; i++) {
+    if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL)
+      continue;
+
+    if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format
+      continue;
+
+    // four-frameP format
+    uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] |
+                                          (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) |
+                                          (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
+    for (j = 0; j < 24; j++)
+      num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x800000 >> j)) == (0x800000 >> j));
+  }
 
-	if (frameP % mbsfn_period == UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset) {	// MBSFN frameP
-	    if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {	// one-frameP format
+  for (i = 0; i < 8; i++ ) {
+    if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL)
+      continue;
+
+    if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format
+      continue;
+
+    // four-frameP format
+    int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset;
+    int common_mbsfn_period  = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod;
+    int commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
+
+    uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] |
+                                          (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) |
+                                          (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
+
+    int jj = frameP % 4;
+    if ((frameP % common_mbsfn_period) != (common_mbsfn_alloc_offset + jj))
+      continue;
+
+    if(UE_mac_inst[module_idP].tdd_Config == NULL){
+      switch (subframe) {
+      case 1:
+        if ((common_mbsfn_SubframeConfig & (0x800000 >> (jj*6))) == (0x800000 >> (jj*6))) {
+          mtch_flag = 1;
+          mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid);
+          UE_mac_inst[module_idP].common_num_sf_alloc++;
+          UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48;
+        }
+        break;
+      case 2:
+        if ((common_mbsfn_SubframeConfig & (0x400000 >> (jj*6))) == (0x400000 >> (jj*6))) {
+          mtch_flag = 1;
+          mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid);
+          UE_mac_inst[module_idP].common_num_sf_alloc++;
+          UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48;
+        }
+        break;
+      case 3:
+        if ((common_mbsfn_SubframeConfig & (0x200000 >> (jj*6))) == (0x200000 >> (jj*6))) {
+          mtch_flag = 1;
+          mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid);
+          UE_mac_inst[module_idP].common_num_sf_alloc++;
+          UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48;
+        }
+        break;
+      case 6:
+        if ((common_mbsfn_SubframeConfig & (0x100000 >> (jj*6))) == (0x100000 >> (jj*6))) {
+          mtch_flag = 1;
+          mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid);
+          UE_mac_inst[module_idP].common_num_sf_alloc++;
+          UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48;
+        }
+        break;
+      case 7:
+        if ((common_mbsfn_SubframeConfig & (0x80000 >> (jj*6))) == (0x80000 >> (jj*6))) {
+          mtch_flag = 1;
+          mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid);
+          UE_mac_inst[module_idP].common_num_sf_alloc++;
+          UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48;
+        }
+        break;
+      case 8:
+        if ((common_mbsfn_SubframeConfig & (0x40000 >> (jj*6))) == (0x40000 >> (jj*6))) {
+          mtch_flag = 1;
+          mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid);
+          UE_mac_inst[module_idP].common_num_sf_alloc++;
+          UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc% ( num_sf_alloc*commonSF_AllocPeriod/common_mbsfn_period);//48;
+        }
+        break;
+      }
+    } else {
+      // TODO TDD
+    }
+    if (mtch_flag == 1)
+      break;
+  }
 
-		if (UE_mac_inst[module_idP].pmch_Config[0]) {
-		    //  Find the first subframe in this MCH to transmit MSI
-		    if (frameP % mch_scheduling_period ==
-			UE_mac_inst[module_idP].
-			mbsfn_SubframeConfig
-			[j]->radioframeAllocationOffset) {
-			while (ii == 0) {
-			    ii = UE_mac_inst[module_idP].
-				mbsfn_SubframeConfig[j]->
-				subframeAllocation.choice.
-				oneFrame.buf[0] & (0x80 >> msi_pos);
-			    msi_pos++;
-			}
-		    }
-		}
+   return mtch_mcs;
+}
 
-		if (UE_mac_inst[module_idP].tdd_Config == NULL)
-		    frame_FDD = 1;
-		else
-		    frame_FDD = 0;
-		// Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
-		switch (subframe) {
-		case 1:
-		    if (frame_FDD == 1) {
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
-			    if (msi_pos == 1) {
-				msi_flag = 1;
-			    }
+int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active)
+{
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_FDD_SF1) ==
-				 MBSFN_FDD_SF1)) {
-				mcch_flag = 1;
-			    }
+  int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1;
+  int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
+  long mch_scheduling_period = -1;
+  uint8_t mch_lcid = 0;
 
-			    mtch_flag = 1;
-			}
-		    }
+#if UE_TIMING_TRACE
+  start_meas(&UE_mac_inst[module_idP].ue_query_mch);
+#endif
 
-		    break;
+  if (UE_mac_inst[module_idP].pmch_Config[0]) {
+    mch_scheduling_period = 8 << UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9;
+  }
 
-		case 2:
-		    if (frame_FDD == 1) {
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
-			    if (msi_pos == 2) {
-				msi_flag = 1;
-			    }
+  for (i = 0;
+       i < UE_mac_inst[module_idP].num_active_mbsfn_area;
+       i++ )
+  {
+    // assume, that there is always a mapping
+    if ((j = ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) {
+      return -1; // continue;
+    }
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_FDD_SF2) ==
-				 MBSFN_FDD_SF2)) {
-				mcch_flag = 1;
-			    }
+    ii = 0;
+    msi_pos = 0;
+    
+    long mbsfn_period =  1 << UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod;
+    long mbsfn_alloc_offset = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset;
+    long mcch_period  = 32 << UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_RepetitionPeriod_r9;
+    long mcch_offset        = UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_Offset_r9;
 
-			    mtch_flag = 1;
-			}
-		    }
+    LOG_D(MAC,
+          "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %ld, mcch period %ld,mac sched period (%ld,%ld))\n",
+          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
+          j,UE_mac_inst[module_idP].num_sf_allocation_pattern,mbsfn_period,mcch_period,
+          mcch_offset,mbsfn_alloc_offset);
+
+    // get the real MCS value
+    switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
+    case 0:
+      mcch_mcs = 2;
+      break;
 
-		    break;
+    case 1:
+      mcch_mcs = 7;
+      break;
 
-		case 3:
-		    if (frame_FDD == 0) {	//TDD
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
-			    if (msi_pos == 1) {
-				msi_flag = 1;
-			    }
+    case 2:
+      mcch_mcs = 13;
+      break;
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_TDD_SF3) ==
-				 MBSFN_TDD_SF3)) {
-				mcch_flag = 1;
-			    }
+    case 3:
+      mcch_mcs = 19;
+      break;
+    }
 
-			    mtch_flag = 1;
-			}
-		    } else {	// FDD
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) {
-			    if (msi_pos == 3) {
-				msi_flag = 1;
-			    }
+    if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format
+      if (frameP % mbsfn_period == mbsfn_alloc_offset) { // MBSFN frameP
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_FDD_SF3) ==
-				 MBSFN_FDD_SF3)) {
-				mcch_flag = 1;
-			    }
+        if (UE_mac_inst[module_idP].pmch_Config[0]) {
+          //  Find the first subframe in this MCH to transmit MSI
+          if (frameP % mch_scheduling_period == mbsfn_alloc_offset) {
+            while (ii == 0) {
+              ii = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80 >> msi_pos);
+              msi_pos++;
+            }
+          }
+        }
+
+        // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
+        switch (subframe) {
+        case 1:
+          if (UE_mac_inst[module_idP].tdd_Config == NULL) {
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
+              if (msi_pos == 1) {
+                msi_flag = 1;
+              }
+
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) {
+                mcch_flag = 1;
+              }
+
+              mtch_flag = 1;
+            }
+          }
 
-			    mtch_flag = 1;
-			}
-		    }
+          break;
 
-		    break;
+        case 2:
+          if (UE_mac_inst[module_idP].tdd_Config == NULL) {
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
+              if (msi_pos == 2) {
+                msi_flag = 1;
+              }
 
-		case 4:
-		    if (frame_FDD == 0) {
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
-			    if (msi_pos == 2) {
-				msi_flag = 1;
-			    }
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) {
+                mcch_flag = 1;
+              }
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_TDD_SF4) ==
-				 MBSFN_TDD_SF4)) {
-				mcch_flag = 1;
-			    }
+              mtch_flag = 1;
+            }
+          }
 
-			    mtch_flag = 1;
-			}
-		    }
+          break;
 
-		    break;
+        case 3:
+          if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
+              if (msi_pos == 1) {
+                msi_flag = 1;
+              }
 
-		case 6:
-		    if (frame_FDD == 1) {
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
-			    if (msi_pos == 4) {
-				msi_flag = 1;
-			    }
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) {
+                mcch_flag = 1;
+              }
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_FDD_SF6) ==
-				 MBSFN_FDD_SF6)) {
-				mcch_flag = 1;
-			    }
+              mtch_flag = 1;
+            }
+          } else { // FDD
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) {
+              if (msi_pos == 3) {
+                msi_flag = 1;
+              }
+
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) {
+                mcch_flag = 1;
+              }
+
+              mtch_flag = 1;
+            }
+          }
 
-			    mtch_flag = 1;
-			}
-		    }
+          break;
 
-		    break;
+        case 4:
+          if (UE_mac_inst[module_idP].tdd_Config != NULL) {
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
+              if (msi_pos == 2) {
+                msi_flag = 1;
+              }
 
-		case 7:
-		    if (frame_FDD == 0) {	// TDD
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
-			    if (msi_pos == 3) {
-				msi_flag = 1;
-			    }
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) {
+                mcch_flag = 1;
+              }
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_TDD_SF7) ==
-				 MBSFN_TDD_SF7)) {
-				mcch_flag = 1;
-			    }
+              mtch_flag = 1;
+            }
+          }
 
-			    mtch_flag = 1;
-			}
-		    } else {	// FDD
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) {
-			    if (msi_pos == 5) {
-				msi_flag = 1;
-			    }
+          break;
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_FDD_SF7) ==
-				 MBSFN_FDD_SF7)) {
-				mcch_flag = 1;
-			    }
+        case 6:
+          if (UE_mac_inst[module_idP].tdd_Config == NULL) {
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
+              if (msi_pos == 4) {
+                msi_flag = 1;
+              }
 
-			    mtch_flag = 1;
-			}
-		    }
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) {
+                mcch_flag = 1;
+              }
 
-		    break;
+              mtch_flag = 1;
+            }
+          }
 
-		case 8:
-		    if (frame_FDD == 0) {	//TDD
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
-			    if (msi_pos == 4) {
-				msi_flag = 1;
-			    }
+          break;
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_TDD_SF8) ==
-				 MBSFN_TDD_SF8)) {
-				mcch_flag = 1;
-			    }
+        case 7:
+          if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
+              if (msi_pos == 3) {
+                msi_flag = 1;
+              }
 
-			    mtch_flag = 1;
-			}
-		    } else {	// FDD
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) {
-			    if (msi_pos == 6) {
-				msi_flag = 1;
-			    }
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) {
+                mcch_flag = 1;
+              }
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_FDD_SF8) ==
-				 MBSFN_FDD_SF8)) {
-				mcch_flag = 1;
-			    }
+              mtch_flag = 1;
+            }
+          } else { // FDD
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) {
+              if (msi_pos == 5) {
+                msi_flag = 1;
+              }
+
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) {
+                mcch_flag = 1;
+              }
+
+              mtch_flag = 1;
+            }
+          }
 
-			    mtch_flag = 1;
-			}
-		    }
+          break;
 
-		    break;
+        case 8:
+          if (UE_mac_inst[module_idP].tdd_Config != NULL) { //TDD
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
+              if (msi_pos == 4) {
+                msi_flag = 1;
+              }
 
-		case 9:
-		    if (frame_FDD == 0) {
-			if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig
-			     [j]->subframeAllocation.choice.oneFrame.
-			     buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
-			    if (msi_pos == 5) {
-				msi_flag = 1;
-			    }
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) {
+                mcch_flag = 1;
+              }
 
-			    if ((frameP % mcch_period ==
-				 UE_mac_inst[module_idP].mbsfn_AreaInfo
-				 [i]->mcch_Config_r9.mcch_Offset_r9)
-				&&
-				((UE_mac_inst[module_idP].mbsfn_AreaInfo
-				  [i]->mcch_Config_r9.sf_AllocInfo_r9.
-				  buf[0] & MBSFN_TDD_SF9) ==
-				 MBSFN_TDD_SF9)) {
-				mcch_flag = 1;
-			    }
+              mtch_flag = 1;
+            }
+          } else { // FDD
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) {
+              if (msi_pos == 6) {
+                msi_flag = 1;
+              }
+
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) {
+                mcch_flag = 1;
+              }
+
+              mtch_flag = 1;
+            }
+          }
 
-			    mtch_flag = 1;
-			}
-		    }
+          break;
 
-		    break;
-		}		// end switch
+        case 9:
+          if (UE_mac_inst[module_idP].tdd_Config != NULL) {
+            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
+              if (msi_pos == 5) {
+                msi_flag = 1;
+              }
 
-		// sf allocation is non-overlapping
-		if ((msi_flag == 1) || (mcch_flag == 1)
-		    || (mtch_flag == 1)) {
-		    LOG_D(MAC,
-			  "[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
-			  module_idP, frameP, subframe, i, j, msi_flag,
-			  mcch_flag, mtch_flag);
+              if ((frameP % mcch_period == mcch_offset) &&
+                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9)) {
+                mcch_flag = 1;
+              }
+
+              mtch_flag = 1;
+            }
+          }
+
+          break;
+        }// end switch
+
+        // Acount for sf_allocable in CSA
+        int num_sf_alloc = 0;
+        for (i = 0; i < 8; i++) {
+          if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL)
+            continue;
+
+          if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
+            continue;
+
+          uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0];
+          for (j = 0; j < 6; j++)
+            num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j));
+        }
+
+        for (i = 0; i < 28; i++) {
+          if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) {
+            if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) {
+              if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL)
+                mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
+              else
+                mtch_mcs = -1;
+              mch_lcid = (uint8_t)i;
+              break;
+            }
+          }
+        }
+
+        // sf allocation is non-overlapping
+        if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
+          LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
+                module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag);
+
+          *sync_area=i;
+          break;
+        }
+      }
+    } else { // four-frameP format
+      uint32_t mbsfn_SubframeConfig = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[2] |
+                                     (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[1]<<8) |
+                                     (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0]<<16);
+      uint32_t MCCH_mbsfn_SubframeConfig = /* UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[2] |
+                                          (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[1]<<8) | */
+                                          (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]<<16);
+
+      jj=frameP%4;
+      if ((frameP % mbsfn_period) == (mbsfn_alloc_offset+jj)) {
+        if (UE_mac_inst[module_idP].tdd_Config == NULL) {
+          switch (subframe) {
+          case 1:
+            if ((mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6))) {
+              if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6)))) {
+                mcch_flag=1;
+                LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n",
+                      frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x800000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc);
+                if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL)
+                  UE_mac_inst[module_idP].common_num_sf_alloc++;
+              }
+            }
+            break;
+          case 2:
+            if ((mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6))) {
+              if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6)))) {
+                mcch_flag=1;
+                LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n",
+                      frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x400000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc);
+                if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL)
+                  UE_mac_inst[module_idP].common_num_sf_alloc++;
+              }
+            }
+            break;
+          case 3:
+            if ((mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6))) {
+              if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6)))) {
+                LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n",
+                      frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x200000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc);
+                mcch_flag=1;
+                if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL)
+                  UE_mac_inst[module_idP].common_num_sf_alloc++;
+              }
+            }
+            break;
+          case 6:
+            if ((mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6))) {
+              if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6)))) {
+                LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n",
+                      frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x100000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc);
+                mcch_flag=1;
+                if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL)
+                  UE_mac_inst[module_idP].common_num_sf_alloc++;
+              }
+            }
+            break;
+          case 7:
+            if ((mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6))) {
+              if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6)))) {
+                LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n",
+                      frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x80000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc);
+                if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL)
+                  UE_mac_inst[module_idP].common_num_sf_alloc++;
+                mcch_flag=1;
+              }
+            }
+            break;
+          case 8:
+            if ((mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6))) {
+              if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6)))) {
+                LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n",
+                      frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x40000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc);
+                if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL)
+                  UE_mac_inst[module_idP].common_num_sf_alloc++;
+                mcch_flag=1;
+              }
+            }
+            break;
+          }// end switch
+        } else {
+          // TODO TDD
+        }
+
+        mtch_mcs = ue_query_p_mch(module_idP, frameP, subframe, &mtch_flag, &msi_flag, &mch_lcid);
+
+        // sf allocation is non-overlapping
+        if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
+          LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
+                module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag);
+          *sync_area=i;
+          break;
+        }
+      }
+    }
+  } // end of for
 
-		    *sync_area = i;
-		    break;
-		}
-	    } else {		// four-frameP format
-	    }
-	}
-    }				// end of for
 #if UE_TIMING_TRACE
-    stop_meas(&UE_mac_inst[module_idP].ue_query_mch);
+  stop_meas(&UE_mac_inst[module_idP].ue_query_mch);
 #endif
 
-    if ((mcch_flag == 1)) {	// || (msi_flag==1))
-	*mcch_active = 1;
-    }
+  if ((mcch_flag == 1)) {	// || (msi_flag==1))
+    *mcch_active = 1;
+  }
 
-    if ((mcch_flag == 1)
-	|| ((msi_flag == 1) && (UE_mac_inst[module_idP].mcch_status == 1))) {
-	return mcch_mcs;
-    } else if ((mtch_flag == 1)
-	       && (UE_mac_inst[module_idP].msi_status == 1)) {
-	return UE_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9;
+  if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ) {
+    if (msi_flag!=1) {
+      for (i=0; i<8; i++)
+        UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = NULL;
+      for (i=0; i<15; i++)
+        UE_mac_inst[module_idP].pmch_Config[i] = NULL;
+      for (i=0; i<28 ;i++) {
+        UE_mac_inst[module_idP].pmch_lcids[i] = -1;
+        UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047;
+        UE_mac_inst[module_idP].msi_status_v[i] = 0;
+      }
     } else {
-	return -1;
+      for (i=0; i<28; i++) {
+        UE_mac_inst[module_idP].pmch_lcids[i] = -1;
+        UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047;
+        UE_mac_inst[module_idP].msi_status_v[i] = 0;
+      }
     }
+    return mcch_mcs;
+  } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status_v[(mch_lcid > 27) ? 27 : mch_lcid] == 1)) {
+    return mtch_mcs;
+  } else {
+    return -1;
+  }
 }
 
 #endif
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index e12fb80e1bda913de5e770730d3fe9ca97aa9ba6..04999bab38da83a7722c3c7a024c32c60324a40f 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -30,6 +30,8 @@
 #define PDCP_C
 //#define DEBUG_PDCP_FIFO_FLUSH_SDU
 
+#define MBMS_MULTICAST_OUT
+
 #include "assertions.h"
 #include "hashtable.h"
 #include "pdcp.h"
@@ -66,6 +68,17 @@ extern int otg_enabled;
 #include "common/ran_context.h"
 extern RAN_CONTEXT_t RC;
 
+#ifdef MBMS_MULTICAST_OUT
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netinet/ip.h>
+# include <netinet/udp.h>
+# include <unistd.h>
+
+static int mbms_socket = -1;
+#endif
+
 //-----------------------------------------------------------------------------
 /*
  * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken
@@ -758,11 +771,26 @@ pdcp_data_ind(
   packet_forwarded = FALSE;
 #endif
 
+#ifdef MBMS_MULTICAST_OUT
+  if ((MBMS_flagP != 0) && (mbms_socket != -1)) {
+    struct iphdr   *ip_header = (struct iphdr*)&sdu_buffer_pP->data[payload_offset];
+    struct udphdr *udp_header = (struct udphdr*)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)];
+    struct sockaddr_in dest_addr;
+
+    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;
+  }
+#endif
+
   if (FALSE == packet_forwarded) {
     new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), __func__);
 
     if (new_sdu_p) {
-      if (pdcp_p->rlc_mode == RLC_MODE_AM ) {
+      if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) {
         pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
       }
 
@@ -803,7 +831,6 @@ pdcp_data_ind(
       
       
     }
-  }
 
   /* Print octets of incoming data in hexadecimal form */
   LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n",
@@ -839,13 +866,14 @@ pdcp_data_ind(
 
   
 #if defined(STOP_ON_IP_TRAFFIC_OVERLOAD)
-  else {
-    AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n",
-                PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
-  }
-
+    else {
+      AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n",
+                  PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
+    }
 #endif
 
+  }
+
   free_mem_block(sdu_buffer_pP, __func__);
 
   if (ctxt_pP->enb_flag) {
@@ -1458,8 +1486,12 @@ rrc_pdcp_config_asn1_req (
 
       for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
         MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
-        lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0];
+        if (MBMS_SessionInfo_p->sessionId_r9)
+          lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0];
+        else
+          lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9;
         mch_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string
+//        mch_id = j;
 
         // can set the mch_id = i
         if (ctxt_pP->enb_flag) {
@@ -1480,6 +1512,14 @@ rrc_pdcp_config_asn1_req (
           }
         }
 
+        LOG_D(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n",
+          lc_id,
+          MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0],
+          MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1],
+          MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2],
+          drb_id,
+          action);
+
         pdcp_config_req_asn1 (
           ctxt_pP,
           NULL,  // unused for MBMS
@@ -2018,6 +2058,12 @@ void pdcp_layer_init(void)
 #endif
   }
 
+#ifdef MBMS_MULTICAST_OUT
+  mbms_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+  if (mbms_socket == -1)
+    LOG_W(PDCP, "Could not create RAW socket, MBMS packets will not be put to the network\n");
+#endif
+
   LOG_I(PDCP, "PDCP layer has been initialized\n");
 
   pdcp_output_sdu_bytes_to_write=0;
@@ -2068,6 +2114,12 @@ void pdcp_layer_cleanup (void)
 {
   list_free (&pdcp_sdu_list);
   hashtable_destroy(pdcp_coll_p);
+#ifdef MBMS_MULTICAST_OUT
+  if(mbms_socket != -1) {
+    close(mbms_socket);
+    mbms_socket = -1;
+  }
+#endif
 }
 
 #ifdef PDCP_USE_RT_FIFO
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index ff49b2d056f12f2e07a6a642322411e0841c5398..8c557188a2a2e115300b7ea9d15ef4032da49e1e 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -208,7 +208,7 @@ rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_
 #define rlc_mbms_ue_get_lcid_by_rb_id(uE_mOD,rB_iD) rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD]
 
 #define rlc_mbms_ue_set_lcid_by_rb_id(uE_mOD,rB_iD,lOG_cH_iD) do { \
-            AssertFatal(rB_iD<NB_RB_MAX, "INVALID RB ID %u", rB_iD); \
+            AssertFatal(rB_iD<NB_RB_MBMS_MAX, "INVALID RB ID %u", rB_iD); \
             rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \
         } while (0);
 
diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c
index aa00ffb773c876f4c8e99edac83394794e457822..8977e422b60591d100fd809aa36643c090469cb2 100644
--- a/openair2/LAYER2/RLC/rlc_rrc.c
+++ b/openair2/LAYER2/RLC/rlc_rrc.c
@@ -414,9 +414,13 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
       for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
         MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
-        mbms_session_id    = MBMS_SessionInfo_p->sessionId_r9->buf[0];
+        if (MBMS_SessionInfo_p->sessionId_r9)
+          mbms_session_id  = MBMS_SessionInfo_p->sessionId_r9->buf[0];
+        else
+          mbms_session_id  = MBMS_SessionInfo_p->logicalChannelIdentity_r9;
         lc_id              = mbms_session_id;
         mbms_service_id    = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string
+//        mbms_service_id    = j;
 
         // can set the mch_id = i
         if (ctxt_pP->enb_flag) {
diff --git a/openair2/NETWORK_DRIVER/LITE/common.c b/openair2/NETWORK_DRIVER/LITE/common.c
index 0d616d5764fa16e47ec5971b8f81346c54d110c8..2ae6f5279d12ce5f2be1f2b1d36ee59d5ddfbef2 100644
--- a/openair2/NETWORK_DRIVER/LITE/common.c
+++ b/openair2/NETWORK_DRIVER/LITE/common.c
@@ -333,7 +333,7 @@ void oai_nw_drv_common_class_wireless2ip(uint16_t dlen,
 
   printk("\n");
 #endif //OAI_DRV_DEBUG_RECEIVE
-  netif_rx(skb);
+  netif_rx_ni(skb);
 #ifdef OAI_DRV_DEBUG_RECEIVE
   printk("[OAI_IP_DRV][%s] end\n",__FUNCTION__);
 #endif
diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c
index d380b8a4d829cf31bf1369996d05de279cab73a5..1c7b8e4d123d41c11b1dfb9f5b47ffc916d8d997 100644
--- a/openair2/NETWORK_DRIVER/MESH/common.c
+++ b/openair2/NETWORK_DRIVER/MESH/common.c
@@ -309,7 +309,7 @@ void nas_COMMON_receive(uint16_t dlen,
 
   printk("\n");
 #endif //NAS_DEBUG_RECEIVE
-  netif_rx(skb);
+  netif_rx_ni(skb);
 #ifdef NAS_DEBUG_RECEIVE
   printk("NAS_COMMON_RECEIVE: end\n");
 #endif
diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c
index 84f425ef3c004646069f1e0496620a6cca4327a9..b21ca5f2dcc7bd9c8fab015f9f95d5b546fa4b77 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/common.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/common.c
@@ -222,7 +222,7 @@ skb_p->mark = rb_idP;
 
   printk("\n");
 #endif //OAI_DRV_DEBUG_RECEIVE
-  netif_rx(skb_p);
+  netif_rx_ni(skb_p);
 #ifdef OAI_DRV_DEBUG_RECEIVE
   printk("[UE_IP_DRV][%s] end\n",__FUNCTION__);
 #endif
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index c23bf12d52a8b533bb54f6023025ee1566fba317..ecdc451eee075c3415e524c1f17bc35c596e48cf 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -4594,10 +4594,30 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB
 //-----------------------------------------------------------------------------
  void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, frame_t frameP, uint8_t mbsfn_sync_area )
 {
+  uint8_t i;
   protocol_ctxt_t               ctxt;
 
   LOG_I(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d  is %d\n",
         ue_mod_idP, frameP, mbsfn_sync_area, UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9.list.count);
+
+  // Configure commonSF_Alloc 
+  for(i=0; i< UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.count;i++){
+    LOG_W(RRC,"[UE %d] Frame %d, commonSF_Alloc_r9: radioframeAllocationPeriod(%ldn),radioframeAllocationOffset(%ld), subframeAllocation(%x,%x,%x)\n",
+          ue_mod_idP, frameP,
+          UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationPeriod<<1,
+          UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->radioframeAllocationOffset,
+          UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[0],
+          UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[1],
+          UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i]->subframeAllocation.choice.oneFrame.buf[2]);
+    UE_mac_inst[ue_mod_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_Alloc_r9.list.array[i];
+  }
+  LOG_W(RRC,"[UE %d] Frame %d, commonSF_AllocPeriod_r9 %drf \n",
+        ue_mod_idP, frameP,
+        4<<UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9);
+
+  // Configure commonSF_AllocPeriod
+  UE_mac_inst[ue_mod_idP].commonSF_AllocPeriod_r9 = UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->commonSF_AllocPeriod_r9;
+
   //  store to MAC/PHY necessary parameters for receiving MTCHs
 
   rrc_mac_config_req_ue(ue_mod_idP,0,eNB_index,