From 825c33df1b4368114e6bf99fbfb2028ac332bf8d Mon Sep 17 00:00:00 2001
From: Raymond Knopp <raymond.knopp@eurecom.fr>
Date: Sun, 16 Sep 2018 23:07:14 +0200
Subject: [PATCH] handling of nr_cellid and creation of context upon CCCH
 transmission. Connection goes until generation of RRCConnectionSetup in CU
 which crashes (it calls rrc_mac_config_req. For DU this should be replaced
 with filling DL_RRC_MESSAGE_TRANSFER

---
 openair2/COMMON/f1ap_messages_types.h         |  9 ++++-
 openair2/ENB_APP/enb_app.c                    |  2 +-
 openair2/ENB_APP/enb_config.c                 | 38 ++++++++++++-------
 openair2/ENB_APP/enb_paramdef.h               |  4 +-
 openair2/F1AP/f1ap_cu_interface_management.c  | 15 ++++++--
 openair2/F1AP/f1ap_cu_rrc_message_transfer.c  | 22 ++++++++++-
 openair2/F1AP/f1ap_du_interface_management.c  | 25 +++++++++++-
 openair2/F1AP/f1ap_du_task.c                  |  5 ++-
 openair2/RRC/LTE/rrc_defs.h                   |  3 +-
 openair2/RRC/LTE/rrc_eNB.c                    | 27 ++++++++++---
 openair3/UTILS/conversions.h                  |  7 ++++
 .../PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf |  2 +
 .../CONF/du.lte.band7.10MHz.if4p5.conf        |  2 +
 13 files changed, 128 insertions(+), 33 deletions(-)

diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
index 824cf657a5..1c1fe6ed42 100644
--- a/openair2/COMMON/f1ap_messages_types.h
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -101,10 +101,10 @@ typedef struct f1ap_setup_req_s {
   uint16_t mnc[F1AP_MAX_NB_CELLS];//[6];
   uint8_t  mnc_digit_length[F1AP_MAX_NB_CELLS];//[6];
 
+  // NR Global Cell Id
+  uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
   // NR Physical Cell Ids
   uint16_t nr_pci[F1AP_MAX_NB_CELLS];
-  // NR Cell Ids
-  uint8_t nr_cellid[F1AP_MAX_NB_CELLS];
   // Number of slide support items (max 16, could be increased to as much as 1024)
   uint16_t num_ssi[F1AP_MAX_NB_CELLS];//[6];
   uint8_t sst[F1AP_MAX_NB_CELLS];//[16][6];
@@ -189,6 +189,8 @@ typedef struct f1ap_setup_resp_s {
   uint16_t mnc[F1AP_MAX_NB_CELLS];
   /// mnc digit length of DU cells
   uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS];
+  // NR Global Cell Id
+  uint64_t nr_cellid[F1AP_MAX_NB_CELLS];
   /// NRPCI
   uint16_t nrpci[F1AP_MAX_NB_CELLS];
   /// num SI messages per DU cell
@@ -228,6 +230,9 @@ typedef struct f1ap_initial_ul_rrc_message_s {
   uint16_t mnc;
   /// mnc digit length of DU cells
   uint8_t mnc_digit_length;
+  /// nr cell id
+  uint64_t nr_cellid;
+  /// crnti
   uint16_t crnti;
   uint8_t *rrc_container;
   int      rrc_container_length;
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index 2f86d38fa6..02e91ad486 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -235,7 +235,7 @@ void *eNB_app_task(void *args_p)
     case F1AP_SETUP_RESP:
       AssertFatal(RC.rrc[0]->node_type == ngran_eNB_DU, "Should not have received F1AP_REGISTER_ENB_CNF in CU/eNB\n");
 
-      LOG_I(ENB_APP, "[eNB %d] Received %s: associated ngran_eNB_CU %s with %d cells to activate\n", instance, ITTI_MSG_NAME (msg_p),
+      LOG_I(ENB_APP, "Received %s: associated ngran_eNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
 	    F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
       
       handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index f9ae28259a..872a5ff358 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -799,12 +799,6 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc) {
 	rrc->sctp_in_streams                       = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
 	rrc->sctp_out_streams                      = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
 
-  // MCC and MNC
-	rrc->mcc= (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX].strptr) );
-	rrc->mnc= (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr) );
-	rrc->mnc_digit_length= strlen(*(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
-	rrc->tac= (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].strptr) );
-
       }
       
       else { // no F1
@@ -812,6 +806,13 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc) {
 	rrc->node_type                             = ngran_eNB;
       }	      
 
+      // MCC and MNC
+      rrc->mcc              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX].strptr) );
+      rrc->mnc              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr) );
+      rrc->mnc_digit_length = strlen(*(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
+      rrc->tac              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].strptr) );
+      rrc->nr_cellid        = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
+
       // search if in active list
 
       LOG_I(RRC,"RRC instances %d\n",num_enbs);
@@ -2404,7 +2405,10 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
                     (F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 3),
                     "BAD MNC DIGIT LENGTH %d",
                     F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]);
-	
+
+	F1AP_SETUP_REQ (msg_p).nr_cellid[k] = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr);
+        LOG_I(ENB_APP,"F1AP: nr_cellid[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).nr_cellid[k]);
+
         LOG_I(ENB_APP,"F1AP: CU_ip4_address in DU %s\n",RC.mac[k]->eth_params_n.remote_addr);
         LOG_I(ENB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.remote_addr));
  	
@@ -2440,9 +2444,13 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) {
           pthread_mutex_unlock(&rrc->cell_info_mutex);
         } while (cell_info_configured ==0);
 
-      	
+
+	rrc->mcc       = F1AP_SETUP_REQ (msg_p).mcc[k];
+	rrc->mnc       = F1AP_SETUP_REQ (msg_p).mnc[k];
+	rrc->tac       = F1AP_SETUP_REQ (msg_p).tac[k];
+	rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).nr_cellid[k];
+
         F1AP_SETUP_REQ (msg_p).nr_pci[k]    = rrc->carrier[0].physCellId;
-        F1AP_SETUP_REQ (msg_p).nr_cellid[k] = 0;
         F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0;
 
 
@@ -3077,13 +3085,17 @@ void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
 
 
   int i,j,si_ind;
-  
+  printf("cells_to_activated %d, RRC instances %d\n",
+	 resp->num_cells_to_activate,RC.nb_inst);
   for (j=0;j<resp->num_cells_to_activate;j++) {
     for (i=0;i<RC.nb_inst;i++) {
       rrc_eNB_carrier_data_t *carrier =  &RC.rrc[i]->carrier[0];
-      // identify local index of cell j by plmn identity
-      if (check_plmn_identity(carrier, resp->mcc[j], resp->mnc[j], resp->mnc_digit_length[j])>0 &&
-          resp->nrpci[j] == carrier->physCellId) {
+      // identify local index of cell j by nr_cellid, plmn identity and physical cell ID
+      printf("Checking cell %d, rrc inst %d : rrc->nr_cellid %x, resp->nr_cellid %x\n",
+	     j,i,RC.rrc[i]->nr_cellid,resp->nr_cellid[j]);
+      if (RC.rrc[i]->nr_cellid == resp->nr_cellid[j] && 
+	  (check_plmn_identity(carrier, resp->mcc[j], resp->mnc[j], resp->mnc_digit_length[j])>0 &&
+	   resp->nrpci[j] == carrier->physCellId)) {
 	// copy system information and decode it 
 	for (si_ind=0;si_ind<resp->num_SI[j];si_ind++)  {
 	  printf("SI %d: ",si_ind);
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 1da25ec7b9..c7dfee7bda 100755
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -195,7 +195,7 @@ typedef enum {
 #define ENB_CONFIG_STRING_REMOTE_S_PORTC                "remote_s_portc"
 #define ENB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
 #define ENB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
-
+#define ENB_CONFIG_STRING_NR_CELLID                     "nr_cellid"
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            cell configuration parameters                                                                */
 /*   optname                                   helpstr   paramflags    XXXptr        defXXXval                   type           numelt     */
@@ -215,6 +215,7 @@ typedef enum {
 {ENB_CONFIG_STRING_REMOTE_S_PORTC,               NULL,   0,            uptr:NULL,   defuintval:50000,            TYPE_UINT,      0},  \
 {ENB_CONFIG_STRING_LOCAL_S_PORTD,                NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
 {ENB_CONFIG_STRING_REMOTE_S_PORTD,               NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_NR_CELLID,                    NULL,   0,            u64ptr:NULL,   defint64val:0,                TYPE_UINT64,    0},  \
 }															     	
 #define ENB_ENB_ID_IDX                  0
 #define ENB_CELL_TYPE_IDX               1
@@ -230,6 +231,7 @@ typedef enum {
 #define ENB_REMOTE_S_PORTC_IDX          11
 #define ENB_LOCAL_S_PORTD_IDX           12
 #define ENB_REMOTE_S_PORTD_IDX          13
+#define ENB_NRCELLID_IDX                14
 /*-------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------------------------------------------------------------------------------*/		  
 
diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c
index 650bbb1729..0d55e8be1e 100644
--- a/openair2/F1AP/f1ap_cu_interface_management.c
+++ b/openair2/F1AP/f1ap_cu_interface_management.c
@@ -146,13 +146,20 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance,
                     F1AP_SETUP_REQ(message_p).mnc[i],
                     F1AP_SETUP_REQ(message_p).mnc_digit_length[i]);
     
-    // @issue in here cellID
-    F1AP_SETUP_REQ(message_p).nr_cellid[i] = 1;
+    
+    // NR cellID
+    BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity,
+				   F1AP_SETUP_REQ(message_p).nr_cellid[i]);
     printf("[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %d\n", assoc_id,
                F1AP_SETUP_REQ(message_p).mcc[i],
                F1AP_SETUP_REQ(message_p).mnc[i],
                F1AP_SETUP_REQ(message_p).nr_cellid[i]);
-    
+    printf("nr_cellId : %x %x %x %x %x\n",
+	   served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0],
+	   served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1],
+	   served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2],
+	   served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3],
+	   served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]);    
     /* - nRPCI */
     F1AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI;
     printf ("F1AP_SETUP_REQ(message_p).nr_pci[%d] %d \n", i, F1AP_SETUP_REQ(message_p).nr_pci[i]);
@@ -306,7 +313,7 @@ int CU_send_F1_SETUP_RESPONSE(instance_t instance,
     F1AP_NRCGI_t nRCGI;
     MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i],
                                      &nRCGI.pLMN_Identity);
-    NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity);
+    NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity);
     cells_to_be_activated_list_item.nRCGI = nRCGI;
 
     /* optional */
diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
index 78090104bb..fb2b47c8df 100644
--- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c
@@ -35,6 +35,9 @@
 #include "f1ap_decoder.h"
 #include "f1ap_itti_messaging.h"
 #include "f1ap_cu_rrc_message_transfer.h"
+#include "common/ran_context.h"
+#include "openair3/UTILS/conversions.h"
+
 // undefine C_RNTI from
 // openair1/PHY/LTE_TRANSPORT/transport_common.h which
 // replaces in ie->value.choice.C_RNTI, causing
@@ -45,6 +48,8 @@
     Initial UL RRC Message Transfer
 */
 
+extern RAN_CONTEXT_t RC;
+
 int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
                                               uint32_t               assoc_id,
                                               uint32_t               stream,
@@ -84,6 +89,9 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
   F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                              F1AP_ProtocolIE_ID_id_NRCGI, true);
 
+  uint64_t nr_cellid;
+  BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid);
+					       
   /* RNTI */
   F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container,
                              F1AP_ProtocolIE_ID_id_C_RNTI, true);
@@ -102,14 +110,24 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t             instance,
   printf ("RRCContainer(CCCH) :");
   for (int i=0;i<ie->value.choice.RRCContainer.size;i++) printf("%2x ",RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]);
 
+  // Find instance from nr_cellid
+  int rrc_inst = -1;
+  for (int i=0;i<RC.nb_inst;i++) {
+          // first get RRC instance (note, no the ITTI instance)
+    eNB_RRC_INST *rrc = RC.rrc[i];
+    if (rrc->nr_cellid == nr_cellid) {
+      rrc_inst = i; 
+      break;
+    }
+  }
+  AssertFatal(rrc_inst>=0,"couldn't find an RRC instance for nr_cell %ll\n",nr_cellid);
 
   RRC_MAC_CCCH_DATA_IND (message_p).frame     = 0; 
   RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0;
   RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = ccch_sdu_len;
-  RRC_MAC_CCCH_DATA_IND (message_p).enb_index = instance; // CU instance 
+  RRC_MAC_CCCH_DATA_IND (message_p).enb_index = rrc_inst; // CU instance 
   RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rnti;
   RRC_MAC_CCCH_DATA_IND (message_p).CC_id      = CC_id; 
-  printf("Sending ITTI message to instance %d, rnti %x\n",instance,rnti);
   itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p);
 
 
diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c
index be36af0a1b..47e1932f19 100644
--- a/openair2/F1AP/f1ap_du_interface_management.c
+++ b/openair2/F1AP/f1ap_du_interface_management.c
@@ -170,9 +170,17 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) {
         /* - nRCGI */
         F1AP_NRCGI_t nRCGI;
         MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &nRCGI.pLMN_Identity);
+	printf("plmn: (%d,%d)\n",f1ap_du_data->mcc[i],f1ap_du_data->mnc[i]);
         //MCC_MNC_TO_PLMNID(208, 95, 2, &nRCGI.pLMN_Identity);
 
         NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[i], &nRCGI.nRCellIdentity);
+	printf("nRCellIdentity (%llx): %x.%x.%x.%x.%x\n",f1ap_du_data->nr_cellid[i],
+	       nRCGI.nRCellIdentity.buf[0],
+	       nRCGI.nRCellIdentity.buf[1],
+	       nRCGI.nRCellIdentity.buf[2],
+	       nRCGI.nRCellIdentity.buf[3],
+	       nRCGI.nRCellIdentity.buf[4]);
+
         served_cell_information.nRCGI = nRCGI;
 
         /* - nRPCI */
@@ -474,14 +482,21 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance,
 
 	 TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i], F1AP_SETUP_RESP (msg_p).mnc_digit_length[i]);
 	 AssertFatal(cell->nRPCI != NULL, "nRPCI is null\n");
-
+	 printf("nr_cellId : %x %x %x %x %x\n",
+		cell->nRCGI.nRCellIdentity.buf[0],
+		cell->nRCGI.nRCellIdentity.buf[1],
+		cell->nRCGI.nRCellIdentity.buf[2],
+		cell->nRCGI.nRCellIdentity.buf[3],
+		cell->nRCGI.nRCellIdentity.buf[4]);
+	 BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity,
+					F1AP_SETUP_RESP (msg_p).nr_cellid[i]);
 	 F1AP_SETUP_RESP (msg_p).nrpci[i] = *cell->nRPCI;
 
 	 F1AP_ProtocolExtensionContainer_160P9_t *ext = cell->iE_Extensions;
 	 AssertFatal(ext!=NULL,"Extension for SI is null\n");
 	 F1AP_SETUP_RESP (msg_p).num_SI[i] = ext->list.count;
 	 AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n");
-	 printf("F1AP: F1Setup-Resp Cell %d MCC %d MNC %d NRPCI %d\n",i,F1AP_SETUP_RESP (msg_p).mcc[i],F1AP_SETUP_RESP (msg_p).mnc[i],F1AP_SETUP_RESP (msg_p).nrpci[i],F1AP_SETUP_RESP (msg_p).num_SI[i]);
+	 printf("F1AP: F1Setup-Resp Cell %d MCC %d MNC %d NRCellid %x num_si %d\n",i,F1AP_SETUP_RESP (msg_p).mcc[i],F1AP_SETUP_RESP (msg_p).mnc[i],F1AP_SETUP_RESP (msg_p).nr_cellid[i],F1AP_SETUP_RESP (msg_p).num_SI[i]);
 	 for (int si =0;si < ext->list.count;si++) {
 	   size_t size = ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.size;
 	   F1AP_SETUP_RESP (msg_p).SI_container_length[i][si] = size;
@@ -585,6 +600,12 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
         /* - nRCGI */
         F1AP_NRCGI_t nRCGI;
         MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &nRCGI.pLMN_Identity);
+	printf("nr_cellId : %x %x %x %x %x\n",
+	       nRCGI.nRCellIdentity.buf[0],
+	       nRCGI.nRCellIdentity.buf[1],
+	       nRCGI.nRCellIdentity.buf[2],
+	       nRCGI.nRCellIdentity.buf[3],
+	       nRCGI.nRCellIdentity.buf[4]);
         NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[i], &nRCGI.nRCellIdentity);
         served_cell_information.nRCGI = nRCGI;
 
diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c
index 1bc49270f0..5edcf01437 100644
--- a/openair2/F1AP/f1ap_du_task.c
+++ b/openair2/F1AP/f1ap_du_task.c
@@ -68,7 +68,8 @@ void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1
   f1ap_du_data = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t));
   *f1ap_du_data = *f1ap_setup_req;
   //printf("sib itti message %s\n", f1ap_setup_req_t->sib1[0]);
-  printf("sib f1ap context %s\n", f1ap_du_data->sib1[0]);
+
+  printf("nr_cellid : %llx (%lld)",f1ap_setup_req->nr_cellid[0],f1ap_setup_req->nr_cellid[0]);
   
   //du_f1ap_register_to_sctp
   itti_send_msg_to_task(TASK_SCTP, instance, message_p);
@@ -175,4 +176,4 @@ void *F1AP_DU_task(void *arg) {
   } // while
 
   return NULL;
-}
\ No newline at end of file
+}
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index ad7d2f31f6..7408f64f35 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -714,7 +714,8 @@ typedef struct eNB_RRC_INST_s {
   int mnc_digit_length;
   /// tac
   int tac;
-
+  /// NR cell id
+  uint64_t nr_cellid;
   // other RAN parameters
   int srb1_timer_poll_retransmit;
   int srb1_poll_pdu;
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 1f5cd605ba..0e6a8bc222 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -7308,8 +7308,11 @@ void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
     int found_cell=0;
     for (int j=0;j<RC.nb_inst;j++) {
       eNB_RRC_INST *rrc = RC.rrc[j];
-      if (rrc->mcc == f1_setup_req->mcc[i] && rrc->mnc == f1_setup_req->mnc[i]) {
-        // RK: cu_cell_ind is the index for cu_cell_ind, could you confirm? 
+      if (rrc->mcc == f1_setup_req->mcc[i] && 
+	  rrc->mnc == f1_setup_req->mnc[i] && 
+	  rrc->nr_cellid == f1_setup_req->nr_cellid[i]) {
+        // check that CU rrc instance corresponds to mcc/mnc/cgi (normally cgi should be enough, but just in case)
+
         rrc->carrier[0].MIB = malloc(f1_setup_req->mib_length[i]);
         rrc->carrier[0].sizeof_MIB = f1_setup_req->mib_length[i];
         LOG_W(RRC, "instance %d mib length %d\n", i, f1_setup_req->mib_length[i]);
@@ -7360,6 +7363,7 @@ void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
         F1AP_SETUP_RESP (msg_p).mcc[cu_cell_ind]                           = rrc->mcc;
         F1AP_SETUP_RESP (msg_p).mnc[cu_cell_ind]                           = rrc->mnc;
         F1AP_SETUP_RESP (msg_p).mnc_digit_length[cu_cell_ind]              = rrc->mnc_digit_length;
+	F1AP_SETUP_RESP (msg_p).nr_cellid[cu_cell_ind]                     = rrc->nr_cellid;
         F1AP_SETUP_RESP (msg_p).nrpci[cu_cell_ind]                         = f1_setup_req->nr_pci[i];
         int num_SI= 0;
         if (rrc->carrier[0].SIB23) {
@@ -7409,6 +7413,7 @@ rrc_enb_task(
   MessageDef                         *msg_p;
   const char                         *msg_name_p;
   instance_t                          instance;
+  int                                rrc_inst;
   int                                 result;
   SRB_INFO                           *srb_info_p;
   int                                 CC_id;
@@ -7426,6 +7431,7 @@ rrc_enb_task(
 
     msg_name_p = ITTI_MSG_NAME(msg_p);
     instance = ITTI_MSG_INSTANCE(msg_p);
+    
     LOG_I(RRC,"Received message %s\n",msg_name_p);
 
     switch (ITTI_MSG_ID(msg_p)) {
@@ -7440,8 +7446,11 @@ rrc_enb_task(
 
       /* Messages from MAC */
     case RRC_MAC_CCCH_DATA_IND:
+
+      rrc_inst = RRC_MAC_CCCH_DATA_IND(msg_p).enb_index;
+
       PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
-                                    instance,
+                                    rrc_inst,
                                     ENB_FLAG_YES,
                                     RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
                                     msg_p->ittiMsgHeader.lte_time.frame,
@@ -7450,15 +7459,23 @@ rrc_enb_task(
             PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt),
             msg_name_p);
 
-      struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance],
+      struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[rrc_inst],
 									 RRC_MAC_CCCH_DATA_IND(msg_p).rnti);
 
+      if (ue_context_p == NULL) {
+
+	// create a ue_context with rnti as random value, will be updated when Attach Request is received
+	ue_context_p = rrc_eNB_get_next_free_ue_context(&ctxt,
+							RRC_MAC_CCCH_DATA_IND(msg_p).rnti
+							);
+      }
+
       CC_id = RRC_MAC_CCCH_DATA_IND(msg_p).CC_id;
       eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; 
       srb_info_p = &ue_p->Srb0;
 
       LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
-	    instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
+	    rrc_inst,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
       if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= RRC_BUFFER_SIZE_MAX) {
           LOG_I(RRC, "CCCH message has size %d > %d\n",RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX);
           break;
diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h
index 04e9712d91..71ca1616fd 100644
--- a/openair3/UTILS/conversions.h
+++ b/openair3/UTILS/conversions.h
@@ -162,6 +162,13 @@ do {                                                                \
         ((aSN)->buf[2] << 4) | (aSN)->buf[3];                       \
 } while(0)
 
+#define BIT_STRING_TO_NR_CELL_IDENTITY(aSN, vALUE)                     \
+do {                                                                   \
+    DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0);       \
+    vALUE = ((aSN)->buf[0] << 28) | ((aSN)->buf[1] << 20) |            \
+        ((aSN)->buf[2] << 12) | ((aSN)->buf[3]<<4) | ((aSN)->buf[4]>>4);  \
+} while(0)
+
 #define MCC_HUNDREDS(vALUE) \
     ((vALUE) / 100)
 /* When MNC is only composed of 2 digits, set the hundreds unit to 0xf */
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf
index ba0bd886a6..8d42fcb761 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf
@@ -19,6 +19,8 @@ eNBs =
 
     mobile_network_code =  "93";
 
+    nr_cellid           = 12345678L
+
     tr_s_preference     = "f1"
 
     local_s_if_name  = "lo";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf
index 360f55d73a..36a4bfde9e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf
@@ -17,6 +17,8 @@ eNBs =
 
     mobile_network_code =  "93";
 
+    nr_cellid           = 12345678L
+ 
     ////////// Physical parameters:
 
     component_carriers = (
-- 
GitLab