From ba735d181f90a1d11011193145b38c7e90367acb Mon Sep 17 00:00:00 2001
From: Navid Nikaein <navid.nikaein@eurecom.fr>
Date: Wed, 30 Mar 2016 09:45:40 +0200
Subject: [PATCH] improve the S1AP e_rab setup messages

---
 openair2/RRC/LITE/defs.h         |   1 +
 openair2/RRC/LITE/rrc_eNB.c      |   7 +-
 openair2/RRC/LITE/rrc_eNB_S1AP.c | 116 +++++++++++++++++--------------
 openair2/RRC/LITE/rrc_eNB_S1AP.h |  19 +++++
 4 files changed, 88 insertions(+), 55 deletions(-)

diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index 85d8e9cabe..e90c55635d 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -228,6 +228,7 @@ typedef enum e_rab_satus_e {
 typedef struct e_rab_param_s {
   e_rab_t param;
   uint8_t status;
+  uint8_t xid; // transaction_id
 } __attribute__ ((__packed__)) e_rab_param_t;
 #endif
 
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 9a9b39ed0d..ada0ec1a05 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -1218,6 +1218,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
     }
     
     ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; 
+    ue_context_pP->ue_context.e_rab[i].xid =rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
     
   }
   
@@ -1225,7 +1226,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
 
    size = do_RRCConnectionReconfiguration(ctxt_pP,
 					  buffer,
-					  rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),   //Transaction_id,
+					  ue_context_pP->ue_context.e_rab[i].xid,
 					  (SRB_ToAddModList_t*)NULL, 
 					  (DRB_ToAddModList_t*)*DRB_configList,
 					  (DRB_ToReleaseList_t*)NULL,  // DRB2_list,
@@ -4183,6 +4184,7 @@ rrc_eNB_decode_dcch(
           rrcConnectionReconfigurationComplete.
           criticalExtensions.choice.
           rrcConnectionReconfigurationComplete_r8);
+	/*NN: revise the condition */
         if (ue_context_p->ue_context.Status == RRC_RECONFIGURED){
 	  dedicated_DRB = 1;
 	  LOG_I(RRC,
@@ -4200,7 +4202,8 @@ rrc_eNB_decode_dcch(
       if (EPC_MODE_ENABLED == 1) {
 	if (dedicated_DRB == 1){
 	  rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
-					     ue_context_p);
+					     ue_context_p,
+					     ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
 	}else {
 	  rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
 						       ue_context_p);
diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c
index 76a10d948f..e8ad798276 100644
--- a/openair2/RRC/LITE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c
@@ -1,6 +1,6 @@
 /*******************************************************************************
     OpenAirInterface
-    Copyright(c) 1999 - 2014 Eurecom
+    Copyright(c) 1999 - 2016 Eurecom
 
     OpenAirInterface is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -28,8 +28,8 @@
 *******************************************************************************/
 /*! \file rrc_eNB_S1AP.c
  * \brief rrc S1AP procedures for eNB
- * \author Laurent Winckel and Sebastien ROUX and Navid Nikaein and Lionel GAUTHIER
- * \date 2013-2014
+ * \author Laurent Winckel, Sebastien ROUX, Navid Nikaein and Lionel GAUTHIER
+ * \date 2013-2016
  * \version 1.0
  * \company Eurecom
  * \email: navid.nikaein@eurecom.fr
@@ -1315,8 +1315,10 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
   }
 }
 
-rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
-				   rrc_eNB_ue_context_t*          const ue_context_pP){
+/*NN: careful about the typcast of xid (long -> uint8_t*/
+int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
+				   rrc_eNB_ue_context_t*          const ue_context_pP,
+				   uint8_t xid ){  
 
   MessageDef      *msg_p         = NULL;
   int e_rab;
@@ -1327,58 +1329,66 @@ rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
   S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
  
   for (e_rab = 0; e_rab <  ue_context_pP->ue_context.setup_e_rabs ; e_rab++) {
-   
-       
-    if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
-     
-      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
-      // TODO add other information from S1-U when it will be integrated
-      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab];
-      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab];
-      //S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length += 4;
-      ue_context_pP->ue_context.e_rab[e_rabs_done].status = E_RAB_STATUS_ESTABLISHED;
-      
-      LOG_I (RRC,"enb_gtp_addr (msg index %d, context index %d, status %d): nb_of_e_rabs %d,  e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
-	     e_rabs_done,  e_rab, ue_context_pP->ue_context.e_rab[e_rab].status,
-	     ue_context_pP->ue_context.nb_of_e_rabs,
-	     S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id,
-	     S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid,
-	     S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[0],
-	     S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[1],
-	     S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[2],
-	     S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[3]);
 
-      e_rabs_done++;
-    } else if ((ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_NEW)  || 
-	       (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)){
-      LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n");
-    }else {
-      ue_context_pP->ue_context.e_rab[e_rabs_failed].status = E_RAB_STATUS_FAILED;
-      S1AP_E_RAB_SETUP_RESP  (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
-      e_rabs_failed++;
-      // TODO add cause when it will be integrated
+    /* only respond to the corresponding transaction */ 
+    if (xid == ue_context_pP->ue_context.e_rab[e_rab].xid) {
+      
+      if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
+     
+	S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+	// TODO add other information from S1-U when it will be integrated
+	S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab];
+	S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab];
+	//S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length += 4;
+	ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
+	
+	LOG_I (RRC,"enb_gtp_addr (msg index %d, context index %d, status %d, xid %d): nb_of_e_rabs %d,  e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
+	       e_rabs_done,  e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid,
+	       ue_context_pP->ue_context.nb_of_e_rabs,
+	       S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id,
+	       S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid,
+	       S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[0],
+	       S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[1],
+	       S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[2],
+	       S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[3]);
+	
+	e_rabs_done++;
+      } else if ((ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_NEW)  || 
+		 (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)){
+	LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n");
+      }else { /* to be improved */
+	ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
+	S1AP_E_RAB_SETUP_RESP  (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+	e_rabs_failed++;
+	// TODO add cause when it will be integrated
+      }
     }
+    
+    LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: nb_of_erabs %d, total e_rabs %d, index %d \n",
+	  ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
+    MSC_LOG_TX_MESSAGE(
+		       MSC_RRC_ENB,
+		       MSC_S1AP_ENB,
+		       (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p),
+		       sizeof(s1ap_e_rab_setup_resp_t),
+		       MSC_AS_TIME_FMT" E_RAB_SETUP_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail",
+		       MSC_AS_TIME_ARGS(ctxt_pP),
+		       ue_context_pP->ue_id_rnti,
+		       S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id,
+		       e_rabs_done, e_rabs_failed);
+
+    
+    S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
+    S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
+    if ((e_rabs_done > 0) )
+      itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
+  } else {
+    /*debug info for the xid */ 
+    LOG_D (RRC,"xid does not corresponds  (context e_rab index %d, status %d, xid %d) \n ",
+	   e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid);
   }
   
-  LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: nb_of_erabs %d, total e_rabs %d, index %d \n",
-	ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
-  MSC_LOG_TX_MESSAGE(
-    MSC_RRC_ENB,
-    MSC_S1AP_ENB,
-    (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p),
-    sizeof(s1ap_e_rab_setup_resp_t),
-    MSC_AS_TIME_FMT" E_RAB_SETUP_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail",
-    MSC_AS_TIME_ARGS(ctxt_pP),
-    ue_context_pP->ue_id_rnti,
-    S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id,
-    e_rabs_done, e_rabs_failed);
-
-
-  S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
-  S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
-  if ((e_rabs_done > 0) )
-    itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
-      
+  return 0;
 }
 
 # endif /* defined(ENABLE_ITTI) */
diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.h b/openair2/RRC/LITE/rrc_eNB_S1AP.h
index ea797e8c20..55f501ec07 100644
--- a/openair2/RRC/LITE/rrc_eNB_S1AP.h
+++ b/openair2/RRC/LITE/rrc_eNB_S1AP.h
@@ -164,6 +164,25 @@ int rrc_eNB_process_S1AP_DOWNLINK_NAS(MessageDef *msg_p, const char *msg_name, i
  */
 int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
 
+
+/*! \fn rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
+ *\brief process a S1AP dedicated E_RAB setup request message received from S1AP.
+ *\param msg_p Message received by RRC.
+ *\param msg_name Message name.
+ *\param instance Message instance.
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
+
+/*! \fn rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid )
+ *\brief send a S1AP dedicated E_RAB setup response
+ *\param ctxt_pP contxt infirmation
+ *\param e_contxt_pP ue specific context at the eNB
+ *\param xid transaction identifier 
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid );  
+
 /*! \fn rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
  *\brief process a S1AP_UE_CTXT_MODIFICATION_REQ message received from S1AP.
  *\param msg_p Message received by RRC.
-- 
GitLab