diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 785dcf760562deb7e0dd703a67bbad2e571a7104..02841b5e9b091bba7b708d87591fdede2c709e6e 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -280,7 +280,7 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
 
 # RRC
 ######
-add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA")
+add_list2_option(RRC_ASN1_VERSION "Rel14" "ASN.1 version of RRC interface" "Rel8" "Rel10" "Rel14" "CBA")
 
 if (${RRC_ASN1_VERSION} STREQUAL "Rel8")
   set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn)
@@ -2195,6 +2195,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
     ${XFORMS_SOURCE}
     ${T_SOURCE}
     ${CONFIG_SOURCES}
+    ${SHLIB_LOADER_SOURCES}
     )
   target_link_libraries (${myExe}
 
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index f5be69d3fa2caea77f0bf0ac28960600e761f5bf..d7b98bce413beb48f97f9447b80fe913c88618f1 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -626,12 +626,17 @@ function main() {
   if [ "$SIMUS_PHY" = "1" ] ; then
     # lte unitary simulators compilation
     echo_info "Compiling unitary tests simulators"
-    simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
+    # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
+    #simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
+    simlist="dlsim ulsim"
     for f in $simlist ; do
       compilations \
       lte-simulators $f \
 	  $f $dbin/$f.$REL
     done
+    compilations \
+          lte-simulators coding \
+          libcoding.so $dbin/libcoding.so
   fi
 
   # Core simulators
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 706cd05fe9ff084d62bf818aebf5e126c6e183dc..3bb051f2912a06eaddae332db052be2baa089272 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -210,7 +210,7 @@ install_protobuf_from_source(){
     #cd protobuf-2.6.1/
     rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
     wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
-    tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $USER --no-same-owner
+    tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner
     cd protobuf-3.3.0/
     ./configure
     echo "Compiling protobuf"
diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c
index 85b5fef5096a4ddabf4f0463ebb07d6675c2d3d0..1d38a3692b358d4cd52ef951cf9108cee905d188 100644
--- a/common/utils/itti/intertask_interface.c
+++ b/common/utils/itti/intertask_interface.c
@@ -325,8 +325,11 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
   /* Increment the global message number */
   message_number = itti_increment_message_number ();
 
+#if 0
+  /* itti dump is disabled */
   itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
                            sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
+#endif
 
   if (destination_task_id != TASK_UNKNOWN) {
 
@@ -421,8 +424,11 @@ int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance
   /* Increment the global message number */
   message_number = itti_increment_message_number ();
 
+#if 0
+  /* itti dump is disabled */
   itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
                            sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
+#endif
 
   if (destination_task_id != TASK_UNKNOWN) {
 
@@ -716,8 +722,11 @@ void itti_mark_task_ready(task_id_t task_id)
 
   AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max);
 
+#if 0
+  /* itti dump is disabled */
   /* Register the thread in itti dump */
   itti_dump_thread_use_ring_buffer();
+#endif
 
   /* Mark the thread as using LFDS queue */
   lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
@@ -848,7 +857,10 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i
   itti_desc.wait_tasks = 0;
   itti_desc.created_tasks = 0;
   itti_desc.ready_tasks = 0;
+#if 0
+  /* itti dump is disabled */
   itti_dump_init (messages_definition_xml, dump_file_name);
+#endif
 
   CHECK_INIT_RETURN(timer_init ());
 
@@ -915,7 +927,10 @@ void itti_wait_tasks_end(void)
     exit (0);
   }
 
+#if 0
+  /* itti dump is disabled */
   itti_dump_exit();
+#endif
 }
 
 void itti_send_terminate_message(task_id_t task_id)
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 6c2e580947da2ebde0616ccd04a83174e2ceefa4..780d3a1a6f830591cab59c0bb975c59f50d41fec 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1451,7 +1451,9 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
 
-void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) {
+/* release the harq if its round is >= 'after_rounds' */
+static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int after_rounds)
+{
 
   LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
@@ -1472,11 +1474,13 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
     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);
+    if (dlsch0_harq->round >= after_rounds) {
+      dlsch0_harq->status = SCH_IDLE;
+      /*if ((dlsch1_harq == NULL)||
+	  ((dlsch1_harq!=NULL)&&
+	   (dlsch1_harq->status == SCH_IDLE)))*/
+      dlsch0->harq_mask   &= ~(1<<harq_pid);
+    }
     LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti);
 
   }
@@ -1496,17 +1500,28 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
 	  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);
+          if (dlsch0_harq->round >= after_rounds) {
+	    dlsch0_harq->status = SCH_IDLE;
+	    if ((dlsch1_harq == NULL)||
+	        ((dlsch1_harq!=NULL)&&
+	         (dlsch1_harq->status == SCH_IDLE)))
+	      dlsch0->harq_mask   &= ~(1<<harq_pid);
+          }
 	}
       }
     }
   }
 }
 
+static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack)
+{
+  /* Maximum number of DL transmissions = 4.
+   * TODO: get the value from configuration.
+   * If is_ack is true then we release immediately. The value -1 can be used for that.
+   */
+  do_release_harq(eNB, UE_id, tb, frame, subframe, mask, is_ack ? -1 : 4);
+}
+
 int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
 
   int M,Mtx=0;
@@ -1607,7 +1622,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
 
       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);
+      release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
 
 #if T_TRACER
       /* TODO: get correct harq pid */
@@ -1633,13 +1648,17 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
 
       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);
+      /* TODO: review this code, it's most certainly wrong.
+       * We have to release the proper HARQ in case of ACK or NACK if max retransmission reached.
+       * Basically, call release_harq with 1 as last argument when ACK and 0 when NACK.
+       */
+      release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      if      (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
       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);
+	release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
+	release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
       }
     }	
   }
@@ -1701,7 +1720,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
       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);
+      release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
 
 #if T_TRACER
       if (harq_ack[0] != 1)
@@ -1721,8 +1740,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
       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);
+      release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+      release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
     }
     else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); 
   }
@@ -1743,7 +1762,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	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);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
       }
       else if (uci->pucch_fmt == pucch_format1b) {
 	pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
@@ -1753,8 +1772,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	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);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+	release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
       }
       break;
     case 1: // multiplexing
@@ -1766,7 +1785,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	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);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
       }
       else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) {
         pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
@@ -1776,8 +1795,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	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);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+	release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
       }
       else { // num_pucch_resources (M) > 1
         pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
@@ -1788,8 +1807,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	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);
+	release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
+	release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
       }
       break;
     case 2: // special bundling (SR collision)
@@ -1800,26 +1819,27 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
  
       switch (harq_ack[0]) {
       case 0:
+        /* TODO: release_harq here? this whole code looks suspicious */
 	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);
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
 	}
 	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);
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
 	}
 	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);
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
 	}
 	break;
       }
diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
index b54fc171c6acb831466726e40ec33ed3e941bb17..9255372340283d8ce89bb0c1c4cfc6c19a2710a9 100644
--- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
@@ -131,7 +131,7 @@ message flex_enb_config_request {
 
 message flex_enb_config_reply {
 	optional flex_header header = 1;
-	optional uint32 eNB_id = 2;		// Unique id to distinguish the eNB
+	optional uint64 eNB_id = 2;		// Unique id to distinguish the eNB
 	repeated flex_cell_config cell_config = 3;
         optional uint32 device_spec = 4;
 }
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 5e9c320f57a0caf5caec567b50c4841316517751..aa5bbdb3c73b71760a5f28ff18c6e430a99125a2 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -60,37 +60,124 @@
 
 extern uint16_t sf_ahead;
 
-
 void RCconfig_flexran()
 {
-  int i;
+  uint16_t i;
+  uint16_t num_enbs;
+  char aprefix[MAX_OPTNAME_SIZE*2 + 8];
+  /* this will possibly truncate the cell id (RRC assumes int32_t).
+   * Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for
+   * the bitshifting to work properly */
+  int32_t Nid_cell = 0;
+  uint16_t Nid_cell_tr = 0;
+  uint32_t enb_id = 0;
+
+  /*
+   * the only reason for all these variables is, that they are "hard-encoded"
+   * into the CCPARAMS_DESC macro and we need it for the Nid_cell variable ...
+   */
+  char *frame_type, *prefix_type, *pbch_repetition, *prach_high_speed,
+    *pusch_hoppingMode, *pusch_enable64QAM, *pusch_groupHoppingEnabled,
+    *pusch_sequenceHoppingEnabled, *phich_duration, *phich_resource,
+    *srs_enable, *srs_ackNackST, *srs_MaxUpPts, *pusch_alpha,
+    *pucch_deltaF_Format1, *pucch_deltaF_Format1b, *pucch_deltaF_Format2,
+    *pucch_deltaF_Format2a, *pucch_deltaF_Format2b,
+    *rach_preamblesGroupAConfig, *rach_messagePowerOffsetGroupB, *pcch_nB;
+  long long int     downlink_frequency;
+  int32_t tdd_config, tdd_config_s, eutra_band, uplink_frequency_offset,
+    Nid_cell_mbsfn, N_RB_DL, nb_antenna_ports, prach_root, prach_config_index,
+    prach_zero_correlation, prach_freq_offset, pucch_delta_shift,
+    pucch_nRB_CQI, pucch_nCS_AN, pucch_n1_AN, pdsch_referenceSignalPower,
+    pdsch_p_b, pusch_n_SB, pusch_hoppingOffset, pusch_groupAssignment,
+    pusch_nDMRS1, srs_BandwidthConfig, srs_SubframeConfig, pusch_p0_Nominal,
+    pucch_p0_Nominal, msg3_delta_Preamble, rach_numberOfRA_Preambles,
+    rach_sizeOfRA_PreamblesGroupA, rach_messageSizeGroupA,
+    rach_powerRampingStep, rach_preambleInitialReceivedTargetPower,
+    rach_preambleTransMax, rach_raResponseWindowSize,
+    rach_macContentionResolutionTimer, rach_maxHARQ_Msg3Tx,
+    pcch_defaultPagingCycle, bcch_modificationPeriodCoeff,
+    ue_TimersAndConstants_t300, ue_TimersAndConstants_t301,
+    ue_TimersAndConstants_t310, ue_TimersAndConstants_t311,
+    ue_TimersAndConstants_n310, ue_TimersAndConstants_n311,
+    ue_TransmissionMode;
+
+  /* get number of eNBs */
+  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL);
+  num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
+
+  /* for eNB ID */
+  paramdef_t ENBParams[]  = ENBPARAMS_DESC;
+  paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0};
+
+  /* for Nid_cell */
+  checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
+  paramdef_t CCsParams[] = CCPARAMS_DESC;
+  paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
+  /* map parameter checking array instances to parameter definition array instances */
+  for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
+    CCsParams[I].chkPptr = &(config_check_CCparams[I]);
+  }
 
   paramdef_t flexranParams[] = FLEXRANPARAMS_DESC;
   config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
 
   if (!RC.flexran) {
-    RC.flexran = calloc(RC.nb_L1_inst, sizeof(flexran_agent_info_t*));
-    AssertFatal(RC.flexran != NULL,
+    RC.flexran = calloc(num_enbs, sizeof(flexran_agent_info_t*));
+    AssertFatal(RC.flexran,
                 "can't ALLOCATE %zu Bytes for %d flexran agent info with size %zu\n",
-                RC.nb_L1_inst * sizeof(flexran_agent_info_t*),
-                RC.nb_L1_inst, sizeof(flexran_agent_info_t*));
+                num_enbs * sizeof(flexran_agent_info_t*),
+                num_enbs, sizeof(flexran_agent_info_t*));
   }
 
-  /* For all agent instance, fill in the same controller configuration. */
-  for (i = 0; i < RC.nb_L1_inst; i++) {
+  for (i = 0; i < num_enbs; i++) {
     RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t));
-    AssertFatal(RC.flexran[i] != NULL,
+    AssertFatal(RC.flexran[i],
                 "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n",
-                sizeof(flexran_agent_info_t), i + 1, RC.nb_L1_inst);
+                sizeof(flexran_agent_info_t), i + 1, num_enbs);
     /* if config says "yes", enable Agent, in all other cases it's like "no" */
-    RC.flexran[i]->enabled          = strcmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0;
+    RC.flexran[i]->enabled          = strcasecmp(*(flexranParams[FLEXRAN_ENABLED].strptr), "yes") == 0;
+    /* if not enabled, simply skip the rest, it is not needed anyway */
+    if (!RC.flexran[i]->enabled)
+      continue;
     RC.flexran[i]->interface_name   = strdup(*(flexranParams[FLEXRAN_INTERFACE_NAME_IDX].strptr));
     //inet_ntop(AF_INET, &(enb_properties->properties[mod_id]->flexran_agent_ipv4_address), in_ip, INET_ADDRSTRLEN);
     RC.flexran[i]->remote_ipv4_addr = strdup(*(flexranParams[FLEXRAN_IPV4_ADDRESS_IDX].strptr));
     RC.flexran[i]->remote_port      = *(flexranParams[FLEXRAN_PORT_IDX].uptr);
     RC.flexran[i]->cache_name       = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr));
-    RC.flexran[i]->node_ctrl_state  = strcmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION;
-    RC.flexran[i]->enb_id           = i;
+    RC.flexran[i]->node_ctrl_state  = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION;
+
+    config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL);
+    /* eNB ID from configuration, as read in by RCconfig_RRC() */
+    if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) {
+      // Calculate a default eNB ID
+# if defined(ENABLE_USE_MME)
+      enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8);
+# else
+      enb_id = i;
+# endif
+    } else {
+        enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
+    }
+
+    /* cell ID */
+    sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i);
+    config_getlist(&CCsParamList, NULL, 0, aprefix);
+    if (CCsParamList.numelt > 0) {
+      sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0);
+      config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
+      Nid_cell_tr = (uint16_t) Nid_cell;
+    }
+
+    RC.flexran[i]->mod_id   = i;
+    RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr);
+
+    /* assume for the moment the monolithic case, i.e. agent can provide
+     * information for all layers */
+    RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY
+                                   | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC
+                                   | FLEXRAN_CAP_RLC   | FLEXRAN_CAP_PDCP
+                                   | FLEXRAN_CAP_SDAP  | FLEXRAN_CAP_RRC;
   }
 }
 
diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c
index bd46ecc49d246f9e81b7d3d2942f42158d30f0a4..8d5cdbc06bd396b68e1e7c43fa11bfdabcf9476a 100644
--- a/openair2/ENB_APP/flexran_agent.c
+++ b/openair2/ENB_APP/flexran_agent.c
@@ -114,12 +114,12 @@ void *receive_thread(void *args) {
   
   while (1) {
 
-    while (flexran_agent_msg_recv(d->enb_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) {
+    while (flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) {
       
       LOG_D(FLEXRAN_AGENT,"received message with size %d\n", size);
   
       // Invoke the message handler
-      msg=flexran_agent_handle_message(d->enb_id, data, size);
+      msg=flexran_agent_handle_message(d->mod_id, data, size);
 
       free(data);
     
@@ -127,7 +127,7 @@ void *receive_thread(void *args) {
       if (msg != NULL){
 	data=flexran_agent_pack_message(msg,&size);
 
-	if (flexran_agent_msg_send(d->enb_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) {
+	if (flexran_agent_msg_send(d->mod_id, FLEXRAN_AGENT_DEFAULT, data, size, priority)) {
 	  err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
 	  goto error;
 	}
@@ -190,13 +190,6 @@ int flexran_agent_start(mid_t mod_id)
     LOG_I(FLEXRAN_AGENT, "FlexRAN Agent for eNB %d is DISABLED\n", mod_id);
     return 100;
   }
-  
-  flexran->enb_id = mod_id;
-  /* assume for the moment the monolithic case, i.e. agent can provide
-   * information for all layers */
-  flexran->capability_mask = FLEXRAN_CAP_LOL1 | FLEXRAN_CAP_HIL1
-                           | FLEXRAN_CAP_LOL2 | FLEXRAN_CAP_HIL2
-                           | FLEXRAN_CAP_PDCP | FLEXRAN_CAP_RRC;
 
   /*
    * Initialize the channel container
diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c
index 6d32aeedbb152facec421b7cfc4d176177320a6e..4b0a22300fc5064e21e68dd4664e48a0ce977207 100644
--- a/openair2/ENB_APP/flexran_agent_common.c
+++ b/openair2/ENB_APP/flexran_agent_common.c
@@ -804,7 +804,6 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
   xid = (enb_config_req_msg->header)->xid;
   
   int i, j;
-  int enb_id = mod_id;
   
   Protocol__FlexEnbConfigReply *enb_config_reply_msg;
   enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply));
@@ -816,10 +815,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
     goto error;
   
   enb_config_reply_msg->header = header;
-  
-  enb_config_reply_msg->enb_id = mod_id;
-  
-  
+
+  enb_config_reply_msg->enb_id = RC.flexran[mod_id]->agent_id;
+  enb_config_reply_msg->has_enb_id = 1;
+
   enb_config_reply_msg->n_cell_config = MAX_NUM_CCs;
   
   Protocol__FlexCellConfig **cell_conf;
@@ -832,61 +831,60 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
       protocol__flex_cell_config__init(cell_conf[i]);
 
       cell_conf[i]->phy_cell_id = 1;
-      cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(enb_id,i);
+      cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i);
 
       cell_conf[i]->cell_id = i;
       cell_conf[i]->has_cell_id = 1;
 
-      cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(enb_id,i);
+      cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i);
       cell_conf[i]->has_pusch_hopping_offset = 1;
 
-      if (flexran_get_hopping_mode(enb_id,i) == 0) {
+      if (flexran_get_hopping_mode(mod_id,i) == 0) {
 	cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
-      } else if(flexran_get_hopping_mode(enb_id,i) == 1) {
+      } else if(flexran_get_hopping_mode(mod_id,i) == 1) {
 	cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
       }
       cell_conf[i]->has_hopping_mode = 1;
 
-      cell_conf[i]->n_sb = flexran_get_n_SB(enb_id,i);
+      cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i);
       cell_conf[i]->has_n_sb = 1;
 
-      if (flexran_get_phich_resource(enb_id,i) == 0) {
+      if (flexran_get_phich_resource(mod_id,i) == 0) {
 	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; //0
-      } else if (flexran_get_phich_resource(enb_id,i) == 1) {
+      } else if (flexran_get_phich_resource(mod_id,i) == 1) {
 	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; //1
-      } else if (flexran_get_phich_resource(enb_id,i) == 2) {
+      } else if (flexran_get_phich_resource(mod_id,i) == 2) {
 	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; // 2
-      } else if (flexran_get_phich_resource(enb_id,i) == 3) {
+      } else if (flexran_get_phich_resource(mod_id,i) == 3) {
 	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;//3
       }
       cell_conf[i]->has_phich_resource = 1;
 
-      if (flexran_get_phich_duration(enb_id,i) == 0) {
+      if (flexran_get_phich_duration(mod_id,i) == 0) {
     	cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
-      } else if(flexran_get_phich_duration(enb_id,i) == 1) {
+      } else if(flexran_get_phich_duration(mod_id,i) == 1) {
 	cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
       }
       cell_conf[i]->has_phich_duration = 1;
-      //TODO: Fill in with actual value, See TS 36.211, section 6.9
-      cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(enb_id,i);
-      cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 0;
-      //TODO: Fill in with actual value
-      /* Protocol__FlexSiConfig *si_config; */
-      /* si_config = malloc(sizeof(Protocol__FlexSiConfig)); */
-      /* if(si_config == NULL) */
-      /* 	goto error; */
-      /* protocol__flex_si_config__init(si_config); */
-      /* //TODO: Fill in with actual value, Frame number to apply the SI configuration */
-      /* si_config->sfn = 1; */
-      /* si_config->has_sfn = 1; */
-      /* //TODO: Fill in with actual value, the length of SIB1 in bytes */
-      /* si_config->sib1_length = get_sib1_length(enb_id,i); */
-      /* si_config->has_sib1_length = 1; */
-      /* //TODO: Fill in with actual value, Scheduling window for all SIs in SF */
-      /* si_config->si_window_length = (uint32_t) get_si_window_length(enb_id,i); */
-      /* si_config->has_si_window_length = 1; */
-      /* //TODO: Fill in with actual value, the number of SI messages */
-      /* si_config->n_si_message=1; */
+      cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i);
+      cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1;
+      Protocol__FlexSiConfig *si_config;
+      si_config = malloc(sizeof(Protocol__FlexSiConfig));
+      if(si_config == NULL)
+        goto error;
+      protocol__flex_si_config__init(si_config);
+
+      si_config->sfn = flexran_get_current_system_frame_num(mod_id);
+      si_config->has_sfn = 1;
+
+      si_config->sib1_length = flexran_get_sib1_length(mod_id,i);
+      si_config->has_sib1_length = 1;
+
+      si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i);
+      si_config->has_si_window_length = 1;
+
+      si_config->n_si_message = 0;
+
       /* Protocol__FlexSiMessage **si_message; */
       /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */
       /* if(si_message == NULL) */
@@ -906,44 +904,42 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
       /* if(si_config->n_si_message > 0){ */
       /* 	si_config->si_message = si_message; */
       /* } */
-      /* cell_conf[i]->si_config = si_config; */
-      
-      cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(enb_id,i);
+
+      cell_conf[i]->si_config = si_config;
+
+      cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i);
       cell_conf[i]->has_dl_bandwidth = 1;
 
-      cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(enb_id,i);
+      cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i);
       cell_conf[i]->has_ul_bandwidth = 1;
 
-      if (flexran_get_ul_cyclic_prefix_length(enb_id, i) == 0) {
+      if (flexran_get_ul_cyclic_prefix_length(mod_id, i) == 0) {
 	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
-      } else if(flexran_get_ul_cyclic_prefix_length(enb_id, i) == 1) {
-	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;      
+      } else if(flexran_get_ul_cyclic_prefix_length(mod_id, i) == 1) {
+	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
       }
       cell_conf[i]->has_ul_cyclic_prefix_length = 1;
 
-      if (flexran_get_ul_cyclic_prefix_length(enb_id,i) == 0) {
+      if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 0) {
 	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL;
-      } else if (flexran_get_ul_cyclic_prefix_length(enb_id,i) == 1) {
+      } else if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 1) {
 	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED;
       }
 
       cell_conf[i]->has_dl_cyclic_prefix_length = 1;
-      //TODO: Fill in with actual value, number of cell specific antenna ports. Currently single port support
-      cell_conf[i]->antenna_ports_count = 1;
+      cell_conf[i]->antenna_ports_count = flexran_get_antenna_ports(mod_id, i);
       cell_conf[i]->has_antenna_ports_count = 1;
 
-      if (flexran_get_duplex_mode(enb_id,i) == 1) {
+      if (flexran_get_duplex_mode(mod_id,i) == 1) {
 	cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
-      } else if(flexran_get_duplex_mode(enb_id,i) == 0) {
+      } else if(flexran_get_duplex_mode(mod_id,i) == 0) {
 	cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
       }
       cell_conf[i]->has_duplex_mode = 1;
-      //TODO: Fill in with actual value, DL/UL subframe assignment. TDD only
-      cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(enb_id, i);
-      cell_conf[i]->has_subframe_assignment = 0;
-      //TODO: Fill in with actual value, TDD only. See TS 36.211, table 4.2.1
-      cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(enb_id,i);
-      cell_conf[i]->has_special_subframe_patterns = 0;
+      cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(mod_id, i);
+      cell_conf[i]->has_subframe_assignment = 1;
+      cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i);
+      cell_conf[i]->has_special_subframe_patterns = 1;
       //TODO: Fill in with actual value, The MBSFN radio frame period
       cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0;
       uint32_t *elem_rfperiod;
@@ -954,7 +950,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
 	elem_rfperiod[j] = 1;
       }
       cell_conf[i]->mbsfn_subframe_config_rfperiod = elem_rfperiod;
-      
+
       //TODO: Fill in with actual value, The MBSFN radio frame offset
       cell_conf[i]->n_mbsfn_subframe_config_rfoffset = 0;
       uint32_t *elem_rfoffset;
@@ -965,7 +961,7 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
 	elem_rfoffset[j] = 1;
       }
       cell_conf[i]->mbsfn_subframe_config_rfoffset = elem_rfoffset;
-      
+
       //TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes
       cell_conf[i]->n_mbsfn_subframe_config_sfalloc = 0;
       uint32_t *elem_sfalloc;
@@ -976,63 +972,62 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F
 	elem_sfalloc[j] = 1;
       }
       cell_conf[i]->mbsfn_subframe_config_sfalloc = elem_sfalloc;
-      
-      cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(enb_id,i);
+
+      cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(mod_id,i);
       cell_conf[i]->has_prach_config_index = 1;
 
-      cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(enb_id,i);
+      cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id,i);
       cell_conf[i]->has_prach_freq_offset = 1;
 
-      cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(enb_id,i);
+      cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id,i);
       cell_conf[i]->has_ra_response_window_size = 1;
 
-      cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(enb_id,i);
+      cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id,i);
       cell_conf[i]->has_mac_contention_resolution_timer = 1;
 
-      cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(enb_id,i);
+      cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id,i);
       cell_conf[i]->has_max_harq_msg3tx = 1;
 
-      cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(enb_id,i);
+      cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(mod_id,i);
       cell_conf[i]->has_n1pucch_an = 1;
 
-      cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(enb_id,i);
+      cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id,i);
       cell_conf[i]->has_deltapucch_shift = 1;
 
-      cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(enb_id,i);
+      cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(mod_id,i);
       cell_conf[i]->has_nrb_cqi = 1;
 
-      cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(enb_id,i);
+      cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id,i);
       cell_conf[i]->has_srs_subframe_config = 1;
 
-      cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(enb_id,i);
+      cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id,i);
       cell_conf[i]->has_srs_bw_config = 1;
 
-      cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(enb_id,i);
+      cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id,i);
       cell_conf[i]->has_srs_mac_up_pts = 1;
 
-      cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (enb_id,i);
+      cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (mod_id,i);
       cell_conf[i]->has_dl_freq = 1;
 
-      cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (enb_id, i);
+      cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, i);
       cell_conf[i]->has_ul_freq = 1;
 
-      cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (enb_id,i);
+      cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (mod_id,i);
       cell_conf[i]->has_eutra_band = 1;
 
-      cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(enb_id, i);
+      cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, i);
       cell_conf[i]->has_dl_pdsch_power = 1;
 
-      cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (enb_id,i);
+      cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id,i);
       cell_conf[i]->has_ul_pusch_power = 1;
- 
 
-      if (flexran_get_enable64QAM(enb_id,i) == 0) {
+      if (flexran_get_enable64QAM(mod_id,i) == 0) {
 	cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM;
-      } else if(flexran_get_enable64QAM(enb_id,i) == 1) {
+      } else if(flexran_get_enable64QAM(mod_id,i) == 1) {
 	cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM;
       }
       cell_conf[i]->has_enable_64qam = 1;
-      
+
       cell_conf[i]->carrier_index = i;
       cell_conf[i]->has_carrier_index = 1;
     }
diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h
index 6364bc628191ec7f9c22bdfa98150170b6dbe101..aa71dd33fab750e933a0d86ab1b1ab43f28c5a43 100644
--- a/openair2/ENB_APP/flexran_agent_defs.h
+++ b/openair2/ENB_APP/flexran_agent_defs.h
@@ -138,12 +138,14 @@ typedef enum {
   FLEXRAN_AGENT_TIMER_STATE_MAX,
 } flexran_agent_timer_state_t;
 
-#define FLEXRAN_CAP_LOL1 0x1
-#define FLEXRAN_CAP_HIL1 0x2
-#define FLEXRAN_CAP_LOL2 0x4   // is: MAC
-#define FLEXRAN_CAP_HIL2 0x8   // is: RLC
-#define FLEXRAN_CAP_PDCP 0x16
-#define FLEXRAN_CAP_RRC  0x32
+#define FLEXRAN_CAP_LOPHY 1
+#define FLEXRAN_CAP_HIPHY 2
+#define FLEXRAN_CAP_LOMAC 4
+#define FLEXRAN_CAP_HIMAC 8
+#define FLEXRAN_CAP_RLC   16
+#define FLEXRAN_CAP_PDCP  32
+#define FLEXRAN_CAP_SDAP  64
+#define FLEXRAN_CAP_RRC   128
 
 typedef enum {
   ENB_NORMAL_OPERATION = 0x0,
@@ -159,7 +161,8 @@ typedef struct {
   uint16_t remote_port;
   char    *cache_name;
 
-  int      enb_id;
+  mid_t    mod_id;
+  uint64_t agent_id;
   uint8_t  capability_mask;
 
   /* lock for waiting before starting or soft-restart */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index a7c79a70d5537d341bfe6d3b82a613e8e7ac6000..8dab2a9b71857a027ded133e2f932df1a1be1d60 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -423,12 +423,15 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
     }
   }				// ul_failure_timer>0
 
+#if 0
+  /* U-plane inactivity timer is disabled. Uncomment to re-enable. */
   UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
   if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){
     LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); 
     mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
     UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer  = 0;
   }// time > 60s
+#endif
 }
 
 void
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 341db67934ecfed3ace6cd1ece1b83a0177f0593..110afc1a5ad287af94d87ac4aa071f7d97aee01f 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -3268,8 +3268,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	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 || pdu[0] == 4)	// NAK (treat DTX as NAK)
+	} else if (pdu[0] == 2 || pdu[0] == 4) {	// NAK (treat DTX as NAK)
 	  sched_ctl->round[CC_idP][harq_pid]++;	// increment round
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+	    sched_ctl->round[CC_idP][harq_pid] = 8;	// release HARQ process
+	    sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+          }
+        }
       } else {
 	// one or two ACK/NAK bits
 	AssertFatal(num_ack_nak <= 2,
@@ -3285,8 +3290,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	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))
+	    && (pdu[0] == 2) && (pdu[1] == 2)) {
 	  sched_ctl->round[CC_idP][harq_pid]++;
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+            sched_ctl->round[CC_idP][harq_pid] = 8;     // release HARQ process
+            sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+          }
+        }
 	else if (((num_ack_nak == 2)
 		  && (sched_ctl->round[CC_idP][harq_pid] < 8)
 		  && (sched_ctl->tbcnt[0][harq_pid] == 2)
@@ -3297,11 +3307,20 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		     && (pdu[0] == 2) && (pdu[1] == 1))) {
 	  sched_ctl->round[CC_idP][harq_pid]++;
 	  sched_ctl->tbcnt[CC_idP][harq_pid] = 1;
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+            sched_ctl->round[CC_idP][harq_pid] = 8;     // release HARQ process
+            sched_ctl->tbcnt[CC_idP][harq_pid] = 0;  /* TODO: do we have to set it to 0? */
+          }
 	} 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))
+		   && (pdu[0] == 2) && (pdu[1] == 2)) {
 	  sched_ctl->round[CC_idP][harq_pid]++;
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+            sched_ctl->round[CC_idP][harq_pid] = 8;     // release HARQ process
+            sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+          }
+        }
 	else
 	  AssertFatal(1 == 0,
 		      "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n",
@@ -3327,12 +3346,18 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		    pdu[1]);
 	if (pdu[0] == 1)
 	  sched_ctl->round[pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[pCCid][harq_pid]++;
+          if (sched_ctl->round[pCCid][harq_pid] == 4)
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+        }
 	if (pdu[1] == 1)
 	  sched_ctl->round[1 - pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4)
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+        }
       }			// A=2
       else if ((num_ack_nak == 3)
 	       && (sched_ctl->round[pCCid][harq_pid] < 8)
@@ -3358,13 +3383,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   ((pdu[0] == 1) && (pdu[1] == 2))) {
 	  sched_ctl->round[pCCid][harq_pid]++;
 	  sched_ctl->tbcnt[pCCid][harq_pid] = 1;
-	} else
+	  if (sched_ctl->round[pCCid][harq_pid] == 4) {
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[pCCid][harq_pid] = 0; /* TODO: do we have to set it to 0? */
+          }
+	} else {
 	  sched_ctl->round[pCCid][harq_pid]++;
+	  if (sched_ctl->round[pCCid][harq_pid] == 4) {
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[pCCid][harq_pid] = 0;
+          }
+        }
 
 	if (pdu[2] == 1)
 	  sched_ctl->round[1 - pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+          }
+        }
       }			// A=3 primary cell has 2 TBs
       else if ((num_ack_nak == 3)
 	       && (sched_ctl->round[1 - pCCid][harq_pid] < 8)
@@ -3390,13 +3428,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   || ((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
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0;
+          }
+	} else {		// both NAK/DTX
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0;
+          }
+        }
 
 	if (pdu[2] == 1)
 	  sched_ctl->round[pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[pCCid][harq_pid]++;
+	  if (sched_ctl->round[pCCid][harq_pid] == 4) {
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+          }
+        }
       }			// A=3 secondary cell has 2 TBs
 #if MAX_NUM_CCs>1
       else if ((num_ack_nak == 4)
@@ -3425,8 +3476,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   || ((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
+	  if (sched_ctl->round[0][harq_pid] == 4) {
+	    sched_ctl->round[0][harq_pid] = 8;
+	    sched_ctl->tbcnt[0][harq_pid] = 0;
+          }
+	} else {		// both NAK/DTX
 	  sched_ctl->round[0][harq_pid]++;
+	  if (sched_ctl->round[0][harq_pid] == 4) {
+	    sched_ctl->round[0][harq_pid] = 8;
+	    sched_ctl->tbcnt[0][harq_pid] = 0;
+          }
+        }
 
 	if ((pdu[2] == 1) && (pdu[3] == 1)) {	// both ACK
 	  sched_ctl->round[1][harq_pid] = 8;
@@ -3435,8 +3495,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   || ((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
+	  if (sched_ctl->round[1][harq_pid] == 4) {
+	    sched_ctl->round[1][harq_pid] = 8;
+	    sched_ctl->tbcnt[1][harq_pid] = 0;
+          }
+	} else {		// both NAK/DTX
 	  sched_ctl->round[1][harq_pid]++;
+	  if (sched_ctl->round[1][harq_pid] == 4) {
+	    sched_ctl->round[1][harq_pid] = 8;
+	    sched_ctl->tbcnt[1][harq_pid] = 0;
+          }
+        }
       }			// A=4 both serving cells have 2 TBs
 #endif
       break;
@@ -3451,8 +3520,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	    if (pdu[j] == 1) {
 	      sched_ctl->round[i][harq_pid] = 8;
 	      sched_ctl->tbcnt[i][harq_pid] = 0;
-	    } else if (pdu[j] == 2)
+	    } else if (pdu[j] == 2) {
 	      sched_ctl->round[i][harq_pid]++;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
+            }
 	    else
 	      AssertFatal(1 == 0,
 			  "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n",
@@ -3467,13 +3541,25 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		       && (pdu[j] == 1) && (pdu[j + 1] == 2)) {
 	      sched_ctl->round[i][harq_pid]++;
 	      sched_ctl->tbcnt[i][harq_pid] = 1;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        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] == 2) && (pdu[j + 1] == 1)) {
 	      sched_ctl->round[i][harq_pid]++;
 	      sched_ctl->tbcnt[i][harq_pid] = 1;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        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] == 2) && (pdu[j + 1] == 2)) {
 	      sched_ctl->round[i][harq_pid]++;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
 	    } else
 	      AssertFatal(1 == 0,
 			  "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n",
@@ -3487,6 +3573,10 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	      sched_ctl->tbcnt[i][harq_pid] = 0;
 	    } else if (pdu[j] == 2) {
 	      sched_ctl->round[i][harq_pid]++;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
 	    } else
 	      AssertFatal(1 == 0,
 			  "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n",
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index b4fb025ea479c5b5b42291af6f88509daa8be6c5..9ccb0e66ab149bb333d46da09ac923515321d2d9 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -212,6 +212,30 @@ rx_sdu(const module_id_t enb_mod_idP,
           UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0;
       } else
 	UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
+
+      first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
+
+      // Program NACK for PHICH
+      LOG_D(MAC,
+	"Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n",
+	current_rnti, harq_pid, first_rb);
+      nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP];
+      nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
+      nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
+        &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->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.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
+      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = 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_body->number_of_hi++;
+      hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0);
+      hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
+      hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4);
+      hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
+
       return;
 
     }
@@ -251,6 +275,9 @@ rx_sdu(const module_id_t enb_mod_idP,
 	ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10;
 	add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP);
       }
+
+      /* TODO: program NACK for PHICH? */
+
       return;
     }
   } else {
@@ -1448,6 +1475,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	      T_INT(first_rb[CC_id]),
 	      T_INT(rb_table[rb_table_index]), T_INT(round));
 
+#if 0
+            /* This is done in rx_sdu, as it has to.
+             * Since the code is a bit different, let's keep this version here for review, in case of problem.
+             */
 	    // fill in NAK information
 
 	    hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
@@ -1471,6 +1502,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 		  UE_template->first_rb_ul[harq_pid],
 		  UE_template->nb_rb_ul[harq_pid],
 		  UE_template->TBS_UL[harq_pid], round);
+#endif
 	    // Add UL_config PDUs
 	    LOG_D(MAC,
 		  "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index e7458c347f40932ef248d991bd51b1e3a554e002..2cdcfc7de857a8c4df4089881040907b731d21c4 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -734,7 +734,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
 
       // control channel or retransmission
       /* TODO: do we have to check for retransmission? */
-      if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) {
+      if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) {
         nb_rbs_required_remaining_1[CC_id][UE_id] =
                 nb_rbs_required[CC_id][UE_id];
       } else {
diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h
index 376b66c79a1e5c61ccedad1aca00806137da49bc..c8565d52bd59beed4d64b822ef04bea122acfc39 100644
--- a/openair2/RRC/LTE/defs_NB_IoT.h
+++ b/openair2/RRC/LTE/defs_NB_IoT.h
@@ -35,6 +35,9 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "COMMON/s1ap_messages_types.h"
+#include "COMMON/rrc_messages_types.h"
+
 #include "collection/tree.h"
 #include "rrc_types_NB_IoT.h"
 #include "COMMON/platform_constants.h"
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index 7f63e8c1ce6fdd179aa6a565bd61ef0dfbdc4ee1..7ba3d88a878e1e294a8d29ca58e7b6d0127b2c38 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -290,6 +290,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
   hashtable_rc_t      hash_rc            = HASH_TABLE_KEY_NOT_EXISTS;
   gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
   protocol_ctxt_t     ctxt;
+  NwGtpv1uRcT         rc;
 
   switch(pUlpApi->apiType) {
     /* Here there are two type of messages handled:
@@ -314,6 +315,12 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
     gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
 #endif
 
+    rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
+                           pUlpApi->apiInfo.recvMsgInfo.hMsg);
+    if (rc != NW_GTPV1U_OK) {
+      LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
+    }
+
     //-----------------------
     // GTPV1U->PDCP mapping
     //-----------------------
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 03313146df30ab2dc486fc10ab494f48e7650226..676ea8988482048fc2f0480306f37b0b437b77b0 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -904,7 +904,6 @@ int main( int argc, char **argv )
   int ret;
 #endif
 
-  start_background_system();
   if ( load_configmodule(argc,argv) == NULL) {
     exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
   } 
@@ -1209,9 +1208,6 @@ int main( int argc, char **argv )
   sync_var=0;
   pthread_cond_broadcast(&sync_cond);
   pthread_mutex_unlock(&sync_mutex);
-  printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
-  end_configmodule();
-  printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
 
   // wait for end of program
   printf("TYPE <CTRL-C> TO TERMINATE\n");
@@ -1271,6 +1267,9 @@ int main( int argc, char **argv )
     }
     free_lte_top();
 
+  printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
+  end_configmodule();
+  printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
 
   pthread_cond_destroy(&sync_cond);
   pthread_mutex_destroy(&sync_mutex);