From 4ad7e9c5c0297dd2327d7280d0ac9f5b1fbc2842 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 6 Nov 2023 07:38:59 +0100 Subject: [PATCH 01/30] Remove dead code in GTP Remove dead code, result of 2136ceec0d3ea5b605df42059bc9602c94018297: we cannot connect() in GTP on multiple remotes (as then only packets of one host might be received), but might need to send to multiple remote sockets. --- openair3/ocp-gtpu/gtp_itf.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index d542dd4b30..69db8caa4a 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -510,27 +510,6 @@ static int udpServerSocket(openAddr_s addr) { freeaddrinfo(servinfo); // all done with this structure - if (false) { - struct addrinfo hints; - memset(&hints,0,sizeof(hints)); - hints.ai_family=AF_UNSPEC; - hints.ai_socktype=SOCK_DGRAM; - hints.ai_protocol=0; - hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG; - struct addrinfo *res=0; - int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res); - - if (err==0) { - for(p = res; p != NULL; p = p->ai_next) { - if ((err=connect(sockfd, p->ai_addr, p->ai_addrlen))==0) - break; - } - } - - if (err) - LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService); - } - int sendbuff = 1000*1000*10; AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); LOG_D(GTPU,"[%d] Created listener for paquets to: %s:%s, send buffer size: %d\n", sockfd, addr.originHost, addr.originService,sendbuff); From 11df08a8f0d0be354e90896e9d48bc71aab8030a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 09:50:43 +0100 Subject: [PATCH 02/30] clang-format: RB_FOREACH is a for_each macro --- .clang-format | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-format b/.clang-format index d3378d0f4a..aa8f087091 100644 --- a/.clang-format +++ b/.clang-format @@ -60,6 +60,7 @@ ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH + - RB_FOREACH IncludeBlocks: Preserve IncludeCategories: - Regex: '^' From 808b7684a822bfa31862ab7c08a41768c6933b4c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 14:50:50 +0100 Subject: [PATCH 03/30] F1AP: Remove commented code --- openair2/F1AP/f1ap_cu_interface_management.c | 37 +------------------- openair2/F1AP/f1ap_cu_task.c | 8 ----- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 03b281ea39..6863dfbd2d 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -194,42 +194,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 memcpy(sys_info->sib1, DUsi->sIB1_message.buf, DUsi->sIB1_message.size); sys_info->sib1_length = DUsi->sIB1_message.size; } - - // char *measurement_timing_information[F1AP_MAX_NB_CELLS]; - // uint8_t ranac[F1AP_MAX_NB_CELLS]; - // int fdd_flag = f1ap_setup_req->fdd_flag; - // union { - // struct { - // uint32_t ul_nr_arfcn; - // uint8_t ul_scs; - // uint8_t ul_nrb; - // uint32_t dl_nr_arfcn; - // uint8_t dl_scs; - // uint8_t dl_nrb; - // uint32_t sul_active; - // uint32_t sul_nr_arfcn; - // uint8_t sul_scs; - // uint8_t sul_nrb; - // uint8_t num_frequency_bands; - // uint16_t nr_band[32]; - // uint8_t num_sul_frequency_bands; - // uint16_t nr_sul_band[32]; - // } fdd; - // struct { - // uint32_t nr_arfcn; - // uint8_t scs; - // uint8_t nrb; - // uint32_t sul_active; - // uint32_t sul_nr_arfcn; - // uint8_t sul_scs; - // uint8_t sul_nrb; - // uint8_t num_frequency_bands; - // uint16_t nr_band[32]; - // uint8_t num_sul_frequency_bands; - // uint16_t nr_sul_band[32]; - // } tdd; - // } nr_mode_info[F1AP_MAX_NB_CELLS]; - + if (req->num_cells_available > 0) { itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); } else { diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 3d1f0b6aac..545091f213 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -208,14 +208,6 @@ void *F1AP_CU_task(void *arg) { &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg)); break; - // case F1AP_SETUP_RESPONSE: // This is from RRC - // CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp) - // break; - - // case F1AP_SETUP_FAILURE: // This is from RRC - // CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure) - // break; - case TERMINATE_MESSAGE: LOG_W(F1AP, " *** Exiting F1AP thread\n"); itti_exit_task(); From 05aefb9aaa15b42feec8c2f5f2d796ade39b72b8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 3 Nov 2023 14:02:57 +0100 Subject: [PATCH 04/30] Correctly read PCI in F1 Setup Response --- openair2/F1AP/f1ap_du_interface_management.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index d271cccde8..f7c440006e 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -317,7 +317,6 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint F1AP_F1SetupResponseIEs_t *ie; int TransactionId = -1; int num_cells_to_activate = 0; - F1AP_Cells_to_be_Activated_List_Item_t *cell; f1ap_setup_resp_t resp = {0}; for (int i=0; i < in->protocolIEs.list.count; i++) { @@ -365,7 +364,8 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject"); AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item, "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item"); - cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item; + F1AP_Cells_to_be_Activated_List_Item_t *cell = + &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item; TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, resp.cells_to_activate[i].plmn.mcc, resp.cells_to_activate[i].plmn.mnc, @@ -377,6 +377,8 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint cell->nRCGI.nRCellIdentity.buf[3], cell->nRCGI.nRCellIdentity.buf[4]); BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, resp.cells_to_activate[i].nr_cellid); + if (cell->nRPCI != NULL) + resp.cells_to_activate[i].nrpci = *cell->nRPCI; F1AP_ProtocolExtensionContainer_10696P112_t *ext = (F1AP_ProtocolExtensionContainer_10696P112_t *)cell->iE_Extensions; if (ext==NULL) From 474c3507f1eb4e87a101e18019123cd695cdec9b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 05:42:32 +0100 Subject: [PATCH 05/30] Allow DUs to reconnect to CU Previous to this commit, the CU creates an F1 instance and initializes GTP after a successful connection establishment, and tears the F1 instance down after the DU disconnects. This does not work when trying to connect multiple DUs, or have them reconnect, as e.g., GTP re-initialization fails (socket already bound). This commit makes the CU F1 instance creation and GTP init at CU task init (only once), and also frees the F1 instance only after the CU task exits, which is at termination of the application, typically. --- openair2/F1AP/f1ap_cu_task.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 545091f213..c15b6d83ad 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -53,20 +53,11 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind, eth_params_t *IPaddrs) { - createF1inst(instance, NULL, NULL); // save the assoc id f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); f1ap_cu_data->assoc_id = sctp_new_association_ind->assoc_id; f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; - if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) { - getCxt(instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs); - AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); - } else - LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n"); - // Fixme: fully inconsistent instances management - // dirty global var is a bad fix - CUuniqInstance=getCxt(instance)->gtpInst; } static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { @@ -76,7 +67,6 @@ static void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_a f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); AssertFatal(f1ap_cu_data != NULL, "illegal state: SCTP shutdown for non-existing F1AP endpoint\n"); LOG_I(F1AP, "Received SCTP shutdown for assoc_id %d, removing endpoint\n", sctp_new_association_resp->assoc_id); - destroyF1inst(instance); /* inform RRC that the DU is gone */ MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_LOST_CONNECTION); message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id; @@ -139,7 +129,19 @@ void *F1AP_CU_task(void *arg) { // Hardcoded instance id! IPaddrs = &RC.nrrrc[0]->eth_params_s; - cu_task_send_sctp_init_req(0, IPaddrs->my_addr); + const int instance = 0; + createF1inst(instance, NULL, NULL); + cu_task_send_sctp_init_req(instance, IPaddrs->my_addr); + + if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) { + getCxt(instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs); + AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); + } else { + LOG_I(F1AP, "In F1AP connection, don't start GTP-U, as we have also E1AP\n"); + } + // Fixme: fully inconsistent instances management + // dirty global var is a bad fix + CUuniqInstance=getCxt(instance)->gtpInst; while (1) { itti_receive_msg(TASK_CU_F1, &received_msg); @@ -224,5 +226,7 @@ void *F1AP_CU_task(void *arg) { received_msg = NULL; } // while + destroyF1inst(instance); + return NULL; } From 4c2bfe7a1f9f6637a47d1ace89f75160201473c5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 14:50:34 +0100 Subject: [PATCH 06/30] F1AP: send() functions take assoc_id To allow to send F1 messages to multiple DUs from the CU, we need to send these messages via different assoc_id (SCTP association ID, basically akin to a file descriptor). Currently, the assoc_id is stored in a context at the F1 module and retrieved in f1ap_itti_send_sctp_data_req(). To facilitate a later change towards indicating (from the RRC) to which assoc_id (hence, DU) to send a message, we refactor all CU_send_*()/DU_send_*() functions to take the assoc_id as a parameter to which to send messages. In this commit, we then pass the assoc_id from the context. A later commit changes this (at the CU) to pass the assoc_id from the message to be sent. --- openair2/F1AP/f1ap_cu_interface_management.c | 32 ++++++++------- openair2/F1AP/f1ap_cu_interface_management.h | 18 ++++----- openair2/F1AP/f1ap_cu_paging.c | 5 ++- openair2/F1AP/f1ap_cu_paging.h | 2 +- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 7 ++-- openair2/F1AP/f1ap_cu_rrc_message_transfer.h | 2 +- openair2/F1AP/f1ap_cu_task.c | 23 ++++++----- openair2/F1AP/f1ap_cu_ue_context_management.c | 29 +++++++------- openair2/F1AP/f1ap_cu_ue_context_management.h | 10 ++--- openair2/F1AP/f1ap_du_interface_management.c | 34 ++++++++-------- openair2/F1AP/f1ap_du_interface_management.h | 17 ++++---- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 14 +++---- openair2/F1AP/f1ap_du_rrc_message_transfer.h | 4 +- openair2/F1AP/f1ap_du_task.c | 28 ++++++------- openair2/F1AP/f1ap_du_ue_context_management.c | 40 ++++++++++--------- openair2/F1AP/f1ap_du_ue_context_management.h | 14 +++---- openair2/F1AP/f1ap_itti_messaging.c | 25 +++--------- openair2/F1AP/f1ap_itti_messaging.h | 2 +- 18 files changed, 147 insertions(+), 159 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 6863dfbd2d..7cd38027ba 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -35,7 +35,8 @@ #include "f1ap_itti_messaging.h" #include "f1ap_cu_interface_management.h" -int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { +int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset) +{ AssertFatal(1==0,"Not implemented yet\n"); } @@ -49,11 +50,11 @@ int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { +int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) +{ AssertFatal(1==0,"Not implemented yet\n"); } - /* Error Indication */ @@ -62,7 +63,7 @@ int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3 AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication) { +int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication) { AssertFatal(1==0,"Not implemented yet\n"); } @@ -198,7 +199,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 if (req->num_cells_available > 0) { itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); } else { - CU_send_F1_SETUP_FAILURE(instance); + CU_send_F1_SETUP_FAILURE(assoc_id); itti_free(TASK_CU_F1,message_p); return -1; } @@ -206,7 +207,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 return 0; } -int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp) +int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp) { F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; @@ -304,11 +305,12 @@ int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int CU_send_F1_SETUP_FAILURE(instance_t instance) { +int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id) +{ LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n"); F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; @@ -371,7 +373,7 @@ int CU_send_F1_SETUP_FAILURE(instance_t instance) { } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -384,12 +386,12 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) { AssertFatal(1==0,"Not implemented yet\n"); } -int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) { AssertFatal(1==0,"Not implemented yet\n"); } @@ -398,8 +400,8 @@ int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, gNB-CU Configuration Update */ -//void CU_send_gNB_CU_CONFIGURATION_UPDATE(F1AP_GNBCUConfigurationUpdate_t *GNBCUConfigurationUpdate) { -int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update) { +int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update) +{ F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer; uint32_t len; @@ -485,7 +487,7 @@ int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configu LOG_DUMPMSG(F1AP, LOG_DUMP_CHAR, buffer, len, "F1AP gNB-CU CONFIGURATION UPDATE : "); ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -511,7 +513,7 @@ int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, AssertFatal(0, "Not implemented yet\n"); } -int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, +int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id, F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse) { AssertFatal(0, "Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h index abdb60bf88..8ed6fdf032 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.h +++ b/openair2/F1AP/f1ap_cu_interface_management.h @@ -36,41 +36,41 @@ /* * Reset */ -int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); +int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset); int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); +int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge); /* * Error Indication */ int CU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication); +int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *ErrorIndication); /* * F1 Setup */ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp); +int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp); -int CU_send_F1_SETUP_FAILURE(instance_t instance); +int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id); /* * gNB-DU Configuration Update */ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_FAILURE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure); -int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge); /* * gNB-CU Configuration Update */ -int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update); +int CU_send_gNB_CU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_t *f1ap_gnb_cu_configuration_update); int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, @@ -89,7 +89,7 @@ int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, +int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(sctp_assoc_t assoc_id, F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse); #endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c index 5175456c4e..330264ffd2 100644 --- a/openair2/F1AP/f1ap_cu_paging.c +++ b/openair2/F1AP/f1ap_cu_paging.c @@ -37,7 +37,8 @@ extern f1ap_setup_req_t *f1ap_du_data_from_du; -int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { +int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging) +{ F1AP_F1AP_PDU_t pdu = {0}; pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; @@ -114,6 +115,6 @@ int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { return -1; } ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h index 5cff651fcc..4029d27312 100644 --- a/openair2/F1AP/f1ap_cu_paging.h +++ b/openair2/F1AP/f1ap_cu_paging.h @@ -32,5 +32,5 @@ #ifndef F1AP_CU_PAGING_H_ #define F1AP_CU_PAGING_H_ -int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging); +int CU_send_Paging(sctp_assoc_t assoc_id, f1ap_paging_ind_t *paging); #endif /* F1AP_DU_PAGING_H_ */ diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 391841cfa0..7e640ccffd 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -107,9 +107,8 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t /* DL RRC Message Transfer. */ -//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) { -int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, - f1ap_dl_rrc_message_t *f1ap_dl_rrc) { +int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc) +{ LOG_D(F1AP, "CU send DL_RRC_MESSAGE_TRANSFER \n"); F1AP_F1AP_PDU_t pdu= {0}; F1AP_DLRRCMessageTransfer_t *out; @@ -207,7 +206,7 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.h b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h index 6b7023a84d..a0c732d104 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h @@ -35,7 +35,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, f1ap_dl_rrc_message_t *f1ap_dl_rrc); +int CU_send_DL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, f1ap_dl_rrc_message_t *f1ap_dl_rrc); int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index c15b6d83ad..d89cba3a4e 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -145,8 +145,9 @@ void *F1AP_CU_task(void *arg) { while (1) { itti_receive_msg(TASK_CU_F1, &received_msg); - LOG_D(F1AP, "CU Task Received %s for instance %ld\n", - ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg)); + sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->assoc_id : 0; + LOG_D(F1AP, "CU Task Received %s for instance %ld: sending SCTP message via assoc_id %d\n", + ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg), assoc_id); switch (ITTI_MSG_ID(received_msg)) { case SCTP_NEW_ASSOCIATION_IND: cu_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(received_msg), @@ -165,48 +166,48 @@ void *F1AP_CU_task(void *arg) { break; case F1AP_SETUP_RESP: // from rrc - CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_F1_SETUP_RESPONSE(assoc_id, &F1AP_SETUP_RESP(received_msg)); break; case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc - CU_send_gNB_CU_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_gNB_CU_CONFIGURATION_UPDATE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg)); break; case F1AP_DL_RRC_MESSAGE: // from rrc - CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_DL_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_DL_RRC_MESSAGE(received_msg)); free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container); break; case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc - CU_send_UE_CONTEXT_SETUP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_SETUP_REQUEST(assoc_id, &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REQ: - CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_MODIFICATION_REQUEST(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc - CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_RELEASE_COMMAND(assoc_id, &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); break; case F1AP_PAGING_IND: - CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_Paging(assoc_id, &F1AP_PAGING_IND(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_CONFIRM: - CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(received_msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REFUSE: - CU_send_UE_CONTEXT_MODIFICATION_REFUSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + CU_send_UE_CONTEXT_MODIFICATION_REFUSE(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(received_msg)); break; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 876cd1e3a9..18663305e3 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -65,8 +65,8 @@ static void setQos(F1AP_NonDynamic5QIDescriptor_t *toFill) { } } -int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, - f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) { +int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) +{ F1AP_F1AP_PDU_t pdu= {0}; /* Create */ /* 0. Message Type */ @@ -509,7 +509,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(instance)->gtpInst, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, f1ap_ue_context_setup_req->gNB_CU_ue_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, @@ -628,7 +628,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, // return -1; // } LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -825,9 +825,8 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc return 0; } - -int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, - f1ap_ue_context_release_cmd_t *cmd) { +int CU_send_UE_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, f1ap_ue_context_release_cmd_t *cmd) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextReleaseCommand_t *out; uint8_t *buffer=NULL; @@ -912,7 +911,7 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -951,7 +950,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; @@ -1555,7 +1554,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; /* dRBID */ drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id; - newGtpuDeleteOneTunnel(getCxt(instance)->gtpInst, + newGtpuDeleteOneTunnel(getCxt(0)->gtpInst, f1ap_ue_context_modification_req->gNB_CU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } @@ -1566,7 +1565,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n"); return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -1833,7 +1832,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm) +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(sctp_assoc_t assoc_id, f1ap_ue_context_modif_confirm_t *confirm) { F1AP_F1AP_PDU_t pdu = {0}; pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; @@ -1891,11 +1890,11 @@ int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context LOG_E(F1AP, "Failed to encode F1 UE Context Modification Confirm\n"); return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse) +int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_refuse_t *refuse) { F1AP_F1AP_PDU_t pdu = {0}; pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; @@ -1958,6 +1957,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_ LOG_E(F1AP, "Failed to encode F1 UE Context Modification Refuse\n"); return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 5409c6e53e..05e67930b3 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -36,7 +36,7 @@ /* * UE Context Setup */ -int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, +int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req); int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -51,7 +51,7 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc /* * UE Context Release (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, +int CU_send_UE_CONTEXT_RELEASE_COMMAND(sctp_assoc_t assoc_id, f1ap_ue_context_release_cmd_t *cmd); int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -59,7 +59,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso /* * UE Context Modification (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -68,9 +68,9 @@ int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t */ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, f1ap_ue_context_modif_confirm_t *confirm); +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(sctp_assoc_t assoc_id, f1ap_ue_context_modif_confirm_t *confirm); -int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, f1ap_ue_context_modif_refuse_t *refuse); +int CU_send_UE_CONTEXT_MODIFICATION_REFUSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_refuse_t *refuse); /* * UE Inactivity Notification diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index f7c440006e..4410094c5f 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -55,11 +55,12 @@ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { +int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) { AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { +int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset) +{ AssertFatal(1==0,"Not implemented yet\n"); } @@ -72,7 +73,8 @@ int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint Error Indication */ -int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p) { +int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p) +{ AssertFatal(1==0,"Not implemented yet\n"); } @@ -86,7 +88,7 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3 */ // SETUP REQUEST -int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req) +int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req) { F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer; @@ -298,7 +300,7 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req) } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -494,10 +496,8 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3 gNB-DU Configuration Update */ -//void DU_send_gNB_DU_CONFIGURATION_UPDATE(F1AP_GNBDUConfigurationUpdate_t *GNBDUConfigurationUpdate) { -int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, - instance_t du_mod_idP, - f1ap_setup_req_t *f1ap_setup_req) { +int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t *f1ap_setup_req) +{ F1AP_F1AP_PDU_t pdu= {0}; uint8_t *buffer=NULL; uint32_t len=0; @@ -893,14 +893,16 @@ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso return 0; } -int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, +int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure) { AssertFatal(1==0,"received gNB CU CONFIGURATION UPDATE FAILURE with cause %d\n", GNBCUConfigurationUpdateFailure->cause); } -int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, - f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) { +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE( + sctp_assoc_t assoc_id, + f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge) +{ AssertFatal(GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated == 0, "%d cells failed to activate\n", GNBCUConfigurationUpdateAcknowledge->num_cells_failed_to_be_activated); @@ -939,13 +941,13 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, } ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu); - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } - -int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, - F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) { +int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id, + F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) +{ AssertFatal(0, "Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h index f077dc547a..8fa166d0bc 100644 --- a/openair2/F1AP/f1ap_du_interface_management.h +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -37,20 +37,20 @@ * Reset */ int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); -int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); +int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge); +int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset); int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); /* * Error Indication */ -int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p); +int DU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_F1AP_PDU_t *pdu_p); int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); /* * F1 Setup */ -int DU_send_F1_SETUP_REQUEST(instance_t instance, f1ap_setup_req_t *setup_req); +int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req); int DU_handle_F1_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -59,8 +59,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3 /* * gNB-DU Configuration Update */ -int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, - instance_t du_mod_idP, +int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t *f1ap_du_data); int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); @@ -75,10 +74,10 @@ int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, */ int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, +int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_failure_t *GNBCUConfigurationUpdateFailure); -int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(sctp_assoc_t assoc_id, f1ap_gnb_cu_configuration_update_acknowledge_t *GNBCUConfigurationUpdateAcknowledge); @@ -86,7 +85,7 @@ int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, /* * gNB-DU Resource Coordination */ -int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, +int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(sctp_assoc_t assoc_id, F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest); int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 5a61879059..3a2f7ce725 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -141,7 +141,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id } /* UL RRC Message Transfer */ -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg) +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_InitialULRRCMessageTransfer_t *out; @@ -170,7 +170,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI; //Fixme: takes always the first cell - addnRCGI(ie2->value.choice.NRCGI, &getCxt(instanceP)->setupReq.cell[0].info); + addnRCGI(ie2->value.choice.NRCGI, &getCxt(0)->setupReq.cell[0].info); /* mandatory */ /* c3. C_RNTI */ // 16 asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie3); @@ -211,20 +211,18 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_ini return -1; } - f1ap_itti_send_sctp_data_req(instanceP, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) +int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_ULRRCMessageTransfer_t *out; uint8_t *buffer = NULL; uint32_t len; LOG_D(F1AP, - "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", - instance, - __func__, + "size %d UE RNTI %x in SRB %d\n", msg->rrc_container_length, msg->gNB_DU_ue_id, msg->srb_id); @@ -277,6 +275,6 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_me return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h index e959d8b9e1..4064a7cd2a 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -38,8 +38,8 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg); +int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_ul_rrc_message_t *msg); -int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, const f1ap_initial_ul_rrc_message_t *msg); +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *msg); #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 797099a480..e53a1e5134 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -80,7 +80,7 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams; f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams; /* setup parameters for F1U and start the server */ - DU_send_F1_SETUP_REQUEST(instance, &f1ap_du_data->setupReq); + DU_send_F1_SETUP_REQUEST(f1ap_du_data->assoc_id, &f1ap_du_data->setupReq); } void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { @@ -102,8 +102,8 @@ void *F1AP_DU_task(void *arg) { MessageDef *msg = NULL; itti_receive_msg(TASK_DU_F1, &msg); instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); - LOG_D(F1AP, "DU Task Received %s for instance %ld\n", - ITTI_MSG_NAME(msg),myInstance); + sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->assoc_id : 0; + LOG_D(F1AP, "DU Task Received %s for instance %ld: sending SCTP messages via assoc_id %d\n", ITTI_MSG_NAME(msg), myInstance, assoc_id); switch (ITTI_MSG_ID(msg)) { case F1AP_SETUP_REQ: AssertFatal(false, "the F1AP_SETUP_REQ should not be received; use the F1AP_DU_REGISTER_REQ instead\n"); @@ -121,12 +121,12 @@ void *F1AP_DU_task(void *arg) { } break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: - DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_ORIGIN_INSTANCE(msg), + DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg)); break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE: - DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(myInstance, + DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(msg)); break; @@ -144,34 +144,32 @@ void *F1AP_DU_task(void *arg) { break; case F1AP_INITIAL_UL_RRC_MESSAGE: // from rrc - { - f1ap_initial_ul_rrc_message_t *msgRrc = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); - DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(myInstance, msgRrc); - } break; + DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_INITIAL_UL_RRC_MESSAGE(msg)); + break; case F1AP_UL_RRC_MESSAGE: // to rrc - DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, &F1AP_UL_RRC_MESSAGE(msg)); + DU_send_UL_NR_RRC_MESSAGE_TRANSFER(assoc_id, &F1AP_UL_RRC_MESSAGE(msg)); break; case F1AP_UE_CONTEXT_SETUP_RESP: - DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); + DU_send_UE_CONTEXT_SETUP_RESPONSE(assoc_id, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_RESP: - DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); + DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); break; case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC - DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance, + DU_send_UE_CONTEXT_RELEASE_REQUEST(assoc_id, &F1AP_UE_CONTEXT_RELEASE_REQ(msg)); break; case F1AP_UE_CONTEXT_RELEASE_COMPLETE: - DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); + DU_send_UE_CONTEXT_RELEASE_COMPLETE(assoc_id, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); break; case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED: - DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg)); + DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg)); break; case TERMINATE_MESSAGE: diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 91cb157c9d..09288d17a2 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -205,7 +205,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i return 0; } -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { +int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *resp) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextSetupResponse_t *out; uint8_t *buffer=NULL; @@ -329,7 +330,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ @@ -542,15 +543,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) { +int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id) +{ AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, - f1ap_ue_context_release_req_t *req) { + +int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_release_req_t *req) +{ F1AP_F1AP_PDU_t pdu; F1AP_UEContextReleaseRequest_t *out; uint8_t *buffer=NULL; @@ -617,7 +620,7 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -681,7 +684,7 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc return 0; } -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete) +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextReleaseComplete_t *out; @@ -764,7 +767,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_rel return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -965,8 +968,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t return 0; } -//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp) +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationResponse_t *out; @@ -1058,7 +1060,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex transport_layer_addr_t tl_addr = {0}; memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; - drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(instance)->gtpInst, + drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, resp->gNB_DU_ue_id, drb->drb_id, drb->drb_id, @@ -1077,7 +1079,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ @@ -1115,7 +1117,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); @@ -1190,7 +1192,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex /* 8.1 SCell_ToBeSetup_Item */ F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; /* - sCell_ID */ - addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(instance)->setupReq.cell[i].info); + addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(0)->setupReq.cell[i].info); asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); tmp->present = F1AP_Cause_PR_radioNetwork; tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; @@ -1299,15 +1301,15 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } -int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { +int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id) { AssertFatal(1==0,"Not implemented yet\n"); } -int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required) +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required) { /* 0. Message Type */ F1AP_F1AP_PDU_t pdu = {0}; @@ -1423,7 +1425,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_contex return -1; } - f1ap_itti_send_sctp_data_req(instance, buffer, len); + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index 536007da42..43663ba538 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -36,16 +36,16 @@ /* * UE Context Setup */ -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req); +int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *req); int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance); +int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id); /* * UE Context Release Request (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, +int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_release_req_t *req); @@ -57,20 +57,20 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc /* * UE Context Release Complete (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete); +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete); /* * UE Context Modification (gNB-CU initiated) */ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp); -int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp); +int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id); /* * UE Context Modification Required (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, f1ap_ue_context_modif_required_t *required); +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required); int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index d4e112d1d5..cdda26c5f6 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -22,27 +22,14 @@ #include "f1ap_common.h" #include "f1ap_itti_messaging.h" -void f1ap_itti_send_sctp_data_req(instance_t instance, uint8_t *buffer, uint32_t buffer_length) +void f1ap_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length) { - MessageDef *message_p; - sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_CU_F1, 0, SCTP_DATA_REQ); - sctp_data_req = &message_p->ittiMsg.sctp_data_req; - sctp_data_req->assoc_id = getCxt(instance)->assoc_id; - sctp_data_req->buffer = buffer; + instance_t instance = 0; // we have only one instance + MessageDef *message_p = itti_alloc_new_message(TASK_CU_F1, instance, SCTP_DATA_REQ); + sctp_data_req_t *sctp_data_req = &message_p->ittiMsg.sctp_data_req; + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; sctp_data_req->stream = 0; - LOG_D(F1AP, "Sending ITTI message to SCTP Task\n"); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } - -void f1ap_itti_send_sctp_close_association(instance_t instance) -{ - MessageDef *message_p = NULL; - sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION); - sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; - sctp_close_association_p->assoc_id = getCxt(instance)->assoc_id; - itti_send_msg_to_task(TASK_SCTP, instance, message_p); -} - diff --git a/openair2/F1AP/f1ap_itti_messaging.h b/openair2/F1AP/f1ap_itti_messaging.h index b132b3d826..6adc3d320e 100644 --- a/openair2/F1AP/f1ap_itti_messaging.h +++ b/openair2/F1AP/f1ap_itti_messaging.h @@ -22,6 +22,6 @@ #ifndef F1AP_ITTI_MESSAGING_H_ #define F1AP_ITTI_MESSAGING_H_ -void f1ap_itti_send_sctp_data_req(instance_t instance, uint8_t *buffer, uint32_t buffer_length); +void f1ap_itti_send_sctp_data_req(sctp_assoc_t assoc_id, uint8_t *buffer, uint32_t buffer_length); #endif /* F1AP_ITTI_MESSAGING_H_ */ From c00b287c6056649cd0eb8cd0441ab499cae36d7c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 05:47:17 +0100 Subject: [PATCH 07/30] Remove RRC UE context printing that depends on DU This code printed BW masks (what is this) and number of MIMO layers. It was dependent on the current DU, and only showed the information for the current DU config (SCS, band). On DU disconnect, it leads to segfaults to this dependency, and IMO is not useful in itself (it could rather be printed when receiving the UE capabilities, for all bands etc.). --- openair2/RRC/NR/rrc_gNB.c | 172 -------------------------------------- 1 file changed, 172 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 027fc69862..b061187f62 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -214,11 +214,6 @@ static int get_dl_band(const f1ap_served_cell_info_t *cell_info) return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.freqinfo.band : cell_info->fdd.dl_freqinfo.band; } -static int get_ul_band(const f1ap_served_cell_info_t *cell_info) -{ - return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.freqinfo.band : cell_info->fdd.ul_freqinfo.band; -} - static int get_ssb_scs(const f1ap_served_cell_info_t *cell_info) { return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs; @@ -2164,158 +2159,6 @@ unsigned int mask_flip(unsigned int x) { return((((x>>8) + (x<<8))&0xffff)>>6); } -static unsigned int get_dl_bw_mask(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_band = get_dl_band(cell_info); - int common_scs = get_ssb_scs(cell_info); - for (int i=0;irf_Parameters.supportedBandListNR.list.count;i++) { - NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; - if (bandNRinfo->bandNR == common_band) { - if (common_band < 257) { // FR1 - switch (common_scs) { - case NR_SubcarrierSpacing_kHz15 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr1 && - bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz30 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr1 && - bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr1 && - bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz->buf)); - break; - } - } - else { - switch (common_scs) { - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr2 && - bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz120 : - if (bandNRinfo->channelBWs_DL && - bandNRinfo->channelBWs_DL->choice.fr2 && - bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz->buf)); - break; - } - } - } - } - return(0); -} - -static unsigned int get_ul_bw_mask(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_band = get_ul_band(cell_info); - int common_scs = get_ssb_scs(cell_info); - for (int i=0;irf_Parameters.supportedBandListNR.list.count;i++) { - NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; - if (bandNRinfo->bandNR == common_band) { - if (common_band < 257) { // FR1 - switch (common_scs) { - case NR_SubcarrierSpacing_kHz15 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr1 && - bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz30 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr1 && - bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr1 && - bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz->buf)); - break; - } - } - else { - switch (common_scs) { - case NR_SubcarrierSpacing_kHz60 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr2 && - bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz->buf)); - break; - case NR_SubcarrierSpacing_kHz120 : - if (bandNRinfo->channelBWs_UL && - bandNRinfo->channelBWs_UL->choice.fr2 && - bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz) - return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz->buf)); - break; - } - } - } - } - return(0); -} - -static int get_ul_mimo_layersCB(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_scs = get_ssb_scs(cell_info); - - // check featureSet - NR_FeatureSets_t *fs=cap->featureSets; - if (fs) { - // go through UL feature sets and look for one with current SCS - for (int i=0;ifeatureSetsUplinkPerCC->list.count;i++) { - if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && - fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH && - fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) - return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH); - } - } - return(1); -} - -static int get_ul_mimo_layers(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_scs = get_ssb_scs(cell_info); - - // check featureSet - NR_FeatureSets_t *fs=cap->featureSets; - if (fs) { - // go through UL feature sets and look for one with current SCS - for (int i=0;ifeatureSetsUplinkPerCC->list.count;i++) { - if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && - fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH) - return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH); - } - } - return(1); -} - -static int get_dl_mimo_layers(const f1ap_served_cell_info_t *cell_info, const NR_UE_NR_Capability_t *cap) -{ - int common_scs = get_ssb_scs(cell_info); - - // check featureSet - NR_FeatureSets_t *fs=cap->featureSets; - if (fs) { - // go through UL feature sets and look for one with current SCS - for (int i=0;ifeatureSetsDownlinkPerCC->list.count;i++) { - if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && - fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH) - return(2<<*fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH); - } - } - return(1); -} - void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -2499,10 +2342,6 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) { const gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context; f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_ctxt->rrc_ue_id); - /* currently, we support only one DU. If we support multiple, need to - * search for the DU corresponding to this UE here */ - const nr_rrc_du_container_t *du = rrc->du; - DevAssert(du != NULL); fprintf(f, "UE %d CU UE ID %d DU UE ID %d RNTI %04x random identity %016lx", @@ -2524,17 +2363,6 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) fprintf(f, " PDU session %d ID %d status %s\n", nb_pdu, pdu->param.pdusession_id, get_pdusession_status_text(pdu->status)); } - if (ue_ctxt->UE_Capability_nr) { - AssertFatal(du->setup_req->num_cells_available == 1, "only one cell supported at the moment\n"); - const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; - fprintf(f, - " UE cap: BW DL %x. BW UL %x, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n", - get_dl_bw_mask(cell_info, ue_ctxt->UE_Capability_nr), - get_ul_bw_mask(cell_info, ue_ctxt->UE_Capability_nr), - get_dl_mimo_layers(cell_info, ue_ctxt->UE_Capability_nr), - get_ul_mimo_layersCB(cell_info, ue_ctxt->UE_Capability_nr), - get_ul_mimo_layers(cell_info, ue_ctxt->UE_Capability_nr)); - } if (ue_ctxt->measResults) print_rrc_meas(f, ue_ctxt->measResults); From 1153e62e45a685bc0e3bfa495dc13505507b99f1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 07:32:30 +0100 Subject: [PATCH 08/30] Move rrc gNB DU handling to separate file --- CMakeLists.txt | 1 + openair2/RRC/NR/rrc_gNB.c | 147 +--------------------------- openair2/RRC/NR/rrc_gNB_du.c | 185 +++++++++++++++++++++++++++++++++++ openair2/RRC/NR/rrc_gNB_du.h | 35 +++++++ 4 files changed, 222 insertions(+), 146 deletions(-) create mode 100644 openair2/RRC/NR/rrc_gNB_du.c create mode 100644 openair2/RRC/NR/rrc_gNB_du.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 27a7c471d5..744c645735 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1282,6 +1282,7 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB_NGAP.c ${NR_RRC_DIR}/rrc_gNB_radio_bearers.c ${NR_RRC_DIR}/rrc_gNB_cuup.c + ${NR_RRC_DIR}/rrc_gNB_du.c ) set(L2_SRC_UE diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b061187f62..348948d991 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -78,6 +78,7 @@ #include "openair3/SECU/secu_defs.h" #include "rrc_gNB_NGAP.h" +#include "rrc_gNB_du.h" #include "rrc_gNB_GTPV1U.h" @@ -1790,137 +1791,6 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, return 0; } -static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell_info_t *info) -{ - const gNB_RrcConfigurationReq *conf = &rrc->configuration; - return conf->num_plmn == 1 // F1 supports only one - && conf->mcc[0] == info->plmn.mcc - && conf->mnc[0] == info->plmn.mnc - && rrc->nr_cellid == info->nr_cellid; -} - -static void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) -{ - gNB_RRC_INST *rrc = RC.nrrrc[0]; - DevAssert(rrc); - - LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); - - // check: - // - it is the first DU - // - it is one cell - // - PLMN and Cell ID matches - // else reject - f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; - if (rrc->du != NULL) { - const f1ap_setup_req_t *other = rrc->du->setup_req; - LOG_E(NR_RRC, "can only handle one DU, but already serving DU %ld (%s)\n", other->gNB_DU_id, other->gNB_DU_name); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - if (req->num_cells_available != 1) { - LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - f1ap_served_cell_info_t *cell_info = &req->cell[0].info; - if (!rrc_gNB_plmn_matches(rrc, cell_info)) { - LOG_E(NR_RRC, - "PLMN mismatch: CU %d%d cellID %ld, DU %d%d cellID %ld\n", - rrc->configuration.mcc[0], - rrc->configuration.mnc[0], - rrc->nr_cellid, - cell_info->plmn.mcc, - cell_info->plmn.mnc, - cell_info->nr_cellid); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it - const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; - if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) { - LOG_E(NR_RRC, "no system information provided by DU, rejecting\n"); - rrc->mac_rrc.f1_setup_failure(&fail); - return; - } - - /* do we need the MIB? for the moment, just check it is valid, then drop it */ - NR_BCCH_BCH_Message_t *mib = NULL; - asn_dec_rval_t dec_rval = - uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length); - if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib - || mib->message.choice.messageClassExtension == NULL) { - LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); - rrc->mac_rrc.f1_setup_failure(&fail); - ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib); - return; - } - - NR_SIB1_t *sib1 = NULL; - if (sys_info->sib1) { - dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length); - if (dec_rval.code != RC_OK) { - LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); - rrc->mac_rrc.f1_setup_failure(&fail); - ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1); - return; - } - if (LOG_DEBUGFLAG(DEBUG_ASN1)) - xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1); - } - - LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name); - - // we accept the DU - rrc->du = calloc(1, sizeof(*rrc->du)); - AssertFatal(rrc->du != NULL, "out of memory\n"); - rrc->du->assoc_id = assoc_id; - - /* ITTI will free the setup request message via free(). So the memory - * "inside" of the message will remain, but the "outside" container no, so - * allocate memory and copy it in */ - rrc->du->setup_req = malloc(sizeof(*rrc->du->setup_req)); - AssertFatal(rrc->du->setup_req != NULL, "out of memory\n"); - *rrc->du->setup_req = *req; - rrc->du->mib = mib->message.choice.mib; - mib->message.choice.mib = NULL; - ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib); - rrc->du->sib1 = sib1; - - served_cells_to_activate_t cell = { - .plmn = cell_info->plmn, - .nr_cellid = cell_info->nr_cellid, - .nrpci = cell_info->nr_pci, - .num_SI = 0, - }; - f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell}; - if (rrc->node_name != NULL) - resp.gNB_CU_name = strdup(rrc->node_name); - rrc->mac_rrc.f1_setup_response(&resp); - - /* - MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE); - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0]; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0]; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0]; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci; - int num_SI = 0; - - if (rrc->carrier.SIB23) { - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23; - num_SI++; - } - - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI; - F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1; - // send - itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2); - */ -} - void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t *ul_rrc) { // first get RRC instance (note, no the ITTI instance) @@ -2260,21 +2130,6 @@ void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cp LOG_I(RRC, "UE %d: received bearer release complete\n", cplt->gNB_cu_cp_ue_id); } -static void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) -{ - AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); - AssertFatal(rrc->du->assoc_id == assoc_id, - "previously connected DU (%d) does not match DU for which connection has been lost (%d)\n", - rrc->du->assoc_id, - assoc_id); - (void) lc; // unused for the moment - ASN_STRUCT_FREE(asn_DEF_NR_MIB, rrc->du->mib); - ASN_STRUCT_FREE(asn_DEF_NR_SIB1, rrc->du->sib1); - free(rrc->du); - rrc->du = NULL; - LOG_I(RRC, "dropping DU with assoc_id %d (UE connections remain, if any)\n", assoc_id); -} - static void print_rrc_meas(FILE *f, const NR_MeasResults_t *measresults) { DevAssert(measresults->measResultServingMOList.list.count >= 1); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c new file mode 100644 index 0000000000..a0eec6c82d --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -0,0 +1,185 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "rrc_gNB_du.h" +#include "common/ran_context.h" +#include "nr_rrc_defs.h" +#include "openair2/F1AP/f1ap_common.h" +#include "executables/softmodem-common.h" + + +static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell_info_t *info) +{ + const gNB_RrcConfigurationReq *conf = &rrc->configuration; + return conf->num_plmn == 1 // F1 supports only one + && conf->mcc[0] == info->plmn.mcc + && conf->mnc[0] == info->plmn.mnc + && rrc->nr_cellid == info->nr_cellid; +} + +void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) +{ + gNB_RRC_INST *rrc = RC.nrrrc[0]; + DevAssert(rrc); + + LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); + + // check: + // - it is the first DU + // - it is one cell + // - PLMN and Cell ID matches + // else reject + if (rrc->du != NULL) { + const f1ap_setup_req_t *other = rrc->du->setup_req; + LOG_E(NR_RRC, "can only handle one DU, but already serving DU %ld (%s)\n", other->gNB_DU_id, other->gNB_DU_name); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; + rrc->mac_rrc.f1_setup_failure(&fail); + return; + } + if (req->num_cells_available != 1) { + LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; + rrc->mac_rrc.f1_setup_failure(&fail); + return; + } + f1ap_served_cell_info_t *cell_info = &req->cell[0].info; + if (!rrc_gNB_plmn_matches(rrc, cell_info)) { + LOG_E(NR_RRC, + "PLMN mismatch: CU %d%d cellID %ld, DU %d%d cellID %ld\n", + rrc->configuration.mcc[0], + rrc->configuration.mnc[0], + rrc->nr_cellid, + cell_info->plmn.mcc, + cell_info->plmn.mnc, + cell_info->nr_cellid); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU}; + rrc->mac_rrc.f1_setup_failure(&fail); + return; + } + // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it + const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; + if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) { + LOG_E(NR_RRC, "no system information provided by DU, rejecting\n"); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(&fail); + return; + } + + /* do we need the MIB? for the moment, just check it is valid, then drop it */ + NR_BCCH_BCH_Message_t *mib = NULL; + asn_dec_rval_t dec_rval = + uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&mib, sys_info->mib, sys_info->mib_length); + if (dec_rval.code != RC_OK || mib->message.present != NR_BCCH_BCH_MessageType_PR_mib + || mib->message.choice.messageClassExtension == NULL) { + LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(&fail); + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib); + return; + } + + NR_SIB1_t *sib1 = NULL; + if (sys_info->sib1) { + dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_SIB1, (void **)&sib1, sys_info->sib1, sys_info->sib1_length); + if (dec_rval.code != RC_OK) { + LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(&fail); + ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1); + return; + } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_SIB1, sib1); + } + + LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name); + + // we accept the DU + rrc->du = calloc(1, sizeof(*rrc->du)); + AssertFatal(rrc->du != NULL, "out of memory\n"); + rrc->du->assoc_id = assoc_id; + + /* ITTI will free the setup request message via free(). So the memory + * "inside" of the message will remain, but the "outside" container no, so + * allocate memory and copy it in */ + rrc->du->setup_req = malloc(sizeof(*rrc->du->setup_req)); + AssertFatal(rrc->du->setup_req != NULL, "out of memory\n"); + *rrc->du->setup_req = *req; + rrc->du->mib = mib->message.choice.mib; + mib->message.choice.mib = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib); + rrc->du->sib1 = sib1; + + served_cells_to_activate_t cell = { + .plmn = cell_info->plmn, + .nr_cellid = cell_info->nr_cellid, + .nrpci = cell_info->nr_pci, + .num_SI = 0, + }; + f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell}; + if (rrc->node_name != NULL) + resp.gNB_CU_name = strdup(rrc->node_name); + rrc->mac_rrc.f1_setup_response(&resp); + + /* + MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE); + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0]; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0]; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0]; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci; + int num_SI = 0; + + if (rrc->carrier.SIB23) { + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23; + num_SI++; + } + + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI; + F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1; + // send + itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2); + */ +} + +void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) +{ + AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); + AssertFatal(rrc->du->assoc_id == assoc_id, + "previously connected DU (%d) does not match DU for which connection has been lost (%d)\n", + rrc->du->assoc_id, + assoc_id); + (void) lc; // unused for the moment + + nr_rrc_du_container_t *du = rrc->du; + f1ap_setup_req_t *req = du->setup_req; + LOG_I(RRC, "releasing DU ID %ld (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); + ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib); + ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1); + /* TODO: free setup request */ + free(rrc->du); + rrc->du = NULL; + + /* TODO invalidate UE assoc IDs */ +} + diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h new file mode 100644 index 0000000000..59236d16d5 --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -0,0 +1,35 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef RRC_GNB_DU_H_ +#define RRC_GNB_DU_H_ + +#include +#include + +struct f1ap_setup_req_s; +struct f1ap_lost_connection_t; +struct gNB_RRC_INST_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); + +#endif /* RRC_GNB_DU_H_ */ From 9a092c143308ea1be8edfe1bc5086635141a47c6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 11:56:37 +0100 Subject: [PATCH 09/30] Put rrcSetupRequest/rrcReestablishmentRequest handling in separate functions --- openair2/RRC/NR/rrc_gNB.c | 335 +++++++++++++++++++------------------- 1 file changed, 164 insertions(+), 171 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 348948d991..fe4f1b31b6 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -106,7 +106,7 @@ extern RAN_CONTEXT_t RC; -static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn); +static inline uint64_t bitStr_to_uint64(const BIT_STRING_t *asn); mui_t rrc_gNB_mui = 0; @@ -1153,22 +1153,162 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP return 0; } -/*------------------------------------------------------------------------------*/ -static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) +static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, const NR_RRCSetupRequest_IEs_t *rrcSetupRequest, const f1ap_initial_ul_rrc_message_t *msg) { - asn_dec_rval_t dec_rval; - NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; - NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; - NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; - rnti_t rnti = msg->crnti; + rrc_gNB_ue_context_t *ue_context_p = NULL; + if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { + /* randomValue BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value + LOG_E(NR_RRC, + "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); + return; + } + uint64_t random_value = 0; + memcpy(((uint8_t *)&random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); + + /* if there is already a registered UE (with another RNTI) with this random_value, + * the current one must be removed from MAC/PHY (zombie UE) + */ + if ((ue_context_p = rrc_gNB_ue_context_random_exist(rrc, random_value))) { + LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", msg->crnti); + AssertFatal(false, "not implemented\n"); + } + + ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { + /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ + /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { + LOG_E(NR_RRC, + "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + return; + } + + uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); + + // memcpy(((uint8_t *) & random_value) + 3, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + + if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(rrc, s_tmsi_part1))) { + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, msg->crnti); + AssertFatal(false, "not implemented\n"); + + /* replace rnti in the context */ + UE->rnti = msg->crnti; + } else { + LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", msg->crnti, s_tmsi_part1); + + ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, s_tmsi_part1, msg->gNB_DU_ue_id); + AssertFatal(ue_context_p != NULL, "out of memory\n"); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->Initialue_identity_5g_s_TMSI.presence = true; + UE->ng_5G_S_TMSI_Part1 = s_tmsi_part1; + } + } else { + uint64_t random_value = 0; + memcpy(((uint8_t *)&random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); + + ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", msg->crnti); + rrc_gNB_generate_RRCReject(0, ue_context_p); + return; + } + + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE = &ue_context_p->ue_context; + UE->establishment_cause = rrcSetupRequest->establishmentCause; + UE->Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); +} + +static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRCReestablishmentRequest_IEs_t *req, const f1ap_initial_ul_rrc_message_t *msg) +{ + const NR_ReestablishmentCause_t cause = req->reestablishmentCause; + const long physCellId = req->ue_Identity.physCellId; + LOG_I(NR_RRC, + "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n", + msg->crnti, + physCellId, + cause == NR_ReestablishmentCause_otherFailure + ? "Other Failure" + : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); /* look up corresponding DU. For the moment, there is only one */ - const nr_rrc_du_container_t *du = gnb_rrc_inst->du; + const nr_rrc_du_container_t *du = rrc->du; AssertFatal(du != NULL, "received CCCH message, but no corresponding DU found\n"); + AssertFatal(du->setup_req->num_cells_available == 1, "cannot handle more than one cell\n"); + const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; + if (physCellId != cell_info->nr_pci) { + /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ + LOG_E(NR_RRC, + " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC " + "establishment\n", + physCellId, + cell_info->nr_pci); + /* 38.401 8.7: "If the UE accessed from a gNB-DU other than the + * original one, the gNB-CU should trigger the UE Context Setup + * procedure" we did not implement this yet; TBD for Multi-DU */ + AssertFatal(false, "not implemented\n"); + return; + } - LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", rnti, msg->rrc_container_length); - dec_rval = + rnti_t old_rnti = req->ue_Identity.c_RNTI; + // TODO: we need to check within a specific DU! + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, old_rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + /* in case we need to do RRC Setup, give the UE a new random identity */ + uint64_t random_value; + fill_random(&random_value, sizeof(random_value)); + random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ + if (ue_context_p == NULL) { + LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); + ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); + return; + } + + // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values + if (req->ue_Identity.c_RNTI < 0x1 || req->ue_Identity.c_RNTI > 0xffef) { + /* c_RNTI range error should not happen */ + LOG_E(NR_RRC, + "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", + req->ue_Identity.c_RNTI); + ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p->ue_context.Srb[1].Active = 1; + rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); + return; + } + + /* TODO: start timer in ITTI and drop UE if it does not come back */ + + // update with new RNTI, and update secondary UE association + UE->rnti = msg->crnti; + cu_remove_f1_ue_data(UE->rrc_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = msg->crnti}; + cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); + + UE->reestablishment_cause = cause; + LOG_D(NR_RRC, "Accept req-> UE physCellId %ld cause %ld\n", physCellId, cause); + + rrc_gNB_generate_RRCReestablishment(ue_context_p, msg->du2cu_rrc_container, old_rnti, du); +} + +static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) +{ + gNB_RRC_INST *rrc = RC.nrrrc[module_id]; + + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", msg->crnti, msg->rrc_container_length); + NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **)&ul_ccch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0); if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { @@ -1179,180 +1319,33 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { switch (ul_ccch_msg->message.choice.c1->present) { case NR_UL_CCCH_MessageType__c1_PR_NOTHING: - /* TODO */ - LOG_I(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message\n"); + LOG_W(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message, ignoring message\n"); break; case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: - LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", rnti); - { - rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; - rrc_gNB_ue_context_t *ue_context_p = NULL; - if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { - /* randomValue BIT STRING (SIZE (39)) */ - if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value - LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); - ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - return -1; - } - uint64_t random_value = 0; - memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - - /* if there is already a registered UE (with another RNTI) with this random_value, - * the current one must be removed from MAC/PHY (zombie UE) - */ - if ((ue_context_p = rrc_gNB_ue_context_random_exist(gnb_rrc_inst, random_value))) { - LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", rnti); - AssertFatal(false, "not implemented\n"); - } - - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { - /* TODO */ - /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ - /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ - if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - return -1; - } - - uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); - - // memcpy(((uint8_t *) & random_value) + 3, - // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, - // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - - if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(gnb_rrc_inst, s_tmsi_part1))) { - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, rnti); - AssertFatal(false, "not implemented\n"); - - /* replace rnti in the context */ - UE->rnti = rnti; - } else { - LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); - - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, s_tmsi_part1, msg->gNB_DU_ue_id); - AssertFatal(ue_context_p != NULL, "out of memory\n"); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE->Initialue_identity_5g_s_TMSI.presence = true; - UE->ng_5G_S_TMSI_Part1 = s_tmsi_part1; - } - } else { - /* TODO */ - uint64_t random_value = 0; - memcpy(((uint8_t *)&random_value) + 3, rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", rnti); - rrc_gNB_generate_RRCReject(module_id, ue_context_p); - break; - } - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE = &ue_context_p->ue_context; - UE->establishment_cause = rrcSetupRequest->establishmentCause; - UE->Srb[1].Active = 1; - rrc_gNB_generate_RRCSetup(module_id, - rnti, - ue_context_p, - msg->du2cu_rrc_container, - msg->du2cu_rrc_container_length); - } + LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", msg->crnti); + rrc_handle_RRCSetupRequest(rrc, &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest, msg); break; case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: - LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); + LOG_E(NR_RRC, "Received rrcResumeRequest message, but handling is not implemented\n"); break; case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { - LOG_DUMPMSG(NR_RRC, - DEBUG_RRC, - (char *)(msg->rrc_container), - msg->rrc_container_length, - "[MSG] RRC Reestablishment Request\n"); - rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest; - const NR_ReestablishmentCause_t cause = rrcReestablishmentRequest.reestablishmentCause; - const long physCellId = rrcReestablishmentRequest.ue_Identity.physCellId; - LOG_I(NR_RRC, - "UE %04x physCellId %ld NR_RRCReestablishmentRequest cause %s\n", - rnti, - physCellId, - cause == NR_ReestablishmentCause_otherFailure - ? "Other Failure" - : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); - - AssertFatal(du->setup_req->num_cells_available == 1, "cannot handle more than one cell\n"); - const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; - if (physCellId != cell_info->nr_pci) { - /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ - LOG_E(NR_RRC, - " NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n", - physCellId, - cell_info->nr_pci); - /* 38.401 8.7: "If the UE accessed from a gNB-DU other than the - * original one, the gNB-CU should trigger the UE Context Setup - * procedure" we did not implement this yet; TBD for Multi-DU */ - AssertFatal(false, "not implemented\n"); - break; - } - - for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { - LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); - } - - rnti_t old_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; - // TODO: we need to check within a specific DU! - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, old_rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - /* in case we need to do RRC Setup, give the UE a new random identity */ - uint64_t random_value; - fill_random(&random_value, sizeof(random_value)); - random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ - if (ue_context_p == NULL) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - ue_context_p->ue_context.Srb[1].Active = 1; - rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); - break; - } - - // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values - if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) { - /* c_RNTI range error should not happen */ - LOG_E(NR_RRC, - "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", - rrcReestablishmentRequest.ue_Identity.c_RNTI); - ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value, msg->gNB_DU_ue_id); - ue_context_p->ue_context.Srb[1].Active = 1; - rrc_gNB_generate_RRCSetup(module_id, rnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); - break; - } - - /* TODO: start timer in ITTI and drop UE if it does not come back */ - - // update with new RNTI, and update secondary UE association - UE->rnti = rnti; - cu_remove_f1_ue_data(UE->rrc_ue_id); - f1_ue_data_t ue_data = {.secondary_ue = rnti}; - cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); - - UE->reestablishment_cause = cause; - LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); - - rrc_gNB_generate_RRCReestablishment(ue_context_p, - msg->du2cu_rrc_container, - old_rnti, - du); + LOG_D(NR_RRC, "Received RRCReestablishmentRequest on UL-CCCH-Message (UE RNTI %04x)\n", msg->crnti); + rrc_handle_RRCReestablishmentRequest( + rrc, + &ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest, + msg); } break; case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: - LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", rnti); + LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", msg->crnti); /* TODO */ break; default: - LOG_E(NR_RRC, "UE %04x Unknown message\n", rnti); + LOG_E(NR_RRC, "UE %04x Unknown message\n", msg->crnti); break; } } @@ -1365,7 +1358,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r *\param[in] pointer to the BIT_STRING_t object. *\return the extracted value. */ -static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn) { +static inline uint64_t bitStr_to_uint64(const BIT_STRING_t *asn) { uint64_t result = 0; int index; int shift; From 3a5cff17d7d4f7197260fd3a7ac8ef829acb42e9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 13:33:19 +0100 Subject: [PATCH 10/30] Combine rrc_gNB_process_initial_ul_rrc_message() and nr_rrc_gNB_decode_ccch() --- openair2/RRC/NR/rrc_gNB.c | 112 ++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 65 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index fe4f1b31b6..a7f55bd0bd 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1302,57 +1302,6 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC rrc_gNB_generate_RRCReestablishment(ue_context_p, msg->du2cu_rrc_container, old_rnti, du); } -static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) -{ - gNB_RRC_INST *rrc = RC.nrrrc[module_id]; - - LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", msg->crnti, msg->rrc_container_length); - NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; - asn_dec_rval_t dec_rval = - uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **)&ul_ccch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0); - - if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { - LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); - return -1; - } - - if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { - switch (ul_ccch_msg->message.choice.c1->present) { - case NR_UL_CCCH_MessageType__c1_PR_NOTHING: - LOG_W(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message, ignoring message\n"); - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: - LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", msg->crnti); - rrc_handle_RRCSetupRequest(rrc, &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest, msg); - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: - LOG_E(NR_RRC, "Received rrcResumeRequest message, but handling is not implemented\n"); - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { - LOG_D(NR_RRC, "Received RRCReestablishmentRequest on UL-CCCH-Message (UE RNTI %04x)\n", msg->crnti); - rrc_handle_RRCReestablishmentRequest( - rrc, - &ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest, - msg); - } break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: - LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", msg->crnti); - /* TODO */ - break; - - default: - LOG_E(NR_RRC, "UE %04x Unknown message\n", msg->crnti); - break; - } - } - ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); - return 0; -} - /*! \fn uint64_t bitStr_to_uint64(BIT_STRING_t *) *\brief This function extract at most a 64 bits value from a BIT_STRING_t object, the exact bits number depend on the BIT_STRING_t contents. *\param[in] pointer to the BIT_STRING_t object. @@ -1786,22 +1735,55 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t *ul_rrc) { - // first get RRC instance (note, no the ITTI instance) - module_id_t i = 0; - for (i=0; i < RC.nb_nr_inst; i++) { - gNB_RRC_INST *rrc = RC.nrrrc[i]; - if (rrc->nr_cellid == ul_rrc->nr_cellid) - break; + gNB_RRC_INST *rrc = RC.nrrrc[0]; + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", ul_rrc->crnti, ul_rrc->rrc_container_length); + NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_UL_CCCH_Message, + (void **)&ul_ccch_msg, + ul_rrc->rrc_container, + ul_rrc->rrc_container_length, + 0, + 0); + if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { + LOG_E(NR_RRC, " FATAL Error in receiving CCCH\n"); + return; } - //AssertFatal(i != RC.nb_nr_inst, "Cell_id not found\n"); - // TODO REMOVE_DU_RRC in monolithic mode, the MAC does not have the - // nr_cellid. Thus, the above check would fail. For the time being, just put - // a warning, as we handle one DU only anyway - if (i == RC.nb_nr_inst) { - i = 0; - LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); + + if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { + switch (ul_ccch_msg->message.choice.c1->present) { + case NR_UL_CCCH_MessageType__c1_PR_NOTHING: + LOG_W(NR_RRC, "Received PR_NOTHING on UL-CCCH-Message, ignoring message\n"); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: + LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", ul_rrc->crnti); + rrc_handle_RRCSetupRequest(rrc, &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest, ul_rrc); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: + LOG_E(NR_RRC, "Received rrcResumeRequest message, but handling is not implemented\n"); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: { + LOG_D(NR_RRC, "Received RRCReestablishmentRequest on UL-CCCH-Message (UE RNTI %04x)\n", ul_rrc->crnti); + rrc_handle_RRCReestablishmentRequest( + rrc, + &ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest, + ul_rrc); + } break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: + LOG_I(NR_RRC, "UE %04x receive rrcSystemInfoRequest message \n", ul_rrc->crnti); + /* TODO */ + break; + + default: + LOG_E(NR_RRC, "UE %04x Unknown message\n", ul_rrc->crnti); + break; + } } - nr_rrc_gNB_decode_ccch(i, ul_rrc); + ASN_STRUCT_FREE(asn_DEF_NR_UL_CCCH_Message, ul_ccch_msg); if (ul_rrc->rrc_container) free(ul_rrc->rrc_container); From 8cdb23639b8c0e152dd13a344a64283dad11024f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 09:51:23 +0100 Subject: [PATCH 11/30] Bugfix: on reestablishment, save new gNB DU UE ID, not RNTI --- openair2/RRC/NR/rrc_gNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index a7f55bd0bd..31911f4aa1 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1293,7 +1293,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC // update with new RNTI, and update secondary UE association UE->rnti = msg->crnti; cu_remove_f1_ue_data(UE->rrc_ue_id); - f1_ue_data_t ue_data = {.secondary_ue = msg->crnti}; + f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id, .du_assoc_id = assoc_id}; cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); UE->reestablishment_cause = cause; From 1af4e8195101eecb36184fd0fa06e6602dc1bf11 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 13:57:14 +0100 Subject: [PATCH 12/30] Paging: not fully implemented, make clear is dummy --- openair2/F1AP/f1ap_du_paging.c | 4 +--- openair2/RRC/NR/nr_rrc_proto.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 9 +++++---- openair2/RRC/NR/rrc_gNB_NGAP.c | 3 ++- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c index 08a2b319e7..5351b6bf26 100644 --- a/openair2/F1AP/f1ap_du_paging.c +++ b/openair2/F1AP/f1ap_du_paging.c @@ -87,9 +87,7 @@ int DU_handle_Paging(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, F1AP_ProtocolIE_ID_id_PagingCell_List, true); - for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - rrc_gNB_generate_pcch_msg((uint32_t)tmsi, pagingdrx, instance, CC_id); - } + AssertFatal(false, "not implemented\n"); return 0; } diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index e5cf454b76..453decc64e 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -159,7 +159,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint); -int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id); +int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint32_t tmsi, uint8_t paging_drx); void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue_p, uint8_t srb_id, const uint8_t* buffer, int size); /** @}*/ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 31911f4aa1..2099cbc432 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2663,7 +2663,10 @@ void rrc_gNB_trigger_release_bearer(int rnti) rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } -int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){ +int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx) +{ + instance_t instance = 0; + uint8_t CC_id = 0; const unsigned int Ttab[4] = {32,64,128,256}; uint8_t Tc; uint8_t Tue; @@ -2674,9 +2677,6 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst uint32_t T; /* DRX cycle */ uint32_t length; uint8_t buffer[RRC_BUF_SIZE]; - const nr_rrc_du_container_t *du = RC.nrrrc[0]->du; - DevAssert(du != NULL); - struct NR_SIB1 *sib1 = du->sib1; /* get default DRX cycle from configuration */ Tc = sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle; @@ -2784,6 +2784,7 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst return -1; } // TODO, send message to pdcp + (void) assoc_id; return 0; } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 49d3ccad99..e2f7c8a13f 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1356,6 +1356,7 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance) && RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc && RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) { for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + AssertFatal(false, "to be implemented properly\n"); if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) { MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND); F1AP_PAGING_IND(m).plmn.mcc = RC.nrrrc[j]->configuration.mcc[0]; @@ -1368,7 +1369,7 @@ int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance) LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx); itti_send_msg_to_task(TASK_CU_F1, instance, m); } else { - rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); + //rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); } // end of nodetype check } // end of cc loop } // end of mcc mnc check From 843a1dc0a3a69995aa88e22044a1ce16ddc6de5c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 15:13:30 +0100 Subject: [PATCH 13/30] Introduce lookup functions for DUs --- openair2/RRC/NR/rrc_gNB.c | 21 +++++++++------------ openair2/RRC/NR/rrc_gNB_du.c | 13 +++++++++++++ openair2/RRC/NR/rrc_gNB_du.h | 5 +++++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2099cbc432..7f97f51f8b 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -524,9 +524,6 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_p->xids[xid] = RRC_DEFAULT_RECONF; - const nr_rrc_du_container_t *du = rrc->du; - DevAssert(du != NULL); - struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList)); /* Add all NAS PDUs to the list */ @@ -551,7 +548,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co dedicatedNAS_MessageList = NULL; } - AssertFatal(du->setup_req->num_cells_available == 1, "cannot handle more than one cell, but have %d\n", du->setup_req->num_cells_available); + const nr_rrc_du_container_t *du = get_du_for_ue(rrc, ue_p->rrc_ue_id); + DevAssert(du != NULL); f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; int scs = get_ssb_scs(cell_info); int band = get_dl_band(cell_info); @@ -1241,10 +1239,12 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC ? "Other Failure" : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); - /* look up corresponding DU. For the moment, there is only one */ - const nr_rrc_du_container_t *du = rrc->du; - AssertFatal(du != NULL, "received CCCH message, but no corresponding DU found\n"); - AssertFatal(du->setup_req->num_cells_available == 1, "cannot handle more than one cell\n"); + sctp_assoc_t assoc_id = 0; // currently, we have only one DU + const nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id); + if (du == NULL) { + LOG_E(RRC, "received CCCH message, but no corresponding DU found\n"); + return; + } const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; if (physCellId != cell_info->nr_pci) { /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */ @@ -1293,7 +1293,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC // update with new RNTI, and update secondary UE association UE->rnti = msg->crnti; cu_remove_f1_ue_data(UE->rrc_ue_id); - f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id, .du_assoc_id = assoc_id}; + f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id}; cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); UE->reestablishment_cause = cause; @@ -2417,9 +2417,6 @@ rrc_gNB_generate_SecurityModeCommand( cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len; } - const nr_rrc_du_container_t *du = rrc->du; - DevAssert(du != NULL); - /* the callback will fill the UE context setup request and forward it */ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1ap_ue_context_setup_t ue_context_setup_req = { diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index a0eec6c82d..98c3cd7a12 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -183,3 +183,16 @@ void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t /* TODO invalidate UE assoc IDs */ } +nr_rrc_du_container_t *get_du_for_ue(gNB_RRC_INST *rrc, uint32_t ue_id) +{ + nr_rrc_du_container_t *du = rrc->du; + if (du == NULL) + return NULL; + return du; +} + +nr_rrc_du_container_t *get_du_by_assoc_id(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) +{ + AssertFatal(assoc_id == rrc->du->assoc_id, "cannot handle multiple DUs yet\n"); + return rrc->du; +} diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h index 59236d16d5..c7472d652c 100644 --- a/openair2/RRC/NR/rrc_gNB_du.h +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -24,12 +24,17 @@ #include #include +#include struct f1ap_setup_req_s; struct f1ap_lost_connection_t; struct gNB_RRC_INST_s; +struct nr_rrc_du_container_t; 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); +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); + #endif /* RRC_GNB_DU_H_ */ From e5684d217c03c6f9041a11c350c920cc7bef8883 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 16:07:58 +0100 Subject: [PATCH 14/30] Assoc ID DU->CU --- openair2/F1AP/f1ap_cu_rrc_message_transfer.c | 1 + openair2/F1AP/f1ap_cu_ue_context_management.c | 5 ++++ openair2/F1AP/f1ap_ids.h | 1 + .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 7 +++++ openair2/RRC/NR/rrc_gNB.c | 26 ++++++++++--------- openair2/RRC/NR/rrc_gNB_UE_context.c | 5 ++-- openair2/RRC/NR/rrc_gNB_UE_context.h | 3 ++- openair2/RRC/NR/rrc_gNB_du.c | 2 ++ 8 files changed, 35 insertions(+), 15 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 7e640ccffd..03c210c972 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -88,6 +88,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t // create an ITTI message and copy SDU message_p = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); ul_rrc->gNB_DU_ue_id = du_ue_id; ul_rrc->nr_cellid = nr_cellid; // CU instance diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 18663305e3..0508c48d31 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -639,6 +639,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_ F1AP_UEContextSetupResponseIEs_t *ie; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_RESP); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_setup_t *f1ap_ue_context_setup_resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextSetupResponse; int i; @@ -772,6 +773,7 @@ int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_i int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); F1AP_UEContextReleaseRequest_t *container; F1AP_UEContextReleaseRequestIEs_t *ie; @@ -921,6 +923,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso F1AP_UEContextReleaseCompleteIEs_t *ie; DevAssert(pdu); MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete; /* GNB_CU_UE_F1AP_ID */ @@ -1576,6 +1579,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t F1AP_UEContextModificationResponseIEs_t *ie; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; int i; @@ -1704,6 +1708,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, sctp_assoc_t DevAssert(pdu != NULL); MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + msg_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p); F1AP_UEContextModificationRequired_t *container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequired; diff --git a/openair2/F1AP/f1ap_ids.h b/openair2/F1AP/f1ap_ids.h index 60d35de737..54d17243c5 100644 --- a/openair2/F1AP/f1ap_ids.h +++ b/openair2/F1AP/f1ap_ids.h @@ -34,6 +34,7 @@ typedef struct f1_ue_data_t { uint32_t secondary_ue; sctp_assoc_t e1_assoc_id; + sctp_assoc_t du_assoc_id; // only used at the CU } f1_ue_data_t; void cu_init_f1_ue_data(void); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index ab3b7646e7..19289597e3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -27,6 +27,7 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_setup_req_t *f1ap_msg = &F1AP_SETUP_REQ(msg); f1ap_msg->gNB_DU_id = req->gNB_DU_id; f1ap_msg->gNB_DU_name = strdup(req->gNB_DU_name); @@ -71,6 +72,7 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, (void) req; /* we don't need the request -- it is to set up GTP in F1 case */ MessageDef *msg = itti_alloc_new_message (TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_RESP(msg); /* copy all fields, but reallocate memory buffers! */ *f1ap_msg = *resp; @@ -100,6 +102,7 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ { (void)req; /* we don't need the request -- it is to set up GTP in F1 case */ MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; @@ -152,6 +155,7 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ static void ue_context_modification_required_direct(const f1ap_ue_context_modif_required_t *required) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQUIRED); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_modif_required_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg); f1ap_msg->gNB_CU_ue_id = required->gNB_CU_ue_id; f1ap_msg->gNB_DU_ue_id = required->gNB_DU_ue_id; @@ -177,6 +181,7 @@ static void ue_context_modification_required_direct(const f1ap_ue_context_modif_ static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); *f1ap_msg = *req; itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); @@ -185,6 +190,7 @@ static void ue_context_release_request_direct(const f1ap_ue_context_release_req_ static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + msg->ittiMsgHeader.originInstance = -1; // means monolithic f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); *f1ap_msg = *complete; itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); @@ -193,6 +199,7 @@ static void ue_context_release_complete_direct(const f1ap_ue_context_release_com static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + msg->ittiMsgHeader.originInstance = -1; // means monolithic /* copy all fields, but reallocate rrc_containers! */ f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); *f1ap_msg = *ul_rrc; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7f97f51f8b..ece5ac35cb 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1151,7 +1151,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP return 0; } -static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, const NR_RRCSetupRequest_IEs_t *rrcSetupRequest, const f1ap_initial_ul_rrc_message_t *msg) +static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id, const NR_RRCSetupRequest_IEs_t *rrcSetupRequest, const f1ap_initial_ul_rrc_message_t *msg) { rrc_gNB_ue_context_t *ue_context_p = NULL; if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { @@ -1175,7 +1175,7 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, const NR_RRCSetupReque AssertFatal(false, "not implemented\n"); } - ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ @@ -1202,7 +1202,7 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, const NR_RRCSetupReque } else { LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", msg->crnti, s_tmsi_part1); - ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, s_tmsi_part1, msg->gNB_DU_ue_id); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, s_tmsi_part1, msg->gNB_DU_ue_id); AssertFatal(ue_context_p != NULL, "out of memory\n"); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; UE->Initialue_identity_5g_s_TMSI.presence = true; @@ -1214,7 +1214,7 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, const NR_RRCSetupReque rrcSetupRequest->ue_Identity.choice.randomValue.buf, rrcSetupRequest->ue_Identity.choice.randomValue.size); - ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); LOG_E(NR_RRC, "RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE %04x\n", msg->crnti); rrc_gNB_generate_RRCReject(0, ue_context_p); return; @@ -1227,7 +1227,7 @@ static void rrc_handle_RRCSetupRequest(gNB_RRC_INST *rrc, const NR_RRCSetupReque rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); } -static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRCReestablishmentRequest_IEs_t *req, const f1ap_initial_ul_rrc_message_t *msg) +static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id, const NR_RRCReestablishmentRequest_IEs_t *req, const f1ap_initial_ul_rrc_message_t *msg) { const NR_ReestablishmentCause_t cause = req->reestablishmentCause; const long physCellId = req->ue_Identity.physCellId; @@ -1239,7 +1239,6 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC ? "Other Failure" : (cause == NR_ReestablishmentCause_handoverFailure ? "Handover Failure" : "reconfigurationFailure")); - sctp_assoc_t assoc_id = 0; // currently, we have only one DU const nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id); if (du == NULL) { LOG_E(RRC, "received CCCH message, but no corresponding DU found\n"); @@ -1270,7 +1269,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC random_value = random_value & 0x7fffffffff; /* random value is 39 bits */ if (ue_context_p == NULL) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC setup\n"); - ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); ue_context_p->ue_context.Srb[1].Active = 1; rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); return; @@ -1282,7 +1281,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI %04lx range error, fallback to RRC setup\n", req->ue_Identity.c_RNTI); - ue_context_p = rrc_gNB_create_ue_context(msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); + ue_context_p = rrc_gNB_create_ue_context(assoc_id, msg->crnti, rrc, random_value, msg->gNB_DU_ue_id); ue_context_p->ue_context.Srb[1].Active = 1; rrc_gNB_generate_RRCSetup(0, msg->crnti, ue_context_p, msg->du2cu_rrc_container, msg->du2cu_rrc_container_length); return; @@ -1293,7 +1292,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, const NR_RRC // update with new RNTI, and update secondary UE association UE->rnti = msg->crnti; cu_remove_f1_ue_data(UE->rrc_ue_id); - f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id}; + f1_ue_data_t ue_data = {.secondary_ue = msg->gNB_DU_ue_id, .du_assoc_id = assoc_id}; cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); UE->reestablishment_cause = cause; @@ -1733,8 +1732,10 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, return 0; } -void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t *ul_rrc) +void rrc_gNB_process_initial_ul_rrc_message(sctp_assoc_t assoc_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); + gNB_RRC_INST *rrc = RC.nrrrc[0]; LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, payload_size %d\n", ul_rrc->crnti, ul_rrc->rrc_container_length); NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; @@ -1758,7 +1759,7 @@ void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %04x)\n", ul_rrc->crnti); - rrc_handle_RRCSetupRequest(rrc, &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest, ul_rrc); + rrc_handle_RRCSetupRequest(rrc, assoc_id, &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest, ul_rrc); break; case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: @@ -1769,6 +1770,7 @@ void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t LOG_D(NR_RRC, "Received RRCReestablishmentRequest on UL-CCCH-Message (UE RNTI %04x)\n", ul_rrc->crnti); rrc_handle_RRCReestablishmentRequest( rrc, + assoc_id, &ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest, ul_rrc); } break; @@ -2242,7 +2244,7 @@ void *rrc_gnb_task(void *args_p) { case F1AP_INITIAL_UL_RRC_MESSAGE: AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type), "should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n"); - rrc_gNB_process_initial_ul_rrc_message(&F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); + rrc_gNB_process_initial_ul_rrc_message(msg_p->ittiMsgHeader.originInstance, &F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); break; /* Messages from PDCP */ diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 8a8c0bdd2e..396edc3175 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -157,7 +157,8 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, rnti not found in collection -rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, +rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id, + rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP, uint32_t du_ue_id) @@ -170,7 +171,7 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_UE_t *ue = &ue_context_p->ue_context; ue->rnti = rnti; ue->random_ue_identity = ue_identityP; - f1_ue_data_t ue_data = {.secondary_ue = du_ue_id}; + f1_ue_data_t ue_data = {.secondary_ue = du_ue_id, .du_assoc_id = assoc_id}; AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id), "UE F1 Context for ID %d already exists, logic bug\n", ue->rrc_ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 3ec0852af6..172ac07ef2 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -50,7 +50,8 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); -rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, +rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(sctp_assoc_t assoc_id, + rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP, uint32_t du_ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 98c3cd7a12..5e47269cc6 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -37,6 +37,7 @@ static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, 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); @@ -164,6 +165,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) 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"); AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); AssertFatal(rrc->du->assoc_id == assoc_id, "previously connected DU (%d) does not match DU for which connection has been lost (%d)\n", From a377e5231c722d7d9647792efe8bad86f823380f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 19:49:41 +0100 Subject: [PATCH 15/30] Set UE DU assoc_id to 0 on DU disconnect An assoc_id of 0 is used to mark UEs whose DU is "offline" (not connected). In this patch, if a DU disconnects, we go through all UEs and set their assoc_id to 0 if they belong to a UE that just went offline. --- openair2/RRC/NR/rrc_gNB_du.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 5e47269cc6..a1b459b6f9 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -22,7 +22,9 @@ #include "rrc_gNB_du.h" #include "common/ran_context.h" #include "nr_rrc_defs.h" +#include "rrc_gNB_UE_context.h" #include "openair2/F1AP/f1ap_common.h" +#include "openair2/F1AP/f1ap_ids.h" #include "executables/softmodem-common.h" @@ -163,6 +165,25 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) */ } +static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) +{ + int count = 0; + rrc_gNB_ue_context_t *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) { + uint32_t ue_id = ue_context_p->ue_context.rrc_ue_id; + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); + if (ue_data.du_assoc_id == assoc_id) { + /* this UE belongs to the DU that disconnected, set du_assoc_id to 0, + * meaning DU is offline */ + cu_remove_f1_ue_data(ue_id); + f1_ue_data_t new = {.secondary_ue = ue_data.secondary_ue, .du_assoc_id = 0 }; + cu_add_f1_ue_data(ue_id, &new); + count++; + } + } + return count; +} + 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"); @@ -182,7 +203,10 @@ void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t free(rrc->du); rrc->du = NULL; - /* TODO invalidate UE assoc IDs */ + int num = invalidate_du_connections(rrc, assoc_id); + if (num > 0) { + LOG_I(NR_RRC, "%d UEs lost through DU disconnect\n", num); + } } nr_rrc_du_container_t *get_du_for_ue(gNB_RRC_INST *rrc, uint32_t ue_id) From e155080ece74a08d783f79337587d996bf976d00 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 30 Oct 2023 17:03:45 +0100 Subject: [PATCH 16/30] Assoc ID CU->DU --- openair2/F1AP/f1ap_cu_task.c | 2 +- openair2/RRC/NR/mac_rrc_dl.h | 16 ++++---- openair2/RRC/NR/mac_rrc_dl_direct.c | 64 +++++++++++++++++++++++++---- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 24 +++++++---- openair2/RRC/NR/rrc_gNB.c | 50 +++++++++++++++------- openair2/RRC/NR/rrc_gNB_du.c | 14 +++---- 6 files changed, 124 insertions(+), 46 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index d89cba3a4e..75d6e1b8cc 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -145,7 +145,7 @@ void *F1AP_CU_task(void *arg) { while (1) { itti_receive_msg(TASK_CU_F1, &received_msg); - sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->assoc_id : 0; + sctp_assoc_t assoc_id = ITTI_MSG_ORIGIN_INSTANCE(received_msg); LOG_D(F1AP, "CU Task Received %s for instance %ld: sending SCTP message via assoc_id %d\n", ITTI_MSG_NAME(received_msg), ITTI_MSG_DESTINATION_INSTANCE(received_msg), assoc_id); switch (ITTI_MSG_ID(received_msg)) { diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 6e43212f5e..36c6af4396 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -25,16 +25,16 @@ #include "platform_types.h" #include "f1ap_messages_types.h" -typedef void (*f1_setup_response_func_t)(const f1ap_setup_resp_t *resp); -typedef void (*f1_setup_failure_func_t)(const f1ap_setup_failure_t *fail); +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 (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); -typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); -typedef void (*ue_context_modification_confirm_func_t)(const f1ap_ue_context_modif_confirm_t *confirm); -typedef void (*ue_context_modification_refuse_func_t)(const f1ap_ue_context_modif_refuse_t *refuse); -typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); +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); +typedef void (*ue_context_modification_confirm_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm); +typedef void (*ue_context_modification_refuse_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse); +typedef void (*ue_context_release_command_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd); -typedef void (*dl_rrc_message_transfer_func_t)(const f1ap_dl_rrc_message_t *dl_rrc); +typedef void (*dl_rrc_message_transfer_func_t)(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc); struct nr_mac_rrc_dl_if_s; void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index ee9a29c6ae..55d1bf0236 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -24,14 +24,62 @@ #include "mac_rrc_dl.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" +static void f1_setup_response_direct(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + f1_setup_response(resp); +} + +static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + f1_setup_failure(fail); +} + +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); + ue_context_setup_request(req); +} + +static void ue_context_modification_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_modification_request(req); +} + +static void ue_context_modification_confirm_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_modification_confirm(confirm); +} + +static void ue_context_modification_refuse_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_modification_refuse(refuse); +} + +static void ue_context_release_command_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + ue_context_release_command(cmd); +} + +static void dl_rrc_message_transfer_direct(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); + dl_rrc_message_transfer(dl_rrc); +} + void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { - mac_rrc->f1_setup_response = f1_setup_response; - mac_rrc->f1_setup_failure = f1_setup_failure; - mac_rrc->ue_context_setup_request = ue_context_setup_request; - mac_rrc->ue_context_modification_request = ue_context_modification_request; - mac_rrc->ue_context_modification_confirm = ue_context_modification_confirm; - mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse; - mac_rrc->ue_context_release_command = ue_context_release_command; - mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer; + mac_rrc->f1_setup_response = f1_setup_response_direct; + mac_rrc->f1_setup_failure = f1_setup_failure_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; + mac_rrc->ue_context_modification_refuse = ue_context_modification_refuse_direct; + mac_rrc->ue_context_release_command = ue_context_release_command_direct; + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 951e9639c5..891d5d94f1 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -24,9 +24,10 @@ #include "mac_rrc_dl.h" #include "nr_rrc_defs.h" -static void f1_setup_response_f1ap(const f1ap_setup_resp_t *resp) +static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_resp_t *f1ap_msg = &F1AP_SETUP_RESP(msg); *f1ap_msg = *resp; if (resp->gNB_CU_name != NULL) @@ -34,17 +35,19 @@ static void f1_setup_response_f1ap(const f1ap_setup_resp_t *resp) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void f1_setup_failure_f1ap(const f1ap_setup_failure_t *fail) +static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_FAILURE); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_setup_failure_t *f1ap_msg = &F1AP_SETUP_FAILURE(msg); *f1ap_msg = *fail; itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) +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); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); *f1ap_msg = *req; AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); @@ -59,9 +62,10 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req) +static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg); *f1ap_msg = *req; if (req->cu_to_du_rrc_information != NULL) { @@ -110,9 +114,10 @@ static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_confirm_t *confirm) +static void ue_context_modification_confirm_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_CONFIRM); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_confirm_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_CONFIRM(msg); f1ap_msg->gNB_CU_ue_id = confirm->gNB_CU_ue_id; f1ap_msg->gNB_DU_ue_id = confirm->gNB_DU_ue_id; @@ -127,17 +132,19 @@ static void ue_context_modification_confirm_f1ap(const f1ap_ue_context_modif_con itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_refuse_f1ap(const f1ap_ue_context_modif_refuse_t *refuse) +static void ue_context_modification_refuse_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REFUSE); + msg->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_modif_refuse_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REFUSE(msg); *f1ap_msg = *refuse; itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) +static void ue_context_release_command_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd) { MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); *msg = *cmd; if (cmd->rrc_container_length > 0) { @@ -149,11 +156,12 @@ static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } -static void dl_rrc_message_transfer_f1ap(const f1ap_dl_rrc_message_t *dl_rrc) +static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); + message_p->ittiMsgHeader.originInstance = assoc_id; f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); *msg = *dl_rrc; if (dl_rrc->old_gNB_DU_ue_id) { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ece5ac35cb..ca8223bd96 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -110,6 +110,16 @@ static inline uint64_t bitStr_to_uint64(const BIT_STRING_t *asn); mui_t rrc_gNB_mui = 0; +// the assoc_id might be 0 (if the DU goes offline). Below helper macro to +// print an error and return from the function in that case +#define RETURN_IF_INVALID_ASSOC_ID(ue_data) \ + { \ + if (ue_data.du_assoc_id == 0) { \ + LOG_E(NR_RRC, "cannot send data: invalid assoc_id 0, DU offline\n"); \ + return; \ + } \ + } + ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -189,6 +199,7 @@ static void freeDRBlist(NR_DRB_ToAddModList_t *list) typedef struct deliver_dl_rrc_message_data_s { const gNB_RRC_INST *rrc; f1ap_dl_rrc_message_t *dl_rrc; + sctp_assoc_t assoc_id; } deliver_dl_rrc_message_data_t; static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { @@ -197,7 +208,7 @@ static void rrc_deliver_dl_rrc_message(void *deliver_pdu_data, ue_id_t ue_id, in data->dl_rrc->rrc_container = (uint8_t *)buf; data->dl_rrc->rrc_container_length = size; DevAssert(data->dl_rrc->srb_id == srb_id); - data->rrc->mac_rrc.dl_rrc_message_transfer(data->dl_rrc); + data->rrc->mac_rrc.dl_rrc_message_transfer(data->assoc_id, data->dl_rrc); } @@ -205,8 +216,9 @@ void nr_rrc_transfer_protected_rrc_message(const gNB_RRC_INST *rrc, const gNB_RR { DevAssert(size > 0); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = srb_id}; - deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id }; nr_pdcp_data_req_srb(ue_p->rrc_ue_id, srb_id, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } @@ -452,6 +464,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, freeSRBlist(SRBs); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -459,7 +472,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, .rrc_container_length = size, .srb_id = CCCH }; - rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(ue_data.du_assoc_id, &dl_rrc); } static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP) @@ -481,6 +494,7 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context LOG_I(NR_RRC, " [RAPROC] ue %04x Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", ue_p->rnti, size); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -490,7 +504,7 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context .execute_duplication = 1, .RAT_frequency_priority_information.en_dc = 0 }; - rrc->mac_rrc.dl_rrc_message_transfer(&dl_rrc); + rrc->mac_rrc.dl_rrc_message_transfer(ue_data.du_assoc_id, &dl_rrc); } //----------------------------------------------------------------------------- @@ -1038,12 +1052,13 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context nr_pdcp_reestablishment(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); uint32_t old_gNB_DU_ue_id = old_rnti; f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, .srb_id = DCCH, .old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; - deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc, .assoc_id = ue_data.du_assoc_id}; nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } @@ -1573,6 +1588,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ gNB_RRC_INST *rrc = RC.nrrrc[0]; f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -1583,7 +1599,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ .servCellId = 0, /* TODO: correct value? */ .ReconfigComplOutcome = successful_reconfig ? RRCreconf_success : RRCreconf_failure, }; - rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } //----------------------------------------------------------------------------- int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, @@ -1953,7 +1969,7 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p) .cause = F1AP_CAUSE_RADIO_NETWORK, .cause_value = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_cu_ue_f1ap_id, }; - rrc->mac_rrc.ue_context_modification_refuse(&refuse); + rrc->mac_rrc.ue_context_modification_refuse(msg_p->ittiMsgHeader.originInstance, &refuse); return; } @@ -1978,7 +1994,7 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p) .cause = F1AP_CAUSE_PROTOCOL, .cause_value = F1AP_CauseProtocol_transfer_syntax_error, }; - rrc->mac_rrc.ue_context_modification_refuse(&refuse); + rrc->mac_rrc.ue_context_modification_refuse(msg_p->ittiMsgHeader.originInstance, &refuse); return; } @@ -2065,6 +2081,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp } f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2079,7 +2096,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp .drbs_to_be_setup = drbs, .cu_to_du_rrc_information = cu2du_p, }; - rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp) @@ -2380,6 +2397,7 @@ void *rrc_gnb_task(void *args_p) { typedef struct deliver_ue_ctxt_setup_data_t { gNB_RRC_INST *rrc; f1ap_ue_context_setup_t *setup_req; + sctp_assoc_t assoc_id; } deliver_ue_ctxt_setup_data_t; static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { @@ -2387,7 +2405,7 @@ static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, deliver_ue_ctxt_setup_data_t *data = deliver_pdu_data; data->setup_req->rrc_container = (uint8_t*)buf; data->setup_req->rrc_container_length = size; - data->rrc->mac_rrc.ue_context_setup_request(data->setup_req); + data->rrc->mac_rrc.ue_context_setup_request(data->assoc_id, data->setup_req); } //----------------------------------------------------------------------------- @@ -2421,6 +2439,7 @@ rrc_gNB_generate_SecurityModeCommand( /* the callback will fill the UE context setup request and forward it */ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_setup_t ue_context_setup_req = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2433,7 +2452,7 @@ rrc_gNB_generate_SecurityModeCommand( .drbs_to_be_setup = 0, /* no new DRBs */ .cu_to_du_rrc_information = cu2du_p, }; - deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req}; + deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req, .assoc_id = ue_data.du_assoc_id }; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, &data); } @@ -2467,6 +2486,7 @@ rrc_gNB_generate_UECapabilityEnquiry( typedef struct deliver_ue_ctxt_release_data_t { gNB_RRC_INST *rrc; f1ap_ue_context_release_cmd_t *release_cmd; + sctp_assoc_t assoc_id; } deliver_ue_ctxt_release_data_t; static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { @@ -2474,7 +2494,7 @@ static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_i deliver_ue_ctxt_release_data_t *data = deliver_pdu_data; data->release_cmd->rrc_container = (uint8_t*) buf; data->release_cmd->rrc_container_length = size; - data->rrc->mac_rrc.ue_context_release_command(data->release_cmd); + data->rrc->mac_rrc.ue_context_release_command(data->assoc_id, data->release_cmd); } //----------------------------------------------------------------------------- @@ -2500,6 +2520,7 @@ rrc_gNB_generate_RRCRelease( gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_release_cmd_t ue_context_release_cmd = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2507,7 +2528,7 @@ rrc_gNB_generate_RRCRelease( .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release .srb_id = DCCH, }; - deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd}; + deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = ue_data.du_assoc_id}; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); @@ -2644,6 +2665,7 @@ void rrc_gNB_trigger_release_bearer(int rnti) f1ap_drb_to_be_released_t drbs_to_be_released[1] = {{.rb_id = drb_id}}; f1_ue_data_t ue_data = cu_get_f1_ue_data(ue->rrc_ue_id); + RETURN_IF_INVALID_ASSOC_ID(ue_data); f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = ue->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, @@ -2659,7 +2681,7 @@ void rrc_gNB_trigger_release_bearer(int rnti) .drbs_to_be_released_length = 1, .drbs_to_be_released = drbs_to_be_released, }; - rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); } int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx) diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index a1b459b6f9..ac73553f2d 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -54,13 +54,13 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) const f1ap_setup_req_t *other = rrc->du->setup_req; LOG_E(NR_RRC, "can only handle one DU, but already serving DU %ld (%s)\n", other->gNB_DU_id, other->gNB_DU_name); f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; - rrc->mac_rrc.f1_setup_failure(&fail); + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } if (req->num_cells_available != 1) { LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available); f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; - rrc->mac_rrc.f1_setup_failure(&fail); + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } f1ap_served_cell_info_t *cell_info = &req->cell[0].info; @@ -74,7 +74,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) cell_info->plmn.mnc, cell_info->nr_cellid); f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU}; - rrc->mac_rrc.f1_setup_failure(&fail); + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it @@ -82,7 +82,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) { LOG_E(NR_RRC, "no system information provided by DU, rejecting\n"); f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; - rrc->mac_rrc.f1_setup_failure(&fail); + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } @@ -94,7 +94,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) || mib->message.choice.messageClassExtension == NULL) { LOG_E(RRC, "Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; - rrc->mac_rrc.f1_setup_failure(&fail); + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, mib); return; } @@ -105,7 +105,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) if (dec_rval.code != RC_OK) { LOG_E(RRC, "Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU\n", dec_rval.consumed); f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; - rrc->mac_rrc.f1_setup_failure(&fail); + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); ASN_STRUCT_FREE(asn_DEF_NR_SIB1, sib1); return; } @@ -140,7 +140,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) f1ap_setup_resp_t resp = {.num_cells_to_activate = 1, .cells_to_activate[0] = cell}; if (rrc->node_name != NULL) resp.gNB_CU_name = strdup(rrc->node_name); - rrc->mac_rrc.f1_setup_response(&resp); + rrc->mac_rrc.f1_setup_response(assoc_id, &resp); /* MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE); From c812cea143052162bee9789d0fe4f5d5fcf86feb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 15:03:54 +0100 Subject: [PATCH 17/30] Multiple DUs in a tree --- openair2/RRC/NR/nr_rrc_defs.h | 7 ++- openair2/RRC/NR/rrc_gNB.c | 1 + openair2/RRC/NR/rrc_gNB_du.c | 81 ++++++++++++++++++++++------------- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 2d5e00b3fc..892873638a 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -366,6 +366,9 @@ typedef struct cucp_cuup_if_s { } cucp_cuup_if_t; typedef struct nr_rrc_du_container_t { + /* Tree-related data */ + RB_ENTRY(nr_rrc_du_container_t) entries; + sctp_assoc_t assoc_id; f1ap_setup_req_t *setup_req; NR_MIB_t *mib; @@ -408,7 +411,9 @@ typedef struct gNB_RRC_INST_s { nr_mac_rrc_dl_if_t mac_rrc; cucp_cuup_if_t cucp_cuup; - nr_rrc_du_container_t *du; + RB_HEAD(rrc_du_tree, nr_rrc_du_container_t) dus; // DUs, indexed by assoc_id + size_t num_dus; + RB_HEAD(rrc_cuup_tree, nr_rrc_cuup_container_t) cuups; // CU-UPs, indexed by assoc_id size_t num_cuups; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ca8223bd96..50cdd38c4d 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -345,6 +345,7 @@ void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *c uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); RB_INIT(&rrc->cuups); + RB_INIT(&rrc->dus); rrc->configuration = *configuration; /// System Information INIT init_NR_SI(rrc); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index ac73553f2d..5423e690e2 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -28,6 +28,18 @@ #include "executables/softmodem-common.h" +static int du_compare(const nr_rrc_du_container_t *a, const nr_rrc_du_container_t *b) +{ + if (a->assoc_id > b->assoc_id) + return 1; + if (a->assoc_id == b->assoc_id) + return 0; + return -1; /* a->assoc_id < b->assoc_id */ +} + +/* Tree management functions */ +RB_GENERATE/*_STATIC*/(rrc_du_tree, nr_rrc_du_container_t, entries, du_compare); + static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell_info_t *info) { const gNB_RrcConfigurationReq *conf = &rrc->configuration; @@ -46,17 +58,10 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) LOG_I(NR_RRC, "Received F1 Setup Request from gNB_DU %lu (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); // check: - // - it is the first DU // - it is one cell // - PLMN and Cell ID matches + // - no previous DU with the same ID // else reject - if (rrc->du != NULL) { - const f1ap_setup_req_t *other = rrc->du->setup_req; - LOG_E(NR_RRC, "can only handle one DU, but already serving DU %ld (%s)\n", other->gNB_DU_id, other->gNB_DU_name); - f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; - rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); - return; - } if (req->num_cells_available != 1) { LOG_E(NR_RRC, "can only handle on DU cell, but gNB_DU %ld has %d\n", req->gNB_DU_id, req->num_cells_available); f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_gNB_CU_Cell_Capacity_Exceeded}; @@ -77,6 +82,20 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } + nr_rrc_du_container_t *it = NULL; + RB_FOREACH(it, rrc_du_tree, &rrc->dus) { + if (it->setup_req->gNB_DU_id == req->gNB_DU_id) { + LOG_E(NR_RRC, + "gNB-DU ID: existing DU %s on assoc_id %d already has ID %ld, rejecting requesting gNB-DU\n", + it->setup_req->gNB_DU_name, + it->assoc_id, + it->setup_req->gNB_DU_id); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + } + // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; if (sys_info == NULL || sys_info->mib == NULL || (sys_info->sib1 == NULL && get_softmodem_params()->sa)) { @@ -116,20 +135,22 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) LOG_I(RRC, "Accepting DU %ld (%s), sending F1 Setup Response\n", req->gNB_DU_id, req->gNB_DU_name); // we accept the DU - rrc->du = calloc(1, sizeof(*rrc->du)); - AssertFatal(rrc->du != NULL, "out of memory\n"); - rrc->du->assoc_id = assoc_id; + nr_rrc_du_container_t *du = calloc(1, sizeof(*du)); + AssertFatal(du != NULL, "out of memory\n"); + du->assoc_id = assoc_id; /* ITTI will free the setup request message via free(). So the memory * "inside" of the message will remain, but the "outside" container no, so * allocate memory and copy it in */ - rrc->du->setup_req = malloc(sizeof(*rrc->du->setup_req)); - AssertFatal(rrc->du->setup_req != NULL, "out of memory\n"); - *rrc->du->setup_req = *req; - rrc->du->mib = mib->message.choice.mib; + du->setup_req = malloc(sizeof(*du->setup_req)); + AssertFatal(du->setup_req != NULL, "out of memory\n"); + *du->setup_req = *req; + du->mib = mib->message.choice.mib; mib->message.choice.mib = NULL; ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_MessageType, mib); - rrc->du->sib1 = sib1; + du->sib1 = sib1; + RB_INSERT(rrc_du_tree, &rrc->dus, du); + rrc->num_dus++; served_cells_to_activate_t cell = { .plmn = cell_info->plmn, @@ -187,21 +208,23 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) 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"); - AssertFatal(rrc->du != NULL, "no DU connected, cannot received F1 lost connection\n"); - AssertFatal(rrc->du->assoc_id == assoc_id, - "previously connected DU (%d) does not match DU for which connection has been lost (%d)\n", - rrc->du->assoc_id, - assoc_id); (void) lc; // unused for the moment - nr_rrc_du_container_t *du = rrc->du; + nr_rrc_du_container_t e = {.assoc_id = assoc_id}; + nr_rrc_du_container_t *du = RB_FIND(rrc_du_tree, &rrc->dus, &e); + if (du == NULL) { + LOG_W(NR_RRC, "no DU connected or not found for assoc_id %d: F1 Setup Failed?\n", assoc_id); + return; + } + f1ap_setup_req_t *req = du->setup_req; LOG_I(RRC, "releasing DU ID %ld (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib); ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1); /* TODO: free setup request */ - free(rrc->du); - rrc->du = NULL; + nr_rrc_du_container_t *removed = RB_REMOVE(rrc_du_tree, &rrc->dus, du); + DevAssert(removed != NULL); + rrc->num_dus--; int num = invalidate_du_connections(rrc, assoc_id); if (num > 0) { @@ -211,14 +234,12 @@ void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t nr_rrc_du_container_t *get_du_for_ue(gNB_RRC_INST *rrc, uint32_t ue_id) { - nr_rrc_du_container_t *du = rrc->du; - if (du == NULL) - return NULL; - return du; + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); + return get_du_by_assoc_id(rrc, ue_data.du_assoc_id); } nr_rrc_du_container_t *get_du_by_assoc_id(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) { - AssertFatal(assoc_id == rrc->du->assoc_id, "cannot handle multiple DUs yet\n"); - return rrc->du; + nr_rrc_du_container_t e = {.assoc_id = assoc_id}; + return RB_FIND(rrc_du_tree, &rrc->dus, &e); } From 7c4ec50e230d7329b5b4bc53b0413a6a5ffc972e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 8 Nov 2023 14:40:55 +0100 Subject: [PATCH 18/30] PLMN check F1 Setup: cellId does not necessarily match Multiple DUs host cells, whose cell ID cannot match (to identify them uniquely). Hence, don't check for equality with CU, because otherwise, we can never connect multiple DUs. --- openair2/RRC/NR/rrc_gNB_du.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 5423e690e2..4c1da64ed2 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -45,8 +45,7 @@ static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell const gNB_RrcConfigurationReq *conf = &rrc->configuration; return conf->num_plmn == 1 // F1 supports only one && conf->mcc[0] == info->plmn.mcc - && conf->mnc[0] == info->plmn.mnc - && rrc->nr_cellid == info->nr_cellid; + && conf->mnc[0] == info->plmn.mnc; } void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) @@ -71,13 +70,11 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) f1ap_served_cell_info_t *cell_info = &req->cell[0].info; if (!rrc_gNB_plmn_matches(rrc, cell_info)) { LOG_E(NR_RRC, - "PLMN mismatch: CU %d%d cellID %ld, DU %d%d cellID %ld\n", + "PLMN mismatch: CU %d%d, DU %d%d\n", rrc->configuration.mcc[0], rrc->configuration.mnc[0], - rrc->nr_cellid, cell_info->plmn.mcc, - cell_info->plmn.mnc, - cell_info->nr_cellid); + cell_info->plmn.mnc); f1ap_setup_failure_t fail = {.cause = F1AP_CauseRadioNetwork_plmn_not_served_by_the_gNB_CU}; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; From 97d574229dd45de73de5078523693e9fc358ea9e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 2 Nov 2023 17:26:08 +0100 Subject: [PATCH 19/30] Check PCI/nrCellID non-overlapping --- openair2/RRC/NR/rrc_gNB_du.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 4c1da64ed2..b8f7668677 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -91,6 +91,23 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); return; } + // note: we assume that each DU contains only one cell; otherwise, we would + // need to check every cell in the requesting DU to any existing cell. + const f1ap_served_cell_info_t *exist_info = &it->setup_req->cell[0].info; + const f1ap_served_cell_info_t *new_info = &req->cell[0].info; + if (exist_info->nr_cellid == new_info->nr_cellid || exist_info->nr_pci == new_info->nr_pci) { + LOG_E(NR_RRC, + "existing DU %s on assoc_id %d already has cellID %ld/physCellId %d, rejecting requesting gNB-DU with cellID %ld/physCellId %d\n", + it->setup_req->gNB_DU_name, + it->assoc_id, + exist_info->nr_cellid, + exist_info->nr_pci, + new_info->nr_cellid, + new_info->nr_pci); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } } // if there is no system info or no SIB1 and we run in SA mode, we cannot handle it From 6520dbc95ae67ceeaa8823191fcbf59c0348b738 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 15:09:31 +0100 Subject: [PATCH 20/30] Implement F1 Setup Failure to originate at RRC --- openair2/F1AP/f1ap_cu_interface_management.c | 10 ++-------- openair2/F1AP/f1ap_cu_interface_management.h | 2 +- openair2/F1AP/f1ap_cu_task.c | 4 ++++ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 7cd38027ba..6e6cd8558d 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -196,13 +196,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 sys_info->sib1_length = DUsi->sIB1_message.size; } - if (req->num_cells_available > 0) { - itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); - } else { - CU_send_F1_SETUP_FAILURE(assoc_id); - itti_free(TASK_CU_F1,message_p); - return -1; - } + itti_send_msg_to_task(TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(instance), message_p); return 0; } @@ -309,7 +303,7 @@ int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_set return 0; } -int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id) +int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail) { LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n"); F1AP_F1AP_PDU_t pdu= {0}; diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h index 8ed6fdf032..4d3f562128 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.h +++ b/openair2/F1AP/f1ap_cu_interface_management.h @@ -54,7 +54,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 int CU_send_F1_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_setup_resp_t *f1ap_setup_resp); -int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id); +int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail); /* * gNB-DU Configuration Update diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 75d6e1b8cc..38fb722b3e 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -170,6 +170,10 @@ void *F1AP_CU_task(void *arg) { &F1AP_SETUP_RESP(received_msg)); break; + case F1AP_SETUP_FAILURE: + CU_send_F1_SETUP_FAILURE(assoc_id, &F1AP_SETUP_FAILURE(received_msg)); + break; + case F1AP_GNB_CU_CONFIGURATION_UPDATE: // from rrc CU_send_gNB_CU_CONFIGURATION_UPDATE(assoc_id, &F1AP_GNB_CU_CONFIGURATION_UPDATE(received_msg)); From 59a25c48ffb3bee4c364b1be74e0e314c365d608 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 15:04:25 +0100 Subject: [PATCH 21/30] RRC UE context lookup by RNTI: use assoc_id --- common/utils/telnetsrv/telnetsrv_bearer.c | 4 ++-- common/utils/telnetsrv/telnetsrv_ci.c | 2 +- .../E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c | 2 +- openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c | 4 ++-- openair2/RRC/NR/L2_nr_interface.c | 2 +- openair2/RRC/NR/rrc_gNB.c | 9 ++++----- openair2/RRC/NR/rrc_gNB_UE_context.c | 14 +++++++++++++- openair2/RRC/NR/rrc_gNB_UE_context.h | 3 ++- openair2/RRC/NR/rrc_gNB_nsa.c | 2 +- 9 files changed, 27 insertions(+), 15 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv_bearer.c b/common/utils/telnetsrv/telnetsrv_bearer.c index f019d3d48b..7281ac3e6b 100644 --- a/common/utils/telnetsrv/telnetsrv_bearer.c +++ b/common/utils/telnetsrv/telnetsrv_bearer.c @@ -71,7 +71,7 @@ int add_bearer(char *buf, int debug, telnet_printfunc_t prnt) } // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti); if (!rrcue) ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); @@ -95,7 +95,7 @@ int release_bearer(char *buf, int debug, telnet_printfunc_t prnt) } // verify it exists in RRC as well - rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti); if (!rrcue) ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 2d7019b00e..943a3eec29 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -87,7 +87,7 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) rnti = strtol(buf, NULL, 16); if (rnti < 1 || rnti >= 0xfffe) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); - ue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti); + ue = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], rnti); if (!ue) ERROR_MSG_RET("could not find UE with RNTI %04x in RRC\n"); } diff --git a/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c b/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c index 3550a80981..0a14dfe915 100644 --- a/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c +++ b/openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c @@ -38,7 +38,7 @@ void read_gtp_sm(void * data) UE_iterator(UE_info->list, UE) { uint16_t const rnti = UE->rnti; - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[mod_id], rnti); + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[mod_id], rnti); if (ue_context_p != NULL) { gtp->msg.ngut[i].rnti = ue_context_p->ue_context.rnti; int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions; diff --git a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c index ea1735fcd8..dc173cc52f 100644 --- a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c +++ b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c @@ -43,7 +43,7 @@ matched_ues_mac_t filter_ues_by_s_nssai_in_du_or_monolithic(test_cond_e const co { if (NODE_IS_MONOLITHIC(RC.nrrrc[0]->node_type)) { - rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti); + rrc_gNB_ue_context_t *rrc_ue_context_list = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[0], ue->rnti); ngap_ue_context_list = ngap_get_ue_context(rrc_ue_context_list->ue_context.rrc_ue_id); assert(ngap_ue_context_list->gNB_instance[0].s_nssai[0][0].sST == value && "Please, check the condition for S-NSSAI. At the moment, OAI supports eMBB"); } @@ -589,7 +589,7 @@ kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3_in_monolithic(const matched_ues_ma for (size_t i = 0; iue_Identity.c_RNTI; - // TODO: we need to check within a specific DU! - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, old_rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, assoc_id, old_rnti); /* in case we need to do RRC Setup, give the UE a new random identity */ uint64_t random_value; fill_random(&random_value, sizeof(random_value)); @@ -1291,6 +1289,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc, sctp_assoc_t return; } + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; // 3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1: RNTI values if (req->ue_Identity.c_RNTI < 0x1 || req->ue_Identity.c_RNTI > 0xffef) { /* c_RNTI range error should not happen */ @@ -2546,7 +2545,7 @@ void rrc_gNB_trigger_new_bearer(int rnti) { /* get RRC and UE */ gNB_RRC_INST *rrc = RC.nrrrc[0]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti); if (ue_context_p == NULL) { LOG_E(RRC, "unknown UE RNTI %04x\n", rnti); return; @@ -2628,7 +2627,7 @@ void rrc_gNB_trigger_release_bearer(int rnti) { /* get RRC and UE */ gNB_RRC_INST *rrc = RC.nrrrc[0]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti); if (ue_context_p == NULL) { LOG_E(RRC, "unknown UE RNTI %04x\n", rnti); return; diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 396edc3175..db082c1965 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -87,7 +87,19 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, ue_i return RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); } -rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) +rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP) +{ + rrc_gNB_ue_context_t *ue_context_p; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_context_p->ue_context.rrc_ue_id); + if (ue_data.du_assoc_id == assoc_id && ue_context_p->ue_context.rnti == rntiP) + return ue_context_p; + } + LOG_W(NR_RRC, "search by RNTI %04x and assoc_id %d: no UE found\n", rntiP, assoc_id); + return NULL; +} + +rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) { rrc_gNB_ue_context_t *ue_context_p; RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 172ac07ef2..af40b33981 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -41,7 +41,8 @@ RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance_pP); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue); -rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); +rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP); +rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index aa39239f88..448de0eb95 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -414,7 +414,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id); - ue_context = rrc_gNB_get_ue_context_by_rnti(rrc, rnti); + ue_context = rrc_gNB_get_ue_context_by_rnti_any_du(rrc, rnti); if (ue_context == NULL) { LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti); return; From 96dfb44ae7f79d979c7fcd2c1f2ca3881c37bc7a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 17:31:44 +0100 Subject: [PATCH 22/30] Print DU information in periodic RRC stats printing --- openair2/RRC/NR/rrc_gNB.c | 11 +++++++++++ openair2/RRC/NR/rrc_gNB_du.c | 19 +++++++++++++++++++ openair2/RRC/NR/rrc_gNB_du.h | 3 +++ 3 files changed, 33 insertions(+) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 87b8f6296a..0bded94269 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2212,12 +2212,23 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) fprintf(f, " PDU session %d ID %d status %s\n", nb_pdu, pdu->param.pdusession_id, get_pdusession_status_text(pdu->status)); } + fprintf(f, " associated DU: "); + if (ue_data.du_assoc_id == -1) + fprintf(f, " (local/integrated CU-DU)"); + else if (ue_data.du_assoc_id == 0) + fprintf(f, " DU offline/unavailable"); + else + fprintf(f, " DU assoc ID %d", ue_data.du_assoc_id); + fprintf(f, "\n"); if (ue_ctxt->measResults) print_rrc_meas(f, ue_ctxt->measResults); ++i; } + fprintf(f, "\n"); + dump_du_info(rrc, f); + fclose(f); } diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index b8f7668677..25763c7ae7 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -257,3 +257,22 @@ nr_rrc_du_container_t *get_du_by_assoc_id(gNB_RRC_INST *rrc, sctp_assoc_t assoc_ nr_rrc_du_container_t e = {.assoc_id = assoc_id}; return RB_FIND(rrc_du_tree, &rrc->dus, &e); } + +void dump_du_info(const gNB_RRC_INST *rrc, FILE *f) +{ + fprintf(f, "%ld connected DUs \n", rrc->num_dus); + int i = 1; + nr_rrc_du_container_t *du = NULL; + /* cast is necessary to eliminate warning "discards ‘const’ qualifier" */ + RB_FOREACH(du, rrc_du_tree, &((gNB_RRC_INST *)rrc)->dus) { + const f1ap_setup_req_t *sr = du->setup_req; + fprintf(f, "[%d] DU ID %ld (%s) ", i++, sr->gNB_DU_id, sr->gNB_DU_name); + if (du->assoc_id == -1) { + fprintf(f, "integrated DU-CU"); + } else { + fprintf(f, "assoc_id %d", du->assoc_id); + } + const f1ap_served_cell_info_t *info = &sr->cell[0].info; + fprintf(f, ": nrCellID %ld, PCI %d\n", info->nr_cellid, info->nr_pci); + } +} diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h index c7472d652c..c57faf3802 100644 --- a/openair2/RRC/NR/rrc_gNB_du.h +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -25,6 +25,7 @@ #include #include #include +#include struct f1ap_setup_req_s; struct f1ap_lost_connection_t; @@ -37,4 +38,6 @@ void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_l 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); +void dump_du_info(const struct gNB_RRC_INST_s *rrc, FILE *f); + #endif /* RRC_GNB_DU_H_ */ From 41c5ea94ae03b7cd15396869a5f86fa1637f1dab Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 17:08:58 +0100 Subject: [PATCH 23/30] Start RRC ITTI task only in CU or monolithic --- executables/nr-softmodem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 75a9e0dc24..c60379dde1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -392,10 +392,11 @@ static int create_gNB_tasks(ngran_node_t node_type) return -1; } - LOG_I(NR_RRC, "Creating NR RRC gNB Task, that will also create TASKS\n"); - if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); - return -1; + if (!NODE_IS_DU(node_type)) { + if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); + return -1; + } } // If CU From e9d91de50b7b9432d8fb3236fe34d731a4642110 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 31 Oct 2023 18:07:36 +0100 Subject: [PATCH 24/30] RFsimulator serverport is a number --- ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf | 2 +- ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf | 2 +- ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf | 2 +- ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf | 2 +- ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf | 2 +- .../conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf | 2 +- .../conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf | 2 +- .../GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf | 2 +- .../GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf | 2 +- targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf | 2 +- .../CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf | 2 +- .../CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf | 2 +- .../CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf | 2 +- .../CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf | 2 +- .../CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf | 2 +- .../CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf | 2 +- .../GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf | 2 +- .../CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf | 2 +- .../CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf | 2 +- targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf index 09f8d5007e..94474b86bf 100644 --- a/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb-du.band78.106prb.rfsim.conf @@ -217,7 +217,7 @@ THREAD_STRUCT = ( rfsimulator: { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf index 5c674b3f6f..95ed9d8429 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf @@ -217,7 +217,7 @@ THREAD_STRUCT = ( ); rfsimulator: { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" diff --git a/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf index 66deda5e59..c81c9fb0f6 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.106prb.rfsim.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf index b72217d5e6..706cae1e23 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.u0.25prb.rfsim.conf @@ -240,7 +240,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf index 60b1e92f9e..a6d97f67fe 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.2x2.conf @@ -232,7 +232,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf index 583235bf60..e736a8830f 100644 --- a/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/untested/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf b/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf index 5dc8cf12f7..564bac2c85 100644 --- a/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf +++ b/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf @@ -229,7 +229,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 4628ee54fe..ebeeb25572 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -278,7 +278,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "enb"; - serverport = "4043"; + serverport = 4043; options = ("saviq"); modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index e951754bf0..eaad417c9b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -240,7 +240,7 @@ THREAD_STRUCT = ( #rfsimulator : #{ # serveraddr = "server"; -# serverport = "4043"; +# serverport = 4043; # options = ("chanmod"); # modelname = "AWGN"; #}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf index 3007cb2af8..67fa7726dc 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf @@ -215,7 +215,7 @@ THREAD_STRUCT = ( ); rfsimulator: { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 073a1c5d17..60077f4ab4 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -228,7 +228,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf index 430c2ddd53..97405a073b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf @@ -236,7 +236,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf index cf60b9b764..21d9a1233f 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -228,7 +228,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf index 88bc9429cc..aa0c090395 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpx300.conf @@ -254,7 +254,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index f9b7bf13fc..f8057be015 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -255,7 +255,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index f5baeba81c..f9646c4aed 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -255,7 +255,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf index bcbbe101ca..ab6c5b7ffb 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf @@ -234,7 +234,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf index 6d6dc4d281..70bab1c6f7 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.usrpx300.conf @@ -234,7 +234,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf index 32a6c8b65f..1d64c6fedf 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf index 0ad8b6066d..6958213f05 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 3b7fadf3bc..665771288b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -230,7 +230,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf index 60a29c50e4..b40df581d4 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf @@ -239,7 +239,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf index ff29e1f572..0ed70dea8b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf @@ -234,7 +234,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf index b5101c1112..31c32a4d1d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf @@ -232,7 +232,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf index a982ed59cd..7593d64465 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -231,7 +231,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf index aa3e5de456..d448ad8cbc 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf @@ -292,7 +292,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf index 65a2a49d50..21bb04ed25 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf @@ -291,7 +291,7 @@ THREAD_STRUCT = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf index 06bb23309e..1e729f7d02 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/pnf.sa.band78.rfsim.conf @@ -33,7 +33,7 @@ RUs = ( rfsimulator : { serveraddr = "server"; - serverport = "4043"; + serverport = 4043; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs"; From 01a095a26856c3338b7a0cd1e9c9c8059ede8037 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 2 Nov 2023 14:56:09 +0100 Subject: [PATCH 25/30] assoc_id only to be stored for DU --- openair2/F1AP/f1ap_common.h | 4 +++- openair2/F1AP/f1ap_cu_task.c | 3 ++- openair2/F1AP/f1ap_du_task.c | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h index 5dcd661b3b..2071234be0 100644 --- a/openair2/F1AP/f1ap_common.h +++ b/openair2/F1AP/f1ap_common.h @@ -401,7 +401,9 @@ typedef struct f1ap_cudu_inst_s { f1ap_net_config_t net_config; /* SCTP information */ - sctp_assoc_t assoc_id; + struct { + sctp_assoc_t assoc_id; + } du; uint16_t sctp_in_streams; uint16_t sctp_out_streams; diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 38fb722b3e..1c2b727237 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -55,7 +55,8 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, { // save the assoc id f1ap_cudu_inst_t *f1ap_cu_data = getCxt(instance); - f1ap_cu_data->assoc_id = sctp_new_association_ind->assoc_id; + // we don't need the assoc_id, subsequent messages (the first being F1 Setup + // Request), will deliver the assoc_id f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; } diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index e53a1e5134..7ba479e1f9 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -76,11 +76,11 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat } // save the assoc id - f1ap_du_data->assoc_id = sctp_new_association_resp->assoc_id; + f1ap_du_data->du.assoc_id = sctp_new_association_resp->assoc_id; f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams; f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams; /* setup parameters for F1U and start the server */ - DU_send_F1_SETUP_REQUEST(f1ap_du_data->assoc_id, &f1ap_du_data->setupReq); + DU_send_F1_SETUP_REQUEST(f1ap_du_data->du.assoc_id, &f1ap_du_data->setupReq); } void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { @@ -102,7 +102,7 @@ void *F1AP_DU_task(void *arg) { MessageDef *msg = NULL; itti_receive_msg(TASK_DU_F1, &msg); instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); - sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->assoc_id : 0; + sctp_assoc_t assoc_id = getCxt(0) != NULL ? getCxt(0)->du.assoc_id : 0; LOG_D(F1AP, "DU Task Received %s for instance %ld: sending SCTP messages via assoc_id %d\n", ITTI_MSG_NAME(msg), myInstance, assoc_id); switch (ITTI_MSG_ID(msg)) { case F1AP_SETUP_REQ: From a6c95537fb705ce048d88270c5a670ea2e268e25 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 6 Nov 2023 07:38:00 +0100 Subject: [PATCH 26/30] Simplify F1 config files --- .../conf_files/gnb-cu.sa.band78.106prb.conf | 20 ++++++++----------- .../gnb-du.sa.band78.106prb.rfsim.conf | 20 ++++++++----------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf b/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf index e7c5dd0514..8a33b6dd96 100644 --- a/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf +++ b/ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf @@ -75,15 +75,11 @@ security = { drb_ciphering = "yes"; drb_integrity = "no"; }; - log_config : - { - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="debug"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - f1ap_log_level ="debug"; - ngap_log_level ="debug"; - }; + +log_config : { + global_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + f1ap_log_level = "info"; + ngap_log_level = "info"; +}; diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf index 95ed9d8429..105530c0ba 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf @@ -223,15 +223,11 @@ serveraddr = "server"; IQfile = "/tmp/rfsimulator.iqs" } - log_config : - { - global_log_level ="info"; - hw_log_level ="info"; - phy_log_level ="info"; - mac_log_level ="info"; - rlc_log_level ="info"; - pdcp_log_level ="info"; - rrc_log_level ="info"; - f1ap_log_level ="debug"; - ngap_log_level ="debug"; - }; +log_config: { + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + f1ap_log_level = "info"; +}; From eefffef55b8a3d6e03243305a9d7e422ad5b63a4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 6 Nov 2023 09:30:52 +0100 Subject: [PATCH 27/30] UndeployGenObject(): allow multiple gNBs/DUs/CUs for log file analysis, like UE --- ci-scripts/cls_containerize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index bc6b36bd8b..7957bdf066 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -1245,7 +1245,7 @@ class Containerize(): fullStatus = True if anyLogs: # Analyzing log file(s)! - listOfPossibleRanContainers = ['enb', 'gnb', 'cu', 'du'] + listOfPossibleRanContainers = ['enb*', 'gnb*', 'cu*', 'du*'] for container in listOfPossibleRanContainers: filenames = './*-oai-' + container + '.log' cmd = f'ls {filenames}' From 1e565f6b7bee60528e81477e72b81077281491d3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 6 Nov 2023 07:50:19 +0100 Subject: [PATCH 28/30] 5G RFsim F1 test: docker-compose: add two more DUs with one UE each --- .../5g_f1_rfsimulator/docker-compose.yaml | 72 +++++++++++++++++++ .../yaml_files/5g_f1_rfsimulator/oai_db.sql | 2 + 2 files changed, 74 insertions(+) diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index dd8c62d97d..e2c6d7ed0d 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -198,6 +198,42 @@ services: interval: 10s timeout: 5s retries: 5 + oai-du2: + image: oaisoftwarealliance/oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-du2 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim --gNBs.[0].gNB_ID 0xe01 --gNBs.[0].nr_cellid 87654321 --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 --MACRLCs.[0].local_n_address 192.168.71.143 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-cu + networks: + public_net: + ipv4_address: 192.168.71.143 + volumes: + - ../../conf_files/gnb-du.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 + oai-du3: + image: oaisoftwarealliance/oai-gnb:develop + privileged: true + container_name: rfsim5g-oai-du3 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim --gNBs.[0].gNB_ID 0xe02 --gNBs.[0].nr_cellid 11111111 --gNBs.[0].servingCellConfigCommon.[0].physCellId 2 --MACRLCs.[0].local_n_address 192.168.71.144 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-cu + networks: + public_net: + ipv4_address: 192.168.71.144 + volumes: + - ../../conf_files/gnb-du.sa.band78.106prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 oai-nr-ue: image: oaisoftwarealliance/oai-nr-ue:develop privileged: true @@ -216,6 +252,42 @@ services: interval: 10s timeout: 5s retries: 5 + oai-nr-ue2: + image: oaisoftwarealliance/oai-nr-ue:develop + privileged: true + container_name: rfsim5g-oai-nr-ue2 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001101 -C 3619200000 --rfsimulator.serveraddr 192.168.71.143 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-du2 + networks: + public_net: + ipv4_address: 192.168.71.151 + volumes: + - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 + oai-nr-ue3: + image: oaisoftwarealliance/oai-nr-ue:develop + privileged: true + container_name: rfsim5g-oai-nr-ue3 + environment: + USE_ADDITIONAL_OPTIONS: --sa --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001102 -C 3619200000 --rfsimulator.serveraddr 192.168.71.144 --log_config.global_log_options level,nocolor,time + depends_on: + - oai-du3 + networks: + public_net: + ipv4_address: 192.168.71.152 + volumes: + - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 networks: public_net: diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql b/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql index fbd7907a71..19a6e27079 100755 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/oai_db.sql @@ -192,6 +192,8 @@ LOCK TABLES `users` WRITE; /*!40000 ALTER TABLE `users` DISABLE KEYS */; INSERT INTO `users` VALUES ('20834123456789','380561234567','35609204079300',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,'+�E��ų\0�,IH��H',0,0,00000000000000000096,'Px�X \Z1��x��','^��K�����FeU���'),('20810000001234','33611123456','35609204079299',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000281454575616225,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','�4�s@���z��~�'),('31002890832150','33638060059','35611302209414',NULL,'PURGED',120,40000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012416,'`�F�݆��D��ϛ���','�4�s@���z��~�'),('001010123456789','33600101789','35609204079298',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'\0 \n \r',1,0,00000000000000000351,'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0','L�*\\�����^��]� '),('208930000000001','33638030001','35609204079301',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000002','33638050002','35609204079502',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000020471,'\0 \n \r','�4�s@���z��~�'),('208950000000003','33638050003','35609204079503',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012343,'\0 \n \r','�4�s@���z��~�'),('208950000000004','33638050004','35609204079504',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000005','33638050005','35609204079505',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000001','33638050001','35609204079501',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208950000000006','33638050006','35609204079506',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000007','33638050007','35609204079507',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208930000000002','33638030002','35609204079302',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000003','33638030003','35609204079303',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000004','33638030004','35609204079304',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000005','33638030005','35609204079305',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000006','33638030006','35609204079306',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208930000000007','33638030007','35609204079307',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000007','33638040007','35609204079407',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000006','33638040006','35609204079406',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000005','33638040005','35609204079405',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000004','33638040004','35609204079404',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000003','33638040003','35609204079403',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000002','33638040002','35609204079402',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208940000000001','33638040001','35609204079401',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'��wq��gzW�Ё��Z]','�4�s@���z��~�'),('208920100001100','33638020001','35609204079201',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001101','33638020001','35609204079201',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204937234,'\0 \n \r','�$I6;��+f�k�u�|�'),('208920100001102','33638020002','35609204079202',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001103','33638020003','35609204079203',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001104','33638020004','35609204079204',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001105','33638020005','35609204079205',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001106','33638020006','35609204079206',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000000000000006103,'ebd07771ace8677a','�$I6;��+f�k�u�|�'),('208920100001107','33638020007','35609204079207',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001108','33638020008','35609204079208',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001109','33638020009','35609204079209',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208920100001110','33638020010','35609204079210',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001111','33638030011','35609304079211',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001112','33638030012','35609304079212',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006103,'ebd07771ace8677a','�4�s@���z��~�'),('208930100001113','33638030013','35609304079213',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000006263,'�SNܒ�Iv��e�6','�4�s@���z��~�'),('208950000000008','33638050008','35609204079508',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000009','33638050009','35609204079509',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000010','33638050010','35609204079510',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000011','33638050011','35609204079511',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000012','33638050012','35609204079512',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000013','33638050013','35609204079513',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000014','33638050014','35609204079514',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000012215,'56f0261d9d051063','�4�s@���z��~�'),('208950000000015','33638050015','35609204079515',NULL,'PURGED',120,50000000,100000000,47,0000000000,1,'��G?/�Д���� |hb',1,0,00000000000000000000,'3536663032363164','�4�s@���z��~�'),('208920100001118','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204934762,'~?03�u-%�ey�y�','�$I6;��+f�k�u�|�'),('208920100001121','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'&��@xg�]���\n��Vp','�$I6;��+f�k�u�|�'),('208920100001119','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'269482407867805d','�$I6;��+f�k�u�|�'),('208920100001120','33638020010','35609204079210',NULL,'NOT_PURGED',120,50000000,100000000,47,0000000000,1,'��k��p~Љu{�K�',1,0,00000281044204935293,'3236393438323430','�$I6;��+f�k�u�|�'); INSERT INTO `users` VALUES ('208990100001100','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1); +INSERT INTO `users` VALUES ('208990100001101','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1); +INSERT INTO `users` VALUES ('208990100001102','1','55000000000000',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0xfec86ba6eb707ed08905757b1bb44b8f,0,0,0x40,'ebd07771ace8677a',0xc42449363bbad02b66d16bc975d77cc1); INSERT INTO `users` VALUES ('208950000000031','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d); INSERT INTO `users` VALUES ('208950000000032','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d); INSERT INTO `users` VALUES ('208950000000033','380561234567','55000000000001',NULL,'PURGED',50,40000000,100000000,47,0000000000,1,0x0C0A34601D4F07677303652C0462535B,0,0,0x40,'ebd07771ace8677a',0x63bfa50ee6523365ff14c1f45f88737d); From 39274212fe8a662c33dc62a71b085ae4dc333a81 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 6 Nov 2023 07:57:15 +0100 Subject: [PATCH 29/30] 5G RFsim F1 test: start 3 DUs, with 1 UE each, PING ONLY --- .../xml_files/container_5g_f1_rfsim.xml | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 86d369e526..0f4e0e5487 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -32,9 +32,8 @@ 000022 000023 000024 + 000025 020021 - 020022 - 030021 100021 @@ -72,33 +71,33 @@ DeployGenObject - Deploy OAI 5G DU RF sim SA + Deploy 3 OAI 5G DUs RF sim SA yaml_files/5g_f1_rfsimulator - oai-du - 8 + oai-du oai-du2 oai-du3 + 10 DeployGenObject Deploy OAI 5G NR-UE RF sim SA yaml_files/5g_f1_rfsimulator - oai-nr-ue - 9 + oai-nr-ue oai-nr-ue2 + 12 + + + + DeployGenObject + Deploy OAI 5G NR-UE RF sim SA + yaml_files/5g_f1_rfsimulator + oai-nr-ue3 + 13 Ping - Ping ext-dn from NR-UE - rfsim5g_ue - -c 20 192.168.72.135 - 5 - - - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - -c 20 12.1.1.2 + Ping ext-dn from all NR-UEs + rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 + -c 20 192.168.72.135 -i0.25 5 From 196e0a2c85ddadafaa0a63ad30e4ec62827ccd3c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 8 Nov 2023 16:35:08 +0100 Subject: [PATCH 30/30] Rewrite F1 documentation --- doc/F1-design.md | 442 +++++++++++++++++++++++++++-------------------- 1 file changed, 256 insertions(+), 186 deletions(-) diff --git a/doc/F1-design.md b/doc/F1-design.md index 7e491f5346..2666856a42 100644 --- a/doc/F1-design.md +++ b/doc/F1-design.md @@ -12,204 +12,44 @@ -# 1. Introduction +[[_TOC_]] -We use OpenAirInterface source code, and it's regular deployment scheme. +# Introduction -F1 specification is in 3GPP documents: TS 38.470 header document and all documents listed in chapter 2 References of TS 38.470. +The F1 interface is the functional split of 3GPP between the CU (centralized +unit: PDCP, RRC, SDAP) and the DU (distributed unit: RLC, MAC, PHY). It is +standardized in TS 38.470 - 38.473 for 5G NR. No equivalent for 4G exists. -This document explains how the source code works. +We assume that each DU handles only one cell. Multiple DUs connected to one CU +are supported. Mobility over F1 is not yet supported. -Offered features and deployment instructions are described in: -https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/f1-interface +# Control plane status (F1-C) -# 2. Common multi-threading architecture # +## Implementation Status -The CU and DU interfaces are based on ITTI threads (see oai/common/utils/ocp_itti/itti.md) +Note that OAI uses F1 "internally". That means, that even if you run a +monolithic gNB, the internal information exchange uses F1. You can therefore +expect that everything working in a monolithic deployment should also work in +F1. The current implementation is based on R16.3. -All OAI upper layers use the ITTI framework to run isolated threads dedicated to one feature. -The lower layers adopt case by case specific software architecture. +Note that NSA does NOT follow this logic yet, and does not work with F1. -```mermaid -graph TD -Linux[configuration file] --> APP[gNB_app_task] -Socks[Linux UDP] --> GTP[nr_gtpv1u_gNB_task] -APP --> CU -APP --> DU -A[Linux SCTP] -->|sockets| SCTP(OAI itti thread TASK_SCTP) -SCTP-->|TASK_NGAP| NG[ngap_gNB_task] -NG-->|TASK_SCTP| SCTP -SCTP-->|TASK_DU_F1| DU[F1AP_DU_task] -SCTP-->|TASK_CU_F1| CU[F1AP_CU_task] -CU-->|TASK_RRC_GNB| RRC -RRC -->|non ITTI| PHY[OAI L1+L2] -RRC -->|API calls to create tunnels| GTP -PHY --> |user plane| GTP -CU --> |TASK_GTPV1_U| GTP -DU --> |TASK_GTPV1_U| GTP -``` -A "task" is a Linux thread running infinite waiting loop on one ITTI queue +The following messages are currently implemented: -app task manages the initial configuration +- F1 Setup Request and F1 Setup Response/Failure +- Initial UL RRC, UL/DL RRC Message Transfer +- F1 UE Context management messages for the "good case" + * Setup Request/Response + * Modification Request/Response + * Release Request/Command/Complete -sctp task mamanges the SCTP Linux sockets +All other messages are not implemented or not working reliably: -CU code runs in the task F1AP_CU_task. It stores it's private data context in a static variable. No mutex is used, as the single interface to CU ITTI tast in incoming ITTI messages. CU task is a single ITTI queue, but multiple CU could exist in one Linux process, using the "instance id" (called "module id" also) to create separate contextual information for each CU instance. +- F1 CU/DU configuration updade +- Paging messages +- Warning Message transmissions -DU code runs in the task F1AP_DU_task. The design is similar to CU task - -All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design: - -1. tunnel creation/deletion is by C API functions direct calls (a mutex protects it) -2. outgoing packets are pushed in a ITTI queue to the gtp thread -3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block - - -# 3. CU F1AP messages # - -## startup - -CU thread starts when the CU starts. It opens listening socket on F1AP_PORT_NUMBER by sending the appropriate message to TASK_SCTP. - -It will accept the first incoming connection on this port - -## F1 SETUP - -DU has connected, and sent this message. - -The CU receives, decode it and send relevant information to RRC thread by message F1AP_SETUP_REQ - -## F1 SETUP response - -RRC sends two messages to CU F1 task: the information to encode the F1 setup response and a second message to encode F1AP_GNB_CU_CONFIGURATION_UPDATE - -Upon reception of these two messages the CU task encodes and sends the messages to the DU - -## UE entry - -When CCH channel decoding finds a new UE identity, it call rrc_gNB_generate_RRCSetup() that will send F1AP_DL_RRC_MESSAGE to the CU task. - -The CU encodes and sends to DU DLRRCMessageTransfer - -## UE attach/detach - -When rrc_gNB_process_RRCReconfigurationComplete() occurs, the RRC sends to CU task the message F1AP_UE_CONTEXT_SETUP_REQ. The CU task encodes the F1 message UEContextSetup and send it to the DU over F1AP. - -This function rrc_gNB_process_RRCReconfigurationComplete() also creates the GTP-U user plane bearers. - -## F1AP incoming messages - -SCTP tasks sends a ITTI message SCTP_DATA_IND to the CU task. - -A array of functions pointers and the F1AP standard identifier "procedureCode", the CU calls the appropriate function - -Hereafter the most significant messages processing - -### CU_handle_F1_SETUP_REQUEST - -Transcodes information to the same message toward RRC (F1AP_SETUP_REQ) - -### CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER - -Transcodes information to the same message toward RRC (NR_RRC_MAC_CCCH_DATA_IND) - -### CU_handle_UL_RRC_MESSAGE_TRANSFER - -Encode and send data to PDCP (calling pdcp_data_ind ()) for processing UL data. - -# DU F1 Messages - -## Startup - -The task "gNB app" after rzading the configuration file, sends a first message F1AP_SETUP_REQ to DU task - -Using this message, the uniq DU task (Linux Thread) creates a DU instance context memory space, calls SCTP task to create a socket to the CU. - -When it receives from the SCTP task the socket creation success, the DU task encodes+sends the F1 setup message to the CU. - -## F1AP_INITIAL_UL_RRC_MESSAGE - -When MAC layer push UL data to DU task, the DU sends to CU the message InitialULRRCMessageTransfer - -## F1AP_UL_RRC_MESSAGE - -In case of SRB bearer, the RLC layer use this message to push rlc bearer payload to DU task, that forward to CU - -## pdcp_data_ind - -This function call in RLC, when it is a DRB will be replaced by F1-U transport to CU - -## F1AP incoming messages - -SCTP tasks sends a ITTI message SCTP_DATA_IND to the DU task. - -A array of functions pointers and the F1AP standard identifier "procedureCode", the DU calls the appropriate function - -Hereafter the most significant messages processing - -### DU_send_F1_SETUP_RESPONSE - -Decode the CU message, then encode a message to TASK_GNB_APP. The thread "APP" extracts the system information block and reconfigure the DU with: du_extract_and_decode_SI(), configure_gnb_du_mac() - -### DU_handle_gNB_CU_CONFIGURATION_UPDATE - -No developped - -### DU_handle_UE_CONTEXT_SETUP_REQUEST - -Push data to RLC layer for transmisstion in DL (to the UE) by calling enqueue_rlc_data_req() - -### DU_handle_DL_RRC_MESSAGE_TRANSFER - -Depending on the content, adds UE context in DU low layers and/or send data to the UE with rlc_data_req() - -# F1-U messages - -The data path by itself doesn't make any difficulty: -1. for UL, rlc calls pdcp_data_ind (DRB) or sends a message to RRC (SRB). So, we can replace pdcp_data_ind() by du_pdcp_data_ind() that will push the message in the GTP tunnel. In CU, assuming the tunnel is in place, the right call back decapsulate the transport (cu_ul_recv()), then calls pdcp_data_ind() in CU -The SRB are sent in DU RRC tasks via itti F1AP_UL_RRC_MESSAGE (see above the processing) -2. For DL, pdcp (in CU for DRBs) calls rlc_data_req (by a decoupling queue and thread rlc_data_req_thread, so function du_rlc_data_req() or enqueue_rlc_data_req()). in DU, assuming the gtp-u tunnel exists, a reception call back (du_dl_recv()) decapsulate the gtp-u packet and calls du_rlc_data_req() - -Hereafter the processing design, that doesn't require to setup a new context storage, as we can use the GTP-U internal tables: rnti+rb=>teid for outgoing gtp-u packets and teid=>rnti+rb for incoming gtp-u packets - -In CU case, the DRB tunnel to DU and the tunnel on N3 have the same key (rnti, rb id), but they run in two different GTP-U instances. -Each instance binds on diffrent sockets. - -For F1-U, both DU and CU binds on the full quadruplet (IP source, port source, IP destination, port destination) from the configuration file parameters: -local_s_address, remote_s_address,local_s_portd, remote_s_portd - -These 4 values are in: -CU: at cell level (same level as nr_cellid parameter), they are read if tr_s_preference = "f1"; is set -DU: in block MACRLCs, if tr_n_preference = "f1"; is set in this block - -## tunnels setup -In GTP-U, TS 29.281 specifies a option header (NR RAN Container This extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user plane interfaces), but it is not mandatory optional header (as is the N3 one). - -So, we can use this header a something reliable with other vendors implementation. - -In DL, we need to associate the packet with: rnti, rb (radio bearer) and "mui" (a OAI internal id that is optional and may be removed soon) to call rlc_data_req() - -In UL, we need also the RNTI, the rb - -So, we need to create a gtp-u tunnel for each rb over F1, then manage in CU and DU the association between a uniq TEid and the pair(rnti, rb). This is already what we have in existing OAI GTP-U layer interface. - -In F1AP, for each "DRB to Be Setup Item IEs", we have a field TNL (transport network layer) to set a specific GTP tunnel (@IP, TEid, udp port is always 2152). This is the same for each message related to DRBs. (F1AP carries the SRB payload inside F1AP). - -So, For each F1AP containing DRB setup/modification/deletion, the related GTP-U tunnels will be modified one to one. -The exception is the intialisation of new tunnel: in the call to tunnel creation, we need to send the remote TEID, but we don't know yet if we are the initial source. In this case, we issue a dummy (0xFFFF) remote teid; when we receive the remote answer, we get the source teid, that we can inform GTP-U with (using update tunnel). - -## processing on GTP-U incoming message - -Du_dl_recv() or cu_ul_recv() are called because we have set this callbacks in creat/update tunnel calls to gtp-u. As gtp-u maintains a pair(rnti,rbid) associated to each tunnel, the functions can be very simple stateless callback that calls pdcp_data_ind() or rlc_data_req() to get back in normal processing path - -## CU/DU outgoing - -DU rlc north output goes to du_pdcp_data_ind() that push a outgoing packet request to gtp-u, using the rnti+rb as ids. GTP-U must have the tunnel existing, then it simply implement the same as in N3 for exemple. - -CU pdcp south output calls cu_rlc_data_ind() that do the same symetric processing. - - -# High-level F1-C code structure +## High-level F1-C code structure The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC) to exchange information. In DL, the CU sends messages as defined by the @@ -252,3 +92,233 @@ Monolithic: mac_rrc_dl_direct.c | | | | +-------------+ ``` + +# Data plane status (F1-U) + +F1-U uses GTP-U for information exchange. The GTP protocol uses some extensions +for NR-U protocol to report buffer status, but this is not properly tested and +might malfunction. One limitation is that the current implementation +acknowledges each packet individually. + +Multiple DUs at one CU are supported in the data plane (as in the control plane). + +# How to run + +As mentioned earlier, OAI uses F1 internally. It is always compiled in. +To start CU/DU, you use `./nr-softmodem` with the appropriate configuration +files, for instance: + +``` +sudo cmake_targets/ran_build/build/nr-softmodem --sa -O ci-scripts/conf_files/gnb-cu.sa.band78.106prb.conf +sudo cmake_targets/ran_build/build/nr-softmodem --sa -O ci-scripts/conf_files/gnb-du.sa.band78.106prb.rfsim.conf +``` + +These files are tested in the CI, and are configured for use in docker, +see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml). + +## Configuration of F1 IP/port information + +For a local deployment, you should update the following fields. +We assume that the CU will bind on `192.168.70.129` towards the core, +`127.0.0.3` towards the DU, and the DU `127.0.0.4` towards the CU. + +In the CU file: +- Update the `gNBs.[0].amf_ip_address` and `gNBs.[0].NETWORK_INTERFACES` + section towards the core (typically, OAI CN is configured to provide a docker + bridge on `192.168.70.129` and the AMF is on `192.168.70.132`): + - `gNBs.[0].amf_ip_address.[0].ipv4 192.168.70.132` + - `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.70.129` + - `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 192.168.70.132` +- Set `gNBs.[0].tr_s_preference` (transport south-bound) to `f1` +- Update the `gNBs.[0].local_s_address` (CU-local south address) for the F1-C + south-bound interface: `127.0.0.3` +- Note: the `gNBs.[0].remote_s_address` (CU-remote/DU south address) is + ignored, but we recommend to put `0.0.0.0` ("any") +- Ports should match the ones in the DU config, but for simplicity and + standards-conformity, simply set all to 2152: + - `local_s_portc` in CU should match `remote_n_portc` in DU + - `local_s_portd` in CU should match `remote_n_portd` in DU + - `remote_s_portc` in CU should match `local_n_portc` in DU + - `remote_s_portd` in CU should match `local_n_portd` in DU + +In the DU file: +- Set `MACRLCs.[0].tr_n_preference` to `f1` +- Update `MACRLCs.[0].local_n_address` (local north-bound address of the DU) to + `127.0.0.4` +- Update `MACRLCs.[].remote_n_address` (remote north-bound address of the CU) + to `127.0.0.3` + +Note: all `local_*_if_name` parameters are ignored. + +## Configuration of multiple DUs + +Upon F1 Setup Request of a new DU, the CU cross-checks that + +- no DUs have the same gNB-DU IDs, taken from `gNBs.[0].gNB_ID`, and +- no cells have the same NR Cell ID, taken from `gNBs.[0].nr_cellid`, and +- no cells have the same physical cell IDs, taken from `gNBs.[0].servingCellConfigCommon.[0].physCellId`. + +If any of these are the same, the CU will reject the DU with an F1 Setup +Failure. Thus, you should make sure that in the DU's configs, these parameters +are set differently. + +You have to of course make sure that the local interface of the DU +(`MACRLCs.[0].local_n_address`) is different as well. + +Assuming you use RFsim, you should make the RFsimulator server side (typically +the gNB) bind on different hosts (`rfsimulator.serverport`). + +# Code documentation + +## Common multi-threading architecture + +The CU and DU interfaces are based on ITTI threads (see `common/utils/ocp_itti/itti.md`) +adopted by all OAI upper layers to run isolated threads dedicated to one feature. + +```mermaid +graph TD +Linux[configuration file] --> APP[gNB_app_task] +Socks[Linux UDP] --> GTP[nr_gtpv1u_gNB_task] +APP --> CU +APP --> DU +A[Linux SCTP] -->|sockets| SCTP(OAI itti thread TASK_SCTP) +SCTP-->|TASK_NGAP| NG[ngap_gNB_task] +NG-->|TASK_SCTP| SCTP +SCTP-->|TASK_DU_F1| DU[F1AP_DU_task] +SCTP-->|TASK_CU_F1| CU[F1AP_CU_task] +CU-->|TASK_RRC_GNB| RRC +RRC -->|non ITTI| PHY[OAI L1+L2] +RRC -->|API calls to create tunnels| GTP +PHY --> |user plane| GTP +CU --> |TASK_GTPV1_U| GTP +DU --> |TASK_GTPV1_U| GTP +``` + +A "task" is a Linux thread running an infinite waiting loop on one ITTI queue. + +The `app` task manages the initial configuration; the `sctp` task manages the +SCTP Linux sockets. + +The CU encoding/decoding runs in the task executing `F1AP_CU_task()`. It stores its private data context in a static variable. +The DU encoding/decoding runs in the task executing `F1AP_DU_task()`. The design is similar to CU task. + +All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design: + +1. tunnel creation/deletion is by C API functions direct calls (a mutex protects it) +2. outgoing packets are pushed in a ITTI queue to the gtp thread +3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block + + +## F1-C messages towards the CU + +The CU thread starts when the CU starts. It opens listening socket on the +configuration-specified IP/port by sending the appropriate message to +`TASK_SCTP`. It will accept any incoming connection and forward any F1 message +to RRC. + +You can trace any message by looking up the handler +`cu_task_handle_sctp_data_ind()`, which ultimately triggers a corresponding +ITTI message sent to RRC. All ITTI messages arriving are dispatched in the ITTI +message handling function in `rrc_gNB.c`. For your convenience, find below a +table of same messages that might arrive from the DU and how they are +forwarded. + +After handling messages, the RRC uses a callback that determines if messages go +directly to the MAC or are sent to the CU ITTI task (see +[above](#high-level-f1-c-code-structure)) + +You might also want to consult TS 38.401 regarding the message exchange. + +| Incoming F1 message | ITTI message to RRC | RRC handler | Comments | +|---------------------|---------------------|-------------|----------| +| F1 Setup Request | `F1AP_SETUP_REQ` | `rrc_gNB_process_f1_setup_req()` | will trigger either a response or failure | +| Initial UL RRC Message Transfer | `F1AP_INITIAL_UL_RRC_MESSAGE` | `rrc_gNB_process_initial_ul_rrc_message()` | first message from UE, follows up with RRC Setup or Reestablishment | +| UL RRC Message Transfer | `F1AP_UL_RRC_MESSAGE` | `rrc_gNB_decode_dcch()` | UL RRC messages contain DCCH | +| UE Context Response | `F1AP_UE_CONTEXT_SETUP_RESP` | `rrc_CU_process_ue_context_setup_response()` | does not trigger a follow-up, as UE sends Security Response | +| UE Context Modification Response | `F1AP_UE_CONTEXT_MODIFICATION_RESP` | `rrc_CU_process_ue_context_modification_response()` | triggers Reconfiguration if CellGroup in answer | +| UE Context Modification Required | `F1AP_UE_CONTEXT_MODIFICATION_REQUIRED` | `rrc_CU_process_ue_modification_required()` | triggers Reconfiguration | +| UE Context Release Request | `F1AP_UE_CONTEXT_RELEASE_REQ` | `rrc_CU_process_ue_context_release_request()` | RRC will trigger UE release | +| UE Context Release Complete | `F1AP_UE_CONTEXT_RELEASE_COMPLETE` | `rrc_CU_process_ue_context_release_complete()` | frees UE Context, signals to NGAP | + +## F1-C Messages towards the DU + +The task "gNB app", after reading the configuration file, sends a message +`F1AP_DU_REGISTER_REQ` to the DU task. This message contains network +configuration for the establishment of the SCTP connection, as well as the F1 +Setup Request to be sent to the CU. + +Using the network configuration, the DU task sets up an SCTP connection via the +SCTP task. When it receives from the SCTP task the socket creation success, +the DU task encodes and sends the F1 setup message to the CU. + +Similarly as for the CU, you can trace any message by looking up the handler +`du_task_handle_sctp_data_ind()`. Unlike in the CU, the decoders do NOT send an +ITTI message, but directly call into the scheduler via a message handling +function. This handler acquires the scheduler mutex and executes the +corresponding message handling functionality. All handlers are in +`mac_rrc_dl_handler.c`. + +After handling messages, the MAC uses a callback that determines if messages +are sent back to RRC via ITTI, or are sent to the DU ITTI task (see +[above](#high-level-f1-c-code-structure)) + +You might also want to consult TS 38.401 regarding the message exchange. + +| Incoming F1 message | MAC handler | Comments | +|---------------------|-------------|----------| +| F1 Setup Response | `f1_setup_response()` | the DU does not start the radio before receiving this message | +| DL RRC Message Transfer | `dl_rrc_message_transfer()` | Processing timer started if reconfiguration is present[^footnote-reconfig] | +| UE Context Setup Request | `ue_context_setup_request()` | | +| UE Context Modification Request | `ue_context_modification_request()` | | +| UE Context Modification Confirm | `ue_context_modification_confirm()` | | +| UE Context Modification Refuse | `ue_context_modification_refuse()` | Will trigger release request | +| UE Context Release Command | `ue_context_release_command()` | Starts timer for release if UE in sync | + +[^footnote-reconfig]: The DU does not decode RRC messages, and does not know + whether an RRC message is a reconfiguration. However, the spec mandates that + a reconfiguration has to be triggered if the CU receives a CellGroupConfig, + originating at the DU. See also flag `expect_reconfiguration`. + +## F1-U messages + +### General + +In the DU in UL, RLC checks in `deliver_sdu()` if we are operating in split +mode, and either (direct) calls `pdcp_data_ind` (DRB) or (f1ap) sends an +`GTPV1U_TUNNEL_DATA_REQ` ITTI message to the GTP task. + +In the CU in UL, assuming the tunnel is in place, GTP decapsulates the packet +and calls the callback `cu_f1u_data_req()`, which calls `pdcp_data_ind()` in CU. + +In the CU in DL, the PDCP function `deliver_pdu_drb_gnb()` either (direct) calls +into the RLC via `enqueue_rlc_data_req()`, or (f1ap) sends a +`GTPV1U_TUNNEL_DATA_REQ` ITTI message to the GTP task. + +In the DU in DL, assuming the GTP-U tunnel exists, GTP decapsulates the packet +and calls the reception call back `du_rlc_data_req()`, which calls +`enqueue_rlc_data_req()` in turn. + +## Tunnel Setup + +In GTP-U, TS 29.281 specifies a optional header (NR RAN Container). This +extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user +plane interfaces, but it is not mandatory. + +Note that the GTP-U uses internal tables. Instead of exposing TEIDs, it uses the +UE ID (RNTI, RRC UE ID) and Radio Bearer ID to map to a TEID for outgoing GTP-U +packets. Upon receiving, it does the reverse and calls the callbacks. In the CU +case, the DRB tunnel to DU and the tunnel on N3 have the same keys (RRC UE ID, +RB ID), but they run in two different GTP-U instances. Each instance binds on +diffrent sockets, which is the reason you cannot have the same interface for +F1-U and N3/NG-U interfaces (this can be considered a design flaw). + +In F1AP, for each "DRB to Be Setup Item IEs", we have a field TNL (transport +network layer) to set a specific GTP tunnel (@IP, TEid). This is the same for +each message related to DRBs. + +So, For each F1AP containing DRB setup/modification/deletion, the related GTP-U +tunnels will be modified one to one. The exception is the intialisation of new +tunnel: in the call to tunnel creation, we need to send the remote TEID, but we +don't know yet if we are the initial source. In this case, we issue a dummy +(0xFFFF) remote TEID; when we receive the remote answer, we get the source teid, +with which the GTP-U endpoint is updadet.