diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 88fdcd852b..73ff31325f 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -37,6 +37,7 @@ #include "f1ap_cu_interface_management.h" extern f1ap_setup_req_t *f1ap_du_data_from_du; +extern RAN_CONTEXT_t RC; int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { AssertFatal(1==0,"Not implemented yet\n"); @@ -102,8 +103,8 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message(TASK_RRC_ENB, F1AP_SETUP_REQ); - + message_p = itti_alloc_new_message(TASK_CU_F1, F1AP_SETUP_REQ); + /* assoc_id */ F1AP_SETUP_REQ(message_p).assoc_id = assoc_id; @@ -245,10 +246,18 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, ); if (num_cells_available > 0) { - itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + if (RC.nrrrc[0]->node_type == ngran_gNB_CU) { + itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); + } else { + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + } } else { CU_send_F1_SETUP_FAILURE(instance); - itti_free(TASK_RRC_ENB,message_p); + if (RC.nrrrc[0]->node_type == ngran_gNB_CU) { + itti_free(TASK_RRC_GNB,message_p); + } else { + itti_free(TASK_RRC_ENB,message_p); + } return -1; } return 0; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 202e1caff1..5bc9f04083 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -636,7 +636,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { } } - rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr); + rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr); if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { @@ -711,6 +711,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { }// }//End for (k=0; k configuration, &NRRRC_CONFIGURATION_REQ(msg_p), sizeof(NRRRC_CONFIGURATION_REQ(msg_p))); }//End if (num_gnbs>0) @@ -1364,10 +1365,11 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) { // pthread_mutex_unlock(&rrc->cell_info_mutex); // } while (cell_info_configured ==0); - // rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k]; - // rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k]; - // rrc->configuration.tac = F1AP_SETUP_REQ (msg_p).tac[k]; + rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k]; + rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k]; + rrc->configuration.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.physCellId; F1AP_SETUP_REQ (msg_p).nr_pci[k] = 0; F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0; @@ -1381,7 +1383,7 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) { F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_band[0] = 1; F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active = 0; } else { - // for test + /***************** for test *****************/ LOG_I(GNB_APP,"ngran_DU: Configuring Cell %d for FDD\n",k); F1AP_SETUP_REQ (msg_p).fdd_flag = 1; F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn = 26200UL; @@ -1402,6 +1404,7 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) { F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_sul_frequency_bands = 0; F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_sul_band[0] = 7; F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active = 0; + /***************** for test *****************/ } F1AP_SETUP_REQ (msg_p).measurement_timing_information[k] = "0"; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 17a6c86999..8a0240a5f5 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -66,6 +66,7 @@ #include "NR_CellGroupConfig.h" #include "NR_ServingCellConfigCommon.h" #include "NR_EstablishmentCause.h" +#include "NR_SIB1.h" //------------------- #include "intertask_interface.h" @@ -428,7 +429,12 @@ typedef struct { uint8_t *ServingCellConfigCommon; uint8_t sizeof_servingcellconfigcommon; + int physCellId; + NR_BCCH_BCH_Message_t mib; + NR_BCCH_BCH_Message_t *mib_DU; + NR_BCCH_DL_SCH_Message_t *siblock1_DU; + NR_SIB1_t *sib1; int ssb_SubcarrierOffset; int pdsch_AntennaPorts; int pusch_TargetSNRx10; @@ -439,7 +445,6 @@ typedef struct { NR_SRB_INFO SI; NR_SRB_INFO Srb0; int initial_csi_index[MAX_NR_RRC_UE_CONTEXTS]; - int physCellId; int p_gNB; } rrc_gNB_carrier_data_t; @@ -467,6 +472,9 @@ typedef struct gNB_RRC_INST_s { /// NR cell id uint64_t nr_cellid; + // RRC configuration + gNB_RrcConfigurationReq configuration; + // other PLMN parameters /// Mobile country code int mcc; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 31be11e85e..3af54a561d 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -281,7 +281,6 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration } } - char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) { protocol_ctxt_t ctxt; gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; @@ -2344,6 +2343,104 @@ rrc_gNB_decode_dcch( return 0; } +void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { + LOG_I(NR_RRC,"Received F1 Setup Request from gNB_DU %llu (%s)\n",(unsigned long long int)f1_setup_req->gNB_DU_id,f1_setup_req->gNB_DU_name); + int cu_cell_ind = 0; + MessageDef *msg_p = NULL; + + for (int i = 0; i < f1_setup_req->num_cells_available; i++) { + int found_cell=0; + for (int j=0; jconfiguration.mcc[0] == f1_setup_req->mcc[i] && + rrc->configuration.mnc[0] == 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.MIB = malloc(f1_setup_req->mib_length[i]); + rrc->carrier.sizeof_MIB = f1_setup_req->mib_length[i]; + LOG_W(NR_RRC, "instance %d mib length %d\n", i, f1_setup_req->mib_length[i]); + LOG_W(NR_RRC, "instance %d sib1 length %d\n", i, f1_setup_req->sib1_length[i]); + memcpy((void *)rrc->carrier.MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]); + if(0) { + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_BCCH_BCH_Message, + (void **)&rrc->carrier.mib_DU, + f1_setup_req->mib[i], + f1_setup_req->mib_length[i]); + AssertFatal(dec_rval.code == RC_OK, + "[gNB_DU %"PRIu8"] Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits)\n", + j, + dec_rval.consumed ); + NR_BCCH_BCH_Message_t *mib = &rrc->carrier.mib; + NR_BCCH_BCH_Message_t *mib_DU = rrc->carrier.mib_DU; + mib->message.present = NR_BCCH_BCH_MessageType_PR_mib; + // mib->message.choice.mib = calloc(1, sizeof(NR_MIB_t)); + mib->message.choice.mib = mib_DU->message.choice.mib; + + rrc->carrier.SIB1 = malloc(f1_setup_req->sib1_length[i]); + rrc->carrier.sizeof_SIB1 = f1_setup_req->sib1_length[i]; + memcpy((void *)rrc->carrier.SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); + dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_BCCH_DL_SCH_Message, + (void **)&rrc->carrier.siblock1_DU, + f1_setup_req->sib1[i], + f1_setup_req->sib1_length[i]); + AssertFatal(dec_rval.code == RC_OK, + "[gNB_DU %"PRIu8"] Failed to decode NR_BCCH_DLSCH_MESSAGE (%zu bits)\n", + j, + dec_rval.consumed ); + + // Parse message and extract SystemInformationBlockType1 field + NR_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier.siblock1_DU; + AssertFatal(bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1, + "bcch_message->message.present != NR_BCCH_DL_SCH_MessageType_PR_c1\n"); + AssertFatal(bcch_message->message.choice.c1->present == NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1, + "bcch_message->message.choice.c1->present != NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n"); + rrc->carrier.sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + rrc->carrier.physCellId = f1_setup_req->nr_pci[i]; + } + + // prepare F1_SETUP_RESPONSE + if (msg_p == NULL) { + msg_p = itti_alloc_new_message (TASK_RRC_GNB,F1AP_SETUP_RESP); + } + + F1AP_SETUP_RESP (msg_p).gNB_CU_name = rrc->node_name; + F1AP_SETUP_RESP (msg_p).mcc[cu_cell_ind] = rrc->configuration.mcc[0]; + F1AP_SETUP_RESP (msg_p).mnc[cu_cell_ind] = rrc->configuration.mnc[0]; + F1AP_SETUP_RESP (msg_p).mnc_digit_length[cu_cell_ind] = rrc->configuration.mnc_digit_length[0]; + 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.SIB23) { + // F1AP_SETUP_RESP (msg_p).SI_container[cu_cell_ind][num_SI] = rrc->carrier.SIB23; + // F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][num_SI] = rrc->carrier.sizeof_SIB23; + // num_SI++; + // } + + F1AP_SETUP_RESP (msg_p).num_SI[cu_cell_ind] = num_SI; + cu_cell_ind++; + found_cell=1; + F1AP_SETUP_RESP (msg_p).num_cells_to_activate = cu_cell_ind; + // send ITTI message to F1AP-CU task + itti_send_msg_to_task (TASK_CU_F1, GNB_MODULE_ID_TO_INSTANCE(j), msg_p); + break; + } else {// setup_req mcc/mnc match rrc internal list element + LOG_W(NR_RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d \n", + j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],rrc->configuration.mnc[0], f1_setup_req->mnc[i]); + } + }// for (int j=0;jnum_cells_available;i++) +} + void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) { gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; @@ -2523,6 +2620,14 @@ void *rrc_gnb_task(void *args_p) { openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p)); break; + /* Messages from F1AP task */ + case F1AP_SETUP_REQ: + AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type), + "should not receive F1AP_SETUP_REQUEST, need call by CU!\n"); + LOG_I(NR_RRC,"[gNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p)); + rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); + break; + /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n");