From c19bdb776f538f549a8df312ecc369bf6b666ecd Mon Sep 17 00:00:00 2001
From: Robert Schmidt <robert.schmidt@eurecom.fr>
Date: Tue, 18 Sep 2018 15:11:37 +0200
Subject: [PATCH] add UE Context Setup Req at CU/DU

- add message sender (CU) + handler (CU) and fill with data from ITTI message
- add PLMNID_TO_MCC_MNC and BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4 macros
- correct TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING:
  change name to TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING, make it send 4B, not 5
---
 openair2/COMMON/f1ap_messages_def.h           |   1 +
 openair2/COMMON/f1ap_messages_types.h         |  32 +++++-
 openair2/F1AP/f1ap_cu_interface_management.c  |  12 +--
 openair2/F1AP/f1ap_cu_ue_context_management.c | 102 ++++++++++--------
 openair2/F1AP/f1ap_cu_ue_context_management.h |   3 +-
 openair2/F1AP/f1ap_du_ue_context_management.c |  93 +++++++++++++++-
 openair3/UTILS/conversions.h                  |  45 +++++---
 7 files changed, 214 insertions(+), 74 deletions(-)

diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h
index f08a9534d4..80da410fac 100644
--- a/openair2/COMMON/f1ap_messages_def.h
+++ b/openair2/COMMON/f1ap_messages_def.h
@@ -39,6 +39,7 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE                , MESSAGE_PRIORITY_MED, f1ap_ul_r
 /* RRC -> F1AP  messages */
 MESSAGE_DEF(F1AP_DL_RRC_MESSAGE              , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t              , f1ap_dl_rrc_message )
 //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
+MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_req_t, f1ap_ue_context_setup_req)
 
 
 
diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
index 9725431906..d133aab66e 100644
--- a/openair2/COMMON/f1ap_messages_types.h
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -22,6 +22,8 @@
 #ifndef F1AP_MESSAGES_TYPES_H_
 #define F1AP_MESSAGES_TYPES_H_
 
+#include "rlc.h"
+
 //-------------------------------------------------------------------------------------------//
 // Defines to access message fields.
 
@@ -33,6 +35,7 @@
 
 #define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message
 #define F1AP_UL_RRC_MESSAGE(mSGpTR)                (mSGpTR)->ittiMsg.f1ap_ul_rrc_message
+#define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR)          (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req
 #define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR)       (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp
 #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR)  (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp
 #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR)  (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail
@@ -249,8 +252,31 @@ typedef struct f1ap_ul_rrc_message_s {
   int      rrc_container_length;
 } f1ap_ul_rrc_message_t;
 
-/*typedef struct f1ap_ue_context_setup_req_s {
- 
-  } f1ap_ue_context_setup_req_t;*/
+typedef struct f1ap_up_tnl_s {
+  in_addr_t tl_address; // currently only IPv4 supported
+  uint32_t  gtp_teid;
+} f1ap_up_tnl_t;
+
+typedef struct f1ap_drb_to_be_setup_s {
+  uint8_t        drb_id;
+  f1ap_up_tnl_t  up_ul_tnl[2];
+  uint8_t        up_ul_tnl_length;
+  rlc_mode_t     rlc_mode;
+} f1ap_drb_to_be_setup_t;
+
+typedef struct f1ap_ue_context_setup_req_s {
+  uint32_t gNB_CU_ue_id;
+  uint32_t *gNB_DU_ue_id;
+  // SpCell Info
+  uint16_t mcc;
+  uint16_t mnc;
+  uint8_t  mnc_digit_length;
+  uint64_t nr_cellid;
+  uint32_t servCellId;
+  uint8_t *cu_to_du_rrc_information;
+  uint8_t  cu_to_du_rrc_information_length;
+  f1ap_drb_to_be_setup_t *drbs_to_be_setup;
+  uint8_t  drbs_to_be_setup_length;
+} f1ap_ue_context_setup_req_t;
 
 #endif /* F1AP_MESSAGES_TYPES_H_ */
diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c
index 7198effdad..75f59c837a 100644
--- a/openair2/F1AP/f1ap_cu_interface_management.c
+++ b/openair2/F1AP/f1ap_cu_interface_management.c
@@ -633,12 +633,12 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_
        F1AP_CP_TransportLayerAddress_t transportLayerAddress;
        memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
        transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
-       TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
        
        // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
        // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
        // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
-       // TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
 
        gnb_cu_tnl_association_to_add_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
 
@@ -680,12 +680,12 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_
        F1AP_CP_TransportLayerAddress_t transportLayerAddress;
        memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
        transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
-       TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
        
        // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
        // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
        // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
-       // TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
 
        gnb_cu_tnl_association_to_remove_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
    
@@ -722,12 +722,12 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_
        F1AP_CP_TransportLayerAddress_t transportLayerAddress;
        memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
        transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address;
-       TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address);
        
        // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t));
        // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port;
        // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t));
-       // TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
+       // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address);
 
        gnb_cu_tnl_association_to_update_item.tNLAssociationTransportLayerAddress = transportLayerAddress;
    
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index 49398f91a1..82f97e4758 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -36,20 +36,17 @@
 #include "f1ap_itti_messaging.h"
 #include "f1ap_cu_ue_context_management.h"
 
-//void CU_send_UE_CONTEXT_SETUP_REQUEST(F1AP_UEContextSetupRequest_t *UEContextSetupRequest) {
-int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
+extern f1ap_setup_req_t *f1ap_du_data_from_du;
+
+int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
+                                     f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req) {
   F1AP_F1AP_PDU_t                 pdu;
   F1AP_UEContextSetupRequest_t    *out;
   F1AP_UEContextSetupRequestIEs_t *ie;
 
   uint8_t  *buffer;
   uint32_t  len;
-  int       i = 0;
-
-  // for test
-  int mcc = 208;
-  int mnc = 93;
-  int mnc_digit_length = 8;
+  int       i = 0, j = 0;
 
   /* Create */
   /* 0. Message Type */
@@ -67,17 +64,17 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
   ie->id                             = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
   ie->criticality                    = F1AP_Criticality_reject;
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
-  ie->value.choice.GNB_CU_UE_F1AP_ID = 126L;
+  ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id;
   ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
 
   /* optional */
   /* c2. GNB_DU_UE_F1AP_ID */
-  if (0) {
+  if (f1ap_ue_context_setup_req->gNB_DU_ue_id) {
     ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t));
     ie->id                             = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
     ie->criticality                    = F1AP_Criticality_ignore;
     ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
-    ie->value.choice.GNB_DU_UE_F1AP_ID = 651L;
+    ie->value.choice.GNB_DU_UE_F1AP_ID = *f1ap_ue_context_setup_req->gNB_DU_ue_id;
     ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
   }
 
@@ -89,9 +86,11 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_NRCGI;
   /* - nRCGI */
   F1AP_NRCGI_t nRCGI;
-  MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
-                                       &nRCGI.pLMN_Identity);
-  NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+  MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc,
+                    f1ap_ue_context_setup_req->mnc,
+                    f1ap_ue_context_setup_req->mnc_digit_length,
+                    &nRCGI.pLMN_Identity);
+  NR_CELL_ID_TO_BIT_STRING(f1ap_ue_context_setup_req->nr_cellid, &nRCGI.nRCellIdentity);
 
   ie->value.choice.NRCGI = nRCGI;
 
@@ -141,7 +140,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List;
 
   for (i=0;
-       i<1;
+       i<0;
        i++) {
 
     F1AP_Candidate_SpCell_ItemIEs_t *candidate_spCell_item_ies;
@@ -156,9 +155,12 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
 
     /* - candidate_SpCell_ID */
     F1AP_NRCGI_t nRCGI;
-    MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
-                                       &nRCGI.pLMN_Identity);
-    NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+    /* TODO add correct mcc/mnc */
+    MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc,
+                      f1ap_ue_context_setup_req->mnc,
+                      f1ap_ue_context_setup_req->mnc_digit_length,
+                      &nRCGI.pLMN_Identity);
+    NR_CELL_ID_TO_BIT_STRING(f1ap_ue_context_setup_req->nr_cellid, &nRCGI.nRCellIdentity);
 
     candidate_spCell_item.candidate_SpCell_ID = nRCGI;
 
@@ -198,7 +200,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
     
     ie->value.choice.ResourceCoordinationTransferContainer.buf = malloc(4);
     ie->value.choice.ResourceCoordinationTransferContainer.size = 4;
-    *ie->value.choice.ResourceCoordinationTransferContainer.buf = "123";
+    strncpy(ie->value.choice.ResourceCoordinationTransferContainer.buf, "123", 3);
 
 
     OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
@@ -215,7 +217,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List;
 
   for (i=0;
-       i<1;
+       i<0;
        i++) {
      //
      F1AP_SCell_ToBeSetup_ItemIEs_t *scell_toBeSetup_item_ies;
@@ -230,8 +232,11 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
 
      //   /* - sCell_ID */
      F1AP_NRCGI_t nRCGI;
-     MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length,
-                                        &nRCGI.pLMN_Identity);
+     /* TODO correct MCC/MNC */
+     MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc,
+                       f1ap_ue_context_setup_req->mnc,
+                       f1ap_ue_context_setup_req->mnc_digit_length,
+                       &nRCGI.pLMN_Identity);
      NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
 
      scell_toBeSetup_item.sCell_ID = nRCGI;
@@ -254,7 +259,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List;
 
   for (i=0;
-       i<1;
+       i<0;
        i++) {
     //
     F1AP_SRBs_ToBeSetup_ItemIEs_t *srbs_toBeSetup_item_ies;
@@ -284,9 +289,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
   ie->criticality                    = F1AP_Criticality_reject;
   ie->value.present                  = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List;
 
-  for (i=0;
-       i<1;
-       i++) {
+  for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) {
     //
     F1AP_DRBs_ToBeSetup_ItemIEs_t *drbs_toBeSetup_item_ies;
     drbs_toBeSetup_item_ies = (F1AP_DRBs_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeSetup_ItemIEs_t));
@@ -299,7 +302,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
     memset((void *)&drbs_toBeSetup_item, 0, sizeof(F1AP_DRBs_ToBeSetup_Item_t));
 
     /* dRBID */
-    drbs_toBeSetup_item.dRBID = 30L;
+    drbs_toBeSetup_item.dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id;
 
     /* qoSInformation */
     drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS;
@@ -307,30 +310,35 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance) {
     drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->qCI = 254L;
 
     /* ULTunnels_ToBeSetup_List */
-    int maxnoofULTunnels = 1; // 2;
-    for (i=0;
-            i<maxnoofULTunnels;
-            i++) {
-            /*  ULTunnels_ToBeSetup_Item */
-            F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item;
+    for (j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
+      f1ap_up_tnl_t *up_tnl = &f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j];
+      /*  ULTunnels_ToBeSetup_Item */
+      F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item;
 
-            // gTPTunnel
-            uLUPTNLInformation_ToBeSetup_Item = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t));
-            uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
-            F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
+      // gTPTunnel
+      uLUPTNLInformation_ToBeSetup_Item = calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t));
+      uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present =
+          F1AP_UPTransportLayerInformation_PR_gTPTunnel;
+      F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
 
-            TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(up_tnl->tl_address, &gTPTunnel->transportLayerAddress);
 
-            OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1234",
-                           strlen("1234"));
-            
-            uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
+      INT32_TO_OCTET_STRING(up_tnl->gtp_teid, &gTPTunnel->gTP_TEID);
+
+      uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel;
 
-            ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item);
+      ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item);
     }
 
     /* rLCMode */
-    drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_um; // enum
+    /* TODO use rlc_mode from f1ap_drb_to_be_setup */
+    switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) {
+    case RLC_MODE_AM:
+      drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_am;
+      break;
+    default:
+      drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_um;
+    }
 
     /* OPTIONAL */
     /* ULConfiguration */
@@ -445,7 +453,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
 
   /* optional */
   /* c3. NRCGI */
-  if (1) {
+  if (0) {
     ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t));
     ie->id                             = F1AP_ProtocolIE_ID_id_SpCell_ID;
     ie->criticality                    = F1AP_Criticality_ignore;
@@ -703,7 +711,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
             uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
             F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
 
-            TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+            TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
 
             OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567",
                              strlen("4567"));
@@ -771,7 +779,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
             uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
             F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
 
-            TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+            TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
 
             OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
                                  strlen("1204"));
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h
index f103a17073..9e25309aa9 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.h
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.h
@@ -36,7 +36,8 @@
 /*
  * UE Context Setup
  */
-int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance);
+int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance,
+                                     f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req);
 
 int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t       instance,
                                         uint32_t         assoc_id,
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index d4d1020206..76aa4299a1 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -41,8 +41,91 @@ extern f1ap_setup_req_t *f1ap_du_data;
 int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t       instance,
                                        uint32_t         assoc_id,
                                        uint32_t         stream,
-                                       F1AP_F1AP_PDU_t *pdu) {
-  AssertFatal(1==0,"Not implemented yet\n");
+                                       F1AP_F1AP_PDU_t *pdu)
+{
+  MessageDef                      *msg_p; // message to RRC
+  F1AP_UEContextSetupRequest_t    *container;
+  F1AP_UEContextSetupRequestIEs_t *ie;
+  int i;
+
+  DevAssert(pdu);
+
+  msg_p = itti_alloc_new_message(TASK_DU_F1, F1AP_UE_CONTEXT_SETUP_REQ);
+	f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req;
+	f1ap_ue_context_setup_req = &F1AP_UE_CONTEXT_SETUP_REQ(msg_p);
+
+  container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest;
+
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
+  f1ap_ue_context_setup_req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
+
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false);
+  if (ie) {
+    f1ap_ue_context_setup_req->gNB_DU_ue_id = malloc(sizeof(uint32_t));
+    if (f1ap_ue_context_setup_req->gNB_DU_ue_id)
+      *f1ap_ue_context_setup_req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
+  } else {
+    f1ap_ue_context_setup_req->gNB_DU_ue_id = NULL;
+  }
+
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_SpCell_ID, true);
+  PLMNID_TO_MCC_MNC(&ie->value.choice.NRCGI.pLMN_Identity,
+										f1ap_ue_context_setup_req->mcc,
+										f1ap_ue_context_setup_req->mnc,
+                    f1ap_ue_context_setup_req->mnc_digit_length);
+  BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity, f1ap_ue_context_setup_req->nr_cellid);
+
+  /* TODO: decode candidate SpCell */
+
+  /* TODO: decode CUtoDURRCInformation */
+
+  /* TODO: Candidate_SpCell_List */
+
+  /* TODO: SCell_ToBeSetup_List */
+
+  /* TODO: SRBs_ToBeSetup_List */
+
+  /* Decode DRBs_ToBeSetup_List */
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container,
+                             F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List, true);
+  f1ap_ue_context_setup_req->drbs_to_be_setup_length = ie->value.choice.DRBs_ToBeSetup_List.list.count;
+  f1ap_ue_context_setup_req->drbs_to_be_setup = calloc(f1ap_ue_context_setup_req->drbs_to_be_setup_length,
+                                                       sizeof(f1ap_drb_to_be_setup_t));
+  AssertFatal(f1ap_ue_context_setup_req->drbs_to_be_setup,
+              "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n");
+  for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; ++i) {
+    f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_req->drbs_to_be_setup[i];
+    F1AP_DRBs_ToBeSetup_Item_t *drbs_tobesetup_item_p;
+    drbs_tobesetup_item_p = &((F1AP_DRBs_ToBeSetup_ItemIEs_t *)ie->value.choice.DRBs_ToBeSetup_List.list.array[i])->value.choice.DRBs_ToBeSetup_Item;
+
+    drb_p->drb_id = drbs_tobesetup_item_p->dRBID;
+
+    /* TODO in the following, assume only one UP UL TNL is present.
+     * this matches/assumes OAI CU implementation, can be up to 2! */
+    drb_p->up_ul_tnl_length = 1;
+    AssertFatal(drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0,
+                "no UL UP TNL Information in DRBs to be Setup list\n");
+    F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0];
+    F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel;
+    BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address);
+    OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].gtp_teid);
+
+    switch (drbs_tobesetup_item_p->rLCMode) {
+    case F1AP_RLCMode_rlc_am:
+      drb_p->rlc_mode = RLC_MODE_AM;
+      break;
+    default:
+      drb_p->rlc_mode = RLC_MODE_TM;
+      break;
+    }
+  }
+
+  AssertFatal(0, "check configuration, send to appropriate handler\n");
+
+  return 0;
 }
 
 //void DU_send_UE_CONTEXT_SETUP_RESPONSE(F1AP_UEContextSetupResponse_t *UEContextSetupResponse) {
@@ -153,7 +236,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance) {
        // *transportLayerAddress.buf = 123;
        // dLUPTNLInformation_ToBeSetup_Item.dL_GTP_Tunnel_EndPoint.transportLayerAddress = transportLayerAddress;
 
-       TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+       TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
 
        OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
                              strlen("1204"));
@@ -441,7 +524,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
         dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
         F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
 
-        TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
 
         OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
                              strlen("1204"));
@@ -495,7 +578,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
         dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
         F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t));
 
-        TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
+        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress);
 
         OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204",
                               strlen("1204"));
diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h
index 71ca1616fd..e2773aeedf 100644
--- a/openair3/UTILS/conversions.h
+++ b/openair3/UTILS/conversions.h
@@ -196,6 +196,17 @@ do {                                                                           \
     (oCTETsTRING)->size = 3;                                                   \
 } while(0)
 
+#define PLMNID_TO_MCC_MNC(oCTETsTRING, mCC, mNC, mNCdIGITlENGTH)                  \
+do {                                                                              \
+    mCC = ((oCTETsTRING)->buf[0] & 0x0F) * 100 +                                  \
+          ((oCTETsTRING)->buf[0] >> 4 & 0x0F) * 10 +                              \
+          ((oCTETsTRING)->buf[1] & 0x0F);                                         \
+    mNCdIGITlENGTH = ((oCTETsTRING)->buf[1] >> 4 & 0x0F) == 0xF ? 2 : 3;          \
+    mNC = (mNCdIGITlENGTH == 2 ? 0 : ((oCTETsTRING)->buf[1] >> 4 & 0x0F) * 100) + \
+          ((oCTETsTRING)->buf[2] & 0x0F) * 10 +                                   \
+          ((oCTETsTRING)->buf[2] >> 4 & 0x0F);                                    \
+} while (0)
+
 #define MCC_MNC_TO_TBCD(mCC, mNC, mNCdIGITlENGTH, tBCDsTRING)        \
 do {                                                                 \
     char _buf[3];                                                    \
@@ -260,7 +271,7 @@ do {                                                                    \
 
 
 /* TS 38.473 v15.2.1 section 9.3.1.32:
- * C RNTI
+ * C RNTI is BIT_STRING(16)
  */
 #define C_RNTI_TO_BIT_STRING(mACRO, bITsTRING)          \
 do {                                                    \
@@ -272,21 +283,31 @@ do {                                                    \
 } while(0)
 
 
-/* TS 38.473 v15.1.1 section 9.3.2.1:
- * TRANSPORT LAYER ADDRESS
+/* TS 38.473 v15.1.1 section 9.3.2.3:
+ * TRANSPORT LAYER ADDRESS for IPv4 is 32bit (TS 38.414)
  */
-#define TRANSPORT_LAYER_ADDRESS_TO_BIT_STRING(mACRO, bITsTRING)    \
+#define TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(mACRO, bITsTRING)    \
 do {                                                    \
-    (bITsTRING)->buf = calloc(5, sizeof(uint8_t));      \
-    (bITsTRING)->buf[0] = (mACRO) >> 28;                \
-    (bITsTRING)->buf[1] = (mACRO) >> 20;                \
-    (bITsTRING)->buf[2] = (mACRO) >> 12;                \
-    (bITsTRING)->buf[3] = (mACRO) >> 4;                 \
-    (bITsTRING)->buf[4] = ((mACRO) & 0x0f) << 4;        \
-    (bITsTRING)->size = 5;                              \
-    (bITsTRING)->bits_unused = 4;                       \
+    (bITsTRING)->buf = calloc(4, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = (mACRO) >> 24 & 0xFF;         \
+    (bITsTRING)->buf[1] = (mACRO) >> 16 & 0xFF;         \
+    (bITsTRING)->buf[2] = (mACRO) >> 8 & 0xFF;          \
+    (bITsTRING)->buf[3] = (mACRO) >> 4 & 0xFF;          \
+    (bITsTRING)->size = 4;                              \
+    (bITsTRING)->bits_unused = 0;                       \
 } while(0)
 
+#define BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(bITsTRING, mACRO)    \
+do {                                                                    \
+    DevCheck((bITsTRING)->size == 4, (bITsTRING)->size, 4, 0);          \
+    DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \
+    mACRO = ((bITsTRING)->buf[0] << 24) +                               \
+            ((bITsTRING)->buf[1] << 16) +                               \
+            ((bITsTRING)->buf[2] << 8) +                                \
+            ((bITsTRING)->buf[3]);                                      \
+} while (0)
+
+
 /* TS 38.473 v15.1.1 section 9.3.1.12:
  * NR CELL ID
  */
-- 
GitLab