diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index aa11892fa6a90593c848a84833f861dd7025fd80..15c44aed22a46638543af94ca08ac8c5a99798c5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -34,4 +34,5 @@ job1:
    - sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no "  --rsync-path="mkdir -p $NFS_TEST_RESULTS_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$NFS_TEST_RESULTS_DIR
    - sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no "  --rsync-path="mkdir -p $EXTERNAL_SHARE_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$EXTERNAL_SHARE_DIR
    - cat $OPENAIR_DIR/cmake_targets/autotests/log/results_autotests.xml
-  when: manual  
+  only:
+   - triggers
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 43284890cfe1e204d5daebfc312858859813ab99..b6a02d12faa00bfdf2a127763f7158ead144159d 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1021,6 +1021,7 @@ set(SCHED_SRC
   ${OPENAIR1_DIR}/SCHED/phy_mac_stub.c
   ${OPENAIR1_DIR}/SCHED/pucch_pc.c
   ${OPENAIR1_DIR}/SCHED/pusch_pc.c
+  ${OPENAIR1_DIR}/SCHED/srs_pc.c
 )
 add_library(SCHED_LIB ${SCHED_SRC})
 
diff --git a/openair1/PHY/CODING/lte_segmentation.c b/openair1/PHY/CODING/lte_segmentation.c
index 746344a6acb6e29e3c124e7b0cc81244de2ccd55..04056c4c9eb919e5bccfdb1ee05e72e2ea8003a7 100644
--- a/openair1/PHY/CODING/lte_segmentation.c
+++ b/openair1/PHY/CODING/lte_segmentation.c
@@ -60,7 +60,7 @@ int lte_segmentation(unsigned char *input_buffer,
   }
 
   if ((*C)>MAX_NUM_DLSCH_SEGMENTS) {
-    msg("lte_segmentation.c: too many segments %d\n",*C);
+      LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
     return(-1);
   }
 
diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h
index 1874c4e8c7d85d9417381869cd998e0674cc2e26..2b65bebc8d41d2954bcc8815849d53aeb07b3c9f 100644
--- a/openair1/PHY/INIT/defs.h
+++ b/openair1/PHY/INIT/defs.h
@@ -206,7 +206,19 @@ void phy_config_dedicated_ue(module_id_t Mod_id,
                              uint8_t CH_index,
                              struct PhysicalConfigDedicated *physicalConfigDedicated);
 
+/*!
+\fn void phy_config_harq_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t CH_index,
+               uint16_t max_harq_tx)
+\brief Configure UE UL max harq Tx.
+\details Invoked upon reception of RRCConnectionSetup or RRCConnectionReconfiguration from eNB.
+@param Mod_id Instance ID for eNB
+@param CC_id Component Carrier index
+@param CH_index Index of eNB for this configuration
+@param max_harq_tx max harq tx information
 
+ */
+void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t CH_index,
+                           uint16_t max_harq_tx);
 /**
 \brief Configure UE MBSFN common parameters.
 \details Invoked upon reception of SIB13 from eNB.
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 3fb1d0c26b297ded1a882f2f13c777a63e6dada8..c10e4dd3c14d082cc92d54271bc2998d3cb492a4 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -482,6 +482,26 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB)
 
       }
 
+      if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) {
+        if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
+
+          eNB->soundingrs_ul_config_dedicated[UE_id].duration             = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration;
+          eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift          = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;
+          eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition   = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
+          eNB->soundingrs_ul_config_dedicated[UE_id].srs_Bandwidth        = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
+          eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex      = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
+          eNB->soundingrs_ul_config_dedicated[UE_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;
+          eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb     = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
+
+
+          LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex);
+
+        }
+
+        LOG_D(PHY,"------------------------------------------------------------\n");
+
+      }
+
       eNB->physicalConfigDedicated[UE_id] = NULL;
     }
   }
@@ -726,6 +746,14 @@ void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
 }
 #endif
 
+void phy_config_harq_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
+                        uint16_t max_harq_tx )
+{
+
+  PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
+  phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx;
+}
+
 void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
                              struct PhysicalConfigDedicated *physicalConfigDedicated )
 {
@@ -742,7 +770,8 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
   phy_vars_ue->dlsch_received_last[eNB_id]=0;
   phy_vars_ue->dlsch_fer[eNB_id]=0;
 
-
+  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1;
+  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1;
 
   if (physicalConfigDedicated) {
     LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, eNB_id);
@@ -852,6 +881,53 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
 
     }
 
+    if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) {
+
+      phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0;
+      if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration             = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift          = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition   = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth        = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex      = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;
+        phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb     = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
+
+
+        LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex);
+      }
+
+      LOG_D(PHY,"------------------------------------------------------------\n");
+
+    }
+
+
+    if (physicalConfigDedicated->cqi_ReportConfig) {
+      if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) {
+	// configure PUSCH CQI reporting
+	phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
+	if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) && 
+	    (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) &&
+	    (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31))
+	  LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic);
+      }
+      if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) {
+	if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) {
+	// configure PUCCH CQI reporting
+	  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
+	  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex     = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex;
+	  if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex)
+	    phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex;	
+	}
+	else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) {
+	  // handle release
+	  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1;
+	  phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1;
+	}
+      }
+    }
+    
 #ifdef CBA
 
     if (physicalConfigDedicated->pusch_CBAConfigDedicated_vlola) {
@@ -868,6 +944,9 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
     return;
   }
 
+  // fill cqi parameters for periodic CQI reporting
+  get_cqipmiri_params(phy_vars_ue,eNB_id);
+
 }
 
 void  phy_config_cba_rnti (module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uint8_t index, rnti_t cba_rnti, uint8_t cba_group_id, uint8_t num_active_cba_groups)
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c b/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
index 6ebd8948cf7108ddfd09791c19361d119107b22f..d713cc01635a2e8a68c7c599ef450d9b8ab38bed 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
@@ -102,7 +102,7 @@ int lte_est_freq_offset(int **dl_ch_estimates,
 {
 
   int ch_offset, omega, dl_ch_shift;
-  struct complex16 *omega_cpx;
+  struct complex16 omega_cpx;
   double phase_offset;
   int freq_offset_est;
   unsigned char aa;
@@ -142,9 +142,8 @@ int lte_est_freq_offset(int **dl_ch_estimates,
     //    printf("Computing freq_offset\n");
     omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
     //omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
-    omega_cpx = (struct complex16*) ω
-
-    //    printf("omega (%d,%d)\n",omega_cpx->r,omega_cpx->i);
+    omega_cpx.r = ((struct complex16*) &omega)->r;
+    omega_cpx.i = ((struct complex16*) &omega)->i;
 
     dl_ch = (int16_t *)&dl_ch_estimates[aa][(((frame_parms->N_RB_DL/2) + 1)*12) + ch_offset];
 
@@ -155,10 +154,12 @@ int lte_est_freq_offset(int **dl_ch_estimates,
 
     // calculate omega = angle(conj(dl_ch)*dl_ch_prev))
     omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
-    omega_cpx->r += ((struct complex16*) &omega)->r;
-    omega_cpx->i += ((struct complex16*) &omega)->i;
+
+    omega_cpx.r += ((struct complex16*) &omega)->r;
+    omega_cpx.i += ((struct complex16*) &omega)->i;
+
     //    phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
-    phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
+    phase_offset += atan2((double)omega_cpx.i,(double)omega_cpx.r);
     //    LOG_I(PHY,"omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index 24d533506ce244ca83469686963a588380164091..38cfc2c8c9f2712e670eadbc1d6b9c569f7b8cfc 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -2857,7 +2857,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
           }
         }
 
-        LOG_D(PHY,"DCI decoding CRNTI  [format_c: %d, nCCE[subframe: %d]: %d ]\n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe]);
+        LOG_D(PHY,"DCI decoding CRNTI  [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2);
         //  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);
 
 
@@ -3248,7 +3248,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                           SI_RNTI,
                           ra_rnti,
 			  P_RNTI,
-			  3,
+			  0,
                           format1A,
                           format1A,
                           format1A,
@@ -3277,7 +3277,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                           SI_RNTI,
                           ra_rnti,
 			  P_RNTI,
-			  2,
+			  1,
                           format1A,
                           format1A,
                           format1A,
@@ -3310,7 +3310,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                           SI_RNTI,
                           ra_rnti,
 			  P_RNTI,
-                          1,
+                          2,
                           format1A,
                           format1A,
                           format1A,
@@ -3339,7 +3339,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                           SI_RNTI,
                           ra_rnti,
 			  P_RNTI,
-                          0,
+                          3,
                           format1A,
                           format1A,
                           format1A,
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index f66ec5fe4bbaaf3697a010b5c4d9f525fd8a5310..a1c118529adc99bc43b582a4b4ab6e529bc1779e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -36,7 +36,10 @@
 #include "PHY/vars.h"
 #endif
 #include "assertions.h"
- 
+
+#include "LAYER2/MAC/extern.h"
+#include "LAYER2/MAC/defs.h"
+
 //#define DEBUG_DCI
 
 uint32_t localRIV2alloc_LUT6[32];
@@ -1260,6 +1263,11 @@ int generate_eNB_dlsch_params_from_dci(int frame,
       dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];
 
     }
+    else
+    {
+    	LOG_E(PHY,"DL Received HarqReTx round=%d mcs=%d rballoc=%d rv=%d \n",
+    			dlsch0_harq->round,mcs,rballoc,rv);
+    }
 
 
     dlsch[0]->current_harq_pid = harq_pid;
@@ -3917,10 +3925,10 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
       } else {
 
-        if (harq_pid>1) {
-          LOG_E(PHY,"Format 1A: harq_pid > 1\n");
-          return(-1);
-        }
+        //if (harq_pid>1) {
+        //  LOG_E(PHY,"Format 1A: harq_pid > 1\n");
+         // return(-1);
+        //}
 
         dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
         NPRB = RIV2nb_rb_LUT25[rballoc];
@@ -4143,6 +4151,20 @@ int generate_ue_dlsch_params_from_dci(int frame,
 
     dlsch0_harq->DCINdi = ndi;
 
+    // this a retransmission
+    if(dlsch0_harq->round)
+    {
+	// compare old TBS to new TBS
+    	if(dlsch0_harq->TBS != TBStable[get_I_TBS(mcs)][NPRB-1])
+    	{
+    		// this is an eNB issue
+    		// retransmisison but old and new TBS are different !!!
+    		// work around, consider it as a new transmission
+    		LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n");
+    		dlsch0_harq->round = 0;
+    	}
+    }
+
     dlsch0_harq->mcs = mcs;
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) {
       dlsch0_harq->TBS = TBStable[mcs][NPRB-1];
@@ -4434,6 +4456,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
       dlsch0_harq->status = ACTIVE;
       dlsch0_harq->DCINdi = ndi;
 
+      dlsch[0]->harq_ack[subframe].send_harq_status = 1;
       if (dlsch0_harq->first_tx==1) {
         LOG_D(PHY,"[PDSCH %x/%d] Format 1 DCI First TX: Clearing flag\n");
         dlsch0_harq->first_tx = 0;
@@ -4452,6 +4475,20 @@ int generate_ue_dlsch_params_from_dci(int frame,
 
     dlsch0_harq->mcs         = mcs;
 
+    // this a retransmission
+    if(dlsch0_harq->round)
+    {
+    	// compare old TBS to new TBS
+    	if(dlsch0_harq->TBS != TBStable[get_I_TBS(mcs)][NPRB-1])
+    	{
+    		// this is an eNB issue
+    		// retransmisison but old and new TBS are different !!!
+    		// work around, consider it as a new transmission
+    		LOG_E(PHY,"Format1 Retransmission but TBS are different: consider it as new transmission !!! \n");
+    		dlsch0_harq->round = 0;
+    	}
+    }
+
     dlsch0_harq->TBS         = TBStable[get_I_TBS(mcs)][NPRB-1];
     if (mcs <= 28)
       dlsch0_harq->Qm          = get_Qm(mcs);
@@ -5519,7 +5556,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
 
 #ifdef DEBUG_DCI
 
-  if (dlsch[0]) {
+  if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
+    printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame,subframe);
     printf("PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
     printf("PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
     printf("PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc_even[0]);
@@ -6194,13 +6232,22 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
   uint8_t harq_pid;
   uint8_t transmission_mode = ue->transmission_mode[eNB_id];
-  ANFBmode_t AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
+  ANFBmode_t AckNackFBMode;
   LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
   //  LTE_UE_DLSCH_t **dlsch = ue->dlsch[0];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   //  uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id];
 
+  if(frame_parms->frame_type == TDD)
+  {
+      AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
+  }
+  else
+  {
+      AckNackFBMode = 1; // 1: multiplexing for FDD
+  }
+
   uint32_t cqi_req;
   uint32_t dai=0;
   uint32_t cshift;
@@ -6351,8 +6398,10 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
 
     if (rballoc > RIV_max) {
-      LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc > RIV_max\n",
-            proc->frame_rx, subframe, rnti, dci_format);
+      LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n",
+            proc->frame_rx, subframe, rnti, dci_format,rballoc,RIV_max);
+      LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid);
+      ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
       return(-1);
     }
 
@@ -6361,7 +6410,11 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
     if ((rnti >= cba_rnti) && (rnti < p_rnti))
       ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct
     else
-      ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+    {
+        ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+        //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+
+    }
 
     ulsch->harq_processes[harq_pid]->TPC                                   = TPC;
 
@@ -6391,7 +6444,42 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ulsch->harq_processes[harq_pid]->round = 0;
       } else {
         //  ulsch->harq_processes[harq_pid]->Ndi = 0;
-        // ulsch->harq_processes[harq_pid]->round++;  // This is done in phich RX
+        //ulsch->harq_processes[harq_pid]->round++;  // This is done in phich RX
+
+        //#ifdef DEBUG_PHICH
+        //LOG_I(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n",
+        //      ue->Mod_id,harq_pid,
+        //      proc->frame_rx,
+        //      subframe,
+        //      ulsch->Mlimit);
+        //#endif
+/*
+        if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich
+        {
+            // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx
+            // ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8];
+            // LOG_I(PHY,"          Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round);
+
+            if (ulsch->harq_processes[harq_pid]->round >= ulsch->Mlimit) //UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx)
+            {
+                ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+                ulsch->harq_processes[harq_pid]->round  = 0;
+                ulsch->harq_processes[harq_pid]->status = IDLE;
+                //LOG_I(PHY,"          PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid);
+                //LOG_I(PHY,"          [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+            }
+            else
+            {
+                // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+                uint8_t rv_table[4] = {0, 2, 3, 1};
+                ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+                ulsch->O_RI = 0;
+                ulsch->O    = 0;
+                ulsch->uci_format = HLC_subband_cqi_nopmi;
+                //LOG_I(PHY,"          [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round);
+            }
+        }
+*/
       }
     }
 
@@ -6441,7 +6529,16 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
 
     if (cqi_req == 1) {
-      ulsch->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
+
+      if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) )
+      {
+          ulsch->O_RI = 1;
+      }
+      else
+      {
+          ulsch->O_RI = 0;
+      }
+      //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
 
       switch(transmission_mode) {
         // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
@@ -7001,15 +7098,19 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
     // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
 
-#ifdef DEBUG_DCI
+ #ifdef DEBUG_DCI 
+    printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx,subframe);
     printf("Format 0 DCI : ulsch (ue): NBRB        %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
     printf("Format 0 DCI :ulsch (ue): first_rb    %d\n",ulsch->harq_processes[harq_pid]->first_rb);
+    printf("Format 0 DCI :ulsch (ue): rballoc     %d\n",rballoc);
     printf("Format 0 DCI :ulsch (ue): harq_pid    %d\n",harq_pid);
+    printf("Format 0 DCI :ulsch (ue): first_tx       %d\n",ulsch->harq_processes[harq_pid]->first_tx);
+    printf("Format 0 DCI :ulsch (ue): DCINdi       %d\n",ulsch->harq_processes[harq_pid]->DCINdi);
     printf("Format 0 DCI :ulsch (ue): round       %d\n",ulsch->harq_processes[harq_pid]->round);
     printf("Format 0 DCI :ulsch (ue): TBS         %d\n",ulsch->harq_processes[harq_pid]->TBS);
     printf("Format 0 DCI :ulsch (ue): mcs         %d\n",ulsch->harq_processes[harq_pid]->mcs);
     printf("Format 0 DCI :ulsch (ue): O           %d\n",ulsch->O);
-
+    printf("Format 0 DCI :ulsch (ue): cqiReq      %d\n",cqi_req);
     if (frame_parms->frame_type == TDD)
       printf("Format 0 DCI :ulsch (ue): O_ACK/DAI   %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
     else
@@ -7017,6 +7118,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
     printf("Format 0 DCI :ulsch (ue): Nsymb_pusch   %d\n",ulsch->Nsymb_pusch);
     printf("Format 0 DCI :ulsch (ue): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
+    printf("Format 0 DCI :ulsch (ue): phich status  %d\n",ulsch->harq_processes[harq_pid]->status);
 #else
     UNUSED_VARIABLE(dai);
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index 01d6cdc449a01feaa793df2039a6786580648956..442fd8216704a4f232396495d95ba1b77be93d8b 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -227,6 +227,11 @@ typedef struct {
   uint8_t control_only;
   /// Flag to indicate that this is a calibration ULSCH (i.e. no MAC SDU and filled with TDD calibration information)
   //  int calibration_flag;
+  /// Number of soft channel bits
+  uint32_t G;
+
+  // decode phich
+  uint8_t decode_phich;
 } LTE_UL_UE_HARQ_t;
 
 typedef struct {
@@ -333,12 +338,16 @@ typedef struct {
   int16_t Po_PUSCH;
   /// PHR - current power headroom (based on last PUSCH transmission)
   int16_t PHR;
+  /// Po_SRS - target output power for SRS
+  int16_t Po_SRS;
   /// num active cba group
   uint8_t num_active_cba_groups;
   /// num dci found for cba
   uint8_t num_cba_dci[10];
   /// allocated CBA RNTI
   uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
+  /// UL max-harq-retransmission
+  uint8_t Mlimit;
 } LTE_UE_ULSCH_t;
 
 typedef struct {
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index f4ab4c092442e30983641d397f5d7b520912b166..4a80110b22fbd86bbdbeb23d49fab26c3747347a 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -249,7 +249,12 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     tc = phy_threegpplte_turbo_decoder16;
   }
   else
-    tc = phy_threegpplte_turbo_decoder8;
+  {
+	  AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n",
+			  harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
+	    tc = phy_threegpplte_turbo_decoder8;
+  }
+
 
   //  nb_rb = dlsch->nb_rb;
 
@@ -448,6 +453,11 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
 #if 1
     if (err_flag == 0) {
 
+    	if (llr8_flag) {
+    		AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
+    				Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
+    	}
+
       start_meas(dlsch_turbo_decoding_stats);
       ret = tc
             (&harq_process->d[r][96],
@@ -609,7 +619,11 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     harq_process->errors[harq_process->round]++;
     harq_process->round++;
 
-    //    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
+
+    if(is_crnti)
+    {
+    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
+    }
     //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
     if (harq_process->round >= dlsch->Mdlharq) {
       harq_process->status = SCH_IDLE;
@@ -622,7 +636,10 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     dlsch->harq_ack[subframe].ack = 1;
     dlsch->harq_ack[subframe].harq_id = harq_pid;
     dlsch->harq_ack[subframe].send_harq_status = 1;
-    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
+    if(is_crnti)
+    {
+    LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
+    }
 
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/group_hopping.c b/openair1/PHY/LTE_TRANSPORT/group_hopping.c
index be3acce5bdfec717bcc455c902cde056cf742bb0..bbd908b34abba06b02b3ec996109cb7f2e461c54 100644
--- a/openair1/PHY/LTE_TRANSPORT/group_hopping.c
+++ b/openair1/PHY/LTE_TRANSPORT/group_hopping.c
@@ -42,6 +42,8 @@ void generate_grouphop(LTE_DL_FRAME_PARMS *frame_parms)
   // This is from Section 5.5.1.3
   uint32_t fss_pusch = frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH;
 
+  uint32_t fss_pucch = frame_parms->Nid_cell;
+
   x2 = frame_parms->Nid_cell/30;
 #ifdef DEBUG_GROUPHOP
   printf("[PHY] GroupHop:");
@@ -49,7 +51,10 @@ void generate_grouphop(LTE_DL_FRAME_PARMS *frame_parms)
 
   for (ns=0; ns<20; ns++) {
     if (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == 0)
+    {
       frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[ns] = fss_pusch%30;
+      frame_parms->pucch_config_common.grouphop[ns]                          = fss_pucch%30;
+    }
     else {
       if ((ns&3) == 0) {
         s = lte_gold_generic(&x1,&x2,reset);
@@ -57,6 +62,7 @@ void generate_grouphop(LTE_DL_FRAME_PARMS *frame_parms)
       }
 
       frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[ns] = (((uint8_t*)&s)[ns&3]+fss_pusch)%30;
+      frame_parms->pucch_config_common.grouphop[ns]                          = (((uint8_t*)&s)[ns&3]+fss_pucch)%30;
     }
 
 #ifdef DEBUG_GROUPHOP
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index 782305d2fdf7906dd96082f56ea807447c40b982..b77cb1bfa4534d5c4c8c1e7e1fe6883834274e97 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -462,6 +462,13 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     }
   }
 
+  /* Consider this is a false detection if the offset is > 1000 Hz */
+  if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
+  {
+	  ret=-1;
+	  LOG_E(HW,"Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
+  }
+
   if (ret==0) {  // PBCH found so indicate sync to higher layers and configure frame parameters
 
     //#ifdef DEBUG_INITIAL_SYNCH
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index 6b66ee0282084e68a27858e9e2c7dcef39eb9b4b..989567ca3498d075237a8b50982460748ab7cf69 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -34,6 +34,10 @@
 #include "PHY/extern.h"
 #include "SCHED/defs.h"
 #include "defs.h"
+
+#include "LAYER2/MAC/extern.h"
+#include "LAYER2/MAC/defs.h"
+
 #ifndef USER_MODE
 #include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
 #endif
@@ -1046,7 +1050,6 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
 
 // This routine demodulates the PHICH and updates PUSCH/ULSCH parameters
 
-
 void rx_phich(PHY_VARS_UE *ue,
 	      UE_rxtx_proc_t *proc,
               uint8_t subframe,
@@ -1081,8 +1084,10 @@ void rx_phich(PHY_VARS_UE *ue,
   if (!ulsch)
     return;
 
+  LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX Status: %d \n",ue->Mod_id,harq_pid,proc->frame_rx,subframe, ulsch->harq_processes[harq_pid]->status);
+
   if (ulsch->harq_processes[harq_pid]->status == ACTIVE) {
-    LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe);
+     LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe);
     Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
 
     if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
@@ -1375,15 +1380,39 @@ void rx_phich(PHY_VARS_UE *ue,
             subframe,
             HI16,
             nseq_PHICH,
-            ngroup_PHICH);
+            ngroup_PHICH,
+            ulsch->Mlimit);
       //#endif
-      ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+
       //      ulsch->harq_processes[harq_pid]->Ndi = 0;
       ulsch->harq_processes[harq_pid]->round++;
-      ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
-      ulsch->O_RI = 0;
-      ulsch->O    = 0;
-      ulsch->uci_format = HLC_subband_cqi_nopmi;
+      
+      if ( ulsch->harq_processes[harq_pid]->round >= (ulsch->Mlimit - 1) )
+      {
+          // this is last push re transmission
+          ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+          ulsch->O_RI = 0;
+          ulsch->O    = 0;
+          ulsch->uci_format = HLC_subband_cqi_nopmi;
+
+          // disable phich decoding since it is the last retransmission
+          ulsch->harq_processes[harq_pid]->status = IDLE;
+
+          //ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+          //ulsch->harq_processes[harq_pid]->round  = 0;
+
+          //LOG_I(PHY,"PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid);
+          //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->Mlimit, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+      }
+      else
+      {
+          // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+          ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+          ulsch->O_RI = 0;
+          ulsch->O    = 0;
+          ulsch->uci_format = HLC_subband_cqi_nopmi;
+          //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round);
+      }
     }
 
 
@@ -1405,11 +1434,22 @@ void rx_phich(PHY_VARS_UE *ue,
       //#endif
     }
 
+   // LOG_I(PHY,"[HARQ-UL harqId: %d] subframe_scheduling_flag = %d \n",harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag);
+
+    // Incase of adaptive retransmission, PHICH is always decoded as ACK (at least with OAI-eNB)
+    // Workaround:
+    // rely only on DCI0 decoding and check if NDI has toggled
+    //   save current harq_processes content in temporary struct
+    //   harqId-8 corresponds to the temporary struct. In total we have 8 harq process(0 ..7) + 1 temporary harq process()
+    //ulsch->harq_processes[8] = ulsch->harq_processes[harq_pid];
+
     ulsch->harq_processes[harq_pid]->subframe_scheduling_flag =0;
     ulsch->harq_processes[harq_pid]->status = IDLE;
     ulsch->harq_processes[harq_pid]->round  = 0;
     // inform MAC?
     ue->ulsch_Msg3_active[eNB_id] = 0;
+
+   //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH ACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
   }
 
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 86bc3723af220571326b57fc8c0b0fb179e82bc3..90971e4a846db58f8a9959c7c021bbd26183e58c 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -1445,6 +1445,9 @@ int32_t generate_ue_ulsch_params_from_rar(PHY_VARS_UE *phy_vars_ue,
 					  uint8_t eNB_id);
 double sinr_eff_cqi_calc(PHY_VARS_UE *phy_vars_ue,
                          uint8_t eNB_id);
+
+uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
+
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
 				       eNB_rxtx_proc_t *proc,
 				       void *dci_pdu,
@@ -1712,6 +1715,20 @@ void generate_pucch1x(int32_t **txdataF,
 		      int16_t amp,
 		      uint8_t subframe);
 
+void generate_pucch2x(int32_t **txdataF,
+		      LTE_DL_FRAME_PARMS *fp,
+		      uint8_t ncs_cell[20][7],
+		      PUCCH_FMT_t fmt,
+		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+		      uint16_t n2_pucch,
+		      uint16_t *payload,
+		      int A,
+		      int B2,
+		      int16_t amp,
+		      uint8_t subframe,
+		      uint16_t rnti);
+
+
 void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue,
 			 UE_rxtx_proc_t *proc,
                          PUCCH_FMT_t format,
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index c0c54b9782b909abb1cb9d0c908cbdad0e4805ca..34e64dfd5f74b325cbc68747c3e63b1962508cc0 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -442,7 +442,7 @@ inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti
   int i;
   uint8_t c;
 
-  x2 = (rnti<<14) + ((1+subframe)<<16)*(1+(fp->Nid_cell<<1)); //this is c_init in 36.211 Sec 6.3.1
+  x2 = (rnti) + ((uint32_t)(1+subframe)<<16)*(1+(fp->Nid_cell<<1)); //this is c_init in 36.211 Sec 6.3.1
   s = lte_gold_generic(&x1, &x2, 1);
   for (i=0;i<19;i++) {
     c = (uint8_t)((s>>i)&1);
@@ -456,22 +456,24 @@ inline void pucch2x_modulation(uint8_t *btilde,int16_t *d,int16_t amp) {
   int i;
 
   for (i=0;i<20;i++) 
-    d[i] = btilde[i] == 1 ? amp : -amp;
+    d[i] = btilde[i] == 1 ? -amp : amp;
 
 }
 
+
+
 uint32_t pucch_code[13] = {0xFFFFF,0x5A933,0x10E5A,0x6339C,0x73CE0,
 			   0xFFC00,0xD8E64,0x4F6B0,0x218EC,0x1B746,
 			   0x0FFFF,0x33FFF,0x3FFFC};
 
+
 void generate_pucch2x(int32_t **txdataF,
 		      LTE_DL_FRAME_PARMS *fp,
 		      uint8_t ncs_cell[20][7],
 		      PUCCH_FMT_t fmt,
 		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
 		      uint16_t n2_pucch,
-		      uint8_t shortened_format,
-		      uint32_t *payload,
+		      uint16_t *payload,
 		      int A,
 		      int B2,
 		      int16_t amp,
@@ -486,13 +488,14 @@ void generate_pucch2x(int32_t **txdataF,
   uint8_t NRB2                      = fp->pucch_config_common.nRB_CQI;
   uint8_t Ncs1                      = fp->pucch_config_common.nCS_AN;
 
-  uint32_t u0 = (fp->Nid_cell + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30;
-  uint32_t u1 = (fp->Nid_cell + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30;
-  uint32_t v0=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
-  uint32_t v1=fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
+  uint32_t u0 = fp->pucch_config_common.grouphop[subframe<<1];
+  uint32_t u1 = fp->pucch_config_common.grouphop[1+(subframe<<1)];
+  uint32_t v0 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
+  uint32_t v1 = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
+
   uint32_t z[12*14],*zptr;
   uint32_t u,v,n;
-  uint8_t ns,N_UL_symb,nsymb;
+  uint8_t ns,N_UL_symb,nsymb_slot0,nsymb_pertti;
   uint32_t nprime,l,n_cs;
   int alpha_ind,data_ind;
   int16_t ref_re,ref_im;
@@ -509,7 +512,6 @@ void generate_pucch2x(int32_t **txdataF,
     return;
   }
 
-
   // pucch2x_encoding
   for (i=0;i<A;i++)
     if ((*payload & (1<<i)) > 0)
@@ -545,66 +547,72 @@ void generate_pucch2x(int32_t **txdataF,
     }
   }
 
-  zptr = z;
 
 #ifdef DEBUG_PUCCH_TX
   printf("[PHY] PUCCH2x: n2_pucch %d\n",n2_pucch);
 #endif
 
   N_UL_symb = (fp->Ncp==0) ? 7 : 6;
-
+  data_ind  = 0;
+  zptr      = z;
   for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) {
 
     if ((ns&1) == 0)
-      nprime = (n2_pucch < 12*NRB2) ? 
-	n2_pucch % 12 :
-	(n2_pucch+Ncs1 + 1)%12;
-    else
-      nprime = (n2_pucch < 12*NRB2) ? 
-        ((12*(nprime+1)) % 13)-1 :
-	(10-n2_pucch)%12;
-
+        nprime = (n2_pucch < 12*NRB2) ?
+                n2_pucch % 12 :
+                (n2_pucch+Ncs1 + 1)%12;
+    else {
+        nprime = (n2_pucch < 12*NRB2) ?
+                ((12*(nprime+1)) % 13)-1 :
+                (10-n2_pucch)%12;
+    }
     //loop over symbols in slot
     for (l=0; l<N_UL_symb; l++) {
       // Compute n_cs (36.211 p. 18)
       n_cs = (ncs_cell[ns][l]+nprime)%12;
 
-      alpha_ind = n_cs;
-      data_ind = 0;
-
+      alpha_ind = 0;
       for (n=0; n<12; n++) {
-
-        // this is r_uv^alpha(n)
-        ref_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
-        ref_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);
-
-        if ((l<2)||(l>=(N_UL_symb-2))) { //these are PUCCH data symbols
-	  ((int16_t *)&zptr[n])[0] = ((int32_t)d[data_ind]*ref_re - (int32_t)d[data_ind+1]*ref_im)>>15;
-	  ((int16_t *)&zptr[n])[1] = ((int32_t)d[data_ind]*ref_im + (int32_t)d[data_ind+1]*ref_re)>>15;
-	}
-	else {
-	  ((int16_t *)&zptr[n])[0] = ref_re;
-	  ((int16_t *)&zptr[n])[1] = ref_im;
-	}
-
+          // this is r_uv^alpha(n)
+          ref_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
+          ref_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);
+
+          if ((l!=1)&&(l!=5)) { //these are PUCCH data symbols
+              ((int16_t *)&zptr[n])[0] = ((int32_t)d[data_ind]*ref_re - (int32_t)d[data_ind+1]*ref_im)>>15;
+              ((int16_t *)&zptr[n])[1] = ((int32_t)d[data_ind]*ref_im + (int32_t)d[data_ind+1]*ref_re)>>15;
+              //LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n);
+          }
+          else {
+              ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15);
+              ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15);
+              //LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n);
+          }
+          alpha_ind = (alpha_ind + n_cs)%12;
       } // n
-      if ((l<2)||(l>=(N_UL_symb-2)))  //these are PUCCH data symbols so increment data index
-	data_ind+=2;
+      zptr+=12;
+
+      if ((l!=1)&&(l!=5))  //these are PUCCH data symbols so increment data index
+	     data_ind+=2;
     } // l
   } //ns
 
   m = n2_pucch/12;
 
 #ifdef DEBUG_PUCCH_TX
-  printf("[PHY] PUCCH: m %d\n",m);
+  LOG_D(PHY,"[PHY] PUCCH: n2_pucch %d m %d\n",n2_pucch,m);
 #endif
-  nsymb = N_UL_symb<<1;
+
+  nsymb_slot0  = ((fp->Ncp==0) ? 7 : 6);
+  nsymb_pertti = nsymb_slot0 << 1;
+
+  //nsymb = nsymb_slot0<<1;
 
   //for (j=0,l=0;l<(nsymb-1);l++) {
-  for (j=0,l=0; l<(nsymb); l++) {
-    if ((l<(nsymb>>1)) && ((m&1) == 0))
+  for (j=0,l=0; l<(nsymb_pertti); l++) {
+
+    if ((l<nsymb_slot0) && ((m&1) == 0))
       re_offset = (m*6) + fp->first_carrier_offset;
-    else if ((l<(nsymb>>1)) && ((m&1) == 1))
+    else if ((l<nsymb_slot0) && ((m&1) == 1))
       re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12;
     else if ((m&1) == 0)
       re_offset = fp->first_carrier_offset + (fp->N_RB_DL - (m>>1) - 1)*12;
@@ -614,23 +622,33 @@ void generate_pucch2x(int32_t **txdataF,
     if (re_offset > fp->ofdm_symbol_size)
       re_offset -= (fp->ofdm_symbol_size);
 
-    symbol_offset = (unsigned int)fp->ofdm_symbol_size*(l+(subframe*nsymb));
+
+
+    symbol_offset = (unsigned int)fp->ofdm_symbol_size*(l+(subframe*nsymb_pertti));
     txptr = &txdataF[0][symbol_offset];
 
+    //LOG_I(PHY,"ofdmSymb %d/%d, firstCarrierOffset %d, symbolOffset[sfn %d] %d, reOffset %d, &txptr: %x \n", l, nsymb, fp->first_carrier_offset, subframe, symbol_offset, re_offset, &txptr[0]);
+
     for (i=0; i<12; i++,j++) {
-      txptr[re_offset++] = z[j];
+      txptr[re_offset] = z[j];
+
+      re_offset++;
 
       if (re_offset==fp->ofdm_symbol_size)
-        re_offset = 0;
+          re_offset -= (fp->ofdm_symbol_size);
 
 #ifdef DEBUG_PUCCH_TX
-      printf("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]);
+      LOG_D(PHY,"[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]);
 #endif
     }
   }
 }
 
 
+//#define Amax 13
+//void init_pucch2x_rx() {};
+
+
 uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 		  PUCCH_FMT_t fmt,
 		  uint8_t UE_id,
diff --git a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c
index a78536246f75ca5cf6c89e68aad80c4204915016..7e29d998a10e30c49d96ba934d2822d86127fe75 100644
--- a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c
@@ -129,18 +129,27 @@ int32_t generate_srs_tx(PHY_VARS_UE *ue,
 
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
-  int32_t *txdataF = ue->common_vars.txdataF[0];
+  int32_t **txdataF = ue->common_vars.txdataF;
   uint16_t msrsb=0,Nb=0,nb,b,msrs0=0,k,Msc_RS,Msc_RS_idx,carrier_pos,symbol_offset;
   uint16_t *Msc_idx_ptr;
   int32_t k0;
-  uint32_t T_SFC;
-  uint32_t subframe_offset;
+  //uint32_t subframe_offset;
   uint8_t Bsrs  = soundingrs_ul_config_dedicated->srs_Bandwidth;
   uint8_t Csrs  = frame_parms->soundingrs_ul_config_common.srs_BandwidthConfig;
   uint8_t Ssrs  = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig;
   uint8_t n_RRC = soundingrs_ul_config_dedicated->freqDomainPosition;
   uint8_t kTC   = soundingrs_ul_config_dedicated->transmissionComb;
 
+  // u is the PUCCH sequence-group number defined in Section 5.5.1.3
+  // ν is the base sequence number defined in Section 5.5.1.4
+  uint32_t u=frame_parms->pucch_config_common.grouphop[1+(subframe<<1)];;
+  uint32_t v=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
+
+  LOG_D(PHY,"SRS root sequence: u %d, v %d\n",u,v);
+  LOG_D(PHY,"CommonSrsConfig:    Csrs %d, Ssrs %d, AnSrsSimultan %d \n",Csrs,Ssrs,frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
+  LOG_D(PHY,"DedicatedSrsConfig: Bsrs %d, bhop %d, nRRC %d, Isrs %d, kTC %d, n_SRS %d\n",Bsrs,soundingrs_ul_config_dedicated->srs_HoppingBandwidth,n_RRC
+                                                                                       ,soundingrs_ul_config_dedicated->srs_ConfigIndex,kTC
+                                                                                       ,soundingrs_ul_config_dedicated->cyclicShift);
 
   if (frame_parms->N_RB_UL < 41) {
     msrs0 = msrsb_6_40[Csrs][0];
@@ -161,7 +170,7 @@ int32_t generate_srs_tx(PHY_VARS_UE *ue,
   }
 
   Msc_RS = msrsb * 6;
-  k0 = (((frame_parms->N_RB_UL>>1)-(msrs0>>1))*12) + kTC;
+  k0 = ( ( (int16_t)(frame_parms->N_RB_UL>>1) - (int16_t)(msrs0>>1) ) * 12 ) + kTC;
   nb  = (4*n_RRC/msrsb)%Nb;
 
   for (b=0; b<=Bsrs; b++) {
@@ -200,53 +209,32 @@ int32_t generate_srs_tx(PHY_VARS_UE *ue,
   msg("generate_srs_tx: Msc_RS = %d, Msc_RS_idx = %d\n",Msc_RS, Msc_RS_idx);
 #endif
 
-  T_SFC = (Ssrs<=7 ? 5 : 10);
-
-  if ((1<<(subframe%T_SFC))&transmission_offset_tdd[Ssrs]) {
+    carrier_pos = (frame_parms->first_carrier_offset + k0);
+    if (carrier_pos>frame_parms->ofdm_symbol_size) {
+        carrier_pos -= frame_parms->ofdm_symbol_size;
+    }
+    uint16_t nsymb = (frame_parms->Ncp==0) ? 14:12;
+    symbol_offset = (int)frame_parms->ofdm_symbol_size*((subframe*nsymb)+(nsymb-1));
 
-#ifndef IFFT_FPGA_UE
-    carrier_pos = (frame_parms->first_carrier_offset + k0) % frame_parms->ofdm_symbol_size;
     //msg("carrier_pos = %d\n",carrier_pos);
+    //subframe_offset = subframe*frame_parms->symbols_per_tti*frame_parms->ofdm_symbol_size;
+    //symbol_offset = subframe_offset+(frame_parms->symbols_per_tti-1)*frame_parms->ofdm_symbol_size;
 
-    subframe_offset = subframe*frame_parms->symbols_per_tti*frame_parms->ofdm_symbol_size;
-    symbol_offset = subframe_offset+(frame_parms->symbols_per_tti-1)*frame_parms->ofdm_symbol_size;
+    int32_t *txptr;
+    txptr = &txdataF[0][symbol_offset];
 
     for (k=0; k<Msc_RS; k++) {
-      ((short*) txdataF)[2*(symbol_offset + carrier_pos)]   = (short) (((int32_t) amp * (int32_t) ul_ref_sigs[0][0][Msc_RS_idx][k<<1])>>15);
-      ((short*) txdataF)[2*(symbol_offset + carrier_pos)+1] = (short) (((int32_t) amp * (int32_t) ul_ref_sigs[0][0][Msc_RS_idx][(k<<1)+1])>>15);
-      carrier_pos+=2;
+      int32_t real = ((int32_t) amp * (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][k<<1])     >> 15;
+      int32_t imag = ((int32_t) amp * (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][(k<<1)+1]) >> 15;
+      txptr[carrier_pos] = (real&0xFFFF) + ((imag<<16)&0xFFFF0000);
 
-      if (carrier_pos >= frame_parms->ofdm_symbol_size)
-        carrier_pos=1;
-    }
 
-#else
-    carrier_pos = (frame_parms->N_RB_UL*12/2 + k0) % (frame_parms->N_RB_UL*12);
-    //msg("carrier_pos = %d\n",carrier_pos);
+      carrier_pos = carrier_pos+2;
 
-    subframe_offset = subframe*frame_parms->symbols_per_tti*frame_parms->N_RB_UL*12;
-    symbol_offset = subframe_offset+(frame_parms->symbols_per_tti-1)*frame_parms->N_RB_UL*12;
-
-    for (k=0; k<Msc_RS; k++) {
-      if ((ul_ref_sigs[0][0][Msc_RS_idx][k<<1] >= 0) && (ul_ref_sigs[0][0][Msc_RS_idx][(k<<1)+1] >= 0))
-        txdataF[symbol_offset+carrier_pos] = (int32_t) 4;
-      else if ((ul_ref_sigs[0][0][Msc_RS_idx][k<<1] >= 0) && (ul_ref_sigs[0][0][Msc_RS_idx][(k<<1)+1] < 0))
-        txdataF[symbol_offset+carrier_pos] = (int32_t) 2;
-      else if ((ul_ref_sigs[0][0][Msc_RS_idx][k<<1] < 0) && (ul_ref_sigs[0][0][Msc_RS_idx][(k<<1)+1] >= 0))
-        txdataF[symbol_offset+carrier_pos] = (int32_t) 3;
-      else if ((ul_ref_sigs[0][0][Msc_RS_idx][k<<1] < 0) && (ul_ref_sigs[0][0][Msc_RS_idx][(k<<1)+1] < 0))
-        txdataF[symbol_offset+carrier_pos] = (int32_t) 1;
-
-      carrier_pos+=2;
-
-      if (carrier_pos >= frame_parms->N_RB_UL*12)
-        carrier_pos=0;
+      if (carrier_pos >= frame_parms->ofdm_symbol_size)
+        carrier_pos=carrier_pos-frame_parms->ofdm_symbol_size;
     }
 
-#endif
-    //  write_output("srs_txF.m","srstxF",&txdataF[symbol_offset],512,1,1);
-  }
-
   return(0);
 }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
index a8f9f6ba574978ff72f164cdf93e11f1ad7f4dd8..37c5dc1432ef818de613c74f757880b5754409d8 100644
--- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
@@ -836,3 +836,5 @@ void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL)
 
 }
 
+
+
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
index 53eaa849fd9eaac63cafc8f8d734ff494d56534f..4559aaa326bd620137d0e6184db2b0cd222c6757 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
@@ -140,6 +140,8 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag)
   if (ulsch) {
     memset(ulsch,0,sizeof(LTE_UE_ULSCH_t));
 
+    ulsch->Mlimit = 4;
+
     for (i=0; i<8; i++) {
 
       ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t));
@@ -498,6 +500,21 @@ uint32_t ulsch_encoding(uint8_t *a,
 
 
     G = G - Q_RI - Q_CQI;
+    ulsch->harq_processes[harq_pid]->G = G;
+
+/*
+    LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK);
+
+    LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n",
+          frame_parms->Nid_cell,ulsch->rnti,
+          harq_pid,
+          ulsch->harq_processes[harq_pid]->round,
+          ulsch->harq_processes[harq_pid]->rvidx,
+          ulsch->harq_processes[harq_pid]->mcs,
+          ulsch->O_RI,
+          ulsch->harq_processes[harq_pid]->O_ACK,
+          G);
+*/
 
     if ((int)G < 0) {
       LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8);
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
index 80168dd3c5519dee1d67d688d0419b30b7721526..ee9bfc53cdd431c2fb7770914f6dcfe3091be058 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
@@ -426,13 +426,14 @@ void ulsch_modulation(int32_t **txdataF,
 
   G = (int)ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
 
+
   // Mapping
   nsymb = (frame_parms->Ncp==0) ? 14:12;
   Msc_PUSCH = ulsch->harq_processes[harq_pid]->nb_rb*12;
 
 #ifdef DEBUG_ULSCH_MODULATION
-  printf("ulsch_modulation.c: Doing modulation (rnti %x,x2 %x) for G=%d bits, harq_pid %d , nb_rb %d, Q_m %d, Nsymb_pusch %d (nsymb %d), subframe %d\n",
-      ulsch->rnti,x2,G,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,Q_m, ulsch->Nsymb_pusch,nsymb,subframe);
+  LOG_D(PHY,"ulsch_modulation.c: Doing modulation (rnti %x,x2 %x) for G=%d bits, harq_pid %d , nb_rb %d, Q_m %d, Nsymb_pusch %d (nsymb %d), subframe %d\n",
+        ulsch->rnti,x2,G,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,Q_m, ulsch->Nsymb_pusch,nsymb,subframe);
 #endif
 
   // scrambling (Note the placeholding bits are handled in ulsch_coding.c directly!)
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 375efa5feadb524e2f6ac92ec491c931f43f0e8c..0e69265d20ce2fe81b22c98edbcc19bddbe9e0bd 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -656,7 +656,7 @@ typedef struct {
   /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime)
   uint32_t rx_gain_byp[4];
   /// \brief Current transmit power
-  int8_t tx_power_dBm[10];
+  int16_t tx_power_dBm[10];
   /// \brief Total number of REs in current transmission
   int tx_total_RE[10];
   /// \brief Maximum transmit power
diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h
index 09d4c74f5234d34ccf8260aa72aff0ac0eab5044..0eb5dc6c97de931dd421bacf0c09b5af394a47e8 100644
--- a/openair1/PHY/extern.h
+++ b/openair1/PHY/extern.h
@@ -117,5 +117,17 @@ extern char eNB_timing[2][20];
 extern int16_t unscrambling_lut[65536*16];
 extern uint8_t scrambling_lut[65536*16];
 
+extern unsigned short msrsb_6_40[8][4];
+extern unsigned short msrsb_41_60[8][4];
+extern unsigned short msrsb_61_80[8][4];
+extern unsigned short msrsb_81_110[8][4];
+extern unsigned short Nb_6_40[8][4];
+extern unsigned short Nb_41_60[8][4];
+extern unsigned short Nb_61_80[8][4];
+extern unsigned short Nb_81_110[8][4];
+
+extern uint16_t hundred_times_log10_NPRB[100];
+extern uint8_t alpha_lut[8];
+
 #endif /*__PHY_EXTERN_H__ */
 
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index f80effbebd4ff67f104c155a083f103e79e0c70e..9005518e7b790b9bd59dcaffa7aebf799823baf2 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -142,6 +142,11 @@ typedef struct {
   uint8_t nCS_AN;
   /// Parameter: \f$N^{(1)}_\text{PUCCH}\f$ see TS 36.213 (10.1). \vr{[0..2047]}
   uint16_t n1PUCCH_AN;
+
+  /// group hopping sequence for DRS \note not part of offical UL-PUCCH_CONFIG_COMMON ASN1 specification.
+  uint8_t grouphop[20];
+  /// sequence hopping sequence for DRS \note not part of offical UL-PUCCH_CONFIG_COMMON ASN1 specification.
+  uint8_t seqhop[20];
 } PUCCH_CONFIG_COMMON;
 
 /// UL-ReferenceSignalsPUSCH from 36.331 RRC spec
@@ -315,6 +320,12 @@ typedef struct {
   uint16_t srs_ConfigIndex;
   /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value.
   uint8_t cyclicShift;
+  // Parameter: ue srs subframe for internal implementation
+  uint8_t srsConfigDedicatedSetup;
+  // Parameter: cell srs subframe for internal implementation
+  uint8_t srsCellSubframe;
+  // Parameter: ue srs subframe for internal implementation
+  uint8_t srsUeSubframe;
 } SOUNDINGRS_UL_CONFIG_DEDICATED;
 
 /// UplinkPowerControlDedicated Information Element from 36.331 RRC spec
@@ -418,16 +429,20 @@ typedef struct {
 
 /// CQI-ReportPeriodic
 typedef struct {
-  /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}
-  uint16_t cqi_PUCCH_ResourceIndex;
+  /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity
+  int16_t cqi_PUCCH_ResourceIndex;
   /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]}
-  uint16_t cqi_PMI_ConfigIndex;
+  int16_t cqi_PMI_ConfigIndex;
   /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]}
   uint8_t K;
-  /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}
-  uint16_t ri_ConfigIndex;
+  /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity
+  int16_t ri_ConfigIndex;
   /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed.
   uint8_t simultaneousAckNackAndCQI;
+  /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C
+  uint16_t Npd;
+  /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C
+  uint16_t N_OFFSET_CQI;
 } CQI_REPORTPERIODIC;
 
 /// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic.
diff --git a/openair1/SCHED/Makefile.inc b/openair1/SCHED/Makefile.inc
index e3fd877e5d7bc6f7052c5f5413fc61c3264425db..559d3dca32b2db60e50caa0f8fc349edf9499e1e 100644
--- a/openair1/SCHED/Makefile.inc
+++ b/openair1/SCHED/Makefile.inc
@@ -3,3 +3,4 @@ SCHED_OBJS += $(TOP_DIR)/SCHED/phy_procedures_lte_ue.o
 SCHED_OBJS += $(TOP_DIR)/SCHED/phy_procedures_lte_eNb.o
 SCHED_OBJS += $(TOP_DIR)/SCHED/pusch_pc.o
 SCHED_OBJS += $(TOP_DIR)/SCHED/pucch_pc.o
+SCHED_OBJS += $(TOP_DIR)/SCHED/srs_pc.o
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 6c39570007244794a08dd018512d03449771e876..2490a4035c14cafd2c7c708f24a9e47073a5e569 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -442,6 +442,17 @@ int8_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,ui
  */
 void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag);
 
+/*! \brief This function implements the power control mechanism for SRS from 36.213.
+    @param phy_vars_ue PHY variables
+    @param proc Pointer to proc descriptor
+    @param eNB_id Index of eNB
+    @param j index of type of PUSCH (SPS, Normal, Msg3)
+    @returns Transmit power
+ */
+void srs_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag);
+
+void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id);
+
 int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
 
 #ifdef LOCALIZATION
@@ -457,6 +468,8 @@ double aggregate_eNB_UE_localization_stats(PHY_VARS_eNB *phy_vars_eNB, int8_t UE
 #endif
 LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
 
+
+
 LTE_DL_FRAME_PARMS *get_lte_frame_parms(module_id_t Mod_id, uint8_t CC_id);
 
 MU_MIMO_mode* get_mu_mimo_mode (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 60238863154c1674fee587dfe0a52e916d962241..d7692749c343fa5c69320e4a2795428e40263c58 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -61,6 +61,9 @@ fifo_dump_emos_UE emos_dump_UE;
 # include "intertask_interface.h"
 #endif
 
+#include "PHY/defs.h"
+
+#include "PHY/CODING/extern.h"
 
 #define DLSCH_RB_ALLOC 0x1fbf  // skip DC RB (total 23/25 RBs)
 #define DLSCH_RB_ALLOC_12 0x0aaa  // skip DC RB (total 23/25 RBs)
@@ -377,6 +380,345 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
   return(0);
 }
 
+uint8_t is_cqi_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+  int subframe = proc->subframe_tx;
+  int frame    = proc->frame_tx;
+  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
+
+  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for CQI TXOp (cqi_ConfigIndex %d) isCQIOp %d\n",
+  //      ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame,subframe,
+  //      cqirep->cqi_PMI_ConfigIndex,
+  //      (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI));
+
+  if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)
+    return(1);
+  else
+    return(0);
+}
+uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+
+
+  int subframe = proc->subframe_tx;
+  int frame    = proc->frame_tx;
+  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
+  int log2Mri = cqirep->ri_ConfigIndex/161;
+  int N_OFFSET_RI = cqirep->ri_ConfigIndex % 161;
+
+  //LOG_I(PHY,"[UE %d][CRNTI %x] AbsSubFrame %d.%d Checking for RI TXOp (ri_ConfigIndex %d) isRIOp %d\n",
+  //      ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame,subframe,
+  //      cqirep->ri_ConfigIndex,
+  //      (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0));
+
+  if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<<log2Mri)) == 0)
+    return(1);
+  else
+    return(0);
+}
+
+void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset)
+{
+    if(TDD == frameType)
+    {
+        if(isrs<10)
+        {
+            mac_xface->macphy_exit("2 ms SRS periodicity not supported");
+        }
+
+        if((isrs>9)&&(isrs<15))
+        {
+            *psrsPeriodicity=5;
+            *psrsOffset=isrs-10;
+        }
+        if((isrs>14)&&(isrs<25))
+        {
+            *psrsPeriodicity=10;
+            *psrsOffset=isrs-15;
+        }
+        if((isrs>24)&&(isrs<45))
+        {
+            *psrsPeriodicity=20;
+            *psrsOffset=isrs-25;
+        }
+        if((isrs>44)&&(isrs<85))
+        {
+            *psrsPeriodicity=40;
+            *psrsOffset=isrs-45;
+        }
+        if((isrs>84)&&(isrs<165))
+        {
+            *psrsPeriodicity=80;
+            *psrsOffset=isrs-85;
+        }
+        if((isrs>164)&&(isrs<325))
+        {
+            *psrsPeriodicity=160;
+            *psrsOffset=isrs-165;
+        }
+        if((isrs>324)&&(isrs<645))
+        {
+            *psrsPeriodicity=320;
+            *psrsOffset=isrs-325;
+        }
+
+        if(isrs>644)
+        {
+            mac_xface->macphy_exit("Isrs out of range");
+        }
+
+    }
+    else
+    {
+        if(isrs<2)
+        {
+            *psrsPeriodicity=2;
+            *psrsOffset=isrs;
+        }
+        if((isrs>1)&&(isrs<7))
+        {
+            *psrsPeriodicity=5;
+            *psrsOffset=isrs-2;
+        }
+        if((isrs>6)&&(isrs<17))
+        {
+            *psrsPeriodicity=10;
+            *psrsOffset=isrs-7;
+        }
+        if((isrs>16)&&(isrs<37))
+        {
+            *psrsPeriodicity=20;
+            *psrsOffset=isrs-17;
+        }
+        if((isrs>36)&&(isrs<77))
+        {
+            *psrsPeriodicity=40;
+            *psrsOffset=isrs-37;
+        }
+        if((isrs>76)&&(isrs<157))
+        {
+            *psrsPeriodicity=80;
+            *psrsOffset=isrs-77;
+        }
+        if((isrs>156)&&(isrs<317))
+        {
+            *psrsPeriodicity=160;
+            *psrsOffset=isrs-157;
+        }
+        if((isrs>316)&&(isrs<637))
+        {
+            *psrsPeriodicity=320;
+            *psrsOffset=isrs-317;
+        }
+        if(isrs>636)
+        {
+            mac_xface->macphy_exit("Isrs out of range");
+        }
+    }
+}
+
+void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
+{
+    LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+    int frame_tx    = proc->frame_tx;
+    int subframe_tx = proc->subframe_tx;
+    uint8_t isSubframeSRS   = 0; // SRS Cell Occasion
+
+    uint8_t is_pucch2_subframe = 0;
+    uint8_t is_sr_an_subframe  = 0;
+
+    SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+
+  // check for SRS opportunity
+  pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
+  pSoundingrs_ul_config_dedicated->srsCellSubframe = 0;
+
+  ue->ulsch[eNB_id]->srs_active   = 0;
+  ue->ulsch[eNB_id]->Nsymb_pusch  = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active;
+  if(frame_parms->soundingrs_ul_config_common.enabled_flag)
+  {
+
+      LOG_D(PHY," SRS SUBFRAMECONFIG: %d, Isrs: %d \n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig, pSoundingrs_ul_config_dedicated->srs_ConfigIndex);
+
+      uint8_t  TSFC;
+      uint16_t deltaTSFC; // bitmap
+      uint8_t  srs_SubframeConfig;
+      uint16_t srsPeriodicity;
+      uint16_t srsOffset;
+
+      // table resuming TSFC (Period) and deltaSFC (offset)
+      const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} };      // Table 5.5.3.3-2 3GPP 36.211 FDD
+      const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
+
+      srs_SubframeConfig = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig;
+      if (FDD == frame_parms->frame_type)
+      {
+          // srs_SubframeConfig =< 14
+          deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
+          TSFC      = deltaTSFCTabType1[srs_SubframeConfig][1];
+      }
+      else
+      {
+          // srs_SubframeConfig =< 13
+          deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
+          TSFC      = deltaTSFCTabType2[srs_SubframeConfig][1];
+      }
+
+      // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
+      uint16_t tmp = (subframe_tx %  TSFC);
+      if((1<<tmp) & deltaTSFC)
+      {
+          // This is a Sounding reference signal subframes
+          isSubframeSRS = 1;
+          pSoundingrs_ul_config_dedicated->srsCellSubframe  = 1;
+      }
+      LOG_D(PHY," ISTDD: %d, TSFC: %d, deltaTSFC: %d, AbsSubframeTX: %d.%d, srsCellSubframe: %d \n", frame_parms->frame_type, TSFC, deltaTSFC, frame_tx, subframe_tx, pSoundingrs_ul_config_dedicated->srsCellSubframe);
+      LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
+      if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
+      {
+          compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset);
+
+          LOG_D(PHY," srsPeriodicity: %d srsOffset: %d isSubframeSRS %d \n",srsPeriodicity,srsOffset,isSubframeSRS);
+
+          // transmit SRS if the four following constraints are respected:
+          // - UE is configured to transmit SRS
+          // - SRS are configured in current subframe
+          // - UE is configured to send SRS in this subframe
+
+          // 36.213 8.2
+          // 1- A UE shall not transmit SRS whenever SRS and PUCCH format 2/2a/2b transmissions happen to coincide in the same subframe
+          // 2- A UE shall not transmit SRS whenever SRS transmit
+          //    on and PUCCH transmission carrying ACK/NACK and/or
+          //    positive SR happen to coincide in the same subframe if the parameter
+          //    Simultaneous-AN-and-SRS is FALSE
+
+          // check PUCCH format 2/2a/2b transmissions
+          is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0);
+          is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe;
+
+          // check ACK/SR transmission
+          if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE)
+          {
+              if(is_SR_TXOp(ue,proc,eNB_id))
+              {
+                  uint32_t SR_payload = 0;
+                  if (ue->mac_enabled==1)
+                  {
+                      int Mod_id = ue->Mod_id;
+                      int CC_id = ue->CC_id;
+                      SR_payload = mac_xface->ue_get_SR(Mod_id,
+                              CC_id,
+                              frame_tx,
+                              eNB_id,
+                              ue->pdcch_vars[eNB_id]->crnti,
+                              subframe_tx); // subframe used for meas gap
+
+                      if (SR_payload > 0)
+                          is_sr_an_subframe = 1;
+                  }
+              }
+
+              uint8_t pucch_ack_payload[2];
+              if (get_ack(&ue->frame_parms,
+                      ue->dlsch[eNB_id][0]->harq_ack,
+                      subframe_tx,pucch_ack_payload) > 0)
+              {
+                  is_sr_an_subframe = 1;
+              }
+          }
+
+          // check SRS UE opportunity
+          if( isSubframeSRS  &&
+                  (((10*frame_tx+subframe_tx) % srsPeriodicity) == srsOffset)
+          )
+          {
+              if ((is_pucch2_subframe == 0) && (is_sr_an_subframe == 0))
+              {
+                  pSoundingrs_ul_config_dedicated->srsUeSubframe = 1;
+                  ue->ulsch[eNB_id]->srs_active   = 1;
+                  ue->ulsch[eNB_id]->Nsymb_pusch  = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active;
+              }
+              else
+              {
+                  LOG_I(PHY,"DROP UE-SRS-TX for this subframe %d.%d: collision with PUCCH2 or SR/AN: PUCCH2-occasion: %d, SR-AN-occasion[simSRS-SR-AN %d]: %d  \n", frame_tx, subframe_tx, is_pucch2_subframe, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, is_sr_an_subframe);
+              }
+          }
+      }
+      LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, ue->ulsch[eNB_id]->Nsymb_pusch);
+  }
+}
+
+void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
+{
+
+  CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic;
+  int cqi_PMI_ConfigIndex = cqirep->cqi_PMI_ConfigIndex;
+
+  if (ue->frame_parms.frame_type == FDD) {
+    if (cqi_PMI_ConfigIndex <= 1) {        // 2 ms CQI_PMI period
+      cqirep->Npd = 2;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex;
+    } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
+      cqirep->Npd = 5;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
+    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
+      cqirep->Npd = 10;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
+    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
+      cqirep->Npd = 20;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
+    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
+      cqirep->Npd = 40;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
+    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
+      cqirep->Npd = 80;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
+    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
+      cqirep->Npd = 160;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
+    }
+    else if (cqi_PMI_ConfigIndex > 317) {
+      
+      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
+	cqirep->Npd = 32;
+      cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
+      }
+      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
+	cqirep->Npd = 64;
+	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
+      }
+      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
+	cqirep->Npd = 128;
+	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
+      }  
+    }
+  }
+  else { // TDD
+   if (cqi_PMI_ConfigIndex == 0) {        // all UL subframes
+     cqirep->Npd = 1;
+     cqirep->N_OFFSET_CQI = 0;
+   } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
+     cqirep->Npd = 5;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-1;
+   } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
+     cqirep->Npd = 10;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-6;
+   } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
+     cqirep->Npd = 20;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-16;
+   } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
+     cqirep->Npd = 40;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-36;
+   } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
+     cqirep->Npd = 80;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-76;
+   } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
+     cqirep->Npd = 160;
+     cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-156;
+   }
+  }
+}
+
 uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 		      UE_rxtx_proc_t *proc,
                       uint8_t eNB_id,
@@ -605,9 +947,18 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc) {
   
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
   ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
-		 ue->hw_timing_advance-
-		 ue->timing_advance-
-		 ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+         ue->hw_timing_advance-
+         ue->timing_advance-
+         ue->N_TA_offset+5);
+  //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);
+
+  if(ulsch_start < 0)
+      ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+
+  if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti))
+      ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+
+  //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);
 #else //this is the normal case
   ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
 #endif //else EXMIMO
@@ -678,6 +1029,15 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc) {
     }
 #endif
 #endif
+    /*
+    only for debug
+    LOG_I(PHY,"ul-signal [subframe: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",subframe_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance);
+    if( (crash == 1) && (subframe_tx == 0) )
+    {
+      LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start);
+      write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
+    }
+    */
     
   } //nb_antennas_tx
   
@@ -874,7 +1234,14 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     ue->generate_ul_signal[eNB_id] = 1;
     
     // deactivate service request
-    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+    LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit);
+    if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1))
+    {
+        LOG_D(PHY,"PUSCH MAX Retransmission acheived ==> send last pusch (%d) \n");
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
+    }
     
     ack_status = get_ack(&ue->frame_parms,
 			 ue->dlsch[eNB_id][0]->harq_ack,
@@ -887,6 +1254,27 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     
     
     
+
+    if (ack_status > 0) {
+
+      // check if we received a PDSCH at subframe_tx - 4
+      // ==> send ACK/NACK on PUSCH
+      if( (ue->dlsch[eNB_id][0]->harq_ack[proc->subframe_rx].send_harq_status) == 1)
+      {
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1;
+      }
+      else
+      {
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 0;
+      }
+      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
+        Mod_id,
+        ue->ulsch[eNB_id]->rnti,
+        frame_tx,subframe_tx,
+        ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
+        ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
+    }
+
 #ifdef DEBUG_PHY_PROC
     LOG_D(PHY,
 	  "[UE  %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d\n",
@@ -905,15 +1293,6 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
 #endif
     
-    if (ack_status > 0) {
-      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
-	    Mod_id,
-	    ue->ulsch[eNB_id]->rnti,
-	    frame_tx,subframe_tx,
-	    ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
-	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
-    }
-    
     
     
     
@@ -1078,15 +1457,93 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
   } // subframe_scheduling_flag==1
 }
 
+void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag)
+{
+
+  //LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  //int8_t  frame_tx    = proc->frame_tx;
+  int8_t  subframe_tx = proc->subframe_tx;
+  int16_t tx_amp;
+  int16_t Po_SRS;
+  uint8_t nb_rb_srs;
+
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+  uint8_t isSrsTxOccasion = pSoundingrs_ul_config_dedicated->srsUeSubframe;
+
+  if(isSrsTxOccasion)
+  {
+    ue->generate_ul_signal[eNB_id] = 1;
+    if (ue->mac_enabled==1)
+    {
+      srs_power_cntl(ue,proc,eNB_id, (uint8_t*)(&nb_rb_srs), abstraction_flag);
+      Po_SRS = ue->ulsch[eNB_id]->Po_SRS;
+    }
+    else
+    {
+      Po_SRS = ue->tx_power_max_dBm;
+    }
+
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+    if (ue->mac_enabled==1)
+    {
+    tx_amp = get_tx_amp(Po_SRS,
+                        ue->tx_power_max_dBm,
+                        ue->frame_parms.N_RB_UL,
+                        nb_rb_srs);
+    }
+    else
+    {
+        tx_amp = AMP;
+    }
+#else
+      tx_amp = AMP;
+#endif
+    LOG_D(PHY,"SRS PROC; TX_MAX_POWER %d, Po_SRS %d, NB_RB_UL %d, NB_RB_SRS %d TX_AMPL %d\n",ue->tx_power_max_dBm,
+            Po_SRS,
+            ue->frame_parms.N_RB_UL,
+            nb_rb_srs,
+            tx_amp);
+
+    generate_srs_tx(ue, eNB_id, tx_amp, subframe_tx);
+  }
+}
+
+int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) {
+
+  if ((ue->transmission_mode[eNB_id]<4)||
+      (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback
+    // 4-bit CQI message
+    *len=4;
+    return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
+		    ue->transmission_mode[eNB_id]));
+  }
+  else { // Mode 1-1 feedback, later
+    *len=0;
+    // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI)
+
+    // 2-antenna ports RI=2, 8 bits (1 PMI, 7 CQI/DIFF CQI)
+    return(0);
+  }
+}
+
+
+int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) {
+
+  return(1);
+}
 
 void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
 
 
   uint8_t pucch_ack_payload[2];
-  uint8_t n1_pucch;
+  uint8_t n1_pucch,n2_pucch;
   ANFBmode_t bundling_flag;
   PUCCH_FMT_t format;
+
   uint8_t SR_payload;
+  uint16_t CQI_payload;
+  uint16_t RI_payload;
+
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int frame_tx=proc->frame_tx;
   int subframe_tx=proc->subframe_tx;
@@ -1095,6 +1552,26 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   int tx_amp;
   int8_t Po_PUCCH;
 
+  SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
+
+  // 36.213 8.2
+  /*if ackNackSRS_SimultaneousTransmission ==  TRUE and in the cell specific SRS subframes UE shall transmit
+    ACK/NACK and SR using the shortened PUCCH format. This shortened PUCCH format shall be used in a cell
+    specific SRS subframe even if the UE does not transmit SRS in that subframe
+  */
+
+  int harq_pid = subframe2harq_pid(&ue->frame_parms,
+                                   frame_tx,
+                                   subframe_tx);
+
+  if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag)
+  {
+      LOG_D(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx);
+      return;
+  }
+
+  uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
+
   bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
   
   if ((frame_parms->frame_type==FDD) ||
@@ -1167,19 +1644,23 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
 	    
     if (SR_payload>0) {
-      LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), n1_pucch %d, Po_PUCCH, amp %d\n",
+      LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH, amp %d\n",
 	    Mod_id,
 	    ue->dlsch[eNB_id][0]->rnti,
+		frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+	    isShortenPucch,
 	    frame_tx, subframe_tx,
 	    pucch_ack_payload[0],pucch_ack_payload[1],
 	    ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
 	    Po_PUCCH,
 	    tx_amp);
     } else {
-      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
+      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
 	    Mod_id,
 	    ue->dlsch[eNB_id][0]->rnti,
 	    frame_tx, subframe_tx,
+		frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+	    isShortenPucch,
 	    n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
 	    Po_PUCCH,
 	    tx_amp);
@@ -1193,7 +1674,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 		       format,
 		       &ue->pucch_config_dedicated[eNB_id],
 		       n1_pucch,
-		       1,  // shortened format
+		       isShortenPucch,  // shortened format
 		       pucch_ack_payload,
 		       tx_amp,
 		       subframe_tx);
@@ -1210,7 +1691,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
     }
   } else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC
-	    
+
     if (ue->mac_enabled == 1) {
       Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,pucch_format1);
     }
@@ -1228,10 +1709,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #else
     tx_amp = AMP;
 #endif
-    LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), n1_pucch %d, Po_PUCCH %d\n",
+    LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
 	  Mod_id,
 	  ue->dlsch[eNB_id][0]->rnti,
 	  frame_tx, subframe_tx,
+	  frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
+	  isShortenPucch,
 	  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
 	  Po_PUCCH);
 	    
@@ -1243,7 +1726,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 		       pucch_format1,
 		       &ue->pucch_config_dedicated[eNB_id],
 		       ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
-		       1,  // shortened format
+		       isShortenPucch,  // shortened format
 		       pucch_ack_payload,  // this is ignored anyway, we just need a pointer
 		       tx_amp,
 		       subframe_tx);
@@ -1258,6 +1741,111 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
     }
   } // SR_Payload==1
+
+  // PUCCH 2x
+
+  if (ue->generate_ul_signal[eNB_id] == 0) { // we have not generated ACK/NAK/SR in this subframe
+
+    n2_pucch = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
+    // only use format2 for now, i.e. now ACK/NAK - CQI multiplexing
+    format = pucch_format2;
+
+    // Periodic CQI report
+    if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
+	(is_cqi_TXOp(ue,proc,eNB_id)==1)){
+
+      if (ue->mac_enabled == 1) {
+	Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
+      }
+      else {
+	Po_PUCCH = ue->tx_power_max_dBm;
+      }
+      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
+      ue->tx_total_RE[subframe_tx] = 12;
+      
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+      tx_amp =  get_tx_amp(Po_PUCCH,
+			   ue->tx_power_max_dBm,
+			   ue->frame_parms.N_RB_UL,
+			   1);
+#else
+      tx_amp = AMP;
+#endif
+      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
+	    Mod_id,
+	    ue->dlsch[eNB_id][0]->rnti,
+	    frame_tx, subframe_tx,
+	    n2_pucch,
+	    Po_PUCCH,
+	    isShortenPucch,
+	    tx_amp);
+      
+      int len;
+      // get the payload : < 12 bits, returned in len
+      CQI_payload = get_pucch2_cqi(ue,eNB_id,&len);
+      generate_pucch2x(ue->common_vars.txdataF,
+		       &ue->frame_parms,
+		       ue->ncs_cell,
+		       format,
+		       &ue->pucch_config_dedicated[eNB_id],
+		       n2_pucch,
+		       &CQI_payload,
+		       len,          // A
+		       0,            // B2 not needed
+		       tx_amp,
+		       subframe_tx,
+		       ue->pdcch_vars[eNB_id]->crnti);
+
+      ue->generate_ul_signal[eNB_id] = 1;
+    }
+    // Periodic RI report
+    else if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
+	     (is_ri_TXOp(ue,proc,eNB_id)==1)){
+
+      if (ue->mac_enabled == 1) {
+	Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
+      }
+      else {
+	Po_PUCCH = ue->tx_power_max_dBm;
+      }
+      ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
+      ue->tx_total_RE[subframe_tx] = 12;
+      
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+      tx_amp =  get_tx_amp(Po_PUCCH,
+			   ue->tx_power_max_dBm,
+			   ue->frame_parms.N_RB_UL,
+			   1);
+#else
+      tx_amp = AMP;
+#endif
+      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
+	    Mod_id,
+	    ue->dlsch[eNB_id][0]->rnti,
+	    frame_tx, subframe_tx,
+	    n2_pucch,
+	    Po_PUCCH,
+	    isShortenPucch,
+	    tx_amp);
+
+      RI_payload = get_pucch2_ri(ue,eNB_id);
+
+      generate_pucch2x(ue->common_vars.txdataF,
+		       &ue->frame_parms,
+		       ue->ncs_cell,
+		       format,
+		       &ue->pucch_config_dedicated[eNB_id],
+		       n2_pucch,
+		       &RI_payload,
+		       1,            // A
+		       0,            // B2 not needed
+		       tx_amp,
+		       subframe_tx,
+		       ue->pdcch_vars[eNB_id]->crnti);
+      
+      ue->generate_ul_signal[eNB_id] = 1;
+    }
+  }
 }
 
 void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) {
@@ -1293,13 +1881,18 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
   }
       
   if (ue->UE_mode[eNB_id] != PRACH) {
+    // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding
+    ue_compute_srs_occasion(ue,proc,eNB_id);
 
     ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
 
   }
   	  
-  if (ue->UE_mode[eNB_id] == PUSCH) { // check if we need to use PUCCH 1a/1b
-	  ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
+  if (ue->UE_mode[eNB_id] == PUSCH) {
+      // check if we need to use PUCCH 1a/1b
+      ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
+      // check if we need to use SRS
+      ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
   } // UE_mode==PUSCH
 	
   	
@@ -2037,7 +2630,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,
-					    SI_RNTI,
+						P_RNTI,
 					    dci_alloc_rx[i].format,
 					    &ue->dlsch_SI[eNB_id],
 					    &ue->frame_parms,
@@ -2530,7 +3123,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 			   subframe_rx,
 			   harq_pid,
 			   pdsch==PDSCH?1:0,
-			   dlsch0->harq_processes[harq_pid]->nb_rb>10?1:0);
+			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
       stop_meas(&ue->dlsch_decoding_stats);
     }
 	
@@ -2547,22 +3140,27 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
     if (ret == (1+dlsch0->max_turbo_iterations)) {
       *dlsch_errors=*dlsch_errors+1;
       
-
+      if(dlsch0->rnti != 0xffff)
+      {
       LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d,TBS %d)\n",
 	    ue->Mod_id,dlsch0->rnti,
 	    harq_pid,frame_rx,subframe_rx,
 	    dlsch0->harq_processes[harq_pid]->rvidx,
 	    dlsch0->harq_processes[harq_pid]->mcs,
 	    dlsch0->harq_processes[harq_pid]->TBS);
+      }
       
 
     } else {
+        if(dlsch0->rnti != 0xffff)
+        {
       LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d,TBS %d)\n",
 	    ue->Mod_id,dlsch0->rnti,
 	    harq_pid,frame_rx,subframe_rx,
 	    dlsch0->harq_processes[harq_pid]->rvidx,
 	    dlsch0->harq_processes[harq_pid]->mcs,
 	    dlsch0->harq_processes[harq_pid]->TBS);
+        }
 
 #ifdef DEBUG_DLSCH
       int j;
@@ -2751,6 +3349,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
  
   // do procedures for C-RNTI
   if (ue->dlsch[eNB_id][0]->active == 1) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
@@ -2760,9 +3359,11 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
   }
   // do procedures for SI-RNTI
   if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
@@ -2772,10 +3373,12 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
   }
 
   // do procedures for SI-RNTI
   if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
@@ -2785,10 +3388,12 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
   }
 
   // do procedures for RA-RNTI
   if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
@@ -2798,6 +3403,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
   }    
   
   if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) {  // do front-end processing for second slot, and first symbol of next subframe
@@ -2833,6 +3439,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
    
   // do procedures for C-RNTI
   if (ue->dlsch[eNB_id][0]->active == 1) {
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
@@ -2851,7 +3458,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			&ue->dlsch_errors[eNB_id],
 			mode,
 			abstraction_flag);
-      
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
 
   }
   else {
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index 5afd57e6a0f9a54ad1be5e09e2d74acc1e04bb07..2795fe65a931d0c0f3c88764e59ac37b54876938 100644
--- a/openair1/SCHED/pucch_pc.c
+++ b/openair1/SCHED/pucch_pc.c
@@ -88,7 +88,7 @@ int8_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,ui
   }
 
   if (pucch_fmt!=pucch_format1) {
-    LOG_I(PHY,"[UE  %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
+    LOG_D(PHY,"[UE  %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
           ue->Mod_id,
           ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
           Po_PUCCH,
@@ -96,7 +96,7 @@ int8_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,ui
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
           ue->dlsch[eNB_id][0]->g_pucch);
   } else {
-    LOG_I(PHY,"[UE  %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
+    LOG_D(PHY,"[UE  %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
           ue->Mod_id,
           ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
           Po_PUCCH,
diff --git a/openair1/SCHED/srs_pc.c b/openair1/SCHED/srs_pc.c
new file mode 100644
index 0000000000000000000000000000000000000000..98049b2ed0cd09a9e1c32da5e8dfad4254970242
--- /dev/null
+++ b/openair1/SCHED/srs_pc.c
@@ -0,0 +1,100 @@
+/*
+ * 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.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file srs_pc.c
+ * \brief Implementation of UE SRS Power Control procedures from 36.213 LTE specifications (Section
+ * \author H. Bilel
+ * \date 2016
+ * \version 0.1
+ * \company TCL
+ * \email: haithem.bilel@alcatelOneTouch.com
+ * \note
+ * \warning
+ */
+
+#include "PHY/defs.h"
+#include "PHY/LTE_TRANSPORT/proto.h"
+#include "PHY/extern.h"
+
+void srs_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t *pnb_rb_srs, uint8_t abstraction_flag)
+{
+
+  int16_t PL;
+  int8_t  p0_NominalPUSCH;
+  int8_t  p0_UE_PUSCH;
+  int8_t  Psrs_offset;
+  int16_t P_srs;
+  int16_t f_pusch;
+  uint8_t alpha;
+  uint8_t Msrs = 0;
+  
+
+  SOUNDINGRS_UL_CONFIG_DEDICATED *psoundingrs_ul_config_dedicated = &ue->soundingrs_ul_config_dedicated[eNB_id];
+  LTE_DL_FRAME_PARMS             *pframe_parms                    = &ue->frame_parms;
+  
+  uint8_t Bsrs  = psoundingrs_ul_config_dedicated->srs_Bandwidth;
+  uint8_t Csrs  = pframe_parms->soundingrs_ul_config_common.srs_BandwidthConfig;
+  LOG_D(PHY," SRS Power Control; AbsSubframe %d.%d, eNB_id %d, N_RB_UL %d, srs_Bandwidth %d, srs_BandwidthConfig %d \n",proc->frame_tx,proc->subframe_tx,eNB_id,pframe_parms->N_RB_UL,Bsrs,Csrs);
+  
+  if (pframe_parms->N_RB_UL < 41)
+  {
+    Msrs    = Nb_6_40[Csrs][Bsrs];
+  } 
+  else if (pframe_parms->N_RB_UL < 61)
+  {
+    Msrs    = Nb_41_60[Csrs][Bsrs];
+  } 
+  else if (pframe_parms->N_RB_UL < 81)
+  {
+    Msrs    = Nb_61_80[Csrs][Bsrs];
+  } 
+  else if (pframe_parms->N_RB_UL <111)
+  {
+    Msrs    = Nb_81_110[Csrs][Bsrs];
+  }
+
+  // SRS Power control 36.213 5.1.3.1
+  // P_srs   =  P_srs_offset+ 10log10(Msrs) + P_opusch(j) + alpha*PL + f(i))
+
+  p0_NominalPUSCH = ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
+  p0_UE_PUSCH     = ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH;
+  Psrs_offset     = (ue->ul_power_control_dedicated[eNB_id].pSRS_Offset - 3);
+
+
+  f_pusch     = ue->ulsch[eNB_id]->f_pusch;
+  alpha       = alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha];
+  PL          = get_PL(ue->Mod_id,ue->CC_id,eNB_id);
+
+  LOG_D(PHY," SRS Power Control; eNB_id %d, p0_NominalPUSCH %d, p0_UE_PUSCH %d, alpha %d \n",eNB_id,p0_NominalPUSCH,p0_UE_PUSCH,alpha);
+  LOG_D(PHY," SRS Power Control; eNB_id %d, pSRS_Offset[dB] %d, Msrs %d, PL %d, f_pusch %d \n",eNB_id,Psrs_offset,Msrs,PL,f_pusch);
+
+  P_srs  = (p0_NominalPUSCH + p0_UE_PUSCH) + Psrs_offset + f_pusch;
+  P_srs += (((int32_t)alpha * (int32_t)PL) + hundred_times_log10_NPRB[Msrs-1])/100 ;
+  
+  ue->ulsch[eNB_id]->Po_SRS = P_srs;
+  if(ue->ulsch[eNB_id]->Po_SRS > ue->tx_power_max_dBm)
+  {
+      ue->ulsch[eNB_id]->Po_SRS = ue->tx_power_max_dBm;
+  }
+
+  pnb_rb_srs[0]             = Msrs;
+  LOG_D(PHY," SRS Power Control; eNB_id %d, Psrs_pc[dBm] %d, Pcmax[dBm] %d, Psrs[dBm] %d\n",eNB_id,P_srs,ue->tx_power_max_dBm,ue->ulsch[eNB_id]->Po_SRS);
+}
diff --git a/openair2/COMMON/as_message.h b/openair2/COMMON/as_message.h
index c8cd92b0609323a5898d153f508bf3528642b1c3..acc9ae6ba11f466fe95ef90b3a10d0ad2a0ea05c 100644
--- a/openair2/COMMON/as_message.h
+++ b/openair2/COMMON/as_message.h
@@ -211,6 +211,14 @@ typedef struct broadcast_info_ind_s {
 #define AS_HSDUPA           (1 << NET_ACCESS_HSDUPA)
 #define AS_EUTRAN           (1 << NET_ACCESS_EUTRAN)
 
+/*
+ * NAS->AS -K_eNB refresh request
+ * NAS request AS to refresh its KeNB key
+ */
+typedef struct kenb_refresh_req_s {
+  Byte_t kenb[32];
+} kenb_refresh_req_t;
+
 /*
  * NAS->AS - Cell Information request
  * NAS request AS to search for a suitable cell belonging to the selected
diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h
index 18a767843680d77b01db77640f32b019ff603684..04b1182482a137f9db97e3855163b97e4507c4aa 100644
--- a/openair2/COMMON/rrc_messages_def.h
+++ b/openair2/COMMON/rrc_messages_def.h
@@ -56,6 +56,7 @@ MESSAGE_DEF(RRC_STATE_IND,              MESSAGE_PRIORITY_MED,       RrcStateInd,
 MESSAGE_DEF(RRC_CONFIGURATION_REQ,      MESSAGE_PRIORITY_MED,       RrcConfigurationReq,        rrc_configuration_req)
 
 // UE: NAS -> RRC messages
+MESSAGE_DEF(NAS_KENB_REFRESH_REQ,       MESSAGE_PRIORITY_MED,       NasKenbRefreshReq,          nas_kenb_refresh_req)
 MESSAGE_DEF(NAS_CELL_SELECTION_REQ,     MESSAGE_PRIORITY_MED,       NasCellSelectionReq,        nas_cell_selection_req)
 MESSAGE_DEF(NAS_CONN_ESTABLI_REQ,       MESSAGE_PRIORITY_MED,       NasConnEstabliReq,          nas_conn_establi_req)
 MESSAGE_DEF(NAS_UPLINK_DATA_REQ,        MESSAGE_PRIORITY_MED,       NasUlDataReq,               nas_ul_data_req)
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index c2df8bab38704f7479c114104151b56e73cd7270..8a4c27f5ebb913c0d1a07302c879dcedb74fe579 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -62,6 +62,7 @@ typedef UL_DCCH_Message_t       RrcUlDcchMessage;
 
 #define RRC_CONFIGURATION_REQ(mSGpTR)   (mSGpTR)->ittiMsg.rrc_configuration_req
 
+#define NAS_KENB_REFRESH_REQ(mSGpTR)    (mSGpTR)->ittiMsg.nas_kenb_refresh_req
 #define NAS_CELL_SELECTION_REQ(mSGpTR)  (mSGpTR)->ittiMsg.nas_cell_selection_req
 #define NAS_CONN_ESTABLI_REQ(mSGpTR)    (mSGpTR)->ittiMsg.nas_conn_establi_req
 #define NAS_UPLINK_DATA_REQ(mSGpTR)     (mSGpTR)->ittiMsg.nas_ul_data_req
@@ -175,6 +176,7 @@ typedef struct RrcConfigurationReq_s {
 } RrcConfigurationReq;
 
 // UE: NAS -> RRC messages
+typedef kenb_refresh_req_t      NasKenbRefreshReq;
 typedef cell_info_req_t         NasCellSelectionReq;
 typedef nas_establish_req_t     NasConnEstabliReq;
 typedef ul_info_transfer_req_t  NasUlDataReq;
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 3fbcadafbbd1f1e75ddd3ed35a41b7d7784949fa..e4252ed50049afbc0f19362697f10e11956fe301 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -70,6 +70,9 @@ void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index)
   UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
   UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
 
+//Set BSR Trigger Bmp and remove timer flags
+  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
+
   // stop ongoing RACH procedure
 
   // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any
@@ -178,8 +181,14 @@ rrc_mac_config_req(
       if (logicalChannelConfig->ul_SpecificParameters) {
         UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity]=logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate *
             logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size
-        UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
-        LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_idP,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup);
+        if (logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup != NULL) {
+            UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity]=*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
+            LOG_D(MAC,"[CONFIG][UE %d] LCID %d is attached to the LCGID %d\n",Mod_idP,logicalChannelIdentity,*logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup);
+        }
+        else {
+        	UE_mac_inst[Mod_idP].scheduling_info.LCGID[logicalChannelIdentity] = MAX_NUM_LCGID;
+        }
+        UE_mac_inst[Mod_idP].scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0;
       } else {
         LOG_E(MAC,"[CONFIG][UE %d] LCID %d NULL ul_SpecificParameters\n",Mod_idP,logicalChannelIdentity);
         mac_xface->macphy_exit("NULL ul_SpecificParameters");
@@ -212,6 +221,7 @@ rrc_mac_config_req(
         } else {
           UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx     = (uint16_t) MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
         }
+        mac_xface->phy_config_harq_ue(Mod_idP,0,eNB_index,UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx);
 
         if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) {
           UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer     = (uint16_t) mac_MainConfig->ul_SCH_Config->retxBSR_Timer;
@@ -225,12 +235,34 @@ rrc_mac_config_req(
       if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) {
         UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer  = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9;
       } else {
-        UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer  = (uint16_t) 0;
+        UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer  = 0;
       }
 
+      if (mac_MainConfig->ext2 && mac_MainConfig->ext2->mac_MainConfig_v1020) {
+        if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10) {
+          UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10;
+        } else {
+          UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0;
+        }
+        if (mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10) {
+          UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t) *mac_MainConfig->ext2->mac_MainConfig_v1020->extendedPHR_r10;
+        } else {
+          UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0;
+        }
+      } else {
+        UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = (uint16_t)0;
+        UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = (uint16_t)0;
+      }
 #endif
-      UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF  = get_sf_periodicBSRTimer(UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer);
-      UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF     = get_sf_retxBSRTimer(UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer);
+      UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF  = MAC_UE_BSR_TIMER_NOT_RUNNING;
+      UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF     = MAC_UE_BSR_TIMER_NOT_RUNNING;
+
+       UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
+
+      LOG_D(MAC,"[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
+            Mod_idP,
+            UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF,
+            UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF);
 
       UE_mac_inst[Mod_idP].scheduling_info.drx_config     = mac_MainConfig->drx_Config;
       UE_mac_inst[Mod_idP].scheduling_info.phr_config     = mac_MainConfig->phr_Config;
@@ -252,6 +284,7 @@ rrc_mac_config_req(
       UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF =  get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer);
       UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF =  get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer);
       UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db =  get_db_dl_PathlossChange(UE_mac_inst[Mod_idP].scheduling_info.PathlossChange);
+      UE_mac_inst[Mod_idP].PHR_reporting_active = 0;
       LOG_D(MAC,"[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF)  pathlosschange %d (db) \n",
             Mod_idP,
             (mac_MainConfig->phr_Config)?mac_MainConfig->phr_Config->present:-1,
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index fd3e76dc101ab3451b642dd6256c614ab66bb454..4b100389296549257aaf809471358dd08d71da6b 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -133,10 +133,18 @@
 /*!\brief maximum value for channel quality indicator */
 #define MAX_CQI_VALUE  15
 
+/*!\brief value for indicating BSR Timer is not running */
+#define MAC_UE_BSR_TIMER_NOT_RUNNING   (0xFFFF)
 
 #define LCID_EMPTY 0
 #define LCID_NOT_EMPTY 1
 
+/*!\brief minimum RLC PDU size to be transmitted = min RLC Status PDU or RLC UM PDU SN 5 bits */
+#define MIN_RLC_PDU_SIZE    (2)
+
+/*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */
+#define MIN_MAC_HDR_RLC_SIZE    (1 + MIN_RLC_PDU_SIZE)
+
 /* 
  * eNB part 
  */ 
@@ -222,11 +230,10 @@ typedef struct {
 typedef BSR_SHORT BSR_TRUNCATED;
 /*!\brief  mac control element: long buffer status report for all logical channel group ID*/
 typedef struct {
-  uint32_t Buffer_size3:6;
-  uint32_t Buffer_size2:6;
-  uint32_t Buffer_size1:6;
-  uint32_t Buffer_size0:6;
-  uint32_t padding:8;
+  uint8_t Buffer_size3:6;
+  uint8_t Buffer_size2:6;
+  uint8_t Buffer_size1:6;
+  uint8_t Buffer_size0:6;
 } __attribute__((__packed__))BSR_LONG;
 
 #define BSR_LONG_SIZE  (sizeof(BSR_LONG))
@@ -336,6 +343,12 @@ typedef struct {
 #define SHORT_BSR 29
 /*!\brief LCID of long BSR for ULSCH */
 #define LONG_BSR 30
+/*!\bitmaps for BSR Triggers */
+#define	BSR_TRIGGER_NONE		(0)			/* No BSR Trigger */
+#define	BSR_TRIGGER_REGULAR		(1)			/* For Regular and ReTxBSR Expiry Triggers */
+#define	BSR_TRIGGER_PERIODIC	(2)			/* For BSR Periodic Timer Expiry Trigger */
+#define	BSR_TRIGGER_PADDING		(4)			/* For Padding BSR Trigger */
+
 
 /*! \brief Downlink SCH PDU Structure */
 typedef struct {
@@ -958,8 +971,12 @@ typedef enum {
 typedef struct {
   /// buffer status for each lcgid
   uint8_t  BSR[MAX_NUM_LCGID]; // should be more for mesh topology
-  /// keep the number of bytes in rlc buffer for each lcid
-  uint16_t  BSR_bytes[MAX_NUM_LCGID];
+  /// keep the number of bytes in rlc buffer for each lcgid
+  int32_t  BSR_bytes[MAX_NUM_LCGID];
+  /// after multiplexing buffer remain for each lcid
+  int32_t  LCID_buffer_remain[MAX_NUM_LCID];
+  /// sum of all lcid buffer size
+  uint16_t  All_lcid_buffer_size_lastTTI;
   /// buffer status for each lcid
   uint8_t  LCID_status[MAX_NUM_LCID];
   /// SR pending as defined in 36.321
@@ -971,11 +988,11 @@ typedef struct {
   /// retxBSR-Timer, default value is sf2560
   uint16_t retxBSR_Timer;
   /// retxBSR_SF, number of subframe before triggering a regular BSR
-  int16_t retxBSR_SF;
+  uint16_t retxBSR_SF;
   /// periodicBSR-Timer, default to infinity
   uint16_t periodicBSR_Timer;
   /// periodicBSR_SF, number of subframe before triggering a periodic BSR
-  int16_t periodicBSR_SF;
+  uint16_t periodicBSR_SF;
   /// default value is 0: not configured
   uint16_t sr_ProhibitTimer;
   /// sr ProhibitTime running
@@ -1000,6 +1017,12 @@ typedef struct {
   int16_t prohibitPHR_SF;
   ///DL Pathloss Change in db
   uint16_t PathlossChange_db;
+
+  /// default value is false
+  uint16_t extendedBSR_Sizes_r10;
+  /// default value is false
+  uint16_t extendedPHR_r10;
+
   //Bj bucket usage per  lcid
   int16_t Bj[MAX_NUM_LCID];
   // Bucket size per lcid
@@ -1087,6 +1110,13 @@ typedef struct {
   uint8_t PHR_reporting_active;
   /// power backoff due to power management (as allowed by P-MPRc) for this cell
   uint8_t power_backoff_db[NUMBER_OF_eNB_MAX];
+  /// BSR report falg management
+  uint8_t BSR_reporting_active;
+  /// retxBSR-Timer expires flag
+  uint8_t retxBSRTimer_expires_flag;
+  /// periodBSR-Timer expires flag
+  uint8_t periodBSRTimer_expires_flag;
+
   /// MBSFN_Subframe Configuration
   struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA?
   /// number of subframe allocation pattern available for MBSFN sync area
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 41577d0e2d3dd8be13916c275e041b4d5700d0ca..e24281b89aeb985a17310d33cb805df5fd20cb18 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -648,7 +648,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
 	      if (opt_enabled==1) {
 		trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0],
 			  rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
-			  eNB->subframe,0,0);
+			  eNB->frame, eNB->subframe,0,0);
 		LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
 		      module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
 	      }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index 312de660a46709eccf7507c3388e76092b27295c..fb015320683e343104bcb5750e9d94c136c98068 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -311,6 +311,7 @@ schedule_SI(
                   0xffff,
                   4,
                   0xffff,
+                  eNB->frame,
                   eNB->subframe,
                   0,
                   0);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 3e7f601ef86d03c730ac8213087382e31559609e..91adb5fb2295ec43c64ab7106f8ac67bc8ab33c9 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -1106,7 +1106,7 @@ schedule_ue_spec(
           if (opt_enabled == 1) {
             trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                       TBS, module_idP, 3, UE_RNTI(module_idP,UE_id),
-                      eNB->subframe,0,0);
+                      eNB->frame, eNB->subframe,0,0);
             LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d  rnti %x  with size %d\n",
                   module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS);
           }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index 383c18f7369f2cdc00c7dfd16abca55619943fd5..1dac7af70480cf3729724eab6956b3d02a4104a5 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -621,7 +621,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
     if (opt_enabled ==1 ) {
       trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.payload,
                 TBS, module_idP, 6, 0xffff,  // M_RNTI = 6 in wirehsark
-                eNB_mac_inst[module_idP].subframe,0,0);
+                eNB_mac_inst[module_idP].frame, eNB_mac_inst[module_idP].subframe,0,0);
       LOG_D(OPT,"[eNB %d][MCH] CC_id %d Frame %d : MAC PDU with size %d\n",
             module_idP, CC_id, frameP, TBS);
     }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index da06e60d252bd8117f90167d8924de4b1276e8bb..ffd9630648d1dd18811f67ee5da965cbd7d14931 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -1006,7 +1006,7 @@ void dump_CCE_table(int *CCE_table,const int nCCE,const unsigned short rnti,cons
   for (i=0;i<nCCE;i++) {
     printf("%1d.",CCE_table[i]);
     if ((i&7) == 7)
-      printf("\n CCE %d: ", i);
+      printf("\n CCE %d: ",i);
   }
 
   Yk = (unsigned int)rnti;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 1add2732257f4bfbb9c34e776cc6407fd3934511..c37224fbfb8e54effc0811311719b1ec1e522c0a 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -93,7 +93,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
   if (opt_enabled == 1) {
-    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP,subframeP, 0,0);
+    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP, frameP, subframeP, 0,0);
     LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
     		  enb_mod_idP, frameP, rntiP, sdu_lenP);
   }
diff --git a/openair2/LAYER2/MAC/extern.h b/openair2/LAYER2/MAC/extern.h
index a0336f3b872246ee49908567c84a03fc51caa3d0..aed8424561c82690379945bab9309c786f475b3f 100644
--- a/openair2/LAYER2/MAC/extern.h
+++ b/openair2/LAYER2/MAC/extern.h
@@ -47,6 +47,8 @@
 
 extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
 //extern uint32_t EBSR_Level[63];
+extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
+//extern uint32_t Extended_BSR_TABLE[63];  ----currently not used 
 
 extern UE_MAC_INST *UE_mac_inst;
 extern eNB_MAC_INST *eNB_mac_inst;
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 0fe9d63b6ff26ba5d03ebe4bb95e004627f2875a..203bd3f36f8a9e24b75bce6627a33bc9ac63f436 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -527,6 +527,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui
 
   mac_xface->phy_config_dedicated_eNB    = phy_config_dedicated_eNB;
   mac_xface->phy_config_dedicated_ue     = phy_config_dedicated_ue;
+  mac_xface->phy_config_harq_ue          = phy_config_harq_ue;
 
   mac_xface->get_lte_frame_parms        = get_lte_frame_parms;
   mac_xface->get_mu_mimo_mode           = get_mu_mimo_mode;
diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h
index 474b73d90ebf8062b7104dbac3a7a40688044139..11fde1f4433436a639e53be96d4b4aaae7c82db4 100644
--- a/openair2/LAYER2/MAC/proto.h
+++ b/openair2/LAYER2/MAC/proto.h
@@ -559,21 +559,6 @@ UE_L2_STATE_t ue_scheduler(
 */
 int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint16_t buflen);
 
-/*! \fn  int get_bsr_lcgid (module_id_t module_idP);
-\brief determine the lcgid for the bsr
-\param[in] Mod_id instance of the UE
-\param[out] lcgid
-*/
-int get_bsr_lcgid (module_id_t module_idP);
-
-/*! \fn  uint8_t get_bsr_len (module_id_t module_idP,uint16_t bufflen);
-\brief determine whether the bsr is short or long assuming that the MAC pdu is built
-\param[in] Mod_id instance of the UE
-\param[in] bufflen size of phy transport block
-\param[out] bsr_len size of bsr control element
-*/
-uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen);
-
 /*! \fn  BSR_SHORT *  get_bsr_short(module_id_t module_idP, uint8_t bsr_len)
 \brief get short bsr level
 \param[in] Mod_id instance of the UE
@@ -590,22 +575,21 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len);
 */
 BSR_LONG * get_bsr_long(module_id_t module_idP, uint8_t bsr_len);
 
-/*! \fn  boolean_t update_bsr(module_id_t module_idP, frame_t frameP, uint8_t lcid)
+/*! \fn  boolean_t update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP)
    \brief get the rlc stats and update the bsr level for each lcid
 \param[in] Mod_id instance of the UE
 \param[in] frame Frame index
-\param[in] lcid logical channel identifier
 */
-boolean_t update_bsr(module_id_t module_idP, frame_t frameP, eNB_index_t eNB_index, uint8_t lcid, uint8_t lcgid);
+boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP,eNB_index_t eNB_index);
 
-/*! \fn  locate (int *table, int size, int value)
+/*! \fn  locate_BsrIndexByBufferSize (int *table, int size, int value)
    \brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table.
 \param[in] *table Pointer to BSR table
 \param[in] size Size of the table
 \param[in] value Value of the buffer
 \return the index in the BSR_LEVEL table
 */
-uint8_t locate (const uint32_t *table, int size, int value);
+uint8_t locate_BsrIndexByBufferSize (const uint32_t *table, int size, int value);
 
 
 /*! \fn  int get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c
index ffc8df479213edd670a323c7c9b68cee519c6991..4d5bb7aad5ad6ea949ef54009163ab5c5e2f46e0 100644
--- a/openair2/LAYER2/MAC/ra_procedures.c
+++ b/openair2/LAYER2/MAC/ra_procedures.c
@@ -272,7 +272,7 @@ void Msg1_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id
 
   if (opt_enabled) {
     trace_pdu(0, NULL, 0, module_idP, 2, UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex,
-              UE_mac_inst[module_idP].subframe, 0, UE_mac_inst[module_idP].RA_attempt_number);
+        UE_mac_inst[module_idP].frame, UE_mac_inst[module_idP].subframe, 0, UE_mac_inst[module_idP].RA_attempt_number);
     LOG_D(OPT,"[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x  with size %d\n",
           module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size);
   }
@@ -296,7 +296,7 @@ void Msg3_tx(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id
 
   if (opt_enabled) { // msg3
     trace_pdu(0, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], UE_mac_inst[module_idP].RA_Msg3_size,
-              module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].subframe, 0, 0);
+              module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].frame, UE_mac_inst[module_idP].subframe, 0, 0);
     LOG_D(OPT,"[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d   with size %d\n",
           module_idP, frameP, UE_mac_inst[module_idP].crnti /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex*/, UE_mac_inst[module_idP].RA_Msg3_size);
   }
@@ -391,7 +391,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
                                 1); //post_padding
           return(&UE_mac_inst[module_idP].RA_prach_resources);
 
-        } else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DCCH] > 0) {
+        } else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) {
           // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example)
           dcch_header_len = 2 + 2;  /// SHORT Subheader + C-RNTI control element
           rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
@@ -412,7 +412,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,
                                             (char *)&ulsch_buff[0]);
 
           LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
-          update_bsr(module_idP, frameP, eNB_indexP,DCCH,UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
+          update_bsr(module_idP, frameP, subframeP,eNB_indexP);
+	      UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] =
+	    		  locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]]);
+
+	      //TO DO: fill BSR infos in UL TBS
+
           //header_len +=2;
           UE_mac_inst[module_idP].RA_active                        = 1;
           UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c
index a637ddf18c436447dd8e76afef066cbb343ef01f..c7bc9120c36809f3dd5957dc67bfeae7f1d8f46e 100644
--- a/openair2/LAYER2/MAC/rar_tools.c
+++ b/openair2/LAYER2/MAC/rar_tools.c
@@ -118,7 +118,7 @@ unsigned short fill_rar(
 
   if (opt_enabled) {
     trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
-              eNB_mac_inst[module_idP].subframe, 0, 0);
+        eNB_mac_inst[module_idP].frame, eNB_mac_inst[module_idP].subframe, 0, 0);
     LOG_D(OPT,"[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and  rapid %d size %d\n",
           module_idP, CC_id, frameP, eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti,
           rarh->RAPID, input_buffer_length);
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index c91c977c3aabb7d961c4cbd95ef59964260ca440..642475a063a25613828f8e35690ca472ed6d01bb 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -70,6 +70,8 @@
 #define DEBUG_HEADER_PARSING 1
 #define ENABLE_MAC_PAYLOAD_DEBUG 1
 
+extern uint8_t usim_test;
+
 /*
 #ifndef USER_MODE
 #define msg debug_msg
@@ -91,7 +93,7 @@ void ue_init_mac(module_id_t module_idP)
   // default values as deined in 36.331 sec 9.2.2
   LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
   //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL;
-  UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
+  UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240;
   UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity;
   UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
   UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
@@ -102,13 +104,19 @@ void ue_init_mac(module_id_t module_idP)
   UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
   UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx=MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
   UE_mac_inst[module_idP].scheduling_info.ttiBundling=0;
+  UE_mac_inst[module_idP].scheduling_info.extendedBSR_Sizes_r10=0;
+  UE_mac_inst[module_idP].scheduling_info.extendedPHR_r10=0;
   UE_mac_inst[module_idP].scheduling_info.drx_config=NULL;
   UE_mac_inst[module_idP].scheduling_info.phr_config=NULL;
-  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF  =  get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer);
-  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF     =  get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
+  // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW.
+  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF  =  MAC_UE_BSR_TIMER_NOT_RUNNING;
+  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF     =  MAC_UE_BSR_TIMER_NOT_RUNNING;
+  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
+  
   UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF =  get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer);
   UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF =  get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer);
   UE_mac_inst[module_idP].scheduling_info.PathlossChange_db =  get_db_dl_PathlossChange(UE_mac_inst[module_idP].scheduling_info.PathlossChange);
+  UE_mac_inst[module_idP].PHR_reporting_active = 0;
 
   for (i=0; i < MAX_NUM_LCID; i++) {
     LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",module_idP,i);
@@ -121,7 +129,8 @@ void ue_init_mac(module_id_t module_idP)
       UE_mac_inst[module_idP].scheduling_info.LCGID[i]=1;
     }
 
-    UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=0;
+    UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=LCID_EMPTY;
+    UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0;
   }
 
 #ifdef CBA
@@ -143,7 +152,7 @@ unsigned char *parse_header(unsigned char *mac_header,
                             unsigned short tb_length)
 {
 
-  unsigned char not_done=1,num_ces=0,num_sdus=0,lcid, num_sdu_cnt;
+  unsigned char not_done=1,num_ces=0,num_cont_res = 0,num_padding = 0,num_sdus=0,lcid, num_sdu_cnt;
   unsigned char *mac_header_ptr = mac_header;
   unsigned short length,ce_len=0;
 
@@ -188,6 +197,7 @@ unsigned char *parse_header(unsigned char *mac_header,
       num_sdus++;
     } else { // This is a control element subheader
       if (lcid == SHORT_PADDING) {
+    	num_padding ++;
         mac_header_ptr++;
       } else {
         rx_ces[num_ces] = lcid;
@@ -197,6 +207,23 @@ unsigned char *parse_header(unsigned char *mac_header,
         if (lcid==TIMING_ADV_CMD) {
           ce_len++;
         } else if (lcid==UE_CONT_RES) {
+
+        	// FNA: check MAC Header is one of thoses defined in Annex B of 36.321
+        	// Check there is only 1 Contention Resolution
+        	if (num_cont_res) {
+        		LOG_W(MAC,"[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n");
+        		// exit parsing
+        		return NULL;
+
+        	}
+
+        	// UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader
+        	if ((not_done == 0) && ((num_sdus) || (num_ces > 1) || (num_padding))) {
+        		LOG_W(MAC,"[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n",num_ces,num_sdus,num_padding);
+        		// exit parsing
+        		return NULL;
+        	}
+          num_cont_res ++;
           ce_len+=6;
         }
       }
@@ -286,6 +313,14 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i
     // notify RRC to relase PUCCH/SRS
     // clear any configured dl/ul
     // initiate RA
+      if (UE_mac_inst[module_idP].scheduling_info.SR_pending){
+          // release all pucch resource
+          UE_mac_inst[module_idP].physicalConfigDedicated = NULL;
+          UE_mac_inst[module_idP].ul_active=0;
+          UE_mac_inst[module_idP].BSR_reporting_active=BSR_TRIGGER_NONE;
+
+          LOG_I(MAC,"[UE %d] Release all SRs \n", module_idP);
+      }
     UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
     UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
     return(0);
@@ -294,12 +329,16 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i
 
 //------------------------------------------------------------------------------
 void
-ue_send_sdu(module_id_t module_idP,
+ue_send_sdu(
+  module_id_t module_idP,
 	    uint8_t CC_id,
 	    frame_t frameP,
 	    uint8_t* sdu,
 	    uint16_t sdu_len,
-	    uint8_t eNB_index) {
+  uint8_t eNB_index
+)
+//------------------------------------------------------------------------------
+{
 
   unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
   unsigned char rx_lcids[NB_RB_MAX];
@@ -313,7 +352,7 @@ ue_send_sdu(module_id_t module_idP,
 
   if (opt_enabled) {
     trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti,
-              UE_mac_inst[module_idP].subframe, 0, 0); 
+        UE_mac_inst[module_idP].frame, UE_mac_inst[module_idP].subframe, 0, 0);
     LOG_D(OPT,"[UE %d][DLSCH] Frame %d trace pdu for rnti %x  with size %d\n",
           module_idP, frameP, UE_mac_inst[module_idP].crnti, sdu_len);
   }
@@ -335,6 +374,8 @@ ue_send_sdu(module_id_t module_idP,
   LOG_T(MAC,"\n");
 #endif
 
+  if (payload_ptr != NULL) {
+
   for (i=0; i<num_ce; i++) {
     //    printf("ce %d : %d\n",i,rx_ces[i]);
     switch (rx_ces[i]) {
@@ -459,6 +500,7 @@ ue_send_sdu(module_id_t module_idP,
     }
     payload_ptr+= rx_lengths[i];
   }
+  } // end if (payload_ptr != NULL)
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
   stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
@@ -491,6 +533,7 @@ void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_i
 	      module_idP,
 	      4,
 	      0xffff,
+	      UE_mac_inst[module_idP].frame,
 	      UE_mac_inst[module_idP].subframe,
 	      0,
 	      0);
@@ -526,6 +569,7 @@ void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_in
 	      module_idP,
 	      4,
 	      P_RNTI,
+		  UE_mac_inst[module_idP].frame,
 	      UE_mac_inst[module_idP].subframe,
 	      0,
 	      0);
@@ -1108,8 +1152,6 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
     *(ce_ptr)     = (long_bsr->Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4);
     *(ce_ptr + 1) = ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr->Buffer_size2 & 0x3C) >> 2);
     *(ce_ptr + 2) = ((long_bsr->Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F);
-    /* Padding */
-    *(ce_ptr + 3) = 0;
     ce_ptr += BSR_LONG_SIZE;
 
     //    printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
@@ -1122,50 +1164,67 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
     LOG_T(MAC,"[UE] sdu subheader %d (lcid %d, %d bytes)\n",i,sdu_lcids[i],sdu_lengths[i]);
 #endif
 
-    if ((first_element>0)) {
-      mac_header_ptr->E = 1;
-#ifdef DEBUG_HEADER_PARSING
-      LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
-            ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
-            ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
-            ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
-#endif
-      mac_header_ptr+=last_size;
-      //      printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
-    } else {
-      first_element=1;
-
+    if ((i == (num_sdus - 1)) && ((short_padding) || (post_padding == 0))) {
+        if (first_element>0) {
+            mac_header_ptr->E = 1;
+      #ifdef DEBUG_HEADER_PARSING
+            LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
+                  ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
+                  ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
+                  ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
+      #endif
+            mac_header_ptr+=last_size;
+        }
+        mac_header_ptr->R    = 0;
+        mac_header_ptr->E    = 0;
+        mac_header_ptr->LCID = sdu_lcids[i];
     }
+    else {
+        if ((first_element>0)) {
+          mac_header_ptr->E = 1;
+    #ifdef DEBUG_HEADER_PARSING
+          LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
+                ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
+                ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
+                ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
+    #endif
+          mac_header_ptr+=last_size;
+          //      printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
+        } else {
+          first_element=1;
 
-    if (sdu_lengths[i] < 128) {
-      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R    = 0; // 3
-      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E    = 0;
-      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F    = 0;
-      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
-      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L    = (unsigned char)sdu_lengths[i];
-      last_size=2;
-#ifdef DEBUG_HEADER_PARSING
-      LOG_D(MAC,"[UE] short sdu\n");
-      LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n",
-            ((uint16_t*)mac_header_ptr)[0],
-            ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R,
-            ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E,
-            ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID,
-            ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F,
-            ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L);
-#endif
-    } else {
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R    = 0;
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E    = 0;
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F    = 1;
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB    = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB    = (unsigned short) sdu_lengths[i]&0xff;
-      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding  = 0x00;
-      last_size=3;
-#ifdef DEBUG_HEADER_PARSING
-      LOG_D(MAC,"[UE] long sdu\n");
-#endif
+        }
+
+        if (sdu_lengths[i] < 128) {
+          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R    = 0; // 3
+          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E    = 0;
+          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F    = 0;
+          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
+          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L    = (unsigned char)sdu_lengths[i];
+          last_size=2;
+    #ifdef DEBUG_HEADER_PARSING
+          LOG_D(MAC,"[UE] short sdu\n");
+          LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n",
+                ((uint16_t*)mac_header_ptr)[0],
+                ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R,
+                ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E,
+                ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID,
+                ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F,
+                ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L);
+    #endif
+        } else {
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R    = 0;
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E    = 0;
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F    = 1;
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB    = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB    = (unsigned short) sdu_lengths[i]&0xff;
+          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding  = 0x00;
+          last_size=3;
+    #ifdef DEBUG_HEADER_PARSING
+          LOG_D(MAC,"[UE] long sdu\n");
+    #endif
+        }
     }
   }
 
@@ -1183,6 +1242,7 @@ unsigned char generate_ulsch_header(uint8_t *mac_header,
     //mac_header_ptr=last_size; // FIXME: should be ++
   }
 
+
   if ((ce_ptr-mac_header_control_elements) > 0) {
     memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements);
     mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
@@ -1205,27 +1265,36 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
 {
 
   mac_rlc_status_resp_t rlc_status;
-  uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0,dtch_header_len_last=0;
-  uint8_t dcch_header_len_tmp=0, dtch_header_len_tmp=0;
-  uint8_t bsr_header_len=0, bsr_ce_len=0, bsr_len=0;
+  uint8_t total_rlc_pdu_header_len=0, rlc_pdu_header_len_last=0 ;
+  uint16_t buflen_remain = 0;
+  uint8_t bsr_len=0,bsr_ce_len=0,bsr_header_len=0;
   uint8_t phr_header_len=0, phr_ce_len=0,phr_len=0;
-  uint8_t lcid=0;
+  uint8_t lcid=0,lcid_rlc_pdu_count=0;
+  boolean_t is_lcid_processed = FALSE;
   uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
   uint8_t sdu_lcids[8]    = { 0, 0, 0, 0, 0, 0, 0, 0 };
   uint8_t payload_offset=0,num_sdus=0;
   uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
   uint16_t sdu_length_total=0;
-  BSR_SHORT bsr_short;
+  BSR_SHORT bsr_short,bsr_truncated;
   BSR_LONG bsr_long;
   BSR_SHORT *bsr_s=&bsr_short;
   BSR_LONG  *bsr_l=&bsr_long;
+  BSR_SHORT *bsr_t=&bsr_truncated;
   POWER_HEADROOM_CMD phr;
   POWER_HEADROOM_CMD *phr_p=&phr;
-  unsigned short short_padding=0, post_padding=0;
-  int lcgid;
+  unsigned short short_padding=0, post_padding=0, padding_len=0;
   int j; // used for padding
   // Compute header length
+  int lcg_id = 0;
+  int lcg_id_bsr_trunc = 0;
+  int highest_priority = 16;
+  int num_lcg_id_with_data = 0;
+  
+  LOG_D(MAC,"[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n",
+                        module_idP, frameP, subframe, buflen);
 
+  
   if (CC_id>0) {
     LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
     mac_xface->macphy_exit("MAC FATAL  CC_id>0");
@@ -1253,33 +1322,76 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
   }
 
 #endif
-  dcch_header_len=2;//sizeof(SCH_SUBHEADER_SHORT);
-  dcch1_header_len=2;//sizeof(SCH_SUBHEADER_SHORT);
-  // hypo length,in case of long header skip the padding byte
-  dtch_header_len=(buflen > 128 ) ? 3 : 2 ; //sizeof(SCH_SUBHEADER_LONG)-1 : sizeof(SCH_SUBHEADER_SHORT);
-  bsr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
+  bsr_header_len = 0;
   phr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
-  phr_ce_len = (UE_mac_inst[module_idP].PHR_reporting_active == 1) ? 1 /* sizeof(POWER_HEADROOM_CMD)*/: 0;
 
-  if (phr_ce_len > 0) {
+  while (lcg_id < MAX_NUM_LCGID) {
+     if  (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]){
+         num_lcg_id_with_data ++;
+     }
+     lcg_id ++;
+  }
+
+  if (num_lcg_id_with_data){
+      LOG_D(MAC,"[UE %d] MAC Tx data pending at frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n",
+                            module_idP,
+                            frameP,
+                            subframe,
+                            num_lcg_id_with_data,
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0],
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1],
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2],
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3],
+                            UE_mac_inst[module_idP].BSR_reporting_active, buflen);
+
+  }
+  //Restart ReTxBSR Timer at new grant indication (36.321)
+  if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING){
+      UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
+  }
+
+  // periodicBSR-Timer expires, trigger BSR
+  if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity)
+            && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)){
+        // Trigger BSR Periodic
+      UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PERIODIC;
+
+      LOG_D(MAC,"[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n",
+                       module_idP, frameP, subframe, buflen);
+
+    }
+
+  //Compute BSR Length if Regular or Periodic BSR is triggered
+  //WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx
+  if (UE_mac_inst[module_idP].BSR_reporting_active){
+
+	  AssertFatal ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_PADDING) == 0 , "Inconsistent BSR Trigger=%d !\n",
+			  UE_mac_inst[module_idP].BSR_reporting_active);
+
+      if (buflen >= 4){
+    	  //A Regular or Periodic BSR can only be sent if TBS >= 4 as transmitting only a BSR is not allowed if UE has data to transmit
+    	  bsr_header_len = 1;
+
+          if (num_lcg_id_with_data <= 1){
+              bsr_ce_len = sizeof(BSR_SHORT); //1 byte
+          }
+          else{
+              bsr_ce_len = BSR_LONG_SIZE; //3 bytes
+          }
+      }
+  }
+
+  bsr_len = bsr_ce_len + bsr_header_len;
+
+  phr_ce_len = (UE_mac_inst[module_idP].PHR_reporting_active == 1) ? 1 /* sizeof(POWER_HEADROOM_CMD)*/: 0;
+  if ((phr_ce_len > 0) && ((phr_ce_len + phr_header_len + bsr_len) <= buflen)){
     phr_len = phr_ce_len + phr_header_len;
     LOG_D(MAC,"[UE %d] header size info: PHR len %d (ce%d,hdr%d) buff_len %d\n",
           module_idP, phr_len, phr_ce_len, phr_header_len, buflen);
   } else {
     phr_len=0;
-  }
-
-  bsr_ce_len = get_bsr_len (module_idP, buflen-phr_len);
-
-  if (bsr_ce_len > 0 ) {
-    bsr_len = bsr_ce_len + bsr_header_len;
-    LOG_D(MAC,"[UE %d] header size info: dcch %d, dcch1 %d, dtch %d, bsr (ce%d,hdr%d) buff_len %d\n",
-          module_idP, dcch_header_len,dcch1_header_len,dtch_header_len, bsr_ce_len, bsr_header_len, buflen);
-  } else {
-    bsr_len=0;
-    //LOG_D(MAC,"[UE %d] Empty buffers, send a long BSR to reset the bsr at eNB \n ",Mod_id);
-    //    bsr_ce_len = sizeof(BSR_LONG);
-    //bsr_len = bsr_ce_len + bsr_header_len;
+    phr_header_len = 0;
+    phr_ce_len = 0;
   }
 
   // check for UL bandwidth requests and add SR control element
@@ -1287,164 +1399,308 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
   // check for UL bandwidth requests and add SR control element
 
   // Check for DCCH first
+// TO DO: Unrool the loop to do it at least once to avoid the if num_sdu
+for (lcid=DCCH; lcid < DTCH ; lcid++) {
+  if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) {
 
-  if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH] == LCID_NOT_EMPTY) {
-
-    rlc_status = mac_rlc_status_ind(module_idP, 
-				    UE_mac_inst[module_idP].crnti, 
-				    eNB_index, 
-				    frameP,
-				    ENB_FLAG_NO,
-				    MBMS_FLAG_NO, // eNB_index
-                                    DCCH,
-                                    (buflen-dcch_header_len-bsr_len-phr_len));
-    LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to "
-          "send (Transport Block size %d, mac header len %d)\n",
-          module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch_header_len);
-
-    sdu_lengths[0] += mac_rlc_data_req(module_idP, 
-				       UE_mac_inst[module_idP].crnti,
-				       eNB_index,
-				       frameP,
-				       ENB_FLAG_NO, 
-				       MBMS_FLAG_NO,
-                                       DCCH,
-                                       (char *)&ulsch_buff[sdu_lengths[0]]);
-
-    sdu_length_total += sdu_lengths[0];
-    sdu_lcids[0] = DCCH;
-    LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
-    num_sdus = 1;
-    update_bsr(module_idP, frameP, eNB_index, DCCH, UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
-    //header_len +=2;
-  } else {
-    dcch_header_len=0;
-    num_sdus = 0;
-  }
-
-  // if the RLC AM is used, then RLC will only provide 2 bytes for ACK
-  // in this case, we sould add bsr
-
-  // DCCH1
-  if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH1] == LCID_NOT_EMPTY) {
-
-    rlc_status = mac_rlc_status_ind(module_idP, 
-				    UE_mac_inst[module_idP].crnti, 
-				    eNB_index,
-				    frameP,
-				    ENB_FLAG_NO,
-				    MBMS_FLAG_NO, // eNB_index
-                                    DCCH1,
-                                    (buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-sdu_length_total));
-
-    LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH1 -> ULSCH, RRC message has %d bytes to"
-          " send (Transport Block size %d, mac header len %d)\n",
-          module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch1_header_len);
-
-    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 
-					     UE_mac_inst[module_idP].crnti,
-					     eNB_index,
-					     frameP,
-					     ENB_FLAG_NO,
-					     MBMS_FLAG_NO,
-					     DCCH1,
-					     (char *)&ulsch_buff[sdu_lengths[num_sdus]]);
-    sdu_length_total += sdu_lengths[num_sdus];
-    sdu_lcids[num_sdus] = DCCH1;
-    LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH1\n",module_idP,sdu_lengths[num_sdus]);
-    num_sdus++;
-    //update_bsr(module_idP, frameP, DCCH1);
-    //dcch_header_len +=2; // include dcch1
-  } else {
-    dcch1_header_len =0;
-  }
+      is_lcid_processed = FALSE;
+      lcid_rlc_pdu_count = 0;
 
-  dtch_header_len=0;
-  dtch_header_len_last=0;
-  for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){
-    dtch_header_len+=3; 
-    dtch_header_len_last=3;
-    
-    if ((UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) &&
-	((bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len+sdu_length_total) <= buflen)) {
-
-    // optimize the dtch header lenght
-    //if ((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] > 128) &&
-    /*   if (((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] >= 128) &&
-    ((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH]+bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len) > buflen)&&
-    buflen >=128 ))
-    dtch_header_len = 3;//sizeof(SCH_SUBHEADER_LONG);
-    else
-    dtch_header_len = 2;//sizeof(SCH_SUBHEADER_SHORT);
-     */
-      rlc_status = mac_rlc_status_ind(module_idP, 
-				      UE_mac_inst[module_idP].crnti, 
-				      eNB_index,
-				      frameP,
-				      ENB_FLAG_NO,
-				      MBMS_FLAG_NO, // eNB_index
-				      lcid,
-				      buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total);
-
-      LOG_D(MAC,"[UE %d] Frame %d : UL-DTCH -> ULSCH%d, %d bytes to send (Transport Block size %d, mac header len %d, BSR byte[%d] %d)\n",
-	    module_idP,frameP, lcid, rlc_status.bytes_in_buffer,buflen,dtch_header_len,
-	    lcid, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcid]);
-      
-       if (rlc_status.bytes_in_buffer > 0) {
-	 sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
-						  UE_mac_inst[module_idP].crnti,
-						  eNB_index,
-						  frameP, 
-						  ENB_FLAG_NO, 
-						  MBMS_FLAG_NO, // eNB_index
-						  lcid,
-						  (char *)&ulsch_buff[sdu_length_total]);
-	 
-	 //adjust dtch header
-	 LOG_D(MAC,"[UE %d] TX Got %d bytes for DTCH\n",module_idP,sdu_lengths[num_sdus]);
-	 sdu_lcids[num_sdus] = lcid;
-	 sdu_length_total += sdu_lengths[num_sdus];
-	 if (sdu_lengths[num_sdus] < 128) {
-	   dtch_header_len --;
-	   dtch_header_len_last --;
-	 }
-	 num_sdus++;
-	 UE_mac_inst[module_idP].ul_active = update_bsr(module_idP, frameP, eNB_index,lcid, UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]);
-       } else {
-	 dtch_header_len -= 3;
-       }
-    } else { // no rlc pdu : generate the dummy header
-      dtch_header_len -= 3;
-    }
+      //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
+      //Adjust at the end of the loop
+      while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
+
+    	  // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU
+    	  if ((usim_test == 0) && (lcid == DCCH1) && (lcid_rlc_pdu_count == 0) && (num_sdus)) {
+
+    		  // Skip SRB2 multiplex if at least one SRB1 SDU is already multiplexed
+    		  break;
+    	  }
+
+          buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
+
+          rlc_status = mac_rlc_status_ind(module_idP,
+                          UE_mac_inst[module_idP].crnti,
+                          eNB_index,
+                          frameP,
+                          ENB_FLAG_NO,
+                          MBMS_FLAG_NO, // eNB_index
+                                          lcid,
+                                          buflen_remain);
+
+          // Workaround for BO issue in RLC AM ReTx : RLC BO can not be bigger than stored MAC BO
+          if (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] <  rlc_status.bytes_in_buffer) {
+
+        	  LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d\n",
+        	                          module_idP,frameP,subframe,
+									  lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count);
+
+        	  // Skip multiplexing for the LCID
+        	  break;
+          }
+
+          /*
+          AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >=  rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d Frame %d Subrame %d\n",
+                  lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe);
+                  */
+
+          if (rlc_status.bytes_in_buffer > 0) {
+
+
+          LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RLC SRB%d has %d bytes to "
+                "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n",
+                module_idP,frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);
+
+
+          sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+                             UE_mac_inst[module_idP].crnti,
+                             eNB_index,
+                             frameP,
+                             ENB_FLAG_NO,
+                             MBMS_FLAG_NO,
+                                             lcid,
+                                             (char *)&ulsch_buff[sdu_length_total]);
+
+
+            AssertFatal (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n",
+                    lcid,sdu_lengths[num_sdus],UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]);
+
+
+
+          sdu_length_total += sdu_lengths[num_sdus];
+          sdu_lcids[num_sdus] = lcid;
+          LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for SRB%d\n",module_idP,sdu_lengths[num_sdus],lcid);
+          //header_len +=2;
+          // update LCID remain buffer
+          UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] -= sdu_lengths[num_sdus];
+          /* Update BSR : substract transmitted data */
+          if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] >= sdu_lengths[num_sdus]){
+              UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] -= sdu_lengths[num_sdus] ;
+          }
+          else {
+              LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Buffer occupancy =%d for LCGID%d is lower than data transmitted=%d for LCID%d\n",
+                        module_idP,frameP,subframe,
+                        UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],
+                        UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],
+                        sdu_lengths[num_sdus],lcid);
+              UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0;
+          }
+
+          //Update the number of LCGID with data as BSR shall reflect status after BSR transmission
+          if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0))
+          {
+              num_lcg_id_with_data --;
+              // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1
+              if ((bsr_len) && (num_lcg_id_with_data == 1))
+              {
+                  bsr_ce_len = sizeof(BSR_SHORT);
+                  bsr_len = bsr_ce_len + bsr_header_len;
+              }
+
+          }
+
+          if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) {
+              //No more remaining TBS after this PDU
+              //exit the function
+              rlc_pdu_header_len_last = 1;
+              is_lcid_processed = TRUE;
+          }
+          else {
+              rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ;
+
+              //Change to 1 byte if it does not fit in the TBS, ie last PDU
+              if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) {
+                  rlc_pdu_header_len_last = 1;
+                  is_lcid_processed = TRUE;
+              }
+          }
+
+          //Update number of SDU
+          num_sdus ++;
+
+          //Update total MAC Header size for RLC PDUs and save last one
+          total_rlc_pdu_header_len += rlc_pdu_header_len_last;
+
+          } //end if (rlc_status.bytes_in_buffer > 0)
+          else {
+              // Switch to next LCID or exit the whole loop
+              is_lcid_processed = TRUE;
+          }
+          lcid_rlc_pdu_count ++;
+   }
+
+    UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY;
+   }
+}
+
+
+// Now Check for DTCH first
+// TO DO: do it according to Logical Channel Prioritization if at least 2 DTCH
+for (lcid=DTCH; lcid < MAX_NUM_LCID ; lcid++) {
+if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) {
+
+    is_lcid_processed = FALSE;
+    lcid_rlc_pdu_count = 0;
+
+    //Multiplex all available DTCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
+    //Adjust at the end of the loop
+    while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
+
+        buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
+
+        rlc_status = mac_rlc_status_ind(module_idP,
+                        UE_mac_inst[module_idP].crnti,
+                        eNB_index,
+                        frameP,
+                        ENB_FLAG_NO,
+                        MBMS_FLAG_NO, // eNB_index
+                                        lcid,
+                                        buflen_remain);
+
+        // Workaround for BO issue in RLC AM ReTx : RLC BO can not be bigger than stored MAC BO
+        if (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] <  rlc_status.bytes_in_buffer) {
+
+      	  LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d\n",
+      	                          module_idP,frameP,subframe,
+									  lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count);
+
+      	  // Skip multiplexing for the LCID
+      	  break;
+        }
+
+        /*
+        AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >=  rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d Frame %d Subrame %d\n",
+                  lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe);
+        */
+
+        if (rlc_status.bytes_in_buffer > 0) {
+
+
+        LOG_D(MAC, "[UE %d] Frame %d : UL-DTCH -> ULSCH, RLC LCID%d has %d bytes to "
+              "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n",
+              module_idP,frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);
+
+
+        sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+                           UE_mac_inst[module_idP].crnti,
+                           eNB_index,
+                           frameP,
+                           ENB_FLAG_NO,
+                           MBMS_FLAG_NO,
+                                           lcid,
+                                           (char *)&ulsch_buff[sdu_length_total]);
+
+        AssertFatal (sdu_lengths[num_sdus] < MAX_ULSCH_PAYLOAD_BYTES, "LCID=%d RLC PDU size = %d is too big\n",
+                lcid,sdu_lengths[num_sdus]);
+
+
+          AssertFatal (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n",
+                  lcid,sdu_lengths[num_sdus],UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]);
+
+
+
+        sdu_length_total += sdu_lengths[num_sdus];
+        sdu_lcids[num_sdus] = lcid;
+        LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LCID%d\n",module_idP,sdu_lengths[num_sdus],lcid);
+        //header_len +=2;
+        // update LCID remain buffer
+        UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] -= sdu_lengths[num_sdus];
+        /* Update BSR : substract transmitted data */
+        if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] >= sdu_lengths[num_sdus]){
+            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] -= sdu_lengths[num_sdus] ;
+        }
+        else {
+            LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Buffer occupancy =%d for LCGID%d is lower than data transmitted=%d for LCID%d\n",
+                      module_idP,frameP,subframe,
+                      UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],
+                      UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],
+                      sdu_lengths[num_sdus],lcid);
+            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0;
+        }
+
+        //Update the number of LCGID with data as BSR shall reflect status after BSR transmission
+        if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0))
+        {
+            num_lcg_id_with_data --;
+            // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1
+            if ((bsr_len) && (num_lcg_id_with_data == 1))
+            {
+                bsr_ce_len = sizeof(BSR_SHORT);
+                bsr_len = bsr_ce_len + bsr_header_len;
+            }
+
+        }
+
+        if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) {
+            //No more remaining TBS after this PDU
+            //exit the function
+            rlc_pdu_header_len_last = 1;
+            is_lcid_processed = TRUE;
+        }
+        else {
+            rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ;
+
+            //Change to 1 byte if it does not fit in the TBS, ie last PDU
+            if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) {
+                rlc_pdu_header_len_last = 1;
+                is_lcid_processed = TRUE;
+            }
+        }
+
+        //Update number of SDU
+        num_sdus ++;
+
+        //Update total MAC Header size for RLC PDUs and save last one
+        total_rlc_pdu_header_len += rlc_pdu_header_len_last;
+
+        } //end if (rlc_status.bytes_in_buffer > 0)
+        else {
+            // Switch to next LCID or exit the whole loop
+            is_lcid_processed = TRUE;
+        }
+        lcid_rlc_pdu_count ++;
+ }
+
+  UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY;
+ }
+}
+
+  //lcgid= get_bsr_lcgid(module_idP);
+
+  // Compute BSR Values and update Nb LCGID with data after multiplexing
+  num_lcg_id_with_data = 0;
+  lcg_id_bsr_trunc = 0;
+  for (lcg_id=0;lcg_id<MAX_NUM_LCGID;lcg_id++){
+      UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]);
+
+      if  (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]){
+          num_lcg_id_with_data ++;
+          lcg_id_bsr_trunc = lcg_id;
+      }
   }
-  
-  lcgid= get_bsr_lcgid(module_idP);
-
-  if (lcgid < 0 ) {
-    bsr_s = NULL;
-    bsr_l = NULL ;
-  } else if ((lcgid ==MAX_NUM_LCGID) && (bsr_ce_len == sizeof(BSR_LONG))) {
-    bsr_s = NULL;
-    bsr_l->Buffer_size0 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0];
-    bsr_l->Buffer_size1 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1];
-    bsr_l->Buffer_size2 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2];
-    bsr_l->Buffer_size3 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3];
-    LOG_D(MAC, "[UE %d] Frame %d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", module_idP,frameP,
-          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0],
-          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1],
-          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2],
-          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]);
-  } else if (bsr_ce_len == sizeof(BSR_SHORT)) {
-    bsr_l = NULL;
-    bsr_s->LCGID = lcgid;
-    bsr_s->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcgid];
-    LOG_D(MAC,"[UE %d] Frame %d report SHORT BSR with level %d for LCGID %d\n",
-          module_idP, frameP, UE_mac_inst[module_idP].scheduling_info.BSR[lcgid],lcgid);
-  } else {
-    bsr_s = NULL;
-    bsr_l = NULL;
+
+
+  if (bsr_ce_len) {
+      //Print updated BSR when sent
+      LOG_D(MAC,"[UE %d] Remaining Buffer after Tx frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n",
+                            module_idP,
+                            frameP,
+                            subframe,
+                            num_lcg_id_with_data,
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0],
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1],
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2],
+                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3],
+                            UE_mac_inst[module_idP].BSR_reporting_active, buflen);
+
+      LOG_D(MAC,"[UE %d] Frame %d Subframe %d TX BSR Regular or Periodic size=%d BSR0=%d BSR1=%d BSR2=%d BSR3=%d\n",module_idP,frameP,subframe,bsr_ce_len,
+              UE_mac_inst[module_idP].scheduling_info.BSR[0],
+              UE_mac_inst[module_idP].scheduling_info.BSR[1],
+              UE_mac_inst[module_idP].scheduling_info.BSR[2],
+              UE_mac_inst[module_idP].scheduling_info.BSR[3]);
   }
 
+
   // build PHR and update the timers
   if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
     phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
@@ -1458,37 +1714,146 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
 
   LOG_T(MAC,"[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n",  module_idP,frameP,bsr_s, bsr_l, phr_p);
 
-  if (dtch_header_len == 0 )
-    dtch_header_len_last =0;
-
-  // adjust the header length
-  dcch_header_len_tmp = dcch_header_len;
-  dtch_header_len_tmp = dtch_header_len;
 
-  if (dtch_header_len==0) {
-    dcch_header_len = (dcch_header_len>0)? 1: dcch_header_len;
-  } else {
-    dtch_header_len_last-=1; 
-    dtch_header_len= (dtch_header_len >0)? dtch_header_len - dtch_header_len_last : dtch_header_len;   
-  }
-
-  if ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) <= 2) {
-    short_padding = buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total;
+  // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order
+  // Check for max padding size, ie MAC Hdr for last RLC PDU = 1
+  /* For Padding BSR:
+     -	if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader:
+         -	if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission;
+         -	else report Short BSR.
+     -	else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR.
+   */
+  if (sdu_length_total) {
+      padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - rlc_pdu_header_len_last + sdu_length_total + 1);
+  }
+  else {
+      padding_len = buflen - (bsr_len + phr_len);
+  }
+
+
+   if ((padding_len) && (bsr_len == 0))
+   {
+	   /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR*/
+     if (padding_len >= (1+BSR_LONG_SIZE))
+     {
+    	 bsr_ce_len = BSR_LONG_SIZE;
+    	 bsr_header_len = 1;
+         // Trigger BSR Padding
+       UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PADDING;
+
+
+     } else if (padding_len >= (1+sizeof(BSR_SHORT))) {
+    	 bsr_ce_len = sizeof(BSR_SHORT);
+    	 bsr_header_len = 1;
+
+    	 if (num_lcg_id_with_data > 1)
+    	 {
+    	  // REPORT TRUNCATED BSR
+       	  //Get LCGID of highest priority LCID with data
+    		 for (lcid=DCCH; lcid < MAX_NUM_LCID ; lcid++) {
+    			 if (UE_mac_inst[module_idP].logicalChannelConfig[lcid] != NULL) {
+        			 lcg_id = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid];
+
+        			 if ((lcg_id < MAX_NUM_LCGID) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id])
+        					 && (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority)) {
+        				 highest_priority = UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority;
+        				 lcg_id_bsr_trunc = lcg_id;
+        			 }
+    			 }
+    		 }
+    	 }
+    	 else
+    	 {
+    		 //Report SHORT BSR, clear bsr_t
+    		 bsr_t = NULL;
+    	 }
+
+       // Trigger BSR Padding
+       UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PADDING;
+     }
+ 	 bsr_len = bsr_header_len + bsr_ce_len;
+   }
+
+   //Fill BSR Infos
+   if (bsr_ce_len == 0 ) {
+     bsr_s = NULL;
+     bsr_l = NULL;
+     bsr_t = NULL;
+   } else if (bsr_ce_len == BSR_LONG_SIZE) {
+     bsr_s = NULL;
+     bsr_t = NULL;
+     bsr_l->Buffer_size0 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0];
+     bsr_l->Buffer_size1 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1];
+     bsr_l->Buffer_size2 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2];
+     bsr_l->Buffer_size3 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3];
+
+     LOG_D(MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", module_idP,frameP,subframe,
+    	   UE_mac_inst[module_idP].BSR_reporting_active,
+           UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0],
+           UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1],
+           UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2],
+           UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]);
+
+   } else if (bsr_ce_len == sizeof(BSR_SHORT)) {
+     bsr_l = NULL;
+     if ((bsr_t != NULL) && (UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_PADDING)) {
+    	 //Truncated BSR
+    	 bsr_s = NULL;
+    	 bsr_t->LCGID = lcg_id_bsr_trunc;
+    	 bsr_t->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc];
+
+         LOG_D(MAC,"[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
+               module_idP, frameP, subframe, UE_mac_inst[module_idP].BSR_reporting_active, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc],lcg_id_bsr_trunc);
+
+     }
+     else
+     {
+    	 bsr_t = NULL;
+         bsr_s->LCGID = lcg_id_bsr_trunc;
+         bsr_s->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc];
+
+         LOG_D(MAC,"[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
+               module_idP, frameP, subframe, UE_mac_inst[module_idP].BSR_reporting_active, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc],lcg_id_bsr_trunc);
+     }
+   }
+
+// 1-bit padding or 2-bit padding  special padding subheader
+// Check for max padding size, ie MAC Hdr for last RLC PDU = 1
+   if (sdu_length_total) {
+       padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - rlc_pdu_header_len_last + sdu_length_total + 1);
+   }
+   else {
+       padding_len = buflen - (bsr_len + phr_len);
+   }
+
+  if (padding_len <= 2) {
+    short_padding = padding_len;
+    // only add padding header
     post_padding = 0;
-  } else {
-    if ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) == buflen) {
+    //update total MAC Hdr size for RLC data
+    if (sdu_length_total) {
+        total_rlc_pdu_header_len = total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1;
+        rlc_pdu_header_len_last = 1;
+   }
+  }
+  else if (sdu_length_total) {
+      post_padding = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
+      // If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding
+      if (post_padding == 0) {
+          total_rlc_pdu_header_len -= rlc_pdu_header_len_last;
+          padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
+          short_padding = padding_len;
+          total_rlc_pdu_header_len ++;
+      }
+  }
+  else {
+    if (padding_len == buflen) {// nona mac pdu
       *access_mode=CANCELED_ACCESS;
     }
 
     short_padding = 0;
 
-    if (dtch_header_len==0) {
-      dcch_header_len = dcch_header_len_tmp;
-    } else {
-      dtch_header_len= dtch_header_len_tmp;
-    }
-
-    post_padding = buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total -1 ;
+    post_padding = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
   }
 
   // Generate header
@@ -1501,33 +1866,64 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
                                          sdu_lcids,    // sdu lcid
                                          phr_p,  // power headroom
                                          NULL,  // crnti
-                                         NULL,  // truncated bsr
+                                         bsr_t,  // truncated bsr
                                          bsr_s, // short bsr
                                          bsr_l,
                                          post_padding); // long_bsr
 
   LOG_D(MAC,
-        "[UE %d] Generate header :bufflen %d  sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,  dcch_header_len %d, dtch_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n",
-        module_idP,buflen, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],payload_offset, dcch_header_len,  dtch_header_len,
+        "[UE %d] Generate header :bufflen %d  sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,  total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n",
+        module_idP,buflen, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],payload_offset, total_rlc_pdu_header_len,
         short_padding,post_padding, bsr_len, phr_len,buflen-sdu_length_total-payload_offset);
   // cycle through SDUs and place in ulsch_buffer
-  memcpy(&ulsch_buffer[payload_offset],ulsch_buff,sdu_length_total);
+  if (sdu_length_total) {
+      memcpy(&ulsch_buffer[payload_offset],ulsch_buff,sdu_length_total);
+  }
 
   // fill remainder of DLSCH with random data
-  for (j=0; j<(buflen-sdu_length_total-payload_offset); j++) {
-    ulsch_buffer[payload_offset+sdu_length_total+j] = (char)(taus()&0xff);
+  if (post_padding) {
+      for (j=0; j<(buflen-sdu_length_total-payload_offset); j++) {
+        ulsch_buffer[payload_offset+sdu_length_total+j] = (char)(taus()&0xff);
+      }
   }
   LOG_D(MAC,"[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n",
         module_idP,payload_offset, sdu_length_total);
   UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
   UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
+
+  /* Actions when a BSR is sent */
+  if (bsr_ce_len)
+  {
+      LOG_D(MAC,"[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n",
+              module_idP, bsr_ce_len, bsr_header_len, buflen);
+
+	  // Reset ReTx BSR Timer
+	  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
+
+	  LOG_D(MAC,"[UE %d] MAC ReTx BSR Timer Reset =%d\n",
+			  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF);
+
+	  // Reset Periodic Timer except when BSR is truncated
+	  if ((bsr_t == NULL) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity))
+	  {
+		  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer);
+
+		  LOG_D(MAC,"[UE %d] MAC Periodic BSR Timer Reset =%d\n",
+				  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF);
+
+	  }
+
+	  // Reset BSR Trigger flags
+	  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
+  }
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT);
   stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
   
   if (opt_enabled) {
-    trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].subframe, 0, 0);
+    trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].frame, UE_mac_inst[module_idP].subframe, 0, 0);
     LOG_D(OPT,"[UE %d][ULSCH] Frame %d trace pdu for rnti %x  with size %d\n",
-          module_idP, UE_mac_inst[module_idP].subframe, UE_mac_inst[module_idP].crnti, buflen);
+          module_idP, UE_mac_inst[module_idP].frame, UE_mac_inst[module_idP].subframe, UE_mac_inst[module_idP].crnti, buflen);
   }
 }
 
@@ -1549,7 +1945,6 @@ ue_scheduler(
   const int            CC_id)
 //------------------------------------------------------------------------------
 {
-
   int lcid; // lcid index
   int TTI= 1;
   int bucketsizeduration = -1;
@@ -1558,6 +1953,7 @@ ue_scheduler(
   // int8_t lcg_id;
   struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL;
   protocol_ctxt_t   ctxt;
+
 #if defined(ENABLE_ITTI)
   MessageDef   *msg_p;
   const char   *msg_name;
@@ -1680,13 +2076,9 @@ ue_scheduler(
   }
 
 
-  // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp.  This should implement the procedures
-  // outlined in Sections 5.4.4 an 5.4.5 of 36.321
-  // Put this in another function
-
   // Get RLC status info and update Bj for all lcids that are active
-  for (lcid=DCCH; lcid <= DTCH; lcid++ ) {
-    if ((lcid == 0) ||(UE_mac_inst[module_idP].logicalChannelConfig[lcid])) {
+  for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++ ) {
+    if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) {
       // meausre the Bj
       if ((directionP == SF_UL)&& (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] >= 0)) {
         if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters) {
@@ -1704,16 +2096,42 @@ ue_scheduler(
         }
       }
 
-      if (update_bsr(module_idP,frameP, eNB_indexP, lcid, UE_mac_inst[module_idP].scheduling_info.LCGID[lcid])) {
-        UE_mac_inst[module_idP].scheduling_info.SR_pending= 1;
-        LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d SR for PUSCH is pending for LCGID %d with BSR level %d (%d bytes in RLC)\n",
-              module_idP, frameP,subframeP,UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],
-              UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],
-              UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);
+      /*
+      if (lcid == DCCH) {    
+        LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d Pending data for SRB1=%d for LCGID %d \n",                  
+        module_idP, frameP,subframeP,UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]],                  
+        UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]);
       }
+      */
     }
   }
 
+  // Call BSR procedure as described in Section 5.4.5 in 36.321
+
+  // First check ReTxBSR Timer because it is always configured
+  // Decrement ReTxBSR Timer if it is running and not null
+  if ((UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING)
+          && (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != 0)){
+      UE_mac_inst[module_idP].scheduling_info.retxBSR_SF --;
+  }
+
+  // Decrement Periodic Timer if it is running and not null
+  if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING)
+            && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != 0)){
+        UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF--;
+    }
+
+  //Check whether Regular BSR is triggered
+  if (update_bsr(module_idP,frameP, subframeP,eNB_indexP) == TRUE) {
+  // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp.  This should implement the procedures
+  // outlined in Sections 5.4.4 an 5.4.5 of 36.321
+    UE_mac_inst[module_idP].scheduling_info.SR_pending= 1;
+    // Regular BSR trigger
+    UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_REGULAR;
+    LOG_D(MAC,"[UE %d][BSR] Regular BSR Triggered Frame %d subframe %d SR for PUSCH is pending\n",
+          module_idP, frameP,subframeP);
+  }
+
   // UE has no valid phy config dedicated ||  no valid/released  SR
   if ((UE_mac_inst[module_idP].physicalConfigDedicated == NULL)) {
     // cancel all pending SRs
@@ -1926,103 +2344,147 @@ int cba_access(module_id_t module_idP,frame_t frameP,sub_frame_t subframe, uint8
 }
 #endif
 
-int get_bsr_lcgid (module_id_t module_idP)
-{
-  int lcgid, lcgid_tmp=-1;
-  int num_active_lcgid = 0;
-
-  for (lcgid = 0 ; lcgid < MAX_NUM_LCGID; lcgid++) {
-    if (UE_mac_inst[module_idP].scheduling_info.BSR[lcgid] > 0 ) {
-      lcgid_tmp = lcgid;
-      num_active_lcgid+=1;
-    }
-  }
-
-  if (num_active_lcgid == 0) {
-    return -1;
-  } else if (num_active_lcgid == 1) {
-    return lcgid_tmp;
-  } else {
-    return MAX_NUM_LCGID;
-  }
-}
-
-uint8_t get_bsr_len (module_id_t module_idP, uint16_t buflen)
-{
-
-  int lcgid=0;
-  uint8_t bsr_len=0,  num_lcgid=0;
-  int pdu = 0;
-
-
-  for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++ ) {
-    if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 ) {
-      pdu += (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] +  bsr_len + 2); //2 = sizeof(SCH_SUBHEADER_SHORT)
-    }
-
-    if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 128 ) { // long header size: adjust the header size
-      pdu += 1;
-    }
-
-    // current phy buff can not transport all sdu for this lcgid -> transmit a bsr for this lcgid
-
-    if ( (pdu > buflen) &&  (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] > 0 ) ) {
-      num_lcgid +=1;
-      bsr_len = (num_lcgid >= 2 ) ? sizeof(BSR_LONG) :  sizeof(BSR_SHORT) ;
-    }
-
-    LOG_D(MAC,"BSR Bytes %d for lcgid %d bsr len %d num lcgid %d\n", UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid], lcgid, bsr_len, num_lcgid);
-  }
-
-  if ( bsr_len > 0 )
-    LOG_D(MAC,"[UE %d] Prepare a %s (Transport Block Size %d, MAC pdu Size %d) \n",
-          module_idP, map_int_to_str(BSR_names, bsr_len), buflen, pdu);
-
-  return bsr_len;
-}
 
-
-boolean_t  update_bsr(module_id_t module_idP, frame_t frameP, eNB_index_t eNB_index, uint8_t lcid, uint8_t lcg_id)
+boolean_t  update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP,eNB_index_t eNB_index)
 {
 
   mac_rlc_status_resp_t rlc_status;
-  boolean_t sr_pending = FALSE;
-
-
-  if ((lcg_id < 0) || (lcg_id >= MAX_NUM_LCGID) ) {
-    return sr_pending;
-  }
-
-  // fixme: need a better way to reset
-  if ((lcid == DCCH) || (lcid == DTCH)) {
-    UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id]=0;
-    UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]=0;
-  }
-
-  //  for (lcid =0 ; lcid < MAX_NUM_LCID; lcid++) {
-  if (UE_mac_inst[module_idP].scheduling_info.LCGID[lcid] == lcg_id) {
-    rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
-                                    lcid,
-                                    0);
-
-    if (rlc_status.bytes_in_buffer > 0 ) {
-      sr_pending = TRUE;
-      UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
-      UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] += locate (BSR_TABLE,BSR_TABLE_SIZE, rlc_status.bytes_in_buffer);
-      UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id] += rlc_status.bytes_in_buffer;
-      // UE_mac_inst[module_idP].scheduling_info.BSR_short_lcid = lcid; // only applicable to short bsr
-      LOG_D(MAC,"[UE %d] BSR level %d (LCGID %d, rlc buffer %d byte)\n",
-            module_idP, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id],lcg_id,  UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]);
-    } else {
-      UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY;
-    }
-  }
-
-  //}
-  return sr_pending;
+  boolean_t bsr_regular_triggered = FALSE;
+  uint8_t lcid;
+  uint8_t lcgid;
+  uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined
+  uint16_t lcgid_buffer_remain[MAX_NUM_LCGID] = {0,0,0,0};
+  int32_t lcid_bytes_in_buffer[MAX_NUM_LCID];
+  /* Array for ordering LCID with data per decreasing priority order */
+  uint8_t lcid_reordered_array[MAX_NUM_LCID]=
+  {MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID,MAX_NUM_LCID};
+  uint8_t pos_next = 0;
+  uint8_t highest_priority = 16;
+  uint8_t array_index = 0;
+
+  // Reset All BSR Infos
+  lcid_bytes_in_buffer[0] = 0;
+  for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++)
+  {
+	  // Reset transmission status
+	  lcid_bytes_in_buffer[lcid] = 0;
+	  UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY;
+  }
+
+  for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++)
+  {
+	  // Reset Buffer Info
+	  UE_mac_inst[module_idP].scheduling_info.BSR[lcgid]=0;
+	  UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid]=0;
+  }
+
+  //Get Buffer Occupancy and fill lcid_reordered_array
+  for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++)
+  {
+	  if (UE_mac_inst[module_idP].logicalChannelConfig[lcid])
+	  {
+		  	lcgid = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid];
+
+		  	// Store already available data to transmit per Group
+		  	if (lcgid < MAX_NUM_LCGID)
+		  	{
+			  	lcgid_buffer_remain[lcgid] += UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid];
+		  	}
+
+		    rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
+		                                    lcid,
+		                                    0);
+
+		    lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer;
+
+		    if (rlc_status.bytes_in_buffer > 0)
+		    {
+		          LOG_D(MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d subframe %d\n",
+		                              module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,subframeP);
+
+		         UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY;
+		         //Update BSR_bytes and position in lcid_reordered_array only if Group is defined
+		         if (lcgid < MAX_NUM_LCGID)
+		         {
+		        	 num_lcid_with_data ++;
+			         // sum lcid buffer which has same lcgid
+			         UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
+
+			         //Fill in the array
+			         array_index = 0;
+			         do
+					{
+			        	 if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority)
+			        	 {
+			        		 //Insert if priority is higher or equal (lower or equal in value)
+			        		 for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--)
+			        		 {
+			        			 lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1];
+
+			        		 }
+			        		 lcid_reordered_array[array_index] = lcid;
+			        		 break;
+
+			        	 }
+			        	 array_index ++;
+					}
+			         while ((array_index < num_lcid_with_data) && (array_index < MAX_NUM_LCID));
+		         }
+		    }
+	  }
+
+  }
+
+  // Check whether a regular BSR can be triggered according to the first cases in 36.321
+  if (num_lcid_with_data)
+  {
+          LOG_D(MAC,"[UE %d] PDCCH Tick at frame %d subframe %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n",
+                            module_idP, frameP, subframeP,num_lcid_with_data,lcid_reordered_array[0],lcid_reordered_array[1],lcid_reordered_array[2]);
+
+	  for (array_index=0; array_index < num_lcid_with_data; array_index++)
+	  {
+		  lcid = lcid_reordered_array[array_index];
+	      /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity
+	         either the data belongs to a logical channel with higher priority than the priorities of the logical channels
+	         which belong to any LCG and for which data is already available for transmission
+	      */
+		  if ((UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] == 0)
+			/* or there is no data available for any of the logical channels which belong to a LCG */
+			||(lcgid_buffer_remain[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)
+			)
+		  {
+			  bsr_regular_triggered = TRUE;
+
+		      LOG_D(MAC,"[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d subframe %d\n",
+		                      module_idP, lcid,UE_mac_inst[module_idP].scheduling_info.LCGID[lcid],frameP, subframeP);
+
+			  break;
+		  }
+	  }
+
+	  // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission
+	  if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF == 0)
+	  {
+		  bsr_regular_triggered = TRUE;
+
+		  if ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_REGULAR) == 0) {
+		        LOG_I(MAC,"[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d subframe %d\n",
+		                          module_idP, frameP, subframeP);
+		  }
+
+	  }
+  }
+
+  //Store Buffer Occupancy in remain buffers for next TTI
+  for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++)
+  {
+	  UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid];
+  }
+
+  return bsr_regular_triggered;
 }
 
-uint8_t locate (const uint32_t *table, int size, int value)
+uint8_t locate_BsrIndexByBufferSize (const uint32_t *table, int size, int value)
 {
 
   uint8_t ju, jm, jl;
@@ -2121,7 +2583,7 @@ int get_sf_periodicBSRTimer(uint8_t sf_offset)
 
   case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity:
   default:
-    return -1;
+    return 0xFFFF;
     break;
   }
 }
diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/vars.h
index 83d159f910a8521e7ebcf1a73692dbeddcd5d670..236439c6e5b732fff57292c5f3e71326974c0ed8 100644
--- a/openair2/LAYER2/MAC/vars.h
+++ b/openair2/LAYER2/MAC/vars.h
@@ -45,6 +45,15 @@ const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57
                                            1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
                                            16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000
                                           };
+// extended bsr table--currently not used										  
+const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,
+                                                     181,223,274,337,414,509,625,769,945,1162,1429,
+                                                     1757,2161,2657,3267,4017,4940,6074,7469,9185,
+                                                     11294,13888,17077,20999,25822,31752,39045,48012,
+                                                     59039,72598,89272,109774,134986,165989,204111,
+                                                     250990,308634,379519,466683,573866,705666,867737,
+                                                     1067031,1312097,1613447,1984009,2439678,3000000,
+                                                     6000000};
 
 //uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index fe85c81de02d93028a1e8f03dce2ce21d6004b50..2ff2d90de96660627be67b0c79711cfc5e4635bf 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -1057,6 +1057,7 @@ rrc_pdcp_config_asn1_req (
 #ifdef Rel10
   ,PMCH_InfoList_r9_t*  const pmch_InfoList_r9_pP
 #endif
+  ,rb_id_t                 *const defaultDRB 
 )
 //-----------------------------------------------------------------------------
 {
@@ -1078,6 +1079,8 @@ rrc_pdcp_config_asn1_req (
 
   hash_key_t      key            = HASHTABLE_NOT_A_KEY_VALUE;
   hashtable_rc_t  h_rc;
+  hash_key_t      key_defaultDRB = HASHTABLE_NOT_A_KEY_VALUE;
+  hashtable_rc_t  h_defaultDRB_rc;
 #ifdef Rel10
   int i,j;
   MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL;
@@ -1098,7 +1101,7 @@ rrc_pdcp_config_asn1_req (
       srb_id = srb2add_list_pP->list.array[cnt]->srb_Identity;
       srb_toaddmod_p = srb2add_list_pP->list.array[cnt];
       rlc_type = RLC_MODE_AM;
-      lc_id = srb_id;// + 2;
+      lc_id = srb_id;
       key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES);
       h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
 
@@ -1194,8 +1197,19 @@ rrc_pdcp_config_asn1_req (
       drb_toaddmod_p = drb2add_list_pP->list.array[cnt];
 
       drb_id = drb_toaddmod_p->drb_Identity;// + drb_id_offset;
+      if (drb_toaddmod_p->logicalChannelIdentity) {
+        lc_id = *(drb_toaddmod_p->logicalChannelIdentity);
+      } else {
+        LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" logicalChannelIdentity is missing in DRB-ToAddMod information element!\n",
+              PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p));
+        continue;
+      }
+
+      if (lc_id == 1 || lc_id == 2) {
+        LOG_E(RLC, PROTOCOL_CTXT_FMT" logicalChannelIdentity = %d is invalid in RRC message when adding DRB!\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id);
+        continue;
+      }
 
-      lc_id = drb_id + 2;
       DevCheck4(drb_id < maxDRB, drb_id, maxDRB, ctxt_pP->module_id, ctxt_pP->rnti);
       key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO);
       h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
@@ -1211,7 +1225,21 @@ rrc_pdcp_config_asn1_req (
         pdcp_p = calloc(1, sizeof(pdcp_t));
         h_rc = hashtable_insert(pdcp_coll_p, key, pdcp_p);
 
-        if (h_rc != HASH_TABLE_OK) {
+        // save the first configured DRB-ID as the default DRB-ID
+        if ((defaultDRB != NULL) && (*defaultDRB == drb_id)) {
+          key_defaultDRB = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag);
+          h_defaultDRB_rc = hashtable_insert(pdcp_coll_p, key_defaultDRB, pdcp_p);
+        } else {
+          h_defaultDRB_rc = HASH_TABLE_OK; // do not trigger any error handling if this is not a default DRB
+        }
+
+        if (h_defaultDRB_rc != HASH_TABLE_OK) {
+          LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD default DRB key 0x%"PRIx64" FAILED\n",
+                PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
+                key_defaultDRB);
+          free(pdcp_p);
+          return TRUE;
+        } else if (h_rc != HASH_TABLE_OK) {
           LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64" FAILED\n",
                 PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p),
                 key);
@@ -1305,7 +1333,6 @@ rrc_pdcp_config_asn1_req (
     for (cnt=0; cnt<drb2release_list_pP->list.count; cnt++) {
       pdrb_id_p = drb2release_list_pP->list.array[cnt];
       drb_id =  *pdrb_id_p;
-      lc_id = drb_id + 2;
       key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_NO);
       h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
 
@@ -1315,6 +1342,7 @@ rrc_pdcp_config_asn1_req (
               drb_id);
         continue;
       }
+      lc_id = pdcp_p->lcid;
 
       action = CONFIG_ACTION_REMOVE;
       pdcp_config_req_asn1 (
@@ -1334,6 +1362,20 @@ rrc_pdcp_config_asn1_req (
         kRRCint_pP,
         kUPenc_pP);
       h_rc = hashtable_remove(pdcp_coll_p, key);
+
+      if ((defaultDRB != NULL) && (*defaultDRB == drb_id)) {
+        // default DRB being removed. nevertheless this shouldn't happen as removing default DRB is not allowed in standard
+        key_defaultDRB = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag);
+        h_defaultDRB_rc = hashtable_get(pdcp_coll_p, key_defaultDRB, (void**)&pdcp_p);
+
+        if (h_defaultDRB_rc == HASH_TABLE_OK) {
+          h_defaultDRB_rc = hashtable_remove(pdcp_coll_p, key_defaultDRB);
+        } else {
+          LOG_E(PDCP, PROTOCOL_CTXT_FMT" PDCP REMOVE FAILED default DRB\n", PROTOCOL_CTXT_ARGS(ctxt_pP));
+        }
+      } else {
+        key_defaultDRB = HASH_TABLE_OK; // do not trigger any error handling if this is not a default DRB
+      }
     }
   }
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index 5bff425abebf488d8926815a81e753f9649202cb..366f79dc9db9a7bf2ca68aa5907781c642c939f6 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -271,6 +271,7 @@ public_pdcp(void rrc_pdcp_config_req (
 * \param[in]  kRRCenc           RRC encryption key
 * \param[in]  kRRCint           RRC integrity key
 * \param[in]  kUPenc            User-Plane encryption key
+* \param[in]  defaultDRB        Default DRB ID
 * \return     A status about the processing, OK or error code.
 */
 public_pdcp(
@@ -286,6 +287,7 @@ public_pdcp(
 #ifdef Rel10
     ,PMCH_InfoList_r9_t  *pmch_InfoList_r9
 #endif
+    ,rb_id_t                 *const defaultDRB 
   ));
 
 /*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t  action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode)
@@ -459,12 +461,25 @@ protected_pdcp(unsigned char          pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];
 protected_pdcp(sdu_size_t             pdcp_input_index_header;)
 protected_pdcp(sdu_size_t             pdcp_input_sdu_size_read;)
 protected_pdcp(sdu_size_t             pdcp_input_sdu_remaining_size_to_read;)
+
 #define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
    ((hash_key_t)mODULE_iD          | \
     (((hash_key_t)(rNTI))   << 8)  | \
     (((hash_key_t)(iS_eNB)) << 24) | \
     (((hash_key_t)(rB_iD))  << 25) | \
-    (((hash_key_t)(iS_sRB)) << 33))
+    (((hash_key_t)(iS_sRB)) << 33) | \
+    (((hash_key_t)(0x55))   << 34))
+
+// hash key to the same PDCP as indexed by PDCP_COLL_KEY_VALUE(... rB_iD, iS_sRB=0) where rB_iD
+// is the default DRB ID. The hidden code 0x55 indicates the key is indexed by (rB_iD,is_sRB)
+// whereas the hidden code 0xaa indicates the key is for default DRB only
+#define PDCP_COLL_KEY_DEFAULT_DRB_VALUE(mODULE_iD, rNTI, iS_eNB) \
+    ((hash_key_t)mODULE_iD          | \
+     (((hash_key_t)(rNTI))   << 8)  | \
+     (((hash_key_t)(iS_eNB)) << 24) | \
+     (((hash_key_t)(0xff))   << 25) | \
+     (((hash_key_t)(0x00))   << 33) | \
+     (((hash_key_t)(0xaa))   << 34))
 
 // service id max val is maxServiceCount = 16 (asn1_constants.h)
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 8f5d0635f04a01f8dac27d86190a4f74d4b3ba3b..fedef42b60c9d10641d3fd884706f9ef85283d38 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -67,6 +67,7 @@ extern int otg_enabled;
 #ifdef PDCP_USE_NETLINK
 #include <sys/socket.h>
 #include <linux/netlink.h>
+#include "NETWORK_DRIVER/UE_IP/constant.h"
 
 extern char nl_rx_buf[NL_MAX_PAYLOAD];
 extern struct sockaddr_nl nas_src_addr, nas_dest_addr;
@@ -186,7 +187,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const  ctxt_pP)
           ret = sendmsg(nas_sock_fd,&nas_msg_tx,0);
 
           if (ret<0) {
-            LOG_D(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno);
+            LOG_E(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno);
       	    MSC_LOG_TX_MESSAGE_FAILED(
       	      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
       	      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
@@ -491,6 +492,10 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
           ctxt.frame         = ctxt_cpy.frame;
           ctxt.enb_flag      = ctxt_cpy.enb_flag;
 
+#ifdef PDCP_DEBUG
+          LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d\n", pdcp_read_header_g.rb_id);
+#endif
+
           if (ctxt_cpy.enb_flag) {
             ctxt.module_id = 0;
             rab_id      = pdcp_read_header_g.rb_id % maxDRB;
@@ -586,11 +591,21 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
             }
           } else { // enb_flag
             if (rab_id != 0) {
-              rab_id = rab_id % maxDRB;
-              key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
-              h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
+              if (rab_id == UE_IP_DEFAULT_RAB_ID) {
+                LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
+                    ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+                key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+                h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
+              } else {
+                rab_id = rab_id % maxDRB;
+                LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n",
+                    ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+                key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
+                h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
+              }
 
               if (h_rc == HASH_TABLE_OK) {
+                rab_id = pdcp_p->rb_id;
 #ifdef PDCP_DEBUG
                 LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
                       ctxt.frame,
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
index 2ff1a6c4b689a44fd8d441225212b473a1ef9011..ded7dc078393adc116d0c0e1ddf5861da94872b9 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
@@ -53,6 +53,7 @@ rlc_am_get_buffer_occupancy_in_bytes (
   uint32_t header_overhead;
 
   // priority of control trafic
+  rlc_pP->status_buffer_occupancy = 0;
   if (rlc_pP->status_requested) {
     if (rlc_pP->t_status_prohibit.running == 0) {
 #if TRACE_RLC_AM_BO
@@ -64,7 +65,7 @@ rlc_am_get_buffer_occupancy_in_bytes (
       }
 
 #endif
-      return ((15  +  rlc_pP->num_nack_sn*(10+1)  +  rlc_pP->num_nack_so*(15+15+1) + 7) >> 3);
+      rlc_pP->status_buffer_occupancy = ((15  +  rlc_pP->num_nack_sn*(10+1)  +  rlc_pP->num_nack_so*(15+15+1) + 7) >> 3);
     }
   }
 
@@ -113,7 +114,8 @@ config_req_rlc_am (
   const protocol_ctxt_t* const ctxt_pP,
   const srb_flag_t             srb_flagP,
   rlc_am_info_t  * const       config_am_pP,
-  const rb_id_t                rb_idP
+  const rb_id_t                rb_idP,
+  const logical_chan_id_t      chan_idP 
 )
 {
   rlc_union_t       *rlc_union_p = NULL;
@@ -135,7 +137,7 @@ config_req_rlc_am (
           config_am_pP->t_reordering,
           config_am_pP->t_status_prohibit);
     rlc_am_init(ctxt_pP, l_rlc_p);
-    rlc_am_set_debug_infos(ctxt_pP, l_rlc_p, srb_flagP, rb_idP);
+    rlc_am_set_debug_infos(ctxt_pP, l_rlc_p, srb_flagP, rb_idP, chan_idP);
     rlc_am_configure(ctxt_pP, l_rlc_p,
                      config_am_pP->max_retx_threshold,
                      config_am_pP->poll_pdu,
@@ -160,7 +162,8 @@ void config_req_rlc_am_asn1 (
   const protocol_ctxt_t* const         ctxt_pP,
   const srb_flag_t                     srb_flagP,
   const struct RLC_Config__am  * const config_am_pP,
-  const rb_id_t                        rb_idP)
+  const rb_id_t                        rb_idP,
+  const logical_chan_id_t              chan_idP)
 {
   rlc_union_t     *rlc_union_p   = NULL;
   rlc_am_entity_t *l_rlc_p         = NULL;
@@ -201,7 +204,7 @@ void config_req_rlc_am_asn1 (
             t_StatusProhibit_tab[config_am_pP->dl_AM_RLC.t_StatusProhibit]);
 
       rlc_am_init(ctxt_pP, l_rlc_p);
-      rlc_am_set_debug_infos(ctxt_pP, l_rlc_p, srb_flagP, rb_idP);
+      rlc_am_set_debug_infos(ctxt_pP, l_rlc_p, srb_flagP, rb_idP, chan_idP);
       rlc_am_configure(ctxt_pP, l_rlc_p,
                        maxRetxThreshold_tab[config_am_pP->ul_AM_RLC.maxRetxThreshold],
                        pollPDU_tab[config_am_pP->ul_AM_RLC.pollPDU],
@@ -338,6 +341,7 @@ rlc_am_get_pdus (
         if (pdu) {
           list_add_tail_eurecom (pdu, &rlc_pP->pdus_to_mac_layer);
           rlc_pP->status_requested = 0;
+          rlc_pP->status_buffer_occupancy = 0;
           rlc_am_start_timer_status_prohibit(ctxt_pP, rlc_pP);
           return;
         }
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
index 5d038dfdbc1ea5eba8f45364f896ecabcbd0052e..61c6a043cc0ba424571e2cba9d662461802563b6 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
@@ -128,31 +128,35 @@ public_rlc_am(void     rlc_am_release (
 * @{
 */
 
-/*! \fn void config_req_rlc_am (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, rlc_am_info_t * config_amP, rb_id_t rb_idP)
+/*! \fn void config_req_rlc_am (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, rlc_am_info_t * config_amP, rb_id_t rb_idP, logical_chan_id_t chan_idP)
 * \brief    Configure the UL and DL parameters of the RLC AM
 * \param[in]  ctxt_pP                   Running context.
 * \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
 * \param[in]  config_amP                Configuration parameters for RLC AM instance.
 * \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier.
 */
 public_rlc_am(void     config_req_rlc_am (
                 const protocol_ctxt_t* const ctxtP,
                 const srb_flag_t  srb_flagP,
                 const rlc_am_info_t * const config_amP,
-                const rb_id_t      rb_idP);)
+                const rb_id_t      rb_idP,
+                const logical_chan_id_t chan_idP);) 
 
-/*! \fn void config_req_rlc_am_asn1 (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, struct RLC_Config__am * config_amP, rb_id_t rb_idP)
+/*! \fn void config_req_rlc_am_asn1 (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, struct RLC_Config__am * config_amP, rb_id_t rb_idP, logical_chan_id_t chan_idP)
 * \brief    Configure the UL and DL parameters of the RLC AM with the asn1c autogenerated pameters structs
 * \param[in]  ctxt_pP                   Running context.
 * \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
 * \param[in]  config_amP                Configuration parameters for RLC AM instance.
 * \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier.
 */
 public_rlc_am(void config_req_rlc_am_asn1 (
                 const protocol_ctxt_t* const ctxtP,
                 const srb_flag_t srb_flagP,
                 const struct RLC_Config__am * const config_amP,
-                const rb_id_t rb_idP);)
+                const rb_id_t rb_idP,
+                const logical_chan_id_t chan_idP);)
 
 /** @} */
 
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c
index d1c3d68c522855a1d75d7ae7bc9efe12dd404778..a7cf302d06758ee5f41f6631c817960ba8b4759c 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c
@@ -246,10 +246,11 @@ rlc_am_set_debug_infos(
   const protocol_ctxt_t* const  ctxt_pP,
   rlc_am_entity_t *const        rlc_pP,
   const srb_flag_t              srb_flagP,
-  const rb_id_t                 rb_idP)
+  const rb_id_t                 rb_idP,
+  const logical_chan_id_t       chan_idP) 
 {
-
   rlc_pP->rb_id         = rb_idP;
+  rlc_pP->channel_id    = chan_idP;
 
   if (srb_flagP) {
     rlc_pP->is_data_plane = 0;
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h
index 52034b7c773da2601d498ed6f9ef9f69bfaa2703..d088f9f0116430ef137d8307bc815e5671c178ad 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.h
@@ -105,13 +105,15 @@ public_rlc_am_init( void rlc_am_configure(const protocol_ctxt_t* const ctxtP,
                     const uint32_t t_reorderingP,
                     const uint32_t t_status_prohibitP);)
 
+
 /*! \fn void rlc_am_set_debug_infos(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const srb_flag_t srb_flagP, const rb_id_t rb_idP)
 * \brief    Set informations that will be displayed in traces, helping the debug process.
 * \param[in]  ctxtP                     Running context.
 * \param[in]  rlc_pP                    RLC AM protocol instance pointer.
 * \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
 * \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier.
 */
-public_rlc_am_init( void rlc_am_set_debug_infos(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const srb_flag_t srb_flagP, const rb_id_t rb_idP);)
+public_rlc_am_init( void rlc_am_set_debug_infos(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const srb_flag_t srb_flagP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP);)
 /** @} */
 #endif
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
index 4bdb3ca00052cbc3bdf0bf2f9cb6ee5001400a97..d0b023833ad24b7fa9fe877d41b6cf446c7740bf 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
@@ -413,8 +413,9 @@ rlc_am_receive_process_data_pdu (
           rlc_am_rx_list_reassemble_rlc_sdus(ctxt_pP, rlc_pP);
         }
 
+        //FNA: fix check VrX out of receiving window
         if (rlc_pP->t_reordering.running) {
-          if ((rlc_pP->vr_x == rlc_pP->vr_r) || ((rlc_am_in_rx_window(ctxt_pP, rlc_pP, pdu_info_p->sn) == 0) && (rlc_pP->vr_x != rlc_pP->vr_mr))) {
+          if ((rlc_pP->vr_x == rlc_pP->vr_r) || ((rlc_am_in_rx_window(ctxt_pP, rlc_pP, rlc_pP->vr_x) == 0) && (rlc_pP->vr_x != rlc_pP->vr_mr))) {
             rlc_am_stop_and_reset_timer_reordering(ctxt_pP, rlc_pP);
           }
         }
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c
index 100802e28c68a629712d0c3ce5f24e3590ea7cdc..e03741707e838a4bf74c796d949d29f24d6495b1 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c
@@ -698,8 +698,8 @@ void rlc_am_v9_3_0_test_tx_rx()
 
   rlc_am_init(&g_am_tx, g_frame);
   rlc_am_init(&g_am_rx, g_frame);
-  rlc_am_set_debug_infos(&g_am_tx, g_frame, 0, 0, 0, 1);
-  rlc_am_set_debug_infos(&g_am_rx, g_frame, 1, 1, 1, 1);
+  rlc_am_set_debug_infos(&g_am_tx, g_frame, 0, 0, 0, 1, 1 /* LC-id = DRB-id */);
+  rlc_am_set_debug_infos(&g_am_rx, g_frame, 1, 1, 1, 1, 1 /* LC-id = DRB-id */);
 
   rlc_am_configure(&g_am_tx, g_frame, max_retx_threshold, poll_pdu, poll_byte, t_poll_retransmit, t_reordering, t_status_prohibit);
   rlc_am_configure(&g_am_rx, g_frame, max_retx_threshold, poll_pdu, poll_byte, t_poll_retransmit, t_reordering, t_status_prohibit);
diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c
index 90fc084e845069c60a6b388edab1ab0e8b4e2382..4d75f3ee30cbd24b086d9728715f886945bb35eb 100644
--- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c
+++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c
@@ -29,7 +29,8 @@ void config_req_rlc_tm (
   const protocol_ctxt_t* const  ctxt_pP,
   const srb_flag_t  srb_flagP,
   const rlc_tm_info_t * const config_tmP,
-  const rb_id_t     rb_idP
+  const rb_id_t rb_idP,
+  const logical_chan_id_t chan_idP
 )
 {
   rlc_union_t     *rlc_union_p  = NULL;
@@ -48,7 +49,7 @@ void config_req_rlc_tm (
 
     rlc_tm_init(ctxt_pP, rlc_p);
     rlc_p->protocol_state = RLC_DATA_TRANSFER_READY_STATE;
-    rlc_tm_set_debug_infos(ctxt_pP, rlc_p, rb_idP, srb_flagP);
+    rlc_tm_set_debug_infos(ctxt_pP, rlc_p, srb_flagP, rb_idP, chan_idP);
     rlc_tm_configure(ctxt_pP, rlc_p, config_tmP->is_uplink_downlink);
   } else {
     LOG_E(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ RB %u RLC NOT FOUND\n",
@@ -144,9 +145,11 @@ void rlc_tm_set_debug_infos(
   const protocol_ctxt_t* const  ctxt_pP,
   rlc_tm_entity_t * const rlcP,
   const srb_flag_t  srb_flagP,
-  const rb_id_t     rb_idP)
+  const rb_id_t     rb_idP,
+  const logical_chan_id_t chan_idP) 
 {
-  rlcP->rb_id     = rb_idP;
+  rlcP->rb_id      = rb_idP;
+  rlcP->channel_id = chan_idP;
 
   if (srb_flagP) {
     rlcP->is_data_plane = 0;
diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h
index f577db47d7ad86ac586830e77855a5bc0b5742f4..0e400a48adc6172633c6cfc4ec6acd2be5045344 100644
--- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h
+++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h
@@ -73,13 +73,14 @@ typedef volatile struct rlc_tm_info_s {
 * \param[in]  srb_flagP                 Flag to indicate SRB (1) or DRB (0)
 * \param[in]  config_tmP                Configuration parameters for RLC TM instance.
 * \param[in]  rb_idP                    Radio bearer identifier.
-* \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
+* \param[in]  chan_idP                  Transport channel identifier.
 */
 public_rlc_tm_init(   void config_req_rlc_tm (
                         const protocol_ctxt_t* const  ctxt_pP,
                         const srb_flag_t  srb_flagP,
                         const rlc_tm_info_t * const config_tmP,
-                        const rb_id_t     rb_idP);)
+                        const rb_id_t     rb_idP,
+                        const logical_chan_id_t chan_idP);) 
 
 /*! \fn void rlc_tm_init (const protocol_ctxt_t* const  ctxt_pP, rlc_tm_entity_t * const rlcP)
 * \brief    Initialize a RLC TM protocol instance, initialize all variables, lists, allocate buffers for making this instance ready to be configured with protocol configuration parameters. After this initialization the RLC TM protocol instance will be in RLC_NULL_STATE state.
@@ -120,11 +121,14 @@ protected_rlc_tm_init(void rlc_tm_configure(
 * \param[in]  rlcP                      RLC TM protocol instance pointer.
 * \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
 * \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier
 */
 protected_rlc_tm_init(void rlc_tm_set_debug_infos(
                         const protocol_ctxt_t* const  ctxt_pP,
                         rlc_tm_entity_t * const       rlcP,
                         const srb_flag_t              srb_flagP,
-                        const rb_id_t                 rb_idP);)
+                        const rb_id_t                 rb_idP,
+                        const logical_chan_id_t chan_idP);)
+
 /** @} */
 #    endif
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
index 3232399d105bd9936862fd7964f53ea3142d7b32..51440d0bfa33bbd6688374173bb5e2d9ad630f28 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
@@ -426,7 +426,7 @@ rlc_um_rx (const protocol_ctxt_t* const ctxt_pP, void *argP, struct mac_data_ind
 
 //-----------------------------------------------------------------------------
 struct mac_status_resp
-rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP)
+rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP)
 {
   struct mac_status_resp status_resp;
   uint16_t  sdu_size = 0;
@@ -434,6 +434,7 @@ rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP
   int32_t diff_time=0;
   rlc_um_entity_t   *rlc_p = NULL;
   mem_block_t       *mb_p = NULL;
+  unsigned int       max_li_overhead = 0;
 
   status_resp.buffer_occupancy_in_pdus         = 0;
   status_resp.buffer_occupancy_in_bytes        = 0;
@@ -453,7 +454,20 @@ rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP
 
     if ((status_resp.buffer_occupancy_in_bytes > 0) && ((mb_p = list_get_head(&rlc_p->input_sdus)) != NULL)) {
 
-      status_resp.buffer_occupancy_in_bytes += rlc_p->tx_header_min_length_in_bytes;
+        //Fix on full Header size
+        if (enb_flagP == ENB_FLAG_NO)
+        {
+            // compute Length Indicator overhead to inform MAC of maximum full RLC PDU size according to stored SDUs
+            // For UE scheduler
+            // Could be useful for eNB: to be checked
+            if (rlc_p->input_sdus.nb_elements <= 1) {
+                max_li_overhead = 0;
+            } else {
+                unsigned int       num_li = rlc_p->input_sdus.nb_elements - 1;
+                max_li_overhead = num_li + (num_li >> 1) + (num_li & 1);
+            }
+        }
+      status_resp.buffer_occupancy_in_bytes += (rlc_p->tx_header_min_length_in_bytes + max_li_overhead);
       status_resp.buffer_occupancy_in_pdus = rlc_p->input_sdus.nb_elements;
 
       diff_time =   ctxt_pP->frame - ((struct rlc_um_tx_sdu_management *)mb_p->data)->sdu_creation_time;
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
index d87f1e29d03f18e9fcd8fc0d180059e1bc0dbd1e..5951eaf1490c58f9b62cc4fca0aabeb4875ce163 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
@@ -186,7 +186,7 @@ protected_rlc_um( void     rlc_um_rx (const protocol_ctxt_t* const ctxt_pP, rlc_
 * \param[in]  tx_statusP                Transmission status given by MAC on previous MAC transmission of the PDU.
 * \return     The maximum number of bytes that can be served by RLC instance to MAC.
 */
-public_rlc_um(    struct mac_status_resp rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP);)
+public_rlc_um(    struct mac_status_resp rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP, const eNB_flag_t enb_flagP);)
 
 /*! \fn struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP)
 * \brief    Gives PDUs to lower layer MAC.
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 688c8f646dc48d5c741e1346730fb764a4096f19..057be0000d45125d1cb9c454d98df2ae2de92b39 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
@@ -40,7 +40,8 @@ void config_req_rlc_um (
   const protocol_ctxt_t* const ctxt_pP,
   const srb_flag_t      srb_flagP,
   const rlc_um_info_t  * const config_um_pP,
-  const rb_id_t         rb_idP)
+  const rb_id_t           rb_idP,
+  const logical_chan_id_t chan_idP)
 {
   rlc_union_t     *rlc_union_p  = NULL;
   rlc_um_entity_t *rlc_p        = NULL;
@@ -61,7 +62,7 @@ void config_req_rlc_um (
     rlc_um_init(ctxt_pP, rlc_p);
 
     if (rlc_um_fsm_notify_event (ctxt_pP, rlc_p, RLC_UM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) {
-      rlc_um_set_debug_infos(ctxt_pP, rlc_p, srb_flagP, rb_idP);
+      rlc_um_set_debug_infos(ctxt_pP, rlc_p, srb_flagP, rb_idP, chan_idP);
       rlc_um_configure(
         ctxt_pP,
         rlc_p,
@@ -87,7 +88,8 @@ void config_req_rlc_um_asn1 (
   const mbms_service_id_t   mbms_service_idP,
   const UL_UM_RLC_t       * const ul_rlc_pP,
   const DL_UM_RLC_t       * const dl_rlc_pP,
-  const rb_id_t             rb_idP)
+  const rb_id_t             rb_idP,
+  const logical_chan_id_t   chan_idP)
 {
   uint32_t         ul_sn_FieldLength   = 0;
   uint32_t         dl_sn_FieldLength   = 0;
@@ -135,7 +137,7 @@ void config_req_rlc_um_asn1 (
 
 
   if (rlc_um_fsm_notify_event (ctxt_pP, rlc_p, RLC_UM_RECEIVE_CRLC_CONFIG_REQ_ENTER_DATA_TRANSFER_READY_STATE_EVENT)) {
-    rlc_um_set_debug_infos(ctxt_pP,rlc_p, srb_flagP, rb_idP);
+    rlc_um_set_debug_infos(ctxt_pP,rlc_p, srb_flagP, rb_idP, chan_idP);
 
     if (ul_rlc_pP != NULL) {
       switch (ul_rlc_pP->sn_FieldLength) {
@@ -416,14 +418,16 @@ void rlc_um_configure(
 void rlc_um_set_debug_infos(
   const protocol_ctxt_t* const ctxt_pP,
   rlc_um_entity_t * const rlc_pP,
-  const srb_flag_t       srb_flagP,
-  const rb_id_t          rb_idP)
+  const srb_flag_t        srb_flagP,
+  const rb_id_t           rb_idP,
+  const logical_chan_id_t chan_idP) 
 {
   LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [SET DEBUG INFOS] rb_id %d srb_flag %d\n",
         PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP),
         rb_idP,
         srb_flagP);
-  rlc_pP->rb_id         = rb_idP;
+  rlc_pP->rb_id      = rb_idP;
+  rlc_pP->channel_id = chan_idP;
 
   if (srb_flagP) {
     rlc_pP->is_data_plane = 0;
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h
index 97af1cfafa54692d8b02181f8238322d490d3aeb..b6964f9f129f0ad1911fc39891d9a9208e13affd 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h
@@ -77,12 +77,14 @@ typedef volatile struct {
 * \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
 * \param[in]  config_umP                Configuration parameters for RLC UM instance.
 * \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier.
 */
 public_rlc_um_control_primitives(   void config_req_rlc_um (
                                       const protocol_ctxt_t* const ctxt_pP,
                                       const srb_flag_t srb_flagP,
                                       const rlc_um_info_t * const config_umP,
-                                      const rb_id_t rb_idP);)
+                                      const rb_id_t rb_idP,
+                                      const logical_chan_id_t chan_idP);) 
 
 /*! \fn void config_req_rlc_um_asn1 (
  *     const protocol_ctxt_t* const ctxt_pP,
@@ -102,6 +104,7 @@ public_rlc_um_control_primitives(   void config_req_rlc_um (
 * \param[in]  ul_rlc_pP                 Configuration parameters for RLC UM UL instance.
 * \param[in]  dl_rlc_pP                 Configuration parameters for RLC UM DL instance.
 * \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier.
 */
 public_rlc_um_control_primitives(   void config_req_rlc_um_asn1 (
                                       const protocol_ctxt_t* const ctxt_pP,
@@ -111,7 +114,8 @@ public_rlc_um_control_primitives(   void config_req_rlc_um_asn1 (
                                       const mbms_service_id_t  mbms_service_idP,
                                       const UL_UM_RLC_t       * const ul_rlc_pP,
                                       const DL_UM_RLC_t       * const dl_rlc_pP,
-                                      const rb_id_t            rb_idP);)
+                                      const rb_id_t            rb_idP,
+                                      const logical_chan_id_t  chan_idP);)
 
 /*! \fn void rlc_um_init (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP)
 * \brief    Initialize a RLC UM protocol instance, initialize all variables, lists, allocate buffers for making this instance ready to be configured with protocol configuration parameters. After this initialization the RLC UM protocol instance will be in RLC_NULL_STATE state.
@@ -169,13 +173,15 @@ protected_rlc_um_control_primitives(void rlc_um_configure(
 * \brief    Set debug informations for a RLC UM protocol instance, these informations are only for trace purpose.
 * \param[in]  ctxtP                     Running context.
 * \param[in]  rlc_pP                    RLC UM protocol instance pointer.
-* \param[in]  rb_idP                    Radio bearer identifier.
 * \param[in]  srb_flagP                 Flag to indicate signalling radio bearer (1) or data radio bearer (0).
+* \param[in]  rb_idP                    Radio bearer identifier.
+* \param[in]  chan_idP                  Transport channel identifier.
 */
 protected_rlc_um_control_primitives(void rlc_um_set_debug_infos(
                                       const protocol_ctxt_t* const ctxt_pP,
                                       rlc_um_entity_t * const rlc_pP,
                                       const srb_flag_t srb_flagP,
-                                      const rb_id_t rb_idP);)
+                                      const rb_id_t rb_idP,
+                                      const logical_chan_id_t chan_idP);) 
 /** @} */
 #    endif
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
index c01e709b415e50f102894f3e7d944cbf2c022f37..92f18e72d7629e228aa4627dc850b3493d7888d5 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
@@ -188,8 +188,8 @@ void rlc_um_v9_3_0_test_windows_10()
   rlc_um_init(&um1);
   rlc_um_init(&um2);
 
-  rlc_um_set_debug_infos(&um1, g_frame, 0, 0, 0, 1);
-  rlc_um_set_debug_infos(&um2, g_frame, 1, 1, 1, 1);
+  rlc_um_set_debug_infos(&um1, g_frame, 0, 0, 0, 1, 1 /*LC-id = RAB-id*/);
+  rlc_um_set_debug_infos(&um2, g_frame, 1, 1, 1, 1, 1 /*LC-id = RAB-id*/);
 
   rlc_um_configure(&um1, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch);
   rlc_um_configure(&um2, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch);
@@ -242,8 +242,8 @@ void rlc_um_v9_3_0_test_windows_5()
   rlc_um_init(&um1);
   rlc_um_init(&um2);
 
-  rlc_um_set_debug_infos(&um1, g_frame, 0, 0, 0, 1);
-  rlc_um_set_debug_infos(&um2, g_frame, 1, 1, 1, 1);
+  rlc_um_set_debug_infos(&um1, g_frame, 0, 0, 0, 1, 1 /* LC-id = DRB-id */);
+  rlc_um_set_debug_infos(&um2, g_frame, 1, 1, 1, 1, 1 /* LC-id = DRB-id */);
 
   rlc_um_configure(&um1, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch);
   rlc_um_configure(&um2, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch);
@@ -471,9 +471,9 @@ void rlc_um_v9_3_0_test_exchange_pdus(rlc_um_entity_t *um_txP,
   memset(&mac_rlc_status_resp_tx, 0, sizeof(struct mac_status_resp));
   memset(&mac_rlc_status_resp_rx, 0, sizeof(struct mac_status_resp));
 
-  mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, g_frame, 1, bytes_txP, tx_status);
+  mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, g_frame, 1, bytes_txP, tx_status,ENB_FLAG_YES);
   data_request_tx        = rlc_um_mac_data_request(um_txP, g_frame);
-  mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, g_frame, 0, bytes_rxP, tx_status);
+  mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, g_frame, 0, bytes_rxP, tx_status,ENB_FLAG_YES);
   data_request_rx        = rlc_um_mac_data_request(um_rxP, g_frame);
 
 
@@ -517,9 +517,9 @@ void rlc_um_v9_3_0_test_exchange_delayed_pdus(rlc_um_entity_t *um_txP,
   memset(&mac_rlc_status_resp_tx, 0, sizeof(struct mac_status_resp));
   memset(&mac_rlc_status_resp_rx, 0, sizeof(struct mac_status_resp));
 
-  mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, g_frame, 1, bytes_txP, tx_status);
+  mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, g_frame, 1, bytes_txP, tx_status,ENB_FLAG_YES);
   data_request_tx        = rlc_um_mac_data_request(um_txP, g_frame);
-  mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, g_frame, 0, bytes_rxP, tx_status);
+  mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, g_frame, 0, bytes_rxP, tx_status,ENB_FLAG_YES);
   data_request_rx        = rlc_um_mac_data_request(um_rxP, g_frame);
 
 
@@ -614,8 +614,8 @@ void rlc_um_v9_3_0_test_reordering(uint32_t sn_field_lengthP)
   um_info.is_mXch          = 0;
 
   srand (0);
-  config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER);
-  config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER);
+  config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/);
+  config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/);
 
   rlc_um_display_rx_window(&um_tx);
 
@@ -736,8 +736,8 @@ void rlc_um_v9_3_0_test_tx_rx_10(void)
   um_info.is_mXch          = 0;
 
   srand (0);
-  config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER);
-  config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER);
+  config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/);
+  config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/);
 
   rlc_um_display_rx_window(&um_tx);
 
@@ -1065,8 +1065,8 @@ void rlc_um_v9_3_0_test_tx_rx_5(void)
   um_info.is_mXch          = 0;
 
   srand (0);
-  config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER);
-  config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER);
+  config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/);
+  config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/);
 
   rlc_um_display_rx_window(&um_tx);
 
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index ec5ee629b168ee572aec7b34d94b5c632af5d2cd..3fd5b8c3bcfef9cb0f016b1e8db3b00a17102950 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -262,7 +262,18 @@ public_rlc(logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[NUMBER_OF_eNB_MAX][NB_RB_
     (((hash_key_t)(rNTI))   << 8)  | \
     (((hash_key_t)(iS_eNB)) << 24) | \
     (((hash_key_t)(rB_iD))  << 25) | \
-    (((hash_key_t)(iS_sRB)) << 33))
+    (((hash_key_t)(iS_sRB)) << 33) | \
+    (((hash_key_t)(0x05))   << 34))
+
+// index to the same RLC entity as RLC_COLL_KEY_VALUE(), but using LC_id instead
+// the hidden last key indicates if this is a hash-key with RB_id (0x05) or LC_id (0x0a)
+#define RLC_COLL_KEY_LCID_VALUE(eNB_iD, rNTI, iS_eNB, lC_iD, iS_sRB) \
+   ((hash_key_t)eNB_iD             | \
+    (((hash_key_t)(rNTI))   << 8)  | \
+    (((hash_key_t)(iS_eNB)) << 24) | \
+    (((hash_key_t)(lC_iD))  << 25) | \
+    (((hash_key_t)(iS_sRB)) << 33) | \
+    (((hash_key_t)(0x0a))   << 34))
 
 // service id max val is maxServiceCount = 16 (asn1_constants.h)
 
diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c
index cb7357b5e7826ea57587fba43a8acb770b60ddf5..d59b187dc763ea19dca362597393309fb1e03969 100644
--- a/openair2/LAYER2/RLC/rlc_mac.c
+++ b/openair2/LAYER2/RLC/rlc_mac.c
@@ -129,7 +129,6 @@ tbs_size_t mac_rlc_data_req(
 {
   //-----------------------------------------------------------------------------
   struct mac_data_req    data_request;
-  rb_id_t                rb_id           = 0;
   rlc_mode_t             rlc_mode        = RLC_MODE_NONE;
   rlc_mbms_id_t         *mbms_id_p       = NULL;
   rlc_union_t           *rlc_union_p     = NULL;
@@ -172,13 +171,7 @@ tbs_size_t mac_rlc_data_req(
       return (tbs_size_t)0;
     }
   } else {
-    if (channel_idP > 2) {
-      rb_id = channel_idP - 2;
-    } else {
-      rb_id = channel_idP;
-    }
-
-    key = RLC_COLL_KEY_VALUE(module_idP, rntiP, enb_flagP, rb_id, srb_flag);
+    key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
   }
 
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
@@ -187,7 +180,7 @@ tbs_size_t mac_rlc_data_req(
     rlc_mode = rlc_union_p->mode;
   } else {
     rlc_mode = RLC_MODE_NONE;
-    AssertFatal (0 , "RLC not configured rb id %u lcid %u RNTI %x!\n", rb_id, channel_idP, rntiP);
+    AssertFatal (0 , "RLC not configured lcid %u RNTI %x!\n", channel_idP, rntiP);
   }
 
   switch (rlc_mode) {
@@ -237,7 +230,6 @@ void mac_rlc_data_ind     (
   crc_t                    *crcs_pP)
 {
   //-----------------------------------------------------------------------------
-  rb_id_t                rb_id      = 0;
   rlc_mode_t             rlc_mode   = RLC_MODE_NONE;
   rlc_mbms_id_t         *mbms_id_p  = NULL;
   rlc_union_t           *rlc_union_p     = NULL;
@@ -287,13 +279,7 @@ void mac_rlc_data_ind     (
       return;
     }
   } else {
-    if (channel_idP > 2) {
-      rb_id = channel_idP - 2;
-    } else {
-      rb_id = channel_idP;
-    }
-
-    key = RLC_COLL_KEY_VALUE(module_idP, rntiP, enb_flagP, rb_id, srb_flag);
+    key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
   }
 
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
@@ -343,7 +329,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
   mac_rlc_status_resp_t  mac_rlc_status_resp;
   struct mac_status_ind  tx_status;
   struct mac_status_resp status_resp;
-  rb_id_t                rb_id       = 0;
   rlc_mode_t             rlc_mode    = RLC_MODE_NONE;
   rlc_mbms_id_t         *mbms_id_p   = NULL;
   rlc_union_t           *rlc_union_p = NULL;
@@ -392,13 +377,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
 
     key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id);
   } else {
-    if (channel_idP > 2) {
-      rb_id = channel_idP - 2;
-    } else {
-      rb_id = channel_idP;
-    }
-
-    key = RLC_COLL_KEY_VALUE(module_idP, rntiP, enb_flagP, rb_id, srb_flag);
+    key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
   }
 
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
@@ -427,7 +406,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
     break;
 
   case RLC_MODE_UM:
-    status_resp = rlc_um_mac_status_indication(&ctxt, &rlc_union_p->rlc.um, tb_sizeP, tx_status);
+    status_resp = rlc_um_mac_status_indication(&ctxt, &rlc_union_p->rlc.um, tb_sizeP, tx_status, enb_flagP);
     mac_rlc_status_resp.bytes_in_buffer                 = status_resp.buffer_occupancy_in_bytes;
     mac_rlc_status_resp.pdus_in_buffer                  = status_resp.buffer_occupancy_in_pdus;
     mac_rlc_status_resp.head_sdu_creation_time          = status_resp.head_sdu_creation_time;
diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c
index c78a3fa144615dfe73c1da8ec773df2a75c40939..9ef8bd87005280f712203fb4ac8ce9780ade675a 100644
--- a/openair2/LAYER2/RLC/rlc_rrc.c
+++ b/openair2/LAYER2/RLC/rlc_rrc.c
@@ -97,7 +97,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
   if (srb2add_listP != NULL) {
     for (cnt=0; cnt<srb2add_listP->list.count; cnt++) {
       rb_id = srb2add_listP->list.array[cnt]->srb_Identity;
-      lc_id  = rb_id + 2;
+      lc_id = rb_id;
 
       LOG_D(RLC, "Adding SRB %d, rb_id %d\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id);
       srb_toaddmod_p = srb2add_listP->list.array[cnt];
@@ -118,7 +118,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 ctxt_pP,
                 SRB_FLAG_YES,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am,
-                rb_id);
+                rb_id, lc_id);
             } else {
               LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                     PROTOCOL_CTXT_ARGS(ctxt_pP),
@@ -137,7 +137,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 UNUSED_PARAM_MBMS_SERVICE_ID,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.ul_UM_RLC,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.dl_UM_RLC,
-                rb_id);
+                rb_id, lc_id);
             } else {
               LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                     PROTOCOL_CTXT_ARGS(ctxt_pP),
@@ -156,7 +156,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 UNUSED_PARAM_MBMS_SERVICE_ID,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_UL.ul_UM_RLC,
                 NULL,
-                rb_id);
+                rb_id, lc_id);
             } else {
               LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                     PROTOCOL_CTXT_ARGS(ctxt_pP),
@@ -175,7 +175,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 UNUSED_PARAM_MBMS_SERVICE_ID,
                 NULL,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_DL.dl_UM_RLC,
-                rb_id);
+                rb_id, lc_id);
             } else {
               LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                     PROTOCOL_CTXT_ARGS(ctxt_pP),
@@ -209,7 +209,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               ctxt_pP,
               SRB_FLAG_YES,
               &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am,
-              rb_id);
+              rb_id,lc_id);
           } else {
             LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                   PROTOCOL_CTXT_ARGS(ctxt_pP),
@@ -225,7 +225,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               UNUSED_PARAM_MBMS_SERVICE_ID,
               NULL, // TO DO DEFAULT CONFIG
               NULL, // TO DO DEFAULT CONFIG
-              rb_id);
+              rb_id, lc_id);
           } else {
             LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n",
                   PROTOCOL_CTXT_ARGS(ctxt_pP),
@@ -247,9 +247,19 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
       drb_toaddmod_p = drb2add_listP->list.array[cnt];
 
       drb_id = drb_toaddmod_p->drb_Identity;
-      lc_id  = drb_id + 2;
+      if (drb_toaddmod_p->logicalChannelIdentity) {
+        lc_id = *drb_toaddmod_p->logicalChannelIdentity;
+      } else {
+        LOG_E(RLC, PROTOCOL_CTXT_FMT" logicalChannelIdentity is missing from drb-ToAddMod information element!\n", PROTOCOL_CTXT_ARGS(ctxt_pP));
+        continue;
+      }
+
+      if (lc_id == 1 || lc_id == 2) {
+        LOG_E(RLC, PROTOCOL_CTXT_FMT" logicalChannelIdentity = %d is invalid in RRC message when adding DRB!\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id);
+        continue;
+      }
 
-      LOG_I(RLC, "Adding DRB %d, lc_id %d\n",drb_id,lc_id);
+      LOG_D(RLC, "Adding DRB %d, lc_id %d\n",drb_id,lc_id);
 
 
       if (drb_toaddmod_p->rlc_Config) {
@@ -264,7 +274,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               ctxt_pP,
               SRB_FLAG_NO,
               &drb_toaddmod_p->rlc_Config->choice.am,
-              drb_id);
+              drb_id, lc_id);
           }
 
           break;
@@ -279,7 +289,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               UNUSED_PARAM_MBMS_SERVICE_ID,
               &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.ul_UM_RLC,
               &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.dl_UM_RLC,
-              drb_id);
+              drb_id, lc_id);
           }
 
           break;
@@ -294,7 +304,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               UNUSED_PARAM_MBMS_SERVICE_ID,
               &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_UL.ul_UM_RLC,
               NULL,
-              drb_id);
+              drb_id, lc_id);
           }
 
           break;
@@ -309,7 +319,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               UNUSED_PARAM_MBMS_SERVICE_ID,
               NULL,
               &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_DL.dl_UM_RLC,
-              drb_id);
+              drb_id, lc_id);
           }
 
           break;
@@ -393,7 +403,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
           mbms_service_id,
           NULL,
           &dl_um_rlc,
-          rb_id);
+          rb_id, lc_id);
       }
     }
   }
@@ -474,6 +484,8 @@ rlc_op_status_t rrc_rlc_remove_rlc   (
   logical_chan_id_t      lcid            = 0;
   hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
   hashtable_rc_t         h_rc;
+  hash_key_t             key_lcid        = HASHTABLE_NOT_A_KEY_VALUE;
+  hashtable_rc_t         h_lcid_rc;
   rlc_union_t           *rlc_union_p = NULL;
 #ifdef Rel10
   rlc_mbms_id_t         *mbms_id_p  = NULL;
@@ -517,23 +529,49 @@ rlc_op_status_t rrc_rlc_remove_rlc   (
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
 
   if (h_rc == HASH_TABLE_OK) {
+    // also remove the hash-key created by LC-id
+    switch (rlc_union_p->mode) {
+    case RLC_MODE_AM:
+      lcid = rlc_union_p->rlc.am.channel_id;
+      break;
+    case RLC_MODE_UM:
+      lcid = rlc_union_p->rlc.um.channel_id;
+      break;
+    case RLC_MODE_TM:
+      lcid = rlc_union_p->rlc.tm.channel_id;
+      break;
+    default:
+      LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] RLC mode is unknown!\n",
+            PROTOCOL_CTXT_ARGS(ctxt_pP),
+            (srb_flagP) ? "SRB" : "DRB",
+            rb_idP);
+    }
+    key_lcid = RLC_COLL_KEY_LCID_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, lcid, srb_flagP);
+    h_lcid_rc = hashtable_get(rlc_coll_p, key_lcid, (void**)&rlc_union_p);
+  } else {
+    h_lcid_rc = HASH_TABLE_KEY_NOT_EXISTS;
+  }
+
+  if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) {
+    h_lcid_rc = hashtable_remove(rlc_coll_p, key_lcid);
     h_rc = hashtable_remove(rlc_coll_p, key);
-    LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASED %s\n",
+    LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASED %s\n",
           PROTOCOL_CTXT_ARGS(ctxt_pP),
           (srb_flagP) ? "SRB" : "DRB",
-          rb_idP,
+          rb_idP, lcid,
           (srb_flagP) ? "SRB" : "DRB");
-  } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
-    LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASE : RLC NOT FOUND %s\n",
+  } else if ((h_rc == HASH_TABLE_KEY_NOT_EXISTS) || (h_lcid_rc == HASH_TABLE_KEY_NOT_EXISTS)) {
+    LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASE : RLC NOT FOUND %s, by RB-ID=%d, by LC-ID=%d\n",
           PROTOCOL_CTXT_ARGS(ctxt_pP),
           (srb_flagP) ? "SRB" : "DRB",
-          rb_idP,
-          (srb_flagP) ? "SRB" : "DRB");
+          rb_idP, lcid,
+          (srb_flagP) ? "SRB" : "DRB",
+          h_rc, h_lcid_rc);
   } else {
-    LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] RELEASE : INTERNAL ERROR %s\n",
+    LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASE : INTERNAL ERROR %s\n",
           PROTOCOL_CTXT_ARGS(ctxt_pP),
           (srb_flagP) ? "SRB" : "DRB",
-          rb_idP,
+          rb_idP, lcid,
           (srb_flagP) ? "SRB" : "DRB");
   }
 
@@ -551,6 +589,8 @@ rlc_union_t* rrc_rlc_add_rlc   (
   //-----------------------------------------------------------------------------
   hash_key_t             key         = HASHTABLE_NOT_A_KEY_VALUE;
   hashtable_rc_t         h_rc;
+  hash_key_t             key_lcid    = HASHTABLE_NOT_A_KEY_VALUE;
+  hashtable_rc_t         h_lcid_rc;
   rlc_union_t           *rlc_union_p = NULL;
 #ifdef Rel10
   rlc_mbms_id_t         *mbms_id_p  = NULL;
@@ -591,6 +631,7 @@ rlc_union_t* rrc_rlc_add_rlc   (
 #endif
   {
     key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
+    key_lcid = RLC_COLL_KEY_LCID_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, srb_flagP);
   }
 
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
@@ -606,8 +647,9 @@ rlc_union_t* rrc_rlc_add_rlc   (
   } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
     rlc_union_p = calloc(1, sizeof(rlc_union_t));
     h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p);
+    h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p);
 
-    if (h_rc == HASH_TABLE_OK) {
+    if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) {
 #ifdef Rel10
 
       if (MBMS_flagP == TRUE) {
@@ -628,11 +670,12 @@ rlc_union_t* rrc_rlc_add_rlc   (
       rlc_union_p->mode = rlc_modeP;
       return rlc_union_p;
     } else {
-      LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc  FAILED %s\n",
+      LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc FAILED %s (add by RB_id=%d; add by LC_id=%d)\n",
             PROTOCOL_CTXT_ARGS(ctxt_pP),
             (srb_flagP) ? "SRB" : "DRB",
             rb_idP,
-            (srb_flagP) ? "SRB" : "DRB");
+            (srb_flagP) ? "SRB" : "DRB",
+            h_rc, h_lcid_rc);
       free(rlc_union_p);
       rlc_union_p = NULL;
       return NULL;
@@ -689,7 +732,7 @@ rlc_op_status_t rrc_rlc_config_req   (
         ctxt_pP,
         srb_flagP,
         &rlc_infoP.rlc.rlc_am_info,
-        rb_idP);
+        rb_idP, rb_idP);
       break;
 
     case RLC_MODE_UM:
@@ -700,7 +743,7 @@ rlc_op_status_t rrc_rlc_config_req   (
         ctxt_pP,
         srb_flagP,
         &rlc_infoP.rlc.rlc_um_info,
-        rb_idP);
+        rb_idP, rb_idP);
       break;
 
     case RLC_MODE_TM:
@@ -711,7 +754,7 @@ rlc_op_status_t rrc_rlc_config_req   (
         ctxt_pP,
         srb_flagP,
         &rlc_infoP.rlc.rlc_tm_info,
-        rb_idP);
+        rb_idP, rb_idP);
       break;
 
     default:
diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c
index 6bef269de874ce0e60805d6e9c1f1c5ebf82e282..86968015975e09e05e37a6639bdcf6eee3cd6cff 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/common.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/common.c
@@ -99,7 +99,8 @@ ue_ip_common_class_wireless2ip(
   hard_header_len = ue_ip_dev[instP]->hard_header_len;
 
   skb_set_mac_header(skb_p, 0);
-
+  skb_set_network_header(skb_p, hard_header_len);
+skb_p->mark = rb_idP;
   //printk("[NAC_COMMIN_RECEIVE]: Packet Type %d (%d,%d)",skb_p->pkt_type,PACKET_HOST,PACKET_BROADCAST);
   skb_p->pkt_type = PACKET_HOST;
 
@@ -344,7 +345,7 @@ void ue_ip_common_wireless2ip(struct nlmsghdr *nlh_pP)
 
   ue_ip_common_class_wireless2ip(pdcph_p->data_size,
                                  (unsigned char *)NLMSG_DATA(nlh_pP) + UE_IP_PDCPH_SIZE,
-                                 pdcph_p->inst,
+                                 1, //pdcph_p->inst,
                                  pdcph_p->rb_id);
 
 }
diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h
index 8c711e971de8d7fe0a955bcad5ca09904ad63b92..aeab9dfe665d84f25b8143312ec690ebc1aa4065 100644
--- a/openair2/PHY_INTERFACE/defs.h
+++ b/openair2/PHY_INTERFACE/defs.h
@@ -185,6 +185,9 @@ typedef struct {
   void (*phy_config_dedicated_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index,
                                   struct PhysicalConfigDedicated *physicalConfigDedicated);
 
+  /// PHY-Config-harq UE
+  void (*phy_config_harq_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index,
+                             uint16_t max_harq_tx);
   /// Configure Common PHY parameters from SIB1
   void (*phy_config_sib1_ue)(module_id_t Mod_id,int CC_id,uint8_t CH_index,
                              TDD_Config_t *tdd_config,
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index 51136dee195bd91cca2cf9fe8bcf229a9f5f4b93..b4290e8b9de4c61219a8580f9b67f7a9d881c5ae 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -109,6 +109,7 @@ typedef struct xer_sprint_string_s {
 } xer_sprint_string_t;
 
 extern unsigned char NB_eNB_INST;
+extern uint8_t usim_test;
 
 uint16_t two_tier_hexagonal_cellIds[7] = {0,1,2,4,5,7,8};
 uint16_t two_tier_hexagonal_adjacent_cellIds[7][6] = {{1,2,4,5,7,8},    // CellId 0
@@ -1260,7 +1261,10 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin
   rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1,
       sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension));
 
-  rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity=2;
+  if(usim_test == 0)
+      rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 2;
+  else
+      rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1;
 
   rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME =
     NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME));
@@ -1384,6 +1388,7 @@ uint8_t
 do_RRCConnectionSetup(
   const protocol_ctxt_t*     const ctxt_pP,
   rrc_eNB_ue_context_t*      const ue_context_pP,
+  int                              CC_id,
   uint8_t*                   const buffer,
   const uint8_t                    transmission_mode,
   const uint8_t                    Transaction_id,
@@ -1488,7 +1493,10 @@ do_RRCConnectionSetup(
   physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH         = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH));
   physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH         = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
   physicalConfigDedicated2->cqi_ReportConfig              = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL;//CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+  if (enb_properties.properties[ctxt_pP->module_id]->srs_enable[CC_id])
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+  else
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL;
   physicalConfigDedicated2->antennaInfo                   = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo));
   physicalConfigDedicated2->schedulingRequestConfig       = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
 #ifdef CBA
@@ -1574,19 +1582,19 @@ do_RRCConnectionSetup(
     */
 
   //soundingRS-UL-ConfigDedicated
-  /*
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = SoundingRS_UL_ConfigDedicated_PR_setup;
-  assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth,
-        SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0);
-  assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth,
-        SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0);
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0;
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1;
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=1;
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0;
-  assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift,
-        SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0);
-  */
+  if (enb_properties.properties[ctxt_pP->module_id]->srs_enable[CC_id]) {
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = SoundingRS_UL_ConfigDedicated_PR_setup;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth =
+                                                             SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth =
+          SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=45;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0;
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift=
+          SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0;
+  }
 
 
   //AntennaInfoDedicated
@@ -2661,6 +2669,21 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname)
 
     // UE_EUTRA_Capability->measParameters.bandListEUTRA.list.count                         = 0;  // no measurements on other bands
     // UE_EUTRA_Capability->featureGroupIndicators  // null
+
+    // featureGroup is mandatory for CMW tests
+    // featureGroup is filled only for usim-test mode
+    BIT_STRING_t *bit_string;
+    uint32_t     featrG;
+    bit_string = CALLOC(1, sizeof(*bit_string));
+    featrG     = 0x04000800;
+    if(usim_test == 1)
+    {
+        bit_string->buf         = &featrG;
+        bit_string->size        = 4;
+        bit_string->bits_unused = 0;
+        UE_EUTRA_Capability->featureGroupIndicators = bit_string;
+    }
+
     // UE_EUTRA_Capability->interRAT_Parameters     // null
   } else {
 
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h
index 661914ea6ec730f2dc824ec8080d7a1799509e89..881a778030294a2d1e9262c57fedd43dd6576f64 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h
@@ -133,6 +133,7 @@ do_RRCConnectionReconfigurationComplete(
 PhysicalConfigDedicated IEs.  The latter does not enable periodic CQI reporting (PUCCH format 2/2a/2b) or SRS.
 @param ctxt_pP Running context
 @param ue_context_pP UE context
+@param CC_id         Component Carrier ID
 @param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
 @param transmission_mode Transmission mode for UE (1-9)
 @param UE_id UE index for this message
@@ -144,6 +145,7 @@ uint8_t
 do_RRCConnectionSetup(
   const protocol_ctxt_t*     const ctxt_pP,
   rrc_eNB_ue_context_t*      const ue_context_pP,
+  int                              CC_id,
   uint8_t*                   const buffer,
   const uint8_t                    transmission_mode,
   const uint8_t                    Transaction_id,
diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index f99b07e89360e13165d52f9853463a96024e9b87..0b0fd6b73fa73097e1fd3e385d1d015254986aa3 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -173,7 +173,7 @@ typedef enum HO_STATE_e {
 #define PAYLOAD_SIZE_MAX 1024
 #define RRC_BUF_SIZE 255
 #define UNDEF_SECURITY_MODE 0xff
-#define NO_SECURITY_MODE 0x33
+#define NO_SECURITY_MODE 0x20
 
 #define CBA_OFFSET        0xfff4
 // #define NUM_MAX_CBA_GROUP 4 // in the platform_constants
@@ -498,6 +498,7 @@ typedef struct UE_RRC_INST_s {
   struct SRB_ToAddMod             *SRB1_config[NB_CNX_UE];
   struct SRB_ToAddMod             *SRB2_config[NB_CNX_UE];
   struct DRB_ToAddMod             *DRB_config[NB_CNX_UE][8];
+  rb_id_t                         *defaultDRB; // remember the ID of the default DRB
   MeasObjectToAddMod_t            *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ];
   struct ReportConfigToAddMod     *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG];
   struct QuantityConfig           *QuantityConfig[NB_CNX_UE];
diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c
index 5d40872172597705c0b6d1f4bb9a637829d65d12..1b22ae5d0bd5e6db7fc4ee8245fead9ea9c69bde 100644
--- a/openair2/RRC/LITE/rrc_UE.c
+++ b/openair2/RRC/LITE/rrc_UE.c
@@ -32,6 +32,7 @@
 #define RRC_UE_C
 
 #include "assertions.h"
+#include "hashtable.h"
 #include "asn1_conversions.h"
 #include "defs.h"
 #include "PHY/TOOLS/dB_routines.h"
@@ -101,6 +102,15 @@ extern void *bigphys_malloc(int);
 
 extern int8_t dB_fixed2(uint32_t x,uint32_t y);
 
+extern void pdcp_config_set_security(
+  const protocol_ctxt_t* const  ctxt_pP,
+  pdcp_t         * const pdcp_pP,
+  const rb_id_t         rb_idP,
+  const uint16_t        lc_idP,
+  const uint8_t         security_modeP,
+  uint8_t        * const kRRCenc,
+  uint8_t        * const kRRCint,
+  uint8_t        * const  kUPenc);
 
 // internal prototypes
 
@@ -807,6 +817,7 @@ rrc_ue_process_measConfig(
       }
     }
 
+    LOG_I(RRC,"call rrc_mac_config_req \n");
     rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index,
                        (RadioResourceConfigCommonSIB_t *)NULL,
                        (struct PhysicalConfigDedicated *)NULL,
@@ -953,6 +964,199 @@ rrc_ue_process_measConfig(
   }
 }
 
+
+void
+rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radioResourceConfigDedicated,
+        const protocol_ctxt_t* const ctxt_pP,
+        uint8_t eNB_index)
+{
+    PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL;
+
+    physicalConfigDedicated2 = CALLOC(1,sizeof(*physicalConfigDedicated2));
+    physicalConfigDedicated2->pdsch_ConfigDedicated         = CALLOC(1,sizeof(*physicalConfigDedicated2->pdsch_ConfigDedicated));
+    physicalConfigDedicated2->pusch_ConfigDedicated         = CALLOC(1,sizeof(*physicalConfigDedicated2->pusch_ConfigDedicated));
+    physicalConfigDedicated2->pucch_ConfigDedicated         = CALLOC(1,sizeof(*physicalConfigDedicated2->pucch_ConfigDedicated));
+    physicalConfigDedicated2->cqi_ReportConfig              = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
+    physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+    physicalConfigDedicated2->schedulingRequestConfig       = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
+    physicalConfigDedicated2->antennaInfo                   = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo));
+
+    physicalConfigDedicated2->uplinkPowerControlDedicated   = CALLOC(1,sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated));
+    physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH         = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
+    physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH         = CALLOC(1,sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH));
+
+    // Update pdsch_ConfigDedicated
+    if(radioResourceConfigDedicated->physicalConfigDedicated->pdsch_ConfigDedicated != NULL)
+    {
+        LOG_I(RRC,"Update pdsch_ConfigDedicated config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated = CALLOC(1,sizeof(PDSCH_ConfigDedicated_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->pdsch_ConfigDedicated,
+                sizeof(physicalConfigDedicated2->pdsch_ConfigDedicated));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for pdsch_ConfigDedicated\n");
+    }
+
+    // Update pusch_ConfigDedicated
+    if(radioResourceConfigDedicated->physicalConfigDedicated->pusch_ConfigDedicated != NULL)
+    {
+        LOG_I(RRC,"Update pusch_ConfigDedicated config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated = CALLOC(1,sizeof(PUSCH_ConfigDedicated_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->pusch_ConfigDedicated,
+                sizeof(physicalConfigDedicated2->pusch_ConfigDedicated));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for pusch_ConfigDedicated\n");
+    }
+
+    // Update pucch_ConfigDedicated
+    if(radioResourceConfigDedicated->physicalConfigDedicated->pucch_ConfigDedicated != NULL)
+    {
+        LOG_I(RRC,"Update pucch_ConfigDedicated config \n");
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated = CALLOC(1,sizeof(PUCCH_ConfigDedicated_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->pucch_ConfigDedicated,
+                sizeof(physicalConfigDedicated2->pucch_ConfigDedicated));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for pucch_ConfigDedicated\n");
+    }
+
+    // Update cqi_ReportConfig
+    if(radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig != NULL)
+    {
+        LOG_I(RRC,"Update cqi_ReportConfig config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig = CALLOC(1,sizeof(CQI_ReportConfig_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig,
+                sizeof(physicalConfigDedicated2->cqi_ReportConfig));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for cqi_ReportConfig\n");
+    }
+
+    // Update schedulingRequestConfig
+    if(radioResourceConfigDedicated->physicalConfigDedicated->schedulingRequestConfig != NULL)
+    {
+        LOG_I(RRC,"Update schedulingRequestConfig config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig = CALLOC(1,sizeof(SchedulingRequestConfig_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->schedulingRequestConfig,
+                sizeof(physicalConfigDedicated2->schedulingRequestConfig));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for schedulingRequestConfig\n");
+    }
+
+    // Update soundingRS_UL_ConfigDedicated
+    if(radioResourceConfigDedicated->physicalConfigDedicated->soundingRS_UL_ConfigDedicated != NULL)
+    {
+        LOG_I(RRC,"Update soundingRS_UL_ConfigDedicated config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(SoundingRS_UL_ConfigDedicated_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->soundingRS_UL_ConfigDedicated,
+                sizeof(physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for soundingRS_UL_ConfigDedicated\n");
+    }
+
+    // Update antennaInfo
+    if(radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo != NULL)
+    {
+        LOG_I(RRC,"Update antennaInfo config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo = CALLOC(1,sizeof(struct PhysicalConfigDedicated__antennaInfo));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo,
+                sizeof(physicalConfigDedicated2->antennaInfo));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for antennaInfo\n");
+    }
+
+
+    // Update uplinkPowerControlDedicated
+    if(radioResourceConfigDedicated->physicalConfigDedicated->uplinkPowerControlDedicated != NULL)
+    {
+        LOG_I(RRC,"Update uplinkPowerControlDedicated config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated = CALLOC(1,sizeof(UplinkPowerControlDedicated_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->uplinkPowerControlDedicated,
+                sizeof(physicalConfigDedicated2->uplinkPowerControlDedicated));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for uplinkPowerControlDedicated\n");
+    }
+
+    // Update tpc_PDCCH_ConfigPUCCH
+    if(radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUCCH != NULL)
+    {
+        LOG_I(RRC,"Update tpc_PDCCH_ConfigPUCCH config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH = CALLOC(1,sizeof(TPC_PDCCH_Config_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUCCH,
+                sizeof(physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH));
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for tpc_PDCCH_ConfigPUCCH\n");
+    }
+
+    // Update tpc_PDCCH_ConfigPUSCH
+    if(radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUSCH != NULL)
+    {
+        LOG_I(RRC,"Update tpc_PDCCH_ConfigPUSCH config \n");
+
+        if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH == NULL)
+            UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH = CALLOC(1,sizeof(TPC_PDCCH_Config_t));
+
+        memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH,
+                (char*)radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUSCH,
+                sizeof(physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
+
+    }
+    else
+    {
+        LOG_I(RRC,"Keep old config for tpc_PDCCH_ConfigPUSCH\n");
+    }
+
+}
 //-----------------------------------------------------------------------------
 void
 rrc_ue_process_radioResourceConfigDedicated(
@@ -973,11 +1177,17 @@ rrc_ue_process_radioResourceConfigDedicated(
 
   // Save physicalConfigDedicated if present
   if (radioResourceConfigDedicated->physicalConfigDedicated) {
+    LOG_I(RRC,"Save physicalConfigDedicated if present \n");
+
     if (UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]) {
+#if 1
+        rrc_ue_update_radioResourceConfigDedicated(radioResourceConfigDedicated, ctxt_pP, eNB_index);
+#else
       memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index],(char*)radioResourceConfigDedicated->physicalConfigDedicated,
              sizeof(struct PhysicalConfigDedicated));
-
+#endif
     } else {
+      LOG_I(RRC,"Init physicalConfigDedicated UE_rrc_inst to radioResourceConfigDedicated->physicalConfigDedicated\n");
       UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated;
     }
   }
@@ -1054,7 +1264,7 @@ rrc_ue_process_radioResourceConfigDedicated(
 #ifdef Rel10
                              ,(PMCH_InfoList_r9_t *)NULL
 #endif
-                            );
+                             ,NULL);
 
     // Refresh SRBs
     rrc_rlc_config_asn1_req(ctxt_pP,
@@ -1095,7 +1305,7 @@ rrc_ue_process_radioResourceConfigDedicated(
             SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
           }
 
-          LOG_D(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 eNB %d) --->][MAC_UE][MOD %02d][]\n",
+          LOG_I(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 eNB %d) --->][MAC_UE][MOD %02d][]\n",
                 ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
           rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index,
                              (RadioResourceConfigCommonSIB_t *)NULL,
@@ -1150,7 +1360,7 @@ rrc_ue_process_radioResourceConfigDedicated(
             SRB2_logicalChannelConfig = &SRB2_logicalChannelConfig_defaultValue;
           }
 
-          LOG_D(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
+          LOG_I(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
                 ctxt_pP->frame,
                 ctxt_pP->module_id,
                 eNB_index,
@@ -1194,6 +1404,15 @@ rrc_ue_process_radioResourceConfigDedicated(
 
   // Establish DRBs if present
   if (radioResourceConfigDedicated->drb_ToAddModList) {
+
+    if ( (UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) &&
+         (radioResourceConfigDedicated->drb_ToAddModList->list.count >= 1) ) {
+        // configure the first DRB ID as the default DRB ID
+        UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t));
+        *UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioResourceConfigDedicated->drb_ToAddModList->list.array[0]->drb_Identity;
+        LOG_I(RRC,"[UE %d] default DRB = %d\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB);
+      }
+
     uint8_t *kUPenc = NULL;
 
 #if defined(ENABLE_SECURITY)
@@ -1225,7 +1444,7 @@ rrc_ue_process_radioResourceConfigDedicated(
 #ifdef Rel10
                              ,(PMCH_InfoList_r9_t *)NULL
 #endif
-                            );
+                             , UE_rrc_inst[ctxt_pP->module_id].defaultDRB);
 
     // Refresh DRBs
     rrc_rlc_config_asn1_req(ctxt_pP,
@@ -1248,7 +1467,7 @@ rrc_ue_process_radioResourceConfigDedicated(
         UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id] = radioResourceConfigDedicated->drb_ToAddModList->list.array[i];
         rrc_ue_establish_drb(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->drb_ToAddModList->list.array[i]);
         // MAC/PHY Configuration
-        LOG_D(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB %d eNB %d) --->][MAC_UE][MOD %02d][]\n",
+        LOG_I(RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB %d eNB %d) --->][MAC_UE][MOD %02d][]\n",
               ctxt_pP->frame, ctxt_pP->module_id,
               radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity,
               eNB_index,
@@ -1386,6 +1605,62 @@ rrc_ue_process_securityModeCommand(
     ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure;
   }
 
+
+#if defined(ENABLE_SECURITY)
+  uint8_t *kRRCenc = NULL;
+  uint8_t *kUPenc = NULL;
+  uint8_t *kRRCint = NULL;
+  pdcp_t *pdcp_p = NULL;
+  hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
+  hashtable_rc_t h_rc;
+
+  key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti,
+      ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
+  h_rc = hashtable_get(pdcp_coll_p, key, (void**) &pdcp_p);
+
+  if (h_rc == HASH_TABLE_OK) {
+    LOG_D(RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %d\n", key);
+
+    LOG_D(RRC, "driving kRRCenc, kRRCint and kUPenc from KeNB="
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x"
+        "%02x%02x%02x%02x\n",
+        UE_rrc_inst[ctxt_pP->module_id].kenb[0],  UE_rrc_inst[ctxt_pP->module_id].kenb[1],  UE_rrc_inst[ctxt_pP->module_id].kenb[2],  UE_rrc_inst[ctxt_pP->module_id].kenb[3],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[4],  UE_rrc_inst[ctxt_pP->module_id].kenb[5],  UE_rrc_inst[ctxt_pP->module_id].kenb[6],  UE_rrc_inst[ctxt_pP->module_id].kenb[7],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[8],  UE_rrc_inst[ctxt_pP->module_id].kenb[9],  UE_rrc_inst[ctxt_pP->module_id].kenb[10], UE_rrc_inst[ctxt_pP->module_id].kenb[11],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[12], UE_rrc_inst[ctxt_pP->module_id].kenb[13], UE_rrc_inst[ctxt_pP->module_id].kenb[14], UE_rrc_inst[ctxt_pP->module_id].kenb[15],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[16], UE_rrc_inst[ctxt_pP->module_id].kenb[17], UE_rrc_inst[ctxt_pP->module_id].kenb[18], UE_rrc_inst[ctxt_pP->module_id].kenb[19],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[20], UE_rrc_inst[ctxt_pP->module_id].kenb[21], UE_rrc_inst[ctxt_pP->module_id].kenb[22], UE_rrc_inst[ctxt_pP->module_id].kenb[23],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[24], UE_rrc_inst[ctxt_pP->module_id].kenb[25], UE_rrc_inst[ctxt_pP->module_id].kenb[26], UE_rrc_inst[ctxt_pP->module_id].kenb[27],
+        UE_rrc_inst[ctxt_pP->module_id].kenb[28], UE_rrc_inst[ctxt_pP->module_id].kenb[29], UE_rrc_inst[ctxt_pP->module_id].kenb[30], UE_rrc_inst[ctxt_pP->module_id].kenb[31]);
+
+    derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm,
+        UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc);
+    derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm,
+        UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint);
+    derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm,
+        UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc);
+
+    if (securityMode != 0xff) {
+      pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
+          UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm
+              | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4),
+          kRRCenc, kRRCint, kUPenc);
+    } else {
+      LOG_W(RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x",
+          securityMode);
+    }
+  } else {
+    LOG_W(RRC, "Could not get PDCP instance where key=0x%\n", key);
+  }
+
+#endif //#if defined(ENABLE_SECURITY)
+
   if (securityModeCommand->criticalExtensions.present == SecurityModeCommand__criticalExtensions_PR_c1) {
     if (securityModeCommand->criticalExtensions.choice.c1.present == SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) {
 
@@ -1719,7 +1994,7 @@ rrc_ue_process_mobilityControlInfo(
   #ifdef Rel10
          ,NULL
   #endif
-         );
+         ,NULL);
 
   rrc_rlc_config_asn1_req(NB_eNB_INST+ue_mod_idP, frameP,0,eNB_index,
         NULL,// SRB_ToAddModList
@@ -1728,7 +2003,7 @@ rrc_ue_process_mobilityControlInfo(
   #ifdef Rel10
         ,NULL
   #endif
-        );
+        ,NULL);
    */
 
 
@@ -1750,7 +2025,7 @@ rrc_ue_process_mobilityControlInfo(
   UE_rrc_inst[ue_mod_idP].DRB_config[eNB_index][0] = NULL;
    */
   //Synchronisation to DL of target cell
-  LOG_D(RRC,
+  LOG_I(RRC,
         "HO: Reset PDCP and RLC for configured RBs.. \n[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 eNB %d) --->][MAC_UE][MOD %02d][]\n",
         ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id);
 
@@ -2610,7 +2885,7 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_
 
   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_D( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
+  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(ctxt_pP->module_id, 0, ENB_FLAG_NO, 0, eNB_index,
@@ -3424,7 +3699,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in
 	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_D( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
+	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(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index,
 			   (RadioResourceConfigCommonSIB_t *)NULL,
@@ -3881,7 +4156,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i
 {
   protocol_ctxt_t               ctxt;
 
-  LOG_D(RRC,"[UE %d] Frame %d : Number of MCH(s) in the MBSFN Sync Area %d  is %d\n",
+  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);
   //  store to MAC/PHY necessary parameters for receiving MTCHs
   rrc_mac_config_req(ue_mod_idP,0,ENB_FLAG_NO,0,eNB_index,
@@ -3933,7 +4208,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i
 #ifdef Rel10
                            ,&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9)
 #endif
-                          );
+                           ,NULL);
 
   rrc_rlc_config_asn1_req(&ctxt,
                           NULL,// SRB_ToAddModList
@@ -4090,6 +4365,30 @@ void *rrc_ue_task( void *args_p )
 
 # if defined(ENABLE_USE_MME)
 
+    case NAS_KENB_REFRESH_REQ:
+        memcpy((void*)UE_rrc_inst[ue_mod_id].kenb, (void*)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(UE_rrc_inst[ue_mod_id].kenb));
+
+        LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KeNB = "
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x"
+            "%02x%02x%02x%02x\n",
+            ue_mod_id, msg_name,
+            UE_rrc_inst[ue_mod_id].kenb[0],  UE_rrc_inst[ue_mod_id].kenb[1],  UE_rrc_inst[ue_mod_id].kenb[2],  UE_rrc_inst[ue_mod_id].kenb[3],
+            UE_rrc_inst[ue_mod_id].kenb[4],  UE_rrc_inst[ue_mod_id].kenb[5],  UE_rrc_inst[ue_mod_id].kenb[6],  UE_rrc_inst[ue_mod_id].kenb[7],
+            UE_rrc_inst[ue_mod_id].kenb[8],  UE_rrc_inst[ue_mod_id].kenb[9],  UE_rrc_inst[ue_mod_id].kenb[10], UE_rrc_inst[ue_mod_id].kenb[11],
+            UE_rrc_inst[ue_mod_id].kenb[12], UE_rrc_inst[ue_mod_id].kenb[13], UE_rrc_inst[ue_mod_id].kenb[14], UE_rrc_inst[ue_mod_id].kenb[15],
+            UE_rrc_inst[ue_mod_id].kenb[16], UE_rrc_inst[ue_mod_id].kenb[17], UE_rrc_inst[ue_mod_id].kenb[18], UE_rrc_inst[ue_mod_id].kenb[19],
+            UE_rrc_inst[ue_mod_id].kenb[20], UE_rrc_inst[ue_mod_id].kenb[21], UE_rrc_inst[ue_mod_id].kenb[22], UE_rrc_inst[ue_mod_id].kenb[23],
+            UE_rrc_inst[ue_mod_id].kenb[24], UE_rrc_inst[ue_mod_id].kenb[25], UE_rrc_inst[ue_mod_id].kenb[26], UE_rrc_inst[ue_mod_id].kenb[27],
+            UE_rrc_inst[ue_mod_id].kenb[28], UE_rrc_inst[ue_mod_id].kenb[29], UE_rrc_inst[ue_mod_id].kenb[30], UE_rrc_inst[ue_mod_id].kenb[31]);
+
+      break;
+
       /* NAS messages */
     case NAS_CELL_SELECTION_REQ:
       ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */
@@ -4202,12 +4501,26 @@ void *rrc_ue_task( void *args_p )
 
       /* Transfer data to PDCP */
       PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, ENB_FLAG_NO, UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0);
-      rrc_data_req (&ctxt,
-		    DCCH,
-		    rrc_mui++,
-		    SDU_CONFIRM_NO,
-		    length, buffer,
-		    PDCP_TRANSMISSION_MODE_CONTROL);
+
+      // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) 
+      if(UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL)
+      {
+          rrc_data_req (&ctxt,
+                  DCCH,
+                  rrc_mui++,
+                  SDU_CONFIRM_NO,
+                  length, buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
+      }
+      else
+      {
+          rrc_data_req (&ctxt,
+                  DCCH1,
+                  rrc_mui++,
+                  SDU_CONFIRM_NO,
+                  length, buffer,
+                  PDCP_TRANSMISSION_MODE_CONTROL);
+      }
       break;
     }
       
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 2ce94ba26c26cbe033a1a485f51f24e21f9fa673..08d50da39cc92964d1ae44a8db1551924dce87d3 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -476,7 +476,7 @@ static void init_MBMS(
 #   ifdef Rel10
                              , &(eNB_rrc_inst[enb_mod_idP].carrier[CC_id].mcch_message->pmch_InfoList_r9)
 #   endif
-                            );
+                             ,NULL);
 
     rrc_rlc_config_asn1_req(&ctxt,
                             NULL, // SRB_ToAddModList
@@ -2619,7 +2619,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
   physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH =
     CALLOC(1, sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH));
   physicalConfigDedicated2->cqi_ReportConfig = NULL;  //CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig));
-  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; //CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
+  physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated));
   physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo));
   physicalConfigDedicated2->schedulingRequestConfig =
     CALLOC(1, sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
@@ -3281,7 +3281,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover(
 #ifdef Rel10
                            , (PMCH_InfoList_r9_t *) NULL
 #endif
-                          );
+                           ,NULL);
 
   rrc_rlc_config_asn1_req(&ctxt,
                           ue_context_pP->ue_context.SRB_configList,
@@ -3523,7 +3523,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
 #ifdef Rel10
     , (PMCH_InfoList_r9_t *) NULL
 #endif
-  );
+    ,NULL);
   // Refresh SRBs/DRBs
   rrc_rlc_config_asn1_req(
     ctxt_pP,
@@ -3743,6 +3743,7 @@ rrc_eNB_generate_RRCConnectionSetup(
   eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.payload_size =
     do_RRCConnectionSetup(ctxt_pP,
                           ue_context_pP,
+                          CC_id,
                           (uint8_t*) eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.Payload,
 			  (fp->nb_antennas_tx_eNB==2)?2:1, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
                           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
@@ -4348,7 +4349,7 @@ rrc_eNB_decode_ccch(
 #   ifdef Rel10
                                , (PMCH_InfoList_r9_t *) NULL
 #   endif
-                              );
+                               ,NULL);
 
       rrc_rlc_config_asn1_req(ctxt_pP,
                               ue_context_p->ue_context.SRB_configList,
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c
index 226f8f0754feb51cb2a517724024b584cc7f6602..d367ec7766a805f0a4e5807570aba88f6b6c4e1d 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.c
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.c
@@ -240,6 +240,10 @@ const char* eurecomFunctionsNames[] = {
   "rx_pdcch",
   "dci_decoding",
   "rx_phich",
+  "pdsch_procedures",
+  "pdsch_procedures_si",
+  "pdsch_procedures_p",
+  "pdsch_procedures_ra",
   "phy_ue_config_sib2",
   "macxface_phy_config_sib1_eNB",
   "macxface_phy_config_sib2_eNB",
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h
index 81a5fb083d98fabf1cdf29583154bd11f6b5096f..1e03e9500232c2b7e627b60d1ede5c2714183b92 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.h
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.h
@@ -214,6 +214,10 @@ typedef enum {
   VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH,
   VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING,
   VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB1_ENB,
   VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB2_ENB,
diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h
index cc1ab6854c66179f9bd718b0bb4a998f5646f42e..0d2ab89e2a71e3c1d5797e9fd2dc94f813195a9a 100644
--- a/openair2/UTIL/OPT/opt.h
+++ b/openair2/UTIL/OPT/opt.h
@@ -81,7 +81,7 @@ extern char in_path[100];
 */
 
 void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
-               int ueid, int rntiType, int rnti, uint8_t subframe,
+               int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
                int oob_event, int oob_event_value);
 
 int init_opt(char *path, char *ip, char *port, radio_type_t radio_type_p);
diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c
index 8f02c4345672f99dbee3f0f96082352e59032c82..a3836f57774a25b2c79ba3239bfe89d71612a7d6 100644
--- a/openair2/UTIL/OPT/probe.c
+++ b/openair2/UTIL/OPT/probe.c
@@ -230,7 +230,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port)
  */
 /* Add framing header to MAC PDU and send. */
 static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
-                      guint16 rnti, guint16 ueid, guint16 subframeNumber,
+                      guint16 rnti, guint16 ueid, guint16 sfnSf,
                       guint8 isPredefinedData, guint8 retx, guint8 crcStatus,
                       guint8 oob_event, guint8 oob_event_value,
                       uint8_t *pdu_buffer, unsigned int pdu_buffer_size)
@@ -278,7 +278,7 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
 
   /* Subframe number */
   frameBuffer[frameOffset++] = MAC_LTE_SUBFRAME_TAG;
-  tmp16 = htons(subframeNumber); // frame counter : this will give an expert info as wireshark expects SF and not F
+  tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F
   memcpy(frameBuffer+frameOffset, &tmp16, 2);
   frameOffset += 2;
 
@@ -287,7 +287,7 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType,
   
 #ifdef WIRESHARK_DEV
   frameOffset += 2;
-  tmp16 = htons(subframeNumber); // subframe
+  tmp16 = htons(sfnSf); // subframe
   memcpy(frameBuffer+frameOffset, &tmp16, 2);
   frameOffset += 2;
 #endif
@@ -428,7 +428,7 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
 
 /* Remote serveraddress (where Wireshark is running) */
 void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
-               int ueid, int rntiType, int rnti, uint8_t subframe, int oob_event,
+               int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
                int oob_event_value)
 {
   MAC_Context_Info_t pdu_context;
@@ -441,7 +441,7 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
 
     SendFrame(radio_type,
               (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK,
-              rntiType, rnti, ueid, subframe,
+              rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber,
               1, 0, 1,  //guint8 isPredefinedData, guint8 retx, guint8 crcStatus
               oob_event,oob_event_value,
               pdu_buffer, pdu_buffer_size);
@@ -460,8 +460,8 @@ void trace_pdu(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
     pdu_context.ueid = ueid;
     pdu_context.isRetx = 0;
     pdu_context.crcStatusOK =1;
-    pdu_context.sysFrameNumber = subframe;
-    pdu_context.subFrameNumber = 0;
+    pdu_context.sysFrameNumber = sysFrameNumber;
+    pdu_context.subFrameNumber = subFrameNumber;
     pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++;
     MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size);
     break;
diff --git a/openair3/NAS/COMMON/API/NETWORK/l2_message.h b/openair3/NAS/COMMON/API/NETWORK/l2_message.h
index b6ad3727cc6b4b4d591faea13669fba9f7d52702..39a2d18905358ddf5300b531f15a3dda8b1c3bf4 100644
--- a/openair3/NAS/COMMON/API/NETWORK/l2_message.h
+++ b/openair3/NAS/COMMON/API/NETWORK/l2_message.h
@@ -109,6 +109,14 @@ Description Defines the messages supported by the Access Stratum sublayer
 #define AS_HSDUPA     (1 << NET_ACCESS_HSDUPA)
 #define AS_EUTRAN     (1 << NET_ACCESS_EUTRAN)
 
+/*
+ * NAS->AS -K_eNB refresh request
+ * NAS request AS to refresh its KeNB key
+ */
+typedef struct kenb_refresh_req_s {
+  Byte_t kenb[32];
+} kenb_refresh_req_t;
+
 /*
  * NAS->AS - Cell Information request
  * NAS request AS to search for a suitable cell belonging to the selected
diff --git a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
index cec2d169774edc2edc704e25a9454ae772f700f3..248540dff3fb8b7481136a3c1b9ba5ca47a81747 100644
--- a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
+++ b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
@@ -188,10 +188,11 @@ int decode_attach_accept(attach_accept_msg *attach_accept, uint8_t *buffer, uint
 
     default:
       errorCodeDecoder = TLV_DECODE_UNEXPECTED_IEI;
+      LOG_TRACE(WARNING, "DECODE_UNEXPECTED_IEI %x (4 bits)", ieiDecoded);
       return TLV_DECODE_UNEXPECTED_IEI;
     }
   }
-
+  LOG_TRACE(WARNING, "DECODED %d\n", decoded);
   return decoded;
 }
 
diff --git a/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c b/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c
index fac93c5df3eb878a5a7c7afc40ba459db6c44e2d..3e0bffde2d1afd718288a1bcee40058096549220 100644
--- a/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c
+++ b/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c
@@ -38,7 +38,7 @@ int decode_authentication_request(authentication_request_msg *authentication_req
   CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, AUTHENTICATION_REQUEST_MINIMUM_LENGTH, len);
 
   /* Decoding mandatory fields */
-  if ((decoded_result = decode_u8_nas_key_set_identifier(&authentication_request->naskeysetidentifierasme, 0, *(buffer + decoded) >> 4, len - decoded)) < 0)
+  if ((decoded_result = decode_u8_nas_key_set_identifier(&authentication_request->naskeysetidentifierasme, 0, *(buffer + decoded), len - decoded)) < 0)
     return decoded_result;
 
   decoded++;
diff --git a/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c b/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c
index aeec3d4024e6e6c81e8452c4820a07a813ead52e..a1a34f94954ccfed88d36be7b5007e2eff9f972d 100644
--- a/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c
+++ b/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c
@@ -72,6 +72,8 @@ int decode_security_mode_command(security_mode_command_msg *security_mode_comman
       decoded += decoded_result;
       /* Set corresponding mask to 1 in presencemask */
       security_mode_command->presencemask |= SECURITY_MODE_COMMAND_IMEISV_REQUEST_PRESENT;
+      LOG_TRACE(INFO," SECURITY MODE COMMAND: IMEISV_REQUEST: %d \n",security_mode_command->imeisvrequest);
+
       break;
 
     case SECURITY_MODE_COMMAND_REPLAYED_NONCEUE_IEI:
diff --git a/openair3/NAS/COMMON/EMM/MSG/SecurityModeComplete.c b/openair3/NAS/COMMON/EMM/MSG/SecurityModeComplete.c
index f10401d09a9d75d5373eca7a359ab6a8b0226dd7..3258134febff5c6ae8cefb871fa0eb4b9cc88218 100644
--- a/openair3/NAS/COMMON/EMM/MSG/SecurityModeComplete.c
+++ b/openair3/NAS/COMMON/EMM/MSG/SecurityModeComplete.c
@@ -76,8 +76,11 @@ int encode_security_mode_complete(security_mode_complete_msg *security_mode_comp
   /* Checking IEI and pointer */
   CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, SECURITY_MODE_COMPLETE_MINIMUM_LENGTH, len);
 
+  LOG_TRACE(INFO,"SECURITY MODE COMMAND COMPLETE:  presencemask: %d \n",security_mode_complete->presencemask);
+
   if ((security_mode_complete->presencemask & SECURITY_MODE_COMPLETE_IMEISV_PRESENT)
       == SECURITY_MODE_COMPLETE_IMEISV_PRESENT) {
+	  LOG_TRACE(INFO,"SECURITY MODE COMMAND COMPLETE: encode imeisv \n");
     if ((encode_result =
            encode_mobile_identity(&security_mode_complete->imeisv,
                                   SECURITY_MODE_COMPLETE_IMEISV_IEI, buffer + encoded, len -
@@ -87,7 +90,7 @@ int encode_security_mode_complete(security_mode_complete_msg *security_mode_comp
     else
       encoded += encode_result;
   }
-
+  LOG_TRACE(INFO,"SECURITY MODE COMMAND COMPLETE done !!! \n");
   return encoded;
 }
 
diff --git a/openair3/NAS/COMMON/IES/EmergencyNumberList.c b/openair3/NAS/COMMON/IES/EmergencyNumberList.c
index 39b59ef0ca79647e478be37207c564d8a6b417a4..9330fdc312ef0107e29298554021bd03d1ae19db 100644
--- a/openair3/NAS/COMMON/IES/EmergencyNumberList.c
+++ b/openair3/NAS/COMMON/IES/EmergencyNumberList.c
@@ -41,10 +41,24 @@ int decode_emergency_number_list(EmergencyNumberList *emergencynumberlist, uint8
   ielen = *(buffer + decoded);
   decoded++;
   CHECK_LENGTH_DECODER(len - decoded, ielen);
-  emergencynumberlist->lengthofemergency = *(buffer + decoded);
-  decoded++;
-  emergencynumberlist->emergencyservicecategoryvalue = *(buffer + decoded) & 0x1f;
-  decoded++;
+  int information_element_index = 0;
+  while ((decoded < ielen) && (information_element_index < EMERGENCY_NUMBER_LIST_MAX_NUMBER_INFORMATION)) {
+    emergencynumberlist->emergency_number_information[information_element_index].lengthofemergency = *(buffer + decoded);
+    decoded++;
+    emergencynumberlist->emergency_number_information[information_element_index].emergencyservicecategoryvalue = *(buffer + decoded) & 0x1f;
+    decoded++;
+    int remaining_len = emergencynumberlist->emergency_number_information[information_element_index].lengthofemergency - 1;
+    int digit_index = 0;
+    while (remaining_len > 0) {
+    	emergencynumberlist->emergency_number_information[information_element_index].bcd_digits[digit_index++] = *(buffer + decoded);
+        decoded++;
+        remaining_len --;
+    }
+    while (digit_index < EMERGENCY_NUMBER_LIST_MAX_2DIGITS) {
+    	emergencynumberlist->emergency_number_information[information_element_index].bcd_digits[digit_index++] = 0xFF;
+    }
+    information_element_index++;
+  }
 #if defined (NAS_DEBUG)
   dump_emergency_number_list_xml(emergencynumberlist, iei);
 #endif
@@ -67,11 +81,16 @@ int encode_emergency_number_list(EmergencyNumberList *emergencynumberlist, uint8
 
   lenPtr  = (buffer + encoded);
   encoded ++;
-  *(buffer + encoded) = emergencynumberlist->lengthofemergency;
-  encoded++;
-  *(buffer + encoded) = 0x00 |
-                        (emergencynumberlist->emergencyservicecategoryvalue & 0x1f);
-  encoded++;
+  for (  int ie_index = 0; ie_index < emergencynumberlist->num_emergency_elements; ie_index++) {
+	  *(buffer + encoded) = emergencynumberlist->emergency_number_information[ie_index].lengthofemergency;
+	  encoded++;
+	  *(buffer + encoded) = 0x00 |
+	                        (emergencynumberlist->emergency_number_information[ie_index].emergencyservicecategoryvalue & 0x1f);
+	  encoded++;
+	  for (int bcd2_index = 0; bcd2_index < (emergencynumberlist->emergency_number_information[ie_index].lengthofemergency - 1); bcd2_index++) {
+		  *(buffer + encoded) = emergencynumberlist->emergency_number_information[ie_index].bcd_digits[bcd2_index];
+	  }
+  }
   *lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
   return encoded;
 }
@@ -83,9 +102,20 @@ void dump_emergency_number_list_xml(EmergencyNumberList *emergencynumberlist, ui
   if (iei > 0)
     /* Don't display IEI if = 0 */
     printf("    <IEI>0x%X</IEI>\n", iei);
-
-  printf("    <Length of emergency>%u</Length of emergency>\n", emergencynumberlist->lengthofemergency);
-  printf("    <Emergency service category value>%u</Emergency service category value>\n", emergencynumberlist->emergencyservicecategoryvalue);
+  for (  int ie_index = 0; ie_index < emergencynumberlist->num_emergency_elements; ie_index++) {
+	  printf("    <Length of emergency>%u</Length of emergency>\n", emergencynumberlist->emergency_number_information[ie_index].lengthofemergency);
+	  printf("    <Emergency service category value>%u</Emergency service category value>\n", emergencynumberlist->emergency_number_information[ie_index].emergencyservicecategoryvalue);
+	  for (int bcd2_index = 0; bcd2_index < (emergencynumberlist->emergency_number_information[ie_index].lengthofemergency - 1); bcd2_index++) {
+		  uint8_t bcd1 = emergencynumberlist->emergency_number_information[ie_index].bcd_digits[bcd2_index] & 0x0f;
+		  uint8_t bcd2 = (emergencynumberlist->emergency_number_information[ie_index].bcd_digits[bcd2_index] & 0xf0) >> 4;
+		  if (bcd1 < 10) {
+		    printf("    <BCD Digit%u>%u</BCD Digit%u>\n", (bcd2_index*2)+1, bcd1, (bcd2_index*2)+1);
+		    if (bcd2 < 10) {
+		    	printf("    <BCD Digit%u>%u</BCD Digit%u>\n", (bcd2_index*2)+2, bcd2, (bcd2_index*2)+2);
+		    }
+		  }
+	  }
+  }
   printf("</Emergency Number List>\n");
 }
 
diff --git a/openair3/NAS/COMMON/IES/EmergencyNumberList.h b/openair3/NAS/COMMON/IES/EmergencyNumberList.h
index d2fd149dc098c9c43b5c6a15df870074f9b8b742..ab47c1ff06766208d0ff18153a05dc7fa6efb599 100644
--- a/openair3/NAS/COMMON/IES/EmergencyNumberList.h
+++ b/openair3/NAS/COMMON/IES/EmergencyNumberList.h
@@ -32,8 +32,14 @@
 #define EMERGENCY_NUMBER_LIST_MAXIMUM_LENGTH 50
 
 typedef struct EmergencyNumberList_tag {
-  uint8_t  lengthofemergency;
-  uint8_t  emergencyservicecategoryvalue:5;
+  uint8_t  num_emergency_elements;
+  struct {
+    uint8_t  lengthofemergency;
+    uint8_t  emergencyservicecategoryvalue:5;
+#define EMERGENCY_NUMBER_LIST_MAX_2DIGITS 6
+    uint8_t  bcd_digits[EMERGENCY_NUMBER_LIST_MAX_2DIGITS]; // length to be fixed
+#define EMERGENCY_NUMBER_LIST_MAX_NUMBER_INFORMATION 2
+  } emergency_number_information[EMERGENCY_NUMBER_LIST_MAX_NUMBER_INFORMATION];
 } EmergencyNumberList;
 
 int encode_emergency_number_list(EmergencyNumberList *emergencynumberlist, uint8_t iei, uint8_t *buffer, uint32_t len);
diff --git a/openair3/NAS/COMMON/IES/MobileIdentity.c b/openair3/NAS/COMMON/IES/MobileIdentity.c
index 7ab30011ce93e42504ae91b752dccc96c97950bf..4651fa0047dffd5b757a1b16d9d50aef3c067403 100644
--- a/openair3/NAS/COMMON/IES/MobileIdentity.c
+++ b/openair3/NAS/COMMON/IES/MobileIdentity.c
@@ -575,6 +575,8 @@ static int encode_imei_mobile_identity(ImeiMobileIdentity_t *imei, uint8_t *buff
 static int encode_imeisv_mobile_identity(ImeisvMobileIdentity_t *imeisv, uint8_t *buffer)
 {
   uint32_t encoded = 0;
+  LOG_TRACE(INFO,"SECURITY MODE COMMAND COMPLETE: encode_imeisv_mobile_identity \n");
+
   *(buffer + encoded) = 0x00 | (imeisv->digit1 << 4) | (imeisv->oddeven << 3) |
                         (imeisv->typeofidentity);
   encoded++;
@@ -590,12 +592,15 @@ static int encode_imeisv_mobile_identity(ImeisvMobileIdentity_t *imeisv, uint8_t
   encoded++;
   *(buffer + encoded) = 0x00 | (imeisv->digit13 << 4) | imeisv->digit12;
   encoded++;
+  *(buffer + encoded) = 0x00 | (imeisv->digit15 << 4) | imeisv->digit14;
+  encoded++;
+  *(buffer + encoded) = 0x00 | (imeisv->parity << 4) | imeisv->digit16;
 
-  if (imeisv->oddeven != MOBILE_IDENTITY_EVEN) {
-    *(buffer + encoded) = 0x00 | (imeisv->digit15 << 4) | imeisv->digit14;
-  } else {
-    *(buffer + encoded) = 0xf0 | imeisv->digit14;
-  }
+  //if (imeisv->oddeven != MOBILE_IDENTITY_EVEN) {
+  //  *(buffer + encoded) = 0x00 | (imeisv->digit15 << 4) | imeisv->digit14;
+  //} else {
+  //  *(buffer + encoded) = 0xf0 | imeisv->digit14;
+  //}
 
   encoded++;
   return encoded;
diff --git a/openair3/NAS/COMMON/IES/MobileIdentity.h b/openair3/NAS/COMMON/IES/MobileIdentity.h
index 8d1c5cdbe5b1a1f31399ff1687edb630dcab6c78..72abcb9ed47774178e509301717ffde8d5680a2f 100644
--- a/openair3/NAS/COMMON/IES/MobileIdentity.h
+++ b/openair3/NAS/COMMON/IES/MobileIdentity.h
@@ -73,8 +73,63 @@ typedef struct {
   uint8_t  mbmssessionid;
 } TmgiMobileIdentity_t;
 
+typedef struct imeisv_s{
+  uint8_t  digit1:4;
+  uint8_t  oddeven:1;
+  uint8_t  typeofidentity:3;
+  uint8_t  digit2:4;
+  uint8_t  digit3:4;
+  uint8_t  digit4:4;
+  uint8_t  digit5:4;
+  uint8_t  digit6:4;
+  uint8_t  digit7:4;
+  uint8_t  digit8:4;
+  uint8_t  digit9:4;
+  uint8_t  digit10:4;
+  uint8_t  digit11:4;
+  uint8_t  digit12:4;
+  uint8_t  digit13:4;
+  uint8_t  digit14:4;
+  uint8_t  digit15:4;
+  uint8_t  digit16:4;
+#define EVEN_PARITY 0
+#define IMEI_ODD_PARITY  0xf
+       uint8_t parity:4;
+} imeisv_t;
+
+#if 0
+typedef struct imeisv_s {
+   uint8_t length;
+   union {
+     struct {
+       uint8_t tac2:4;
+       uint8_t tac1:4;
+       uint8_t tac4:4;
+       uint8_t tac3:4;
+       uint8_t tac6:4;
+       uint8_t tac5:4;
+       uint8_t tac8:4;
+       uint8_t tac7:4;
+       uint8_t snr2:4;
+       uint8_t snr1:4;
+       uint8_t snr4:4;
+       uint8_t snr3:4;
+       uint8_t snr6:4;
+       uint8_t snr5:4;
+       uint8_t svn2:4;
+       uint8_t svn1:4;
+#define EVEN_PARITY 0
+#define IMEI_ODD_PARITY  0xf
+       uint8_t parity:4;
+     } num;
+#define IMEISV_BCD8_SIZE   9
+     uint8_t value[IMEISV_BCD8_SIZE];
+   } u;
+} imeisv_t;
+#endif
+
 typedef ImsiMobileIdentity_t ImeiMobileIdentity_t;
-typedef ImsiMobileIdentity_t ImeisvMobileIdentity_t;
+typedef imeisv_t             ImeisvMobileIdentity_t;
 typedef ImsiMobileIdentity_t TmsiMobileIdentity_t;
 typedef ImsiMobileIdentity_t NoMobileIdentity_t;
 
diff --git a/openair3/NAS/TOOLS/usim_data.c b/openair3/NAS/TOOLS/usim_data.c
index 3313f474983b4b1e2beeaf9c7501918c2ff6d95f..23eba29bb134cf1fa3ad8a9bacec4f546d23cd96 100644
--- a/openair3/NAS/TOOLS/usim_data.c
+++ b/openair3/NAS/TOOLS/usim_data.c
@@ -220,6 +220,7 @@ int main (int argc, const char* argv[])
     usim_data.imsi.u.num.digit13 = 3;
     usim_data.imsi.u.num.digit14 = 4;
     usim_data.imsi.u.num.digit15 = 0xF;
+    usim_data.usimtestmode = 1; // set usim in test mode in order to get the CMW500 K key
 #endif
     /*
      * Ciphering and Integrity Keys
diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c
index a517799ff7c33eccf721736dc35251fc87cc796a..58ca9aa279e95e66375647e3760bf490f833dded 100644
--- a/openair3/NAS/UE/API/USIM/usim_api.c
+++ b/openair3/NAS/UE/API/USIM/usim_api.c
@@ -72,6 +72,7 @@ Description Implements the API used by the NAS layer to read/write
 #define USIM_API_K_SIZE         16
 //#define USIM_API_K_VALUE        "fec86ba6eb707ed08905757b1bb44b8f"
 #define USIM_API_K_VALUE        "8BAF473F2F8FD09487CCCBD7097C6862"
+#define TEST_USIM_API_K_VALUE   "000102030405060708090a0b0c0d0e0f" // CMW500 K key
 
 static uint8_t _usim_api_k[USIM_API_K_SIZE];
 
@@ -136,7 +137,14 @@ int usim_api_read(usim_data_t* data)
   }
 
   /* initialize the subscriber authentication security key */
-  _usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE);
+  if(data->usimtestmode == 0)
+  {
+    _usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE);
+  }
+  else
+  {
+    _usim_api_hex_string_to_hex_value(_usim_api_k, TEST_USIM_API_K_VALUE, USIM_API_K_SIZE);
+  }
 
   free(path);
   LOG_FUNC_RETURN (RETURNok);
@@ -181,6 +189,189 @@ int usim_api_write(const usim_data_t* data)
   LOG_FUNC_RETURN (RETURNok);
 }
 
+/****************************************************************************
+ **                                                                        **
+ ** Name:        usim_api_authenticate_test()                              **
+ **                                                                        **
+ ** Description: Performs mutual authentication of the USIM to the network,**
+ **              checking whether authentication token AUTN can be accep-  **
+ **              ted. If so, returns an authentication response RES and    **
+ **              the ciphering and integrity keys.                         **
+ **              In case of synch failure, returns a re-synchronization    **
+ **              token AUTS.                                               **
+ **                                                                        **
+ **              Key Generation for Test USIM based on 34.108              **
+ **                                                                        **
+ **              Authentication and key generating function algorithms are **
+ **              specified in 3GPP TS 35.206.                              **
+ **                                                                        **
+ ** Inputs:      rand_pP:          Random challenge number                    **
+ **              autn_pP:          Authentication token                       **
+ **                             AUTN = (SQN xor AK) || AMF || MAC          **
+ **                                         48          16     64 bits     **
+ **              Others:        Security key                               **
+ **                                                                        **
+ ** Outputs:     auts_pP:          Re-synchronization token                   **
+ **              res_pP:           Authentication response                    **
+ **              ck_pP:            Ciphering key                              **
+ **              ik_pP             Integrity key                              **
+ **                                                                        **
+ **              Return:        RETURNerror, RETURNok                      **
+ **              Others:        None                                       **
+ **                                                                        **
+ ***************************************************************************/
+int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* autn_pP,
+                               OctetString* auts_pP, OctetString* res_pP,
+                               OctetString* ck_pP, OctetString* ik_pP)
+{
+  LOG_FUNC_IN;
+
+  int rc;
+  int i;
+
+  LOG_TRACE(INFO, "USIM-API  - rand :%s",dump_octet_string(rand_pP));
+  LOG_TRACE(INFO, "USIM-API  - autn :%s",dump_octet_string(autn_pP));
+
+  //step1: XDOUT = RAND xor K
+  //       RES = XDOUT
+  for (i=0; i<USIM_API_K_SIZE; i++)
+  {
+      res_pP->value[i] = rand_pP->value[i] ^ _usim_api_k[i];
+  }
+
+  //step2: res = f2(xdout,n)
+  //       ck  = f3(xdout)
+  //       ik  = f4(xdout)
+  //       ak  = f5(xdout)
+  u8 ak[USIM_API_AK_SIZE];
+  for (i=0; i<15; i++)
+  {
+      ck_pP->value[i] = res_pP->value[i+1];
+  }
+  ck_pP->value[15] = res_pP->value[0];
+
+  for (i=0; i<14; i++)
+  {
+      ik_pP->value[i] = res_pP->value[i+2];
+  }
+  ik_pP->value[14] = res_pP->value[0];
+  ik_pP->value[15] = res_pP->value[1];
+
+  for (i=0; i<USIM_API_AK_SIZE; i++)
+  {
+      ak[i] = res_pP->value[i+3];
+  }
+  LOG_TRACE(INFO, "USIM-API  - res(f2)  :%s",dump_octet_string(res_pP));
+  LOG_TRACE(INFO, "USIM-API  - ck(f3)   :%s",dump_octet_string(ck_pP));
+  LOG_TRACE(INFO, "USIM-API  - ik(f4)   :%s",dump_octet_string(ik_pP));
+  LOG_TRACE(INFO, "USIM-API  - ak(f5)   : %02X%02X%02X%02X%02X%02X",
+            ak[0],ak[1],ak[2],ak[3],ak[4],ak[5]);
+
+  //step3: concatenate SQN with AMP SQN||AMF
+  //       SQN = AUTN xor ak
+  u8 sqn[USIM_API_SQN_SIZE];
+  for (i = 0; i < USIM_API_SQN_SIZE; i++) {
+    sqn[i] = autn_pP->value[i] ^ ak[i];
+  }
+  LOG_TRACE(INFO, "USIM-API  - Retrieved SQN %02X%02X%02X%02X%02X%02X",
+            sqn[0],sqn[1],sqn[2],sqn[3],sqn[4],sqn[5]);
+  LOG_TRACE(INFO, "USIM-API  - Retrieved AMF %02X%02X",
+            autn_pP->value[USIM_API_SQN_SIZE],autn_pP->value[USIM_API_SQN_SIZE+1]);
+
+#define USIM_API_XMAC_SIZE 8
+  u8 cdout[USIM_API_XMAC_SIZE];
+  for (i = 0; i < USIM_API_XMAC_SIZE; i++)
+  {
+    if(i < USIM_API_SQN_SIZE)
+    {
+        cdout[i] = sqn[i];
+    }
+    else
+    {
+        cdout[i] = autn_pP->value[i];
+    }
+  }
+  LOG_TRACE(INFO, "USIM-API  - Retrieved CDOUT %02X%02X%02X%02X%02X%02X%02X%02X",
+          cdout[0],cdout[1],cdout[2],cdout[3],cdout[4],cdout[5],cdout[6],cdout[7]);
+
+  //step4:calculate XMAC from cdout and xdout
+  u8 xmac[USIM_API_XMAC_SIZE];
+  for(i = 0; i < USIM_API_XMAC_SIZE; i++)
+  {
+      xmac[i] = res_pP->value[i] ^ cdout[i];
+  }
+  LOG_TRACE(INFO,
+            "USIM-API  - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X",
+            xmac[0],xmac[1],xmac[2],xmac[3],
+            xmac[4],xmac[5],xmac[6],xmac[7]);
+
+  /* Compare the XMAC with the MAC included in AUTN */
+#define USIM_API_AMF_SIZE 2
+
+  if ( memcmp(xmac, &autn_pP->value[USIM_API_SQN_SIZE + USIM_API_AMF_SIZE],
+              USIM_API_XMAC_SIZE) != 0 ) {
+    LOG_TRACE(INFO,
+              "USIM-API  - Comparing the XMAC with the MAC included in AUTN Failed");
+    rc = RETURNerror;
+    //LOG_FUNC_RETURN (RETURNerror);
+  } else {
+    LOG_TRACE(INFO,
+              "USIM-API  - Comparing the XMAC with the MAC included in AUTN Succeeded");
+    /* Verify that the received sequence number SQN is in the correct range */
+    rc = _usim_api_check_sqn(*(uint32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]);
+  }
+
+
+  if (rc != RETURNok) {
+    /* Synchronisation failure; compute the AUTS parameter */
+
+    /* Concealed value of the counter SQNms in the USIM:
+     * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */
+    f5star(_usim_api_k, rand_pP->value, ak);
+
+
+    u8 sqn_ms[USIM_API_SQNMS_SIZE];
+    memset(sqn_ms, 0, USIM_API_SQNMS_SIZE);
+
+    //#define USIM_API_SQN_MS_SIZE  3
+    printf("_usim_api_data.sqn_ms %p\n",_usim_api_data.sqn_ms);
+    for (i = 0; i < USIM_API_SQNMS_SIZE; i++) {
+      //#warning "LG:BUG HERE TODO"
+      printf("i %d:  ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]);
+      sqn_ms[USIM_API_SQNMS_SIZE - i] =
+        ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i];
+    }
+
+    u8 sqnms[USIM_API_SQNMS_SIZE];
+
+    for (i = 0; i < USIM_API_SQNMS_SIZE; i++) {
+      sqnms[i] = sqn_ms[i] ^ ak[i];
+    }
+
+    LOG_TRACE(DEBUG, "USIM-API  - SQNms %02X%02X%02X%02X%02X%02X",
+              sqnms[0],sqnms[1],sqnms[2],sqnms[3],sqnms[4],sqnms[5]);
+
+    /* Synchronisation message authentication code:
+     * MACS = f1*K(SQNMS || RAND || AMF) */
+#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE
+    u8 macs[USIM_API_MACS_SIZE];
+    f1star(_usim_api_k, rand_pP->value, sqn_ms,
+           &rand_pP->value[USIM_API_SQN_SIZE], macs);
+    LOG_TRACE(DEBUG, "USIM-API  - MACS %02X%02X%02X%02X%02X%02X%02X%02X",
+              macs[0],macs[1],macs[2],macs[3],
+              macs[4],macs[5],macs[6],macs[7]);
+
+    /* Synchronisation authentication token:
+     * AUTS = Conc(SQNMS) || MACS */
+    memcpy(&auts_pP->value[0], sqnms, USIM_API_SQNMS_SIZE);
+    memcpy(&auts_pP->value[USIM_API_SQNMS_SIZE], macs, USIM_API_MACS_SIZE);
+    auts_pP->length = USIM_API_SQNMS_SIZE + USIM_API_MACS_SIZE;
+    LOG_FUNC_RETURN (RETURNerror);
+  }
+
+  LOG_FUNC_RETURN (RETURNok);
+}
+
 /****************************************************************************
  **                                                                        **
  ** Name:        usim_api_authenticate()                                   **
diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h
index 3667abd4eeebfa195e6e4e7e54d4c51f337171cc..8cfaeb8aed67d14a0ca3cecde85eeba9433ce3d1 100644
--- a/openair3/NAS/UE/API/USIM/usim_api.h
+++ b/openair3/NAS/UE/API/USIM/usim_api.h
@@ -327,6 +327,8 @@ typedef struct {
   usim_epsloci_t epsloci;
   /* Non-Access Stratum configuration       */
   usim_nasconfig_t nasconfig;
+  /* usim test mode */
+  uint8_t usimtestmode;
 } usim_data_t;
 
 /****************************************************************************/
@@ -344,5 +346,8 @@ int usim_api_write(const usim_data_t* data);
 int usim_api_authenticate(const OctetString* rand, const OctetString* autn,
                           OctetString* auts, OctetString* res,
                           OctetString* ck, OctetString* ik);
+int usim_api_authenticate_test(const OctetString* rand, const OctetString* autn,
+                               OctetString* auts, OctetString* res,
+                               OctetString* ck, OctetString* ik);
 
 #endif /* __USIM_API_H__*/
diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c
index 7ffab89f89c2dff1ed2b592edc24c78e068941ca..9022acbdac8d1a3cc4e6f9602dacb2572b79a323 100644
--- a/openair3/NAS/UE/EMM/Authentication.c
+++ b/openair3/NAS/UE/EMM/Authentication.c
@@ -79,6 +79,8 @@ extern void *_emm_service_t3417_handler(void *);
 extern void *_emm_detach_t3421_handler(void *);
 extern void *_emm_tau_t3430_handler(void *);
 
+extern uint8_t usim_test;
+
 /****************************************************************************/
 /*******************  L O C A L    D E F I N I T I O N S  *******************/
 /****************************************************************************/
@@ -233,7 +235,14 @@ int emm_proc_authentication_request(int native_ksi, int ksi,
        * of the core network by means of the received AUTN parameter and
        * request the USIM to compute RES, CK and IK for given RAND
        */
-      rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik);
+      if(usim_test == 0)
+      {
+        rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik);
+      }
+      else
+      {
+        rc = usim_api_authenticate_test(rand, autn, &auts, &res, &ck, &ik); // XOR algo for autentication on usim test mode
+      }
     }
 
     if (rc != RETURNok) {
diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c
index 707996b5a752e04e8aa055478de199f7a7056135..85f98c4bd7b03e40e093b37d3c86827f1c21fe82 100644
--- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c
+++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c
@@ -55,6 +55,7 @@ Description Implements the EPS Mobility Management procedures executed
 /****************************************************************************/
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
 /****************************************************************************/
+extern uint8_t usim_test;
 
 /****************************************************************************/
 /*******************  L O C A L    D E F I N I T I O N S  *******************/
@@ -109,7 +110,14 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt)
     /*
      * Initiate the attach procedure for EPS services
      */
-    rc = emm_proc_attach(EMM_ATTACH_TYPE_EPS);
+    if(usim_test == 0)
+    {
+      rc = emm_proc_attach(EMM_ATTACH_TYPE_EPS);
+    }
+    else
+    {
+      rc = emm_proc_attach(EMM_ATTACH_TYPE_IMSI); // CMW500 IMSI initial attach expected
+    }
     break;
 
   case _EMMREG_ATTACH_REQ:
diff --git a/openair3/NAS/UE/EMM/SAP/emm_asDef.h b/openair3/NAS/UE/EMM/SAP/emm_asDef.h
index bf0e6f6c3765525dbd6ed6f3e77818d6785b7866..69ea979b6361328530af8557330a47ad33d55e67 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_asDef.h
+++ b/openair3/NAS/UE/EMM/SAP/emm_asDef.h
@@ -120,6 +120,7 @@ typedef struct emm_as_security_s {
   uint8_t ucs2;
   uint8_t uia;        /* Replayed UMTS integrity algorithms   */
   uint8_t gea;        /* Replayed GPRS encryption algorithms   */
+  uint8_t imeisv_request;
   uint8_t umts_present;
   uint8_t gprs_present;
 
diff --git a/openair3/NAS/UE/EMM/SAP/emm_recv.c b/openair3/NAS/UE/EMM/SAP/emm_recv.c
index 32e8e1ec30ef8cd2ab725360c4737ff3ca48cc0d..0ad41b09d878862b677cc35da535f103baf1cadf 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_recv.c
+++ b/openair3/NAS/UE/EMM/SAP/emm_recv.c
@@ -137,8 +137,15 @@ int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause)
   /*
    * Message checking
    */
-  if (msg->tailist.typeoflist !=
-      TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS) {
+  // supported cases:
+  // typeoflist = 1 Or
+  // typeoflist = 0 and numberofelements = 1 (ie numberofelements equal to zero see 3gpp 24.301 9.9.3.33.1)
+  LOG_TRACE(DEBUG,"attach accept type of list: %d, number of element: %d\n",msg->tailist.typeoflist, msg->tailist.numberofelements);
+  if (!( (msg->tailist.typeoflist == TRACKING_AREA_IDENTITY_LIST_ONE_PLMN_CONSECUTIVE_TACS) ||
+         ((msg->tailist.typeoflist == 0) && ( msg->tailist.numberofelements == 0))
+       )
+     )
+  {
     /* Only list of TACs belonging to one PLMN with consecutive
      * TAC values is supported */
     *emm_cause = EMM_CAUSE_IE_NOT_IMPLEMENTED;
@@ -465,13 +472,15 @@ int emm_recv_security_mode_command(security_mode_command_msg *msg,
    * Message processing
    */
   /* Execute the security mode control procedure initiated by the network */
+  LOG_TRACE(INFO,"Execute the security mode control procedure initiated by the network:  imeisvrequest %d\n",msg->imeisvrequest);
   rc = emm_proc_security_mode_command(
          msg->naskeysetidentifier.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED,
          msg->naskeysetidentifier.naskeysetidentifier,
          msg->selectednassecurityalgorithms.typeofcipheringalgorithm,
          msg->selectednassecurityalgorithms.typeofintegrityalgorithm,
          msg->replayeduesecuritycapabilities.eea,
-         msg->replayeduesecuritycapabilities.eia);
+         msg->replayeduesecuritycapabilities.eia,
+		 msg->imeisvrequest & 0x7);
 
   LOG_FUNC_RETURN (rc);
 }
diff --git a/openair3/NAS/UE/EMM/SAP/emm_send.c b/openair3/NAS/UE/EMM/SAP/emm_send.c
index 7e13d03c7b101ac40108622a667a4decd676c271..e3fc4fa7f990622aa6a78f922d863e6ca2074669 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_send.c
+++ b/openair3/NAS/UE/EMM/SAP/emm_send.c
@@ -855,6 +855,34 @@ int emm_send_security_mode_complete(const emm_as_security_t *msg,
   /* Mandatory - Message type */
   emm_msg->messagetype = SECURITY_MODE_COMPLETE;
 
+  if(msg->imeisv_request)
+  {
+	  // configure imeisv param
+	  emm_msg->presencemask |= SECURITY_MODE_COMPLETE_IMEISV_PRESENT;
+
+	  // 33 85 76 02 05 26 84 01 F1
+	  emm_msg->imeisv.imeisv.digit1         = 0x3;
+	  emm_msg->imeisv.imeisv.oddeven        = 0x0;
+	  emm_msg->imeisv.imeisv.typeofidentity = 0x3;
+	  emm_msg->imeisv.imeisv.digit2         = 0x5;
+	  emm_msg->imeisv.imeisv.digit3         = 0x7;
+	  emm_msg->imeisv.imeisv.digit4         = 0x4;
+	  emm_msg->imeisv.imeisv.digit5         = 0x7;
+	  emm_msg->imeisv.imeisv.digit6         = 0x3;
+	  emm_msg->imeisv.imeisv.digit7         = 0x0;
+	  emm_msg->imeisv.imeisv.digit8         = 0x4;
+	  emm_msg->imeisv.imeisv.digit9         = 0x0;
+	  emm_msg->imeisv.imeisv.digit10        = 0x0;
+	  emm_msg->imeisv.imeisv.digit11        = 0x7;
+	  emm_msg->imeisv.imeisv.digit12        = 0x0;
+	  emm_msg->imeisv.imeisv.digit13        = 0x5;
+	  emm_msg->imeisv.imeisv.digit14        = 0x3;
+	  emm_msg->imeisv.imeisv.digit15        = 0x0;
+	  emm_msg->imeisv.imeisv.digit16        = 0x0;
+	  emm_msg->imeisv.imeisv.parity         = IMEI_ODD_PARITY;
+
+	  size += SECURITY_MODE_COMPLETE_MAXIMUM_LENGTH;
+  }
   LOG_FUNC_RETURN (size);
 }
 
diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c
index c48c2cbaafb815f34ee862764d0b36acea5d450b..f27eb7b4afa87a25a76e08beb95f4a2aa6607b9c 100644
--- a/openair3/NAS/UE/EMM/SecurityModeControl.c
+++ b/openair3/NAS/UE/EMM/SecurityModeControl.c
@@ -65,6 +65,10 @@ Description Defines the security mode control EMM procedure executed by the
 #include "secu_defs.h"
 #include "msc.h"
 
+#if  defined(NAS_BUILT_IN_UE)
+#include "nas_itti_messaging.h"
+#endif
+
 /****************************************************************************/
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
 /****************************************************************************/
@@ -142,7 +146,7 @@ static void _security_release(emm_security_context_t *ctx);
  **                                                                        **
  ***************************************************************************/
 int emm_proc_security_mode_command(int native_ksi, int ksi,
-                                   int seea, int seia, int reea, int reia)
+                                   int seea, int seia, int reea, int reia, int imeisv_request)
 {
   LOG_FUNC_IN;
 
@@ -286,7 +290,9 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
 
       _emm_data.security->selected_algorithms.encryption = seea;
       _emm_data.security->selected_algorithms.integrity  = seia;
-
+#if  defined(NAS_BUILT_IN_UE)
+      nas_itti_kenb_refresh_req(_security_data.kenb.value);
+#endif
     }
     /*
      * NAS security mode command not accepted by the UE
@@ -323,6 +329,7 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
   emm_sap.u.emm_as.u.security.guti = _emm_data.guti;
   emm_sap.u.emm_as.u.security.ueid = 0;
   emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC;
+  emm_sap.u.emm_as.u.security.imeisv_request = imeisv_request;
   emm_sap.u.emm_as.u.security.emm_cause = emm_cause;
   /* Setup EPS NAS security data */
   emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx,
diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c
index eb92f849de80900288b0939ce729224a4302f572..2eb4d8fa24d6b18c1d7e8f88d01bbfc00961c2ca 100644
--- a/openair3/NAS/UE/EMM/emm_main.c
+++ b/openair3/NAS/UE/EMM/emm_main.c
@@ -40,6 +40,7 @@ Description Defines the EPS Mobility Management procedure call manager,
 #include "emm_main.h"
 #include "nas_log.h"
 #include "emmData.h"
+#include "MobileIdentity.h"
 
 #include "memory.h"
 #include "usim_api.h"
@@ -52,6 +53,7 @@ Description Defines the EPS Mobility Management procedure call manager,
 /****************************************************************************/
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
 /****************************************************************************/
+extern uint8_t usim_test;
 
 /****************************************************************************/
 /*******************  L O C A L    D E F I N I T I O N S  *******************/
@@ -159,6 +161,7 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei)
   /*
    * Get USIM application data
    */
+  _usim_data.usimtestmode = usim_test;
   if ( usim_api_read(&_usim_data) != RETURNok ) {
     /* The USIM application may not be present or not valid */
     LOG_TRACE(WARNING, "EMM-MAIN  - Failed to read USIM application data");
@@ -917,7 +920,7 @@ static int _emm_main_get_imei(imei_t *imei, const char *imei_str)
   int len = strlen(imei_str);
 
   if (len % 2) {
-    imei->u.num.parity = ODD_PARITY;
+    imei->u.num.parity = IMEI_ODD_PARITY;
   } else {
     imei->u.num.parity = EVEN_PARITY;
   }
diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h
index e6a3ae0cdd0d85ac093887f9e784bf1ea7590c84..60f71f11c200ebd67ef02b90b5088cfa92dbaead 100644
--- a/openair3/NAS/UE/EMM/emm_proc.h
+++ b/openair3/NAS/UE/EMM/emm_proc.h
@@ -174,7 +174,7 @@ int emm_proc_authentication_delete(void);
  * --------------------------------------------------------------------------
  */
 int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia,
-                                   int reea, int reia);
+                                   int reea, int reia,int imeisv_request);
 
 /*
  *---------------------------------------------------------------------------
diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c
index 248633c3a192abfa68bbd0103e95492fcc6d732e..20af58dac67563576cb9c9f425a7bd63987033ec 100644
--- a/openair3/NAS/UE/UEprocess.c
+++ b/openair3/NAS/UE/UEprocess.c
@@ -71,6 +71,8 @@ static void _nas_signal_handler(int signal);
 
 static void _nas_clean(int usr_fd, int net_fd);
 
+uint8_t usim_test = 0;
+
 /****************************************************************************/
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
 /****************************************************************************/
diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c
index 10bfdf9d6e9623edd5387ad4afbe4035327a56a6..7667ad50a438b95892355a31c86b98b39c5f6e71 100644
--- a/openair3/NAS/UE/nas_itti_messaging.c
+++ b/openair3/NAS/UE/nas_itti_messaging.c
@@ -180,6 +180,39 @@ int nas_itti_protected_msg(const char *buffer, const nas_message_t *msg, const i
 
 extern unsigned char NB_eNB_INST;
 
+int nas_itti_kenb_refresh_req(const Byte_t kenb[32])
+{
+  MessageDef *message_p;
+
+  message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ);
+
+  memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb));
+
+  MSC_LOG_TX_MESSAGE(
+      MSC_NAS_UE,
+      MSC_RRC_UE,
+      NULL,0,
+      "0 NAS_KENB_REFRESH_REQ KeNB "
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x"
+      "%02x%02x%02x%02x",
+      kenb[0],  kenb[1],  kenb[2],  kenb[3],
+      kenb[4],  kenb[5],  kenb[6],  kenb[7],
+      kenb[8],  kenb[9],  kenb[10], kenb[11],
+      kenb[12], kenb[13], kenb[14], kenb[15],
+      kenb[16], kenb[17], kenb[18], kenb[19],
+      kenb[20], kenb[21], kenb[22], kenb[23],
+      kenb[24], kenb[25], kenb[26], kenb[27],
+      kenb[28], kenb[29], kenb[30], kenb[31]);
+
+  return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p);
+}
+
 int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat)
 {
   MessageDef *message_p;
diff --git a/openair3/NAS/UE/nas_itti_messaging.h b/openair3/NAS/UE/nas_itti_messaging.h
index dae4f5fb2837a4dc25df98680a59456e1bbaa86a..22c09f109b3be64977db004b3d12579f5ff2b688 100644
--- a/openair3/NAS/UE/nas_itti_messaging.h
+++ b/openair3/NAS/UE/nas_itti_messaging.h
@@ -47,6 +47,9 @@ int nas_itti_protected_msg(
 
 
 # if defined(NAS_BUILT_IN_UE)
+
+int nas_itti_kenb_refresh_req(const Byte_t kenb[32]);
+
 int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat);
 
 int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data_pP, uint32_t lengthP);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
index ef7c1cc19c35ba05b9d21f90c2ca20751b54a0b0..a79cb2cae6301060a579ffc143defc2bb61d7d60 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
@@ -62,11 +62,11 @@ eNBs =
         pusch_nDMRS1                              = 0;
         phich_duration                            = "NORMAL";
         phich_resource                            = "ONESIXTH";
-        srs_enable                                = "DISABLE";
-        /*  srs_BandwidthConfig                   =;
-        srs_SubframeConfig                        =;
-        srs_ackNackST                             =;
-        srs_MaxUpPts                              =;*/
+        srs_enable                                = "ENABLE";
+        srs_BandwidthConfig                       =2;
+        srs_SubframeConfig                        =13;
+        srs_ackNackST                             ="DISABLE";
+        srs_MaxUpPts                              ="DISABLE";
 
         pusch_p0_Nominal                          = -108;
         pusch_alpha                               = "AL1";
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index c73bc8d01b527d390c4efc425621039371c51c22..a9d7a07e2645054b5d207f9cbf3831c591968064 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -204,6 +204,7 @@ char   rf_config_file[1024];
 
 int chain_offset=0;
 int phy_test = 0;
+uint8_t usim_test = 0;
 
 
 char ref[128] = "internal";
@@ -378,6 +379,7 @@ void help (void) {
   printf("  --ue-scan_carrier set UE to scan around carrier\n");
   printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
   printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
+  printf("  --usim-test use XOR autentication algo in case of test usim mode\n"); 
   printf("  --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); 
   printf("  -C Set the downlink frequency for all component carriers\n");
   printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
@@ -685,6 +687,7 @@ static void get_options (int argc, char **argv)
     LONG_OPTION_DUMP_FRAME,
     LONG_OPTION_LOOPMEMORY,
     LONG_OPTION_PHYTEST,
+    LONG_OPTION_USIMTEST,
     LONG_OPTION_MMAPPED_DMA,
     LONG_OPTION_SINGLE_THREAD_DISABLE,
 #if T_TRACER
@@ -711,6 +714,7 @@ static void get_options (int argc, char **argv)
     {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
     {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
     {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
+    {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST},
     {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
     {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE},
 #if T_TRACER
@@ -810,6 +814,9 @@ static void get_options (int argc, char **argv)
       phy_test = 1;
       break;
 
+    case LONG_OPTION_USIMTEST:
+        usim_test = 1;
+      break;
     case LONG_OPTION_MMAPPED_DMA:
       mmapped_dma = 1;
       break;
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index f4b8e0ab3a0f289b42d638e211d27b8275cabce4..a0c7c75f54638de0def84c53d50edb268a5d965f 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -1006,8 +1006,8 @@ void *UE_thread(void *arg) {
 
       }// start_rx_stream==0
       else {
-	UE->proc.proc_rxtx[0].frame_rx++;
-	UE->proc.proc_rxtx[1].frame_rx++;
+	//UE->proc.proc_rxtx[0].frame_rx++;
+	//UE->proc.proc_rxtx[1].frame_rx++;
 	
 	for (int sf=0;sf<10;sf++) {
 	  for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) 
@@ -1093,6 +1093,11 @@ void *UE_thread(void *arg) {
 	  }
 	  // increment instance count and change proc subframe/frame variables
 	  int instance_cnt_rxtx = ++proc->instance_cnt_rxtx;
+	  if(sf == 0)
+	  {
+	     UE->proc.proc_rxtx[0].frame_rx++;
+	     UE->proc.proc_rxtx[1].frame_rx++;
+	  }
 	  proc->subframe_rx=sf;
 	  proc->subframe_tx=(sf+4)%10;
 	  proc->frame_tx = proc->frame_rx + ((proc->subframe_rx>5)?1:0);
diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c
index 9253c2c50df55235bb749af62704ce53d7309eaa..3a06a627803f3bd3d1d92fdbbb259ca6b5960f55 100644
--- a/targets/SIMU/USER/oaisim.c
+++ b/targets/SIMU/USER/oaisim.c
@@ -127,6 +127,8 @@ char smbv_ip[16];
 //#define K                      2             /* averaging coefficient */
 //#define TARGET_SF_TIME_NS      1000000       /* 1ms = 1000000 ns */
 
+uint8_t usim_test = 0;
+
 frame_t frame = 0;
 char stats_buffer[16384];
 channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index 17c2af2bc64d255e73523d5069898057ed0da927..3592e72361340ec1cda70ecd960e98ce6cd142ca 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -1276,7 +1276,7 @@ void init_openair1(void)
   for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
       
-      PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=23;
+      PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=10;
       
       PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB=100;
 
@@ -1518,7 +1518,7 @@ void update_ocm()
           //calc_path_loss (enb_data[eNB_id], ue_data[UE_id], eNB2UE[eNB_id][UE_id], oai_emulation.environment_system_config,0);
           UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB = eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB;
           //    if (frame % 50 == 0)
-          LOG_I(OCM,"Path loss (CCid %d) between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n",
+          LOG_D(OCM,"Path loss (CCid %d) between eNB %d at (%f,%f) and UE %d at (%f,%f) is %f, angle %f\n",
                 CC_id,eNB_id,enb_data[eNB_id]->x,enb_data[eNB_id]->y,UE_id,ue_data[UE_id]->x,ue_data[UE_id]->y,
                 eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB, eNB2UE[eNB_id][UE_id][CC_id]->aoa);
           //double dx, dy, distance;
diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
index 0c1500fd5e3aa2ca4bad398ca97f566ba293f0c5..dc395281dce2d69febc4e5f7e86f6fbcb538a2d0 100644
--- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
+++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
@@ -188,9 +188,9 @@ void pdcp_rlc_test_exchange_pdus(rlc_um_entity_t *um_txP,
   memset(&mac_rlc_status_resp_tx, 0, sizeof(struct mac_status_resp));
   memset(&mac_rlc_status_resp_rx, 0, sizeof(struct mac_status_resp));
 
-  mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, bytes_txP, tx_status);
+  mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, bytes_txP, tx_status, ENB_FLAG_YES);
   data_request_tx        = rlc_um_mac_data_request(um_txP);
-  mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, bytes_rxP, tx_status);
+  mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, bytes_rxP, tx_status, ENB_FLAG_YES);
   data_request_rx        = rlc_um_mac_data_request(um_rxP);