diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 149bf1ece04e3a29fccb492129d4f3d71b9cff8e..65b41872bdac3adbe6dc8f326fa05339cab32088 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -22,10 +22,10 @@ /* F1AP -> SCTP */ MESSAGE_DEF(F1AP_CU_SCTP_REQ , MESSAGE_PRIORITY_MED, f1ap_cu_setup_req_t , f1ap_cu_setup_req) -/* eNB application layer -> F1AP messages */ +/* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/ MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req) -/* F1AP -> eNB application layer messages */ +/* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */ MESSAGE_DEF(F1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, f1ap_setup_resp_t , f1ap_setup_resp) MESSAGE_DEF(F1AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED, f1ap_setup_failure_t , f1ap_setup_failure) @@ -41,3 +41,5 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) + + diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 15b6ba2650e6fa113ff850b882596981b4a043a1..d7da511353df51fa1bb9249053b1bfef03570006 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -82,7 +82,7 @@ typedef struct f1ap_setup_req_s { enum cell_type_e cell_type; /// number of DU cells available - uint16_t num_cells_available; //0< num_cells_to_available <= 512; + uint16_t num_cells_available; //0< num_cells_available <= 512; // Served Cell Information /* Tracking area code */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 1d9a08814414e67819b21d460e82a2a0f0304f78..c3236ca4caafa2334fe78297cc356b4f74b45ec5 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -774,11 +774,11 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc) { sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,i,ENB_CONFIG_STRING_SCTP_CONFIG); config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); - int gNB_CU_id = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr); - LOG_I(ENB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,gNB_CU_id); + rrc->node_id = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr); + LOG_I(ENB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id); - char *gNB_CU_name = *(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr); - LOG_I(ENB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,gNB_CU_name); + rrc->node_name = strdup(*(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr); + LOG_I(ENB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name); rrc->eth_params_s.local_if_name = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr)); LOG_I(RRC,"Configuring CU-DU interfaces for MACRLC on %s\n",rrc->eth_params_s.local_if_name); @@ -2363,13 +2363,18 @@ int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) { // Output a list of all eNBs. config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); AssertFatal(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr != NULL, - "eNB id %d is not defined in configuration file\n",i); + "eNB id %d is not defined in configuration file\n",i); + + F1AP_SETUP_REQ (msg_p).num_available_cells = 0; + for (k=0; k <num_enbs ; k++) { if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) { paramdef_t SCTPParams[] = SCTPPARAMS_DESC; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + F1AP_SETUP_REQ (msg_p).num_available_cells++; + F1AP_SETUP_REQ (msg_p).gNB_DU_id = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr); LOG_I(ENB_APP,"F1AP: gNB_DU_id[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_id); diff --git a/openair2/F1AP/f1ap_cu.c b/openair2/F1AP/f1ap_cu.c index 7c2c6441045ec0970cb334bae023482e9d34159a..7ab5739b15927b1e94e921c54f065ab207b31215 100644 --- a/openair2/F1AP/f1ap_cu.c +++ b/openair2/F1AP/f1ap_cu.c @@ -208,7 +208,9 @@ void CU_handle_F1_SETUP_REQUEST(F1AP_F1SetupRequest_t *message_p) { } /* decode */ //CU_F1AP_decode(args_p); - + // fill in f1ap_setup_req message for RRC task + + /* handle */ // send successful callback diff --git a/openair2/F1AP/f1ap_du.c b/openair2/F1AP/f1ap_du.c index 978a0356cfeb6bedae8aabd6e3e94ea51bb93e01..ff77379167072f1b074147e6058fdcc453e9baf6 100644 --- a/openair2/F1AP/f1ap_du.c +++ b/openair2/F1AP/f1ap_du.c @@ -64,7 +64,7 @@ typedef struct f1ap_info { uint16_t in_streams; uint16_t out_streams; - /* Connexion id used between SCTP/S1AP */ + /* Connexion id used between SCTP/F1AP */ uint16_t cnx_id; /* SCTP association id */ diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index ae3dd3402d386f0c19dcef43cd377b5ce4247a80..968f2fb942b9252ee485e04f4cb66569b4328d1a 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -642,7 +642,9 @@ typedef struct { uint32_t ul_CarrierFreq; uint32_t pbch_repetition; BCCH_BCH_Message_t mib; + BCCH_BCH_Message_t *mib_DU; BCCH_DL_SCH_Message_t siblock1; + BCCH_DL_SCH_Message_t *siblock1_DU; BCCH_DL_SCH_Message_t systemInformation; // SystemInformation_t systemInformation; SystemInformationBlockType1_t *sib1; @@ -679,6 +681,8 @@ typedef struct eNB_RRC_INST_s { /// southbound midhaul configuration ngran_node_t node_type; eth_params_t eth_params_s; + char *node_name; + uint32_t node_id; rrc_eNB_carrier_data_t carrier[MAX_NUM_CCs]; uid_allocator_t uid_allocator; // for rrc_ue_head RB_HEAD(rrc_ue_tree_s, rrc_eNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 8dcff3bf576e216c027dcf2dc73515897a10ba2a..f9c47a5edba5778bf72f2c6ca3afeaa77c92888b 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -7274,7 +7274,100 @@ void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP, rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0); } +void handle_f1_setup_request(f1ap_setup_req_t *f1_setup_req) { + + f1ap_setup_resp_t *f1_setup_resp=NULL; + + LOG_I(RRC,"Received F1 Setup Request from gNB_DU %d (%s)\n",f1_setup_req->gNB_DU_id,f1_setup_req->gNB_DU_name); + + uint16_t num_cells_to_activate = 0; + + int cu_cell_ind=0; + + for (int i=0;i<f1_setup_req->num_cells_available;i++) { + // check that mcc/mnc match and grab MIB/SIB1 + 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]) { + rrc->carrier[0].MIB = malloc(f1_setup_req->mib_length[i]); + rrc->carrier[0].mib_length = f1_setup_req->mib_length[i]; + + memcpy((void*)rrc->carrier[0].MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]); + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_BCCH_BCH_Message, + (void **)&rrc->carrier[0].mib_DU, + f1_setup_req->mib[i], + f1_setup_req->mib_length[i]); + AssertFatal(dec_rval.code == RC_OK, + "[eNB_DU %"PRIu8"] Failed to decode BCCH_BCH_MESSAGE (%zu bits)\n", + j, + dec_rval.consumed ); + BCCH_BCH_Message_t *mib = rrc->carrier[0].mib; + BCCH_BCH_Message_t *mib_DU = rrc->carrier[0].mib_DU; + mib->message.dl_Bandwidth = mib_DU->message_dl_Bandwidth; + mib->message.phich_Config.phich_Resource = mib_DU->message.phich_Config.phich_Resource; + mib->message.phich_Config.phich_duration = mib_DU->message.phich_Config.phich_duration; + + rrc->carrier[0].SIB1 = malloc(f1_setup_req->sib1_length[i]); + rrc->carrier[0].sib1_length = f1_setup_req->sib1_length[i]; + memcpy((void*)rrc->carrier[0].SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); + dec_rval = uper_decode_complete(NULL, + &asn_DEF_BCCH_DL_SCH_Message, + (void **)&rrc->carrier[0].siblock1_DU, + f1_setup_req->sib1[i], + f1_setup_req->sib1_length[i]); + AssertFatal(dec_rval.code == RC_OK, + "[eNB_DU %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", + j, + dec_rval.consumed ); + // Parse message and extract SystemInformationBlockType1 field + BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier[0].siblock1_DU; + AssertFatal(bcch_message->message.present == BCCH_DL_SCH_MessageType_PR_c1, + "bcch_message->message.present != BCCH_DL_SCH_MessageType_PR_c1\n"); + AssertFatal(bcch_message->message.choice.c1.present == BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1, + "bcch_message->message.choice.c1.present != BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n"); + rrc->carrier[0].sib1 = bcch_message->message.choice.c1.choice.systemInformationBlockType1; + rrc->carrier[0].physCellId = f1_setup_req->nrpci[i]; + // prepare F1_SETUP_RESPONSE + + if (msg_p == NULL) { + msg_p = itti_alloc_new_message (TASK_F1AP,F1AP_SETUP_RESP); + F1AP_SETUP_RESP (msg_p).gNB_CU_name = rrc->node_name; + F1AP_SETUP_RESP (msg_p).gNB_CU_id = rrc->node_id; + } + 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).nrpci[cu_cell_ind] = f1_setup_req->nrpci[i]; + int num_SI= 0; + if (rrc->SIB23) { + F1AP_SETUP_RESP (msg_p).SI_container[cu_cell_ind][num_SI] = rrc->SIB23; + F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][num_SI] = rrc->sizeof_SIB23; + num_SI++; + } + F1AP_SETUP_RESP (msg_p).num_SI = num_SI; + // send ITTI message to F1AP-CU task + itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), f1_setup_resp); + cu_cell_ind++; + found_cell=1; + break; + } // setup_req mcc/mnc match rrc internal list element + }// for (int j=0;j<RC.nb_inst;j++) + if (found_cell==0) { + AssertFatal(1==0,"No cell found\n"); + /*msg_p = itti_alloc_new_message (TASK_F1AP,F1AP_SETUP_FAILURE); + F1AP_SETUP_RESP (msg_p).cause = rrc->node_name; + F1AP_SETUP_RESP (msg_p).time_to_wait = rrc->node_id; + F1AP_SETUP_RESP (msg_p).criticality_diagnostics = rrc->node_name;*/ + } + // handle other failure cases + }//for (int i=0;i<f1_setup_req->num_cells_available;i++) +} + + + // ignore 5GNR fields for now, just take MIB and SIB1 //----------------------------------------------------------------------------- void* rrc_enb_task( @@ -7427,7 +7520,16 @@ rrc_enb_task( LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p)); openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance)); break; + / * Messages from F1AP task */ + case F1AP_SETUP_REQUEST: + AssertFatal(RC.rrc[0]->node_type == ngran_eNB_CU || RC.rrc[0]->node_type == ngran_ng_eNB_CU, + "should not receive F1AP_SETUP_REQUEST if this isn't a CU!\n"); + LOG_I(RRC"[eNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p)); + + + handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); + break; default: LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p); break;