From 4c3024e4892a2390e76279df210c4bd5a943ed63 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Wed, 20 Nov 2013 10:43:23 +0000
Subject: [PATCH] - Declared asn1 inlined conversions functions as static to
 avoid errors at link time - Forward initial context setup req message to RRC
 - Updated some data types related to initial context setup request

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4454 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 common/utils/asn1_conversions.h           |  8 +-
 openair-cn/COMMON/common_types.h          |  2 +-
 openair-cn/S1AP/s1ap_eNB_handlers.c       | 91 +++++++++++++++--------
 openair-cn/S1AP/s1ap_eNB_nas_procedures.c |  5 +-
 openair-cn/S1AP/s1ap_eNB_ue_context.h     |  5 ++
 openair2/COMMON/s1ap_messages_types.h     | 55 +++++++++++++-
 6 files changed, 126 insertions(+), 40 deletions(-)

diff --git a/common/utils/asn1_conversions.h b/common/utils/asn1_conversions.h
index 265957f601..42b375f48c 100644
--- a/common/utils/asn1_conversions.h
+++ b/common/utils/asn1_conversions.h
@@ -40,7 +40,7 @@
  *\param[in] pointer to the BIT_STRING_t object.
  *\return the extracted value.
  */
-inline uint8_t BIT_STRING_to_uint8(BIT_STRING_t *asn) {
+static inline uint8_t BIT_STRING_to_uint8(BIT_STRING_t *asn) {
   DevCheck ((asn->size == 1), asn->size, 0, 0);
 
   return asn->buf[0] >> asn->bits_unused;
@@ -51,7 +51,7 @@ inline uint8_t BIT_STRING_to_uint8(BIT_STRING_t *asn) {
  *\param[in] pointer to the BIT_STRING_t object.
  *\return the extracted value.
  */
-inline uint16_t BIT_STRING_to_uint16(BIT_STRING_t *asn) {
+static inline uint16_t BIT_STRING_to_uint16(BIT_STRING_t *asn) {
   uint16_t result = 0;
   int index = 0;
 
@@ -77,7 +77,7 @@ inline uint16_t BIT_STRING_to_uint16(BIT_STRING_t *asn) {
  *\param[in] pointer to the BIT_STRING_t object.
  *\return the extracted value.
  */
-inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
+static inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
   uint32_t result = 0;
   int index;
   int shift;
@@ -100,7 +100,7 @@ inline uint32_t BIT_STRING_to_uint32(BIT_STRING_t *asn) {
  *\param[in] pointer to the BIT_STRING_t object.
  *\return the extracted value.
  */
-inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) {
+static inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) {
   uint64_t result = 0;
   int index;
   int shift;
diff --git a/openair-cn/COMMON/common_types.h b/openair-cn/COMMON/common_types.h
index 97175afe01..74af62ef08 100644
--- a/openair-cn/COMMON/common_types.h
+++ b/openair-cn/COMMON/common_types.h
@@ -74,7 +74,7 @@ typedef enum {
     NAM_MAX,
 } network_access_mode_t;
 
-typedef uint32_t bitrate_t;
+typedef uint64_t bitrate_t;
 
 typedef uint8_t  ebi_t;
 typedef char*    APN_t;
diff --git a/openair-cn/S1AP/s1ap_eNB_handlers.c b/openair-cn/S1AP/s1ap_eNB_handlers.c
index 31e5cd8eea..64facc3345 100644
--- a/openair-cn/S1AP/s1ap_eNB_handlers.c
+++ b/openair-cn/S1AP/s1ap_eNB_handlers.c
@@ -39,6 +39,8 @@
 
 #include "intertask_interface.h"
 
+#include "asn1_conversions.h"
+
 #include "s1ap_common.h"
 #include "s1ap_ies_defs.h"
 // #include "s1ap_eNB.h"
@@ -339,15 +341,18 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
 static
 int s1ap_eNB_handle_initial_context_request(uint32_t               assoc_id,
                                             uint32_t               stream,
-                                            struct s1ap_message_s *message_p)
+                                            struct s1ap_message_s *s1ap_message_p)
 {
+    int i;
+
     s1ap_eNB_mme_data_t   *mme_desc_p;
     s1ap_eNB_ue_context_t *ue_desc_p;
+    MessageDef            *message_p;
 
     S1ap_InitialContextSetupRequestIEs_t *initialContextSetupRequest_p;
-    DevAssert(message_p != NULL);
+    DevAssert(s1ap_message_p != NULL);
 
-    initialContextSetupRequest_p = &message_p->msg.s1ap_InitialContextSetupRequestIEs;
+    initialContextSetupRequest_p = &s1ap_message_p->msg.s1ap_InitialContextSetupRequestIEs;
 
     if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
         S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
@@ -371,35 +376,57 @@ int s1ap_eNB_handle_initial_context_request(uint32_t               assoc_id,
 
     ue_desc_p->mme_ue_s1ap_id = initialContextSetupRequest_p->mme_ue_s1ap_id;
 
-//     {
-//         int i;
-// 
-//         extern int s1ap_eNB_handle_api_req(eNB_mme_desc_t     *eNB_desc_p,
-//                                            s1ap_rrc_api_req_t *api_req_p);
-// 
-//         s1ap_rrc_api_req_t api_req;
-//         s1ap_initial_ctxt_setup_resp_t *initial_ctxt_resp_p;
-// 
-//         memset(&api_req, 0, sizeof(s1ap_rrc_api_req_t));
-// 
-//         initial_ctxt_resp_p = &api_req.msg.initial_ctxt_resp;
-//         api_req.api_req = S1AP_API_INITIAL_CONTEXT_SETUP_RESP;
-// 
-//         initial_ctxt_resp_p->eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
-//         initial_ctxt_resp_p->e_rabs_failed = 0;
-//         initial_ctxt_resp_p->nb_of_e_rabs
-//         = initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.e_RABToBeSetupItemCtxtSUReq.count;
-//         for (i = 0; i < initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.e_RABToBeSetupItemCtxtSUReq.count; i++)
-//         {
-//             struct E_RABToBeSetupItemCtxtSUReq_s *item;
-//             item = (struct E_RABToBeSetupItemCtxtSUReq_s *)initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.e_RABToBeSetupItemCtxtSUReq.array[i];
-//             initial_ctxt_resp_p->e_rabs = realloc(initial_ctxt_resp_p->e_rabs, i * sizeof(e_rab_setup_t));
-//             initial_ctxt_resp_p->e_rabs[i].e_rab_id = 5;
-// 
-//         }
-// 
-//         s1ap_eNB_handle_api_req(eNB_desc_p, &api_req);
-//     }
+    message_p = itti_alloc_new_message(TASK_S1AP, S1AP_INITIAL_CONTEXT_SETUP_REQ);
+
+    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
+    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_e_rabs =
+    initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.s1ap_E_RABToBeSetupItemCtxtSUReq.count;
+
+    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul = initialContextSetupRequest_p->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateUL;
+    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl = initialContextSetupRequest_p->uEaggregateMaximumBitrate.uEaggregateMaximumBitRateDL;
+
+    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.encryption_algorithms =
+    BIT_STRING_to_uint16(&initialContextSetupRequest_p->ueSecurityCapabilities.encryptionAlgorithms);
+    S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
+    BIT_STRING_to_uint16(&initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms);
+
+    /* Copy the security key */
+    memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
+           initialContextSetupRequest_p->securityKey.buf, initialContextSetupRequest_p->securityKey.size);
+
+    for (i = 0; i < initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.s1ap_E_RABToBeSetupItemCtxtSUReq.count; i++)
+    {
+        S1ap_E_RABToBeSetupItemCtxtSUReq_t *item_p;
+
+        item_p = (S1ap_E_RABToBeSetupItemCtxtSUReq_t *)initialContextSetupRequest_p->e_RABToBeSetupListCtxtSUReq.s1ap_E_RABToBeSetupItemCtxtSUReq.array[i];
+
+        S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].e_rab_id = item_p->e_RAB_ID;
+        if (item_p->nAS_PDU != NULL) {
+            /* Only copy NAS pdu if present */
+            S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = item_p->nAS_PDU->size;
+
+            S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer =
+            malloc(sizeof(uint8_t) * item_p->nAS_PDU->size);
+
+            memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer,
+                   item_p->nAS_PDU->buf, item_p->nAS_PDU->size);
+        } else {
+            S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = 0;
+            S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = NULL;
+        }
+
+        /* Set the QOS informations */
+        S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI;
+
+        S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.priority_level =
+        item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel;
+        S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability =
+        item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
+        S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability =
+        item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
+    }
+
+    itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
 
     return 0;
 }
diff --git a/openair-cn/S1AP/s1ap_eNB_nas_procedures.c b/openair-cn/S1AP/s1ap_eNB_nas_procedures.c
index 8a419774f9..ad8b0ae860 100644
--- a/openair-cn/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair-cn/S1AP/s1ap_eNB_nas_procedures.c
@@ -122,8 +122,9 @@ int s1ap_eNB_handle_nas_first_req(
     DevAssert(ue_desc_p != NULL);
 
     /* Keep a reference to the selected MME */
-    ue_desc_p->mme_ref = mme_desc_p;
-    ue_desc_p->rnti    = s1ap_nas_first_req_p->rnti;
+    ue_desc_p->mme_ref      = mme_desc_p;
+    ue_desc_p->rnti         = s1ap_nas_first_req_p->rnti;
+    ue_desc_p->eNB_instance = instance_p;
 
     do {
         struct s1ap_eNB_ue_context_s *collision_p;
diff --git a/openair-cn/S1AP/s1ap_eNB_ue_context.h b/openair-cn/S1AP/s1ap_eNB_ue_context.h
index 26ceff968b..87cffac184 100644
--- a/openair-cn/S1AP/s1ap_eNB_ue_context.h
+++ b/openair-cn/S1AP/s1ap_eNB_ue_context.h
@@ -31,6 +31,8 @@
 #include "tree.h"
 #include "queue.h"
 
+#include "s1ap_eNB_defs.h"
+
 #ifndef S1AP_ENB_UE_CONTEXT_H_
 #define S1AP_ENB_UE_CONTEXT_H_
 
@@ -72,6 +74,9 @@ typedef struct s1ap_eNB_ue_context_s {
 
     /* Reference to MME data this UE is attached to */
     struct s1ap_eNB_mme_data_s *mme_ref;
+
+    /* Reference to eNB data this UE is attached to */
+    s1ap_eNB_instance_t *eNB_instance;
 } s1ap_eNB_ue_context_t;
 
 inline int s1ap_eNB_compare_eNB_ue_s1ap_id(
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index f146ca0a0f..69d5c055ab 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -33,6 +33,43 @@ typedef struct net_ip_address_s {
     char ipv6_address[40];
 } net_ip_address_t;
 
+typedef uint64_t bitrate_t;
+
+typedef struct {
+    bitrate_t br_ul;
+    bitrate_t br_dl;
+} ambr_t;
+
+typedef enum priority_level_s {
+    PRIORITY_LEVEL_SPARE       = 0,
+    PRIORITY_LEVEL_HIGHEST     = 1,
+    PRIORITY_LEVEL_LOWEST      = 14,
+    PRIORITY_LEVEL_NO_PRIORITY = 15,
+} priority_level_t;
+
+typedef enum {
+    PRE_EMPTION_CAPABILITY_ENABLED  = 0,
+    PRE_EMPTION_CAPABILITY_DISABLED = 1,
+    PRE_EMPTION_CAPABILITY_MAX,
+} pre_emp_capability_t;
+
+typedef enum {
+    PRE_EMPTION_VULNERABILITY_ENABLED  = 0,
+    PRE_EMPTION_VULNERABILITY_DISABLED = 1,
+    PRE_EMPTION_VULNERABILITY_MAX,
+} pre_emp_vulnerability_t;
+
+typedef struct {
+    priority_level_t        priority_level;
+    pre_emp_capability_t    pre_emp_capability;
+    pre_emp_vulnerability_t pre_emp_vulnerability;
+} allocation_retention_priority_t;
+
+typedef struct security_capabilities_s {
+    uint16_t encryption_algorithms;
+    uint16_t integrity_algorithms;
+} security_capabilities_t;
+
 /* Maximum number of e-rabs to be setup/deleted in a single message.
  * Even if only one bearer will be modified by message.
  */
@@ -45,6 +82,12 @@ typedef struct net_ip_address_s {
 
 #define S1AP_MAX_NB_MME_IP_ADDRESS 10
 
+/* Security key length used within eNB
+ * Even if only 16 bytes will be effectively used,
+ * the key length is 32 bytes (256 bits)
+ */
+#define SECURITY_KEY_LENGTH 32
+
 /* Provides the establishment cause for the RRC connection request as provided
  * by the upper layers. W.r.t. the cause value names: highPriorityAccess
  * concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
@@ -102,7 +145,8 @@ typedef struct transport_layer_addr_s {
 
 typedef struct e_rab_level_qos_parameter_s {
     uint8_t qci;
-    
+
+    allocation_retention_priority_t allocation_retention_priority;
 } e_rab_level_qos_parameter_t;
 
 typedef struct e_rab_s {
@@ -206,6 +250,15 @@ typedef s1ap_uplink_nas_t s1ap_downlink_nas_t;
 typedef struct s1ap_initial_context_setup_req_s {
     unsigned eNB_ue_s1ap_id:24;
 
+    /* UE aggregate maximum bitrate */
+    ambr_t ue_ambr;
+
+    /* Security algorithms */
+    security_capabilities_t security_capabilities;
+
+    /* Security key */
+    uint8_t security_key[SECURITY_KEY_LENGTH];
+
     /* Number of e_rab to be setup in the list */
     uint8_t  nb_of_e_rabs;
     /* list of e_rab to be setup by RRC layers */
-- 
GitLab