From aa18edb8ac1b895731453309ad8c5e4772ca6b87 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 11 Feb 2024 14:55:17 +0100 Subject: [PATCH] gNB-DU config update msg def and handle in CU --- openair2/COMMON/f1ap_messages_def.h | 3 + openair2/COMMON/f1ap_messages_types.h | 55 ++++++++++++++++ openair2/RRC/NR/mac_rrc_dl.h | 2 + openair2/RRC/NR/mac_rrc_dl_direct.c | 7 ++ openair2/RRC/NR/mac_rrc_dl_f1ap.c | 6 ++ openair2/RRC/NR/nr_rrc_defs.h | 1 + openair2/RRC/NR/rrc_gNB.c | 5 ++ openair2/RRC/NR/rrc_gNB_du.c | 93 +++++++++++++++++++++++++++ openair2/RRC/NR/rrc_gNB_du.h | 2 + 9 files changed, 174 insertions(+) diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index a5e10b01f9..9177ed9001 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -27,11 +27,14 @@ MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t, MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req) MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t , f1ap_gnb_cu_configuration_update_acknowledge) MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_failure_t , f1ap_gnb_cu_configuration_update_failure) +MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE, MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_t, f1ap_gnb_du_configuration_update) /* 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) MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_t , f1ap_gnb_cu_configuration_update) +MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_acknowledge_t, f1ap_gnb_du_configuration_update_acknowledge) +MESSAGE_DEF(F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, f1ap_gnb_du_configuration_update_failure_t, f1ap_gnb_du_configuration_update_failure) /* F1AP -> RRC to inform about lost connection */ MESSAGE_DEF(F1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, f1ap_lost_connection_t, f1ap_lost_connection) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index f99f4ce250..8ce2c2a8ca 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -39,6 +39,10 @@ #define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update #define F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_acknowledge #define F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_failure +#define F1AP_GNB_DU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update +#define F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_acknowledge +#define F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_failure + #define F1AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_failure #define F1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.f1ap_lost_connection @@ -247,6 +251,57 @@ typedef struct f1ap_gnb_cu_configuration_update_failure_s { uint16_t criticality_diagnostics; } f1ap_gnb_cu_configuration_update_failure_t; +/*DU configuration messages*/ +typedef struct f1ap_gnb_du_configuration_update_s { + /*TODO UPDATE TO SUPPORT DU CONFIG*/ + + /* Transaction ID */ + uint64_t transaction_id; + /// int cells_to_add + uint16_t num_cells_to_add; + struct { + f1ap_served_cell_info_t info; + f1ap_gnb_du_system_info_t *sys_info; + } cell_to_add[F1AP_MAX_NB_CELLS]; + + /// int cells_to_modify + uint16_t num_cells_to_modify; + struct { + f1ap_plmn_t old_plmn; + uint64_t old_nr_cellid; // NR Global Cell Id + f1ap_served_cell_info_t info; + f1ap_gnb_du_system_info_t *sys_info; + } cell_to_modify[F1AP_MAX_NB_CELLS]; + + /// int cells_to_delete + uint16_t num_cells_to_delete; + struct { + // NR CGI + f1ap_plmn_t plmn; + uint64_t nr_cellid; // NR Global Cell Id + } cell_to_delete[F1AP_MAX_NB_CELLS]; + + /// string holding gNB_CU_name + uint64_t *gNB_DU_ID; +} f1ap_gnb_du_configuration_update_t; + +typedef struct f1ap_gnb_du_configuration_update_acknowledge_s { + /// ulong transaction id + uint64_t transaction_id; + /// string holding gNB_CU_name + char *gNB_CU_name; + /// number of DU cells to activate + uint16_t num_cells_to_activate; // 0< num_cells_to_activate <= 512; + served_cells_to_activate_t cells_to_activate[F1AP_MAX_NB_CELLS]; +} f1ap_gnb_du_configuration_update_acknowledge_t; + +typedef struct f1ap_gnb_du_configuration_update_failure_s { + /*TODO UPDATE TO SUPPORT DU CONFIG*/ + uint16_t cause; + uint16_t time_to_wait; + uint16_t criticality_diagnostics; +} f1ap_gnb_du_configuration_update_failure_t; + typedef struct f1ap_dl_rrc_message_s { uint32_t gNB_CU_ue_id; diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 0899bca06a..49eb03512a 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -27,6 +27,8 @@ typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp); typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail); +typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id, + const f1ap_gnb_du_configuration_update_acknowledge_t *ack); typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req); typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index 55d1bf0236..2373b548eb 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -36,6 +36,12 @@ static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_fail f1_setup_failure(fail); } +static void gnb_du_configuration_update_ack_direct(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + AssertFatal(false, "%s() not implemented\n", __func__); +} + static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req) { AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); @@ -76,6 +82,7 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->f1_setup_response = f1_setup_response_direct; mac_rrc->f1_setup_failure = f1_setup_failure_direct; + mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct; mac_rrc->ue_context_setup_request = ue_context_setup_request_direct; mac_rrc->ue_context_modification_request = ue_context_modification_request_direct; mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_direct; diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index b440f1818a..e3bdca518f 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -44,6 +44,11 @@ static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failur itti_send_msg_to_task(TASK_CU_F1, 0, msg); } +static void gnb_du_configuration_update_ack_f1ap(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack) +{ + AssertFatal(false, "%s() not implemented\n", __func__); +} + static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); @@ -208,6 +213,7 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->f1_setup_response = f1_setup_response_f1ap; mac_rrc->f1_setup_failure = f1_setup_failure_f1ap; + mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_f1ap; mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap; mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm_f1ap; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 6a5c9f691f..fda89f6f8a 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -359,6 +359,7 @@ typedef struct { typedef struct nr_mac_rrc_dl_if_s { f1_setup_response_func_t f1_setup_response; f1_setup_failure_func_t f1_setup_failure; + gnb_du_configuration_update_ack_func_t gnb_du_configuration_update_acknowledge; ue_context_setup_request_func_t ue_context_setup_request; ue_context_modification_request_func_t ue_context_modification_request; ue_context_modification_confirm_func_t ue_context_modification_confirm; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d0d9735426..24df6141e9 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2477,6 +2477,11 @@ void *rrc_gnb_task(void *args_p) { rrc_CU_process_f1_lost_connection(RC.nrrrc[0], &F1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance); break; + case F1AP_GNB_DU_CONFIGURATION_UPDATE: + AssertFatal(!NODE_IS_DU(RC.nrrrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST in DU!\n"); + rrc_gNB_process_f1_du_configuration_update(&F1AP_GNB_DU_CONFIGURATION_UPDATE(msg_p), msg_p->ittiMsgHeader.originInstance); + break; + /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n"); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index bbf9942ddc..fdbe1a4551 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -219,6 +219,99 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) return count; } +static void update_cell_info(nr_rrc_du_container_t *du, const f1ap_served_cell_info_t *new_ci) +{ + DevAssert(du != NULL); + DevAssert(new_ci != NULL); + + AssertFatal(du->setup_req->num_cells_available == 1, "expected 1 cell for DU, but has %d\n", du->setup_req->num_cells_available); + f1ap_served_cell_info_t *ci = &du->setup_req->cell[0].info; + + ci->nr_cellid = new_ci->nr_cellid; + ci->nr_pci = new_ci->nr_pci; + if (new_ci->tac != NULL) + *ci->tac = *new_ci->tac; + ci->num_ssi = new_ci->num_ssi; + ci->sst = new_ci->sst; + ci->sd = new_ci->sd; + ci->mode = new_ci->mode; + if (ci->mode == F1AP_MODE_TDD) + ci->tdd = new_ci->tdd; + else + ci->fdd = new_ci->fdd; +} + +void rrc_gNB_process_f1_du_configuration_update(f1ap_gnb_du_configuration_update_t *conf_up, sctp_assoc_t assoc_id) +{ + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); + gNB_RRC_INST *rrc = RC.nrrrc[0]; + DevAssert(rrc); + + // check: + // - it is one cell + // - PLMN and Cell ID matches + // - no previous DU with the same ID + // else reject + + nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id); + AssertError(du != NULL, return, "no DU found for assoc_id %d\n", assoc_id); + + const f1ap_served_cell_info_t *info = &du->setup_req->cell[0].info; + if (conf_up->num_cells_to_add > 0) { + // Here we check if the number of cell limit is respectet, otherwise send failure + LOG_W(RRC, "du_configuration_update->cells_to_add_list is not supported yet"); + } + + if (conf_up->num_cells_to_modify > 0) { + // here the old nrcgi is used to find the cell information, if it exist then we modify consequently otherwise we fail + AssertFatal(conf_up->num_cells_to_modify == 1, "cannot handle more than one cell!\n"); + + if (info->nr_cellid != conf_up->cell_to_modify[0].old_nr_cellid) { + LOG_W(RRC, "no cell with ID %ld found, ignoring gNB-DU configuration update\n", conf_up->cell_to_modify[0].old_nr_cellid); + return; + } + + // verify the new plmn of the cell + if (!rrc_gNB_plmn_matches(rrc, &conf_up->cell_to_modify[0].info)) { + LOG_W(RRC, "PLMN does not match, ignoring gNB-DU configuration update\n"); + return; + } + + update_cell_info(du, &conf_up->cell_to_modify[0].info); + + const f1ap_gnb_du_system_info_t *sys_info = conf_up->cell_to_modify[0].sys_info; + + if (sys_info != NULL && sys_info->mib != NULL && !(sys_info->sib1 == NULL && get_softmodem_params()->sa)) { + // MIB is mandatory, so will be overwritten. SIB1 is optional, so will + // only be overwritten if present in sys_info + ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib); + if (sys_info->sib1 != NULL) + ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1); + + NR_BCCH_BCH_Message_t *mib = NULL; + if (!extract_sys_info(sys_info, &mib, &du->sib1)) { + LOG_W(RRC, "cannot update sys_info for DU %ld\n", du->setup_req->gNB_DU_id); + } else { + DevAssert(mib != NULL); + du->mib = mib->message.choice.mib; + mib->message.choice.mib = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib); + LOG_I(RRC, "update system information of DU %ld\n", du->setup_req->gNB_DU_id); + } + } + } + + if (conf_up->num_cells_to_delete > 0) { + // delete the cell and send cell to desactive IE in the response. + LOG_W(RRC, "du_configuration_update->cells_to_delete_list is not supported yet"); + } + + /* Send DU Configuration Acknowledgement */ + f1ap_gnb_du_configuration_update_acknowledge_t ack = {.transaction_id = conf_up->transaction_id}; + + rrc->mac_rrc.gnb_du_configuration_update_acknowledge(assoc_id, &ack); +} + void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) { AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h index c57faf3802..618450f774 100644 --- a/openair2/RRC/NR/rrc_gNB_du.h +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -31,9 +31,11 @@ struct f1ap_setup_req_s; struct f1ap_lost_connection_t; struct gNB_RRC_INST_s; struct nr_rrc_du_container_t; +struct f1ap_gnb_du_configuration_update_s; void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id); void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); +void rrc_gNB_process_f1_du_configuration_update(struct f1ap_gnb_du_configuration_update_s *conf_up, sctp_assoc_t assoc_id); struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id); struct nr_rrc_du_container_t *get_du_by_assoc_id(struct gNB_RRC_INST_s *rrc, sctp_assoc_t assoc_id);