diff --git a/common/ran_context.h b/common/ran_context.h
index 625e029382ed3bf222dad96eb2c64d53147c622c..4e25729c86a2377da0fd69b3a23093f8317e92f8 100644
--- a/common/ran_context.h
+++ b/common/ran_context.h
@@ -56,6 +56,8 @@ typedef struct {
   int *nb_CC;
   /// Number of MACRLC instances in this node
   int nb_macrlc_inst;
+  /// Number of component carriers per instance in this node
+  int *nb_mac_CC;
   /// Number of L1 instances in this node
   int nb_L1_inst;
   /// Number of Component Carriers per instance in this node
diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c
index d70a6386b94d4f5ca2b481a60aafb89e4fb09ef0..5ffb17c2345c9262341db5ff1a2fa30a101e2192 100644
--- a/common/utils/itti/intertask_interface.c
+++ b/common/utils/itti/intertask_interface.c
@@ -623,7 +623,7 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t
       read_ret = read (itti_desc.threads[thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
       AssertFatal (read_ret == sizeof(sem_counter), "Read from task message FD (%d) failed (%d/%d)!\n", thread_id, (int) read_ret, (int) sizeof(sem_counter));
 
-
+      printf("sem_counter %d task %d\n", (int)sem_counter, task_id);
       if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) {
         /* No element in list -> this should not happen */
         AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
@@ -631,9 +631,13 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t
 
       AssertFatal(message != NULL, "Message from message queue is NULL!\n");
       *received_msg = message->msg;
+
+      printf("ITTI: message %s\n", ITTI_MSG_NAME(message->msg));
+
       result = itti_free (ITTI_MSG_ORIGIN_ID(*received_msg), message);
       AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
 
+
       /* Mark that the event has been processed */
       itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN;
       return;
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index faf884429c53551a29f3fefe8e31d397e947a002..3a7eab5a5d7fe4874e17c00368cdaff93fdc5e98 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -153,91 +153,93 @@ void phy_config_request(PHY_Config_t *phy_config) {
                     RC.eNB[Mod_id][CC_id]->X_u);
 
 #ifdef Rel14
-  fp->prach_emtc_config_common.prach_Config_enabled=1;
-
-  fp->prach_emtc_config_common.rootSequenceIndex                                         = cfg->emtc_config.prach_catm_root_sequence_index.value;
-
-  fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag                            = cfg->emtc_config.prach_catm_high_speed_flag.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig                = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value;
-
-  // CE Level 3 parameters
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3]                  = cfg->emtc_config.prach_ce_level_3_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]   = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value;
-  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3],
-	      "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n");
-
-
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3]                     = cfg->emtc_config.prach_ce_level_3_configuration_index.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3]                      = cfg->emtc_config.prach_ce_level_3_frequency_offset.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_offset.value;
-  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1)
-    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-		      fp->frame_type,
-		      RC.eNB[Mod_id][CC_id]->X_u_br[3]);
-
-  // CE Level 2 parameters
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2]                  = cfg->emtc_config.prach_ce_level_2_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]   = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value;
-  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2],
-	      "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n");
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2]                     = cfg->emtc_config.prach_ce_level_2_configuration_index.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2]                      = cfg->emtc_config.prach_ce_level_2_frequency_offset.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_offset.value;
-  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1)
-    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-		      fp->frame_type,
-		      RC.eNB[Mod_id][CC_id]->X_u_br[2]);
-
-  // CE Level 1 parameters
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1]                  = cfg->emtc_config.prach_ce_level_1_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]   = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value;
-  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1],
-	      "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n");
-
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1]                     = cfg->emtc_config.prach_ce_level_1_configuration_index.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1]                      = cfg->emtc_config.prach_ce_level_1_frequency_offset.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_offset.value;
-  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1)
-    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-		      fp->frame_type,
-		      RC.eNB[Mod_id][CC_id]->X_u_br[1]);
+  if (cfg->emtc_config.prach_ce_level_0_enable.value == 1) {
+    fp->prach_emtc_config_common.prach_Config_enabled=1;
+
+    fp->prach_emtc_config_common.rootSequenceIndex                                         = cfg->emtc_config.prach_catm_root_sequence_index.value;
+
+    fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag                            = cfg->emtc_config.prach_catm_high_speed_flag.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig                = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value;
+
+    // CE Level 3 parameters
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3]                  = cfg->emtc_config.prach_ce_level_3_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]   = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value;
+    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3],
+		"prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n");
+
+
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3]                     = cfg->emtc_config.prach_ce_level_3_configuration_index.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3]                      = cfg->emtc_config.prach_ce_level_3_frequency_offset.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_offset.value;
+    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1)
+      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+			fp->frame_type,
+			RC.eNB[Mod_id][CC_id]->X_u_br[3]);
+
+    // CE Level 2 parameters
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2]                  = cfg->emtc_config.prach_ce_level_2_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]   = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value;
+    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2],
+		"prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n");
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2]                     = cfg->emtc_config.prach_ce_level_2_configuration_index.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2]                      = cfg->emtc_config.prach_ce_level_2_frequency_offset.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_offset.value;
+    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1)
+      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+			fp->frame_type,
+			RC.eNB[Mod_id][CC_id]->X_u_br[2]);
+
+    // CE Level 1 parameters
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1]                  = cfg->emtc_config.prach_ce_level_1_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]   = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value;
+    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1],
+		"prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n");
+
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1]                     = cfg->emtc_config.prach_ce_level_1_configuration_index.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1]                      = cfg->emtc_config.prach_ce_level_1_frequency_offset.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_offset.value;
+    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1)
+      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+			fp->frame_type,
+			RC.eNB[Mod_id][CC_id]->X_u_br[1]);
   
-  // CE Level 0 parameters
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]                  = cfg->emtc_config.prach_ce_level_0_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]   = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value;
-  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0],
-	      "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n",
-	      fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0],
-	      fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]);
-  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0,
-	      "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n");
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0]                     = cfg->emtc_config.prach_ce_level_0_configuration_index.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0]                      = cfg->emtc_config.prach_ce_level_0_frequency_offset.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0]                = cfg->emtc_config.prach_ce_level_0_hopping_enable.value;
-  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0]                = cfg->emtc_config.prach_ce_level_0_hopping_offset.value;
-  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1)
-    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-		      fp->frame_type,
-		      RC.eNB[Mod_id][CC_id]->X_u_br[0]);
+    // CE Level 0 parameters
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]                  = cfg->emtc_config.prach_ce_level_0_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]   = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value;
+    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0],
+		"prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n",
+		fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0],
+		fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]);
+    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0,
+		"prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n");
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0]                     = cfg->emtc_config.prach_ce_level_0_configuration_index.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0]                      = cfg->emtc_config.prach_ce_level_0_frequency_offset.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0]                = cfg->emtc_config.prach_ce_level_0_hopping_enable.value;
+    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0]                = cfg->emtc_config.prach_ce_level_0_hopping_offset.value;
+    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1)
+      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+			fp->frame_type,
+			RC.eNB[Mod_id][CC_id]->X_u_br[0]);
+  }
 #endif
 
 
@@ -264,9 +266,9 @@ void phy_config_request(PHY_Config_t *phy_config) {
   fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled     = 0;
   fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled  = 0;
   if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 1) 
-      fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
+    fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
   if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 2) 
-      fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1;
+    fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1;
   LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
   fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH   =  cfg->uplink_reference_signal_config.group_assignment.value;
   LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
@@ -313,14 +315,14 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
 }
 
 /*
-void phy_config_sib2_eNB(uint8_t Mod_id,
-                         int CC_id,
-                         RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
-                         ARFCN_ValueEUTRA_t *ul_CArrierFreq,
-                         long *ul_Bandwidth,
-                         AdditionalSpectrumEmission_t *additionalSpectrumEmission,
-                         struct MBSFN_SubframeConfigList  *mbsfn_SubframeConfigList)
-{
+  void phy_config_sib2_eNB(uint8_t Mod_id,
+  int CC_id,
+  RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
+  ARFCN_ValueEUTRA_t *ul_CArrierFreq,
+  long *ul_Bandwidth,
+  AdditionalSpectrumEmission_t *additionalSpectrumEmission,
+  struct MBSFN_SubframeConfigList  *mbsfn_SubframeConfigList)
+  {
 
   LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
   //LTE_eNB_UE_stats *eNB_UE_stats      = RC.eNB[Mod_id][CC_id].eNB_UE_stats;
@@ -347,7 +349,7 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
 
   init_prach_tables(839);
   compute_prach_seq(&fp->prach_config_common,fp->frame_type,
-                    RC.eNB[Mod_id][CC_id]->X_u);
+  RC.eNB[Mod_id][CC_id]->X_u);
 
   fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift;
   fp->pucch_config_common.nRB_CQI          = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI;
@@ -389,15 +391,15 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
   fp->soundingrs_ul_config_common.enabled_flag                        = 0;
 
   if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) {
-    fp->soundingrs_ul_config_common.enabled_flag                        = 1;
-    fp->soundingrs_ul_config_common.srs_BandwidthConfig                 = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
-    fp->soundingrs_ul_config_common.srs_SubframeConfig                  = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig;
-    fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
+  fp->soundingrs_ul_config_common.enabled_flag                        = 1;
+  fp->soundingrs_ul_config_common.srs_BandwidthConfig                 = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
+  fp->soundingrs_ul_config_common.srs_SubframeConfig                  = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig;
+  fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
 
-    if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
-      fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 1;
-    else
-      fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 0;
+  if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
+  fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 1;
+  else
+  fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 0;
   }
 
 
@@ -425,34 +427,34 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
 
   // MBSFN
   if (mbsfn_SubframeConfigList != NULL) {
-    fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count;
-
-    for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
-      fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod;
-      fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset;
-
-      if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
-        fp->MBSFN_config[i].fourFrames_flag = 0;
-        fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
-        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
-              fp->MBSFN_config[i].mbsfn_SubframeConfig);
-      } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
-        fp->MBSFN_config[i].fourFrames_flag = 1;
-        fp->MBSFN_config[i].mbsfn_SubframeConfig =
-          mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]|
-          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
-          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16);
-
-        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
-              fp->MBSFN_config[i].mbsfn_SubframeConfig);
-      }
-    }
+  fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count;
+
+  for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
+  fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod;
+  fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset;
+
+  if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
+  fp->MBSFN_config[i].fourFrames_flag = 0;
+  fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
+  LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
+  fp->MBSFN_config[i].mbsfn_SubframeConfig);
+  } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
+  fp->MBSFN_config[i].fourFrames_flag = 1;
+  fp->MBSFN_config[i].mbsfn_SubframeConfig =
+  mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]|
+  (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
+  (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16);
+
+  LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
+  fp->MBSFN_config[i].mbsfn_SubframeConfig);
+  }
+  }
 
   } else
-    fp->num_MBSFN_config = 0;
+  fp->num_MBSFN_config = 0;
 
   //
-}
+  }
 */
 
 void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
@@ -852,7 +854,7 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility
     PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8);
 
     LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti,
-                                   PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti);
+	  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti);
   }
 
   if(ho_failed) {
@@ -881,67 +883,67 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n
 }
 
 /*
-void phy_config_dedicated_eNB(uint8_t Mod_id,
-                              int CC_id,
-                              uint16_t rnti,
-                              struct PhysicalConfigDedicated *physicalConfigDedicated)
-{
+  void phy_config_dedicated_eNB(uint8_t Mod_id,
+  int CC_id,
+  uint16_t rnti,
+  struct PhysicalConfigDedicated *physicalConfigDedicated)
+  {
 
   PHY_VARS_eNB *eNB = RC.eNB[Mod_id][CC_id];
   int8_t UE_id = find_ue(rnti,eNB);
   int i;
 
   if (UE_id == -1) {
-    LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id);
-    return;
+  LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id);
+  return;
   }
 
 
   if (physicalConfigDedicated) {
-    eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated;
-    LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated);
-
-    if (physicalConfigDedicated->antennaInfo) {
-      switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
-      case AntennaInfoDedicated__transmissionMode_tm1:
-        eNB->transmission_mode[UE_id] = 1;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm2:
-        eNB->transmission_mode[UE_id] = 2;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm3:
-        eNB->transmission_mode[UE_id] = 3;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm4:
-        eNB->transmission_mode[UE_id] = 4;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm5:
-        eNB->transmission_mode[UE_id] = 5;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm6:
-        eNB->transmission_mode[UE_id] = 6;
-        break;
-      case AntennaInfoDedicated__transmissionMode_tm7:
-        lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
-
-	for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1;
-	eNB->transmission_mode[UE_id] = 7;
-	break;
-      default:
-        LOG_E(PHY,"Unknown transmission mode!\n");
-        break;
-      }
-      LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]);
+  eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated;
+  LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated);
+
+  if (physicalConfigDedicated->antennaInfo) {
+  switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
+  case AntennaInfoDedicated__transmissionMode_tm1:
+  eNB->transmission_mode[UE_id] = 1;
+  break;
+  case AntennaInfoDedicated__transmissionMode_tm2:
+  eNB->transmission_mode[UE_id] = 2;
+  break;
+  case AntennaInfoDedicated__transmissionMode_tm3:
+  eNB->transmission_mode[UE_id] = 3;
+  break;
+  case AntennaInfoDedicated__transmissionMode_tm4:
+  eNB->transmission_mode[UE_id] = 4;
+  break;
+  case AntennaInfoDedicated__transmissionMode_tm5:
+  eNB->transmission_mode[UE_id] = 5;
+  break;
+  case AntennaInfoDedicated__transmissionMode_tm6:
+  eNB->transmission_mode[UE_id] = 6;
+  break;
+  case AntennaInfoDedicated__transmissionMode_tm7:
+  lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
+
+  for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1;
+  eNB->transmission_mode[UE_id] = 7;
+  break;
+  default:
+  LOG_E(PHY,"Unknown transmission mode!\n");
+  break;
+  }
+  LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]);
 
-    } else {
-      LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id);
-    }
   } else {
-    LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id);
-    return;
+  LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id);
+  }
+  } else {
+  LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id);
+  return;
   }
 
-}
+  }
 */
 
 #if defined(Rel10) || defined(Rel14)
@@ -953,11 +955,11 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
 
 }
 /*
-void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
-                                    uint16_t rnti,
-                                    SCellToAddMod_r10_t *sCellToAddMod_r10,
-                                    int CC_id)
-{
+  void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
+  uint16_t rnti,
+  SCellToAddMod_r10_t *sCellToAddMod_r10,
+  int CC_id)
+  {
 
 
   uint8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][0]);
@@ -968,37 +970,37 @@ void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
   uint32_t carrier_freq_local;
 
   if ((dl_CarrierFreq_r10>=36000) && (dl_CarrierFreq_r10<=36199)) {
-    carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1
-    LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
-	  //eNB->frame
-	  0,
-	  CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
+  carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1
+  LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
+  //eNB->frame
+  0,
+  CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
   } else if ((dl_CarrierFreq_r10>=6150) && (dl_CarrierFreq_r10<=6449)) {
-    carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1
-    // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band
-    LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
-          //eNB->frame
-          0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
+  carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1
+  // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band
+  LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
+  //eNB->frame
+  0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
   } else {
-    LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id,
-	  //eNB->frame
-	  0,dl_CarrierFreq_r10,CC_id,UE_id);
+  LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id,
+  //eNB->frame
+  0,dl_CarrierFreq_r10,CC_id,UE_id);
   }
 
   if (physicalConfigDedicatedSCell_r10) {
-//#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB"
-    //  eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10;
-    LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id,
-	  //eNB->frame
-          0,CC_id,UE_id);
+  //#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB"
+  //  eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10;
+  LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id,
+  //eNB->frame
+  0,CC_id,UE_id);
   } else {
-    LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, 
-	  //eNB->frame
-	  0,CC_id,UE_id);
-    return;
+  LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, 
+  //eNB->frame
+  0,CC_id,UE_id);
+  return;
   }
 
-}
+  }
 */
 
 #endif
@@ -1172,7 +1174,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
       }
       if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) {
         if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) {
-        // configure PUCCH CQI reporting
+	  // 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)
@@ -1211,12 +1213,12 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
   phy_vars_ue->decode_MIB = 0;
   //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
   if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234)
-      phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
+    phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
   else
-      phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
+    phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
 
   LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti,
-                               phy_vars_ue->pdcch_vars[1][eNB_id]->crnti);
+	phy_vars_ue->pdcch_vars[1][eNB_id]->crnti);
 
 }
 
@@ -1653,7 +1655,7 @@ int phy_init_RU(RU_t *ru) {
       ru->common.txdata[i]  = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
 
       LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i],
-	     fp->samples_per_tti*10*sizeof(int32_t));
+	    fp->samples_per_tti*10*sizeof(int32_t));
 
     }
     for (i=0;i<ru->nb_rx;i++) {
@@ -1843,12 +1845,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
 #endif
   
   /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) 
-  AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
-              "nb_antennas_rx too large");
-  for (i=0; i<fp->nb_antennas_rx; i++) {
-    prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
-    LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
-    }*/
+     AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
+     "nb_antennas_rx too large");
+     for (i=0; i<fp->nb_antennas_rx; i++) {
+     prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
+     LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
+     }*/
   
   for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
     
@@ -1876,7 +1878,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
       pusch_vars[UE_id]->rxdataF_comp[i]     = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
       pusch_vars[UE_id]->ul_ch_mag[i]  = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
       pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
-      }
+    }
     
     pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
   } //UE_id
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index b9576e9c9d14f3505f58507eb620217956c2b2be..2e8d3f5e46a85ab08e8220a571473131d29d566f 100755
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -2130,11 +2130,11 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
 
       if (dci_alloc[i].L == (uint8_t)L) {
 
-#ifdef DEBUG_DCI_ENCODING
+	//#ifdef DEBUG_DCI_ENCODING
         LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L,
               *(unsigned int*)dci_alloc[i].dci_pdu);
         dump_dci(frame_parms,&dci_alloc[i]);
-#endif
+	//#endif
 
         if (dci_alloc[i].firstCCE>=0) {
           e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 2a43455e254b8a1e09c27b8e612b0934751847c6..7deb8e8da73f0d15c3318a16652decb736cfdd2b 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -863,13 +863,12 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 
   uint8_t *dci_pdu = &dci_alloc->dci_pdu[0];
   nfapi_dl_config_dci_dl_pdu_rel8_t *rel8 = &pdu->dci_dl_pdu_rel8;
-  int harq_pid;
+
   LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
   int beamforming_mode = 0;
   int UE_id=-1;
   int subframe = proc->subframe_tx;
-  int RIV_max;
   int NPRB;
   int TB0_active;
   int TB1_active;
@@ -882,7 +881,8 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
   dci_alloc->harq_pid = rel8->harq_process;
   dci_alloc->ra_flag  = 0;
 
-  LOG_D(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n",
+
+  LOG_I(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n",
 	rel8->dci_format,rel8->cce_idx,rel8->aggregation_level,rel8->rnti,rel8->harq_process);
   if ((rel8->rnti_type == 2 ) && (rel8->rnti != SI_RNTI) && (rel8->rnti != P_RNTI)) dci_alloc->ra_flag = 1;
 
@@ -898,12 +898,13 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
   dlsch1_harq                               = dlsch1->harq_processes[rel8->harq_process];
   dlsch1_harq->codeword                     = 1;
   dlsch0->subframe_tx[subframe]             = 1;  
-
+  dlsch0->harq_mask                         |= (1<<rel8->harq_process);
   switch (rel8->dci_format) {
 
   case NFAPI_DL_DCI_FORMAT_1A:
     dci_alloc->format     = format1A;
     dlsch0->active       = 1;
+    dlsch0->harq_mask                         |= (1<<rel8->harq_process);
 
     switch (fp->N_RB_DL) {
     case 6:
@@ -936,7 +937,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rel8->resource_block_coding];
       dlsch0_harq->vrb_type           =  rel8->virtual_resource_block_assignment_flag;
       dlsch0_harq->nb_rb          = RIV2nb_rb_LUT6[rel8->resource_block_coding];//NPRB;
-      RIV_max = RIV_max6;
       break;
     case 25:
       if (fp->frame_type == TDD) {
@@ -967,7 +967,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rel8->resource_block_coding];
       dlsch0_harq->vrb_type           =  rel8->virtual_resource_block_assignment_flag;
       dlsch0_harq->nb_rb          = RIV2nb_rb_LUT25[rel8->resource_block_coding];//NPRB;
-      RIV_max                     = RIV_max25;
       break;
     case 50:
       if (fp->frame_type == TDD) {
@@ -999,7 +998,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       dlsch0_harq->rb_alloc[1]     = localRIV2alloc_LUT50_1[rel8->resource_block_coding];
       dlsch0_harq->vrb_type           =  rel8->virtual_resource_block_assignment_flag;
       dlsch0_harq->nb_rb              = RIV2nb_rb_LUT50[rel8->resource_block_coding];//NPRB;
-      RIV_max = RIV_max50;
       break;
     case 100:
       if (fp->frame_type == TDD) {
@@ -1033,7 +1031,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rel8->resource_block_coding];
       dlsch0_harq->vrb_type         =  rel8->virtual_resource_block_assignment_flag;
       dlsch0_harq->nb_rb            = RIV2nb_rb_LUT100[rel8->resource_block_coding];//NPRB;
-      RIV_max = RIV_max100;
       break;
     }
 
@@ -1072,6 +1069,9 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 
     dci_alloc->format           = format1;
     dlsch0->active              = 1;
+    dlsch0->harq_mask           |= (1<<rel8->harq_process);
+
+    LOG_I(PHY,"Frame %d, Subframe %d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",proc->frame_tx,subframe,rel8->harq_process);
 
     switch (fp->N_RB_DL) {
     case 6:
@@ -1224,6 +1224,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 
     }
 
+    LOG_I(PHY,"DCI: Set harq_ids[%d] to %d\n",subframe,rel8->harq_process);
     dlsch0->harq_ids[subframe] = rel8->harq_process;
 
 
@@ -1414,15 +1415,18 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
     dlsch1_harq->Nl        = 1;
     dlsch0->active = 1;
     dlsch1->active = 1;
-
+    dlsch0->harq_mask                         |= (1<<rel8->harq_process);
+    dlsch1->harq_mask                         |= (1<<rel8->harq_process);
 
     // check if either TB is disabled (see 36-213 V11.3 Section )
     if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
       dlsch0->active = 0;
+      dlsch0->harq_mask                         &= ~(1<<rel8->harq_process);
     }
 
     if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
       dlsch1->active = 0;
+      dlsch1->harq_mask                         &= ~(1<<rel8->harq_process);
     }
 
    // dlsch0_harq->dl_power_off = 0;
@@ -1704,6 +1708,8 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
     if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) {
       dlsch0->active = 1;
       dlsch1->active = 1;
+      dlsch0->harq_mask                         |= (1<<rel8->harq_process);
+      dlsch1->harq_mask                         |= (1<<rel8->harq_process);
       dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
       dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
       dlsch0_harq->mcs = rel8->mcs_1;
@@ -1725,7 +1731,10 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       dlsch1 = eNB->dlsch[UE_id][0];
       dlsch0->active = 1;
       dlsch1->active = 1;
-      dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
+
+      dlsch0->harq_mask                         |= (1<<rel8->harq_process);
+      dlsch1->harq_mask                         |= (1<<rel8->harq_process);
+
       dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
       dlsch0_harq->mcs = rel8->mcs_1;
       dlsch1_harq->mcs = rel8->mcs_2;
@@ -1740,6 +1749,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
     }
     else if (TB0_active && (TB1_active==0)) {
       dlsch0->active = 1;
+      dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
       dlsch0_harq->mcs = rel8->mcs_1;
       dlsch0_harq->Qm  = get_Qm(rel8->mcs_1);
@@ -1754,6 +1764,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
     }
     else if ((TB0_active==0) && TB1_active) {
       dlsch1->active = 1;
+      dlsch1->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
       dlsch1_harq->mcs = rel8->mcs_2;
       dlsch1_harq->Qm  = get_Qm(rel8->mcs_2);
@@ -2196,7 +2207,7 @@ int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
   dlsch0_harq->dl_power_off = 1;
   
   dlsch0->active = 1;
-  
+  dlsch0->harq_mask                         |= (1<<rel13->harq_process);  
   
   
   if (dlsch0_harq->round == 0) {
@@ -2222,9 +2233,225 @@ int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
 
 }
 
-int fill_dci_and_ulsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_hi_dci0_dci_pdu *pdu) {
+void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
+	      nfapi_hi_dci0_dci_pdu *pdu) {
+
+  uint8_t UE_id;
+
+  AssertFatal((UE_id=find_ulsch(pdu->dci_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
+	      "No existing UE ULSCH for rnti %x\n",pdu->dci_pdu_rel8.rnti);
+
+  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
+
+  uint32_t cqi_req = pdu->dci_pdu_rel8.cqi_csi_request;
+  uint32_t dai     = pdu->dci_pdu_rel8.dl_assignment_index;
+  uint32_t cshift  = pdu->dci_pdu_rel8.cyclic_shift_2_for_drms;
+  uint32_t TPC     = pdu->dci_pdu_rel8.tpc;
+  uint32_t mcs     = pdu->dci_pdu_rel8.mcs_1;
+  uint32_t rballoc = computeRIV(frame_parms->N_RB_DL,
+				pdu->dci_pdu_rel8.resource_block_start,
+				pdu->dci_pdu_rel8.number_of_resource_block);
+
+  uint32_t ndi     = pdu->dci_pdu_rel8.new_data_indication_1;
+
+  void *dci_pdu = (void*)dci_alloc->dci_pdu;
+
+  dci_alloc->format   = format0;
+  dci_alloc->firstCCE = pdu->dci_pdu_rel8.cce_index;
+  dci_alloc->L        = pdu->dci_pdu_rel8.aggregation_level;
+  dci_alloc->rnti     = pdu->dci_pdu_rel8.rnti;
+  //  dci_alloc->harq_pid = pdu->dci_pdu_rel8.harq_process;
+  dci_alloc->ra_flag  = 0;
+
+  switch (frame_parms->N_RB_DL) {
+  case 6:
+    if (frame_parms->frame_type == TDD) {
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
+      //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
+    } else {
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift      = cshift;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC         = TPC;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs         = mcs;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi         = ndi;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
+      //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type        = 0;
+    }
+    
+    break;
+    
+  case 25:
+    if (frame_parms->frame_type == TDD) {
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
+      //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
+    } else {
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift      = cshift;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC         = TPC;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs         = mcs;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi         = ndi;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
+      //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->type        = 0;
+    }
+    
+    break;
+    
+  case 50:
+    if (frame_parms->frame_type == TDD) {
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
+      //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
+    } else {
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift      = cshift;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC         = TPC;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs         = mcs;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi         = ndi;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
+      //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->type = 0;
+    }
+    
+    break;
+    
+  case 100:
+    if (frame_parms->frame_type == TDD) {
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
+      //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
+    } else {
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift      = cshift;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC         = TPC;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs         = mcs;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi         = ndi;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
+      //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->type        = 0;
+    }
+    
+      //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc);
+      break;
+      
+  default:
+    LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+    DevParam (frame_parms->N_RB_DL, 0, 0);
+    break;
+  }
+}
+
+void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) {
+
+  uint8_t harq_pid;
+
+  uint8_t UE_id;
+
+  AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
+	      "No existing UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti);
+
+  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
+  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
+
+  int use_srs = 0;
+
+  harq_pid = ulsch_pdu->ulsch_pdu_rel8.harq_process_number;
+
+
+  ulsch->harq_processes[harq_pid]->frame                                 = frame;
+  ulsch->harq_processes[harq_pid]->subframe                              = subframe;
+
+  ulsch->harq_processes[harq_pid]->first_rb                              = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
+  ulsch->harq_processes[harq_pid]->nb_rb                                 = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
+
+  AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
+
+  ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
+  ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
+  ulsch->harq_processes[harq_pid]->n_DMRS                                = ulsch_pdu->ulsch_pdu_rel8.cyclic_shift_2_for_drms;
+  
+  ulsch->harq_processes[harq_pid]->Nsymb_pusch                           = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
+  ulsch->harq_processes[harq_pid]->srs_active                            = use_srs;
+  
+  //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
+  if(ulsch->harq_processes[harq_pid]->n_DMRS == 0)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 1)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 2)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 3)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 4)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 5)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 6)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;
+  
+   
+  LOG_I(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n",
+	eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS,
+	frame,subframe);
+  
+  
+  ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version;
+  ulsch->harq_processes[harq_pid]->Qm    = ulsch_pdu->ulsch_pdu_rel8.modulation_type;
+
 
-  exit(-1);
+  if (ulsch->harq_processes[harq_pid]->round == 0) {
+    ulsch->harq_processes[harq_pid]->status        = ACTIVE;
+    
+    ulsch->harq_processes[harq_pid]->TBS           = ulsch_pdu->ulsch_pdu_rel8.size<<3;
+    
+    ulsch->harq_processes[harq_pid]->Msc_initial   = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
+    ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch;
+    ulsch->harq_processes[harq_pid]->round = 0;
+  } 
+  
+  ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
+  LOG_I(PHY,"Filling ULSCH %x for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
+	ulsch->rnti,
+	frame,
+	subframe,
+	harq_pid,
+	ulsch->harq_processes[harq_pid]->first_rb,
+	ulsch->harq_processes[harq_pid]->nb_rb,
+	ulsch->harq_processes[harq_pid]->rvidx,
+	ulsch->harq_processes[harq_pid]->Qm,
+	ulsch->harq_processes[harq_pid]->TBS,
+	ulsch->harq_processes[harq_pid]->round);  
+  
+  
 }
 
 int generate_eNB_dlsch_params_from_dci(int frame,
@@ -6488,16 +6715,33 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
     uint8_t  rah       = pdci_info_extarcted->rah;
     uint8_t  dai       = pdci_info_extarcted->dai;
 
-    uint8_t  NPRB    = 0;
+    uint8_t  NPRB      = 0;
+    uint8_t  NPRB4TBS  = 0;
 
     if(dci_format == format1A)
     {
-        if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
+      switch (N_RB_DL) {
+      case 6:
+	NPRB     = RIV2nb_rb_LUT6[rballoc];
+	break;
+      case 25:
+	NPRB     = RIV2nb_rb_LUT25[rballoc];
+	break;
+      case 50:
+	NPRB     = RIV2nb_rb_LUT50[rballoc];
+	break;
+      case 100:
+	NPRB     = RIV2nb_rb_LUT100[rballoc];
+	break;
+      }
+      if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
         {
-            NPRB = (TPC&1) + 2;
+	  NPRB4TBS = (TPC&1) + 2;
         }
-        else
+      else
         {
+	  NPRB4TBS = NPRB;
+	  /*
             switch (N_RB_DL) {
             case 6:
                 NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
@@ -6512,11 +6756,13 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                 NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
                 break;
             }
+	  */
         }
     }
     else // format1
     {
         NPRB = conv_nprb(rah, rballoc, N_RB_DL);
+	NPRB4TBS=NPRB;
     }
 
     pdlsch0->current_harq_pid = harq_pid;
@@ -6607,7 +6853,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                 pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc];
                 pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT50_0[rballoc];
                 pdlsch0_harq->rb_alloc_odd[1]  = localRIV2alloc_LUT50_1[rballoc];
-                //      printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]);
+                      printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]);
             } else { // DISTRIBUTED
                 if ((rballoc&(1<<10)) == 0) {
                     rballoc = rballoc&(~(1<<10));
@@ -6674,14 +6920,14 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
 
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
     {
-        pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1];
+        pdlsch0_harq->TBS = TBStable[mcs1][NPRB4TBS-1];
         pdlsch0_harq->Qm  = 2;
     }
     else
     {
         if(mcs1 < 29)
         {
-            pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1];
+            pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB4TBS-1];
             pdlsch0_harq->Qm  = get_Qm(mcs1);
         }
     }
@@ -9443,6 +9689,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
 }
 
+/*
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
                                        eNB_rxtx_proc_t *proc,
                                        void *dci_pdu,
@@ -9612,13 +9859,13 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
 
 
     if (cqi_req == 1) {
-      /* 36.213 7.2.1 (release 10) says:
-       * "RI is only reported for transmission modes 3 and 4,
-       * as well as transmission modes 8 and 9 with PMI/RI reporting"
-       * This is for aperiodic reporting.
-       * TODO: deal with TM 8&9 correctly when they are implemented.
-       * TODO: deal with periodic reporting if we implement it.
-       */
+      // 36.213 7.2.1 (release 10) says:
+      // "RI is only reported for transmission modes 3 and 4,
+      // as well as transmission modes 8 and 9 with PMI/RI reporting"
+      // This is for aperiodic reporting.
+      // TODO: deal with TM 8&9 correctly when they are implemented.
+      // TODO: deal with periodic reporting if we implement it.
+      //
       if (transmission_mode == 3 || transmission_mode == 4)
         ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
       else
@@ -10022,13 +10269,13 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
       ulsch->harq_processes[harq_pid]->mcs         = mcs;
       //      ulsch->harq_processes[harq_pid]->calibration_flag = 0;
       //if (ulsch->harq_processes[harq_pid]->mcs)
-      /*
-      if (ulsch->harq_processes[harq_pid]->mcs == 29) {
-      ulsch->harq_processes[harq_pid]->mcs = 4;
+      //
+      //if (ulsch->harq_processes[harq_pid]->mcs == 29) {
+      //ulsch->harq_processes[harq_pid]->mcs = 4;
       // ulsch->harq_processes[harq_pid]->calibration_flag = 1;
       // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb);
-      }
-      */
+      //}
+      
       ulsch->harq_processes[harq_pid]->TBS         = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];
 
       ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch->harq_processes[harq_pid]->nb_rb;
@@ -10073,7 +10320,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
   }
 
 }
-
+*/
 
 double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe)
 {
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index e8be4facd4c4706a4fc58e92e446590fceee8ac7..fd5adcdf4b902db98918194e23718f12e92f1e51 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -398,14 +398,10 @@ typedef struct {
   uint8_t subframe;
   /// Frame for reception
   uint32_t frame;
-  /// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator)
-  uint8_t subframe_cba_scheduling_flag;
   /// PHICH active flag
   uint8_t phich_active;
   /// PHICH ACK
   uint8_t phich_ACK;
-  /// Last TPC command
-  uint8_t TPC;
   /// First Allocated RB
   uint16_t first_rb;
   /// First Allocated RB - previous scheduling
@@ -413,7 +409,9 @@ typedef struct {
   /// is done after a new scheduling
   uint16_t previous_first_rb;
   /// Current Number of RBs
-  uint16_t nb_rb;
+  uint16_t nb_rb; 
+  /// Current Modulation order
+  uint8_t Qm;
   /// Transport block size
   uint32_t TBS;
   /// The payload + CRC size in bits
@@ -468,8 +466,6 @@ typedef struct {
   uint8_t srs_active;
   /// Index of current HARQ round for this ULSCH
   uint8_t round;
-  /// MCS format for this ULSCH
-  uint8_t mcs;
   /// Redundancy-version of the current sub-frame
   uint8_t rvidx;
   /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
@@ -513,6 +509,9 @@ typedef enum {
   pucch_format1=0,
   pucch_format1a,
   pucch_format1b,
+  pucch_format1b_csA2,
+  pucch_format1b_csA3,
+  pucch_format1b_csA4,
   pucch_format2,
   pucch_format2a,
   pucch_format2b,
@@ -547,14 +546,24 @@ typedef struct {
   uint16_t    rnti;
   /// Type (SR,HARQ,CQI,HARQ_SR,HARQ_CQI,SR_CQI,HARQ_SR_CQI)
   UCI_type_t  type;
+  /// SRS active flag
+  uint8_t     srs_active;
   /// PUCCH format to use
   PUCCH_FMT_t pucch_fmt;
-  /// antenna indicator
+  /// number of PUCCH antenna ports 
+  uint8_t     num_antenna_ports;
+  /// number of PUCCH resources
   uint8_t     num_pucch_resources;
-  /// two antenna n1_pucch
-  uint16_t    n_pucch_1[2];
-  /// two antenna n2_pucch
+  /// two antenna n1_pucch 1_0
+  uint16_t    n_pucch_1[4][2];
+  /// two antenna n1_pucch 1_0 for SR
+  uint16_t    n_pucch_1_0_sr[2];
+   /// two antenna n2_pucch
   uint16_t    n_pucch_2[2];
+  /// two antenna n3_pucch
+  uint16_t    n_pucch_3[2];
+  /// TDD Bundling/multiplexing flag
+  uint8_t     tdd_bundling;
 #ifdef Rel14
   /// non BL/CE, CEmodeA, CEmodeB
   UE_type_t ue_type;
@@ -573,7 +582,7 @@ typedef struct {
   // Indicates if the resource blocks allocated for this grant overlap with the SRS configuration.
   uint8_t Nsrs;
 #endif
-} LTE_eNB_UCI_t;
+} LTE_eNB_UCI;
 
 typedef struct {
   /// HARQ process mask, indicates which processes are currently active
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index 489b6bbfcb6bfff96db0634110ff542f8889f226..091beddec7d5472725bec1bf7bf0a0e4c81d33c4 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -353,10 +353,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
 
 
-#ifdef DEBUG_PHY
+  //#ifdef DEBUG_PHY
   LOG_D(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
   LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
-#endif
+  //#endif
 
   aatx = frame_parms->nb_antenna_ports_eNB;
   aarx = frame_parms->nb_antennas_rx;
@@ -3327,9 +3327,9 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext,
 
   // Determine scaling amplitude based the symbol
 
-ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a));
-
-    LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol);
+  ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a));
+  
+  LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol);
    // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
 
   ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
index bbd29e6d70e1bb4acb7346b6b2075367656c3753..5eeb661f8cb4dba068ab9a6f36b40424c3855b4f 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
@@ -124,7 +124,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   }
 
 #ifdef DEBUG_SCRAMBLING
-  printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G);
+  printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2);
 #endif
   s = lte_gold_scram(&x1, &x2, 1);
 
@@ -206,7 +206,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
     x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1
 
 #ifdef DEBUG_SCRAMBLING
-  printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G);
+    printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d G %d, x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G,x2);
 #endif
   s = lte_gold_scram(&x1, &x2, 1);
 
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 1c77083deb79763000ffa3867a2c9d62aef9539a..ccd842f215bdf65a550415c6b7fc262f5b998769 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -200,14 +200,14 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) {
     if (packet_type > IF4p5_PRACH)
       rxF = &prach_rxsigF_br[packet_type - IF4p5_PRACH - 1][0][0];
     else 
-#else
+#endif
       rxF = &prach_rxsigF[0][0];
-#endif    
 
+    AssertFatal(rxF!=NULL,"rxF is null\n");
     if (eth->flags == ETH_RAW_IF4p5_MODE) {
-       memcpy((void *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t),
-              (void*)rxF, 
-              PRACH_BLOCK_SIZE_BYTES);
+      memcpy((void *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t),
+	     (void*)rxF, 
+	     PRACH_BLOCK_SIZE_BYTES);
     } else {
       memcpy((void *)(tx_buffer_prach + sizeof_IF4p5_header_t),
              (void *)rxF,
@@ -335,13 +335,14 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint
     if (*packet_type > IF4p5_PRACH)
       rxF = &prach_rxsigF_br[*packet_type - IF4p5_PRACH - 1][0][0];
     else 
-#else
-      rxF = &prach_rxsigF[0][0];
 #endif
+      rxF = &prach_rxsigF[0][0];
 
     // FIX: hard coded prach samples length
     db_fulllength = PRACH_NUM_SAMPLES;
 
+    AssertFatal(rxF!=NULL,"rxF is null\n");
+
     if (eth->flags == ETH_RAW_IF4p5_MODE) {		
       memcpy(rxF, 
              (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t), 
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index 121f9b84907727f7b3fd247d6f23736e9247b0d5..e44a345d907e2de42c3d29ef2fb07e5e92073ad5 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -1474,8 +1474,9 @@ void rx_phich(PHY_VARS_UE *ue,
     //ulsch->harq_processes[8] = ulsch->harq_processes[harq_pid];
 
 
-    ulsch->harq_processes[harq_pid]->status = SCH_IDLE;
-    ulsch->harq_processes[harq_pid]->round  = 0;
+    ulsch->harq_processes[harq_pid]->status                   = SCH_IDLE;
+    ulsch->harq_processes[harq_pid]->round                    = 0;
+    ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
     // inform MAC?
     ue->ulsch_Msg3_active[eNB_id] = 0;
 
@@ -1490,21 +1491,20 @@ void rx_phich(PHY_VARS_UE *ue,
 
 void generate_phich_top(PHY_VARS_eNB *eNB,
                         eNB_rxtx_proc_t *proc,
-			int16_t amp,
-                        uint8_t sect_id)
+			int16_t amp)
 {
 
 
   LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms;
-  LTE_eNB_ULSCH_t **ulsch = eNB->ulsch;
   int32_t **txdataF = eNB->common_vars.txdataF;
   uint8_t harq_pid;
   uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH;
   uint8_t NSF_PHICH = 4;
   uint8_t pusch_subframe;
-  uint8_t UE_id;
+  uint8_t i;
   uint32_t pusch_frame;
   int subframe = proc->subframe_tx;
+  phich_config_t *phich;
 
   // compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211
 
@@ -1520,98 +1520,42 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
   pusch_subframe = phich_subframe2_pusch_subframe(frame_parms,subframe);
   harq_pid = subframe2harq_pid(frame_parms,pusch_frame,pusch_subframe);
 
-  for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
-    if ((ulsch[UE_id])&&(ulsch[UE_id]->rnti>0)) {
-      if (ulsch[UE_id]->harq_processes[harq_pid]->phich_active == 1) {
+  for (i=0; i<eNB->phich_vars[subframe&1].num_hi; i++) {
 
-        LOG_I(PHY,"[eNB][PUSCH %d/%x] Frame %d subframe %d (pusch_subframe %d,pusch_frame %d) phich active %d\n",
-              harq_pid,ulsch[UE_id]->rnti,proc->frame_tx,subframe,pusch_subframe,pusch_frame,ulsch[UE_id]->harq_processes[harq_pid]->phich_active);
-
-        /* the HARQ process may have been reused by a new scheduling, so we use
-         * previous values of first_rb and n_DMRS to compute ngroup_PHICH and nseq_PHICH
-         */
-
-        ngroup_PHICH = (ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb +
-                        ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)%Ngroup_PHICH;
-
-        if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) {
-
-          if ((pusch_subframe == 4) || (pusch_subframe == 9))
-            ngroup_PHICH += Ngroup_PHICH;
-        }
-
-        nseq_PHICH = ((ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb/Ngroup_PHICH) +
-                      ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)%(2*NSF_PHICH);
-        LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d dci_alloc %d)\n",
-              eNB->Mod_id,harq_pid,proc->frame_tx,
-              subframe,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,
-              ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK,
-              ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb,
-              ulsch[UE_id]->harq_processes[harq_pid]->dci_alloc);
-
-        T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe),
-          T_INT(UE_id), T_INT(ulsch[UE_id]->rnti), T_INT(harq_pid),
-          T_INT(Ngroup_PHICH), T_INT(NSF_PHICH),
-          T_INT(ngroup_PHICH), T_INT(nseq_PHICH),
-          T_INT(ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK),
-          T_INT(ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb),
-          T_INT(ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS));
-
-        if (ulsch[UE_id]->Msg3_active == 1) {
-          LOG_I(PHY,"[eNB %d][PUSCH %d][RAPROC] Frame %d, subframe %d: Generating Msg3 PHICH for UE %d, ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d\n",
-                eNB->Mod_id,harq_pid,proc->frame_tx,subframe,
-                UE_id,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK,
-                ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb);
-        }
-
-        if (eNB->abstraction_flag == 0) {
-          generate_phich(frame_parms,
-                         amp,//amp*2,
-                         nseq_PHICH,
-                         ngroup_PHICH,
-                         ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK,
-                         subframe,
-                         txdataF);
-        } else {
-          /*
-          generate_phich_emul(frame_parms,
-                  //nseq_PHICH,
-                  //ngroup_PHICH,
-                  ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK,
-                  subframe);
-          */
-        }
-
-        // if no format0 DCI was transmitted by MAC, prepare the
-        // MCS parameters for the retransmission
-
-
-        if ((ulsch[UE_id]->harq_processes[harq_pid]->dci_alloc == 0) &&
-            (ulsch[UE_id]->harq_processes[harq_pid]->rar_alloc == 0) ) {
-          if (ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK==0 ) {
-            T(T_ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION, T_INT(eNB->Mod_id), T_INT(proc->frame_tx),
-              T_INT(subframe), T_INT(UE_id), T_INT(ulsch[UE_id]->rnti), T_INT(harq_pid));
-            LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d, subframe %d : PHICH NACK / (no format0 DCI) Setting subframe_scheduling_flag\n",
-                  eNB->Mod_id,harq_pid,proc->frame_tx,subframe);
-	    //            ulsch[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
-	    ulsch[UE_id]->harq_processes[harq_pid]->subframe = (subframe + 4)%10;
- 	    if (subframe>5) ulsch[UE_id]->harq_processes[harq_pid]->frame++;
-            ulsch[UE_id]->harq_processes[harq_pid]->rvidx = rv_table[ulsch[UE_id]->harq_processes[harq_pid]->round&3];
-            ulsch[UE_id]->harq_processes[harq_pid]->O_RI                                  = 0;
-            ulsch[UE_id]->harq_processes[harq_pid]->Or2                                   = 0;
-            ulsch[UE_id]->harq_processes[harq_pid]->Or1                                   = 0;
-            ulsch[UE_id]->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
-
-          } else {
-            LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d PHICH ACK (no format0 DCI) Clearing subframe_scheduling_flag, setting round to 0\n",
-                  eNB->Mod_id,harq_pid,proc->frame_tx,subframe);
-	    ulsch[UE_id]->harq_processes[harq_pid]->status = SCH_IDLE;
-            ulsch[UE_id]->harq_processes[harq_pid]->round=0;
-          }
-        }
-
-        ulsch[UE_id]->harq_processes[harq_pid]->phich_active=0;
-      } // phich_active==1
-    } //ulsch_ue[UE_id] is non-null
-  }// UE loop
+    phich = &eNB->phich_vars[subframe&1].config[i];
+    
+    ngroup_PHICH = (phich->first_rb +
+		    phich->n_DMRS)%Ngroup_PHICH;
+    
+    if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) {
+      
+      if ((pusch_subframe == 4) || (pusch_subframe == 9))
+	ngroup_PHICH += Ngroup_PHICH;
+    }
+    
+    nseq_PHICH = ((phich->first_rb/Ngroup_PHICH) +
+		  phich->n_DMRS)%(2*NSF_PHICH);
+    LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, AMP %d  ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d)\n",
+	  eNB->Mod_id,harq_pid,proc->frame_tx,
+	  subframe,amp,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,
+	  phich->hi,
+	  phich->first_rb);
+    
+    T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe),
+      T_INT(i), T_INT(0), T_INT(harq_pid),
+      T_INT(Ngroup_PHICH), T_INT(NSF_PHICH),
+      T_INT(ngroup_PHICH), T_INT(nseq_PHICH),
+      T_INT(phich->hi),
+      T_INT(phich->first_rb),
+      T_INT(phich->n_DMRS));
+    
+    generate_phich(frame_parms,
+		   amp,//amp*2,
+		   nseq_PHICH,
+		   ngroup_PHICH,
+		   phich->hi,
+		   subframe,
+		   txdataF);
+  }//  for (i=0; i<eNB->phich_vars[subframe&1].num_hi; i++) { 
+  eNB->phich_vars[subframe&1].num_hi=0;
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 867a2877fef174a46d5845673c490572ef93ca03..f69a22419c900ce26a87b04cbfb7cefd36f9978c 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -1661,11 +1661,12 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
 			DCI_ALLOC_t *dci_alloc,
 			nfapi_dl_config_dci_dl_pdu *pdu);
 
+int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu);
 
-int fill_dci_and_ulsch(PHY_VARS_eNB *eNB,
-			eNB_rxtx_proc_t *proc,
-			DCI_ALLOC_t *dci_alloc,
-			nfapi_hi_dci0_dci_pdu *pdu);
+void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
+	      nfapi_hi_dci0_dci_pdu *pdu);
+
+void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe);
 
 int32_t generate_eNB_dlsch_params_from_dci(int frame,
     uint8_t subframe,
@@ -1862,8 +1863,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB,
 
 void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
 			eNB_rxtx_proc_t *proc,
-                        int16_t amp,
-                        uint8_t sect_id);
+                        int16_t amp);
 
 /* \brief  This routine demodulates the PHICH and updates PUSCH/ULSCH parameters.
    @param phy_vars_ue Pointer to UE variables
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 47e60808c3916a002e4febd8abe113791af06353..add3d67554d5afd830789fe1b218443252cf7eb4 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -1857,25 +1857,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     }
     first_call=0;
   }
-  /*
-  switch (frame_parms->N_RB_UL) {
-
-  case 6:
-    sigma2_dB -= 8;
-    break;
-  case 25:
-    sigma2_dB -= 14;
-    break;
-  case 50:
-    sigma2_dB -= 17;
-    break;
-  case 100:
-    sigma2_dB -= 20;
-    break;
-  default:
-    sigma2_dB -= 14;
-  }
-  */  
+
 
   if(fmt!=pucch_format3) {  /* PUCCH format3 */
   
@@ -2241,8 +2223,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
               stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
               stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
             } else { //reference_symbols
-              stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
-              stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
+              stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
+              stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
             }
 
             off+=2;
@@ -2420,13 +2402,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
       if (fmt==pucch_format1b)
         *(1+payload) = (stat_im<0) ? 1 : 0;
     } else { // insufficient energy on PUCCH so NAK
-      *payload = 0;
+      *payload = 4;  // DTX
       ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re);
       ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im);
       eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
 
       if (fmt==pucch_format1b)
-        *(1+payload) = 0;
+        *(1+payload) = 6;
     }
   } else {
     LOG_E(PHY,"[eNB] PUCCH fmt2/2a/2b not supported\n");
diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c
index 92f2851a6d57c1b7b8ee1cbdf4cdb59040da6c0d..158521f5985c4c5469279b69f2c3c0800d77826c 100644
--- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c
@@ -116,7 +116,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB,
     break;
   }
 
-  ulsch_harq->TPC                = (rar[3]>>2)&7;//rar->TPC;
+
   rballoc = (((uint16_t)(rar[1]&7))<<7)|(rar[2]>>1);
 
   if (rballoc>RIV_max) {
@@ -150,19 +150,19 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB,
   ulsch->rnti = rnti;
   ulsch->harq_mask = 1<<harq_pid;
 
-  if (ulsch_harq->round == 0) {
+  //  if (ulsch_harq->round == 0) {
     ulsch_harq->status = ACTIVE;
     ulsch_harq->rvidx = 0;
-    ulsch_harq->mcs         = ((rar[2]&1)<<3)|(rar[3]>>5);
-    //ulsch_harq->TBS         = dlsch_tbs25[ulsch_harq->mcs][ulsch_harq->nb_rb-1];
-    ulsch_harq->TBS         = TBStable[get_I_TBS_UL(ulsch_harq->mcs)][ulsch_harq->nb_rb-1];
+    uint8_t mcs               = ((rar[2]&1)<<3)|(rar[3]>>5);
+    ulsch_harq->TBS           = TBStable[get_I_TBS_UL(mcs)][ulsch_harq->nb_rb-1];
+    ulsch_harq->Qm            = get_Qm_ul(mcs);
     ulsch_harq->Msc_initial   = 12*ulsch_harq->nb_rb;
     ulsch_harq->Nsymb_initial = 9;
     ulsch_harq->round = 0;
-  } else {
+    /*  } else {
     ulsch_harq->rvidx = 0;
     ulsch_harq->round++;
-  }
+    }*/
 
 
   ulsch->Msg3_active = 1;
@@ -173,6 +173,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB,
 		 &ulsch_harq->frame,
 		 &ulsch_harq->subframe);
 
+  LOG_I(PHY,"Programming msg3 reception in (%d,%d)\n",ulsch_harq->frame,ulsch_harq->subframe);
   use_srs = is_srs_occasion_common(frame_parms,ulsch_harq->frame,ulsch_harq->subframe);
   ulsch_harq->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
   ulsch_harq->srs_active                            = use_srs;
@@ -264,15 +265,11 @@ int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue,
   ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT[rballoc];
   ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT[rballoc];
 
-  if (ulsch->harq_processes[harq_pid]->nb_rb ==0)
-    return(-1);
+  AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb >0, "nb_rb == 0\n");
 
   ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb];
 
-  if (ulsch->harq_processes[harq_pid]->nb_rb > 4) {
-    LOG_D(PHY,"rar_tools.c: unlikely rb count for RAR grant : nb_rb > 3\n");
-    return(-1);
-  }
+  AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb > 6,"unlikely rb count for RAR grant : nb_rb > 6\n");
 
   //  ulsch->harq_processes[harq_pid]->Ndi                                   = 1;
   if (ulsch->harq_processes[harq_pid]->round == 0)
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
index 8b72b4e73332c5c9d74c6452ffe380b9cceb1d08..f61749e6cac54e3b88cd8ba6d842eae0dea0b862 100644
--- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
@@ -232,18 +232,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_
       stats->DL_pmi_dual   = ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi;
       break;
 
-    case HLC_subband_cqi_mcs_CBA:
-      if ((*crnti == ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti) && (*crnti !=0)) {
-        *access_mode=CBA_ACCESS;
-        LOG_N(PHY,"[eNB] UCI for CBA : mcs %d  crnti %x\n",
-              ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti);
-      } else {
-        LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n",
-              *crnti, ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti);
-      }
-
-      break;
-
     case unknown_cqi:
     default:
       LOG_N(PHY,"[eNB][UCI] received unknown uci (rb %d)\n",N_RB_DL);
@@ -318,18 +306,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_
       stats->DL_pmi_dual   = ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi;
       break;
 
-    case HLC_subband_cqi_mcs_CBA:
-      if ((*crnti == ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti) && (*crnti !=0)) {
-        *access_mode=CBA_ACCESS;
-        LOG_N(PHY,"[eNB] UCI for CBA : mcs %d  crnti %x\n",
-              ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti);
-      } else {
-        LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n",
-              *crnti, ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti);
-      }
-
-      break;
-
     case unknown_cqi:
     default:
       LOG_N(PHY,"[eNB][UCI] received unknown uci (rb %d)\n",N_RB_DL);
@@ -398,18 +374,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_
       stats->DL_pmi_dual   = ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi;
       break;
 
-    case HLC_subband_cqi_mcs_CBA:
-      if ((*crnti == ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti) && (*crnti !=0)) {
-        *access_mode=CBA_ACCESS;
-        LOG_N(PHY,"[eNB] UCI for CBA : mcs %d  crnti %x\n",
-              ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti);
-      } else {
-        LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n",
-              *crnti, ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti);
-      }
-
-      break;
-
     case unknown_cqi:
     default:
       LOG_N(PHY,"[eNB][UCI] received unknown uci (RB %d)\n",N_RB_DL);
@@ -478,18 +442,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_
       stats->DL_pmi_dual   = ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi;
       break;
 
-    case HLC_subband_cqi_mcs_CBA:
-      if ((*crnti == ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti) && (*crnti !=0)) {
-        *access_mode=CBA_ACCESS;
-        LOG_N(PHY,"[eNB] UCI for CBA : mcs %d  crnti %x\n",
-              ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti);
-      } else {
-        LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n",
-              *crnti, ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti);
-      }
-
-      break;
-
     case unknown_cqi:
     default:
       LOG_N(PHY,"[eNB][UCI] received unknown uci (RB %d)\n",N_RB_DL);
@@ -750,13 +702,6 @@ void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL)
       break;
     }
 
-#endif //DEBUG_UCI
-    break;
-
-  case HLC_subband_cqi_mcs_CBA:
-#ifdef DEBUG_UCI
-    LOG_I(PHY,"[PRINT CQI] hlc_cqi_mcs_CBA : eNB %d, mcs %d\n",eNB_id,((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs);
-    LOG_I(PHY,"[PRINT CQI] hlc_cqi_mcs_CBA : eNB %d, rnti %x\n",eNB_id,((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti);
 #endif //DEBUG_UCI
     break;
 
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 6ff4fd58fd5680671bf7ca5a30893d7f0b7440f9..ac2c682bc1681e54b3909dd577fa1472b3fc30b4 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -224,7 +224,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
   int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
   LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
   LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
-  int Q_m = get_Qm_ul(ulsch_harq->mcs);
+  int Q_m = ulsch_harq->Qm;
   int G = ulsch_harq->G;
   uint32_t E;
   uint32_t Gp,GpmodC,Nl=1;
@@ -352,7 +352,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
                                    1,
                                    ulsch_harq->rvidx,
                                    (ulsch_harq->round==0)?1:0,  // clear
-                                   get_Qm_ul(ulsch_harq->mcs),
+                                   ulsch_harq->Qm,
                                    1,
                                    r,
                                    &E)==-1) {
@@ -447,7 +447,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
   int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
   LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
   LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
-  //int Q_m = get_Qm_ul(ulsch_harq->mcs);
+
   int G = ulsch_harq->G;
   unsigned int E;
   int Cby2;
@@ -571,7 +571,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
                                    1,
                                    ulsch_harq->rvidx,
                                    (ulsch_harq->round==0)?1:0,  // clear
-                                   get_Qm_ul(ulsch_harq->mcs),
+                                   ulsch_harq->Qm,
                                    1,
                                    r,
                                    &E)==-1) {
@@ -655,7 +655,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
   int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
   LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
   LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
-  //int Q_m = get_Qm_ul(ulsch_harq->mcs);
+
   int G = ulsch_harq->G;
   unsigned int E;
 
@@ -736,7 +736,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
                                    1,
                                    ulsch_harq->rvidx,
                                    (ulsch_harq->round==0)?1:0,  // clear
-                                   get_Qm_ul(ulsch_harq->mcs),
+                                   ulsch_harq->Qm,
                                    1,
                                    r,
                                    &E)==-1) {
@@ -907,16 +907,15 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   A = ulsch_harq->TBS;
 
 
-  Q_m = get_Qm_ul(ulsch_harq->mcs);
+  Q_m = ulsch_harq->Qm;
   G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
 
 
 #ifdef DEBUG_ULSCH_DECODING
-  printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
+  printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
       frame_parms->Nid_cell,ulsch->rnti,x2,
       ulsch_harq->round,
       ulsch_harq->rvidx,
-      ulsch_harq->mcs,
       ulsch_harq->O_RI,
       ulsch_harq->O_ACK,
       G,
@@ -952,12 +951,11 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   }
 
   AssertFatal(sumKr>0,
-	      "[eNB %d] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
+	      "[eNB %d] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
 	      frame_parms->Nid_cell,ulsch->rnti,x2,
 	      harq_pid,
 	      ulsch_harq->round,
 	      ulsch_harq->rvidx,
-	      ulsch_harq->mcs,
 	      ulsch_harq->O_RI,
 	      ulsch_harq->O_ACK,
 	      G,
@@ -2015,41 +2013,6 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
   } else
     *crnti = 0x0;
 
-  // Do abstraction here to determine if packet it in error
-  /* if (ulsch_abstraction_MIESM(eNB->sinr_dB_eNB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1)
-   flag = 1;
-   else flag = 0;*/
-
-
-  /*
-  //SINRdbPost = eNB->sinr_dB_eNB;
-  mcsPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,
-  nrbPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb;
-  frbPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb;
-
-
-  if(nrbPost > 0)
-  {
-  SINRdbPost = eNB->sinr_dB_eNB;
-  ULflag1 = 1;
-  }
-  else
-  {
-   SINRdbPost = NULL  ;
-   ULflag1 = 0 ;
-  }*/
-
-  //
-  // write_output("postprocSINR.m","SINReNB",eNB->sinr_dB,301,1,7);
-
-
-  //Yazdir buraya her frame icin 300 eNb
-  // fprintf(SINRrx,"%e,%e,%e,%e;\n",SINRdbPost);
-  //fprintf(SINRrx,"%e\n",SINRdbPost);
-
-  // fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
-
-  // if (ulsch_abstraction(eNB->sinr_dB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1) {
   if (1) {
     LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n");
 
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index 18f46adf8f8838dcb47ee963e79ab15c7d01405a..1c947949a71b555f9e6dc2db28a634b6186bb563 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -1025,381 +1025,16 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
 
 
 
-#if defined(__x86_64__) || defined(__i386__)
-__m128i QAM_amp128U_0,QAM_amp128bU_0,QAM_amp128U_1,QAM_amp128bU_1;
-#endif
-
-void ulsch_channel_compensation_alamouti(int32_t **rxdataF_ext,                 // For Distributed Alamouti Combining
-    int32_t **ul_ch_estimates_ext_0,
-    int32_t **ul_ch_estimates_ext_1,
-    int32_t **ul_ch_mag_0,
-    int32_t **ul_ch_magb_0,
-    int32_t **ul_ch_mag_1,
-    int32_t **ul_ch_magb_1,
-    int32_t **rxdataF_comp_0,
-    int32_t **rxdataF_comp_1,
-    LTE_DL_FRAME_PARMS *frame_parms,
-    uint8_t symbol,
-    uint8_t Qm,
-    uint16_t nb_rb,
-    uint8_t output_shift)
-{
-#if defined(__x86_64__) || defined(__i386__)
-  uint16_t rb;
-  __m128i *ul_ch128_0,*ul_ch128_1,*ul_ch_mag128_0,*ul_ch_mag128_1,*ul_ch_mag128b_0,*ul_ch_mag128b_1,*rxdataF128,*rxdataF_comp128_0,*rxdataF_comp128_1;
-  uint8_t aarx;//,symbol_mod;
-  __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
-
-  //  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
-
-  //    printf("comp: symbol %d\n",symbol);
-
-
-  if (Qm == 4) {
-    QAM_amp128U_0 = _mm_set1_epi16(QAM16_n1);
-    QAM_amp128U_1 = _mm_set1_epi16(QAM16_n1);
-  } else if (Qm == 6) {
-    QAM_amp128U_0  = _mm_set1_epi16(QAM64_n1);
-    QAM_amp128bU_0 = _mm_set1_epi16(QAM64_n2);
-
-    QAM_amp128U_1  = _mm_set1_epi16(QAM64_n1);
-    QAM_amp128bU_1 = _mm_set1_epi16(QAM64_n2);
-  }
-
-  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-
-    ul_ch128_0          = (__m128i *)&ul_ch_estimates_ext_0[aarx][symbol*frame_parms->N_RB_DL*12];
-    ul_ch_mag128_0      = (__m128i *)&ul_ch_mag_0[aarx][symbol*frame_parms->N_RB_DL*12];
-    ul_ch_mag128b_0     = (__m128i *)&ul_ch_magb_0[aarx][symbol*frame_parms->N_RB_DL*12];
-    ul_ch128_1          = (__m128i *)&ul_ch_estimates_ext_1[aarx][symbol*frame_parms->N_RB_DL*12];
-    ul_ch_mag128_1      = (__m128i *)&ul_ch_mag_1[aarx][symbol*frame_parms->N_RB_DL*12];
-    ul_ch_mag128b_1     = (__m128i *)&ul_ch_magb_1[aarx][symbol*frame_parms->N_RB_DL*12];
-    rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
-    rxdataF_comp128_0   = (__m128i *)&rxdataF_comp_0[aarx][symbol*frame_parms->N_RB_DL*12];
-    rxdataF_comp128_1   = (__m128i *)&rxdataF_comp_1[aarx][symbol*frame_parms->N_RB_DL*12];
-
-
-    for (rb=0; rb<nb_rb; rb++) {
-      //      printf("comp: symbol %d rb %d\n",symbol,rb);
-      if (Qm>2) {
-        // get channel amplitude if not QPSK
-
-        mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],ul_ch128_0[0]);
-
-        mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
 
-        mmtmpU1 = _mm_madd_epi16(ul_ch128_0[1],ul_ch128_0[1]);
-        mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-        mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
 
-        ul_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
-        ul_ch_mag128b_0[0] = ul_ch_mag128_0[0];
-        ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128U_0);
-        ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],2); // 2 to compensate the scale channel estimate
 
-        ul_ch_mag128_0[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0);
-        ul_ch_mag128b_0[1] = ul_ch_mag128_0[1];
-        ul_ch_mag128_0[1] = _mm_mulhi_epi16(ul_ch_mag128_0[1],QAM_amp128U_0);
-        ul_ch_mag128_0[1] = _mm_slli_epi16(ul_ch_mag128_0[1],2); // 2 to scale compensate the scale channel estimate
 
-        mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],ul_ch128_0[2]);
-        mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-        mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
 
-        ul_ch_mag128_0[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
-        ul_ch_mag128b_0[2] = ul_ch_mag128_0[2];
 
-        ul_ch_mag128_0[2] = _mm_mulhi_epi16(ul_ch_mag128_0[2],QAM_amp128U_0);
-        ul_ch_mag128_0[2] = _mm_slli_epi16(ul_ch_mag128_0[2],2);  //  2 to scale compensate the scale channel estimat
 
 
-        ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128bU_0);
-        ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],2);  //  2 to scale compensate the scale channel estima
 
 
-        ul_ch_mag128b_0[1] = _mm_mulhi_epi16(ul_ch_mag128b_0[1],QAM_amp128bU_0);
-        ul_ch_mag128b_0[1] = _mm_slli_epi16(ul_ch_mag128b_0[1],2);   //  2 to scale compensate the scale channel estima
-
-        ul_ch_mag128b_0[2] = _mm_mulhi_epi16(ul_ch_mag128b_0[2],QAM_amp128bU_0);
-        ul_ch_mag128b_0[2] = _mm_slli_epi16(ul_ch_mag128b_0[2],2);   //  2 to scale compensate the scale channel estima
-
-
-
-
-        mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],ul_ch128_1[0]);
-
-        mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-
-        mmtmpU1 = _mm_madd_epi16(ul_ch128_1[1],ul_ch128_1[1]);
-        mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-        mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1);
-
-        ul_ch_mag128_1[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0);
-        ul_ch_mag128b_1[0] = ul_ch_mag128_1[0];
-        ul_ch_mag128_1[0] = _mm_mulhi_epi16(ul_ch_mag128_1[0],QAM_amp128U_1);
-        ul_ch_mag128_1[0] = _mm_slli_epi16(ul_ch_mag128_1[0],2); // 2 to compensate the scale channel estimate
-
-        ul_ch_mag128_1[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0);
-        ul_ch_mag128b_1[1] = ul_ch_mag128_1[1];
-        ul_ch_mag128_1[1] = _mm_mulhi_epi16(ul_ch_mag128_1[1],QAM_amp128U_1);
-        ul_ch_mag128_1[1] = _mm_slli_epi16(ul_ch_mag128_1[1],2); // 2 to scale compensate the scale channel estimate
-
-        mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],ul_ch128_1[2]);
-        mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-        mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0);
-
-        ul_ch_mag128_1[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
-        ul_ch_mag128b_1[2] = ul_ch_mag128_1[2];
-
-        ul_ch_mag128_1[2] = _mm_mulhi_epi16(ul_ch_mag128_1[2],QAM_amp128U_0);
-        ul_ch_mag128_1[2] = _mm_slli_epi16(ul_ch_mag128_1[2],2);  //  2 to scale compensate the scale channel estimat
-
-
-        ul_ch_mag128b_1[0] = _mm_mulhi_epi16(ul_ch_mag128b_1[0],QAM_amp128bU_1);
-        ul_ch_mag128b_1[0] = _mm_slli_epi16(ul_ch_mag128b_1[0],2);  //  2 to scale compensate the scale channel estima
-
-
-        ul_ch_mag128b_1[1] = _mm_mulhi_epi16(ul_ch_mag128b_1[1],QAM_amp128bU_1);
-        ul_ch_mag128b_1[1] = _mm_slli_epi16(ul_ch_mag128b_1[1],2);   //  2 to scale compensate the scale channel estima
-
-        ul_ch_mag128b_1[2] = _mm_mulhi_epi16(ul_ch_mag128b_1[2],QAM_amp128bU_1);
-        ul_ch_mag128b_1[2] = _mm_slli_epi16(ul_ch_mag128b_1[2],2);   //  2 to scale compensate the scale channel estima
-      }
-
-
-      /************************For Computing (y)*(h0*)********************************************/
-
-      // multiply by conjugated channel
-      mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],rxdataF128[0]);
-      //  print_ints("re",&mmtmpU0);
-
-      // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
-      mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[0],_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
-      //  print_ints("im",&mmtmpU1);
-      mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]);
-      // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
-      mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-      //  print_ints("re(shift)",&mmtmpU0);
-      mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-      //  print_ints("im(shift)",&mmtmpU1);
-      mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
-      mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
-      //        print_ints("c0",&mmtmpU2);
-      //  print_ints("c1",&mmtmpU3);
-      rxdataF_comp128_0[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[0]);
-      //        print_shorts("ch:",ul_ch128_0[0]);
-      //        print_shorts("pack:",rxdataF_comp128_0[0]);
-
-      // multiply by conjugated channel
-      mmtmpU0 = _mm_madd_epi16(ul_ch128_0[1],rxdataF128[1]);
-      // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
-      mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[1],_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
-      mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[1]);
-      // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
-      mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-      mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-      mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
-      mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
-
-      rxdataF_comp128_0[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[1]);
-      //        print_shorts("ch:",ul_ch128_0[1]);
-      //        print_shorts("pack:",rxdataF_comp128_0[1]);
-      //       multiply by conjugated channel
-      mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],rxdataF128[2]);
-      // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
-      mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[2],_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
-      mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[2]);
-      // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
-      mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-      mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-      mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
-      mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
-
-      rxdataF_comp128_0[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[2]);
-      //        print_shorts("ch:",ul_ch128_0[2]);
-      //        print_shorts("pack:",rxdataF_comp128_0[2]);
-
-
-
-
-      /*************************For Computing (y*)*(h1)************************************/
-      // multiply by conjugated signal
-      mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],rxdataF128[0]);
-      //  print_ints("re",&mmtmpU0);
-
-      // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
-      mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[0],_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]);
-      //  print_ints("im",&mmtmpU1);
-      mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[0]);
-      // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
-      mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-      //  print_ints("re(shift)",&mmtmpU0);
-      mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-      //  print_ints("im(shift)",&mmtmpU1);
-      mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
-      mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
-      //        print_ints("c0",&mmtmpU2);
-      //  print_ints("c1",&mmtmpU3);
-      rxdataF_comp128_1[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[0]);
-      //        print_shorts("ch_conjugate:",ul_ch128_1[0]);
-      //        print_shorts("pack:",rxdataF_comp128_1[0]);
-
-
-      // multiply by conjugated signal
-      mmtmpU0 = _mm_madd_epi16(ul_ch128_1[1],rxdataF128[1]);
-      // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
-      mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[1],_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
-      mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[1]);
-      // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
-      mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-      mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-      mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
-      mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
-
-      rxdataF_comp128_1[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[1]);
-      //        print_shorts("ch_conjugate:",ul_ch128_1[1]);
-      //        print_shorts("pack:",rxdataF_comp128_1[1]);
-
-
-      //       multiply by conjugated signal
-      mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],rxdataF128[2]);
-      // mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
-      mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[2],_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1));
-      mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate);
-      mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[2]);
-      // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit)
-      mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
-      mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift);
-      mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1);
-      mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
-
-      rxdataF_comp128_1[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
-      //        print_shorts("rx:",rxdataF128[2]);
-      //        print_shorts("ch_conjugate:",ul_ch128_0[2]);
-      //        print_shorts("pack:",rxdataF_comp128_1[2]);
-
-
-
-      ul_ch128_0+=3;
-      ul_ch_mag128_0+=3;
-      ul_ch_mag128b_0+=3;
-      ul_ch128_1+=3;
-      ul_ch_mag128_1+=3;
-      ul_ch_mag128b_1+=3;
-      rxdataF128+=3;
-      rxdataF_comp128_0+=3;
-      rxdataF_comp128_1+=3;
-
-    }
-  }
-
-
-  _mm_empty();
-  _m_empty();
-#endif
-}
-
-
-
-
-void ulsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti Receiver Combining
-                    int32_t **rxdataF_comp,
-                    int32_t **rxdataF_comp_0,
-                    int32_t **rxdataF_comp_1,
-                    int32_t **ul_ch_mag,
-                    int32_t **ul_ch_magb,
-                    int32_t **ul_ch_mag_0,
-                    int32_t **ul_ch_magb_0,
-                    int32_t **ul_ch_mag_1,
-                    int32_t **ul_ch_magb_1,
-                    uint8_t symbol,
-                    uint16_t nb_rb)
-{
-
-#if defined(__x86_64__) || defined(__i386__)
-  int16_t *rxF,*rxF0,*rxF1;
-  __m128i *ch_mag,*ch_magb,*ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b;
-  uint8_t rb,re,aarx;
-  int32_t jj=(symbol*frame_parms->N_RB_DL*12);
-
-
-  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-
-    rxF      = (int16_t*)&rxdataF_comp[aarx][jj];
-    rxF0     = (int16_t*)&rxdataF_comp_0[aarx][jj];   // Contains (y)*(h0*)
-    rxF1     = (int16_t*)&rxdataF_comp_1[aarx][jj];   // Contains (y*)*(h1)
-    ch_mag   = (__m128i *)&ul_ch_mag[aarx][jj];
-    ch_mag0 = (__m128i *)&ul_ch_mag_0[aarx][jj];
-    ch_mag1 = (__m128i *)&ul_ch_mag_1[aarx][jj];
-    ch_magb = (__m128i *)&ul_ch_magb[aarx][jj];
-    ch_mag0b = (__m128i *)&ul_ch_magb_0[aarx][jj];
-    ch_mag1b = (__m128i *)&ul_ch_magb_1[aarx][jj];
-
-    for (rb=0; rb<nb_rb; rb++) {
-
-      for (re=0; re<12; re+=2) {
-
-        // Alamouti RX combining
-
-        rxF[0] = rxF0[0] + rxF1[2];                   // re((y0)*(h0*))+ re((y1*)*(h1)) = re(x0)
-        rxF[1] = rxF0[1] + rxF1[3];                   // im((y0)*(h0*))+ im((y1*)*(h1)) = im(x0)
-
-        rxF[2] = rxF0[2] - rxF1[0];                   // re((y1)*(h0*))- re((y0*)*(h1)) = re(x1)
-        rxF[3] = rxF0[3] - rxF1[1];                   // im((y1)*(h0*))- im((y0*)*(h1)) = im(x1)
-
-        rxF+=4;
-        rxF0+=4;
-        rxF1+=4;
-      }
-
-      // compute levels for 16QAM or 64 QAM llr unit
-      ch_mag[0] = _mm_adds_epi16(ch_mag0[0],ch_mag1[0]);
-      ch_mag[1] = _mm_adds_epi16(ch_mag0[1],ch_mag1[1]);
-      ch_mag[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]);
-      ch_magb[0] = _mm_adds_epi16(ch_mag0b[0],ch_mag1b[0]);
-      ch_magb[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]);
-      ch_magb[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]);
-
-      ch_mag+=3;
-      ch_mag0+=3;
-      ch_mag1+=3;
-      ch_magb+=3;
-      ch_mag0b+=3;
-      ch_mag1b+=3;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-#endif
-}
-
-
-
-
-
-#if defined(__x86_64__) || defined(__i386__)
-__m128i avg128U;
-#elif defined(__arm__)
-int32x4_t avg128U;
-#endif
 
 void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
                          LTE_DL_FRAME_PARMS *frame_parms,
@@ -1410,10 +1045,13 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
   int16_t rb;
   uint8_t aarx;
 #if defined(__x86_64__) || defined(__i386__)
+  __m128i avg128U;
   __m128i *ul_ch128;
 #elif defined(__arm__)
   int16x4_t *ul_ch128;
+  int32x4_t avg128U;
 #endif
+
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
     //clear average level
 #if defined(__x86_64__) || defined(__i386__)
@@ -1464,8 +1102,7 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
 #endif
 }
 
-int32_t avgU[2];
-int32_t avgU_0[2],avgU_1[2]; // For the Distributed Alamouti Scheme
+
 
 void rx_ulsch(PHY_VARS_eNB *eNB,
 	      eNB_rxtx_proc_t *proc,
@@ -1482,7 +1119,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
   uint32_t l,i;
   int32_t avgs;
   uint8_t log2_maxh=0,aarx;
-
+  int32_t avgU[2];
 
 
   //  uint8_t harq_pid = ( ulsch->RRCConnRequest_flag== 0) ? subframe2harq_pid_tdd(frame_parms->tdd_config,subframe) : 0;
@@ -1492,7 +1129,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
   int subframe = proc->subframe_rx;
 
   harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe);
-  Qm = get_Qm_ul(ulsch[UE_id]->harq_processes[harq_pid]->mcs);
+  Qm = ulsch[UE_id]->harq_processes[harq_pid]->Qm;
 #ifdef DEBUG_ULSCH
   printf("rx_ulsch: harq_pid %d, nb_rb %d first_rb %d\n",harq_pid,ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,ulsch[UE_id]->harq_processes[harq_pid]->first_rb);
 
@@ -1701,8 +1338,8 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB,
 
   harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe);
 
-  printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, mcs %d, Qm %d, N_symb %d\n", subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,
-         eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,get_Qm_ul(eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs),
+  printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,
+         eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm,
          eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch);
   //#ifndef OAI_EMU
   write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96],
@@ -1739,7 +1376,7 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB,
   write_output("/tmp/ulsch_rxF_comp0.m","ulsch0_rxF_comp0",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
   //  write_output("ulsch_rxF_comp1.m","ulsch0_rxF_comp1",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
   write_output("/tmp/ulsch_rxF_llr.m","ulsch_llr",eNB->pusch_vars[UE_id]->llr,
-               eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*get_Qm_ul(eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs)
+               eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm
                *eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch,1,0);
   write_output("/tmp/ulsch_ch_mag.m","ulsch_ch_mag",&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
   //  write_output("ulsch_ch_mag1.m","ulsch_ch_mag1",&eNB->pusch_vars[UE_id]->ul_ch_mag[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1);
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index cea702ef7804d69da774a5eca5e9027df3a05b8f..a3e96e528414ab8ec91f526181e31864e42131ec 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -180,16 +180,16 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   uint32_t total_dlsch_bitrate = phy_vars_enb->total_dlsch_bitrate;
   int coded_bits_per_codeword = 0;
   uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
-  int mcs = 0;
+  int Qm = 2;
 
   // choose max MCS to compute coded_bits_per_codeword
   if (phy_vars_enb->ulsch[UE_id]!=NULL) {
     for (harq_pid=0; harq_pid<3; harq_pid++) {
-      mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs);
+      Qm = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->Qm,Qm);
     }
   }
 
-  coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti;
+  coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
 
   chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
   llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 2c1ec6096703963d9dde59a60908e6b7cd0e27d0..2ca502d1f686d68bc203da6e772dfd22d2b7d39e 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -901,6 +901,14 @@ typedef struct PHY_VARS_eNB_s {
   nfapi_rx_indication_pdu_t  rx_pdu_list[NFAPI_RX_IND_MAX_PDU];
   /// NFAPI RX ULSCH CRC information
   nfapi_crc_indication_pdu_t crc_pdu_list[NFAPI_CRC_IND_MAX_PDU];
+  /// NFAPI HARQ information
+  nfapi_harq_indication_pdu_t harq_pdu_list[NFAPI_HARQ_IND_MAX_PDU];
+  /// NFAPI SR information
+  nfapi_sr_indication_pdu_t sr_pdu_list[NFAPI_SR_IND_MAX_PDU];
+  /// NFAPI CQI information
+  nfapi_cqi_indication_pdu_t cqi_pdu_list[NFAPI_CQI_IND_MAX_PDU];
+  /// NFAPI CQI information (raw component)
+  nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU];
   /// NFAPI PRACH information
   nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES];
 #ifdef Rel14
@@ -909,13 +917,14 @@ typedef struct PHY_VARS_eNB_s {
 #endif
   Sched_Rsp_t          Sched_INFO;
   LTE_eNB_PDCCH        pdcch_vars[2];
+  LTE_eNB_PHICH        phich_vars[2];
 #ifdef Rel14
   LTE_eNB_EPDCCH       epdcch_vars[2];
   LTE_eNB_MPDCCH       mpdcch_vars[2];
   LTE_eNB_PRACH        prach_vars_br;
 #endif
   LTE_eNB_COMMON       common_vars;
-  LTE_eNB_UCI_t        uci_vars[NUMBER_OF_UE_MAX];
+  LTE_eNB_UCI          uci_vars[NUMBER_OF_UE_MAX];
   LTE_eNB_SRS          srs_vars[NUMBER_OF_UE_MAX];
   LTE_eNB_PBCH         pbch;
   LTE_eNB_PUSCH       *pusch_vars[NUMBER_OF_UE_MAX];
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 2a0e1dbf50e9924c14c9daf294e55defd7cf9fdd..fd6e36246fa6658a61ef10dadc2d9d1cb6e00737 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -350,6 +350,14 @@ typedef struct {
 
 /// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec
 typedef struct {
+  /// This descriptor is active
+  uint8_t active;
+  /// This descriptor's frame
+  uint16_t frame;
+  /// This descriptor's subframe
+  uint8_t  subframe;
+  /// rnti
+  uint16_t rnti;
   /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value.
   uint8_t srs_Bandwidth;
   /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value.
@@ -831,6 +839,16 @@ typedef struct {
   DCI_ALLOC_t dci_alloc[32];
 } LTE_eNB_PDCCH;
 
+typedef struct {
+  uint8_t hi;
+  uint8_t first_rb;
+  uint8_t n_DMRS;
+} phich_config_t;
+
+typedef struct {
+  uint8_t num_hi;
+  phich_config_t config[32];
+} LTE_eNB_PHICH;
 
 typedef struct {
   uint8_t     num_dci;
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index f387dd5efb14fa0a1765cfa4893027d6f283d9f0..14ffc6a5dc077ff08664b960c8b5979fce8d9307 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -95,212 +95,12 @@ int harq_pid_round[NUMBER_OF_UE_MAX][8] = {{0}};
 
 //DCI_ALLOC_t dci_alloc[8];
 
-uint8_t is_SR_subframe(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id)
-{
-
-  const int subframe = proc->subframe_rx;
-  const int frame = proc->frame_rx;
-
-  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
-        eNB->Mod_id,eNB->ulsch[UE_id]->rnti,frame,subframe,
-        eNB->scheduling_request_config[UE_id].sr_ConfigIndex);
-
-  if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
-    if ((subframe%5) == eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
-      return(1);
-  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
-    if (subframe==(eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
-      return(1);
-  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
-    if ((10*(frame&1)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
-      return(1);
-  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
-    if ((10*(frame&3)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
-      return(1);
-  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
-    if ((10*(frame&7)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
-      return(1);
-  }
-
-  return(0);
-}
-
-
-int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
-{
-  uint8_t i;
-
-
-  LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
-        eNB->Mod_id,
-        eNB->CC_id,
-        (uint16_t)rnti);
-
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
-      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
-      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
-      return(-1);
-    } else {
-      if (eNB->UE_stats[i].crnti==0) {
-        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
-        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
-        eNB->dlsch[i][0]->rnti = rnti;
-        eNB->ulsch[i]->rnti = rnti;
-        eNB->UE_stats[i].crnti = rnti;
-
-	eNB->UE_stats[i].Po_PUCCH1_below = 0;
-	eNB->UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
-	eNB->UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
-	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
-	      eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
-	      eNB->rx_total_gain_dB,
-	      eNB->UE_stats[i].Po_PUCCH);
-  
-        return(i);
-      }
-    }
-  }
-  return(-1);
-}
-
-int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
-  uint8_t i;
-  int CC_id;
-  PHY_VARS_eNB *eNB;
-
-  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
-    eNB = RC.eNB[Mod_idP][CC_id];
-    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-      if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
-	MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rntiP);
-	LOG_E(PHY,"Can't remove UE, not enough memory allocated\n");
-	return(-1);
-      } else {
-	if (eNB->UE_stats[i].crnti==rntiP) {
-	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
-
-	  LOG_D(PHY,"eNB %d removing UE %d with rnti %x\n",eNB->Mod_id,i,rntiP);
-
-	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
-	  clean_eNb_dlsch(eNB->dlsch[i][0]);
-	  clean_eNb_ulsch(eNB->ulsch[i]);
-	  //eNB->UE_stats[i].crnti = 0;
-	  memset(&eNB->UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
-	  //  mac_exit_wrapper("Removing UE");
-	  
-
-	  return(i);
-	}
-      }
-    }
-  }
-  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
-  return(-1);
-}
-
-/*
-int8_t find_next_ue_index(PHY_VARS_eNB *eNB)
-{
-  uint8_t i;
-
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    if (eNB->UE_stats[i].crnti==0) {
-	(eNB->dlsch[i][0]->rnti==0))
-      LOG_D(PHY,"Next free UE id is %d\n",i);
-      return(i);
-    }
-  }
-
-  return(-1);
-}
-*/
-
-/*
-int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t harq_flag)
-{
-  LTE_eNB_DLSCH_t *DLSCH_ptr;
-  LTE_eNB_ULSCH_t *ULSCH_ptr;
-  uint8_t ulsch_subframe,ulsch_frame;
-  int i;
-  int8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][CC_id]);
-
-  if (UE_id==-1) {
-    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
-    *round=0;
-    return(-1);
-  }
-
-  if ((harq_flag == openair_harq_DL) || (harq_flag == openair_harq_RA))  {// this is a DL request
-
-    DLSCH_ptr = RC.eNB[Mod_id][CC_id]->dlsch[(uint32_t)UE_id][0];
-
-    if (harq_flag == openair_harq_RA) {
-      if (DLSCH_ptr->harq_processes[0] != NULL) {
-	*harq_pid = 0;
-	*round = DLSCH_ptr->harq_processes[0]->round;
-	return 0;
-      } else {
-	return -1;
-      }
-    }
-
-    // let's go synchronous for the moment - maybe we can change at some point
-    i = (frame * 10 + subframe) % 8;
-
-    if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
-      *harq_pid = i;
-      *round = DLSCH_ptr->harq_processes[i]->round;
-    } else if (DLSCH_ptr->harq_processes[i]->status == SCH_IDLE) {
-      *harq_pid = i;
-      *round = 0;
-    } else {
-      printf("%s:%d: bad state for harq process - PLEASE REPORT!!\n", __FILE__, __LINE__);
-      abort();
-    }
-  } else { // This is a UL request
-
-    ULSCH_ptr = RC.eNB[Mod_id][CC_id]->ulsch[(uint32_t)UE_id];
-    ulsch_subframe = pdcch_alloc2ul_subframe(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe);
-    ulsch_frame    = pdcch_alloc2ul_frame(&RC.eNB[Mod_id][CC_id]->frame_parms,frame,subframe);
-    // Note this is for TDD configuration 3,4,5 only
-    *harq_pid = subframe2harq_pid(&RC.eNB[Mod_id][CC_id]->frame_parms,
-                                  ulsch_frame,
-                                  ulsch_subframe);
-    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
-    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
-  }
-
-  return(0);
-}
-*/
-
-int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
-{
-  return RC.eNB[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
-}
-
-int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
-{
-  return RC.eNB[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
-}
-
-void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type)
-{
-  UNUSED(r_type);
-  int subframe = proc->subframe_rx;
-
-#ifdef DEBUG_PHY_PROC
-  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", eNB->Mod_id,proc->frame_rx, subframe);
-#endif
-
-
-  lte_eNB_I0_measurements(eNB,
-			  subframe,
-			  0,
-			  eNB->first_run_I0_measurements);
-
-}
+void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
+void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling);
+void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti);
+void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe);
+void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
+void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
 
 
 
@@ -513,191 +313,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
 
 }
 
-/*
-void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
-
-  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
-  int frame = proc->frame_tx;
-  int subframe = proc->subframe_tx;
-
-  // if we have SI_RNTI, configure dlsch parameters and CCE index
-  if (dci_alloc->rnti == SI_RNTI) {
-    LOG_D(PHY,"Generating dlsch params for SI_RNTI\n");
-    
-    generate_eNB_dlsch_params_from_dci(frame,
-				       subframe,
-				       &dci_alloc->dci_pdu[0],
-				       dci_alloc->rnti,
-				       dci_alloc->format,
-				       &eNB->dlsch_SI,
-				       fp,
-				       NULL,
-				       SI_RNTI,
-				       0,
-				       P_RNTI,
-				       eNB->UE_stats[0].DL_pmi_single,
-				       0);
-    LOG_I(PHY,"frame %d, subframe %d : SI with mcs %d\n",frame,subframe,eNB->dlsch_SI->harq_processes[0]->mcs);
-    
-    eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE;
-   
-    LOG_I(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8", aggregation %d\n",eNB->Mod_id,frame,subframe,
-	  eNB->dlsch_SI->nCCE[subframe],1<<dci_alloc->L);
-    
-  } else if (dci_alloc->ra_flag == 1) {  // This is format 1A allocation for RA
-    // configure dlsch parameters and CCE index
-    LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");    
-    
-    generate_eNB_dlsch_params_from_dci(frame,
-				       subframe,
-				       &dci_alloc->dci_pdu[0],
-				       dci_alloc->rnti,
-				       dci_alloc->format,
-				       &eNB->dlsch_ra,
-				       fp,
-				       NULL,
-				       SI_RNTI,
-				       dci_alloc->rnti,
-				       P_RNTI,
-				       eNB->UE_stats[0].DL_pmi_single,
-				       0);
-    
-        
-    eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE;
-    
-    LOG_I(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8" length %d bits\n",eNB->Mod_id,frame,subframe,
-	  eNB->dlsch_ra->nCCE[subframe],
-	  dci_alloc->dci_length);
-  }
-  
-  else if ((dci_alloc->format != format0)&&
-	   (dci_alloc->format != format3)&&
-	   (dci_alloc->format != format3A)&&
-	   (dci_alloc->format != format4)){ // this is a normal DLSCH allocation
-    
-
-    
-    if (UE_id>=0) {
-      LOG_I(PHY,"Generating dlsch params for RNTI %x\n",dci_alloc->rnti);      
-      
-      generate_eNB_dlsch_params_from_dci(frame,
-					 subframe,
-					 &dci_alloc->dci_pdu[0],
-					 dci_alloc->rnti,
-					 dci_alloc->format,
-					 eNB->dlsch[(uint8_t)UE_id],
-					 fp,
-					 &eNB->pdsch_config_dedicated[UE_id],
-					 SI_RNTI,
-					 0,
-					 P_RNTI,
-					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single,
-					 eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id]);
-      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
-	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe);
-      
-      
-      T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
-        T_INT(dci_alloc->rnti), T_INT(dci_alloc->format),
-        T_INT(dci_alloc->harq_pid),
-        T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[dci_alloc->harq_pid]->mcs),
-        T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[dci_alloc->harq_pid]->TBS));
-
-      eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
-      
-      LOG_I(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8" length %d bits\n",eNB->Mod_id,frame,subframe,
-	    dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe],dci_alloc->dci_length);
-      
-      LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
-	    eNB->Mod_id, dci_alloc->rnti,
-	    frame, subframe,UE_id,
-	    dci_alloc->format,
-	    1<<dci_alloc->L);
-    } else {
-      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
-	    eNB->Mod_id,frame,dci_alloc->rnti);
-    }
-  }
-  
-}
-
-void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
 
-  int harq_pid;
-  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
-  int frame = proc->frame_tx;
-  int subframe = proc->subframe_tx;
-  
-//  uint16_t srsPeriodicity=0;
-//  uint16_t srsOffset=0;
-//  uint16_t srsConfigIndex=0;
-//  uint16_t do_srs=0;
-  
-  uint16_t is_srs_pos=0;
-
-  LOG_I(PHY,
-	"[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8"), aggregation %d\n",
-	eNB->Mod_id,
-	subframe2harq_pid(fp,
-			  pdcch_alloc2ul_frame(fp,frame,subframe),
-			  pdcch_alloc2ul_subframe(fp,subframe)),
-	frame,
-	subframe,
-	pdcch_alloc2ul_frame(fp,frame,subframe),
-	pdcch_alloc2ul_subframe(fp,subframe),
-	dci_alloc->rnti,
-	dci_alloc->dci_pdu[0],
-	1<<dci_alloc->L);
-  
-  is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe));
-  
-//if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup) {
-//    srsConfigIndex = eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex;
-//    compute_srs_pos(fp->frame_type, srsConfigIndex, &srsPeriodicity, &srsOffset);
-//    if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) {
-//     do_srs = 1;
-//    }
-//  }
-//      LOG_D(PHY,"frame %d (%d), subframe %d (%d), UE_id %d: is_srs_pos %d, do_SRS %d, index %d, period %d, offset %d \n",
-//	    frame,pdcch_alloc2ul_frame(fp,frame,subframe),subframe,pdcch_alloc2ul_subframe(fp,subframe),
-//	    UE_id,is_srs_pos,do_srs,srsConfigIndex,srsPeriodicity,srsOffset);
-//  
-
-  generate_eNB_ulsch_params_from_dci(eNB,
-				     proc,
-				     &dci_alloc->dci_pdu[0],
-				     dci_alloc->rnti,
-				     format0,
-				     UE_id,
-				     SI_RNTI,
-				     0,
-				     P_RNTI,
-				     CBA_RNTI,
-				     is_srs_pos);  
-  LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n",
-	eNB->Mod_id,frame,subframe,dci_alloc->rnti,
-	dci_alloc->firstCCE);
-  
-  // get the hard_pid for this subframe 
-  harq_pid = subframe2harq_pid(fp,
-			       pdcch_alloc2ul_frame(fp,frame,subframe),
-			       pdcch_alloc2ul_subframe(fp,subframe));
-  
-  AssertFatal(harq_pid!=255,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,frame);
-
-  eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
-  
-  T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
-    T_INT(dci_alloc->rnti), T_INT(harq_pid),
-    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->mcs),
-    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->round),
-    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->first_rb),
-    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->nb_rb),
-    T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->TBS),
-    T_INT(dci_alloc->L),
-    T_INT(dci_alloc->firstCCE));
-}
-*/
 
 void pdsch_procedures(PHY_VARS_eNB *eNB,
 		      eNB_rxtx_proc_t *proc,
@@ -712,11 +328,10 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
   LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
   int input_buffer_length = dlsch_harq->TBS/8;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
-  int i;
 
   if (frame < 20) {
 
-    LOG_D(PHY,
+    LOG_I(PHY,
 	  "[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", pdsch_start %d, G %d, nb_rb %"PRIu16", rb0 %x, rb1 %x, TBS %"PRIu16", pmi_alloc %"PRIx64", rv %"PRIu8" (round %"PRIu8")\n",
 	  eNB->Mod_id, dlsch->rnti,harq_pid,
 	  frame, subframe, input_buffer_length, dlsch_harq->pdsch_start,
@@ -777,8 +392,9 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
 
 
   LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag);
-  // 36-212
+  // 36-212 
   start_meas(&eNB->dlsch_encoding_stats);
+  AssertFatal(dlsch_harq->pdu!=NULL,"dlsch_harq->pdu == NULL (rnti %x)\n",dlsch->rnti);
   eNB->te(eNB,
 	  dlsch_harq->pdu,
 	  dlsch_harq->pdsch_start,
@@ -858,13 +474,12 @@ void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
 				  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
 
 void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
-				  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) {
+				  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu){
   
   int idx                         = proc->subframe_tx&1;
   LTE_eNB_PDCCH *pdcch_vars       = &eNB->pdcch_vars[idx];
-  nfapi_hi_dci0_dci_pdu *pdu      = &hi_dci0_config_pdu->dci_pdu;
   // copy dci configuration in to eNB structure
-  fill_dci_and_ulsch(eNB,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],pdu);
+  fill_dci0(eNB,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu);
 }
 
 void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
@@ -875,17 +490,25 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
 				 nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) {
   
   nfapi_hi_dci0_hi_pdu *pdu      = &hi_dci0_config_pdu->hi_pdu;
+  LTE_eNB_PHICH *phich           = &eNB->phich_vars[proc->subframe_tx&1];
+
   // copy dci configuration in to eNB structure
   LOG_D(PHY,"Received HI PDU which value %d (rbstart %d,cshift %d)\n",
 	hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value,
 	hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start,
 	hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms);
-}
 
-handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
-		     nfapi_dl_config_request_pdu_t *dl_config_pdu,
-		     uint8_t *sdu) {
+  phich->config[phich->num_hi].hi       = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value;
+  phich->config[phich->num_hi].first_rb = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start;
+  phich->config[phich->num_hi].n_DMRS   = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms;
+  phich->num_hi++;
+  AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n");
+}
 
+void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
+			  nfapi_dl_config_request_pdu_t *dl_config_pdu,
+			  uint8_t *sdu) {
+ 
   nfapi_dl_config_bch_pdu_rel8_t *rel8 = &dl_config_pdu->bch_pdu.bch_pdu_rel8;
   
   AssertFatal(rel8->length == 3, "BCH PDU has length %d != 3\n",rel8->length);
@@ -910,10 +533,10 @@ extern uint32_t localRIV2alloc_LUT100_2[6000];
 extern uint32_t localRIV2alloc_LUT100_3[6000];
 #endif
 
-handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
-		       nfapi_dl_config_request_pdu_t *dl_config_pdu,
-		       uint8_t codeword_index,
-		       uint8_t *sdu) {
+void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
+			    nfapi_dl_config_request_pdu_t *dl_config_pdu,
+			    uint8_t codeword_index,
+			    uint8_t *sdu) {
 
   nfapi_dl_config_dlsch_pdu_rel8_t *rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8;
 #ifndef Rel8
@@ -926,7 +549,7 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
   int UE_id;
   int harq_pid;
-  
+   
   
   UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
   AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
@@ -945,12 +568,15 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   dlsch1_harq     = dlsch1->harq_processes[harq_pid];
   AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n");
 
+  
   dlsch0_harq->pdsch_start = eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols;
 
-  LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch, rnti %x, UE_id %d, harq_pid %d\n",
-    proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid);
-  if (codeword_index == 0) dlsch0_harq->pdu                    = sdu;
-  else                     dlsch1_harq->pdu                    = sdu;
+  if (dlsch0_harq->round==0) {  //get pointer to SDU if this a new SDU
+    LOG_I(PHY,"NFAPI: frame %d, subframe %d: programming dlsch, rnti %x, UE_id %d, harq_pid %d\n",
+	  proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid);
+    if (codeword_index == 0) dlsch0_harq->pdu                    = sdu;
+    else                     dlsch1_harq->pdu                    = sdu;
+  }
 
 #ifdef Rel14
   dlsch0->sib1_br_flag=0;
@@ -1005,131 +631,330 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
     dlsch0_harq->codeword           = 0;
   }
   else {
-
+    dlsch0->i0               = 0xFFFF;
   }
 #endif
 }
 
-handle_uci_harq_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_ul_config_request_pdu_t *ul_config_pdu) {
+uint16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8};
 
+void handle_ulsch_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) {
+
+  nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8;
+
+  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
+  LTE_UL_eNB_HARQ_t *ulsch_harq;
+  nfapi_ul_config_ulsch_harq_information *harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information;
+
+  int harq_pid = rel8->harq_process_number;
+  ulsch_harq = ulsch->harq_processes[harq_pid];
+  ulsch_harq->frame                      = frame;
+  ulsch_harq->subframe                   = subframe;
+  ulsch_harq->O_ACK                      = harq_information->harq_information_rel10.harq_size;
+  ulsch->beta_offset_harqack_times8      = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq];
 }
 
-handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
-		    nfapi_ul_config_request_pdu_t *ul_config_pdu) {
+uint16_t to_beta_offset_ri[16]={9,13,16,20,25,32,40,50,64,80,101,127,160,0,0,0};
+uint16_t to_beta_offset_cqi[16]={0,0,9,10,11,13,14,16,18,20,23,25,28,32,40,50};
 
-  nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8;
+void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) {
+
+  nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9;
+
+  LTE_eNB_ULSCH_t *ulsch        = eNB->ulsch[UE_id];
+  int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number;
+  LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
+
+  ulsch_harq->frame                       = frame;
+  ulsch_harq->subframe                    = subframe;  
+  ulsch_harq->O_RI                        = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size;
+  ulsch_harq->Or1                         = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0];
+  if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1];
+  ulsch->beta_offset_ri_times8            = to_beta_offset_ri[rel9->delta_offset_ri];
+  ulsch->beta_offset_cqi_times8           = to_beta_offset_cqi[rel9->delta_offset_cqi];
+}
+
+void handle_ulsch_cqi_harq_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) {
+
+  nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information.cqi_ri_information_rel9;
+
+  LTE_eNB_ULSCH_t *ulsch        = eNB->ulsch[UE_id];
+  int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number;
+  LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
+  nfapi_ul_config_ulsch_harq_information *harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
+
+  ulsch_harq->frame                       = frame;
+  ulsch_harq->subframe                    = subframe;  
+  ulsch_harq->O_RI                        = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size;
+  ulsch_harq->Or1                         = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0];
+  ulsch_harq->O_ACK                       = harq_information->harq_information_rel10.harq_size;
+
+  if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1];
+
+  ulsch->beta_offset_harqack_times8       = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq];
+  ulsch->beta_offset_ri_times8            = to_beta_offset_ri[rel9->delta_offset_ri];
+  ulsch->beta_offset_cqi_times8           = to_beta_offset_cqi[rel9->delta_offset_cqi];
+
+}
+
+void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information) {
+
+
+  if (eNB->frame_parms.frame_type == FDD) {
+    uci->num_pucch_resources = harq_information->harq_information_rel9_fdd.number_of_pucch_resources; 
+
+    LOG_I(PHY,"Programming UCI HARQ mode %d : size %d in (%d,%d)\n",
+	  harq_information->harq_information_rel9_fdd.ack_nack_mode,
+	  harq_information->harq_information_rel9_fdd.harq_size,
+	  uci->frame,uci->subframe);
+
+    if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
+	(harq_information->harq_information_rel9_fdd.harq_size == 1)) {
+      uci->pucch_fmt =  pucch_format1a;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+    }
+    else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) &&
+	     (harq_information->harq_information_rel9_fdd.harq_size == 2)) {
+      uci->pucch_fmt =  pucch_format1b;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+    }
+    else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) &&
+	     (harq_information->harq_information_rel9_fdd.harq_size == 2)) {
+      uci->pucch_fmt =  pucch_format1b_csA2;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+      uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1;
+      uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
+    }
+    else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) &&
+	     (harq_information->harq_information_rel9_fdd.harq_size == 3)) {
+      uci->pucch_fmt =  pucch_format1b_csA3;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+      uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1;
+      uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
+      uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2;
+      uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2;
+    }
+    else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) &&
+	     (harq_information->harq_information_rel9_fdd.harq_size == 4)) {
+      uci->pucch_fmt =  pucch_format1b_csA4;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+      uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1;
+      uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
+      uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2;
+      uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2;
+    }
+    else if (harq_information->harq_information_rel9_fdd.ack_nack_mode == 2) {
+      uci->pucch_fmt =  pucch_format3;
+      uci->n_pucch_3[0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0;
+      uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0;
+    }
+    else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel9_fdd.ack_nack_mode);
+  }
+  else { // TDD
+    uci->num_pucch_resources = harq_information->harq_information_rel10_tdd.number_of_pucch_resources; 
+
+    if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) {//bundling
+
+      uci->pucch_fmt =  harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b;
+      uci->tdd_bundling = 1;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+    }
+    else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing 
+	     (uci->num_pucch_resources == 1)) {
+      uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b;
+      uci->tdd_bundling = 0;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+    }
+    else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing M>1
+	     (uci->num_pucch_resources > 1)) {
+      uci->pucch_fmt = pucch_format1b;
+      uci->tdd_bundling = 0;
+      uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
+      uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0;
+      uci->n_pucch_1[1][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_1;
+      uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1;
+      uci->n_pucch_1[2][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_2;
+      uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2;
+      uci->n_pucch_1[3][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_3;
+      uci->n_pucch_1[3][1] = harq_information->harq_information_rel11.n_pucch_2_3;
+    }
+    else if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 2) {
+      uci->pucch_fmt =  pucch_format3;
+      uci->n_pucch_3[0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0;
+      uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0;
+    }
+    else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel10_tdd.ack_nack_mode);
+  }
+}
+
+void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) {
+  LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
+
+  uci->frame               = frame;
+  uci->subframe            = subframe;
+  uci->rnti                = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
+  uci->type                = SR;
+  uci->pucch_fmt           = pucch_format1;
+  uci->num_antenna_ports   = 1;
+  uci->num_pucch_resources = 1;
+  uci->n_pucch_1_0_sr[0]   = ul_config_pdu->uci_sr_pdu.sr_information.sr_information_rel8.pucch_index;
+  uci->srs_active          = srs_active;
+  uci->active              = 1;
+
+  LOG_I(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n",
+	uci->rnti,uci->n_pucch_1_0_sr[0],frame,subframe);
+  
+
+}
+
+void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) {
+
+  LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
+
+  uci->frame               = frame;
+  uci->subframe            = subframe;
+  uci->rnti                = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
+  uci->type                = HARQ_SR;
+  uci->num_antenna_ports   = 1;
+  uci->num_pucch_resources = 1;
+  uci->n_pucch_1_0_sr[0]    = ul_config_pdu->uci_sr_harq_pdu.sr_information.sr_information_rel8.pucch_index;
+  uci->srs_active          = srs_active;
+  uci->active              = 1;
+
+
+  handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_sr_harq_pdu.harq_information);
+}
+
+void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) {
+
+  LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
+
+  uci->frame             = frame;
+  uci->subframe          = subframe;
+  uci->rnti              = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
+  uci->type              = HARQ;
+  uci->srs_active        = srs_active;
+  uci->num_antenna_ports = ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel11.num_ant_ports;
+
+  handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_harq_pdu.harq_information);
+
+  uci->active=1;
+  
+}
+
+
+void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) {
+
+  int i;
+
+  for (i=0;i<NUMBER_OF_UE_MAX;i++) {
+    
+    if (eNB->soundingrs_ul_config_dedicated[i].active==1) continue;
+    
+    eNB->soundingrs_ul_config_dedicated[i].active               = 1;
+    eNB->soundingrs_ul_config_dedicated[i].frame                = frame;
+    eNB->soundingrs_ul_config_dedicated[i].subframe             = subframe;
+    eNB->soundingrs_ul_config_dedicated[i].rnti                 = ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti;
+    eNB->soundingrs_ul_config_dedicated[i].srs_Bandwidth        = ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth;
+    eNB->soundingrs_ul_config_dedicated[i].srs_HoppingBandwidth = ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth;
+    eNB->soundingrs_ul_config_dedicated[i].freqDomainPosition   = ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position;
+    eNB->soundingrs_ul_config_dedicated[i].transmissionComb     = ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb;
+    eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex      = ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs;
+    eNB->soundingrs_ul_config_dedicated[i].cyclicShift          = ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift;
+    break; 
+  }
+  AssertFatal(i<NUMBER_OF_UE_MAX,"No room for SRS processing\n");
+}
 
-  uint16_t *RIV2nb_rb_LUT, *RIV2first_rb_LUT;
-  uint16_t RIV_max;
-  uint16_t use_srs=0;
+void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+			 nfapi_ul_config_request_pdu_t *ul_config_pdu,
+			 uint16_t frame,uint8_t subframe,uint8_t srs_present) {
+
+  nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8;
 
   int8_t UE_id;
-  LTE_eNB_ULSCH_t *ulsch;
-  LTE_UL_eNB_HARQ_t *ulsch_harq;
 
   // check if we have received a dci for this ue and ulsch descriptor is configured
 
-  if (ul_config_pdu == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) {
-    AssertFatal((UE_id = find_ulsch(rel8->rnti,eNB,SEARCH_EXIST))>=0,
+  if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) {
+    AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST))>=0,
 		"No existing UE ULSCH for rnti %x\n",rel8->rnti);
     AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0,
 		"ulsch for UE_id %d is not active\n",UE_id);
-    LOG_I(PHY,"Applying UL config for UE %d, rnti %x\n",
-	  UE_id,rel8->rnti);
-    /*
-#ifdef Rel14
-    nfapi_ul_config_ulsch_pdu_rel13_t *rel13 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13;
-    int harq_pid = rel8->harq_process_number;
+    LOG_I(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n",
+	  UE_id,rel8->rnti,frame,subframe);
 
-    if (rel13->ue_type > 0) { // This is a BL/CE UE, retrieve PUSCH programming
-      ulsch = eNB->ulsch[UE_id];
-      
-      ulsch_harq = ulsch->harq_processes[harq_pid];
-      
-      switch (eNB->frame_parms.N_RB_DL) {
-      case 6:
-	RIV2nb_rb_LUT     = &RIV2nb_rb_LUT6[0];
-	RIV2first_rb_LUT  = &RIV2first_rb_LUT6[0];
-	RIV_max           = RIV_max6;
-	break;
-	
-      case 25:
-	RIV2nb_rb_LUT     = &RIV2nb_rb_LUT25[0];
-	RIV2first_rb_LUT  = &RIV2first_rb_LUT25[0];
-	RIV_max           = RIV_max25;
-	break;
-	
-      case 50:
-	RIV2nb_rb_LUT     = &RIV2nb_rb_LUT50[0];
-	RIV2first_rb_LUT  = &RIV2first_rb_LUT50[0];
-	RIV_max           = RIV_max50;
-	break;
-	
-      case 100:
-	RIV2nb_rb_LUT     = &RIV2nb_rb_LUT100[0];
-	RIV2first_rb_LUT  = &RIV2first_rb_LUT100[0];
-	RIV_max           = RIV_max100;
-	break;
-	
-      default:
-	DevParam(frame_parms->N_RB_DL, harq_pid, 0);
-	break;
-      }
-      
-      
-      ulsch_harq->first_rb               = rel8->resource_block_start;
-      ulsch_harq->nb_rb                  = rel8->number_of_resource_blocks;
-      ulsch_harq->O_RI                   = 0;//1;
-      ulsch_harq->Or2                    = 0;
-      ulsch_harq->Or1                    = 0;
-      ulsch_harq->O_ACK                  = 0;//2;
-      ulsch->beta_offset_cqi_times8      = 18;
-      ulsch->beta_offset_ri_times8       = 10;
-      ulsch->beta_offset_harqack_times8  = 16;
-      
-      ulsch->rnti = rel8->rnti;
-      ulsch->harq_mask = 1<<harq_pid;
-      
-      if (ulsch_harq->round == 0) {
-	ulsch_harq->status = ACTIVE;
-	ulsch_harq->rvidx = 0;
-	//ulsch_harq->TBS         = dlsch_tbs25[ulsch_harq->mcs][ulsch_harq->nb_rb-1];
-	ulsch_harq->TBS         = TBStable[get_I_TBS_UL(ulsch_harq->mcs)][ulsch_harq->nb_rb-1];
-	ulsch_harq->Msc_initial   = 12*ulsch_harq->nb_rb;
-	ulsch_harq->Nsymb_initial = 9;
-	ulsch_harq->round = 0;
-      } else {
-	ulsch_harq->rvidx = 0;
-	ulsch_harq->round++;
-      }
-      use_srs = is_srs_occasion_common(frame_parms,ulsch_harq->frame,ulsch_harq->subframe);
-      ulsch_harq->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
-      ulsch_harq->srs_active                            = use_srs;
-    }
-    #endif
-*/
+    fill_ulsch(eNB,&ul_config_pdu->ulsch_pdu,frame,subframe);
+
+  }
+ 
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) {
+    AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
+		"No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
+    AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0,
+		"ulsch for UE_id %d is not active\n",UE_id);
+
+    fill_ulsch(eNB,&ul_config_pdu->ulsch_harq_pdu.ulsch_pdu,frame,subframe);
+    handle_ulsch_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
+
+  } 
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) {
+    AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
+				    eNB,SEARCH_EXIST_OR_FREE))>=0,
+		"No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
+    AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0,
+		"ulsch for UE_id %d is not active\n",UE_id);
+    fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu,frame,subframe);
+    handle_ulsch_cqi_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
+
+  } 
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) {
+    AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
+				    eNB,SEARCH_EXIST_OR_FREE))>=0,
+		"No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
+    AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0,
+		"ulsch for UE_id %d is not active\n",UE_id);
+    fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu,frame,subframe);
+    handle_ulsch_cqi_harq_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
+
+  } 
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
+    AssertFatal((UE_id = find_uci(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,
+				  proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
+		"No available UE UCI for rnti %x\n",ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti);
+    handle_uci_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
   }
-  else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) {
-    AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST))>=0,
-		"No existing UE UCI for rnti %x\n",rel8->rnti);
-    handle_uci_harq_pdu(eNB,proc,ul_config_pdu);
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) {
+    AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n");
   }
-  else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) {
-    
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) {
+    AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n");
   }
-  else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) {
-    
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
+    AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n");
   }
-  else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
+    AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,
+				  proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
+		"No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti);
+    handle_uci_sr_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
     
   }
-  else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
-    
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
+    AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
+		"No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti);
+    handle_uci_sr_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
   }
-  else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) {
-    
+  else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_SRS_PDU_TYPE) {
+    handle_srs_pdu(eNB,ul_config_pdu,frame,subframe);
   }
-	      
 }
 
 void schedule_response(Sched_Rsp_t *Sched_INFO) {
@@ -1164,12 +989,9 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
   AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe);
   AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame);
 
-  int8_t UE_id;
   uint8_t number_dl_pdu             = DL_req->dl_config_request_body.number_pdu;
   uint8_t number_hi_dci0_pdu        = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi;
   uint8_t number_ul_pdu             = UL_req->ul_config_request_body.number_of_pdus;
-  uint8_t number_pdsch_rnti         = DL_req->dl_config_request_body.number_pdsch_rnti;
-  uint8_t transmission_power_pcfich = DL_req->dl_config_request_body.transmission_power_pcfich;
 
 
   nfapi_dl_config_request_pdu_t *dl_config_pdu;
@@ -1180,10 +1002,10 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
 
   eNB->pdcch_vars[subframe&1].num_pdcch_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols;
   eNB->pdcch_vars[subframe&1].num_dci           = 0;
+  eNB->phich_vars[subframe&1].num_hi            = 0;
 
-
-  LOG_D(PHY,"NFAPI: received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n",
-	number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu);
+  LOG_I(PHY,"NFAPI: Frame %d, Subframe %d: received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n",
+	frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu);
 
   
   if ((subframe_select(fp,ul_subframe)==SF_UL) ||
@@ -1202,7 +1024,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
   }
   for (i=0;i<number_dl_pdu;i++) {
     dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i];
-    LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type);
+    LOG_I(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type);
     switch (dl_config_pdu->pdu_type) {
     case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
       handle_nfapi_dci_dl_pdu(eNB,proc,dl_config_pdu);
@@ -1233,7 +1055,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
 			     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks-1,
 			     TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data);
       if (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == eNB->preamble_list[0].preamble_rel8.rnti) {// is RAR pdu
-	LOG_I(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n"); 
+	LOG_I(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n",frame,subframe); 
 	generate_eNB_ulsch_params_from_rar(eNB,
 					   TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data,
 					   frame,
@@ -1261,9 +1083,14 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
   }
   
   for (i=0;i<number_hi_dci0_pdu;i++) {
+
     hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
+
+    LOG_I(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type);
+
     switch (hi_dci0_req_pdu->pdu_type) {
 
+
     case NFAPI_HI_DCI0_DCI_PDU_TYPE:
       handle_nfapi_hi_dci0_dci_pdu(eNB,proc,hi_dci0_req_pdu);
       eNB->pdcch_vars[subframe&1].num_dci++; 
@@ -1271,7 +1098,6 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
 
     case NFAPI_HI_DCI0_HI_PDU_TYPE:
       handle_nfapi_hi_dci0_hi_pdu(eNB,proc,hi_dci0_req_pdu);
-      eNB->pdcch_vars[subframe&1].num_dci++; 
 
       break;
     }
@@ -1281,9 +1107,15 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
     ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i];
     LOG_I(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type);
     AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE ||
-		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE,
+		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE ||
+		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE ||
+		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE ||
+		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE ||
+		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE ||
+		ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
+		,
 		"Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type);
-    handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu);
+    handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu,UL_req->sfn_sf>>4,UL_req->sfn_sf&0xf,UL_req->ul_config_request_body.srs_present);
   }
 }
 
@@ -1298,7 +1130,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   UNUSED(rn);
   int frame=proc->frame_tx;
   int subframe=proc->subframe_tx;
-  uint32_t i,j,aa;
+  uint32_t i,aa;
   uint8_t harq_pid;
   int8_t UE_id=0;
   uint8_t num_pdcch_symbols=0;
@@ -1317,39 +1149,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
 
-  /*
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    // If we've dropped the UE, go back to PRACH mode for this UE
-    if ((frame==0)&&(subframe==0)) {
-      if (eNB->UE_stats[i].crnti > 0) {
-	LOG_I(PHY,"UE %d : rnti %x\n",i,eNB->UE_stats[i].crnti);
-      }
-    }
-    if (eNB->UE_stats[i].ulsch_consecutive_errors == ULSCH_max_consecutive_errors) {
-      LOG_W(PHY,"[eNB %d, CC %d] frame %d, subframe %d, UE %d: ULSCH consecutive error count reached %u, triggering UL Failure\n",
-            eNB->Mod_id,eNB->CC_id,frame,subframe, i, eNB->UE_stats[i].ulsch_consecutive_errors);
-      eNB->UE_stats[i].ulsch_consecutive_errors=0;
-      mac_xface->UL_failure_indication(eNB->Mod_id,
-				       eNB->CC_id,
-				       frame,
-				       eNB->UE_stats[i].crnti,
-				       subframe);
-				       
-    }
-	
-
-  }
-
-
-  // Get scheduling info for next subframe
-  // This is called only for the CC_id = 0 and triggers scheduling for all CC_id's
-  if (eNB->mac_enabled==1) {
-    if (eNB->CC_id == 0) {
-      mac_xface->eNB_dlsch_ulsch_scheduler(eNB->Mod_id,0,frame,subframe);//,1);
-    }
-  }
-  */
-
   // clear the transmit data array for the current subframe
   for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) {      
     memset(&eNB->common_vars.txdataF[aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)],
@@ -1422,12 +1221,8 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,(frame*10)+subframe);
 
-  // Apply physicalConfigDedicated if needed
-  // This is for UEs that have received this IE, which changes these DL and UL configuration, we apply after a delay for the eNodeB UL parameters
-  phy_config_dedicated_eNB_step2(eNB);
-
   if (num_dci > 0)
-    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8")\n",eNB->Mod_id,frame, subframe,
+    LOG_I(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8")\n",eNB->Mod_id,frame, subframe,
 	  num_dci);
     
   generate_dci_top(num_pdcch_symbols,
@@ -1479,73 +1274,23 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
 
 
-  // if we have PHICH to generate
-
-  if (is_phich_subframe(fp,subframe))
-    {
-      generate_phich_top(eNB,
-			 proc,
-			 AMP,
-			 0);
-    }
-
-  /*
-  if (frame>=10 && subframe>=9) {
-    write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1);
-    write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1);
-    abort();
-  }
-  */
+  generate_phich_top(eNB,
+		     proc,
+		     AMP);
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
   if (do_meas==1) stop_meas(&eNB->phy_proc_tx);
   
 }
 
-void process_Msg3(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id, uint8_t harq_pid)
-{
-  // this prepares the demodulation of the first PUSCH of a new user, containing Msg3
-  int subframe = proc->subframe_rx;
-  int frame = proc->frame_rx;
-  LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
-  LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[harq_pid];
-
-  LOG_D(PHY,"[eNB %d][RAPROC] frame %d : subframe %d : process_Msg3 UE_id %d (active %d, subframe %d, frame %d)\n",
-        eNB->Mod_id,
-        frame,subframe,
-        UE_id,ulsch->Msg3_active,
-        ulsch_harq->subframe,
-        ulsch_harq->frame);
-
-  ulsch_harq->Msg3_flag = 0;
-
-  if ((ulsch->Msg3_active == 1) &&
-      (ulsch_harq->subframe == subframe) &&
-      (ulsch_harq->frame == (uint32_t)frame))   {
-
-    //    harq_pid = 0;
-
-    ulsch->Msg3_active = 0;
-    ulsch_harq->Msg3_flag = 1;
-    LOG_D(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Setting subframe_scheduling_flag (Msg3) for UE %d\n",
-          eNB->Mod_id,
-          frame,subframe,UE_id);
-  }
-}
-
-
-// This function retrieves the harq_pid of the corresponding DLSCH process
-// and updates the error statistics of the DLSCH based on the received ACK
-// info from UE along with the round index.  It also performs the fine-grain
-// rate-adaptation based on the error statistics derived from the ACK/NAK process
 
 void process_HARQ_feedback(uint8_t UE_id,
-                           PHY_VARS_eNB *eNB,
+			   PHY_VARS_eNB *eNB,
 			   eNB_rxtx_proc_t *proc,
-                           uint8_t pusch_flag,
-                           uint8_t *pucch_payload,
-                           uint8_t pucch_sel,
-                           uint8_t SR_payload)
+			   uint8_t pusch_flag,
+			   uint8_t *pucch_payload,
+			   uint8_t pucch_sel,
+			   uint8_t SR_payload)
 {
 
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
@@ -1817,145 +1562,6 @@ void process_HARQ_feedback(uint8_t UE_id,
   }
 }
 
-void get_n1_pucch_eNB(PHY_VARS_eNB *eNB,
-		      eNB_rxtx_proc_t *proc,
-                      uint8_t UE_id,
-                      int16_t *n1_pucch0,
-                      int16_t *n1_pucch1,
-                      int16_t *n1_pucch2,
-                      int16_t *n1_pucch3)
-{
-
-  LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms;
-  uint8_t nCCE0,nCCE1;
-  int sf;
-  int frame = proc->frame_rx;
-  int subframe = proc->subframe_rx;
-
-  if (frame_parms->frame_type == FDD ) {
-    sf = (subframe<4) ? (subframe+6) : (subframe-4);
-
-    if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[sf]>0) {
-      *n1_pucch0 = frame_parms->pucch_config_common.n1PUCCH_AN + eNB->dlsch[(uint32_t)UE_id][0]->nCCE[sf];
-      *n1_pucch1 = -1;
-    } else {
-      *n1_pucch0 = -1;
-      *n1_pucch1 = -1;
-    }
-  } else {
-
-    switch (frame_parms->tdd_config) {
-    case 1:  // DL:S:UL:UL:DL:DL:S:UL:UL:DL
-      if (subframe == 2) {  // ACK subframes 5 and 6
-        /*  if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
-	    nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[6];
-	    *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
-	    }
-	    else
-	    *n1_pucch1 = -1;*/
-
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[5];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch0 = -1;
-
-        *n1_pucch1 = -1;
-      } else if (subframe == 3) { // ACK subframe 9
-
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[9];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch0 = -1;
-
-        *n1_pucch1 = -1;
-
-      } else if (subframe == 7) { // ACK subframes 0 and 1
-        //harq_ack[0].nCCE;
-        //harq_ack[1].nCCE;
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[0];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch0 = -1;
-
-        *n1_pucch1 = -1;
-      } else if (subframe == 8) { // ACK subframes 4
-        //harq_ack[4].nCCE;
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[4]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[4];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch0 = -1;
-
-        *n1_pucch1 = -1;
-      } else {
-        LOG_D(PHY,"[eNB %d] frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
-              eNB->Mod_id,
-              frame,
-              subframe,frame_parms->tdd_config);
-        return;
-      }
-
-      break;
-
-    case 3:  // DL:S:UL:UL:UL:DL:DL:DL:DL:DL
-      if (subframe == 2) {  // ACK subframes 5,6 and 1 (S in frame-2), forget about n-11 for the moment (S-subframe)
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[6]>0) {
-          nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[6];
-          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch1 = -1;
-
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[5]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[5];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch0 = -1;
-      } else if (subframe == 3) { // ACK subframes 7 and 8
-        LOG_D(PHY,"get_n1_pucch_eNB : subframe 3, subframe_tx[7] %d, subframe_tx[8] %d\n",
-              eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[7],eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[8]);
-
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[8]>0) {
-          nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[8];
-          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
-          LOG_D(PHY,"nCCE1 %d, n1_pucch1 %d\n",nCCE1,*n1_pucch1);
-        } else
-          *n1_pucch1 = -1;
-
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[7]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[7];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
-          LOG_D(PHY,"nCCE0 %d, n1_pucch0 %d\n",nCCE0,*n1_pucch0);
-        } else
-          *n1_pucch0 = -1;
-      } else if (subframe == 4) { // ACK subframes 9 and 0
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[0]>0) {
-          nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[0];
-          *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch1 = -1;
-
-        if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[9]>0) {
-          nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[9];
-          *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN;
-        } else
-          *n1_pucch0 = -1;
-      } else {
-        LOG_D(PHY,"[eNB %d] Frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
-              eNB->Mod_id,frame,subframe,frame_parms->tdd_config);
-        return;
-      }
-
-      break;
-    }  // switch tdd_config
-
-    // Don't handle the case M>2
-    *n1_pucch2 = -1;
-    *n1_pucch3 = -1;
-  }
-}
 
 void prach_procedures(PHY_VARS_eNB *eNB,
 #ifdef Rel14
@@ -1998,12 +1604,12 @@ void prach_procedures(PHY_VARS_eNB *eNB,
   for (i=0;i<eNB->num_RU;i++) {
     ru=eNB->RU_list[i];
     for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
-      eNB->prach_vars.rxsigF[aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
+      eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
 #ifdef Rel14
       int ce_level;
 
       if (br_flag==1)
-	for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa];
+	for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa];
 #endif
     }
   }
@@ -2020,13 +1626,13 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 #endif
 	   );
 
-#ifdef DEBUG_PHY_PROC
+  //#ifdef DEBUG_PHY_PROC
   LOG_I(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d\n",
         frame,subframe,
 	max_preamble[0],
         max_preamble_energy[0]/10,
         max_preamble_delay[0]);
-#endif
+  //q#endif
 
 #ifdef Rel14
   if (br_flag==1) {
@@ -2046,7 +1652,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 	  (prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions
 	  (eNB->prach_vars_br.repetition_number[ce_level]==
 	   eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) {
-    */
+    */ 
     if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]==1){ 
       if (max_preamble_energy[0] > 350) {
 	eNB->UL_INFO.rach_ind_br.number_of_preambles++;
@@ -2076,7 +1682,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 #endif
 
     {
-      if (max_preamble_energy[0] > 10000) {
+      if (max_preamble_energy[0] > 350) {
 
 	LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
 	      eNB->Mod_id,
@@ -2091,29 +1697,27 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 	    T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), 0,
 	      T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
 	    
-	    if (eNB->mac_enabled==1) {
-	      
-	      prach_vars = &eNB->prach_vars;
-	      
-	      
-	      pthread_mutex_lock(&eNB->UL_INFO_mutex);
-	      
-	      eNB->UL_INFO.rach_ind.number_of_preambles                 = 1;
-	      eNB->UL_INFO.rach_ind.preamble_list                       = eNB->preamble_list;
-	      
-	      eNB->preamble_list[0].preamble_rel8.timing_advance        = max_preamble_delay[0];
-	      eNB->preamble_list[0].preamble_rel8.preamble              = max_preamble[0];
-	      eNB->preamble_list[0].preamble_rel8.rnti                  = 1+subframe;  // note: fid is implicitly 0 here
-	      eNB->preamble_list[0].preamble_rel13.rach_resource_type   = 0;
-	      eNB->preamble_list[0].instance_length                     = 0; //don't know exactly what this is
-
-	      LOG_I(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
-		    eNB->preamble_list[0].preamble_rel8.timing_advance,
-		    eNB->preamble_list[0].preamble_rel8.preamble,
-		    eNB->preamble_list[0].preamble_rel8.rnti,
-		    eNB->preamble_list[0].preamble_rel13.rach_resource_type);	    
-	      pthread_mutex_unlock(&eNB->UL_INFO_mutex);
-	    }
+	    prach_vars = &eNB->prach_vars;
+	    
+	    
+	    pthread_mutex_lock(&eNB->UL_INFO_mutex);
+	    
+	    eNB->UL_INFO.rach_ind.number_of_preambles                 = 1;
+	    eNB->UL_INFO.rach_ind.preamble_list                       = eNB->preamble_list;
+	    
+	    eNB->preamble_list[0].preamble_rel8.timing_advance        = max_preamble_delay[0];
+	    eNB->preamble_list[0].preamble_rel8.preamble              = max_preamble[0];
+	    eNB->preamble_list[0].preamble_rel8.rnti                  = 1+subframe;  // note: fid is implicitly 0 here
+	    eNB->preamble_list[0].preamble_rel13.rach_resource_type   = 0;
+	    eNB->preamble_list[0].instance_length                     = 0; //don't know exactly what this is
+	    
+	    LOG_I(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
+		  eNB->preamble_list[0].preamble_rel8.timing_advance,
+		  eNB->preamble_list[0].preamble_rel8.preamble,
+		  eNB->preamble_list[0].preamble_rel8.rnti,
+		  eNB->preamble_list[0].preamble_rel13.rach_resource_type);	    
+	    pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+      
       } // max_preamble_energy > 350
     } // else br_flag
       /*
@@ -2134,47 +1738,74 @@ void prach_procedures(PHY_VARS_eNB *eNB,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
 }
 
-void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid,uint8_t do_srs)
+void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
+
+  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+  const int subframe = proc->subframe_rx;
+  const int frame = proc->frame_rx;
+
+  int i;
+
+  if (is_srs_occasion_common(fp,frame,subframe)) { 
+  
+  // Do SRS processing 
+  // check if there is SRS and we have to use shortened format
+  // TODO: check for exceptions in transmission of SRS together with ACK/NACK
+    for (i=0;i<NUMBER_OF_UE_MAX;i++) {
+
+      if (eNB->soundingrs_ul_config_dedicated[i].active==1) {
+
+      
+	if (lte_srs_channel_estimation(fp,
+				       &eNB->common_vars,
+				       &eNB->srs_vars[i],
+				       &eNB->soundingrs_ul_config_dedicated[i],
+				       subframe,
+				       0/*eNB_id*/)) {
+	  LOG_E(PHY,"problem processing SRS\n");
+	}
+	eNB->soundingrs_ul_config_dedicated[i].active=0;
+      }
+    }
+  }
+}
+
+void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe) {
+
+  pthread_mutex_lock(&eNB->UL_INFO_mutex);
+  nfapi_sr_indication_pdu_t *pdu =   &eNB->UL_INFO.sr_ind.sr_pdu_list[eNB->UL_INFO.sr_ind.number_of_srs];
+
+  pdu->instance_length                                = 0; // don't know what to do with this
+  //  pdu->rx_ue_information.handle                       = handle;
+  pdu->rx_ue_information.rnti                         = rnti;
+  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+
+  eNB->UL_INFO.sr_ind.number_of_srs++;
+  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+}
+
+void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 {
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
-  uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0};
-  int16_t n1_pucch0 = -1, n1_pucch1 = -1, n1_pucch2 = -1, n1_pucch3 = -1;
+  uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0};
   uint8_t do_SR = 0;
   uint8_t pucch_sel = 0;
-  int32_t metric0=0,metric1=0,metric0_SR=0;
+  int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric;
   ANFBmode_t bundling_flag;
   PUCCH_FMT_t format;
   const int subframe = proc->subframe_rx;
   const int frame = proc->frame_rx;
+  int i;
+  LTE_eNB_UCI *uci;
+  uint16_t tdd_multiplexing_mask=0;
+  int res;
 
-  if ((eNB->dlsch[UE_id][0]) &&
-      (eNB->dlsch[UE_id][0]->rnti>0) &&
-      (eNB->ulsch[UE_id]->harq_processes[harq_pid]->frame != frame) &&
-      (eNB->ulsch[UE_id]->harq_processes[harq_pid]->subframe != subframe)) {
-
-    // check SR availability
-    do_SR = is_SR_subframe(eNB,proc,UE_id);
-    //      do_SR = 0;
-
-    // Now ACK/NAK
-    // First check subframe_tx flag for earlier subframes
-
-    get_n1_pucch_eNB(eNB,
-                     proc,
-                     UE_id,
-                     &n1_pucch0,
-                     &n1_pucch1,
-                     &n1_pucch2,
-                     &n1_pucch3);
-
-    LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d, subframe %d Checking for PUCCH (%d,%d,%d,%d) SR %d\n",
-          eNB->Mod_id,eNB->dlsch[UE_id][0]->rnti,
-          frame,subframe,
-          n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,do_SR);
+  for (i=0;i<NUMBER_OF_UE_MAX;i++) {
 
-    if ((n1_pucch0==-1) && (n1_pucch1==-1) && (do_SR==0)) {  // no TX PDSCH that have to be checked and no SR for this UE_id
-    } else {
-      // otherwise we have some PUCCH detection to do
+    uci = &eNB->uci_vars[i];
+    if ((uci->active == 1) &&
+	(uci->frame == frame) &&
+	(uci->subframe == subframe)) {
 
       // Null out PUCCH PRBs for noise measurement
       switch(fp->N_RB_UL) {
@@ -2204,285 +1835,699 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq
         break;
       }
 
-      if (do_SR == 1) {
-        eNB->UE_stats[UE_id].sr_total++;
-
-
-	metric0_SR = rx_pucch(eNB,
-			      pucch_format1,
-			      UE_id,
-			      eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,
+      switch (uci->type) {
+      case SR:
+      case HARQ_SR:
+		
+	metric_SR = rx_pucch(eNB,
+			      uci->pucch_fmt,
+			      i,
+			      uci->n_pucch_1_0_sr[0],
 			      0, // n2_pucch
-			      do_srs, // shortened format
+			      uci->srs_active, // shortened format
 			      &SR_payload,
 			      frame,
 			      subframe,
 			      PUCCH1_THRES);
-	LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n",
+	LOG_I(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n",
 	      eNB->Mod_id,
-	      eNB->ulsch[UE_id]->rnti,
+	      uci->rnti,
 	      frame,
 	      subframe,
 	      SR_payload,
-	      eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex);
-      }// do_SR==1
-
-      if ((n1_pucch0==-1) && (n1_pucch1==-1)) { // just check for SR
-      } else if (fp->frame_type==FDD) { // FDD
-        // if SR was detected, use the n1_pucch from SR, else use n1_pucch0
-        //          n1_pucch0 = (SR_payload==1) ? eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex:n1_pucch0;
-
-        LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload);
-
-	metric0 = rx_pucch(eNB,
-			   pucch_format1a,
-			   UE_id,
-			   (uint16_t)n1_pucch0,
-			   0, //n2_pucch
-			   do_srs, // shortened format
-			   pucch_payload0,
-			   frame,
-			   subframe,
-			   PUCCH1a_THRES);
-        
-
-        /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index */
-        if (do_SR && metric0 > metric0_SR) SR_payload = 0;
-
-        if (do_SR && metric0 <= metric0_SR) {
-          /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */
-          SR_payload = 1;
-
-	  metric0=rx_pucch(eNB,
-			   pucch_format1a,
-			   UE_id,
-			   eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,
-			   0, //n2_pucch
-			   do_srs, // shortened format
-			   pucch_payload0,
-			   frame,
-			   subframe,
-			   PUCCH1a_THRES);
-        }
-
+	      uci->n_pucch_1_0_sr[0]);
+	if (uci->type == SR) {
+	  if (SR_payload == 1) {
+	    fill_sr_indication(eNB,uci->rnti,frame,subframe);
+	    return;
+	  }
+	  else {
+	    return;
+	  }
+	}
+      case HARQ:
+	if (fp->frame_type == FDD) {
+	  LOG_I(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n",
+		frame,subframe,i,
+		uci->pucch_fmt,uci->type,
+		uci->frame,uci->subframe,uci->n_pucch_1[0][0],
+		SR_payload);
+	  
+	  metric[0] = rx_pucch(eNB,
+			       uci->pucch_fmt,
+			       i,
+			       uci->n_pucch_1[0][0],
+			       0, //n2_pucch
+			       uci->srs_active, // shortened format
+			       pucch_b0b1[0],
+			       frame,
+			       subframe,
+			       PUCCH1a_THRES);
+	  
+	  
+	  /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */
+	  if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
+	  else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe);
+ 
+	  if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
+	    /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */
+	    SR_payload = 1;
+	    
+	    metric[0]=rx_pucch(eNB,
+			       uci->pucch_fmt,
+			       i,
+			       uci->n_pucch_1_0_sr[0],
+			       0, //n2_pucch
+			       uci->srs_active, // shortened format
+			       pucch_b0b1[0],
+			       frame,
+			       subframe,
+			       PUCCH1a_THRES);
+	  }
+	  
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
-            eNB->Mod_id,
-            eNB->dlsch[UE_id][0]->rnti,
-            frame,subframe,
-            pucch_payload0[0],metric0);
+	  LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
+		eNB->Mod_id,
+		uci->rnti,
+		frame,subframe,
+		pucch_b0b1[0][0],metric0);
 #endif
+	  
+	  fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
 
-        process_HARQ_feedback(UE_id,eNB,proc,
-                            0,// pusch_flag
-                            pucch_payload0,
-                            2,
-                            SR_payload);
-      } // FDD
-      else {  //TDD
-
-        bundling_flag = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode;
-
-        // fix later for 2 TB case and format1b
-
-        if ((fp->frame_type==FDD) ||
-          (bundling_flag==bundling)    ||
-          ((fp->frame_type==TDD)&&(fp->tdd_config==1)&&((subframe!=2)&&(subframe!=7)))) {
-          format = pucch_format1a;
-        } else {
-          format = pucch_format1b;
-        }
+	}
+	else { // frame_type == TDD
+	  
 
-        // if SR was detected, use the n1_pucch from SR
-        if (SR_payload==1) {
+	  // if SR was detected, use the n1_pucch from SR
+	  if (SR_payload==1) {
 #ifdef DEBUG_PHY_PROC
-          LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id,
-                eNB->dlsch[UE_id][0]->rnti,
-                frame,subframe,
-                n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
+	    LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id,
+		  eNB->dlsch[UE_id][0]->rnti,
+		  frame,subframe,
+		  n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
 #endif
-
-	  metric0 = rx_pucch(eNB,
-			     format,
-			     UE_id,
-			     eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,
-			     0, //n2_pucch
-			     do_srs, // shortened format
-			     pucch_payload0,
-			     frame,
-			     subframe,
-			     PUCCH1a_THRES);
-        } else { //using n1_pucch0/n1_pucch1 resources
+	    
+	    metric[0] = rx_pucch(eNB,
+				 pucch_format1b,
+				 i,
+				 uci->n_pucch_1_0_sr[0],
+				 0, //n2_pucch
+				 uci->srs_active, // shortened format
+				 pucch_b0b1[0],
+				 frame,
+				 subframe,
+				 PUCCH1a_THRES);
+	  } else { //using assigned pucch resources
 #ifdef DEBUG_PHY_PROC
-          LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",eNB->Mod_id,
-                eNB->dlsch[UE_id][0]->rnti,
-                frame,subframe,
-                n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format);
+	    LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK M=%d (%d,%d,%d,%d) format %d\n",eNB->Mod_id,
+		  eNB->dlsch[UE_id][0]->rnti,
+		  frame,subframe,
+		  uci->num_pucch_resources,
+		  uci->n_pucch_1[res][0],
+		  uci->n_pucch_1[res][1],
+		  uci->n_pucch_1[res][2],
+		  uci->n_pucch_1[res][3],
+		  uci->pucch_fmt);
 #endif
-          metric0=0;
-          metric1=0;
-
-          // Check n1_pucch0 metric
-          if (n1_pucch0 != -1) {
-	    metric0 = rx_pucch(eNB,
-			       format,
-			       UE_id,
-			       (uint16_t)n1_pucch0,
-			       0, // n2_pucch
-			       do_srs, // shortened format
-			       pucch_payload0,
-			       frame,
-			       subframe,
-			       PUCCH1a_THRES);
-          }
+	    for (res=0;res<uci->num_pucch_resources;res++)
+	      metric[res] = rx_pucch(eNB,
+				     uci->pucch_fmt,
+				     i,
+				     uci->n_pucch_1[res][0],
+				     0, // n2_pucch
+				     uci->srs_active, // shortened format
+				     pucch_b0b1[res],
+				     frame,
+				     subframe,
+				     PUCCH1a_THRES);
+	  	  
+	    
+
+	  }
 
-          // Check n1_pucch1 metric
-          if (n1_pucch1 != -1) {
-	    metric1 = rx_pucch(eNB,
-			       format,
-			       UE_id,
-			       (uint16_t)n1_pucch1,
-			       0, //n2_pucch
-			       do_srs, // shortened format
-			       pucch_payload1,
-			       frame,
-			       subframe,
-			       PUCCH1a_THRES);
-          }
-        }
-	
-        if (SR_payload == 1) {
-          pucch_payload = pucch_payload0;
 	  
-          if (bundling_flag == bundling)
-            pucch_sel = 2;
-        } else if (bundling_flag == multiplexing) { // multiplexing + no SR
-          pucch_payload = (metric1>metric0) ? pucch_payload1 : pucch_payload0;
-          pucch_sel     = (metric1>metric0) ? 1 : 0;
-        } else { // bundling + no SR
-          if (n1_pucch1 != -1)
-            pucch_payload = pucch_payload1;
-          else if (n1_pucch0 != -1)
-            pucch_payload = pucch_payload0;
+	  if (SR_payload == 1) { // this implements Table 7.3.1 from 36.213
+	    if (pucch_b0b1[0][0] == 4) { // there isn't a likely transmission
+	      harq_ack[0] = 4; // DTX
+	    }
+	    else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1) { // 1/4/7 ACKs
+	      harq_ack[0] = 1;
+	    }
+	    else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1) { // 2/5/8 ACKs
+	      harq_ack[0] = 2;
+	    }
+	    else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1) { // 3/6/9 ACKs
+	      harq_ack[0] = 3;
+	    }
+	    else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1) { // 0 ACKs, or at least one DL assignment missed
+	      harq_ack[0] = 0;
+	    }
+	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
+	  } 
+	  else if ((bundling_flag == 0) && (res==2)){ // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
+	    if (pucch_b0b1[0][0] == 4 ||
+		pucch_b0b1[1][0] == 4) { // there isn't a likely transmission
+	      harq_ack[0] = 4; // DTX
+	      harq_ack[1] = 6; // NACK/DTX
+	    } 
+	    else {
+	      if (metric[1]>metric[0]) {
+		if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 1; // ACK
+		  tdd_multiplexing_mask = 0x3;
+		}
+		else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1){
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  tdd_multiplexing_mask = 0x2;
+		}
+		else {
+		  harq_ack[0] = 4; // DTX
+		  harq_ack[1] = 4; // DTX
+		}
+	      }
+	      else {
+		if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x1;
+		}
+		else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){
+		  harq_ack[0] = 2; // NACK
+		  harq_ack[1] = 6; // NACK/DTX
+		}
+		else {
+		  harq_ack[0] = 4; // DTX
+		  harq_ack[1] = 4; // DTX
+		}
+	      }
+	    }
+	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
+	  } //else if ((bundling_flag == 0) && (res==2))
+	  else if ((bundling_flag == 0) && (res==3)){ // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
+	    
+	    if (harq_ack[0] == 4 ||
+		harq_ack[1] == 4 ||
+		harq_ack[2] == 4) { // there isn't a likely transmission
+	      harq_ack[0] = 4; // DTX
+	      harq_ack[1] = 6; // NACK/DTX
+	      harq_ack[2] = 6; // NACK/DTX
+	      
+	    } 
+	    else {
+	      
+	      max_metric = max(metric[0],max(metric[1],metric[2]));
+	      
+	      if (metric[0]==max_metric) {
+		if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x1;
+		}
+		else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){
+		  harq_ack[0] = 2; // NACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 6; // NACK/DTX
+		}
+		else {
+		  harq_ack[0] = 4; // DTX
+		  harq_ack[1] = 4; // DTX
+		  harq_ack[2] = 4; // DTX
+		}
+	      } // if (metric[0]==max_metric) {
+	      else if (metric[1]==max_metric) {
+	      
+	        if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x3;
+		}
+		else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x2;
+		}
+		else {
+		  harq_ack[0] = 4; // DTX
+		  harq_ack[1] = 4; // DTX
+		  harq_ack[2] = 4; // DTX
+		}
+	      } // if (metric[1]==max_metric) {
+	      else {
+  	        if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 1; // ACK
+		  tdd_multiplexing_mask = 0x7;
+		}
+		else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) {
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 1; // ACK
+		  tdd_multiplexing_mask = 0x5;
+		}
+		else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 1; // ACK
+		  tdd_multiplexing_mask = 0x6;
+		}
+		else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 1; // ACK
+		  tdd_multiplexing_mask = 0x4;
+		}
+	      }
+	    }
+	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
+	  } //else if ((bundling_flag == 0) && (res==3)) 
+	  else if ((bundling_flag == 0) && (res==4)){ // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
+	    if (pucch_b0b1[0][0] == 4 ||
+		pucch_b0b1[1][0] == 4 ||
+		pucch_b0b1[2][0] == 4 ||
+		pucch_b0b1[3][0] == 4) { // there isn't a likely transmission
+	      harq_ack[0] = 4; // DTX
+	      harq_ack[1] = 6; // NACK/DTX
+	      harq_ack[2] = 6; // NACK/DTX
+	      harq_ack[3] = 6; // NACK/DTX
+		
+	    } else {
+
+	      max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3])));
+	      
+	      if (metric[0]==max_metric) {
+		if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1){
+		  harq_ack[0] = 2; // NACK
+		  harq_ack[1] = 4; // DTX
+		  harq_ack[2] = 4; // DTX
+		  harq_ack[3] = 4; // DTX
+		}
+		else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0x9;
+		}
+		else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x1;
+		}
+		else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){
+		  harq_ack[0] = 2; // NACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 6; // NACK/DTX
+		}
+		
+	      } 
+	      else if (metric[1]==max_metric) {
+		if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0xF;
+		}
+		else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1 ) {
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x3;
+		}
+		else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0xE;
+		}
+		else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x2;
+		}
+	      } 
+	      else if (metric[2]==max_metric) {
+		if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x7;
+		}
+		else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) {
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 6; // NACK/DTX
+		  tdd_multiplexing_mask = 0x5;
+		}
+		else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) {
+		  harq_ack[0] = 4; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 4; // NACK/DTX
+		  tdd_multiplexing_mask = 0x6;
+		}
+		else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) {
+		  harq_ack[0] = 4; // NACK/DTX
+		  harq_ack[1] = 4; // NACK/DTX
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 4; // NACK/DTX
+		  tdd_multiplexing_mask = 0x4;
+		}
+	      } 
+	      else { // max_metric[3]=max_metric
+		if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){
+		  harq_ack[0] = 1; // ACK
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0xD;
+		}
+		else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 1; // ACK
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0xA;
+		}
+		else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 1; // ACK
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0xC;
+		}
+		else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) {
+		  harq_ack[0] = 6; // NACK/DTX
+		  harq_ack[1] = 6; // NACK/DTX
+		  harq_ack[2] = 6; // NACK/DTX
+		  harq_ack[3] = 1; // ACK
+		  tdd_multiplexing_mask = 0x8;
+		}
+	      }
+	    }
+	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
+	  } // else if ((bundling_flag == 0) && (res==4))
+	  else { // bundling
+	    harq_ack[0] = pucch_b0b1[0][0];
+	    harq_ack[1] = pucch_b0b1[0][1];
+	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode
+	  }
 	  
-          pucch_sel = 2;  // indicate that this is a bundled ACK/NAK
-        }
-	
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id,
-              eNB->dlsch[UE_id][0]->rnti,
-              frame,subframe,
-              metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]);
+	  LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id,
+		eNB->dlsch[UE_id][0]->rnti,
+		frame,subframe,
+		metric0,metric1,pucch_sel,pucch_b0b1[0],pucch_b0b1[1]);
 #endif
-        process_HARQ_feedback(UE_id,eNB,proc,
-                              0,// pusch_flag
-                              pucch_payload,
-                              pucch_sel,
-                              SR_payload);
-      } // TDD
-    }
-
-    if (SR_payload == 1) {
-      LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id,
-            eNB->ulsch[UE_id]->rnti,frame,subframe);
-      eNB->UE_stats[UE_id].sr_received++;
-
-      if (eNB->first_sr[UE_id] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
-        eNB->first_sr[UE_id] = 0;
-        eNB->dlsch[UE_id][0]->harq_processes[0]->round=0;
-        eNB->dlsch[UE_id][0]->harq_processes[0]->status=SCH_IDLE;
-        LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
-              eNB->Mod_id,
-              eNB->ulsch[UE_id]->rnti,frame,subframe);
+	}
+	break;
+      default:
+	AssertFatal(1==0,"Unsupported UCI type %d\n",uci->type);
+	break;
       }
-
-      if (eNB->mac_enabled==1) {
-	/*
-        mac_xface->SR_indication(eNB->Mod_id,
-                                 eNB->CC_id,
-                                 frame,
-                                 eNB->dlsch[UE_id][0]->rnti,subframe);
-	*/
-
-	// fill eNB->UL_info with SR indications
+    
+      if (SR_payload == 1) {
+	LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id,
+	      uci->rnti,frame,subframe);
+	
+	if (eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
+	  eNB->first_sr[i] = 0;
+	  eNB->dlsch[i][0]->harq_processes[0]->round=0;
+	  eNB->dlsch[i][0]->harq_processes[0]->status=SCH_IDLE;
+	  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n",
+		eNB->Mod_id,
+		eNB->ulsch[i]->rnti,frame,subframe);
+	}
       }
     }
   }
 }
 
+void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
 
+  uint32_t ret=0,i,j,k;
+  uint32_t harq_pid, harq_idx, round;
+  uint8_t nPRS;
+  int sync_pos;
+  uint16_t rnti=0;
+  uint8_t access_mode;
+  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
+  LTE_eNB_ULSCH_t *ulsch;
+  LTE_UL_eNB_HARQ_t *ulsch_harq;
 
-extern int oai_exit;
+  const int subframe = proc->subframe_rx;
+  const int frame    = proc->frame_rx;
+  int offset         = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1;
+  
+  if (fp->frame_type == FDD) harq_pid = ((10*frame) + subframe)&7;
+  else                       harq_pid = subframe%10;
 
-extern void *td_thread(void*);
 
-void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) {
 
-  eNB_proc_t *proc = &eNB->proc;
+  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
 
-  proc->tdp.eNB = eNB;
-  proc->instance_cnt_td         = -1;
+    ulsch = eNB->ulsch[i];
+    ulsch_harq = ulsch->harq_processes[harq_pid];
+    if (ulsch->rnti>0) LOG_I(PHY,"Frame %d, subframe %d: PUSCH procedures, harq_pid %d, UE %d/%x\n",
+			     frame,subframe,harq_pid,i,ulsch->rnti);
     
-  pthread_mutex_init( &proc->mutex_td, NULL);
-  pthread_cond_init( &proc->cond_td, NULL);
-
-  pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp);
+    if ((ulsch) &&
+        (ulsch->rnti>0) &&
+        (ulsch_harq->status == ACTIVE) &&
+	(ulsch_harq->frame == frame) &&
+	(ulsch_harq->subframe == subframe)) {
+      
+      
+      // UE is has ULSCH scheduling
+      round = ulsch_harq->round;
+ 
+      for (int rb=0;
+           rb<=ulsch_harq->nb_rb;
+	   rb++) {
+	int rb2 = rb+ulsch_harq->first_rb;
+	eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
+      }
 
-}
 
-extern void *te_thread(void*);
+      LOG_I(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n",
+	    eNB->Mod_id,
+	    frame,
+	    subframe,
+	    i);
 
-void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) {
 
-  eNB_proc_t *proc = &eNB->proc;
+      nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
 
-  proc->tep.eNB = eNB;
-  proc->instance_cnt_te         = -1;
-    
-  pthread_mutex_init( &proc->mutex_te, NULL);
-  pthread_cond_init( &proc->cond_te, NULL);
+      ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + 
+			    fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
+			    nPRS)%12;
 
-  printf("Creating te_thread\n");
-  pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep);
+      LOG_I(PHY,
+            "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n",
+            eNB->Mod_id,harq_pid,frame,subframe,
+            ulsch_harq->dci_alloc,
+            ulsch_harq->rar_alloc,
+            ulsch_harq->round,
+            ulsch_harq->first_rb,
+            ulsch_harq->nb_rb,
+            ulsch_harq->Qm,
+            ulsch_harq->TBS,
+            ulsch_harq->rvidx,
+            ulsch->cyclicShift,
+            ulsch_harq->n_DMRS2,
+            fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
+            nPRS,
+            ulsch_harq->O_ACK);
 
-}
+      start_meas(&eNB->ulsch_demodulation_stats);
 
+      rx_ulsch(eNB,proc,
+	       i);
+      
 
+      stop_meas(&eNB->ulsch_demodulation_stats);
 
-/*
-void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc){
 
+      start_meas(&eNB->ulsch_decoding_stats);
+
+      ret = ulsch_decoding(eNB,proc,
+			   i,
+			   0, // control_only_flag
+			   ulsch_harq->V_UL_DAI,
+			   ulsch_harq->nb_rb>20 ? 1 : 0);
+      
 
-  //  eNB_proc_t *proc       = &eNB->proc;
-  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
-  const int subframe     = proc->subframe_rx;
-  const int frame        = proc->frame_rx;
-  int offset             = (eNB->single_thread_flag==1) ? 0 : (subframe&1);
 
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB+offset, proc->frame_rx );
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB+offset, proc->subframe_rx );
+      stop_meas(&eNB->ulsch_decoding_stats);
+
+      LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
+            eNB->Mod_id,harq_pid,
+            frame,subframe,
+            ulsch->rnti,
+            dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
+            dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
+            20,//eNB->measurements.n0_power_dB[0],
+            20,//eNB->measurements.n0_power_dB[1],
+            ulsch_harq->o_ACK[0],
+            ulsch_harq->o_ACK[1],
+            ret);
 
-  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) {
 
-    if (eNB->node_function == NGFI_RRU_IF4p5) {
-      /// **** in TDD during DL send_IF4 of ULTICK to RCC **** ///
-      send_IF4p5(eNB, proc->frame_rx, proc->subframe_rx, IF4p5_PULTICK, 0);
-    }    
-    return;
-  }
+      //compute the expected ULSCH RX power (for the stats)
+      eNB->ulsch[(uint32_t)i]->harq_processes[harq_pid]->delta_TF =
+        get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
+
+
+      if (ulsch_harq->cqi_crc_status == 1) {
+#ifdef DEBUG_PHY_PROC
+        //if (((frame%10) == 0) || (frame < 50))
+        print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL);
+#endif
+
+      }
+      fill_ulsch_cqi_indication(eNB,frame,subframe,
+				ulsch_harq,
+				ulsch->rnti);
+      
+      if (ret == (1+MAX_TURBO_ITERATIONS)) {
+        T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti),
+          T_INT(harq_pid));
+
+        ulsch_harq->round++;
+
+	fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC
+
+        LOG_I(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,ulsch_harq->round);
+
+	LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
+	      eNB->Mod_id,harq_pid,
+	      frame,subframe, i,
+	      ulsch_harq->round-1,
+	      ulsch->Mlimit,
+	      ulsch_harq->o_ACK[0],
+	      ulsch_harq->o_ACK[1]);
+	
+#if defined(MESSAGE_CHART_GENERATOR_PHY)
+	MSC_LOG_RX_DISCARDED_MESSAGE(
+				     MSC_PHY_ENB,MSC_PHY_UE,
+				     NULL,0,
+				     "%05u:%02u ULSCH received rnti %x harq id %u round %d",
+				     frame,subframe,
+				     ulsch->rnti,harq_pid,
+				     ulsch_harq->round-1
+				     );
+#endif
+
+      }  // ulsch in error
+      else {
+	
+
+	fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
+	fill_rx_indication(eNB,i,frame,subframe);    // indicate SDU to MAC
+        T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti),
+          T_INT(harq_pid));
+
+#if defined(MESSAGE_CHART_GENERATOR_PHY)
+        MSC_LOG_RX_MESSAGE(
+			   MSC_PHY_ENB,MSC_PHY_UE,
+			   NULL,0,
+			   "%05u:%02u ULSCH received rnti %x harq id %u",
+			   frame,subframe,
+			   ulsch->rnti,harq_pid
+			   );
+#endif
+
+#ifdef DEBUG_PHY_PROC
+#ifdef DEBUG_ULSCH
+	LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
+                harq_pid,ulsch_harq->TBS>>3);
+	
+	for (j=0; j<ulsch_harq->TBS>>3; j++)
+	  LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]);
+	
+	LOG_T(PHY,"\n");
+#endif
+#endif
+
+        
+	
+      }  // ulsch not in error
+
+      if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling);
+
+#ifdef DEBUG_PHY_PROC
+      LOG_D(PHY,"[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n",
+            eNB->Mod_id,frame,subframe,
+            harq_pid,
+            i,
+            ret,
+            ulsch_harq->cqi_crc_status,
+            ulsch_harq->o_ACK[0],
+            ulsch_harq->o_ACK[1],
+            eNB->UE_stats[i].ulsch_errors[harq_pid],
+            eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
+#endif
+      
+    } //     if ((ulsch) &&
+      //         (ulsch->rnti>0) &&
+      //         (ulsch_harq->status == ACTIVE))
+  }   //   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
+}
+
+extern int oai_exit;
+
+extern void *td_thread(void*);
+
+void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) {
+
+  eNB_proc_t *proc = &eNB->proc;
+
+  proc->tdp.eNB = eNB;
+  proc->instance_cnt_td         = -1;
+    
+  pthread_mutex_init( &proc->mutex_td, NULL);
+  pthread_cond_init( &proc->cond_td, NULL);
+
+  pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp);
+
+}
+
+extern void *te_thread(void*);
 
+void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) {
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 1 ); 
-  start_meas(&eNB->phy_proc_rx);
-  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe);
+  eNB_proc_t *proc = &eNB->proc;
 
+  proc->tep.eNB = eNB;
+  proc->instance_cnt_te         = -1;
+    
+  pthread_mutex_init( &proc->mutex_te, NULL);
+  pthread_cond_init( &proc->cond_te, NULL);
 
-  if (eNB->fep) eNB->fep(eNB,proc);
+  printf("Creating te_thread\n");
+  pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep);
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 0 );
 }
 
-*/
+
+
+
 
 void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
 
@@ -2542,531 +2587,360 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
 
 }
 
-void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag) {
+void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) {
 
-  pthread_mutex_lock(&eNB->UL_INFO_mutex);
-  nfapi_crc_indication_pdu_t *pdu =   &eNB->UL_INFO.crc_ind.crc_pdu_list[eNB->UL_INFO.crc_ind.number_of_crcs];
+  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+  int harq_pid;
+  int subframe_tx;
+  int M,m;
 
-  pdu->instance_length                                = 0; // don't know what to do with this
-  //  pdu->rx_ue_information.handle                       = handle;
-  pdu->rx_ue_information.rnti                         = eNB->ulsch[UE_id]->rnti;
-  pdu->crc_indication_rel8.crc_flag                   = crc_flag;
-  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+  AssertFatal(UE_id!=-1,"no existing dlsch context\n");
+  AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+  dlsch0 = eNB->dlsch[UE_id][0];
+  dlsch1 = eNB->dlsch[UE_id][1];
 
-  eNB->UL_INFO.crc_ind.number_of_crcs++;
-  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
-}
+  if (eNB->frame_parms.frame_type == FDD) {  
+    subframe_tx = (subframe+6)%10;
+    harq_pid = dlsch0->harq_ids[subframe_tx];
+    AssertFatal((harq_pid>=0) && (harq_pid<10),"harq_pid %d not in 0...9\n",harq_pid);
+    dlsch0_harq     = dlsch0->harq_processes[harq_pid];
+    dlsch1_harq     = dlsch1->harq_processes[harq_pid];
+    AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
+
+    dlsch0_harq->status = SCH_IDLE;
+    if ((dlsch1_harq == NULL)||
+	((dlsch1_harq!=NULL)&&
+	 (dlsch1_harq->status == SCH_IDLE)))
+      dlsch0->harq_mask   &= ~(1<<harq_pid);
+  }
+  else { // release all processes in the bundle that was acked, based on mask
+         // This is at most 4 for multiplexing and 9 for bundling/special bundling
+    M=ul_ACK_subframe2_M(&eNB->frame_parms,
+                         subframe);
 
-void update_harq_scheduling(LTE_DL_FRAME_PARMS *fp,LTE_UL_eNB_HARQ_t *ulsch_harq,int frame,int subframe) {
-  if (fp->frame_type == FDD) {
-    ulsch_harq->frame    += (ulsch_harq->subframe>1) ? 1 : 0;
-    ulsch_harq->subframe  = (ulsch_harq->subframe + 8)%10;
+    for (m=0; m<M; m++) {
+      subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms,
+						 subframe,
+						 m);
+      if (((1<<m)&mask) > 0) {
+	harq_pid = dlsch0->harq_ids[subframe_tx];
+	if ((harq_pid>=0) && (harq_pid<10)) {
+	  dlsch0_harq     = dlsch0->harq_processes[harq_pid];
+	  dlsch1_harq     = dlsch1->harq_processes[harq_pid];
+	  AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
+      
+	  dlsch0_harq->status = SCH_IDLE;
+	  if ((dlsch1_harq == NULL)||
+	      ((dlsch1_harq!=NULL)&&
+	       (dlsch1_harq->status == SCH_IDLE)))
+	    dlsch0->harq_mask   &= ~(1<<harq_pid);
+	}
+      }
+    }
   }
-  else ulsch_harq->frame++;
 }
 
+int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
 
-void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type)
-{
-  //RX processing for ue-specific resources (i
-  UNUSED(r_type);
-  uint32_t ret=0,i,j,k;
-  uint32_t harq_pid, harq_idx, round;
-  uint8_t nPRS;
-  int sync_pos;
-  uint16_t rnti=0;
-  uint8_t access_mode;
-  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
-  LTE_eNB_ULSCH_t *ulsch;
-  LTE_UL_eNB_HARQ_t *ulsch_harq;
-
-  const int subframe = proc->subframe_rx;
-  const int frame    = proc->frame_rx;
-  int offset         = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1;
-
-  uint16_t srsPeriodicity;
-  uint16_t srsOffset;
-  uint16_t do_srs=0;
-  uint16_t is_srs_pos=0;
-
-  T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
-
-  T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0),
-    T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti],
-             eNB->frame_parms.samples_per_tti * 4));
-
-  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return;
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC+offset, 1 );
-
-#ifdef DEBUG_PHY_PROC
-  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe);
-#endif
+  int M,Mtx=0;
+  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+  int harq_pid;
+  int subframe_tx;
+  int m;
 
-  eNB->rb_mask_ul[0]=0;
-  eNB->rb_mask_ul[1]=0;
-  eNB->rb_mask_ul[2]=0;
-  eNB->rb_mask_ul[3]=0;
+  M=ul_ACK_subframe2_M(&eNB->frame_parms,
+		       subframe);
+  
+  for (m=0; m<M; m++) {
+    subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms,
+					       subframe,
+					       m);
+    harq_pid = dlsch0->harq_ids[subframe_tx];
+    if (harq_pid>=0 && harq_pid<10) {
+      dlsch0_harq     = dlsch0->harq_processes[harq_pid];
+      dlsch1_harq     = dlsch1->harq_processes[harq_pid];
+      AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
+      if (dlsch0_harq->status == ACTIVE||
+	  (dlsch1_harq!=NULL && dlsch1_harq->status == ACTIVE)) Mtx ++;
+    }
+  }
+  return(Mtx);
+}
 
-  eNB->UL_INFO.rx_ind.number_of_pdus  = 0;
-  eNB->UL_INFO.crc_ind.number_of_crcs = 0;
 
-  // Check for active processes in current subframe
-  harq_pid = subframe2harq_pid(fp,
-                               frame,subframe);
+void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti) {
 
-  is_srs_pos = is_srs_occasion_common(fp,frame,subframe);
+  pthread_mutex_lock(&eNB->UL_INFO_mutex);
+  nfapi_cqi_indication_pdu_t *pdu         = &eNB->UL_INFO.cqi_ind.cqi_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis];
+  nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis];
+  uint8_t O;
+
+  pdu->rx_ue_information.rnti = rnti;
+  if (ulsch_harq->cqi_crc_status != 1) pdu->cqi_indication_rel9.data_offset = 0;
+  else               pdu->cqi_indication_rel9.data_offset = 1; // fill in after all cqi_indications have been generated when non-zero
+
+  // by default set O to rank 1 value
+  pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + (ulsch_harq->Or1&7) > 0 ? 1 : 0; 
+  pdu->cqi_indication_rel9.ri[0]  = 0;
+
+  // if we have RI bits, set them and if rank2 overwrite O
+  if (ulsch_harq->O_RI>0) {
+    pdu->cqi_indication_rel9.ri[0] = ulsch_harq->o_RI[0];
+    if (ulsch_harq->o_RI[0] == 2)   pdu->cqi_indication_rel9.length = (ulsch_harq->Or2>>3) + (ulsch_harq->Or2&7) > 0 ? 1 : 0; 
+    pdu->cqi_indication_rel9.timing_advance = 0;
+  }
   
-  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
+  pdu->cqi_indication_rel9.number_of_cc_reported = 1;
+  pdu->ul_cqi_information.channel = 1; // PUSCH
+  memcpy((void*)raw_pdu->pdu,ulsch_harq->o,pdu->cqi_indication_rel9.length);
+  eNB->UL_INFO.cqi_ind.number_of_cqis++;
+  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 
-    ulsch = eNB->ulsch[i];
-    ulsch_harq = ulsch->harq_processes[harq_pid];
+}
 
-    // Do SRS processing 
-    // check if there is SRS and we have to use shortened format
-    // TODO: check for exceptions in transmission of SRS together with ACK/NACK
-    do_srs=0;
-    if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[i].srsConfigDedicatedSetup ) {
-      compute_srs_pos(fp->frame_type, eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex, &srsPeriodicity, &srsOffset);
-      if (((10*frame+subframe) % srsPeriodicity) == srsOffset) {
-	do_srs = 1;
-      }
-    }
+void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling) {
 
-    if (do_srs==1) {
-      if (lte_srs_channel_estimation(fp,
-				     &eNB->common_vars,
-				     &eNB->srs_vars[i],
-				     &eNB->soundingrs_ul_config_dedicated[i],
-				     subframe,
-				     0/*eNB_id*/)) {
-	LOG_E(PHY,"problem processing SRS\n");
-      }
-    }
-    
-    // Do PUCCH processing 
+  int UE_id;
 
-    pucch_procedures(eNB,proc,i,harq_pid, do_srs);
 
+  pthread_mutex_lock(&eNB->UL_INFO_mutex);
+  nfapi_harq_indication_pdu_t *pdu =   &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs];
+  int M;
+  int i;
 
-    // check for Msg3
-    if (eNB->mac_enabled==1) {
-      //      if (eNB->UE_stats[i].mode == RA_RESPONSE) {
-	process_Msg3(eNB,proc,i,harq_pid);
-	//      }
-    }
+  pdu->instance_length                                = 0; // don't know what to do with this
+  //  pdu->rx_ue_information.handle                       = handle;
+  pdu->rx_ue_information.rnti                         = rnti;
 
+  if (eNB->frame_parms.frame_type == FDD) {
+    pdu->harq_indication_fdd_rel13.mode = 0;  
+    pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
 
-    eNB->pusch_stats_rb[i][(frame*10)+subframe] = -63;
-    eNB->pusch_stats_round[i][(frame*10)+subframe] = 0;
-    eNB->pusch_stats_mcs[i][(frame*10)+subframe] = -63;
+    for (i=0;i<ulsch_harq->O_ACK;i++) {
+      AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]);
 
-    if ((ulsch) &&
-        (eNB->ulsch[i]->rnti>0) &&
-        (ulsch_harq->status = ACTIVE))
-      LOG_D(PHY,"Frame %d Subframe UE %d/%x active: scheduled for (%d,%d)\n",
-	    frame,i,eNB->ulsch[i]->rnti,ulsch_harq->frame,ulsch_harq->subframe);
-    if ((ulsch) &&
-        (eNB->ulsch[i]->rnti>0) &&
-        (ulsch_harq->status = ACTIVE) &&
-        (ulsch_harq->subframe==subframe)&&
-        (ulsch_harq->frame==frame)) {
-      // UE is has ULSCH scheduling
-      round = ulsch_harq->round;
- 
-      for (int rb=0;
-           rb<=ulsch_harq->nb_rb;
-	   rb++) {
-	int rb2 = rb+ulsch_harq->first_rb;
-	eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
+      pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i];
+      // release DLSCH if needed
+      if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
+   
+    }
+  }
+  else { // TDD
+    M=ul_ACK_subframe2_M(&eNB->frame_parms,
+			 subframe);
+
+    pdu->harq_indication_fdd_rel13.mode = 1-bundling;  
+    pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
+
+    for (i=0;i<ulsch_harq->O_ACK;i++) {
+      AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]);
+
+      pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i];
+      // release DLSCH if needed
+      if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
+      if      (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+      else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
+      else if (M>1 && ulsch_harq->o_ACK[i] == 1) {
+	// spatial bundling
+	release_harq(eNB,UE_id,0,frame,subframe,1<<i);
+	release_harq(eNB,UE_id,1,frame,subframe,1<<i);
       }
+    }	
+  }
+  eNB->UL_INFO.harq_ind.number_of_harqs++;
+  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 
+}
 
-      if (ulsch_harq->Msg3_flag == 1) {
-        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for Msg3 in Sector %d\n",
-              eNB->Mod_id,
-              frame,
-              subframe,
-              eNB->UE_stats[i].sector);
-	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_MSG3,1);
-      } else {
-
-        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d Mode %s\n",
-              eNB->Mod_id,
-              frame,
-              subframe,
-              i,
-              mode_string[eNB->UE_stats[i].mode]);
-      }
+void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask) {
 
+  int UE_id,i;
 
-      nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
 
-      ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
-				    nPRS)%12;
+  pthread_mutex_lock(&eNB->UL_INFO_mutex);
+  nfapi_harq_indication_pdu_t *pdu =   &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs];
 
-      if (fp->frame_type == FDD ) {
-        int sf = (subframe<4) ? (subframe+6) : (subframe-4);
+  pdu->instance_length                                = 0; // don't know what to do with this
+  //  pdu->rx_ue_information.handle                       = handle;
+  pdu->rx_ue_information.rnti                         = uci->rnti;
 
-        if (eNB->dlsch[i][0]->subframe_tx[sf]>0) { // we have downlink transmission
-          ulsch_harq->O_ACK = 1;
-        } else {
-          ulsch_harq->O_ACK = 0;
-        }
-      }
 
-      LOG_D(PHY,
-            "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, mcs %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n",
-            eNB->Mod_id,harq_pid,frame,subframe,
-            ulsch_harq->dci_alloc,
-            ulsch_harq->rar_alloc,
-            ulsch_harq->round,
-            ulsch_harq->first_rb,
-            ulsch_harq->nb_rb,
-            ulsch_harq->mcs,
-            ulsch_harq->TBS,
-            ulsch_harq->rvidx,
-            eNB->ulsch[i]->cyclicShift,
-            ulsch_harq->n_DMRS2,
-            fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
-            nPRS,
-            ulsch_harq->O_ACK);
-      eNB->pusch_stats_rb[i][(frame*10)+subframe] = ulsch_harq->nb_rb;
-      eNB->pusch_stats_round[i][(frame*10)+subframe] = ulsch_harq->round;
-      eNB->pusch_stats_mcs[i][(frame*10)+subframe] = ulsch_harq->mcs;
-      start_meas(&eNB->ulsch_demodulation_stats);
-
-      rx_ulsch(eNB,proc,
-	       i);
+  if (eNB->frame_parms.frame_type == FDD) {
+    if (uci->pucch_fmt == pucch_format1a) {
+      pdu->harq_indication_fdd_rel13.mode = 0;  
+      pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1;
       
+      AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
+      pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
+      // release DLSCH if needed
+      if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+    }
+    else if (uci->pucch_fmt == pucch_format1b) {
+      pdu->harq_indication_fdd_rel13.mode = 0;  
+      pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2;
+      AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
+      AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]);
+      pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
+      pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1]; 
+      // release DLSCH if needed
+      if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+      if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+    }
+    else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); 
+  }
+  else { // TDD
 
-      stop_meas(&eNB->ulsch_demodulation_stats);
+    AssertFatal(tdd_mapping_mode==0 || tdd_mapping_mode==1 || tdd_mapping_mode==2,
+		"Illegal tdd_mapping_mode %d\n",tdd_mapping_mode);
 
+    pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode;  
 
-      start_meas(&eNB->ulsch_decoding_stats);
+    switch (tdd_mapping_mode) {
+    case 0: // bundling
 
-      ret = ulsch_decoding(eNB,proc,
-			   i,
-			   0, // control_only_flag
-			   ulsch_harq->V_UL_DAI,
-			   ulsch_harq->nb_rb>20 ? 1 : 0);
+      if (uci->pucch_fmt == pucch_format1a) {
+	pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;	
+	AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
+	pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
+	// release all bundled DLSCH if needed
+	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+      }
+      else if (uci->pucch_fmt == pucch_format1b) {
+	pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
+	AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
+	AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]);
+	pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
+	pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; 
+	// release all DLSCH if needed
+	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+      }
+      break;
+    case 1: // multiplexing
+      AssertFatal(uci->pucch_fmt == pucch_format1b,"uci->pucch_format %d is not format1b\n",uci->pucch_fmt);
       
-
-
-      stop_meas(&eNB->ulsch_decoding_stats);
-
-      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
-            eNB->Mod_id,harq_pid,
-            frame,subframe,
-            ulsch->rnti,
-            dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
-            dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
-            eNB->UE_stats[i].UL_rssi[0],
-            eNB->UE_stats[i].UL_rssi[1],
-            20,//eNB->measurements.n0_power_dB[0],
-            20,//eNB->measurements.n0_power_dB[1],
-            ulsch_harq->o_ACK[0],
-            ulsch_harq->o_ACK[1],
-            ret);
-
-
-      //compute the expected ULSCH RX power (for the stats)
-      eNB->ulsch[(uint32_t)i]->harq_processes[harq_pid]->delta_TF =
-        get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
-
-      eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][ulsch_harq->round]++;
-#ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d Clearing subframe_scheduling_flag\n",
-            eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid);
-#endif
-
-      if (ulsch_harq->cqi_crc_status == 1) {
-#ifdef DEBUG_PHY_PROC
-        //if (((frame%10) == 0) || (frame < 50))
-        print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL);
-#endif
-        extract_CQI(ulsch_harq->o,
-                    ulsch_harq->uci_format,
-                    &eNB->UE_stats[i],
-                    fp->N_RB_DL,
-                    &rnti, &access_mode);
-        eNB->UE_stats[i].rank = ulsch_harq->o_RI[0];
-
+      if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1a) {
+	pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;	
+	AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
+	pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
+	// release all DLSCH if needed
+	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
       }
-
-      if (ulsch_harq->Msg3_flag == 1)
-	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_MSG3,0);
-
-      if (ret == (1+MAX_TURBO_ITERATIONS)) {
-        T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti),
-          T_INT(harq_pid));
-
-        eNB->UE_stats[i].ulsch_round_errors[harq_pid][ulsch_harq->round]++;
-        ulsch_harq->phich_active = 1;
-        ulsch_harq->phich_ACK = 0;
-        ulsch_harq->round++;
-
-	update_harq_scheduling(fp,ulsch_harq,frame,subframe);
-
-	fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC
-
-        LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,ulsch_harq->round);
-
-        if (ulsch_harq->Msg3_flag == 1) {
-
-          LOG_I(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d\n",
-                eNB->Mod_id,
-                eNB->CC_id,
-                frame,subframe, i,
-                ulsch_harq->round-1);
-
-	  
-	  LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
-		eNB->Mod_id,harq_pid,
-		frame,subframe,
-		ulsch->rnti,
-		dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
-		dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
-		eNB->UE_stats[i].UL_rssi[0],
-		eNB->UE_stats[i].UL_rssi[1],
-		eNB->measurements.n0_power_dB[0],
-		eNB->measurements.n0_power_dB[1],
-		ulsch_harq->o_ACK[0],
-		ulsch_harq->o_ACK[1],
-		ret);
-          LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i);
-        } // This is Msg3 error
-
-        else { //normal ULSCH
-          LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
-                eNB->Mod_id,harq_pid,
-                frame,subframe, i,
-                ulsch_harq->round-1,
-                ulsch->Mlimit,
-                ulsch_harq->o_ACK[0],
-                ulsch_harq->o_ACK[1]);
-
-#if defined(MESSAGE_CHART_GENERATOR_PHY)
-          MSC_LOG_RX_DISCARDED_MESSAGE(
-				       MSC_PHY_ENB,MSC_PHY_UE,
-				       NULL,0,
-				       "%05u:%02u ULSCH received rnti %x harq id %u round %d",
-				       frame,subframe,
-				       ulsch->rnti,harq_pid,
-				       ulsch_harq->round-1
-				       );
-#endif
-
-          if (ulsch_harq->round== ulsch->Mlimit) {
-            LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d ULSCH Mlimit %d reached\n",
-                  eNB->Mod_id,harq_pid,
-                  frame,subframe, i,
-                  ulsch->Mlimit);
-	    
-            ulsch_harq->round=0;
-            ulsch_harq->phich_active=0;
-            eNB->UE_stats[i].ulsch_errors[harq_pid]++;
-            eNB->UE_stats[i].ulsch_consecutive_errors++;
-	    
-	  }
+      else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) {
+	pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
+	AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]);
+	AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]);
+	pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
+	pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; 
+	// release all DLSCH if needed
+	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+      }
+      else { // num_pucch_resources (M) > 1
+	pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources;
+
+	pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
+	pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1];
+	if (uci->num_pucch_resources == 3) 	pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2];
+	if (uci->num_pucch_resources == 4) 	pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3];
+	// spatial-bundling in this case so release both HARQ if necessary
+	release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask);
+	release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask);
+      }
+      break;
+    case 2: // special bundling (SR collision)
+      pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
+      int tdd_config5_sf2scheds=0;
+      if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe);
+ 
+      switch (harq_ack[0]) {
+      case 0:
+	break;
+      case 1: // check if M=1,4,7
+	if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
+	    tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) {
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff);
 	}
-      }  // ulsch in error
-      else {
-	
+	break;
+      case 2: // check if M=2,5,8
+	if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || 
+	    tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	}
+	break;
+      case 3: // check if M=3,6,9
+	if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || 
+	    tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	}
+	break;
+      }
+      break;
 
-	fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
-	fill_rx_indication(eNB,i,frame,subframe);    // indicate SDU to MAC
-        T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti),
-          T_INT(harq_pid));
+    }
+  } //TDD
 
-        if (ulsch_harq->Msg3_flag == 1) {
-	  LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
-		eNB->Mod_id,harq_pid,
-		frame,subframe);
-	  LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
-		eNB->Mod_id,harq_pid,
-		frame,subframe,
-		ulsch->rnti,
-		dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
-		dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
-		eNB->UE_stats[i].UL_rssi[0],
-		eNB->UE_stats[i].UL_rssi[1],
-		eNB->measurements.n0_power_dB[0],
-		eNB->measurements.n0_power_dB[1],
-		ulsch_harq->o_ACK[0],
-		ulsch_harq->o_ACK[1],
-		ret);
-	}
-#if defined(MESSAGE_CHART_GENERATOR_PHY)
-        MSC_LOG_RX_MESSAGE(
-			   MSC_PHY_ENB,MSC_PHY_UE,
-			   NULL,0,
-			   "%05u:%02u ULSCH received rnti %x harq id %u",
-			   frame,subframe,
-			   ulsch->rnti,harq_pid
-			   );
-#endif
-        for (j=0; j<fp->nb_antennas_rx; j++)
-          //this is the RSSI per RB
-          eNB->UE_stats[i].UL_rssi[j] =
-	    
-            dB_fixed(eNB->pusch_vars[i]->ulsch_power[j]*
-                     (ulsch_harq->nb_rb*12)/
-                     fp->ofdm_symbol_size) -
-            eNB->rx_total_gain_dB -
-            hundred_times_log10_NPRB[ulsch_harq->nb_rb-1]/100 -
-            get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0)/100;
-	    
-        ulsch_harq->phich_active = 1;
-        ulsch_harq->phich_ACK = 1;
-        ulsch_harq->round = 0;
-        eNB->UE_stats[i].ulsch_consecutive_errors = 0;
-
-        if (ulsch_harq->Msg3_flag == 1) {
-	  if (eNB->mac_enabled==1) {
-
-	    LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n",
-		  eNB->Mod_id,
-		  frame,harq_pid,i);
-	    if (eNB->mac_enabled) {
-	      // Fill UL info
-	    }
-	    // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
-	    if (ulsch_harq->Msg3_flag == 0 ) {
-	      eNB->UE_stats[i].mode = PRACH;
-	      eNB->ulsch[(uint32_t)i]->Msg3_active = 0;
-	    } // Msg3_flag == 0
-	    
-	  } // mac_enabled==1
 
-          eNB->UE_stats[i].mode = PUSCH;
-          ulsch_harq->Msg3_flag = 0;
+  eNB->UL_INFO.harq_ind.number_of_harqs++;
+  pthread_mutex_unlock(&eNB->UL_INFO_mutex);  
 
-	  LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",eNB->Mod_id,frame,subframe,i);
+}
 
-          for (k=0; k<8; k++) { //harq_processes
-            for (j=0; j<eNB->dlsch[i][0]->Mlimit; j++) {
-              eNB->UE_stats[i].dlsch_NAK[k][j]=0;
-              eNB->UE_stats[i].dlsch_ACK[k][j]=0;
-              eNB->UE_stats[i].dlsch_trials[k][j]=0;
-            }
 
-            eNB->UE_stats[i].dlsch_l2_errors[k]=0;
-            eNB->UE_stats[i].ulsch_errors[k]=0;
-            eNB->UE_stats[i].ulsch_consecutive_errors=0;
+void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag) {
 
-            for (j=0; j<ulsch->Mlimit; j++) {
-              eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0;
-              eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
-              eNB->UE_stats[i].ulsch_round_errors[k][j]=0;
-              eNB->UE_stats[i].ulsch_round_fer[k][j]=0;
-            }
-          }
+  pthread_mutex_lock(&eNB->UL_INFO_mutex);
+  nfapi_crc_indication_pdu_t *pdu =   &eNB->UL_INFO.crc_ind.crc_pdu_list[eNB->UL_INFO.crc_ind.number_of_crcs];
 
-          eNB->UE_stats[i].dlsch_sliding_cnt=0;
-          eNB->UE_stats[i].dlsch_NAK_round0=0;
-          eNB->UE_stats[i].dlsch_mcs_offset=0;
-        } // Msg3_flag==1
-	else {  // Msg3_flag == 0
+  pdu->instance_length                                = 0; // don't know what to do with this
+  //  pdu->rx_ue_information.handle                       = handle;
+  pdu->rx_ue_information.rnti                         = eNB->ulsch[UE_id]->rnti;
+  pdu->crc_indication_rel8.crc_flag                   = crc_flag;
 
-#ifdef DEBUG_PHY_PROC
-#ifdef DEBUG_ULSCH
-          LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
-                harq_pid,ulsch_harq->TBS>>3);
+  eNB->UL_INFO.crc_ind.number_of_crcs++;
+  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+}
 
-          for (j=0; j<ulsch_harq->TBS>>3; j++)
-            LOG_T(PHY,"%x.",eNB->ulsch[i]->harq_processes[harq_pid]->b[j]);
+void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type)
+{
+  //RX processing for ue-specific resources (i
+  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
+  const int subframe = proc->subframe_rx;
+  const int frame    = proc->frame_rx;
 
-          LOG_T(PHY,"\n");
-#endif
-#endif
 
-        } // Msg3_flag == 0
+  if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return;
 
-        
+  T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
 
-#ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[eNB %d] frame %d, subframe %d: user %d: timing advance = %d\n",
-              eNB->Mod_id,
-              frame, subframe,
-              i,
-              eNB->UE_stats[i].timing_advance_update);
-#endif
+  T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0),
+    T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti],
+             eNB->frame_parms.samples_per_tti * 4));
 
 
-      }  // ulsch not in error
 
-      // process HARQ feedback
-#ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d, Processing HARQ feedback for UE %d (after PUSCH)\n",eNB->Mod_id,
-            eNB->dlsch[i][0]->rnti,
-            frame,subframe,
-            i);
-#endif
-      process_HARQ_feedback(i,
-                            eNB,proc,
-                            1, // pusch_flag
-                            0,
-                            0,
-                            0);
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 );
 
-#ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[eNB %d] Frame %d subframe %d, sect %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n",
-            eNB->Mod_id,frame,subframe,
-            eNB->UE_stats[i].sector,
-            harq_pid,
-            i,
-            ret,
-            eNB->ulsch[i]->harq_processes[harq_pid]->cqi_crc_status,
-            eNB->ulsch[i]->harq_processes[harq_pid]->o_ACK[0],
-            eNB->ulsch[i]->harq_processes[harq_pid]->o_ACK[1],
-            eNB->UE_stats[i].ulsch_errors[harq_pid],
-            eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
-#endif
-      
-      // dump stats to VCD
-      if (i==0) {
-	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_MCS0+harq_pid,eNB->pusch_stats_mcs[0][(frame*10)+subframe]);
-	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RB0+harq_pid,eNB->pusch_stats_rb[0][(frame*10)+subframe]);
-	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_ROUND0+harq_pid,eNB->pusch_stats_round[0][(frame*10)+subframe]);
-	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RSSI0+harq_pid,dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]));
-	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RES0+harq_pid,ret);
-	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN0+harq_pid,(frame*10)+subframe);
-      }
-    } // ulsch[0] && ulsch[0]->rnti>0 && ulsch[0]->subframe_scheduling_flag == 1
-
-
-    // update ULSCH statistics for tracing
-    if ((frame % 100 == 0) && (subframe == 4)) {
-      for (harq_idx=0; harq_idx<8; harq_idx++) {
-        for (round=0; round<ulsch->Mlimit; round++) {
-          if ((eNB->UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
-               eNB->UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]) != 0) {
-            eNB->UE_stats[i].ulsch_round_fer[harq_idx][round] =
-              (100*(eNB->UE_stats[i].ulsch_round_errors[harq_idx][round] -
-                    eNB->UE_stats[i].ulsch_round_errors_last[harq_idx][round]))/
-              (eNB->UE_stats[i].ulsch_decoding_attempts[harq_idx][round] -
-               eNB->UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]);
-          } else {
-            eNB->UE_stats[i].ulsch_round_fer[harq_idx][round] = 0;
-          }
+  LOG_I(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe);
 
-          eNB->UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round] =
-            eNB->UE_stats[i].ulsch_decoding_attempts[harq_idx][round];
-          eNB->UE_stats[i].ulsch_round_errors_last[harq_idx][round] =
-            eNB->UE_stats[i].ulsch_round_errors[harq_idx][round];
-        }
-      }
-    }
+  eNB->rb_mask_ul[0]=0;
+  eNB->rb_mask_ul[1]=0;
+  eNB->rb_mask_ul[2]=0;
+  eNB->rb_mask_ul[3]=0;
 
-    if ((frame % 100 == 0) && (subframe==4)) {
-      eNB->UE_stats[i].dlsch_bitrate = (eNB->UE_stats[i].total_TBS -
-					eNB->UE_stats[i].total_TBS_last);
+  eNB->UL_INFO.rx_ind.number_of_pdus  = 0;
+  eNB->UL_INFO.crc_ind.number_of_crcs = 0;
 
-      eNB->UE_stats[i].total_TBS_last = eNB->UE_stats[i].total_TBS;
-    }
+  srs_procedures(eNB,proc);
+
+  uci_procedures(eNB,proc);
 
-  } // loop i=0 ... NUMBER_OF_UE_MAX-1
+  pusch_procedures(eNB,proc);
 
   lte_eNB_I0_measurements(eNB,
 			  subframe,
@@ -3074,53 +2948,12 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
 			  eNB->first_run_I0_measurements);
   eNB->first_run_I0_measurements = 0;
   
-
-
-  //}
-
-#if defined(FLEXRAN_AGENT_SB_IF)
-#ifndef DISABLE_SF_TRIGGER
-  //Send subframe trigger to the controller
-  if (mac_agent_registered[eNB->Mod_id]) {
-    agent_mac_xface[eNB->Mod_id]->flexran_agent_send_sf_trigger(eNB->Mod_id);
-  }
-#endif
-#endif
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC+offset, 0 );
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 );
 
   stop_meas(&eNB->phy_proc_rx);
 
 }
 
-#undef DEBUG_PHY_PROC
 
-#if defined(Rel10) || defined(Rel14)
-int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type)
-{
 
-  int do_proc=0;// do nothing
-
-  switch(r_type) {
-  case no_relay:
-    do_proc= no_relay; // perform the normal eNB operation
-    break;
-
-  case multicast_relay:
-    if (((next_slot >>1) < 6) || ((next_slot >>1) > 8))
-      do_proc = 0; // do nothing
-    else // SF#6, SF#7 and SF#8
-      do_proc = multicast_relay; // do PHY procedures eNB TX
-
-    break;
-
-  default: // should'not be here
-    LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type);
-    do_proc=0;
-    break;
-  }
-
-  return do_proc;
-}
-#endif
 
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 046e37097c204f30018e117a77bda641cd0753a0..818a3402ca0bd83024bf1705b8b8ae34132b7d30 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -1905,6 +1905,9 @@ void get_pucch_param(PHY_VARS_UE    *ue,
 
     case pucch_format1a:
     case pucch_format1b:
+    case pucch_format1b_csA2:
+    case pucch_format1b_csA3:
+    case pucch_format1b_csA4:
     {
         pucch_resource[0] = get_n1_pucch(ue,
                                          proc,
@@ -3379,16 +3382,16 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 		       subframe_rx<<1);
     stop_meas(&ue->dlsch_unscrambling_stats);
     
-#if 0
-    LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
-    LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
-#endif
+    //#if 0
+    LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even[0]);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
+    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
+    //#endif
     
     start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
     ret = dlsch_decoding(ue,
@@ -3471,13 +3474,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       
       if(dlsch0->rnti != 0xffff)
       {
-      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %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]->round,
-	    dlsch0->harq_processes[harq_pid]->mcs,
-	    dlsch0->harq_processes[harq_pid]->TBS);
+	LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %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]->round,
+	      dlsch0->harq_processes[harq_pid]->mcs,
+	      dlsch0->harq_processes[harq_pid]->TBS);
       }
       
 
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index 92e756fa7376ece8f4cdd0d79bf81e226cbcac74..5186153821b507791f045f185a5bf1e1c97b825d 100644
--- a/openair1/SCHED/pucch_pc.c
+++ b/openair1/SCHED/pucch_pc.c
@@ -63,6 +63,9 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
 
   case pucch_format1a:
   case pucch_format1b:
+  case pucch_format1b_csA2:
+  case pucch_format1b_csA3:
+  case pucch_format1b_csA4:
     Po_PUCCH += (1+(ue->frame_parms.ul_power_control_config_common.deltaF_PUCCH_Format1b<<1));
     break;
 
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index be55afa231dee67312fe60e8b8ce9092cf9d481e..19a0da05fe4b8553f36ebdebd853f8e649541693 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -496,9 +496,12 @@ void RCconfig_RU() {
               config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf)
               )
             ) {
-        local_rf_flag = CONFIG_FALSE;
+	local_rf_flag = CONFIG_FALSE;
       }			  
-      
+      else {
+        if (strcmp(local_rf, "no") == 0) 
+	  local_rf_flag = CONFIG_FALSE;
+      }
       if (local_rf_flag == CONFIG_TRUE) { // eNB or RRU
 	
 
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 0d9980ed1071ccb5da6e7ad6f0f1826e4400163d..7913f1a60285396225fa82f80f4de3d6b62fab57 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -582,7 +582,7 @@ int rrc_mac_config_req_eNB(module_id_t                      Mod_idP,
     if (UE_id == -1)
       LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
     else
-      config_dedicated(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated);
+      UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated;
   } 
 
 
@@ -658,19 +658,20 @@ int rrc_mac_config_req_eNB(module_id_t                      Mod_idP,
 
 #endif
 
-  AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
-  PHY_Config_t phycfg;
-  phycfg.Mod_id = Mod_idP;
-  phycfg.CC_id  = CC_idP;
-  phycfg.cfg    = &RC.mac[Mod_idP]->config[CC_idP];
-
-  if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); 
-
+  if (radioResourceConfigCommon!=NULL) {
+    AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
+    PHY_Config_t phycfg;
+    phycfg.Mod_id = Mod_idP;
+    phycfg.CC_id  = CC_idP;
+    phycfg.cfg    = &RC.mac[Mod_idP]->config[CC_idP];
+    
+    if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); 
+  }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
-
-  return(0);			   
-
+  
+  return(0);			     
 }
+
 int
 rrc_mac_config_req_ue(
   module_id_t                      Mod_idP,
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 1499ba3753498f910561334387548e3d60214dbf..cee4688fe68b4d22e2cf76b1adfb48dafa00742b 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -755,11 +755,12 @@ typedef struct {
 
 #ifdef Rel14
   uint8_t rach_resource_type;
- uint16_t mpdcch_repetition_cnt;
-  struct PhysicalConfigDedicated  *physicalConfigDedicated;
+  uint16_t mpdcch_repetition_cnt;
   frame_t Msg2_frame;
-  sub_frame_t Msg2_subframe;
 #endif
+  sub_frame_t Msg2_subframe;
+
+  PhysicalConfigDedicated_t  *physicalConfigDedicated;
 
 } UE_TEMPLATE;
 
@@ -791,9 +792,13 @@ typedef struct {
   uint16_t priority[MAX_NUM_LCID];
 
   // resource scheduling information
-  uint8_t       harq_pid[MAX_NUM_CCs];
-  uint8_t       round[MAX_NUM_CCs];
-  uint8_t       round_UL[8][MAX_NUM_CCs];
+  
+  /// Current DL harq round per harq_pid on each CC
+  uint8_t       round[MAX_NUM_CCs][10];
+  /// Current Active TBs per harq_pid on each CC
+  uint8_t       tbcnt[MAX_NUM_CCs][10];
+  /// Current UL harq round per harq_pid on each CC
+  uint8_t       round_UL[MAX_NUM_CCs][8];
   uint8_t       dl_pow_off[MAX_NUM_CCs];
   uint16_t      pre_nb_available_rbs[MAX_NUM_CCs];
   unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX];
@@ -803,11 +808,34 @@ typedef struct {
   int32_t       context_active_timer;
   int32_t       cqi_req_timer;
   int32_t       ul_inactivity_timer;
-  int32_t       ul_failure_timer;
+  int32_t       ul_failure_timer; 
   int32_t       ul_scheduled;
   int32_t       ra_pdcch_order_sent;
   int32_t       ul_out_of_sync;
   int32_t       phr_received;
+  uint8_t       periodic_ri_received[NFAPI_CC_MAX];
+  uint8_t       aperiodic_ri_received[NFAPI_CC_MAX];
+  uint8_t       pucch1_snr[NFAPI_CC_MAX];
+  uint8_t       pucch2_snr[NFAPI_CC_MAX];
+  uint8_t       pucch3_snr[NFAPI_CC_MAX];
+  uint8_t       pusch_snr[NFAPI_CC_MAX];
+  uint16_t      feedback_cnt[NFAPI_CC_MAX];
+  uint16_t      timing_advance;
+  uint16_t      timing_advance_r9;
+  uint8_t       periodic_wideband_cqi[NFAPI_CC_MAX];
+  uint8_t       periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX];
+  uint8_t       periodic_wideband_pmi[NFAPI_CC_MAX];
+  uint8_t       periodic_subband_cqi[NFAPI_CC_MAX][16];
+  uint8_t       periodic_subband_spatial_diffcqi[NFAPI_CC_MAX][16];
+  uint8_t       aperiodic_subband_cqi0[NFAPI_CC_MAX][25];
+  uint8_t       aperiodic_subband_pmi[NFAPI_CC_MAX][25];
+  uint8_t       aperiodic_subband_diffcqi0[NFAPI_CC_MAX][25];
+  uint8_t       aperiodic_subband_cqi1[NFAPI_CC_MAX][25];
+  uint8_t       aperiodic_subband_diffcqi1[NFAPI_CC_MAX][25];
+  uint8_t       aperiodic_wideband_cqi0[NFAPI_CC_MAX];
+  uint8_t       aperiodic_wideband_pmi[NFAPI_CC_MAX];
+  uint8_t       aperiodic_wideband_cqi1[NFAPI_CC_MAX];
+  uint8_t       aperiodic_wideband_pmi1[NFAPI_CC_MAX];
 } UE_sched_ctrl;
 /*! \brief eNB template for the Random access information */
 typedef struct {
@@ -867,12 +895,18 @@ typedef struct {
   uint8_t msg3_nb_rb;
   /// Msg3 MCS
   uint8_t msg3_mcs;
+  /// Msg3 TPC command
+  uint8_t msg3_TPC;
+  /// Msg3 ULdelay command
+  uint8_t msg3_ULdelay;
+  /// Msg3 cqireq command
+  uint8_t msg3_cqireq;
   /// Round of Msg3 HARQ
   uint8_t msg3_round;
   /// TBS used for Msg4
-  int Msg4_TBsize;
+  int msg4_TBsize;
   /// MCS used for Msg4
-  int Msg4_mcs;
+  int msg4_mcs;
 #ifdef Rel14
   uint8_t rach_resource_type;
   uint8_t msg2_mpdcch_repetition_cnt;
@@ -954,6 +988,8 @@ typedef struct {
   RA_TEMPLATE RA_template[NB_RA_PROC_MAX];
   /// VRB map for common channels
   uint8_t vrb_map[100];
+  /// VRB map for common channels and retransmissions by PHICH
+  uint8_t vrb_map_UL[100];
   /// MBSFN SubframeConfig
   struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8];
   /// number of subframe allocation pattern available for MBSFN sync area
@@ -1006,7 +1042,7 @@ typedef struct eNB_MAC_INST_s {
   /// Common cell resources
   COMMON_channels_t common_channels[MAX_NUM_CCs];
   /// current PDU index (BCH,MCH,DLSCH)
-  int pdu_index[MAX_NUM_CCs];
+  uint16_t pdu_index[MAX_NUM_CCs];
 
   /// NFAPI Config Request Structure
   nfapi_config_request_t config[MAX_NUM_CCs];
@@ -1016,9 +1052,12 @@ typedef struct eNB_MAC_INST_s {
   nfapi_dl_config_request_t DL_req[MAX_NUM_CCs];
   /// Preallocated UL pdu list
   nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU];
-  nfapi_ul_config_request_pdu_t ul_config_pdu_list_msg3[MAX_NUM_CCs];
-  /// NFAPI UL Config Request Structure
+  /// Preallocated UL pdu list for ULSCH (n+k delay)
+  nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU];
+  /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place
   nfapi_ul_config_request_t UL_req[MAX_NUM_CCs];
+  /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests
+  nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10];
   /// Preallocated HI_DCI0 pdu list 
   nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU];
   /// NFAPI HI/DCI0 Config Request Structure
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 7e6e2b67c9cd84f1a8f69b3083f5bb88948b7d24..eb6a56d39e9a879970e30e5d1f7477b197732fff 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -70,6 +70,234 @@ extern RAN_CONTEXT_t RC;
 
 uint16_t pdcch_order_table[6] = {31,31,511,2047,2047,8191};
 
+
+void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) {
+
+  eNB_MAC_INST                   *eNB            = RC.mac[module_idP];
+  UE_list_t                      *UE_list        = &eNB->UE_list;
+  nfapi_ul_config_request_body_t *ul_req;
+  int CC_id,UE_id;  
+  COMMON_channels_t                   *cc        = RC.mac[module_idP]->common_channels;
+  SoundingRS_UL_ConfigCommon_t      *soundingRS_UL_ConfigCommon;
+  struct SoundingRS_UL_ConfigDedicated     *soundingRS_UL_ConfigDedicated;
+  uint8_t  TSFC;
+  uint16_t deltaTSFC; // bitmap
+  uint8_t  srs_SubframeConfig;
+  
+  // table for 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
+
+  uint16_t srsPeriodicity,srsOffset;
+
+  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
+    soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon;
+    // check if SRS is enabled in this frame/subframe
+    if (soundingRS_UL_ConfigCommon) {
+      srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig;
+      if (cc[CC_id].tdd_Config == NULL) { // FDD
+	deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
+	TSFC      = deltaTSFCTabType1[srs_SubframeConfig][1];
+      }
+      else { // TDD
+	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 = (subframeP %  TSFC);
+
+      if((1<<tmp) & deltaTSFC) {
+	// This is an SRS subframe, loop over UEs
+	for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+	  
+	  ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
+	  
+	  
+	  AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
+	  
+	  if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) {
+	    if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
+	      get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset);
+	      if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) {
+		// Prorgram SRS
+		ul_req->srs_present                                                 = 1;
+		nfapi_ul_config_request_pdu_t* ul_config_pdu                        = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
+		memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+		ul_config_pdu->pdu_type                                             = NFAPI_UL_CONFIG_SRS_PDU_TYPE;
+		ul_config_pdu->pdu_size                                             = 2+(uint8_t)(2+sizeof(nfapi_ul_config_srs_pdu));
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.size                            = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);;
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti                            = UE_list->UE_template[CC_id][UE_id].rnti;
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth                   = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position       = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth           = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb               = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs                           = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;	
+		ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;	
+		//		ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port                   = ;//
+		//		ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs                = ;//
+		RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
+		ul_req->number_of_pdus++;
+	      } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) 
+	    } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) 
+	  } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) 
+	} // for (UE_id ...
+      } // if((1<<tmp) & deltaTSFC)
+
+    }// SRS config
+  }
+}
+
+void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) { 
+
+  eNB_MAC_INST                   *eNB          = RC.mac[module_idP];
+  UE_list_t                      *UE_list      = &eNB->UE_list;
+  COMMON_channels_t              *cc;
+  nfapi_ul_config_request_body_t *ul_req;
+  int CC_id,UE_id;  
+  struct CQI_ReportPeriodic *cqi_ReportPeriodic;
+  uint16_t Npd,N_OFFSET_CQI;
+  int H;
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+
+    cc = &eNB->common_channels[CC_id];
+    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+
+      ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
+
+      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
+
+      if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) {
+	if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL &&
+	    (cqi_ReportPeriodic->present!=CQI_ReportPeriodic_PR_release)) {
+	  //Rel8 Periodic CQI/PMI/RI reporting
+
+	  get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H);
+	  
+	  if ((((frameP*10)+subframeP)%Npd) == N_OFFSET_CQI) {  // CQI opportunity
+	    UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id]=(((frameP*10)+subframeP)/Npd)%H;
+	    // Program CQI
+	    nfapi_ul_config_request_pdu_t* ul_config_pdu                                     = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
+	    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+	    ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
+	    ul_config_pdu->pdu_size                                                          = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu));
+	    ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
+	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
+	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id],
+															CC_id,
+															cc,
+															get_tmode(module_idP,CC_id,UE_id),
+															cqi_ReportPeriodic);
+	    ul_req->number_of_pdus++;
+
+#if defined(Rel10) || defined(Rel14)
+	    // PUT rel10-13 UCI options here
+#endif	    
+	  }
+	  else if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) &&
+		   ((((frameP*10)+subframeP)%((H*Npd)<<(*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex/161)))==
+		    N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex%161))) {  // RI opportunity
+	    // Program RI
+	    nfapi_ul_config_request_pdu_t* ul_config_pdu                                     = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
+	    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+	    ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
+	    ul_config_pdu->pdu_size                                                          = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu));
+	    ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
+	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
+	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = (cc->p_eNB==2)?1:2;
+	    RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
+	    ul_req->number_of_pdus++;
+	  }
+
+	} // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) {
+      } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig)
+    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+  } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+}
+
+void schedule_SR(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) {
+
+  eNB_MAC_INST                   *eNB          = RC.mac[module_idP];
+  UE_list_t                      *UE_list      = &eNB->UE_list;
+  nfapi_ul_config_request_body_t *ul_req;
+  int CC_id,UE_id;  
+  SchedulingRequestConfig_t      *SRconfig;
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+
+    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+
+      ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
+
+
+      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
+
+      if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) {
+	if (SRconfig->present == SchedulingRequestConfig_PR_setup) {
+
+	  
+	  if (SRconfig->choice.setup.sr_ConfigIndex <= 4) {        // 5 ms SR period
+	    if ((subframeP%5) != SRconfig->choice.setup.sr_ConfigIndex)
+	      continue;
+	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period
+	    if (subframeP!=(SRconfig->choice.setup.sr_ConfigIndex-5))
+	      continue;
+	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period
+	    if ((10*(frameP&1)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-15))
+	      continue;
+	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period
+	    if ((10*(frameP&3)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-35))
+	      continue;
+	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period
+	    if ((10*(frameP&7)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-75))
+	      continue;
+	  }	  
+	} // SRconfig->present == SchedulingRequestConfig_PR_setup)
+      } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) 
+
+      // if we get here there is some PUCCH1 reception to schedule for SR
+
+      int ul_ulsch_only=0;
+      // check that there is no existing UL grant for ULSCH which overrides the SR
+      for (int i=0;i<ul_req->number_of_pdus;i++)
+	if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) &&
+	    (ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
+	    ul_ulsch_only=1;
+	    break;
+	}
+
+      // drop the allocation because ULSCH with handle it with BSR
+      if (ul_ulsch_only==1) continue;
+      
+      // if we get here then there is no UL grant so program the SR
+      ul_req->ul_config_pdu_list[ul_req->number_of_pdus].pdu_type                                                 = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
+      ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
+
+      // check Rel10 or Rel8 SR
+#if defined(Rel10) || defined(Rel14)
+      if ((UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) &&
+	  (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)&&
+	  (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) {
+
+	ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel10.number_of_pucch_resources = 1;
+	ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel10.pucch_index_p1 = 
+	  *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;
+
+
+      }
+      else 
+#endif
+	{
+	  ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel8.pucch_index =  
+	    UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex;
+	  LOG_I(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti);
+	}
+      RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
+      ul_req->number_of_pdus++;
+    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id])
+  } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
+}
+
 void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
 		      frame_t frameP, sub_frame_t subframeP) {
 
@@ -138,6 +366,7 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra
   nfapi_ul_config_request_t *UL_req         = &eNB->UL_req[0];
   nfapi_hi_dci0_request_t   *HI_DCI0_req    = &eNB->HI_DCI0_req[0];
   nfapi_tx_request_t        *TX_req         = &eNB->TX_req[0];
+
   
   eNB->pdu_index[CC_idP]                                     = 0;
   DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols           = 1;
@@ -149,11 +378,40 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra
   HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf                            = subframeP + (frameP<<3);
   HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci                    = 0;
   
+  
   UL_req[CC_idP].ul_config_request_body.number_of_pdus                      = 0;
   UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources      = 0; // ignored, handled by PHY for now
   UL_req[CC_idP].ul_config_request_body.srs_present                         = 0; // ignored, handled by PHY for now
+  
+
   TX_req[CC_idP].tx_request_body.number_of_pdus                 = 0;
 
+
+}
+
+void copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) {
+
+  int CC_id;
+  eNB_MAC_INST *eNB;
+  nfapi_ul_config_request_body_t *ul_req_tmp;
+  nfapi_ul_config_request_body_t *ul_req;
+
+  eNB = RC.mac[module_idP];
+
+  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
+
+    ul_req_tmp       = &eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body;
+    ul_req           = &eNB->UL_req[CC_id].ul_config_request_body;
+    
+    eNB->UL_req[CC_id].sfn_sf   = (frameP<<4) + subframeP;
+    ul_req->number_of_pdus                     = ul_req_tmp->number_of_pdus;
+    ul_req_tmp->number_of_pdus = 0;
+
+    memcpy((void*)ul_req->ul_config_pdu_list,
+	   (void*)ul_req_tmp->ul_config_pdu_list,
+	   ul_req->number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
+  
+  }
 }
 
 void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)  
@@ -187,17 +445,19 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     mbsfn_status[CC_id]=0;
-    // clear vrb_map
+
+    // clear vrb_maps
     memset(cc[CC_id].vrb_map,0,100);
+    memset(cc[CC_id].vrb_map_UL,0,100);
 
-    // clear DL/UL info for new scheduling round
-    clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP);
 
 #if defined(Rel10) || defined(Rel14)
     cc[CC_id].mcch_active =0;
 #endif
     RC.mac[module_idP]->frame    = frameP;
     RC.mac[module_idP]->subframe = subframeP;
+
+    clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP);
   }
 
   // refresh UE list based on UEs dropped by PHY in previous subframe
@@ -223,81 +483,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
 
     RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
 
-    /*
-      //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
-#if defined(FLEXRAN_AGENT_S_IF)
-      if (mac_agent_registered[module_idP]) {
-	agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
-									  rnti,
-									  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
-      }
-#endif
-}*/
     check_ul_failure(module_idP,CC_id,i,frameP,subframeP);
 
   }
 
-#if defined(ENABLE_ITTI)
-
-  do {
-    // Checks if a message has been sent to MAC sub-task
-    itti_poll_msg (TASK_MAC_ENB, &msg_p);
-
-    if (msg_p != NULL) {
-      msg_name = ITTI_MSG_NAME (msg_p);
-      instance = ITTI_MSG_INSTANCE (msg_p);
-
-      switch (ITTI_MSG_ID(msg_p)) {
-      case MESSAGE_TEST:
-        LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
-        break;
-
-      case RRC_MAC_BCCH_DATA_REQ:
-        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
-              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
-              RRC_MAC_BCCH_DATA_REQ (msg_p).frame, RRC_MAC_BCCH_DATA_REQ (msg_p).enb_index);
-
-        // TODO process BCCH data req.
-        break;
-
-      case RRC_MAC_CCCH_DATA_REQ:
-        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
-              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
-              RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index);
-
-        // TODO process CCCH data req.
-        break;
-
-#if defined(Rel10) || defined(Rel14)
-
-      case RRC_MAC_MCCH_DATA_REQ:
-        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n",
-              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
-              RRC_MAC_MCCH_DATA_REQ (msg_p).frame, RRC_MAC_MCCH_DATA_REQ (msg_p).enb_index, RRC_MAC_MCCH_DATA_REQ (msg_p).mbsfn_sync_area);
-
-        // TODO process MCCH data req.
-        break;
-#endif
-
-      default:
-        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
-        break;
-      }
-
-      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
-      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-    }
-  } while(msg_p != NULL);
-
-#endif
-
-/* #ifndef DISABLE_SF_TRIGGER */
-/*   //Send subframe trigger to the controller */
-/*   if (mac_agent_registered[module_idP]) { */
-/*     agent_mac_xface[module_idP]->flexran_agent_send_sf_trigger(module_idP); */
-/*   } */
-/* #endif */
-  
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP);
   pdcp_run(&ctxt);
 
@@ -319,34 +508,29 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
 
   // This schedules MIB
   if ((subframeP==0) && (frameP&3) == 0) schedule_mib(module_idP,frameP,subframeP);
-
-  // This schedules SI for legacy LTE and eMTC
+  // This schedules SI for legacy LTE and eMTC starting in subframeP
   schedule_SI(module_idP,frameP,subframeP);
-
-  // This schedules Random-Access for legacy LTE and eMTC
+  // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
   schedule_RA(module_idP,frameP,subframeP);
 
-  // This schedules ULSCH in subframeP+k
+  // copy previously scheduled UL resources (ULSCH + HARQ)
+
+  copy_ulreq(module_idP,frameP,subframeP);
+  // This schedules SRS in subframeP
+  schedule_SRS(module_idP,frameP,subframeP);
+  // This schedules ULSCH in subframeP (dci0)
   schedule_ulsch(module_idP,frameP,subframeP);
+  // This schedules UCI_SR in subframeP
+  schedule_SR(module_idP,frameP,subframeP);
+  // This schedules UCI_CSI in subframeP
+  schedule_CSI(module_idP, frameP, subframeP);
 
   // This schedules DLSCH in subframeP
   schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
 
-  // Allocate CCEs and Msg3 for good after scheduling is done
-  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
-    allocate_CCEs(module_idP,CC_id,subframeP,0);
-    check_and_add_msg3(module_idP,frameP,subframeP);
-  }
-
-#if defined(FLEXRAN_AGENT_SB_IF)
-#ifndef DISABLE_CONT_STATS
-  //Send subframe trigger to the controller
-  if (mac_agent_registered[module_idP]) {
-    agent_mac_xface[module_idP]->flexran_agent_send_update_mac_stats(module_idP);
-  }
-#endif
-#endif
-
+  // Allocate CCEs for good after scheduling is done
+  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) allocate_CCEs(module_idP,CC_id,subframeP,0);
+  
 
   stop_meas(&RC.mac[module_idP]->eNB_scheduler);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 457a41c5175a276cce3f969b014b4a3c3523fba7..99604b290dd7ee84d17fa50e3ef858b60dbccdb0 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -62,136 +62,114 @@
 
 #include "T.h"
 
-void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) {
+void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP) {
 
   eNB_MAC_INST                    *eNB = RC.mac[module_idP];
-  RA_TEMPLATE                     *RA_template;
-  COMMON_channels_t               *cc  = eNB->common_channels;
-  uint8_t                         i;
-  int msg3_prog_subframe,msg3_prog_frame;
-  int CC_id;
+  COMMON_channels_t               *cc  = &eNB->common_channels[CC_id];
+  uint8_t                         i,j;
+  nfapi_ul_config_request_t      *ul_req;
   nfapi_ul_config_request_pdu_t  *ul_config_pdu;
-  nfapi_ul_config_request_body_t *ul_req;
+  nfapi_ul_config_request_body_t *ul_req_body;
   nfapi_hi_dci0_request_body_t   *hi_dci0_req;
   nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
 
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    hi_dci0_req   = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
-    ul_req        = &eNB->UL_req[CC_id].ul_config_request_body;
-
-    for (i=0; i<NB_RA_PROC_MAX; i++) {
+  uint8_t rvseq[4] = {0,2,3,1};
 
-      RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i];
 
-      if (RA_template->RA_active == TRUE) {
+  hi_dci0_req   = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
+  ul_req        = &eNB->UL_req_tmp[CC_id][RA_template->Msg3_subframe];
+  ul_req_body   = &ul_req->ul_config_request_body;
+  AssertFatal(RA_template->RA_active == TRUE,"RA is not active for RA %X\n",RA_template->rnti);
 
 #ifdef Rel14
-	if (RA_template->rach_resource_type>0) {
-	    // program reception 4 subframes prior to transmission
-	  msg3_prog_subframe =  (RA_template->Msg3_subframe + 6)%10;
-	  
-	  if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023;
-	  else                              msg3_prog_frame=RA_template->Msg3_frame;
-	  LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d CE level %d is active, Msg3 in (%d,%d), programmed in (%d,%d)\n",
-		module_idP,frameP,subframeP,CC_id,i,RA_template->rach_resource_type-1,
-		RA_template->Msg3_frame,RA_template->Msg3_subframe,
-		msg3_prog_frame,msg3_prog_subframe);
-	    if ((msg3_prog_frame==frameP) && 
-		(msg3_prog_subframe==subframeP)) {
-	      LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
-		    frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
-	      eNB->UL_req[CC_id].sfn_sf                                                      = (RA_template->Msg3_frame<<4) + RA_template->Msg3_subframe;
-	      if (RA_template->msg3_round == 0) { // program ULSCH
-		ul_config_pdu                                                                  = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
-		
-		memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
-		ul_config_pdu->pdu_type                                                        = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
-		ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = RA_template->rnti;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = narrowband_to_first_rb(cc,RA_template->msg34_narrowband)+RA_template->msg3_first_rb;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = RA_template->msg3_nb_rb;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                        = 2;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = ((10*frameP)+subframeP)&7;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(RA_template->msg3_mcs,
-													    RA_template->msg3_nb_rb);
-		// Re13 fields
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                               = RA_template->rach_resource_type>2 ? 2 : 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions           = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number                     = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io            = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe;
-		ul_req->number_of_pdus++;
-	      }
-	    }	  
-	}
-	else
+  if (RA_template->rach_resource_type>0) {
+    LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d CE level %d is active, Msg3 in (%d,%d)\n",
+	  module_idP,frameP,subframeP,CC_id,i,RA_template->rach_resource_type-1,
+	  RA_template->Msg3_frame,RA_template->Msg3_subframe);
+    LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
+	  frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
+
+    ul_config_pdu                                                                  = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; 
+    
+    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+    ul_config_pdu->pdu_type                                                        = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
+    ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = RA_template->rnti;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = narrowband_to_first_rb(cc,RA_template->msg34_narrowband)+RA_template->msg3_first_rb;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = RA_template->msg3_nb_rb;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                        = 2;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = rvseq[RA_template->msg3_round];
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = ((10*RA_template->Msg3_frame)+RA_template->Msg3_subframe)&7;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(RA_template->msg3_mcs,
+												RA_template->msg3_nb_rb);
+    // Re13 fields
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                               = RA_template->rach_resource_type>2 ? 2 : 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions           = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number                     = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io            = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe;
+    ul_req_body->number_of_pdus++;
+  } //  if (RA_template->rach_resource_type>0) {	 
+  else
 #endif
-	  {
-	    // program reception 4 subframes prior to transmission
-	    msg3_prog_subframe =  (RA_template->Msg3_subframe + 6)%10;
-	    
-	    if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023;
-	    else                              msg3_prog_frame=RA_template->Msg3_frame;
-	    LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active, Msg3 in (%d,%d), programmed in (%d,%d)\n",
-		  module_idP,frameP,subframeP,CC_id,i,RA_template->Msg3_frame,RA_template->Msg3_subframe,
-		  msg3_prog_frame,msg3_prog_subframe);
+    {
+      LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active, Msg3 in (%d,%d)\n",
+	    module_idP,frameP,subframeP,CC_id,i,RA_template->Msg3_frame,RA_template->Msg3_subframe);
 	    
-	    if ((msg3_prog_frame==frameP) && 
-		(msg3_prog_subframe==subframeP)) {
-	      LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
-		    frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
-	      eNB->UL_req[CC_id].sfn_sf                                                      = (RA_template->Msg3_frame<<4) + RA_template->Msg3_subframe;
-	      if (RA_template->msg3_round == 0) { // program ULSCH
-		ul_config_pdu                                                                  = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
-		
-		memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
-		ul_config_pdu->pdu_type                                                        = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
-		ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = RA_template->rnti;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                        = 2;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(10,ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks);
-		ul_req->number_of_pdus++;
-	      }
-	    }
-	    else { // program HI
-	      hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; 	
-	      memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
-	      hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
-	      hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
-	      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = 1; // note this is hard-coded like in fill_rar
-	      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
-	      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 0;
-	      hi_dci0_req->number_of_hi++;
-	      
-	      LOG_I(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA %d (mcs %d, first rb %d, nb_rb %d,round %d)\n",
-		    module_idP,RA_template[i].rnti,CC_id,frameP,subframeP,i,10,
-		    1,1,
-		    RA_template[i].msg3_round-1);
-	    } // PHICH
-	  } // non-BL/CE UE case
-      } // RA_active = TRUE
-    } // for RA_processes
-  } // for CCids
+      LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
+	    frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
+      
+      ul_config_pdu                                                                  = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; 
+      
+      memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+      ul_config_pdu->pdu_type                                                        = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
+      ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = RA_template->rnti;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = RA_template->msg3_first_rb;
+      AssertFatal(RA_template->msg3_nb_rb > 0, "nb_rb = 0\n");
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = RA_template->msg3_nb_rb;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                        = 2;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = 0;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = 0;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = rvseq[RA_template->msg3_round];
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = subframe2harqpid(cc,RA_template->Msg3_frame,RA_template->Msg3_subframe);
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 1;
+      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(10,RA_template->msg3_nb_rb);
+      ul_req_body->number_of_pdus++;
+      // save UL scheduling information for preprocessor
+      for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1;
+      
+      
+      if (RA_template->msg3_round != 0) { // program HI too
+	hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; 	
+	memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
+	hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
+	hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
+	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = RA_template->msg3_first_rb; 
+	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
+	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 0;
+	hi_dci0_req->number_of_hi++;
+	// save UL scheduling information for preprocessor
+	for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1;
+	
+	LOG_I(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA %d (mcs %d, first rb %d, nb_rb %d,round %d)\n",
+	      module_idP,RA_template->rnti,CC_id,frameP,subframeP,i,10,
+	      1,1,
+	      RA_template->msg3_round-1);
+      } //       if (RA_template->msg3_round != 0) { // program HI too
+    } // non-BL/CE UE case
 }
 
 void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) {
@@ -347,7 +325,7 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 
       if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
 	// Program PDSCH
-	LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH %d\n",
+	LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
 	      module_idP,frameP,subframeP);
 	RA_template->generate_rar = 0;	      
 	
@@ -389,8 +367,7 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	
 	// Program UL processing for Msg3, same as regular LTE
 	get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
-	
-	
+	add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);
 	fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1);
 	// DL request
 	eNB->TX_req[CC_idP].sfn_sf                                            = (frameP<<3)+subframeP;
@@ -416,7 +393,8 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	      
 	      RA_template->RA_dci_fmt1,
 	      RA_template->RA_dci_size_bits1);
-	
+
+	// Allocate 4 PRBS starting in RB 0
 	first_rb = 0;
 	vrb_map[first_rb] = 1;
 	vrb_map[first_rb+1] = 1;
@@ -440,7 +418,8 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
 	
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,4);      
-	
+
+	// This checks if the above DCI allocation is feasible in current subframe
 	if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
 	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
 		frameP,subframeP,RA_template->RA_rnti);
@@ -477,10 +456,13 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	  
 	  // Program UL processing for Msg3
 	  get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
+
 	  LOG_I(MAC,"Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
 		frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
 	  
 	  fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7);
+	  add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);
+
 	  // DL request
 	  eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<3)+subframeP;
 	  TX_req                                                                = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; 		     
@@ -517,7 +499,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
   nfapi_ul_config_request_body_t *ul_req;
   uint8_t                         lcid;
   uint8_t                         offset;
-
+  int harq_pid;
 
 
 #ifdef Rel14
@@ -579,13 +561,16 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
   
   dl_req        = &eNB->DL_req[CC_idP].dl_config_request_body;
   dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
-  ul_req        = &eNB->UL_req[CC_idP].ul_config_request_body;
-  ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
   N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
 
   UE_id = find_UE_id(module_idP,RA_template->rnti);
   AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
   
+  // set HARQ process round to 0 for this UE
+  
+  if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
+  else harq_pid = ((frameP*10)+subframeP)&7;
+
   
   // Get RRCConnectionSetup for Piggyback
   rrc_sdu_length = mac_rrc_data_req(module_idP,
@@ -598,11 +583,11 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 				    module_idP,
 				    0); // not used in this case
   
-  AssertFatal(rrc_sdu_length>=0,
+  AssertFatal(rrc_sdu_length>0,
 	      "[MAC][eNB Scheduler] CCCH not allocated\n");
   
   
-  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
+  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
 	module_idP, CC_idP, frameP, subframeP,UE_id, rrc_sdu_length);
   
   
@@ -657,7 +642,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels                        = 4; // fix to 4 for now
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version                            = 0;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator                            = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = 0;
+      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = harq_pid;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length                                   = 0;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi                                          = 0;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag                                      = 0;
@@ -741,23 +726,22 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	
 	RA_template->generate_Msg4=0;
 	RA_template->wait_ack_Msg4=1;
-	RA_template->RA_active = FALSE;
+
 	lcid=0;
 	
-	// set HARQ process 0 round to 0 for this UE
-	UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0;
+	UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0;
 	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
 	
-	if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
-	  msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header;
+	if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
+	  msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
 	  msg4_post_padding = 0;
 	} else {
 	  msg4_padding = 0;
-	  msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1;
+	  msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
 	}
 	
 	LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
-	      module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
+	      module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
 	DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
 	// CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
 	offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
@@ -788,8 +772,10 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	int absSF = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe;
 	// see Section 10.2 from 36.213
 	int ackNAK_absSF = absSF + reps + 4;
-	
-	eNB->UL_req[CC_idP].sfn_sf                                                                   = ((ackNAK_absSF/10)<<4) + (ackNAK_absSF%10);
+	AssertFatal(reps>2,"Have to handle programming of ACK when PDSCH repetitions is > 2\n");
+	ul_req        = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF%10].ul_config_request_body;
+	ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
+
 	ul_config_pdu->pdu_type                                                                     = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; 
 	ul_config_pdu->pdu_size                                                                     = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu));
 	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle                       = 0; // don't know how to use this
@@ -812,7 +798,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	}
 	ul_req->number_of_pdus++;
 	T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
-	  T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize));
+	  T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->msg4_TBsize));
 	
 	if (opt_enabled==1) {
 	  trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
@@ -831,6 +817,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
 	      module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
 	
+	/// Choose first 4 RBs for Msg4, should really check that these are free!
 	first_rb=0;
 	
 	vrb_map[first_rb] = 1;
@@ -839,48 +826,40 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	vrb_map[first_rb+3] = 1;
 	
 	
-	memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
-	dl_config_pdu->pdu_type                                                          = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
-	dl_config_pdu->pdu_size                                                          = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                             = NFAPI_DL_DCI_FORMAT_1A;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level                      = 4;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                                   = RA_template->rnti;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                              = 1;    // C-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power                     = 6000; // equal to RS power
-	
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                           = 0;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                                    = 1; // no TPC
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1                   = 1;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1                   = 0;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
-	
-	// Compute MCS for 3 PRB
+	// Compute MCS/TBS for 3 PRB (coded on 4 vrb)
 	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
 	
-	
 	if ((rrc_sdu_length+msg4_header) <= 22) {
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = 4;
-	  RA_template->Msg4_TBsize = 22;
+	  RA_template->msg4_mcs                       = 4;
+	  RA_template->msg4_TBsize = 22;
 	} else if ((rrc_sdu_length+msg4_header) <= 28) {
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = 5;
-	  RA_template->Msg4_TBsize = 28;
+	  RA_template->msg4_mcs                       = 5;
+	  RA_template->msg4_TBsize = 28;
 	} else if ((rrc_sdu_length+msg4_header) <= 32) {
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = 6;
-	  RA_template->Msg4_TBsize = 32;
+	  RA_template->msg4_mcs                       = 6;
+	  RA_template->msg4_TBsize = 32;
 	} else if ((rrc_sdu_length+msg4_header) <= 41) {
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = 7;
-	  RA_template->Msg4_TBsize = 41;
+	  RA_template->msg4_mcs                       = 7;
+	  RA_template->msg4_TBsize = 41;
 	} else if ((rrc_sdu_length+msg4_header) <= 49) {
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = 8;
-	  RA_template->Msg4_TBsize = 49;
+	  RA_template->msg4_mcs                       = 8;
+	  RA_template->msg4_TBsize = 49;
 	} else if ((rrc_sdu_length+msg4_header) <= 57) {
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = 9;
-	  RA_template->Msg4_TBsize = 57;
+	  RA_template->msg4_mcs    = 9;
+	  RA_template->msg4_TBsize = 57;
 	}
 
-	RA_template->Msg4_mcs = dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1;
-
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4);
+	fill_nfapi_dl_dci_1A(dl_config_pdu,
+			     4,                           // aggregation_level
+			     RA_template->rnti,           // rnti
+			     1,                           // rnti_type, CRNTI
+			     harq_pid,                    // harq_process
+			     1,                           // tpc, none
+			     getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
+			     RA_template->msg4_mcs,       // mcs
+			     1,                           // ndi
+			     0,                           // rv
+			     0);                          // vrb_flag
 	
 	if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
 	  dl_req->number_dci++;
@@ -888,22 +867,26 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	  
 	  RA_template->generate_Msg4=0;
 	  RA_template->wait_ack_Msg4=1;
-	  RA_template->RA_active = FALSE;
+	  RA_template->Msg4_frame++;
+	  RA_template->Msg4_frame&=1023;
+
 	  lcid=0;
 	  
 	  // set HARQ process 0 round to 0 for this UE
-	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0;
+	  if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
+	  else harq_pid = ((frameP*10)+subframeP)&7;
+	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0;
 	  
-	  if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
-	    msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header;
+	  if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
+	    msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
 	    msg4_post_padding = 0;
 	  } else {
 	    msg4_padding = 0;
-	    msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1;
+	    msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
 	  }
 	  
 	  LOG_I(MAC,"[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
-		module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
+		module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
 	  DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
 	  // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
 	  offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
@@ -920,35 +903,50 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 		 &cc[CC_idP].CCCH_pdu.payload[0],
 		 rrc_sdu_length);
 	  
+	  // DLSCH Config
+	  fill_nfapi_dlsch_config(eNB,
+				  dl_req,
+				  RA_template->msg4_TBsize,
+				  eNB->pdu_index[CC_idP]++,
+				  RA_template->rnti,
+				  2,                           // resource_allocation_type : format 1A/1B/1D
+				  0,                           // virtual_resource_block_assignment_flag : localized
+				  getRIV(N_RB_DL,first_rb,4),  // resource_block_coding : RIV, 4 PRB
+				  2,                           // modulation: QPSK
+				  0,                           // redundancy version
+				  1,                           // transport_blocks
+				  0,                           // transport_block_to_codeword_swap_flag (0)
+				  (cc->p_eNB==1 ) ? 0 : 1,     // transmission_scheme
+				  1,                           // number of layers
+				  1,                           // number of subbands
+				  //0,                         // codebook index 
+				  1,                           // ue_category_capacity
+				  4,                           // pa: 0 dB
+				  0,                           // delta_power_offset_index
+				  0,                           // ngap
+				  1,                           // NPRB = 3 like in DCI
+				  (cc->p_eNB==1 ) ? 1 : 2,     // transmission mode
+				  1,                           // num_bf_prb_per_subband
+				  1);                          // num_bf_vector
+
 	  // DL request
-	  eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<3)+subframeP;
-	  TX_req                                                                = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; 		     	      
-	  TX_req->pdu_length                                                    = rrc_sdu_length;
-	  TX_req->pdu_index                                                     = eNB->pdu_index[CC_idP]++;
-	  TX_req->num_segments                                                  = 1;
-	  TX_req->segments[0].segment_length                                    = rrc_sdu_length;
-	  TX_req->segments[0].segment_data                                      = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0];
-	  eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
+	  eNB->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_idP].tx_request_body,
+							 (frameP*10)+subframeP,
+							 rrc_sdu_length,
+							 &eNB->pdu_index[CC_idP],
+							 eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); 
 
 	  // Program PUCCH1a for ACK/NAK
-	  memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
-	  ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; 
-	  ul_config_pdu->pdu_size                                                          = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu));
-	  ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle            = 0; // don't know how to use this
-	  ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti              = RA_template->rnti;
-	  if (cc[CC_idP].tdd_Config==NULL) { // FDD case
-	    ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0   = cc[CC_idP].radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx;
-	    // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
-	    ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size     = 1;  // 1-bit ACK/NAK
-	  }
-	  else {
-	    AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD case yet\n");
-	  }
-
-	  ul_req->number_of_pdus++;
+	  // Program ACK/NAK for Msg4 PDSCH
+	  fill_nfapi_uci_acknak(module_idP,
+				CC_idP,
+				RA_template->rnti,
+				(frameP*10)+subframeP,
+				dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
 
+	  
 	  T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
-	    T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize));
+	    T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->msg4_TBsize));
 	  
 	  if (opt_enabled==1) {
 	    trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
@@ -975,7 +973,7 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
   UE_list_t                       *UE_list=&eNB->UE_list;
   nfapi_dl_config_request_body_t *dl_req;
 
-  int                             round;
+  int                             round,harq_pid;
   /*
 #ifdef Rel14
   COMMON_channels_t               *cc  = eNB->common_channels;
@@ -1011,67 +1009,81 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
   */
 
   // check HARQ status and retransmit if necessary
-  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \tn",
-	module_idP,CC_idP,frameP,subframeP);
+
   // Get candidate harq_pid from PHY
   
   UE_id = find_UE_id(module_idP,RA_template->rnti);
   AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
-  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP];
+  if (cc[CC_idP].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
+  else harq_pid = ((frameP*10)+subframeP)&7;
+
+  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid];
   vrb_map       = cc[CC_idP].vrb_map;
   
   dl_req        = &eNB->DL_req[CC_idP].dl_config_request_body;
   dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
   N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
   
-  if (round>0) {
+  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged (round %d)\n",
+	module_idP,CC_idP,frameP,subframeP,round);
+
+  if (round!=8) {
     
 #ifdef Rel14
-    AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n");
+    if (RA_template->rach_resource_type>0) {
+      AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n");
+    }
+    else
 #endif 
-    {
-      if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	       
-	
-	//RA_template->wait_ack_Msg4++;
-	// we have to schedule a retransmission
-	
-	first_rb=0;
-	vrb_map[first_rb] = 1;
-	vrb_map[first_rb+1] = 1;
-	vrb_map[first_rb+2] = 1;
-	vrb_map[first_rb+3] = 1;
-	
-	memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
-	dl_config_pdu->pdu_type                                                          = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
-	dl_config_pdu->pdu_size                                                          = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                             = NFAPI_DL_DCI_FORMAT_1A;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level                      = 4;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                                   = RA_template->rnti;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                              = 1;    // C-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power                     = 6000; // equal to RS power
-	
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                           = 0;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                                    = 1; // no TPC
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1                   = 1;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1                   = round;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                                  = RA_template->Msg4_mcs;
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
-	
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4);
-	
-	if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
-	  dl_req->number_dci++;
-	  dl_req->number_pdu++;
+      {
+	if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	       
 	  
-	  LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
-	}
-	else
-	  LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
-	LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
-	      module_idP,CC_idP,frameP,subframeP,RA_template->rnti);
-      }
-    }
-    
+	  //RA_template->wait_ack_Msg4++;
+	  // we have to schedule a retransmission
+	  
+	  first_rb=0;
+	  vrb_map[first_rb] = 1;
+	  vrb_map[first_rb+1] = 1;
+	  vrb_map[first_rb+2] = 1;
+	  vrb_map[first_rb+3] = 1;
+	  
+	  fill_nfapi_dl_dci_1A(dl_config_pdu,
+			       4,                           // aggregation_level
+			       RA_template->rnti,           // rnti
+			       1,                           // rnti_type, CRNTI
+			       0,                           // harq_process
+			       1,                           // tpc, none
+			       getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
+			       RA_template->msg4_mcs,       // mcs
+			       1,                           // ndi
+			       round,                       // rv
+			       0);                          // vrb_flag
+	  
+	  if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
+	    dl_req->number_dci++;
+	    dl_req->number_pdu++;
+	    
+	    LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
+	  }
+	  else
+	    LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
+	  LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
+		module_idP,CC_idP,frameP,subframeP,RA_template->rnti);
+	  
+	  
+	  // Program PUCCH1a for ACK/NAK
+	  
+
+	  fill_nfapi_uci_acknak(module_idP,CC_idP,
+				RA_template->rnti,
+				(frameP*10)+subframeP,
+				dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
+	  
+	  // prepare frame for retransmission
+	  RA_template->Msg4_frame++;
+	  RA_template->Msg4_frame&=1023;
+	} // Msg4 frame/subframe
+      } // regular LTE case
   } else {
     LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP);
     RA_template->wait_ack_Msg4=0;
@@ -1095,7 +1107,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
 
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    // skip UL component carriers
+    // skip UL component carriers if TDD
     if (is_UL_sf(&cc[CC_id],subframeP)==1) continue;
 
 
@@ -1141,15 +1153,20 @@ void initiate_ra_proc(module_id_t module_idP,
   COMMON_channels_t   *cc  = &RC.mac[module_idP]->common_channels[CC_id];
   RA_TEMPLATE *RA_template = &cc->RA_template[0];
 
-  struct PRACH_ConfigSIB_v1310 *ext4_prach=cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
-  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13= &ext4_prach->prach_ParametersListCE_r13;
+  struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
+  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
 
+  if (cc->radioResourceConfigCommon_BR && cc->radioResourceConfigCommon_BR->ext4) {
+    ext4_prach=cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
+    prach_ParametersListCE_r13= &ext4_prach->prach_ParametersListCE_r13;
+  }
   LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,subframeP,preamble_index);
 #ifdef Rel14
   LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  PRACH resource type %d\n",module_idP,CC_id,frameP,subframeP,rach_resource_type);
 #endif
 
-  if (prach_ParametersListCE_r13->list.count<rach_resource_type) {
+  if (prach_ParametersListCE_r13 && 
+      prach_ParametersListCE_r13->list.count<rach_resource_type) {
     LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d, only %d CE levels configured\n",
 	  module_idP,CC_id,
 	  rach_resource_type,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index 04485a9d3e275d7ef3f5ed4a4b9d95641ac6ccd4..aec302c36a032d58c04189460a3101789d1ed029 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -240,7 +240,7 @@ schedule_SIB1_BR(
     // Rel13 fields
     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 1; // CEModeA UE
     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 0; // SIB1-BR
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF; // absolute SF
+    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF; // absolute SFx
     
     //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
     dl_req->number_pdu++;
@@ -401,8 +401,8 @@ schedule_SI_BR(
 	    vrb_map[first_rb+5] = 1;
 
 	    if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n",
-					   module_idP,frameP,subframeP,CC_id,si_Narrowband_r13-1,rvidx,
-					   sf_mod_period,si_WindowLength_BR_r13,si_RepetitionPattern_r13,
+					   module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx,
+					   sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13,
 					   bcch_sdu_length);	    
 
 
@@ -524,7 +524,7 @@ void schedule_mib(module_id_t   module_idP,
       LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n",
 	    frameP,subframeP,dl_req->number_pdu,mib_sdu_length);
 
-      if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,cc->mib->message.schedulingInfoSIB1_BR_r13);
+      if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,(int)cc->mib->message.schedulingInfoSIB1_BR_r13);
 
       dl_config_pdu                                                         = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
       memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
@@ -671,7 +671,14 @@ schedule_SI(
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1        = 0;
 	
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding       = getRIV(N_RB_DL,first_rb,4);      
-	
+
+	// Rel10 fields
+	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = 3;
+	// Rel13 fields
+	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 0; // regular UE
+	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 2; // not BR
+	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF; // absolute SF	
+
 	if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) {
 	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n",
 		frameP,subframeP);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 825d0fa8b69494b382c264bc59cfcca0862cf6cd..ebd880da12a8aa8e48e498b4dd67e0328b8bf670 100755
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -609,8 +609,12 @@ schedule_ue_spec(
       }
 
       nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
-      harq_pid = ue_sched_ctl->harq_pid[CC_id];
-      round = ue_sched_ctl->round[CC_id];
+
+      if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
+      else harq_pid = ((frameP*10)+subframeP)&7;
+
+      round = ue_sched_ctl->round[CC_id][harq_pid];
+
       UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti;
       UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(module_idP,rnti);
       UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; 
@@ -645,8 +649,10 @@ schedule_ue_spec(
       /* process retransmission  */
 
       if (round > 0) {
+
         // get freq_allocation
         nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+	TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid],nb_rb);
 
         if (nb_rb <= nb_available_rb) {
           if (cc[CC_id].tdd_Config != NULL) {
@@ -729,9 +735,38 @@ schedule_ue_spec(
 	      dl_req->number_dci++;
 	      dl_req->number_pdu++;
 
+	      fill_nfapi_dlsch_config(eNB,dl_req,
+				      TBS,
+				      eNB->pdu_index[CC_id],
+				      rnti,
+				      0, // type 0 allocation from 7.1.6 in 36.213
+				      0, // virtual_resource_block_assignment_flag, unused here
+				      0,          // resource_block_coding, to be filled in later
+				      getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]),
+				      round&3   , // redundancy version
+				      1, // transport blocks
+				      0, // transport block to codeword swap flag
+				      cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
+				      1, // number of layers
+				      1, // number of subbands
+			     //			     uint8_t codebook_index,
+				      4, // UE category capacity
+				      UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 
+				      0, // delta_power_offset for TM5
+				      0, // ngap
+				      0, // nprb
+				      cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
+				      0, //number of PRBs treated as one subband, not used here
+				      0 // number of beamforming vectors, not used here
+				      );
+
+	      eNB->pdu_index[CC_id]++;
+	      program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
+	      // No TX request for retransmission (check if null request for FAPI)
 	    }
 	    else {
-	      // No TX request for retransmission (check if null request for FAPI)
+	      LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
+		    frameP,subframeP,UE_id,rnti);
 	    }
 	  }
 
@@ -789,7 +824,7 @@ schedule_ue_spec(
 					      ENB_FLAG_YES,
 					      MBMS_FLAG_NO,
 					      DCCH,
-						  TBS, //not used
+					      TBS, //not used
 					      (char *)&dlsch_buffer[0]);
 
             T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
@@ -993,15 +1028,7 @@ schedule_ue_spec(
               j = j+1;
             }
           }
-	  /*
-          RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
-          RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
 
-          for(j=0; j<N_RBG[CC_id]; j++) {
-            RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
-
-          }
-	  */
           // decrease mcs until TBS falls below required length
           while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) {
             mcs--;
@@ -1120,7 +1147,7 @@ schedule_ue_spec(
           // this is the normalized RX power
 	  eNB_UE_stats =  &UE_list->eNB_UE_stats[CC_id][UE_id];
 	  normalized_rx_power = eNB_UE_stats->Po_PUCCH_dBm; 
-	  target_rx_power = get_target_pucch_rx_power(module_idP,CC_id) + 20;
+	  target_rx_power = cc[CC_id].radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH + 20;
 	    
           // this assumes accumulated tpc
 	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
@@ -1184,27 +1211,59 @@ schedule_ue_spec(
 		  module_idP,CC_id,harq_pid,round,mcs);
 	    
 	  }
-	  dl_req->number_dci++;
-	  dl_req->number_pdu++;
-
-          // Toggle NDI for next time
-          LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
-                CC_id, frameP,subframeP,UE_id,
-                UE_list->UE_template[CC_id][UE_id].rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
-          
-	  UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
-	  UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
-	  UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
-
-	  eNB->TX_req[CC_id].sfn_sf                                             = (frameP<<3)+subframeP;
-	  TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; 
-	  TX_req->pdu_length                                                    = TBS;
-	  TX_req->pdu_index                                                     = eNB->pdu_index[CC_id]++;
-	  TX_req->num_segments                                                  = 1;
-	  TX_req->segments[0].segment_length                                    = TBS;
-	  TX_req->segments[0].segment_data                                      = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[harq_pid];
-	  eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
-
+	  if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) {
+	    dl_req->number_dci++;
+	    dl_req->number_pdu++;
+	    
+	    // Toggle NDI for next time
+	    LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
+		  CC_id, frameP,subframeP,UE_id,
+		  rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
+	    
+	    UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+	    UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
+	    UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
+	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
+	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
+	    
+	    fill_nfapi_dlsch_config(eNB,dl_req,
+				    TBS,
+				    eNB->pdu_index[CC_id],
+				    rnti,
+				    0, // type 0 allocation from 7.1.6 in 36.213
+				    0, // virtual_resource_block_assignment_flag, unused here
+				    0, // resource_block_coding, to be filled in later
+				    getQm(mcs),
+				    0, // redundancy version
+				    1, // transport blocks
+				    0, // transport block to codeword swap flag
+				    cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
+				    1, // number of layers
+				    1, // number of subbands
+				    //			     uint8_t codebook_index,
+				    4, // UE category capacity
+				    UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 
+				    0, // delta_power_offset for TM5
+				    0, // ngap
+				    0, // nprb
+				    cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
+				    0, //number of PRBs treated as one subband, not used here
+				    0 // number of beamforming vectors, not used here
+				    );  
+	    eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
+							  (frameP*10)+subframeP,
+							  TBS,
+							  &eNB->pdu_index[CC_id],
+							  eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[harq_pid]);
+	    
+	    eNB->pdu_index[CC_id]++;
+	    program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
+				 
+	  }
+	  else {
+	    LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
+		  frameP,subframeP,UE_id,rnti);
+	  }
         } else {  // There is no data from RLC or MAC header, so don't schedule
 
         }
@@ -1277,7 +1336,8 @@ fill_DLSCH_dci(
         // clear scheduling flag
         eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING;
         rnti = UE_RNTI(module_idP,UE_id);
-	harq_pid = UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id];
+	if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
+	else harq_pid = ((frameP*10)+subframeP)&7;
         nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
 
 	eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; 
@@ -1297,7 +1357,11 @@ fill_DLSCH_dci(
 	      (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti)) {
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding    = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub);
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
-	    break;
+	  }
+	  else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&&
+		   (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti)) {
+	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding    = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub);
+	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 0;
 	  }
 	}
       }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 45cb7082f9be6564db0cc3d7a8baed95fb8ab0f9..dea0a91481a7972436f0383e6278784be4226aea 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -59,6 +59,52 @@
 #define ENABLE_MAC_PAYLOAD_DEBUG
 #define DEBUG_eNB_SCHEDULER 1
 
+int choose(int n,int k) {
+
+  int res  = 1;
+  int res2 = 1;
+  int i;
+
+  if (k>n) return(0);
+  if (n==k) return(1);
+
+  for (i=n;i>k;i--) res*=i;
+  for (i=2;i<=(n-k);i++) res2*=i;
+
+  return(res/res2);
+}
+
+// Patented algorithm from Yang et al, US Patent 2009, "Channel Quality Indexing and Reverse Indexing"
+void reverse_index(int N,int M,int r,int *v) {
+
+  int BaseValue=0;
+  int IncreaseValue,ThresholdValue;
+  int sumV;
+  int i;
+
+  r = choose(N,M) - 1 - r;
+  memset((void*)v,0,M*sizeof(int));
+
+  sumV=0;
+  i=M;
+  while (i>0 && r>0) {
+
+    IncreaseValue = choose(N-M+1-sumV-v[i-1]+i-2,i-1);
+    ThresholdValue = BaseValue+IncreaseValue;
+    if (r>=ThresholdValue) {
+      v[i-1]++;
+      BaseValue=ThresholdValue;
+    }
+    else {
+      r=r-BaseValue;
+      sumV+=v[i-1];
+      i--;
+      BaseValue=0;
+    }
+
+  }
+
+}
 int to_prb(int dl_Bandwidth) {
   int prbmap[6] = {6,15,25,50,75,100};
 
@@ -97,7 +143,15 @@ uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) {
   return(RIV);
 }
 
+uint8_t getQm(uint8_t mcs) {
+
+  if (mcs<10) return(2);
+  else if (mcs<17) return(4);
+  else return (6);
+}
+
 void get_Msg3alloc(COMMON_channels_t *cc,
+
 		   sub_frame_t current_subframe,
 		   frame_t current_frame,
 		   frame_t *frame,
@@ -403,6 +457,53 @@ uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
 
 }
 
+uint32_t pdcchalloc2ulframe(COMMON_channels_t *ccP,uint32_t frame, uint8_t n)
+{
+  uint32_t ul_frame;
+
+  if ((ccP->tdd_Config) &&
+      (ccP->tdd_Config->subframeAssignment == 1) &&
+      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
+    ul_frame = (frame + (n==1 ? 0 : 1));
+  else if ((ccP->tdd_Config) &&
+	   (ccP->tdd_Config->subframeAssignment == 6) &&
+	   ((n==0)||(n==1)||(n==5)||(n==6)))
+    ul_frame = (frame + (n>=5 ? 1 : 0));
+  else if ((ccP->tdd_Config) &&
+	   (ccP->tdd_Config->subframeAssignment == 6) &&
+           (n==9)) // tdd_config 6 SF 9
+    ul_frame = (frame+1);
+  else
+    ul_frame = (frame+(n>=6 ? 1 : 0));
+
+  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame);
+  return ul_frame;
+
+}
+
+uint8_t pdcchalloc2ulsubframe(COMMON_channels_t *ccP,uint8_t n) {
+
+  uint8_t ul_subframe;
+
+  if ((ccP->tdd_Config) &&
+      (ccP->tdd_Config->subframeAssignment == 1) &&
+      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
+    ul_subframe = ((n+6)%10);
+  else if ((ccP->tdd_Config) &&
+	   (ccP->tdd_Config->subframeAssignment == 6) &&
+           ((n==0)||(n==1)||(n==5)||(n==6)))
+    ul_subframe = ((n+7)%10);
+  else if ((ccP->tdd_Config) &&
+	   (ccP->tdd_Config->subframeAssignment == 6) &&
+           (n==9)) // tdd_config 6 SF 9
+    ul_subframe = ((n+5)%10);
+  else
+    ul_subframe = ((n+4)%10);
+
+  LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
+  return ul_subframe;
+}
+
 int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP)
 {
 
@@ -460,12 +561,751 @@ int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP)
 
   default:
     AssertFatal(1==0,"subframe %d Unsupported TDD configuration %d\n",
-		subframeP,ccP->tdd_Config->subframeAssignment);
+		subframeP,(int)ccP->tdd_Config->subframeAssignment);
     break;
 
   }
 }
 
+uint16_t get_pucch1_absSF(COMMON_channels_t *cc,uint16_t dlsch_absSF) {
+
+  uint16_t sf,f,nextf;
+  
+  if (cc->tdd_Config==NULL) { //FDD n+4
+    return((dlsch_absSF + 4)%10240);
+  }
+  else {
+    sf    = dlsch_absSF%10;
+    f     = dlsch_absSF/10;
+    nextf = (f+1)&1023;
+
+    switch (cc->tdd_Config->subframeAssignment) {
+    case 0:
+      AssertFatal(1==0,"SFA 0 to be filled in now, :-)\n");
+      break;
+    case 1:
+      if      ((sf==5) || (sf==6)) return((10*nextf) + 2);                                        // ACK/NAK in SF 2 next frame
+      else if (sf==9)              return((10*nextf) + 3);                                        // ACK/NAK in SF 3 next frame
+      else if ((sf==0) || (sf==1)) return((10*f) + 2);                                            // ACK/NAK in SF 7 same frame
+      else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 3\n",sf);
+      break;
+    case 2:
+      if      ((sf==4) || (sf==5) || (sf==6) || (sf==8)) return((10*nextf) + 2);                  // ACK/NAK in SF 2 next frame
+      else if (sf==9)                                    return((10*nextf) + 7);                  // ACK/NAK in SF 7 next frame
+      else if ((sf==0) || (sf==1) || (sf==3))            return((10*f) + 7);                      // ACK/NAK in SF 7 same frame
+      else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 3\n",sf);
+      break;
+    case 3:
+      if      ((sf==5) || (sf==6) || (sf==7) || (sf==8) || (sf==9)) return((10*nextf) + (sf>>1)); // ACK/NAK in 2,3,4 resp. next frame 
+      else if (sf==1)                                               return((10*nextf) + 2);       // ACK/NAK in 2 next frame 
+      else if (sf==0)                                               return((10*f) + 4);           // ACK/NAK in 4 same frame 
+      else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 3\n",sf);
+      break;
+    case 4:
+      if      ((sf==6) || (sf==7) || (sf==8) || (sf==9)) return(((10*nextf) + 3)%10240);          // ACK/NAK in SF 3 next frame
+      else if ((sf==0) || (sf==1) || (sf==4) || (sf==5)) return(((10*nextf) + 2)%10240);          // ACK/NAK in SF 2 next frame
+      else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 4\n",sf);
+      break;
+    case 5:
+      if      ((sf==0) || (sf==1) || (sf==3) || (sf==4) || (sf==5) || (sf==6) || (sf==7) || (sf==8)) return(((10*nextf) + 2)%10240);     // ACK/NAK in SF 3 next frame
+      else if (sf==9)                                                                                return(((10*(1+nextf)) + 2)%10240); // ACK/NAK in SF 2 next frame           
+      else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 5\n",sf);      
+      break;
+    case 6:
+      AssertFatal(1==0,"SFA 6 To be filled in now, :-)\n");
+      break;
+    default:
+      AssertFatal(1==0,"Illegal TDD subframe Assigment %d\n",(int)cc->tdd_Config->subframeAssignment);
+      break;
+    }
+  }
+  AssertFatal(1==0,"Shouldn't get here\n");
+}
+
+void get_srs_pos(COMMON_channels_t *cc,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset) {
+
+  if(cc->tdd_Config) { // TDD
+    AssertFatal(isrs>=10,"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;
+    }
+    
+    AssertFatal(isrs<=644,"Isrs out of range %d>644\n",isrs);
+      
+  } // TDD
+  else { // FDD
+
+    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;
+    }
+    AssertFatal(isrs<=636,"Isrs out of range %d>636\n",isrs);
+	
+  }
+}
+
+void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_ReportPeriodic,uint16_t *Npd,uint16_t *N_OFFSET_CQI,int *H) {
+
+  uint16_t cqi_PMI_ConfigIndex = cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex;
+  uint8_t Jtab[6] = {0,2,2,3,4,4};
+
+  AssertFatal(cqi_ReportPeriodic!=NULL,"cqi_ReportPeriodic is null!\n");
+
+  if (cc->tdd_Config==NULL) { //FDD
+    if (cqi_PMI_ConfigIndex <= 1) {        // 2 ms CQI_PMI period
+      *Npd = 2;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex;
+    } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
+      *Npd = 5;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-2;
+    } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
+      *Npd = 10;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-7;
+    } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
+      *Npd = 20;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-17;
+    } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
+      *Npd = 40;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-37;
+    } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
+      *Npd = 80;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-77;
+    } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
+      *Npd = 160;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
+    }
+    else if (cqi_PMI_ConfigIndex > 317) {
+      
+      if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
+	*Npd = 32;
+      *N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
+      }
+      else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
+	*Npd = 64;
+	*N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
+      }
+      else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
+	*Npd = 128;
+	*N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
+      }  
+    }
+  }
+  else { // TDD
+   if (cqi_PMI_ConfigIndex == 0) {        // all UL subframes
+     *Npd = 1;
+     *N_OFFSET_CQI = 0;
+   } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period
+     *Npd = 5;
+     *N_OFFSET_CQI = cqi_PMI_ConfigIndex-1;
+   } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period
+     *Npd = 10;
+     *N_OFFSET_CQI = cqi_PMI_ConfigIndex-6;
+   } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period
+     *Npd = 20;
+     *N_OFFSET_CQI = cqi_PMI_ConfigIndex-16;
+   } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period
+     *Npd = 40;
+     *N_OFFSET_CQI = cqi_PMI_ConfigIndex-36;
+   } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period
+     *Npd = 80;
+     *N_OFFSET_CQI = cqi_PMI_ConfigIndex-76;
+   } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period
+     *Npd = 160;
+     *N_OFFSET_CQI = cqi_PMI_ConfigIndex-156;
+   }
+  }
+
+  // get H
+  if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI)
+    *H = 1+(Jtab[cc->mib->message.dl_Bandwidth]*cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k);
+  else
+    *H=1;
+}
+
+
+uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc,uint8_t tmode,uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic) {
+
+  int Ntab[6]       = {0,4,7,9,10,13};
+  int Ntab_uesel[6] = {0,8,13,17,19,25};
+  int N             = Ntab[cc->p_eNB];
+  int Ltab_uesel[6] = {0,6,9,13,15,18};
+  int L             = Ltab_uesel[cc->p_eNB];
+
+  AssertFatal(cqi_ReportModeAperiodic != NULL,"cqi_ReportPeriodic is null!\n");
+
+  switch (*cqi_ReportModeAperiodic) {
+  
+  case CQI_ReportModeAperiodic_rm12:
+    AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n",tmode);
+    AssertFatal(cc->p_eNB<=4,"only up to 4 antenna ports supported here\n");
+    if (ri==1 && cc->p_eNB==2) return(4+(N<<1));
+    else if (ri==2 && cc->p_eNB==2) return(8+N);
+    else if (ri==1 && cc->p_eNB==4) return(4+(N<<2));
+    else if (ri>1  && cc->p_eNB==4) return(8+(N<<2));		 
+    break;
+  case CQI_ReportModeAperiodic_rm20:
+    // Table 5.2.2.6.3-1 (36.212)
+    AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n",tmode);
+    AssertFatal(tmode!=9 && tmode!=10,"TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n");
+    return(4+2+L);
+    break;
+  case CQI_ReportModeAperiodic_rm22:
+    // Table 5.2.2.6.3-2 (36.212)
+    AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n",tmode);
+    AssertFatal(tmode!=9 && tmode!=10,"TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n");
+    if (ri==1 && cc->p_eNB==2) return(4+2+0+0+L+4);
+    if (ri==2 && cc->p_eNB==2) return(4+2+4+2+L+2);
+    if (ri==1 && cc->p_eNB==4) return(4+2+0+0+L+8);
+    if (ri>=2 && cc->p_eNB==4) return(4+2+4+2+L+8);
+    break;
+  case CQI_ReportModeAperiodic_rm30:
+    // Table 5.2.2.6.2-1 (36.212)
+    AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n",tmode);
+    AssertFatal(tmode!=8 && tmode!=9 && tmode!=10,"TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n");
+    return(4+(N<<1));
+    break;
+  case CQI_ReportModeAperiodic_rm31:
+    // Table 5.2.2.6.2-2 (36.212)
+    AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n",tmode);
+    AssertFatal(tmode!=8 && tmode!=9 && tmode!=10,"TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n");
+    if (ri==1 && cc->p_eNB==2) return(4+(N<<1)+0+0+2);
+    else if (ri==2 && cc->p_eNB==2) return(4+(N<<1)+4+(N<<1)+1);
+    else if (ri==1 && cc->p_eNB==4) return(4+(N<<1)+0+0+4);
+    else if (ri>=2 && cc->p_eNB==4) return(4+(N<<1)+4+(N<<1)+4);
+    break;
+  case CQI_ReportModeAperiodic_rm32_v1250:
+    AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n",tmode);
+    AssertFatal(1==0,"CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n");
+    break;
+  case CQI_ReportModeAperiodic_rm10_v1310:
+    // Table 5.2.2.6.1-1F/G (36.212)
+    if (ri==1) return(4); // F
+    else return(7); // G
+    break;
+  case CQI_ReportModeAperiodic_rm11_v1310:
+    // Table 5.2.2.6.1-1H (36.212)
+    AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n",tmode);
+    AssertFatal(cc->p_eNB<=4,"only up to 4 antenna ports supported here\n");
+    if (ri==1 && cc->p_eNB==2) return(4+0+2);
+    else if (ri==2 && cc->p_eNB==2) return(4+4+1);
+    else if (ri==1 && cc->p_eNB==4) return(4+0+4);
+    else if (ri>1  && cc->p_eNB==4) return(4+4+4);		 
+
+    break;
+  }
+
+}
+
+uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic) {
+
+  int no_pmi=0;
+  //    Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)};
+
+  uint8_t Ltab[6] = {0,1,2,2,2,2};
+  uint8_t ri = sched_ctl->periodic_ri_received[CC_idP];
+
+  AssertFatal(cqi_ReportPeriodic != NULL,"cqi_ReportPeriodic is null!\n");
+  AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING,
+	      "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n");
+  AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING,
+	      "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n");
+
+  switch(tmode) {
+  case 1:
+  case 2:
+  case 5:
+  case 6:
+  case 7:
+    no_pmi=1;
+    break;
+  default:
+    no_pmi=0;
+  }
+
+
+
+  if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) ||
+      (sched_ctl->feedback_cnt[CC_idP] == 0)) {
+    // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities
+    if (no_pmi == 1)
+      return(4);
+    else if ((cc->p_eNB==2) && (ri==1)) return(6);
+    else if ((cc->p_eNB==2) && (ri==2)) return(8);
+    else if ((cc->p_eNB==4) && (ri==1)) return(8);
+    else if ((cc->p_eNB==4) && (ri==2)) return(11);
+    else AssertFatal(1==0,"illegal combination p %d, ri %d, no_pmi %d\n",cc->p_eNB,ri,no_pmi);
+  }
+  else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) {
+    if ((no_pmi == 1)||ri==1) return(4+Ltab[cc->mib->message.dl_Bandwidth]);
+    else 
+      return(7+Ltab[cc->mib->message.dl_Bandwidth]);    
+  }
+  AssertFatal(1==0,"Shouldn't get here : cqi_ReportPeriodic->present %d\n",cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present);
+}
+
+void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t   *dl_config_pdu,
+			  uint8_t aggregation_level,
+			  uint16_t rnti,
+			  uint8_t rnti_type,
+			  uint8_t harq_process,
+			  uint8_t tpc,
+			  uint16_t resource_block_coding,
+			  uint8_t mcs,
+			  uint8_t ndi,
+			  uint8_t rv,
+			  uint8_t vrb_flag) {
+  
+  memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
+  dl_config_pdu->pdu_type                                                          = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
+  dl_config_pdu->pdu_size                                                          = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                             = NFAPI_DL_DCI_FORMAT_1A;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level                      = aggregation_level;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                                   = rnti;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                              = rnti_type;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power                     = 6000; // equal to RS power
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                           = harq_process;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                                    = tpc; // no TPC
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding                  = resource_block_coding;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                                  = mcs;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1                   = ndi;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1                   = rv;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag;
+  
+}
+
+void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t frameP, sub_frame_t subframeP,uint8_t cce_idx) {
+
+  eNB_MAC_INST                   *eNB      = RC.mac[module_idP];
+  COMMON_channels_t              *cc       = eNB->common_channels;
+  UE_list_t                      *UE_list  = &eNB->UE_list;
+  rnti_t                         rnti      = UE_RNTI(module_idP,UE_idP);
+  nfapi_ul_config_request_body_t *ul_req;
+  nfapi_ul_config_request_pdu_t  *ul_config_pdu;
+
+  int use_simultaneous_pucch_pusch=0;
+  nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL;
+  nfapi_ul_config_harq_information *harq_information = NULL;
+  
+#if defined(Rel10) || defined(Rel14)
+  
+  if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2) &&
+      (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) &&
+      (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10) &&	    
+      (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) use_simultaneous_pucch_pusch=1;
+#endif
+  
+  // pucch1 and pusch feedback is similar, namely in n+k subframes from now
+  // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k
+  int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP],subframeP+(10*frameP));
+  
+  if ((ul_config_pdu = has_ul_grant(module_idP,CC_idP,
+				    ul_absSF,
+				    rnti)) == NULL) {
+    // no UL grant so
+    // Program ACK/NAK alone Format 1a/b or 3
+    
+    ul_req        = &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF%10].ul_config_request_body;
+    ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];	    
+    // Do PUCCH
+    fill_nfapi_uci_acknak(module_idP,
+			  CC_idP,
+			  rnti,
+			  (frameP*10)+subframeP,
+			  cce_idx);
+  }
+  else { // there is already an existing UL grant so update it if needed
+    // on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc)
+    switch(ul_config_pdu->pdu_type) {
+    case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE:
+    case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE:
+    case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE:
+      if (use_simultaneous_pucch_pusch==1) {
+	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE,
+		    "Cannot be NFAPI_UL_CONFIG_ULSCH_PDU_TYPE, simultaneous_pucch_pusch is active\n");
+	// Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE 
+	harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information;
+	ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE;
+      }
+      else {
+	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE,
+		    "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n");
+	// Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE 
+	ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information;
+	ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+	ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial=0; // last symbol not punctured
+	ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks=
+	  ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet
+      }
+      break;
+    case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE:
+    case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE:
+    case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE:
+    case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE:
+      if (use_simultaneous_pucch_pusch==1) {
+	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE||
+		    ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE,
+		    "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_RI_xxx_PDU_TYPE, simultaneous_pucch_pusch is active\n");
+	// convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE
+	harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information;
+	ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE;
+	
+      }
+      else { 
+	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE ||
+		    ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE,
+		    "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_xxx_PDU_TYPE, simultaneous_pucch_pusch is inactive\n");
+	// Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_RI_HARQ_PDU_TYPE 
+	ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
+	ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+	ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial=0; // last symbol not punctured
+	ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks=
+	  ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet		
+      }
+      
+      break;
+      
+    case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE:
+    case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE:
+      // convert/keep it to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE
+      ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE;
+      harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information;
+      break;
+    case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE:
+    case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE:
+      // convert/keep it to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE
+      ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE;
+      harq_information = &ul_config_pdu->uci_cqi_harq_pdu.harq_information;
+      break;
+      
+    case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE:
+    case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE:
+      // convert/keep it to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE
+      ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE;
+      harq_information = &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information;
+      break;
+    }
+  }
+  
+  if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP,CC_idP,
+								rnti,
+								ulsch_harq_information);
+  
+  
+  if (harq_information) fill_nfapi_harq_information(module_idP,CC_idP,
+						    rnti,
+						    (frameP*10)+subframeP,
+						    harq_information,
+						    cce_idx);
+}
+
+uint8_t get_V_UL_DAI(module_id_t module_idP,int CC_idP,uint16_t rntiP) {
+
+  nfapi_hi_dci0_request_body_t        *HI_DCI0_req         = &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body;
+  nfapi_hi_dci0_request_pdu_t         *hi_dci0_pdu         = &HI_DCI0_req->hi_dci0_pdu_list[0];
+
+  for (int i=0;i<HI_DCI0_req->number_of_dci;i++) {
+    if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE)&&
+	(hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP))
+	return(hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index);
+  }
+  return(4); // this is rule from Section 7.3 in 36.213
+}
+void fill_nfapi_ulsch_harq_information(module_id_t module_idP,
+				       int CC_idP,
+				       uint16_t rntiP,
+				       nfapi_ul_config_ulsch_harq_information *harq_information) {
+
+
+  eNB_MAC_INST                   *eNB      = RC.mac[module_idP];
+  COMMON_channels_t              *cc       = &eNB->common_channels[CC_idP];
+  UE_list_t                      *UE_list  = &eNB->UE_list;
+
+  int UE_id                                = find_UE_id(module_idP,rntiP);
+
+  PUSCH_ConfigDedicated_t              *puschConfigDedicated;
+  //  PUSCH_ConfigDedicated_v1020_t        *puschConfigDedicated_v1020;
+  //  PUSCH_ConfigDedicated_v1130_t        *puschConfigDedicated_v1130;
+  //  PUSCH_ConfigDedicated_v1250_t        *puschConfigDedicated_v1250;
+
+  AssertFatal(UE_id>=0,"UE_id cannot be found, impossible\n");
+  AssertFatal(UE_list!=NULL,"UE_list is null\n");
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated for rnti %x is null\n",rntiP);
+  AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *)UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pusch_ConfigDedicated)!=NULL,"physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n",rntiP);
+#if defined(Rel14) || defined(Rel14)
+  /*  if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 =  UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020;
+#endif
+#ifdef Rel14
+  if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 =  UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130;
+  if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 =  UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250;
+  */
+#endif
+  harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index;
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL,"pucch_ConfigDedicated is null!\n");
+  if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode!=NULL)&&
+      (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode==PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing))
+      harq_information->harq_information_rel10.ack_nack_mode = 1;  // multiplexing
+  else
+      harq_information->harq_information_rel10.ack_nack_mode = 0;  // bundling
+
+  switch(get_tmode(module_idP,CC_idP,UE_id)) {
+  case 1:
+  case 2:
+  case 5:
+  case 6:
+  case 7:
+
+    if (cc->tdd_Config==NULL) // FDD
+      harq_information->harq_information_rel10.harq_size = 1;
+    else {
+      if (harq_information->harq_information_rel10.ack_nack_mode == 1)
+	harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP,CC_idP,rntiP);
+      else
+	harq_information->harq_information_rel10.harq_size = 1;
+    }
+    break;
+  default: // for any other TM we need 2 bits harq 
+    
+    if (cc->tdd_Config==NULL) {
+	harq_information->harq_information_rel10.harq_size     = 2;  
+    }
+    else {
+      if (harq_information->harq_information_rel10.ack_nack_mode == 1)
+	harq_information->harq_information_rel10.harq_size     = get_V_UL_DAI(module_idP,CC_idP,rntiP);  
+      else
+	harq_information->harq_information_rel10.harq_size     = 2;  
+    }
+    break;
+  } // get Tmode
+}
+  
+void fill_nfapi_harq_information(module_id_t module_idP,
+				 int CC_idP,
+				 uint16_t rntiP,
+				 uint16_t absSFP,
+				 nfapi_ul_config_harq_information *harq_information,
+				 uint8_t cce_idxP) {
+  
+  eNB_MAC_INST                   *eNB      = RC.mac[module_idP];
+  COMMON_channels_t              *cc       = &eNB->common_channels[CC_idP];
+  UE_list_t                      *UE_list  = &eNB->UE_list;
+
+  int UE_id                                = find_UE_id(module_idP,rntiP);
+
+
+  AssertFatal(UE_id>=0,"UE_id cannot be found, impossible\n");
+  AssertFatal(UE_list!=NULL,"UE_list is null\n");
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated for rnti %x is null\n",rntiP);
+
+  harq_information->harq_information_rel11.num_ant_ports = 1;
+
+  switch(get_tmode(module_idP,CC_idP,UE_id)) {
+  case 1:
+  case 2:
+  case 5:
+  case 6:
+  case 7:
+    if (cc->tdd_Config!=NULL) {
+      AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL,
+		  "pucch_ConfigDedicated is null for TDD!\n");
+      if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode!=NULL)&&
+	  (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode==PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) {
+	harq_information->harq_information_rel10_tdd.harq_size     = 2;  // 2-bit ACK/NAK
+	harq_information->harq_information_rel10_tdd.ack_nack_mode = 1;  // multiplexing
+      }
+      else {
+	harq_information->harq_information_rel10_tdd.harq_size     = 1;  // 1-bit ACK/NAK
+	harq_information->harq_information_rel10_tdd.ack_nack_mode = 0;  // bundling
+      }
+      harq_information->harq_information_rel10_tdd.n_pucch_1_0   = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;
+      harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1;
+    } else {
+      harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1;
+      harq_information->harq_information_rel9_fdd.harq_size                 = 1;  // 1-bit ACK/NAK
+      harq_information->harq_information_rel9_fdd.n_pucch_1_0               = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;
+    }
+    break;
+  default: // for any other TM we need 2 bits harq 
+    if (cc->tdd_Config!=NULL) {
+      AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL,
+		  "pucch_ConfigDedicated is null for TDD!\n");
+      if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode!=NULL)&&
+	  (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode==PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) {
+	harq_information->harq_information_rel10_tdd.ack_nack_mode = 1;  // multiplexing
+      }
+      else {
+	harq_information->harq_information_rel10_tdd.ack_nack_mode = 0;  // bundling
+      }
+      harq_information->harq_information_rel10_tdd.harq_size       = 2;  
+      harq_information->harq_information_rel10_tdd.n_pucch_1_0   = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;
+      harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1;
+    }
+    else {
+      harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1;
+      harq_information->harq_information_rel9_fdd.ack_nack_mode    = 0;  // 1a/b
+      harq_information->harq_information_rel9_fdd.harq_size        = 2;
+      harq_information->harq_information_rel9_fdd.n_pucch_1_0      = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;  
+    }
+    break;
+  } // get Tmode
+}
+ 
+
+uint16_t fill_nfapi_uci_acknak(module_id_t module_idP,
+			       int CC_idP,
+			       uint16_t rntiP,
+			       uint16_t absSFP,
+			       uint8_t cce_idxP) {
+
+  eNB_MAC_INST                   *eNB          = RC.mac[module_idP];
+  COMMON_channels_t              *cc           = &eNB->common_channels[CC_idP];
+  
+  int ackNAK_absSF                             = get_pucch1_absSF(cc,absSFP);
+  nfapi_ul_config_request_body_t *ul_req       = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF%10].ul_config_request_body;
+  nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
+
+
+  memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+  ul_config_pdu->pdu_type                                                              = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; 
+  ul_config_pdu->pdu_size                                                              = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu));
+  ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle                = 0; // don't know how to use this
+  ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti                  = rntiP;
+
+  fill_nfapi_harq_information(module_idP,CC_idP,
+			      rntiP,
+			      absSFP,
+			      &ul_config_pdu->uci_harq_pdu.harq_information,
+			      cce_idxP);
+  LOG_I(MAC,"Filled in HARQ for rnti %x, cce_idxP %d-> n1_pucch %d\n",rntiP,cce_idxP,ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0);
+
+  ul_req->number_of_pdus++;
+
+  return(((ackNAK_absSF/10)<<4) + (ackNAK_absSF%10));
+}
+
+void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, 
+			     nfapi_dl_config_request_body_t *dl_req,
+			     uint16_t length,
+			     uint16_t pdu_index,
+			     uint16_t rnti,
+			     uint8_t resource_allocation_type,
+			     uint8_t virtual_resource_block_assignment_flag,
+			     uint16_t resource_block_coding,
+			     uint8_t modulation,
+			     uint8_t redundancy_version,
+			     uint8_t transport_blocks,
+			     uint8_t transport_block_to_codeword_swap_flag,
+			     uint8_t transmission_scheme,
+			     uint8_t number_of_layers,
+			     uint8_t number_of_subbands,
+			     //			     uint8_t codebook_index,
+			     uint8_t ue_category_capacity,
+			     uint8_t pa,
+			     uint8_t delta_power_offset_index,
+			     uint8_t ngap,
+			     uint8_t nprb,
+			     uint8_t transmission_mode,
+			     uint8_t num_bf_prb_per_subband,
+			     uint8_t num_bf_vector
+			     ) {
+
+  nfapi_dl_config_request_pdu_t   *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
+
+  dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
+  memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
+  dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
+  dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length                                 = length;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = pdu_index;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = rnti;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = resource_allocation_type;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag;   
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = resource_block_coding;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = modulation; 
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = redundancy_version;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = transport_blocks;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = transport_block_to_codeword_swap_flag;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = transmission_scheme;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = number_of_layers;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = number_of_subbands;
+  //  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = codebook_index;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = ue_category_capacity;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = pa;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = delta_power_offset_index;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = ngap;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = nprb;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = transmission_mode;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = num_bf_prb_per_subband;
+  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = num_bf_vector;
+  dl_req->number_pdu++;
+}
+
+uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,uint16_t pdu_length, uint16_t *pdu_index, uint8_t *pdu) {
+
+  nfapi_tx_request_pdu_t *TX_req        = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; 
+  LOG_I(MAC,"Filling TX_req %d for pdu length %d\n",tx_req_body->number_of_pdus,pdu_length);
+  TX_req->pdu_length                    = pdu_length;
+  TX_req->pdu_index                     = *pdu_index++;
+  TX_req->num_segments                  = 1;
+  TX_req->segments[0].segment_length    = pdu_length;
+  TX_req->segments[0].segment_data      = pdu;
+  tx_req_body->number_of_pdus++;
+
+  return(((absSF/10)<<4) + (absSF%10));
+}
 #ifdef Rel14
 
 int get_numnarrowbands(long dl_Bandwidth) {
@@ -517,7 +1357,7 @@ int mpdcch_sf_condition(eNB_MAC_INST *eNB,int CC_id, frame_t frameP,sub_frame_t
     AssertFatal(1==0,"MPDCCH Type 2A not handled yet\n");
     break;
   case TYPEUESPEC:
-    epdcch_setconfig_r11= &eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0] ;
+    epdcch_setconfig_r11= eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0] ;
     
     
     AssertFatal(epdcch_setconfig_r11 != NULL," epdcch_setconfig_r11 is null for UE specific \n");
@@ -564,7 +1404,7 @@ int narrowband_to_first_rb(COMMON_channels_t *cc, int nb_index) {
     else            return(1+(6*nb_index));
     break;
   default:
-    AssertFatal(1==0,"Impossible dl_Bandwidth %d\n",cc->mib->message.dl_Bandwidth);
+    AssertFatal(1==0,"Impossible dl_Bandwidth %d\n",(int)cc->mib->message.dl_Bandwidth);
     break;
   }
 }
@@ -632,10 +1472,16 @@ int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP)
 
  
 
-  for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++)
+  for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) {
+    LOG_I(MAC,"Checking RA_id %d for %x : RA_active %d, wait_ack_Msg4 %d\n",
+	  RA_id,rntiP,
+	  RA_template[RA_id].RA_active,
+	  RA_template[RA_id].wait_ack_Msg4);
+	  
     if (RA_template[RA_id].RA_active==TRUE && 
         RA_template[RA_id].wait_ack_Msg4 == 0 &&
 	RA_template[RA_id].rnti == rntiP) return(RA_id);
+  }
   return(-1);
 }
 
@@ -815,9 +1661,7 @@ int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP)
   int pCC_id;
 
   if (UE_id == -1) {
-printf("MAC: cannot remove UE rnti %x\n", rntiP);
     LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
-    mac_phy_remove_ue(mod_idP, rntiP);
     return 0;
   }
 
@@ -843,7 +1687,6 @@ printf("MAC: cannot remove UE rnti %x\n", rntiP);
   eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti                        = NOT_A_RNTI;
   eNB_dlsch_info[mod_idP][pCC_id][UE_id].status                      = S_DL_NONE;
 
-  mac_phy_remove_ue(mod_idP,rntiP);
 
   // check if this has an RA process active
   RA_TEMPLATE *RA_template;
@@ -1151,7 +1994,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
   if (UE_sched_ctl->ul_out_of_sync>0)
     return(0);
 
-  LOG_D(MAC,"[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));
+  LOG_I(MAC,"[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));
 
   if ((UE_template->bsr_info[LCGID0]>0) ||
       (UE_template->bsr_info[LCGID1]>0) ||
@@ -1165,7 +2008,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
        (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED
     { 
 
-    LOG_D(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));
+    LOG_I(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));
     return(1);
   } else {
     return(0);
@@ -1955,10 +2798,94 @@ try_again:
 
   return 0;
 
-failed:
+ failed:
   return -1;
 }
 
+/*
+uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP) {
+  
+  if (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config == NULL) 
+    return(0);
+  
+  switch (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment) {
+  
+  case 0:
+  case 1:
+  case 2:
+  case 6:
+    return(0);
+  case 3:
+    // 1,5,6 -> 2, prog. 8, buffer 0
+    // 7,8   -> 3, prog. 9, buffer 1
+    // 9,0   -> 4, prog. 0, buffer 0
+    if ((subframeP == 7) || (subframeP == 8)) return(1);
+    else                                      return(0);
+  case 4:
+    // 0,1,4,5 -> 2, prog. 8, buffer 0
+    // 6,7,8,9 -> 3, prog. 9, buffer 1
+    if (subframeP<6) return(0);
+    else             return(1);
+    return(1);
+    break;
+  case 5:
+    // 9(-1),0,1,3,4,5,6,7,8,9 -> 2, prog 8, buffer 0
+    return(0);
+    break;
+  default:
+    AssertFatal(1==0,"Should not get here, why is tdd_Config->subframeAssignment = %d\n",(int)RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment);
+    break;
+  }
+  return(0);
+}
+*/
+ 
+nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t subframeP,uint16_t rnti) {
+
+  nfapi_ul_config_request_body_t *ul_req;            
+  nfapi_ul_config_request_pdu_t *ul_config_pdu; 
+		
+  ul_req        = &RC.mac[module_idP]->UL_req_tmp[CC_idP][subframeP].ul_config_request_body;
+  ul_config_pdu = &ul_req->ul_config_pdu_list[0];
+
+  for (int i=0; i<ul_req->number_of_pdus;i++){
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE)&&
+	(ul_config_pdu[i].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE)&&
+	(ul_config_pdu[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)&&
+	(ul_config_pdu[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)&&
+	(ul_config_pdu[i].uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE)&&
+	(ul_config_pdu[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE)&&
+	(ul_config_pdu[i].uci_cqi_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) &&
+	(ul_config_pdu[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_uci_csi_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+    if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE)&&
+	(ul_config_pdu[i].ulsch_csi_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
+
+
+
+  }
+  return(NULL); // no ul grant at all for this UE
+}
+ 
 boolean_t CCE_allocation_infeasible(int module_idP,
 				    int CC_idP,
 				    int format_flag,
@@ -1995,7 +2922,570 @@ boolean_t CCE_allocation_infeasible(int module_idP,
   return(res);
 }
 
-void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP)
+void extract_harq(module_id_t mod_idP,int CC_idP,int UE_id,frame_t frameP,sub_frame_t subframeP,void *harq_indication,int format) {
+
+  UE_list_t *UE_list       = &RC.mac[mod_idP]->UE_list;
+  UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  rnti_t rnti              = UE_RNTI(mod_idP,UE_id);
+  COMMON_channels_t *cc    = &RC.mac[mod_idP]->common_channels[CC_idP];
+  nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd;
+  nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd;
+  uint16_t num_ack_nak;
+  int numCC = UE_list->numactiveCCs[UE_id];
+  int pCCid = UE_list->pCC_id[UE_id];
+  int spatial_bundling = 0;
+  int tmode[5];
+  int i,j;
+  uint8_t *pdu;
+
+#ifdef Rel14
+  AssertFatal(UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL,"pucch_ConfigDedicated is null!\n");
+  if ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) &&
+      (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) &&
+      (((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13) && 
+	(format==0)) ||
+       ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13) && 
+	(format==1))))
+    spatial_bundling = 1;
+#endif
+
+  for (i=0;i<numCC;i++) tmode[i] = get_tmode(mod_idP,i,UE_id);
+		      
+  if (cc->tdd_Config) { 
+    harq_indication_tdd = (nfapi_harq_indication_tdd_rel13_t *)harq_indication;
+    //    pdu = &harq_indication_tdd->harq_tb_n[0];
+
+    num_ack_nak = harq_indication_tdd->number_of_ack_nack;
+
+    switch (harq_indication_tdd->mode) {
+      case 0: // Format 1a/b
+	AssertFatal(numCC==1,"numCC %d > 1, should not be using Format1a/b\n",numCC);
+	break;
+      case 1: // Channel Selection
+	break;
+      case 2: // Format 3
+	break;
+      case 3: // Format 4
+	break;
+      case 4: // Format 5
+	break;
+    }
+  }
+  else {
+
+    harq_indication_fdd = (nfapi_harq_indication_fdd_rel13_t *)harq_indication;
+    num_ack_nak = harq_indication_fdd->number_of_ack_nack;
+    pdu = &harq_indication_fdd->harq_tb_n[0];
+
+    uint8_t harq_pid = ((10*frameP) + subframeP + 10236)&7;
+
+    switch (harq_indication_fdd->mode) {
+      case 0: // Format 1a/b (10.1.2.1)
+	AssertFatal(numCC==1,"numCC %d > 1, should not be using Format1a/b\n",numCC);
+	if (tmode[0]==1 || tmode[0]==2 || tmode[0]==5 || tmode[0]==6 || tmode[0]==7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port
+	  // single ACK/NAK bit
+	  AssertFatal(num_ack_nak==1,"num_ack_nak %d > 1 for 1 CC and single-layer transmission\n",num_ack_nak);
+	  AssertFatal(sched_ctl->round[CC_idP][harq_pid]<8,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",harq_pid,UE_id,rnti);
+	  AssertFatal(pdu[0] == 1 || pdu[0] == 2, "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n",pdu[0],harq_pid,UE_id,rnti);
+	  LOG_I(MAC,"Received %d for harq_pid %d\n",pdu[0],harq_pid);
+
+	  if (pdu[0] == 1) { // ACK
+	    sched_ctl->round[CC_idP][harq_pid]=8; // release HARQ process
+	    sched_ctl->tbcnt[CC_idP][harq_pid]=0;
+	  }
+	  else if (pdu[0] == 2) // NAK
+	    sched_ctl->round[CC_idP][harq_pid]++; // increment round
+	}
+	else {
+	  // one or two ACK/NAK bits
+	  AssertFatal(num_ack_nak>2,"num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n",num_ack_nak);
+	  if ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==1) && (pdu[0] == 1) && (pdu[1] == 1)) {
+	    sched_ctl->round[CC_idP][harq_pid]=8;
+	    sched_ctl->tbcnt[CC_idP][harq_pid]=0;
+	  }
+	  if ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==1) && (pdu[0] == 2) && (pdu[1] == 2))
+	    sched_ctl->round[CC_idP][harq_pid]++;
+	  else if (((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[0][harq_pid]==2) && (pdu[0] == 1) && (pdu[1] == 2)) ||
+		   ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==2) && (pdu[0] == 2) && (pdu[1] == 1))) {
+	    sched_ctl->round[CC_idP][harq_pid]++;
+	    sched_ctl->tbcnt[CC_idP][harq_pid]=1;
+	  }
+	  else if ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==2) && (pdu[0] == 2) && (pdu[1] == 2))
+	    sched_ctl->round[CC_idP][harq_pid]++;
+	  else AssertFatal(1==0,"Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n",
+			   num_ack_nak,sched_ctl->round[CC_idP][harq_pid],sched_ctl->round[CC_idP][harq_pid],pdu[0],pdu[1], harq_pid,UE_id,
+			   rnti);
+	}
+	break;
+      case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells
+	AssertFatal(numCC==2,"Should not receive harq indication with channel selection with %d active CCs\n",
+		    numCC);
+	
+	if ((num_ack_nak == 2) && (sched_ctl->round[pCCid][harq_pid]<8) && (sched_ctl->round[1-pCCid][harq_pid]<8) && (sched_ctl->tbcnt[pCCid][harq_pid]==1) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==1)) {
+	  AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]);
+	  AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]);
+	  if (pdu[0] == 1) sched_ctl->round[pCCid][harq_pid]=8;
+	  else             sched_ctl->round[pCCid][harq_pid]++;
+	  if (pdu[1] == 1) sched_ctl->round[1-pCCid][harq_pid]=8;
+	  else             sched_ctl->round[1-pCCid][harq_pid]++;
+	} // A=2
+	else if ((num_ack_nak == 3) && (sched_ctl->round[pCCid][harq_pid]<8) && (sched_ctl->tbcnt[pCCid][harq_pid]==2) && (sched_ctl->round[1-pCCid][harq_pid]<8) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==1)) {
+	  AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]);
+	  AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]);
+	  AssertFatal(pdu[2]<=3,"pdu[2] %d is not ACK/NAK/DTX\n",pdu[2]);
+	  AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2,"sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n",pCCid,harq_pid,UE_id,rnti);
+	  AssertFatal(sched_ctl->tbcnt[1-pCCid][harq_pid] == 1,"sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n",1-pCCid,harq_pid,UE_id,rnti);
+	  if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK
+	      sched_ctl->round[pCCid][harq_pid]=8;
+	      sched_ctl->tbcnt[pCCid][harq_pid]=0;
+	  }
+	  else if (((pdu[0] == 2) && (pdu[1] == 1))||
+		   ((pdu[0] == 1) && (pdu[1] == 2))){
+	    sched_ctl->round[pCCid][harq_pid]++;
+	    sched_ctl->tbcnt[pCCid][harq_pid]=1;
+	  }
+	  else
+ 	    sched_ctl->round[pCCid][harq_pid]++;
+
+	  if (pdu[2] == 1) sched_ctl->round[1-pCCid][harq_pid]=8;
+	  else             sched_ctl->round[1-pCCid][harq_pid]++;
+	} // A=3 primary cell has 2 TBs
+	else if ((num_ack_nak == 3) && (sched_ctl->round[1-pCCid][harq_pid]<8) && (sched_ctl->round[pCCid][harq_pid]<8) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==2) && (sched_ctl->tbcnt[pCCid][harq_pid]==1)) {
+	  AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]);
+	  AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]);
+	  AssertFatal(pdu[2]<=3,"pdu[2] %d is not ACK/NAK/DTX\n",pdu[2]);
+	  AssertFatal(sched_ctl->tbcnt[1-pCCid][harq_pid] == 2,"sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n",1-pCCid,harq_pid,UE_id,rnti);
+	  AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1,"sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n",pCCid,harq_pid,UE_id,rnti);
+	  if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK
+	      sched_ctl->round[1-pCCid][harq_pid]=8;
+	      sched_ctl->tbcnt[1-pCCid][harq_pid]=0;
+	  }
+	  else if (((pdu[0] >= 2) && (pdu[1] == 1))||
+		   ((pdu[0] == 1) && (pdu[1] >= 2))){ // one ACK
+	    sched_ctl->round[1-pCCid][harq_pid]++;
+	    sched_ctl->tbcnt[1-pCCid][harq_pid]=1;
+	  }
+	  else  // both NAK/DTX
+ 	    sched_ctl->round[1-pCCid][harq_pid]++;
+
+	  if (pdu[2] == 1) sched_ctl->round[pCCid][harq_pid]=8;
+	  else             sched_ctl->round[pCCid][harq_pid]++;
+	} // A=3 secondary cell has 2 TBs
+#if MAX_NUM_CCs>1
+	else if ((num_ack_nak == 4) && (sched_ctl->round[0][harq_pid]<8) && (sched_ctl->round[1][harq_pid]<8) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==2) && (sched_ctl->tbcnt[pCCid][harq_pid]==2)) {
+	  AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]);
+	  AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]);
+	  AssertFatal(pdu[2]<=3,"pdu[2] %d is not ACK/NAK/DTX\n",pdu[2]);
+	  AssertFatal(pdu[3]<=3,"pdu[3] %d is not ACK/NAK/DTX\n",pdu[3]);
+	  AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2,"sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n",harq_pid,UE_id,rnti);
+	  AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2,"sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n",harq_pid,UE_id,rnti);
+	  if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK
+	      sched_ctl->round[0][harq_pid]=8;
+	      sched_ctl->tbcnt[0][harq_pid]=0;
+	  }
+	  else if (((pdu[0] >= 2) && (pdu[1] == 1))||
+		   ((pdu[0] == 1) && (pdu[1] >= 2))){ // one ACK
+	    sched_ctl->round[0][harq_pid]++;
+	    sched_ctl->tbcnt[0][harq_pid]=1;
+	  }
+	  else  // both NAK/DTX
+ 	    sched_ctl->round[0][harq_pid]++;
+
+	  if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK
+	      sched_ctl->round[1][harq_pid]=8;
+	      sched_ctl->tbcnt[1][harq_pid]=0;
+	  }
+	  else if (((pdu[2] >= 2) && (pdu[3] == 1))||
+		   ((pdu[2] == 1) && (pdu[3] >= 2))){ // one ACK
+	    sched_ctl->round[1][harq_pid]++;
+	    sched_ctl->tbcnt[1][harq_pid]=1;
+	  }
+	  else  // both NAK/DTX
+ 	    sched_ctl->round[1][harq_pid]++;
+	} // A=4 both serving cells have 2 TBs 
+#endif
+	break;
+      case 2: // Format 3
+	AssertFatal(numCC>2,"Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n",
+		    numCC);
+	for (i=0,j=0;i<numCC;i++) {
+	  if ((sched_ctl->round[i][harq_pid]<8)) {
+	    if (tmode[i]==1 || tmode[i]==2 || tmode[0]==5 || tmode[0]==6 || tmode[0]==7) {
+	      if (pdu[j] == 1) { 
+		sched_ctl->round[i][harq_pid]=8;
+		sched_ctl->tbcnt[i][harq_pid]=0;
+	      }
+	      else if (pdu[j] == 2) sched_ctl->round[i][harq_pid]++;
+	      else AssertFatal(1==0,"Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n",
+			       i,harq_pid,pdu[j],UE_id,rnti);
+	      j++;
+	    }
+	    else if (spatial_bundling == 0) {
+	      if      ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 1) && (pdu[j+1]==1)) {
+		sched_ctl->round[i][harq_pid]=8;
+		sched_ctl->tbcnt[i][harq_pid]=0;
+	      }
+	      else if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 1) && (pdu[j+1]==2)) {
+		sched_ctl->round[i][harq_pid]++;
+		sched_ctl->tbcnt[i][harq_pid]=1;
+	      }
+	      else if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 2) && (pdu[j+1]==1)) {
+		sched_ctl->round[i][harq_pid]++;
+		sched_ctl->tbcnt[i][harq_pid]=1;
+	      }
+	      else if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 2) && (pdu[j+1]==2)) {
+		sched_ctl->round[i][harq_pid]++;
+	      }
+	      else AssertFatal(1==0,"Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n",
+			       i,harq_pid,sched_ctl->tbcnt[i][harq_pid],pdu[j],pdu[j+1],UE_id,rnti);
+	      j+=2;
+	    }
+	    else if (spatial_bundling == 1) {
+	      if      (pdu[j] == 1) {
+		sched_ctl->round[i][harq_pid]=8;
+		sched_ctl->tbcnt[i][harq_pid]=0;
+	      }
+	      else if (pdu[j] == 2) {
+		sched_ctl->round[i][harq_pid]++;
+	      }
+	      else AssertFatal(1==0,"Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n",
+			       pdu[j],i,harq_pid,UE_id,rnti);
+	      j++;
+	    }
+	    else AssertFatal(1==0,"Illegal value for spatial_bundling %d\n",spatial_bundling);
+	  }
+	}
+	break;
+      case 3: // Format 4
+	AssertFatal(1==0,"Should not receive harq indication with Format 4\n");
+	break;
+      case 4: // Format 5
+	AssertFatal(1==0,"Should not receive harq indication with Format 5\n");
+	break;
+    }
+  }
+}
+void extract_pucch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length) {
+
+  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  COMMON_channels_t *cc=&RC.mac[mod_idP]->common_channels[CC_idP];
+  struct CQI_ReportPeriodic *cqi_ReportPeriodic;
+  int no_pmi;
+  uint8_t Ltab[6] = {0,2,4,4,4,4};
+  uint8_t Jtab[6] = {0,2,2,3,4,4};
+  int feedback_cnt;
+
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL,"cqi_ReportConfig is null for UE %d\n",UE_id);
+  AssertFatal((cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL,
+	      "cqi_ReportPeriodic is null for UE %d\n",UE_id);
+  
+  // determine feedback mode
+  AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING,
+	      "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n");
+  AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING,
+	      "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n");
+
+  uint16_t Npd,N_OFFSET_CQI;
+  int H,K,bandwidth_part,L,Lmask;
+  int ri    = sched_ctl->periodic_ri_received[CC_idP];
+  
+  get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H);
+  K            =(H-1)/Jtab[cc->mib->message.dl_Bandwidth];
+  L            = Ltab[cc->mib->message.dl_Bandwidth];
+  Lmask        =L-1;
+  feedback_cnt = (((frameP*10)+subframeP)/Npd)%H;
+
+  if (feedback_cnt>0) bandwidth_part = (feedback_cnt-1)%K;
+  else                bandwidth_part = 0;
+
+  switch(get_tmode(mod_idP,CC_idP,UE_id)) {
+  case 1:
+  case 2:
+  case 3:
+  case 7:
+    no_pmi=1;
+    break;
+  case 4:
+  case 5:
+  case 6:
+    no_pmi=0;
+    break;
+  default:
+    // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213)
+    no_pmi=0;
+  }
+          
+  if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) || 
+      (feedback_cnt==0)){
+      // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI)
+
+    if (no_pmi == 1) { // get spatial_diffcqi if needed
+      sched_ctl->periodic_wideband_cqi[CC_idP]             = pdu[0]&0xF;
+      sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0]>>4)&7;
+    }
+    else if ((cc->p_eNB==2) && (ri==1))  {
+      // p=2 Rank 1 wideband CQI/PMI 6 bits
+      sched_ctl->periodic_wideband_cqi[CC_idP]             = pdu[0]&0xF;
+      sched_ctl->periodic_wideband_pmi[CC_idP]             = (pdu[0]>>4)&3;
+    }
+    else if ((cc->p_eNB==2) && (ri>1)) {
+      // p=2 Rank 2 wideband CQI/PMI 8 bits
+      sched_ctl->periodic_wideband_cqi[CC_idP]             = pdu[0]&0xF;
+      sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0]>>4)&7;
+      sched_ctl->periodic_wideband_pmi[CC_idP]             = (pdu[0]>>7)&1;
+    }
+    else if ((cc->p_eNB==4) && (ri==1)) {
+      // p=4 Rank 1 wideband CQI/PMI 8 bits
+      sched_ctl->periodic_wideband_cqi[CC_idP]             = pdu[0]&0xF;
+      sched_ctl->periodic_wideband_pmi[CC_idP]             = (pdu[0]>>4)&0x0F;
+
+    }
+    else if ((cc->p_eNB==4) && (ri>1)) {
+      // p=4 Rank 2 wideband CQI/PMI 11 bits
+      sched_ctl->periodic_wideband_cqi[CC_idP]             = pdu[0]&0xF;
+      sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0]>>4)&7;
+      sched_ctl->periodic_wideband_pmi[CC_idP]             = (pdu[0]>>7)&0xF;
+    }
+    else AssertFatal(1==0,"illegal combination p %d, ri %d, no_pmi %d\n",cc->p_eNB,ri,no_pmi);
+  }
+  else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) {
+    // This is Table 5.2.3.3.2-2 for 36.213
+    if (ri==1) {
+      //4+Ltab[cc->mib->message.dl_Bandwidth] bits
+      sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part*L)+((pdu[0]>>4)&Lmask)]              = pdu[0]&0xF;
+    }
+    else if (ri>1) {
+      //7+Ltab[cc->mib->message.dl_Bandwidth] bits;    
+      sched_ctl->periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part*L)+((pdu[0]>>7)&Lmask)]  = (pdu[0]>>4)&7;
+      sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part*L)+((pdu[0]>>7)&Lmask)]              = pdu[0]&0xF;
+    }
+  }
+}
+
+void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length) {
+
+  UE_list_t *UE_list    = &RC.mac[mod_idP]->UE_list;
+  COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; 
+  UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  int Ntab[6]       = {0,4,7,9,10,13};
+  int Ntab_uesel[6] = {0,8,13,17,19,25};
+  int Ltab_uesel[6] = {0,6,9,13,15,18};
+  int Mtab_uesel[6] = {0,1,3,5,6,6};
+  int v[6];
+  int i;
+  uint64_t p = *(uint64_t*)pdu;
+  CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic;
+
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
+  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL,"cqi_ReportConfig is null for UE %d\n",UE_id);
+  AssertFatal((cqi_ReportModeAperiodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic)!=NULL,
+	      "cqi_ReportModeAperiodic is null for UE %d\n",UE_id);
+
+  int N     = Ntab[cc->p_eNB];
+  int tmode = get_tmode(mod_idP,CC_idP,UE_id);
+  int ri    = sched_ctl->aperiodic_ri_received[CC_idP];
+  int r,diffcqi0=0,diffcqi1=0,pmi_uesel=0;
+  int bw = cc->mib->message.dl_Bandwidth;
+  int m;
+
+  switch(*cqi_ReportModeAperiodic) {
+
+  case CQI_ReportModeAperiodic_rm12:
+    // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6)
+    AssertFatal(tmode==4 || tmode==6 || tmode==8|| tmode==9 || tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n",tmode);
+    if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213
+      if ((ri==1) && (cc->p_eNB==2)) { 
+	sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+	for (i=0;i<N;i++) {
+	  sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x03);
+	  p>>=2;
+	}
+      }
+      if ((ri==2) && (cc->p_eNB==2)) { 
+	sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+	sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+	for (i=0;i<N;i++) {
+	  sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01);
+	  p>>=1;
+	}
+      }
+      if ((ri==1) && (cc->p_eNB==4)) { 
+	sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+	for (i=0;i<N;i++) {
+	  sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x03);
+	  p>>=4;
+	}
+      }
+      if ((ri==2) && (cc->p_eNB==4)) { 
+	sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+	sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+	for (i=0;i<N;i++) {
+	  sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01);
+	  p>>=4;
+	}
+      }
+    } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213
+    else {
+      AssertFatal(1==0,"support for TM 8-10 to be done\n");
+    }
+
+   break;
+  case CQI_ReportModeAperiodic_rm20:
+    // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 
+    AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n",tmode);
+
+    sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+    diffcqi0 = (uint8_t)(p&0x03); p>>=2;
+    r = (uint8_t)(p&((1>>Ltab_uesel[bw])-1));
+    reverse_index(Ntab_uesel[bw],Mtab_uesel[bw],r,v);
+    for (m=0;m<Mtab_uesel[bw];m++) sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0;
+    break;
+  case CQI_ReportModeAperiodic_rm22:
+    // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213
+
+    AssertFatal(tmode==4 || tmode==6 || tmode==8|| tmode==9 || tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n",tmode);
+
+    sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+    diffcqi0 = (uint8_t)(p&0x03); p>>=2;
+    
+    if (ri>1) {
+      sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      diffcqi1 = (uint8_t)(p&0x03); p>>=2;
+    }
+    r = (uint8_t)(p&((1>>Ltab_uesel[bw])-1)); p>>=Ltab_uesel[bw];
+    reverse_index(Ntab_uesel[bw],Mtab_uesel[bw],r,v);
+    if ((ri==1)&&(cc->p_eNB==2)) {
+      pmi_uesel                                  = p&0x3; p>>=2;
+      sched_ctl->aperiodic_wideband_pmi[CC_idP]  = p&0x3;
+    }
+    else if ((ri==2)&&(cc->p_eNB==2)) {
+      pmi_uesel                                  = p&0x1; p>>=1;
+      sched_ctl->aperiodic_wideband_pmi[CC_idP]  = p&0x1;
+    }
+    else if (cc->p_eNB==4) {
+      pmi_uesel                                  = p&0x0F; p>>=4;
+      sched_ctl->aperiodic_wideband_pmi[CC_idP]  = p&0x0F;
+    }
+    for (m=0;m<Mtab_uesel[bw];m++) { 
+      sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0;
+      if (ri>1) sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = diffcqi1;
+      sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]]      = pmi_uesel;
+    }
+    break;
+  case CQI_ReportModeAperiodic_rm30:
+    //subband CQI no PMI (TM1/2/3/7)
+    AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n",tmode);
+    sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+    for (i=0;i<N;i++) {
+      sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03);
+      p>>=2;
+    }
+    break;
+  case CQI_ReportModeAperiodic_rm31:
+    //subband CQI single PMI (TM4/5/6)
+    AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n",tmode);
+
+    if ((ri==1) && (cc->p_eNB==2)) { 
+      sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      for (i=0;i<N;i++) {
+	sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03);
+	p>>=2;
+      }
+      sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x03;
+    }
+    if ((ri==2) && (cc->p_eNB==2)) { 
+      sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      for (i=0;i<N;i++) {
+	sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01);
+	p>>=1;
+      }
+      sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      for (i=0;i<N;i++) {
+	sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01);
+	p>>=1;
+      }
+      sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x01;
+    }
+    if ((ri==1) && (cc->p_eNB==4)) { 
+      sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      for (i=0;i<N;i++) {
+	sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03);
+	p>>=2;
+      }
+      sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x0F;
+    }
+    if ((ri>1) && (cc->p_eNB==4)) { // Note : 64 bits for 20 MHz
+      sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      for (i=0;i<N;i++) {
+	sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01);
+	p>>=1;
+      }
+      sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+      for (i=0;i<N;i++) {
+	sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01);
+	p>>=2;
+      }
+      sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x0F;
+    }
+    
+    break;
+  case CQI_ReportModeAperiodic_rm32_v1250:
+    AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n",tmode);
+    AssertFatal(1==0,"CQI_ReportModeAperiodic_rm32 to be done\n");
+    break;
+  case CQI_ReportModeAperiodic_rm10_v1310:
+    AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n",tmode);
+    AssertFatal(1==0,"CQI_ReportModeAperiodic_rm10 to be done\n");
+    break;
+  case CQI_ReportModeAperiodic_rm11_v1310:
+    AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n",tmode);
+    AssertFatal(1==0,"CQI_ReportModeAperiodic_rm11 to be done\n");
+    break;
+  }
+
+  
+}
+
+void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, 
+		    nfapi_cqi_indication_rel9_t *rel9,uint8_t *pdu,
+		    nfapi_ul_cqi_information_t *ul_cqi_information) {
+
+  int UE_id = find_UE_id(mod_idP, rntiP);
+  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+
+  if (UE_id  >= 0) {
+
+    if (ul_cqi_information->channel == 0) { // PUCCH
+
+      // extract pucch csi information before changing RI information
+      extract_pucch_csi(mod_idP,CC_idP,UE_id,frameP,subframeP,pdu,rel9->length);
+
+      memcpy((void*)sched_ctl->periodic_ri_received,
+	     (void*)rel9->ri,
+	     rel9->number_of_cc_reported);
+
+      // SNR for PUCCH2
+      sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi;
+    }
+    else { //PUSCH
+      memcpy((void*)sched_ctl->aperiodic_ri_received,
+	     (void*)rel9->ri,
+	     rel9->number_of_cc_reported);
+
+      extract_pusch_csi(mod_idP,CC_idP,UE_id,frameP,subframeP,pdu,rel9->length);
+      
+    }
+
+    // timing advance
+    sched_ctl->timing_advance    = rel9->timing_advance;
+    sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; 
+  }
+}
+
+void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, uint8_t ul_cqi)
 {
  
   int UE_id = find_UE_id(mod_idP, rntiP);
@@ -2003,7 +3493,7 @@ void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP
  
   if (UE_id  != -1) {
     if (mac_eNB_get_rrc_status(mod_idP,UE_RNTI(mod_idP,UE_id)) < RRC_CONNECTED)
-      LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
+      LOG_I(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
     UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
     UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION,1);
@@ -2033,3 +3523,21 @@ void UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti
     LOG_W(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
   }
 }
+
+void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_harq_indication_pdu_t *harq_pdu) {
+
+
+  rnti_t rnti              = harq_pdu->rx_ue_information.rnti;
+  uint8_t ul_cqi           = harq_pdu->ul_cqi_information.ul_cqi;
+  uint8_t channel          = harq_pdu->ul_cqi_information.channel;
+  int UE_id                = find_UE_id(mod_idP, rnti);
+  UE_list_t *UE_list       = &RC.mac[mod_idP]->UE_list;
+  UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  COMMON_channels_t *cc    = &RC.mac[mod_idP]->common_channels[CC_idP];
+    // extract HARQ Information
+  LOG_I(MAC,"Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x\n",frameP,subframeP,channel,UE_id,rnti);
+  if (cc->tdd_Config) extract_harq(mod_idP,CC_idP,UE_id,frameP,subframeP,(void*)&harq_pdu->harq_indication_tdd_rel13,channel);
+  else                extract_harq(mod_idP,CC_idP,UE_id,frameP,subframeP,(void*)&harq_pdu->harq_indication_fdd_rel13,channel);
+  if (channel == 0)     sched_ctl->pucch1_snr[CC_idP] = ul_cqi;
+
+}
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index bd0ef80011d749353eb6dd2b65d821953a50beb8..0c49914bf568b9e64f7503b1e73178e03cf2dc6f 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -133,7 +133,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
 		"maxHARQ %d should be greater than 1\n",
 		(int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
 
-    if (sduP==NULL) { // we've got an error
+    if (sduP==NULL) { // we've got an error on Msg3
       LOG_I(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id,
 	    RA_template[RA_id].msg3_round,
 	    (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
@@ -145,6 +145,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
       // prepare handling of retransmission
       RA_template[RA_id].Msg3_frame += ((RA_template[RA_id].Msg3_subframe>1) ? 1 : 0);
       RA_template[RA_id].Msg3_subframe = (RA_template[RA_id].Msg3_subframe+8)%10;
+      add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP);
       return;
     }
   }
@@ -333,7 +334,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
   }
 
   for (i=0; i<num_sdu; i++) {
-    LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
+    LOG_I(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
 
     T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
       T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
@@ -343,8 +344,8 @@ void rx_sdu(const module_id_t enb_mod_idP,
     switch (rx_lcids[i]) {
     case CCCH :
       if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
-        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d), dropping packet\n",
-              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX);
+        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
+              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP);
         break;
       }
       LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
@@ -407,7 +408,17 @@ void rx_sdu(const module_id_t enb_mod_idP,
 	  // prepare transmission of Msg4
           RA_template->generate_Msg4 = 1;
           RA_template->wait_ack_Msg4 = 0;
-	  
+	  // Program ACK for PHICH
+	  LOG_I(MAC,"Programming PHICH ACK for Msg3 rnti %x\n",RA_template->rnti);
+	  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body;
+	  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; 	
+	  memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
+	  hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
+	  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
+	  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = RA_template->msg3_first_rb; 
+	  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
+	  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 1;
+	  hi_dci0_req->number_of_hi++;
 	  // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
 	  RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
 	  RA_template->Msg4_subframe = (subframeP+4)%10;
@@ -786,7 +797,7 @@ void schedule_ulsch(module_id_t module_idP,
 void schedule_ulsch_rnti(module_id_t   module_idP,
                          frame_t       frameP,
                          sub_frame_t   subframeP,
-                         unsigned char sched_subframe,
+                         unsigned char sched_subframeP,
                          uint16_t     *first_rb)
 {
 
@@ -812,8 +823,22 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
   UE_list_t         *UE_list=&eNB->UE_list;
   UE_TEMPLATE       *UE_template;
   UE_sched_ctrl     *UE_sched_ctrl;
-  nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
-  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
+  int               tmode;
+  int               sched_frame=frameP;
+
+  if (sched_subframeP<subframeP) sched_frame++;
+
+  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
+  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
+
+  nfapi_ul_config_request_pdu_t  *ul_config_pdu;
+
+
+
+  nfapi_ul_config_request_body_t *ul_req_tmp       = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body;
+
+  ul_config_pdu                                    = &ul_req_tmp->ul_config_pdu_list[0]; 
+
 
   LOG_D(MAC,"entering ulsch preprocesor\n");
   ulsch_scheduler_pre_processor(module_idP,
@@ -823,9 +848,9 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
 
   LOG_D(MAC,"exiting ulsch preprocesor\n");
 
-  eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<3)+subframeP;
-  hi_dci0_req->number_of_dci     = 0;
-  hi_dci0_req->number_of_hi      = 0;
+  eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
+
+
   // loop over all active UEs
   for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) {
 
@@ -904,8 +929,8 @@ abort();
 
       UE_template   = &UE_list->UE_template[CC_id][UE_id];
       UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
-      harq_pid = subframe2harqpid(&cc[CC_id],frameP,subframeP);
-      round    = UE_sched_ctrl->round_UL[harq_pid][CC_id];
+      harq_pid      = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframeP);
+      round         = UE_sched_ctrl->round_UL[harq_pid][CC_id];
       /*      
       if (get_UL_harq_info(module_idP,CC_id,frameP,subframeP,&harq_pid,&round)<0) {
 	LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
@@ -1049,13 +1074,85 @@ abort();
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1             = ndi;
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc                               = tpc;
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request                   = cqi_req;
-	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index               = UE_template->DAI_ul[sched_subframe];
+	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index               = UE_template->DAI_ul[sched_subframeP];
 
 	    if (!CCE_allocation_infeasible(module_idP,CC_id,2,subframeP,
 					   aggregation,
-					   rnti))
+					   rnti)) {
+
 	      eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
-		
+
+	      LOG_I(MAC,"Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
+		    frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP);
+
+	      // Add UL_config PDUs
+	      ul_config_pdu                                                                  = &ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus]; 
+	      
+	      memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+	      if (cqi_req==0)
+		ul_config_pdu->pdu_type                                                      = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
+	      else
+		ul_config_pdu->pdu_type                                                      = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; 
+	      ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = rnti;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = first_rb[CC_id];
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = rb_table[rb_table_index];
+	      if      (mcs<11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 2;
+	      else if (mcs<21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 4;
+	      else             ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 6;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = cshift;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = ndi;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = 0;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = harq_pid;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 0;
+	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(mcs,
+													  rb_table[rb_table_index]);
+#ifdef Rel14
+	      // Re13 fields
+	      if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
+		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                               = UE_template->rach_resource_type>2 ? 2 : 1;
+		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions           = 1;
+		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number                     = 1;
+		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io            = (frameP*10)+subframeP;
+	      }
+#endif
+	      ul_req_tmp->number_of_pdus++;
+	      
+	      if (cqi_req == 1) {
+		// Add CQI portion 
+		tmode = get_tmode(module_idP,CC_id,UE_id);
+						
+		ul_config_pdu->pdu_type                                                           = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; 
+		ul_config_pdu->pdu_size                                                           = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu));
+		((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.report_type             = 1;
+		((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1;
+		if (cc->p_eNB<=2 && (tmode==3||tmode==4||tmode==8||tmode==9||tmode==10))
+		  ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1;
+		else if (cc->p_eNB<=2) 
+		  ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0;
+		else if (cc->p_eNB==4)
+		  ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2;
+
+		AssertFatal(UE_template->physicalConfigDedicated->cqi_ReportConfig!=NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n");
+		AssertFatal(UE_template->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic!=NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n");
+		AssertFatal(UE_template->physicalConfigDedicated->pusch_ConfigDedicated!=NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n");
+		for (int ri=0;ri<(1<<((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size);ri++)
+		  ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = 
+		    get_dl_cqi_pmi_size_pusch(&UE_list->UE_sched_ctrl[UE_id],
+					      cc,
+					      tmode,
+					      1+ri,
+					      UE_template->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic);
+
+		((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi        = UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
+		((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri         = UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
+	      }
+	    }	
 	    add_ue_ulsch_info(module_idP,
 			      CC_id,
 			      UE_id,
@@ -1080,7 +1177,6 @@ abort();
 	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = UE_template->cshift[harq_pid];
 	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 0;
 	    hi_dci0_req->number_of_hi++;
-
             LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d,round %d)\n",
                   module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
                   UE_template->first_rb_ul[harq_pid], UE_template->nb_rb_ul[harq_pid],
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 6e5fa91f1452501c54bdb2813bf67158a766fd67..ae4b52222d59daa436b61eedd5795a2ac13527e7 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -175,11 +175,20 @@ int mac_top_init_eNB()
       for (j=0;j<MAX_NUM_CCs;j++) {
 	RC.mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list      = RC.mac[i]->dl_config_pdu_list[j];
 	RC.mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list      = RC.mac[i]->ul_config_pdu_list[j];
+	for (int k=0;k<10;k++) RC.mac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list   = RC.mac[i]->ul_config_pdu_list_tmp[j][k];
 	RC.mac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list     = RC.mac[i]->hi_dci0_pdu_list[j];
 	RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list                    = RC.mac[i]->tx_request_pdu[j];
 	RC.mac[i]->ul_handle                                                = 0;
       }
     }
+
+    AssertFatal(rlc_module_init()==0,"Could not initialize RLC layer\n");
+
+    // These should be out of here later
+    pdcp_layer_init ();
+
+    rrc_init_global_param();
+
   } else {
     RC.mac = NULL;
   }
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index 7c77bf87297f757a53f067b21f844ec8a01a13d6..4bcda249e9520c31926ff4b0ffe8cce57f6d6bcf 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -263,13 +263,19 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin
 {
 
   uint8_t round,round_max=0,UE_id;
-  int CC_id;
+  int CC_id,harq_pid;
   UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
+  COMMON_channels_t *cc;
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
+    cc = &RC.mac[Mod_id]->common_channels[CC_id];
+
     UE_id = find_UE_id(Mod_id,rnti);
-    round    = UE_list->UE_sched_ctrl[UE_id].round[CC_id];
+    if (cc->tdd_Config) harq_pid = ((frame*10)+subframe)%10;
+    else harq_pid = ((frame*10)+subframe)&7;
+
+    round    = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid];
     if (round > round_max) {
       round_max = round;
     }
@@ -507,9 +513,10 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
   int transmission_mode = 0;
   UE_sched_ctrl *ue_sched_ctl;
   //  int rrc_status           = RRC_IDLE;
+  COMMON_channels_t *cc;
 
 #ifdef TM5
-  int harq_pid1=0,harq_pid2=0;
+  int harq_pid1=0;
   int round1=0,round2=0;
   int UE_id2;
   uint16_t                i1,i2,i3;
@@ -581,12 +588,10 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
     for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
       CC_id = UE_list->ordered_CCids[ii][UE_id];
       ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-      harq_pid = ue_sched_ctl->harq_pid[CC_id];
-      round    = ue_sched_ctl->round[CC_id];
-
-      // if there is no available harq_process, skip the UE
-      if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
-        continue;
+      cc=&RC.mac[Mod_id]->common_channels[ii];
+      if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
+      else harq_pid = ((frameP*10)+subframeP)&7;
+      round    = ue_sched_ctl->round[CC_id][harq_pid];
 
       average_rbs_per_user[CC_id]=0;
 
@@ -681,8 +686,7 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
         for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
           CC_id = UE_list->ordered_CCids[ii][UE_id];
 	  ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-	  harq_pid = ue_sched_ctl->harq_pid[CC_id];
-	  round    = ue_sched_ctl->round[CC_id];
+	  round    = ue_sched_ctl->round[CC_id][harq_pid];
 
           rnti = UE_RNTI(Mod_id,UE_id);
 
@@ -731,7 +735,6 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
                   UE_id2 = ii;
                   rnti2 = UE_RNTI(Mod_id,UE_id2);
 		  ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2];
-		  harq_pid2 = ue_sched_ctl2->harq_pid[CC_id];
 		  round2    = ue_sched_ctl2->round[CC_id];
                   if(rnti2 == NOT_A_RNTI)
                     continue;
@@ -887,7 +890,7 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
 #endif
 
 
-  LOG_I(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti);
+  LOG_D(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti);
   // initialize harq_pid and round
 
   /*
@@ -1078,11 +1081,11 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
   UE_TEMPLATE        *UE_template               = 0;
   int                N_RB_DL;
   int                N_RB_UL;
-  //LOG_I(MAC,"assign max mcs min rb\n");
+  LOG_D(MAC,"In ulsch_preprocessor: assign max mcs min rb\n");
   // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB
   assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb);
 
-  //LOG_I(MAC,"sort ue \n");
+  LOG_D(MAC,"In ulsch_preprocessor: sort ue \n");
   // sort ues
   sort_ue_ul (module_idP,frameP, subframeP);
 
@@ -1101,7 +1104,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
     }
   }
 
-  //LOG_I(MAC,"step2 \n");
+  LOG_D(MAC,"In ulsch_preprocessor: step2 \n");
   // step 2: calculate the average rb per UE
   total_ue_count =0;
   max_num_ue_to_be_scheduled=0;
@@ -1119,9 +1122,11 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
 
     UE_id = i;
 
+    LOG_D(MAC,"In ulsch_preprocessor: handling UE %d/%x\n",UE_id,rnti);
     for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
       // This is the actual CC_id in the list
       CC_id = UE_list->ordered_ULCCids[n][UE_id];
+      LOG_D(MAC,"In ulsch_preprocessor: handling UE %d/%x CCid %d\n",UE_id,rnti,CC_id);
       UE_template = &UE_list->UE_template[CC_id][UE_id];
       average_rbs_per_user[CC_id]=0;
 
@@ -1174,6 +1179,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
       CC_id = UE_list->ordered_ULCCids[n][UE_id];
       harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id],frameP,subframeP);
 
+
       //      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL);
 
       if(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id]>0) {
@@ -1183,7 +1189,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
       }
 
       total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id];
-
+      LOG_D(MAC,"In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n",nb_allocated_rbs[CC_id][UE_id],UE_id,rnti,CC_id,harq_pid);
     }
   }
 
diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h
index 85eaca5b218087ce7b448b104f0414aa140eafa2..ac969cc02c4c768ed836e97fd7bd1a7d4667f670 100644
--- a/openair2/LAYER2/MAC/proto.h
+++ b/openair2/LAYER2/MAC/proto.h
@@ -29,6 +29,8 @@
 #ifndef __LAYER2_MAC_PROTO_H__
 #define __LAYER2_MAC_PROTO_H__
 
+#include "LAYER2/MAC/defs.h"
+
 /** \addtogroup _mac
  *  @{
  */
@@ -287,11 +289,14 @@ void rx_sdu(const module_id_t enb_mod_idP,
 
 
 /* \brief Function to indicate a scheduled schduling request (SR) was received by eNB.
-@param Mod_id Instance ID of eNB
+@param Mod_idP Instance ID of eNB
+@param CC_idP CC_id of received SR
+@param frameP of received SR
+@param subframeP Index of subframe where SR was received
 @param rnti RNTI of UE transmitting the SR
-@param subframe Index of subframe where SR was received
+@param ul_cqi SNR measurement of PUCCH (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps)
 */
-void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti, sub_frame_t subframe);
+void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe,rnti_t rnti,uint8_t ul_cqi);
 
 /* \brief Function to indicate a UL failure was detected by eNB PHY.
 @param Mod_id Instance ID of eNB
@@ -314,10 +319,7 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rn
 MCH_PDU *get_mch_sdu( module_id_t Mod_id, int CC_id, frame_t frame, sub_frame_t subframe);
 
 
-//added for ALU icic purpose
-uint32_t  Get_Cell_SBMap(module_id_t module_idP);
-void UpdateSBnumber(module_id_t module_idP);
-//end ALU's algo
+
 
 
 void        ue_mac_reset      (module_id_t module_idP,uint8_t eNB_index);
@@ -326,6 +328,7 @@ void        init_ue_sched_info(void);
 void        add_ue_ulsch_info (module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframe,UE_ULSCH_STATUS status);
 void        add_ue_dlsch_info (module_id_t module_idP, int CC_id,int UE_id, sub_frame_t subframe,UE_DLSCH_STATUS status);
 int         find_UE_id        (module_id_t module_idP, rnti_t rnti) ;
+int         find_RA_id        (module_id_t mod_idP, int CC_idP, rnti_t rntiP);
 rnti_t      UE_RNTI           (module_id_t module_idP, int UE_id);
 int         UE_PCCID          (module_id_t module_idP, int UE_id);
 uint8_t     find_active_UEs   (module_id_t module_idP);
@@ -896,11 +899,92 @@ int to_prb(int dl_Bandwidth);
 uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
 			frame_t frame,
 			sub_frame_t current_subframe);
+
+uint32_t pdcchalloc2ulframe(COMMON_channels_t *ccP,uint32_t frame, uint8_t n);
+
+uint8_t pdcchalloc2ulsubframe(COMMON_channels_t *ccP,uint8_t n);
+
 int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP);
 
-uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe);
+uint8_t getQm(uint8_t mcs);
 
+uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe);
 
+void get_srs_pos(COMMON_channels_t *cc,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
+
+void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_PMI_ConfigIndex,uint16_t *Npd,uint16_t *N_OFFSET_CQI,int *H);
+
+uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic);
+
+uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc,uint8_t tmode, uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic);
+void extract_pucch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP, uint8_t *pdu, uint8_t length);
+
+void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length);
+
+uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,uint16_t pdu_length, uint16_t *pdu_index, uint8_t *pdu );
+
+void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t frameP, sub_frame_t subframeP,uint8_t cce_idx);
+
+void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t *dl_req,
+			     uint16_t length,
+			     uint16_t pdu_index,
+			     uint16_t rnti,
+			     uint8_t resource_allocation_type,
+			     uint8_t virtual_resource_block_assignment_flag,
+			     uint16_t resource_block_coding,
+			     uint8_t modulation,
+			     uint8_t redundancy_version,
+			     uint8_t transport_blocks,
+			     uint8_t transport_block_to_codeword_swap_flag,
+			     uint8_t transmission_scheme,
+			     uint8_t number_of_layers,
+			     uint8_t number_of_subbands,
+			     //			     uint8_t codebook_index,
+			     uint8_t ue_category_capacity,
+			     uint8_t pa,
+			     uint8_t delta_power_offset_index,
+			     uint8_t ngap,
+			     uint8_t nprb,
+			     uint8_t transmission_mode,
+			     uint8_t num_bf_prb_per_subband,
+			     uint8_t num_bf_vector
+			     );
+
+void fill_nfapi_harq_information(module_id_t module_idP,
+				 int CC_idP,
+				 uint16_t rntiP,
+				 uint16_t absSFP,
+				 nfapi_ul_config_harq_information *harq_information,
+				 uint8_t cce_idxP);
+
+void fill_nfapi_ulsch_harq_information(module_id_t module_idP,
+				       int CC_idP,
+				       uint16_t rntiP,
+				       nfapi_ul_config_ulsch_harq_information *harq_information);
+
+uint16_t fill_nfapi_uci_acknak(module_id_t module_idP,
+			       int CC_idP,
+			       uint16_t rntiP,
+			       uint16_t absSFP,
+			       uint8_t cce_idxP);
+
+void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t   *dl_config_pdu,
+			  uint8_t aggregation_level,
+			  uint16_t rnti,
+			  uint8_t rnti_type,
+			  uint8_t harq_process,
+			  uint8_t tpc,
+			  uint16_t resource_block_coding,
+			  uint8_t mcs,
+			  uint8_t ndi,
+			  uint8_t rv,
+			  uint8_t vrb_flag);
+
+nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t subframeP,uint16_t rnti);
+
+uint8_t get_tmode(module_id_t module_idP,int CC_idP,int UE_idP);
+
+uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP);
 
 #ifdef Rel14
 int get_numnarrowbandbits(long dl_Bandwidth);
diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c
index f9ccd4f9edaa45dce3eb96c6f6fe12b789034c0c..a225037e3b3f266bf86d9a8b2a31ac9a357137bf 100644
--- a/openair2/LAYER2/MAC/rar_tools.c
+++ b/openair2/LAYER2/MAC/rar_tools.c
@@ -62,8 +62,8 @@ unsigned short fill_rar(
   //  RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
   uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
   int i,ra_idx = -1;
-  uint16_t rballoc;
-  uint8_t mcs,TPC,ULdelay,cqireq;
+  RA_TEMPLATE *RA_template;
+
   AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs);
 
   for (i=0; i<NB_RA_PROC_MAX; i++) {
@@ -73,7 +73,8 @@ unsigned short fill_rar(
       break;
     }
   }
-
+  RA_template = &RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx];
+ 
   //DevAssert( ra_idx != -1 );
   if (ra_idx==-1)
     return(0);
@@ -81,52 +82,43 @@ unsigned short fill_rar(
   // subheader fixed
   rarh->E                     = 0; // First and last RAR
   rarh->T                     = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader
-  rarh->RAPID                 = RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment
-  /*
-  rar->R                      = 0;
-  rar->Timing_Advance_Command = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset/4;
-  rar->hopping_flag           = 0;
-  rar->rb_alloc               = mac_xface->computeRIV(N_RB_UL,12,2);  // 2 RB
-  rar->mcs                    = 2;                                   // mcs 2
-  rar->TPC                    = 4;   // 2 dB power adjustment
-  rar->UL_delay               = 0;
-  rar->cqi_req                = 1;
-  rar->t_crnti                = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti;
-   */
-  rar[4] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti>>8);
-  rar[5] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti&0xff);
-  //RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset = 0;
-  RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
-  rar[0] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
-  rar[1] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
-  rballoc = mac_computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant
+  rarh->RAPID                 = RA_template->preamble_index; // Respond to Preamble 0 only for the moment
+  rar[4] = (uint8_t)(RA_template->rnti>>8);
+  rar[5] = (uint8_t)(RA_template->rnti&0xff);
+  //RA_template->timing_offset = 0;
+  RA_template->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
+  rar[0] = (uint8_t)(RA_template->timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
+  rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
+  RA_template->msg3_first_rb=1;
+  RA_template->msg3_nb_rb=1;
+  uint16_t rballoc = mac_computeRIV(N_RB_UL,RA_template->msg3_first_rb,RA_template->msg3_nb_rb); // first PRB only for UL Grant
   rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
   rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc
-  mcs = 10;
-  TPC = 3;
-  ULdelay = 0;
-  cqireq = 0;
-  rar[2] |= ((mcs&0x8)>>3);  // mcs 10
-  rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1);
+  RA_template->msg3_mcs = 10;
+  RA_template->msg3_TPC = 3;
+  RA_template->msg3_ULdelay = 0;
+  RA_template->msg3_cqireq = 0;
+  rar[2] |= ((RA_template->msg3_mcs&0x8)>>3);  // mcs 10
+  rar[3] = (((RA_template->msg3_mcs&0x7)<<5)) | ((RA_template->msg3_TPC&7)<<2) | ((RA_template->msg3_ULdelay&1)<<1) | (RA_template->msg3_cqireq&1);
 
   LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n",
         module_idP, CC_id,
         frameP,
         *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5],
         ra_idx,
-        RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti,
+        RA_template->rnti,
         rarh->RAPID,RC.mac[module_idP]->common_channels[CC_id].RA_template[0].preamble_index,
-        RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset);
+        RA_template->timing_offset);
 
   if (opt_enabled) {
     trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1,
         RC.mac[module_idP]->frame, RC.mac[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, RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti,
+          module_idP, CC_id, frameP, RA_template->rnti,
           rarh->RAPID, input_buffer_length);
   }
 
-  return(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti);
+  return(RA_template->rnti);
 }
 
 #ifdef Rel14
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index 70104e8331ce20dc07168efc805def288238aed9..b05e983c30f99dfb2d76d1a2ddcdc63fe8053605 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -54,6 +54,52 @@ void handle_rach(UL_IND_t *UL_info) {
 #endif
 }
 
+void handle_sr(UL_IND_t *UL_info) {
+
+  int i;
+
+  for (i=0;i<UL_info->sr_ind.number_of_srs;i++) 
+    SR_indication(UL_info->module_id,
+		  UL_info->CC_id,
+		  UL_info->frame,
+		  UL_info->subframe,
+		  UL_info->sr_ind.sr_pdu_list[i].rx_ue_information.rnti,
+		  UL_info->sr_ind.sr_pdu_list[i].ul_cqi_information.ul_cqi);
+
+  UL_info->sr_ind.number_of_srs=0;
+}
+
+void handle_cqi(UL_IND_t *UL_info) {
+
+  int i;
+
+  for (i=0;i<UL_info->cqi_ind.number_of_cqis;i++) 
+    cqi_indication(UL_info->module_id,
+		   UL_info->CC_id,
+		   UL_info->frame,
+		   UL_info->subframe,
+		   UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti,
+		   &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9,
+		   UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu,
+		   &UL_info->cqi_ind.cqi_pdu_list[i].ul_cqi_information);
+
+  UL_info->cqi_ind.number_of_cqis=0;
+}
+
+void handle_harq(UL_IND_t *UL_info) {
+
+  int i;
+
+  for (i=0;i<UL_info->harq_ind.number_of_harqs;i++) 
+    harq_indication(UL_info->module_id,
+		    UL_info->CC_id,
+		    UL_info->frame,
+		    UL_info->subframe,
+		    &UL_info->harq_ind.harq_pdu_list[i]);
+
+  UL_info->harq_ind.number_of_harqs=0;
+}
+
 void handle_ulsch(UL_IND_t *UL_info) {
 
   int i;
@@ -70,12 +116,12 @@ void handle_ulsch(UL_IND_t *UL_info) {
 	   UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length,
 	   UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance,
 	   UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
-
   }
+    
   UL_info->rx_ind.number_of_pdus=0;
-
+  
   for (i=0;i<UL_info->crc_ind.number_of_crcs;i++) {
-
+    
     if (UL_info->crc_ind.crc_pdu_list[i].crc_indication_rel8.crc_flag == 1) { // CRC error indication
       LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe);
       rx_sdu(UL_info->module_id,
@@ -88,8 +134,8 @@ void handle_ulsch(UL_IND_t *UL_info) {
 	     0,
 	     0);
     }
-
- 
+    
+    
   }
   UL_info->crc_ind.number_of_crcs=0;
 }
@@ -121,9 +167,19 @@ void UL_indication(UL_IND_t *UL_info)
   ifi->CC_mask |= (1<<CC_id);
  
 
+  // clear DL/UL info for new scheduling round
+  clear_nfapi_information(RC.mac[module_id],CC_id,
+			  UL_info->frame,UL_info->subframe);
+
 
   handle_rach(UL_info);
 
+  handle_sr(UL_info);
+
+  handle_cqi(UL_info);
+
+  handle_harq(UL_info);
+
   // clear HI prior to hanling ULSCH
   mac->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi                     = 0;
   
@@ -143,13 +199,19 @@ void UL_indication(UL_IND_t *UL_info)
     sched_info->subframe    = (UL_info->subframe+4)%10;
     sched_info->DL_req      = &mac->DL_req[CC_id];
     sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id];
-    sched_info->UL_req      = &mac->UL_req[CC_id];
+    if ((mac->common_channels[CC_id].tdd_Config==NULL) ||
+	(is_UL_sf(&mac->common_channels[CC_id],(sched_info->subframe+4)%10)>0)) 
+      sched_info->UL_req      = &mac->UL_req[CC_id];
+    else
+      sched_info->UL_req      = NULL;
+
     sched_info->TX_req      = &mac->TX_req[CC_id];
     AssertFatal(ifi->schedule_response!=NULL,
 		"UL_indication is null (mod %d, cc %d)\n",
 		module_id,
 		CC_id);
     ifi->schedule_response(sched_info);
+
     LOG_D(PHY,"Schedule_response: frame %d, subframe %d (dl_pdus %d / %p)\n",sched_info->frame,sched_info->subframe,sched_info->DL_req->dl_config_request_body.number_pdu,
 	  &sched_info->DL_req->dl_config_request_body.number_pdu);
   }						 
diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h
index 80844b10c88da38da4f524a08bc90d7f383b3cc6..e33a8291e2eab88969a790df5d3d2ffc09269643 100644
--- a/openair2/PHY_INTERFACE/IF_Module.h
+++ b/openair2/PHY_INTERFACE/IF_Module.h
@@ -1,10 +1,4 @@
-
-/*This is the interface module between PHY
-*Provided the FAPI style interface structures for P7.
-*
-*
-*
-*//*
+/*
  * 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.
@@ -43,14 +37,6 @@
 #include "openair1/PHY/LTE_TRANSPORT/defs.h"
 #include "nfapi_interface.h"
 
-// uplink subframe P7
-
-
-	///
-
-/*UL_IND_t:
-* A structure handles all the uplink information.
-*/
 
 #define MAX_NUM_DL_PDU 100
 #define MAX_NUM_UL_PDU 100
diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c
index a67e86f808a2e67d38e4d51a6292d3c269dcaf1a..7d3cd347308f739a37a23f5676737fec82e1f873 100644
--- a/openair2/RRC/LITE/L2_interface.c
+++ b/openair2/RRC/LITE/L2_interface.c
@@ -84,7 +84,7 @@ mac_rrc_data_req(
   
 #ifdef DEBUG_RRC
   int i;
-  LOG_T(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id);
+  LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id);
 #endif
 
   eNB_RRC_INST *rrc;
@@ -218,7 +218,7 @@ mac_rrc_data_req(
 
       // check if data is there for MAC
       if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer
-        LOG_D(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload);
+        LOG_I(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload);
 
 #if defined(ENABLE_ITTI)
         {
@@ -504,9 +504,9 @@ mac_rrc_data_ind(
 
   } else { // This is an eNB
     Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
-    LOG_T(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
-
-#if defined(ENABLE_ITTI)
+    LOG_I(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
+    
+#if 0 //defined(ENABLE_ITTI)
     {
       MessageDef *message_p;
       int msg_sdu_size = sizeof(RRC_MAC_CCCH_DATA_IND (message_p).sdu);
@@ -526,6 +526,7 @@ mac_rrc_data_ind(
       RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
       memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
       memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size);
+      LOG_I(RRC,"[eNB %d] Sending message to RRC task\n",module_idP);
       itti_send_msg_to_task (TASK_RRC_ENB, ctxt.instance, message_p);
     }
 #else
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index 70f27a7cf5be22cd9cbc95c9f5c13f87776fe6cd..dcbbaf28d24550c17737377bd132f6adb1e95e45 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -1371,9 +1371,7 @@ do_RRCConnectionSetup(
     physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL;
   physicalConfigDedicated2->antennaInfo                   = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo));
   physicalConfigDedicated2->schedulingRequestConfig       = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig));
-#ifdef CBA
-  physicalConfigDedicated2->pusch_CBAConfigDedicated_vlola = CALLOC(1,sizeof(*physicalConfigDedicated2->pusch_CBAConfigDedicated_vlola));
-#endif
+
   // PDSCH
   //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a,
   //        PDSCH_ConfigDedicated__p_a_dB0);
diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c
index d9d7799270e4490849f7833b6b7644f54e9ce1b1..5c9d06f98630effb5175fd414decdd1c5953d20f 100644
--- a/openair2/RRC/LITE/rrc_common.c
+++ b/openair2/RRC/LITE/rrc_common.c
@@ -151,72 +151,9 @@ rrc_init_global_param(
   Rlc_info_am_config.rlc.rlc_am_info.t_poll_retransmit = 15;
   Rlc_info_am_config.rlc.rlc_am_info.t_reordering = 50;
   Rlc_info_am_config.rlc.rlc_am_info.t_status_prohibit = 10;
-#ifndef NO_RRM
-
-  if (L3_xface_init ()) {
-    return (-1);
-  }
-
-#endif
-
-  return 0;
-}
-
-#ifndef NO_RRM
-//-----------------------------------------------------------------------------
-int
-L3_xface_init(
-  void
-)
-//-----------------------------------------------------------------------------
-{
-
-  int ret = 0;
-
-#ifdef USER_MODE
 
-  int sock;
-  LOG_D(RRC, "[L3_XFACE] init de l'interface \n");
-
-  if (open_socket (&S_rrc, RRC_RRM_SOCK_PATH, RRM_RRC_SOCK_PATH, 0) == -1) {
-    return (-1);
-  }
-
-  if (S_rrc.s == -1) {
-    return (-1);
-  }
-
-  socket_setnonblocking (S_rrc.s);
-  msg ("Interface Connected... RRM-RRC\n");
   return 0;
-
-#else
-
-  ret=rtf_create(RRC2RRM_FIFO,32768);
-
-  if (ret < 0) {
-    msg("[openair][MAC][INIT] Cannot create RRC2RRM fifo %d (ERROR %d)\n",RRC2RRM_FIFO,ret);
-    return(-1);
-  } else {
-    msg("[openair][MAC][INIT] Created RRC2RRM fifo %d\n",RRC2RRM_FIFO);
-    rtf_reset(RRC2RRM_FIFO);
-  }
-
-  ret=rtf_create(RRM2RRC_FIFO,32768);
-
-  if (ret < 0) {
-    msg("[openair][MAC][INIT] Cannot create RRM2RRC fifo %d (ERROR %d)\n",RRM2RRC_FIFO,ret);
-    return(-1);
-  } else {
-    msg("[openair][MAC][INIT] Created RRC2RRM fifo %d\n",RRM2RRC_FIFO);
-    rtf_reset(RRM2RRC_FIFO);
-  }
-
-  return(0);
-
-#endif
 }
-#endif
 
 //-----------------------------------------------------------------------------
 void
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index c733ebdfd4a28b6bf62904875e6aad319e61419c..a8769c2690cd1c5e8a76c751bc927fe6b3f14538 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -3453,38 +3453,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
                      ue_context_pP->ue_context.kenb, &kRRCint);
 
 #endif
-#if ENABLE_RAL
-  {
-    MessageDef                         *message_ral_p = NULL;
-    rrc_ral_connection_reconfiguration_ind_t connection_reconfiguration_ind;
-    int                                 i;
-
-    message_ral_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_RAL_CONNECTION_RECONFIGURATION_IND);
-    memset(&connection_reconfiguration_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ind_t));
-    connection_reconfiguration_ind.ue_id = ctxt_pP->rnti;
-
-    if (DRB_configList != NULL) {
-      connection_reconfiguration_ind.num_drb = DRB_configList->list.count;
-
-      for (i = 0; (i < DRB_configList->list.count) && (i < maxDRB); i++) {
-        connection_reconfiguration_ind.drb_id[i] = DRB_configList->list.array[i]->drb_Identity;
-      }
-    } else {
-      connection_reconfiguration_ind.num_drb = 0;
-    }
-
-    if (SRB_configList != NULL) {
-      connection_reconfiguration_ind.num_srb = SRB_configList->list.count;
-    } else {
-      connection_reconfiguration_ind.num_srb = 0;
-    }
 
-    memcpy(&message_ral_p->ittiMsg, (void *)&connection_reconfiguration_ind,
-           sizeof(rrc_ral_connection_reconfiguration_ind_t));
-    LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_IND to RAL\n");
-    itti_send_msg_to_task(TASK_RAL_ENB, ctxt_pP->instance, message_ral_p);
-  }
-#endif
   // Refresh SRBs/DRBs
   MSC_LOG_TX_MESSAGE(
     MSC_RRC_ENB,
@@ -4423,7 +4392,7 @@ rrc_eNB_decode_dcch(
                sdu_sizeP,
                0,
                0);
-
+  /*
 #if defined(ENABLE_ITTI)
 #   if defined(DISABLE_ITTI_XER_PRINT)
   {
@@ -4452,7 +4421,7 @@ rrc_eNB_decode_dcch(
   }
 #   endif
 #endif
-
+  */
   {
     for (i = 0; i < sdu_sizeP; i++) {
       LOG_T(RRC, "%x.", Rx_sdu[i]);
@@ -4971,13 +4940,14 @@ rrc_enb_task(
 
   protocol_ctxt_t                     ctxt;
   itti_mark_task_ready(TASK_RRC_ENB);
-
+  LOG_I(RRC,"Entering main loop of RRC message task\n");
   while (1) {
     // Wait for a message
     itti_receive_msg(TASK_RRC_ENB, &msg_p);
 
     msg_name_p = ITTI_MSG_NAME(msg_p);
     instance = ITTI_MSG_INSTANCE(msg_p);
+    LOG_I(RRC,"Received message %s\n",msg_name_p);
 
     switch (ITTI_MSG_ID(msg_p)) {
     case TERMINATE_MESSAGE:
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index c28b9e839c4377755498fc5a1a87e5cef27b78b2..ef3124ff248b3878886b2111179691cf2268fd2f 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -98,19 +98,13 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
 #   endif
 
     if (enb_nb > 0) {
+      LOG_I(RRC,"Creating RRC eNB Task\n");
+
       if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
         LOG_E(RRC, "Create task for RRC eNB failed\n");
         return -1;
       }
 
-#   if ENABLE_RAL
-
-      if (itti_create_task (TASK_RAL_ENB, eRAL_task, NULL) < 0) {
-        LOG_E(RAL_ENB, "Create task for RAL eNB failed\n");
-        return -1;
-      }
-
-#   endif
     }
 
     if (ue_nb > 0) {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
index 218adf005050ee9fd017a027e418122450fffbf4..11abf64431734d84b34b7a3752cfcdd086c88270 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
@@ -195,8 +195,8 @@ L1s = (
 RUs = (
     {		  
       	local_if_name  = "lo";			  
-      	remote_address = "127.0.0.1";
-    	local_address  = "127.0.0.2"; 
+      	remote_address = "127.0.0.2";
+    	local_address  = "127.0.0.1"; 
     	local_portc    = 50000;	
     	remote_portc   = 50000;
     	local_portd    = 50001;	
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 386026690c60c4a4af75cbad6489ba52bcdb00b6..956914a38a70d901eb031124f3d5ed5697bb1570 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -940,6 +940,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
       LOG_I(PHY,"Setting indication lists\n");
       eNB->UL_INFO.rx_ind.rx_pdu_list   = eNB->rx_pdu_list;
       eNB->UL_INFO.crc_ind.crc_pdu_list = eNB->crc_pdu_list;
+      eNB->UL_INFO.sr_ind.sr_pdu_list = eNB->sr_pdu_list;
+      eNB->UL_INFO.harq_ind.harq_pdu_list = eNB->harq_pdu_list;
+      eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list;
+      eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
     }
 
   }